Skip to content

Commit

Permalink
Fixed access to files via token, i.e. for guest accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
Jesse Geens committed Nov 13, 2024
1 parent d7a0558 commit b7deeb4
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 3 deletions.
6 changes: 6 additions & 0 deletions changelog/unreleased/eos-grpc-token-access.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Enhancement: access to EOS via tokens over gRPC

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.


https://github.com/cs3org/reva/pull/4934
45 changes: 44 additions & 1 deletion pkg/eosclient/eosgrpc/eosgrpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -1603,7 +1603,50 @@ func (c *Client) ReadVersion(ctx context.Context, auth eosclient.Authorization,

// GenerateToken returns a token on behalf of the resource owner to be used by lightweight accounts.
func (c *Client) GenerateToken(ctx context.Context, auth eosclient.Authorization, path string, a *acl.Entry) (string, error) {
return "", errtypes.NotSupported("TODO")
log := appctx.GetLogger(ctx)
log.Info().Str("func", "GenerateToken").Str("uid,gid", auth.Role.UID+","+auth.Role.GID).Str("path", path).Msg("")

// Initialize the common fields of the NSReq
rq, err := c.initNSRequest(ctx, auth, "")
if err != nil {
log.Error().Str("func", "GenerateToken").Str("err", err.Error()).Msg("Error on initNSRequest")
return "", err
}

msg := new(erpc.NSRequest_TokenRequest)
msg.Token = &erpc.ShareToken{}
msg.Token.Token = &erpc.ShareProto{}
msg.Token.Token.Permission = a.Permissions
// TODO(jgeens): right now hardcoded to 3600, but in binary client this was set to c.opt.TokenExpiry
msg.Token.Token.Expires = uint64(time.Now().Add(time.Duration(3600) * time.Second).Unix())
msg.Token.Token.Allowtree = true
msg.Token.Token.Path = path

rq.Command = &erpc.NSRequest_Token{
Token: msg,
}

// Now send the req and see what happens
resp, err := c.cl.Exec(appctx.ContextGetClean(ctx), rq)
e := c.getRespError(resp, err)
if e != nil {
log.Error().Str("func", "GenerateToken").Str("err", e.Error()).Msg("")
return "", e
}

if resp == nil {
log.Error().Str("func", "GenerateToken").Msg("nil grpc response")
return "", errtypes.InternalError(fmt.Sprintf("nil response for uid: '%s' ", auth.Role.UID))
}

// For some reason, the token is embedded in the error, with error code 0
if resp.GetError() != nil {
if resp.GetError().Code == 0 {
return resp.GetError().Msg, nil
}
}
log.Error().Str("func", "GenerateToken").Msg("GenerateToken over gRPC expected an error but did not receive one")
return "", err
}

func (c *Client) getVersionFolderInode(ctx context.Context, auth eosclient.Authorization, p string) (uint64, error) {
Expand Down
14 changes: 12 additions & 2 deletions pkg/eosclient/eosgrpc/eoshttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,9 @@ func (c *EOSHTTPClient) buildFullURL(urlpath string, auth eosclient.Authorizatio
fullurl += "?"
}

if auth.Role.UID != "" {
if auth.Token != "" {
fullurl += "authz=" + auth.Token
} else if auth.Role.UID != "" {
fullurl += fmt.Sprintf("eos.ruid=%s&eos.rgid=%s", auth.Role.UID, auth.Role.GID)
}

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

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

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

0 comments on commit b7deeb4

Please sign in to comment.