From 1de400736183a5b3b1ba52cddf6fe0a866bef4a4 Mon Sep 17 00:00:00 2001 From: Ishank Arora Date: Tue, 19 Apr 2022 10:00:57 +0200 Subject: [PATCH] Enable federated account access (#2685) --- changelog/unreleased/federated-accounts.md | 3 +++ .../services/gateway/usershareprovider.go | 4 ++- .../ocs/handlers/cloud/users/users.go | 4 +-- pkg/app/provider/wopi/wopi.go | 2 +- pkg/auth/manager/demo/demo.go | 2 +- pkg/auth/manager/json/json.go | 2 +- pkg/auth/manager/oidc/oidc.go | 2 +- pkg/auth/manager/owncloudsql/owncloudsql.go | 2 +- pkg/cbox/user/rest/rest.go | 27 ++++++++++--------- pkg/cbox/utils/conversions.go | 2 ++ pkg/storage/utils/eosfs/eosfs.go | 14 ++++++---- 11 files changed, 39 insertions(+), 25 deletions(-) create mode 100644 changelog/unreleased/federated-accounts.md diff --git a/changelog/unreleased/federated-accounts.md b/changelog/unreleased/federated-accounts.md new file mode 100644 index 0000000000..3129b0c1c9 --- /dev/null +++ b/changelog/unreleased/federated-accounts.md @@ -0,0 +1,3 @@ +Enhancement: Enable federated account access + +https://github.com/cs3org/reva/pull/2685 \ No newline at end of file diff --git a/internal/grpc/services/gateway/usershareprovider.go b/internal/grpc/services/gateway/usershareprovider.go index 8a5e1c284d..a161e22233 100644 --- a/internal/grpc/services/gateway/usershareprovider.go +++ b/internal/grpc/services/gateway/usershareprovider.go @@ -323,7 +323,9 @@ func (s *svc) UpdateReceivedShare(ctx context.Context, req *collaboration.Update } // if we don't need to create/delete references then we return early. - if !s.c.CommitShareToStorageRef || ctxpkg.ContextMustGetUser(ctx).Id.Type == userpb.UserType_USER_TYPE_LIGHTWEIGHT { + if !s.c.CommitShareToStorageRef || + ctxpkg.ContextMustGetUser(ctx).Id.Type == userpb.UserType_USER_TYPE_LIGHTWEIGHT || + ctxpkg.ContextMustGetUser(ctx).Id.Type == userpb.UserType_USER_TYPE_FEDERATED { return res, nil } diff --git a/internal/http/services/owncloud/ocs/handlers/cloud/users/users.go b/internal/http/services/owncloud/ocs/handlers/cloud/users/users.go index ce97004bc0..528eda616e 100644 --- a/internal/http/services/owncloud/ocs/handlers/cloud/users/users.go +++ b/internal/http/services/owncloud/ocs/handlers/cloud/users/users.go @@ -131,8 +131,8 @@ func (h *Handler) GetUsers(w http.ResponseWriter, r *http.Request) { } var total, used uint64 var relative float32 - // lightweight accounts don't have access to their storage space - if u.Id.Type != userpb.UserType_USER_TYPE_LIGHTWEIGHT { + // lightweight and federated accounts don't have access to their storage space + if u.Id.Type != userpb.UserType_USER_TYPE_LIGHTWEIGHT && u.Id.Type != userpb.UserType_USER_TYPE_FEDERATED { getQuotaRes, err := gc.GetQuota(ctx, &gateway.GetQuotaRequest{Ref: &provider.Reference{Path: getHomeRes.Path}}) if err != nil { sublog.Error().Err(err).Msg("error calling GetQuota") diff --git a/pkg/app/provider/wopi/wopi.go b/pkg/app/provider/wopi/wopi.go index 9916b32d65..f25122f40b 100644 --- a/pkg/app/provider/wopi/wopi.go +++ b/pkg/app/provider/wopi/wopi.go @@ -140,7 +140,7 @@ func (p *wopiProvider) GetAppURL(ctx context.Context, resource *provider.Resourc u, ok := ctxpkg.ContextGetUser(ctx) if ok { // else defaults to "Guest xyz" - if u.Id.Type == userpb.UserType_USER_TYPE_LIGHTWEIGHT { + if u.Id.Type == userpb.UserType_USER_TYPE_LIGHTWEIGHT || u.Id.Type == userpb.UserType_USER_TYPE_FEDERATED { q.Add("userid", resource.Owner.OpaqueId+"@"+resource.Owner.Idp) } else { q.Add("userid", u.Id.OpaqueId+"@"+u.Id.Idp) diff --git a/pkg/auth/manager/demo/demo.go b/pkg/auth/manager/demo/demo.go index 7f2e1ddd6d..c3a23790ca 100644 --- a/pkg/auth/manager/demo/demo.go +++ b/pkg/auth/manager/demo/demo.go @@ -62,7 +62,7 @@ func (m *manager) Authenticate(ctx context.Context, clientID, clientSecret strin if c.Secret == clientSecret { var scopes map[string]*authpb.Scope var err error - if c.User.Id != nil && c.User.Id.Type == user.UserType_USER_TYPE_LIGHTWEIGHT { + if c.User.Id != nil && (c.User.Id.Type == user.UserType_USER_TYPE_LIGHTWEIGHT || c.User.Id.Type == user.UserType_USER_TYPE_FEDERATED) { scopes, err = scope.AddLightweightAccountScope(authpb.Role_ROLE_OWNER, nil) if err != nil { return nil, nil, err diff --git a/pkg/auth/manager/json/json.go b/pkg/auth/manager/json/json.go index daf81e25b3..1e989fba5f 100644 --- a/pkg/auth/manager/json/json.go +++ b/pkg/auth/manager/json/json.go @@ -117,7 +117,7 @@ func (m *manager) Authenticate(ctx context.Context, username string, secret stri if c.Secret == secret { var scopes map[string]*authpb.Scope var err error - if c.ID != nil && c.ID.Type == user.UserType_USER_TYPE_LIGHTWEIGHT { + if c.ID != nil && (c.ID.Type == user.UserType_USER_TYPE_LIGHTWEIGHT || c.ID.Type == user.UserType_USER_TYPE_FEDERATED) { scopes, err = scope.AddLightweightAccountScope(authpb.Role_ROLE_OWNER, nil) if err != nil { return nil, nil, err diff --git a/pkg/auth/manager/oidc/oidc.go b/pkg/auth/manager/oidc/oidc.go index 0a510ef2fe..ec5b67be47 100644 --- a/pkg/auth/manager/oidc/oidc.go +++ b/pkg/auth/manager/oidc/oidc.go @@ -238,7 +238,7 @@ func (am *mgr) Authenticate(ctx context.Context, clientID, clientSecret string) } var scopes map[string]*authpb.Scope - if userID != nil && userID.Type == user.UserType_USER_TYPE_LIGHTWEIGHT { + if userID != nil && (userID.Type == user.UserType_USER_TYPE_LIGHTWEIGHT || userID.Type == user.UserType_USER_TYPE_FEDERATED) { scopes, err = scope.AddLightweightAccountScope(authpb.Role_ROLE_OWNER, nil) if err != nil { return nil, nil, err diff --git a/pkg/auth/manager/owncloudsql/owncloudsql.go b/pkg/auth/manager/owncloudsql/owncloudsql.go index b700b63805..65bba2c5a3 100644 --- a/pkg/auth/manager/owncloudsql/owncloudsql.go +++ b/pkg/auth/manager/owncloudsql/owncloudsql.go @@ -144,7 +144,7 @@ func (m *manager) Authenticate(ctx context.Context, login, clientSecret string) } var scopes map[string]*authpb.Scope - if userID != nil && userID.Type == user.UserType_USER_TYPE_LIGHTWEIGHT { + if userID != nil && (userID.Type == user.UserType_USER_TYPE_LIGHTWEIGHT || userID.Type == user.UserType_USER_TYPE_FEDERATED) { scopes, err = scope.AddLightweightAccountScope(authpb.Role_ROLE_OWNER, nil) if err != nil { return nil, nil, err diff --git a/pkg/cbox/user/rest/rest.go b/pkg/cbox/user/rest/rest.go index 7fc1c3c427..78ec0ffbbb 100644 --- a/pkg/cbox/user/rest/rest.go +++ b/pkg/cbox/user/rest/rest.go @@ -143,7 +143,7 @@ func (m *manager) getUser(ctx context.Context, url string) (map[string]interface t, _ := userData["type"].(string) userType := getUserType(t, userData["upn"].(string)) - if userType != userpb.UserType_USER_TYPE_APPLICATION && userType != userpb.UserType_USER_TYPE_FEDERATED { + if userType != userpb.UserType_USER_TYPE_APPLICATION { users = append(users, userData) } } @@ -290,15 +290,15 @@ func (m *manager) GetUserByClaim(ctx context.Context, claim, value string, skipF } var userData map[string]interface{} - if strings.HasPrefix(value, "guest:") { + if claim == "upn" && strings.HasPrefix(value, "guest:") { // Lightweight accounts need to be fetched by email, regardless of the demanded claim - if userData, err = m.getLightweightUser(ctx, strings.TrimPrefix(value, "guest:")); err != nil { - return nil, err - } + userData, err = m.getLightweightUser(ctx, strings.TrimPrefix(value, "guest:")) } else { - if userData, err = m.getUserByParam(ctx, claim, value); err != nil { - return nil, errors.Wrap(err, "rest: failed getUserByParam, claim="+claim+", value="+value) - } + userData, err = m.getUserByParam(ctx, claim, value) + } + + if err != nil { + return nil, err } u, err := m.parseAndCacheUser(ctx, userData) if err != nil { @@ -329,7 +329,10 @@ func (m *manager) findUsersByFilter(ctx context.Context, url string, users map[s continue } - upn, _ := usrInfo["upn"].(string) + upn, ok := usrInfo["upn"].(string) + if !ok { + continue + } mail, _ := usrInfo["primaryAccountEmail"].(string) name, _ := usrInfo["displayName"].(string) uidNumber, _ := usrInfo["uid"].(float64) @@ -337,7 +340,7 @@ func (m *manager) findUsersByFilter(ctx context.Context, url string, users map[s t, _ := usrInfo["type"].(string) userType := getUserType(t, upn) - if userType == userpb.UserType_USER_TYPE_APPLICATION || userType == userpb.UserType_USER_TYPE_FEDERATED { + if userType == userpb.UserType_USER_TYPE_APPLICATION { continue } @@ -372,7 +375,7 @@ func (m *manager) FindUsers(ctx context.Context, query string, skipFetchingGroup // Look at namespaces filters. If the query starts with: // "a" => look into primary/secondary/service accounts - // "l" => look into lightweight accounts + // "l" => look into lightweight/federated accounts // none => look into primary parts := strings.SplitN(query, ":", 2) @@ -413,7 +416,7 @@ func (m *manager) FindUsers(ctx context.Context, query string, skipFetchingGroup case "a": accountsFilters = []userpb.UserType{userpb.UserType_USER_TYPE_PRIMARY, userpb.UserType_USER_TYPE_SECONDARY, userpb.UserType_USER_TYPE_SERVICE} case "l": - accountsFilters = []userpb.UserType{userpb.UserType_USER_TYPE_LIGHTWEIGHT} + accountsFilters = []userpb.UserType{userpb.UserType_USER_TYPE_LIGHTWEIGHT, userpb.UserType_USER_TYPE_FEDERATED} } for _, u := range users { diff --git a/pkg/cbox/utils/conversions.go b/pkg/cbox/utils/conversions.go index 3148e24377..271f8d5cb1 100644 --- a/pkg/cbox/utils/conversions.go +++ b/pkg/cbox/utils/conversions.go @@ -199,6 +199,8 @@ func ExtractUserID(u string) *userpb.UserId { t := userpb.UserType_USER_TYPE_PRIMARY if strings.HasPrefix(u, "guest:") { t = userpb.UserType_USER_TYPE_LIGHTWEIGHT + } else if strings.Contains(u, "@") { + t = userpb.UserType_USER_TYPE_FEDERATED } return &userpb.UserId{OpaqueId: u, Type: t} } diff --git a/pkg/storage/utils/eosfs/eosfs.go b/pkg/storage/utils/eosfs/eosfs.go index 288bdd206d..c8c44b7c56 100644 --- a/pkg/storage/utils/eosfs/eosfs.go +++ b/pkg/storage/utils/eosfs/eosfs.go @@ -467,7 +467,7 @@ func (fs *eosfs) GetPathByID(ctx context.Context, id *provider.ResourceId) (stri if err != nil { return "", errors.Wrap(err, "eosfs: no user in ctx") } - if u.Id.Type == userpb.UserType_USER_TYPE_LIGHTWEIGHT { + if u.Id.Type == userpb.UserType_USER_TYPE_LIGHTWEIGHT || u.Id.Type == userpb.UserType_USER_TYPE_FEDERATED { auth, err := fs.getRootAuth(ctx) if err != nil { return "", err @@ -647,7 +647,8 @@ func (fs *eosfs) getEosACL(ctx context.Context, g *provider.Grant) (*acl.Entry, var qualifier string if t == acl.TypeUser { // if the grantee is a lightweight account, we need to set it accordingly - if g.Grantee.GetUserId().Type == userpb.UserType_USER_TYPE_LIGHTWEIGHT { + if g.Grantee.GetUserId().Type == userpb.UserType_USER_TYPE_LIGHTWEIGHT || + g.Grantee.GetUserId().Type == userpb.UserType_USER_TYPE_FEDERATED { t = acl.TypeLightweight qualifier = g.Grantee.GetUserId().OpaqueId } else { @@ -680,7 +681,8 @@ func (fs *eosfs) RemoveGrant(ctx context.Context, ref *provider.Reference, g *pr var recipient string if eosACLType == acl.TypeUser { // if the grantee is a lightweight account, we need to set it accordingly - if g.Grantee.GetUserId().Type == userpb.UserType_USER_TYPE_LIGHTWEIGHT { + if g.Grantee.GetUserId().Type == userpb.UserType_USER_TYPE_LIGHTWEIGHT || + g.Grantee.GetUserId().Type == userpb.UserType_USER_TYPE_FEDERATED { eosACLType = acl.TypeLightweight recipient = g.Grantee.GetUserId().OpaqueId } else { @@ -779,7 +781,8 @@ func (fs *eosfs) GetMD(ctx context.Context, ref *provider.Reference, mdKeys []st } fn := "" - if u.Id.Type == userpb.UserType_USER_TYPE_LIGHTWEIGHT { + if u.Id.Type == userpb.UserType_USER_TYPE_LIGHTWEIGHT || + u.Id.Type == userpb.UserType_USER_TYPE_FEDERATED { p, err := fs.resolve(ctx, ref) if err != nil { return nil, errors.Wrap(err, "eosfs: error resolving reference") @@ -1951,7 +1954,8 @@ func (fs *eosfs) getUserAuth(ctx context.Context, u *userpb.User, fn string) (eo return fs.singleUserAuth, err } - if u.Id.Type == userpb.UserType_USER_TYPE_LIGHTWEIGHT { + if u.Id.Type == userpb.UserType_USER_TYPE_LIGHTWEIGHT || + u.Id.Type == userpb.UserType_USER_TYPE_FEDERATED { return fs.getEOSToken(ctx, u, fn) }