Skip to content

Commit b7deeb4

Browse files
committed
Fixed access to files via token, i.e. for guest accounts
1 parent d7a0558 commit b7deeb4

File tree

3 files changed

+62
-3
lines changed

3 files changed

+62
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Enhancement: access to EOS via tokens over gRPC
2+
3+
As a guest account, accessing a file shared with you relies on a token that is generated on behalf of the resource owner. This method, GenerateToken, has now been implemented in the EOS gRPC client. Additionally, the HTTP client now takes tokens into account.
4+
5+
6+
https://github.com/cs3org/reva/pull/4934

pkg/eosclient/eosgrpc/eosgrpc.go

+44-1
Original file line numberDiff line numberDiff line change
@@ -1603,7 +1603,50 @@ func (c *Client) ReadVersion(ctx context.Context, auth eosclient.Authorization,
16031603

16041604
// GenerateToken returns a token on behalf of the resource owner to be used by lightweight accounts.
16051605
func (c *Client) GenerateToken(ctx context.Context, auth eosclient.Authorization, path string, a *acl.Entry) (string, error) {
1606-
return "", errtypes.NotSupported("TODO")
1606+
log := appctx.GetLogger(ctx)
1607+
log.Info().Str("func", "GenerateToken").Str("uid,gid", auth.Role.UID+","+auth.Role.GID).Str("path", path).Msg("")
1608+
1609+
// Initialize the common fields of the NSReq
1610+
rq, err := c.initNSRequest(ctx, auth, "")
1611+
if err != nil {
1612+
log.Error().Str("func", "GenerateToken").Str("err", err.Error()).Msg("Error on initNSRequest")
1613+
return "", err
1614+
}
1615+
1616+
msg := new(erpc.NSRequest_TokenRequest)
1617+
msg.Token = &erpc.ShareToken{}
1618+
msg.Token.Token = &erpc.ShareProto{}
1619+
msg.Token.Token.Permission = a.Permissions
1620+
// TODO(jgeens): right now hardcoded to 3600, but in binary client this was set to c.opt.TokenExpiry
1621+
msg.Token.Token.Expires = uint64(time.Now().Add(time.Duration(3600) * time.Second).Unix())
1622+
msg.Token.Token.Allowtree = true
1623+
msg.Token.Token.Path = path
1624+
1625+
rq.Command = &erpc.NSRequest_Token{
1626+
Token: msg,
1627+
}
1628+
1629+
// Now send the req and see what happens
1630+
resp, err := c.cl.Exec(appctx.ContextGetClean(ctx), rq)
1631+
e := c.getRespError(resp, err)
1632+
if e != nil {
1633+
log.Error().Str("func", "GenerateToken").Str("err", e.Error()).Msg("")
1634+
return "", e
1635+
}
1636+
1637+
if resp == nil {
1638+
log.Error().Str("func", "GenerateToken").Msg("nil grpc response")
1639+
return "", errtypes.InternalError(fmt.Sprintf("nil response for uid: '%s' ", auth.Role.UID))
1640+
}
1641+
1642+
// For some reason, the token is embedded in the error, with error code 0
1643+
if resp.GetError() != nil {
1644+
if resp.GetError().Code == 0 {
1645+
return resp.GetError().Msg, nil
1646+
}
1647+
}
1648+
log.Error().Str("func", "GenerateToken").Msg("GenerateToken over gRPC expected an error but did not receive one")
1649+
return "", err
16071650
}
16081651

16091652
func (c *Client) getVersionFolderInode(ctx context.Context, auth eosclient.Authorization, p string) (uint64, error) {

pkg/eosclient/eosgrpc/eoshttp.go

+12-2
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,9 @@ func (c *EOSHTTPClient) buildFullURL(urlpath string, auth eosclient.Authorizatio
241241
fullurl += "?"
242242
}
243243

244-
if auth.Role.UID != "" {
244+
if auth.Token != "" {
245+
fullurl += "authz=" + auth.Token
246+
} else if auth.Role.UID != "" {
245247
fullurl += fmt.Sprintf("eos.ruid=%s&eos.rgid=%s", auth.Role.UID, auth.Role.GID)
246248
}
247249

@@ -291,7 +293,15 @@ func (c *EOSHTTPClient) GETFile(ctx context.Context, remoteuser string, auth eos
291293
// Execute the request. I don't like that there is no explicit timeout or buffer control on the input stream
292294
log.Debug().Str("func", "GETFile").Str("finalurl", finalurl).Msg("sending req")
293295

294-
resp, err := c.doReq(req, remoteuser)
296+
// c.doReq sets headers such as remoteuser and x-gateway-authorization
297+
// we don't want those when using a token (i.e. ?authz=), so in this case
298+
// we skip this and call the HTTP client directly
299+
var resp *http.Response
300+
if auth.Token != "" {
301+
resp, err = c.cl.Do(req)
302+
} else {
303+
resp, err = c.doReq(req, remoteuser)
304+
}
295305

296306
// Let's support redirections... and if we retry we have to retry at the same FST, avoid going back to the MGM
297307
if resp != nil && (resp.StatusCode == http.StatusFound || resp.StatusCode == http.StatusTemporaryRedirect) {

0 commit comments

Comments
 (0)