mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-05-12 22:39:34 -05:00
proxy: Add an interface for user role assignment
This moves the lookup and the creation of the users' role assignemt out of the user backend into its own interface. This makes the user backend a bit simpler and allows to provide different implemenation for the user role assignment more easily.
This commit is contained in:
committed by
Ralf Haferkamp
parent
490a835a3a
commit
d57d52b33d
@@ -31,6 +31,7 @@ import (
|
||||
proxyHTTP "github.com/owncloud/ocis/v2/services/proxy/pkg/server/http"
|
||||
"github.com/owncloud/ocis/v2/services/proxy/pkg/tracing"
|
||||
"github.com/owncloud/ocis/v2/services/proxy/pkg/user/backend"
|
||||
"github.com/owncloud/ocis/v2/services/proxy/pkg/userroles"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
@@ -149,7 +150,6 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config)
|
||||
|
||||
userProvider = backend.NewCS3UserBackend(
|
||||
backend.WithLogger(logger),
|
||||
backend.WithRoleService(rolesClient),
|
||||
backend.WithRevaAuthenticator(revaClient),
|
||||
backend.WithMachineAuthAPIKey(cfg.MachineAuthAPIKey),
|
||||
backend.WithOIDCissuer(cfg.OIDC.Issuer),
|
||||
@@ -159,6 +159,11 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config)
|
||||
logger.Fatal().Msgf("Invalid accounts backend type '%s'", cfg.AccountBackend)
|
||||
}
|
||||
|
||||
roleAssigner := userroles.NewDefaultRoleAssigner(
|
||||
userroles.WithRoleService(rolesClient),
|
||||
userroles.WithLogger(logger),
|
||||
)
|
||||
|
||||
storeClient := storesvc.NewStoreService("com.owncloud.api.store", grpc.DefaultClient())
|
||||
if err != nil {
|
||||
logger.Error().Err(err).
|
||||
@@ -210,6 +215,7 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config)
|
||||
Logger: logger,
|
||||
PreSignedURLConfig: cfg.PreSignedURL,
|
||||
UserProvider: userProvider,
|
||||
UserRoleAssigner: roleAssigner,
|
||||
Store: storeClient,
|
||||
})
|
||||
|
||||
@@ -236,6 +242,7 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config)
|
||||
middleware.AccountResolver(
|
||||
middleware.Logger(logger),
|
||||
middleware.UserProvider(userProvider),
|
||||
middleware.UserRoleAssigner(roleAssigner),
|
||||
middleware.TokenManagerConfig(*cfg.TokenManager),
|
||||
middleware.UserOIDCClaim(cfg.UserOIDCClaim),
|
||||
middleware.UserCS3Claim(cfg.UserCS3Claim),
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/owncloud/ocis/v2/services/proxy/pkg/user/backend"
|
||||
"github.com/owncloud/ocis/v2/services/proxy/pkg/userroles"
|
||||
|
||||
revactx "github.com/cs3org/reva/v2/pkg/ctx"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/log"
|
||||
@@ -24,6 +25,7 @@ func AccountResolver(optionSetters ...Option) func(next http.Handler) http.Handl
|
||||
userProvider: options.UserProvider,
|
||||
userOIDCClaim: options.UserOIDCClaim,
|
||||
userCS3Claim: options.UserCS3Claim,
|
||||
userRoleAssigner: options.UserRoleAssigner,
|
||||
autoProvisionAccounts: options.AutoprovisionAccounts,
|
||||
}
|
||||
}
|
||||
@@ -33,6 +35,7 @@ type accountResolver struct {
|
||||
next http.Handler
|
||||
logger log.Logger
|
||||
userProvider backend.UserBackend
|
||||
userRoleAssigner userroles.UserRoleAssigner
|
||||
autoProvisionAccounts bool
|
||||
userOIDCClaim string
|
||||
userCS3Claim string
|
||||
@@ -95,7 +98,7 @@ func (m accountResolver) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
|
||||
// resolve the user's roles
|
||||
user, err = m.userProvider.GetUserRoles(ctx, user)
|
||||
user, err = m.userRoleAssigner.UpdateUserRoleAssignment(ctx, user, claims)
|
||||
if err != nil {
|
||||
m.logger.Error().Err(err).Msg("Could not get user roles")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/owncloud/ocis/v2/services/proxy/pkg/config"
|
||||
"github.com/owncloud/ocis/v2/services/proxy/pkg/user/backend"
|
||||
"github.com/owncloud/ocis/v2/services/proxy/pkg/user/backend/mocks"
|
||||
userRoleMocks "github.com/owncloud/ocis/v2/services/proxy/pkg/userroles/mocks"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/test-go/testify/mock"
|
||||
)
|
||||
@@ -124,9 +125,13 @@ func newMockAccountResolver(userBackendResult *userv1beta1.User, userBackendErr
|
||||
ub.On("GetUserByClaims", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(userBackendResult, token, userBackendErr)
|
||||
ub.On("GetUserRoles", mock.Anything, mock.Anything).Return(userBackendResult, nil)
|
||||
|
||||
ra := userRoleMocks.UserRoleAssigner{}
|
||||
ra.On("UpdateUserRoleAssignment", mock.Anything, mock.Anything, mock.Anything).Return(userBackendResult, nil)
|
||||
|
||||
return AccountResolver(
|
||||
Logger(log.NewLogger()),
|
||||
UserProvider(&ub),
|
||||
UserRoleAssigner(&ra),
|
||||
TokenManagerConfig(config.TokenManager{JWTSecret: "secret"}),
|
||||
UserOIDCClaim(oidcclaim),
|
||||
UserCS3Claim(cs3claim),
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/owncloud/ocis/v2/services/proxy/pkg/user/backend"
|
||||
"github.com/owncloud/ocis/v2/services/proxy/pkg/userroles"
|
||||
|
||||
settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
|
||||
storesvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/store/v0"
|
||||
@@ -27,8 +28,10 @@ type Options struct {
|
||||
PolicySelector config.PolicySelector
|
||||
// HTTPClient to use for communication with the oidcAuth provider
|
||||
HTTPClient *http.Client
|
||||
// UP
|
||||
// UserProvider backend to use for resolving User
|
||||
UserProvider backend.UserBackend
|
||||
// UserRoleAssigner to user for assign a users default role
|
||||
UserRoleAssigner userroles.UserRoleAssigner
|
||||
// SettingsRoleService for the roles API in settings
|
||||
SettingsRoleService settingssvc.RoleService
|
||||
// OIDCProviderFunc to lazily initialize an oidc provider, must be set for the oidc_auth middleware
|
||||
@@ -202,6 +205,13 @@ func UserProvider(up backend.UserBackend) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// UserRoleAssigner sets the mechanism for assigning the default user roles
|
||||
func UserRoleAssigner(ra userroles.UserRoleAssigner) Option {
|
||||
return func(o *Options) {
|
||||
o.UserRoleAssigner = ra
|
||||
}
|
||||
}
|
||||
|
||||
// AccessTokenVerifyMethod set the mechanism for access token verification
|
||||
func AccessTokenVerifyMethod(method string) Option {
|
||||
return func(o *Options) {
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
storesvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/store/v0"
|
||||
"github.com/owncloud/ocis/v2/services/proxy/pkg/config"
|
||||
"github.com/owncloud/ocis/v2/services/proxy/pkg/user/backend"
|
||||
"github.com/owncloud/ocis/v2/services/proxy/pkg/userroles"
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
)
|
||||
|
||||
@@ -43,6 +44,7 @@ type SignedURLAuthenticator struct {
|
||||
Logger log.Logger
|
||||
PreSignedURLConfig config.PreSignedURL
|
||||
UserProvider backend.UserBackend
|
||||
UserRoleAssigner userroles.UserRoleAssigner
|
||||
Store storesvc.StoreService
|
||||
}
|
||||
|
||||
@@ -202,7 +204,7 @@ func (m SignedURLAuthenticator) Authenticate(r *http.Request) (*http.Request, bo
|
||||
return nil, false
|
||||
}
|
||||
|
||||
user, err = m.UserProvider.GetUserRoles(r.Context(), user)
|
||||
user, err = m.UserRoleAssigner.ApplyUserRole(r.Context(), user)
|
||||
if err != nil {
|
||||
m.Logger.Error().
|
||||
Err(err).
|
||||
|
||||
@@ -2,13 +2,10 @@ package backend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
||||
cs3 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
@@ -26,7 +23,6 @@ var (
|
||||
// UserBackend allows the proxy to retrieve users from different user-backends (accounts-service, CS3)
|
||||
type UserBackend interface {
|
||||
GetUserByClaims(ctx context.Context, claim, value string) (*cs3.User, string, error)
|
||||
GetUserRoles(ctx context.Context, user *cs3.User) (*cs3.User, error)
|
||||
Authenticate(ctx context.Context, username string, password string) (*cs3.User, string, error)
|
||||
CreateUserFromClaims(ctx context.Context, claims map[string]interface{}) (*cs3.User, error)
|
||||
}
|
||||
@@ -35,34 +31,3 @@ type UserBackend interface {
|
||||
type RevaAuthenticator interface {
|
||||
Authenticate(ctx context.Context, in *gateway.AuthenticateRequest, opts ...grpc.CallOption) (*gateway.AuthenticateResponse, error)
|
||||
}
|
||||
|
||||
// loadRolesIDs returns the role-ids assigned to an user
|
||||
func loadRolesIDs(ctx context.Context, opaqueUserID string, rs settingssvc.RoleService) ([]string, error) {
|
||||
req := &settingssvc.ListRoleAssignmentsRequest{AccountUuid: opaqueUserID}
|
||||
assignmentResponse, err := rs.ListRoleAssignments(ctx, req)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
roleIDs := make([]string, 0)
|
||||
|
||||
for _, assignment := range assignmentResponse.Assignments {
|
||||
roleIDs = append(roleIDs, assignment.RoleId)
|
||||
}
|
||||
|
||||
return roleIDs, nil
|
||||
}
|
||||
|
||||
// encodeRoleIDs encoded the given role id's in to reva-specific format to be able to mint a token from them
|
||||
func encodeRoleIDs(roleIDs []string) (*types.OpaqueEntry, error) {
|
||||
roleIDsJSON, err := json.Marshal(roleIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.OpaqueEntry{
|
||||
Decoder: "json",
|
||||
Value: roleIDsJSON,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -16,13 +16,10 @@ import (
|
||||
"github.com/cs3org/reva/v2/pkg/token"
|
||||
libregraph "github.com/owncloud/libre-graph-api-go"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/log"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/middleware"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/oidc"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/registry"
|
||||
settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
|
||||
"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
|
||||
settingsService "github.com/owncloud/ocis/v2/services/settings/pkg/service/v0"
|
||||
"go-micro.dev/v4/metadata"
|
||||
"go-micro.dev/v4/selector"
|
||||
)
|
||||
|
||||
@@ -38,7 +35,6 @@ type Option func(o *Options)
|
||||
type Options struct {
|
||||
logger log.Logger
|
||||
tokenManager token.Manager
|
||||
roleService settingssvc.RoleService
|
||||
authProvider RevaAuthenticator
|
||||
machineAuthAPIKey string
|
||||
oidcISS string
|
||||
@@ -56,12 +52,6 @@ func WithTokenManager(t token.Manager) Option {
|
||||
}
|
||||
}
|
||||
|
||||
func WithRoleService(rs settingssvc.RoleService) Option {
|
||||
return func(o *Options) {
|
||||
o.roleService = rs
|
||||
}
|
||||
}
|
||||
|
||||
func WithRevaAuthenticator(ra RevaAuthenticator) Option {
|
||||
return func(o *Options) {
|
||||
o.authProvider = ra
|
||||
@@ -120,54 +110,6 @@ func (c *cs3backend) GetUserByClaims(ctx context.Context, claim, value string) (
|
||||
return user, res.Token, nil
|
||||
}
|
||||
|
||||
func (c *cs3backend) GetUserRoles(ctx context.Context, user *cs3.User) (*cs3.User, error) {
|
||||
var roleIDs []string
|
||||
if user.Id.Type != cs3.UserType_USER_TYPE_LIGHTWEIGHT {
|
||||
var err error
|
||||
roleIDs, err = loadRolesIDs(ctx, user.Id.OpaqueId, c.roleService)
|
||||
if err != nil {
|
||||
c.logger.Error().Err(err).Msgf("Could not load roles")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(roleIDs) == 0 {
|
||||
// This user doesn't have a role assignment yet. Assign a
|
||||
// default user role. At least until proper roles are provided. See
|
||||
// https://github.com/owncloud/ocis/v2/issues/1825 for more context.
|
||||
if user.Id.Type == cs3.UserType_USER_TYPE_PRIMARY {
|
||||
c.logger.Info().Str("userid", user.Id.OpaqueId).Msg("user has no role assigned, assigning default user role")
|
||||
ctx = metadata.Set(ctx, middleware.AccountID, user.Id.OpaqueId)
|
||||
_, err := c.roleService.AssignRoleToUser(ctx, &settingssvc.AssignRoleToUserRequest{
|
||||
AccountUuid: user.Id.OpaqueId,
|
||||
RoleId: settingsService.BundleUUIDRoleUser,
|
||||
})
|
||||
if err != nil {
|
||||
c.logger.Error().Err(err).Msg("Could not add default role")
|
||||
return nil, err
|
||||
}
|
||||
roleIDs = append(roleIDs, settingsService.BundleUUIDRoleUser)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enc, err := encodeRoleIDs(roleIDs)
|
||||
if err != nil {
|
||||
c.logger.Error().Err(err).Msg("Could not encode loaded roles")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if user.Opaque == nil {
|
||||
user.Opaque = &types.Opaque{
|
||||
Map: map[string]*types.OpaqueEntry{
|
||||
"roles": enc,
|
||||
},
|
||||
}
|
||||
} else {
|
||||
user.Opaque.Map["roles"] = enc
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (c *cs3backend) Authenticate(ctx context.Context, username string, password string) (*cs3.User, string, error) {
|
||||
res, err := c.authProvider.Authenticate(ctx, &gateway.AuthenticateRequest{
|
||||
Type: "basic",
|
||||
@@ -329,7 +271,7 @@ func (c cs3backend) cs3UserFromLibregraph(ctx context.Context, lu *libregraph.Us
|
||||
// the Graph API. This user is needed for autoprovisioning of users from incoming OIDC
|
||||
// claims.
|
||||
func getAutoProvisionUserCreator() (*cs3.User, error) {
|
||||
encRoleID, err := encodeRoleIDs([]string{settingsService.BundleUUIDRoleAdmin})
|
||||
roleIDsJSON, err := json.Marshal([]string{settingsService.BundleUUIDRoleAdmin})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -343,7 +285,10 @@ func getAutoProvisionUserCreator() (*cs3.User, error) {
|
||||
},
|
||||
Opaque: &types.Opaque{
|
||||
Map: map[string]*types.OpaqueEntry{
|
||||
"roles": encRoleID,
|
||||
"roles": &types.OpaqueEntry{
|
||||
Decoder: "json",
|
||||
Value: roleIDsJSON,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -97,29 +97,6 @@ func (_m *UserBackend) GetUserByClaims(ctx context.Context, claim string, value
|
||||
return r0, r1, r2
|
||||
}
|
||||
|
||||
// GetUserRoles provides a mock function with given fields: ctx, user
|
||||
func (_m *UserBackend) GetUserRoles(ctx context.Context, user *userv1beta1.User) (*userv1beta1.User, error) {
|
||||
ret := _m.Called(ctx, user)
|
||||
|
||||
var r0 *userv1beta1.User
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *userv1beta1.User) *userv1beta1.User); ok {
|
||||
r0 = rf(ctx, user)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*userv1beta1.User)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *userv1beta1.User) error); ok {
|
||||
r1 = rf(ctx, user)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
type mockConstructorTestingTNewUserBackend interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
package userroles
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
cs3 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
"github.com/cs3org/reva/v2/pkg/utils"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/middleware"
|
||||
settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
|
||||
settingsService "github.com/owncloud/ocis/v2/services/settings/pkg/service/v0"
|
||||
"go-micro.dev/v4/metadata"
|
||||
)
|
||||
|
||||
type defaultRoleAssigner struct {
|
||||
Options
|
||||
}
|
||||
|
||||
// NewDefaultRoleAssigner returns an implemenation of the UserRoleAssigner interface
|
||||
func NewDefaultRoleAssigner(opts ...Option) UserRoleAssigner {
|
||||
opt := Options{}
|
||||
for _, o := range opts {
|
||||
o(&opt)
|
||||
}
|
||||
|
||||
return defaultRoleAssigner{
|
||||
Options: opt,
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateUserRoleAssignment assigns the role "User" to the supplied user. Unless the user
|
||||
// already has a different role assigned.
|
||||
func (d defaultRoleAssigner) UpdateUserRoleAssignment(ctx context.Context, user *cs3.User, claims map[string]interface{}) (*cs3.User, error) {
|
||||
var roleIDs []string
|
||||
if user.Id.Type != cs3.UserType_USER_TYPE_LIGHTWEIGHT {
|
||||
var err error
|
||||
roleIDs, err = loadRolesIDs(ctx, user.Id.OpaqueId, d.roleService)
|
||||
if err != nil {
|
||||
d.logger.Error().Err(err).Msgf("Could not load roles")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(roleIDs) == 0 {
|
||||
// This user doesn't have a role assignment yet. Assign a
|
||||
// default user role. At least until proper roles are provided. See
|
||||
// https://github.com/owncloud/ocis/v2/issues/1825 for more context.
|
||||
if user.Id.Type == cs3.UserType_USER_TYPE_PRIMARY {
|
||||
d.logger.Info().Str("userid", user.Id.OpaqueId).Msg("user has no role assigned, assigning default user role")
|
||||
ctx = metadata.Set(ctx, middleware.AccountID, user.Id.OpaqueId)
|
||||
_, err := d.roleService.AssignRoleToUser(ctx, &settingssvc.AssignRoleToUserRequest{
|
||||
AccountUuid: user.Id.OpaqueId,
|
||||
RoleId: settingsService.BundleUUIDRoleUser,
|
||||
})
|
||||
if err != nil {
|
||||
d.logger.Error().Err(err).Msg("Could not add default role")
|
||||
return nil, err
|
||||
}
|
||||
roleIDs = append(roleIDs, settingsService.BundleUUIDRoleUser)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
user.Opaque = utils.AppendJSONToOpaque(user.Opaque, "roles", roleIDs)
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// ApplyUserRole it looks up the user's role in the settings service and adds it
|
||||
// user's opaque data
|
||||
func (d defaultRoleAssigner) ApplyUserRole(ctx context.Context, user *cs3.User) (*cs3.User, error) {
|
||||
roleIDs, err := loadRolesIDs(ctx, user.Id.OpaqueId, d.roleService)
|
||||
if err != nil {
|
||||
d.logger.Error().Err(err).Msgf("Could not load roles")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
user.Opaque = utils.AppendJSONToOpaque(user.Opaque, "roles", roleIDs)
|
||||
return user, nil
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// Code generated by mockery v2.14.0. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
)
|
||||
|
||||
// UserRoleAssigner is an autogenerated mock type for the UserRoleAssigner type
|
||||
type UserRoleAssigner struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// ApplyUserRole provides a mock function with given fields: ctx, user
|
||||
func (_m *UserRoleAssigner) ApplyUserRole(ctx context.Context, user *userv1beta1.User) (*userv1beta1.User, error) {
|
||||
ret := _m.Called(ctx, user)
|
||||
|
||||
var r0 *userv1beta1.User
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *userv1beta1.User) *userv1beta1.User); ok {
|
||||
r0 = rf(ctx, user)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*userv1beta1.User)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *userv1beta1.User) error); ok {
|
||||
r1 = rf(ctx, user)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// UpdateUserRoleAssignment provides a mock function with given fields: ctx, user, claims
|
||||
func (_m *UserRoleAssigner) UpdateUserRoleAssignment(ctx context.Context, user *userv1beta1.User, claims map[string]interface{}) (*userv1beta1.User, error) {
|
||||
ret := _m.Called(ctx, user, claims)
|
||||
|
||||
var r0 *userv1beta1.User
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *userv1beta1.User, map[string]interface{}) *userv1beta1.User); ok {
|
||||
r0 = rf(ctx, user, claims)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*userv1beta1.User)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *userv1beta1.User, map[string]interface{}) error); ok {
|
||||
r1 = rf(ctx, user, claims)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
type mockConstructorTestingTNewUserRoleAssigner interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
// NewUserRoleAssigner creates a new instance of UserRoleAssigner. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewUserRoleAssigner(t mockConstructorTestingTNewUserRoleAssigner) *UserRoleAssigner {
|
||||
mock := &UserRoleAssigner{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package userroles
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
cs3 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/log"
|
||||
settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
|
||||
)
|
||||
|
||||
//go:generate mockery --name=UserRoleAssigner
|
||||
|
||||
// UserRoleAssigner allows to provide different implemenation for how users get their default roles
|
||||
// assigned by the proxy during authentication
|
||||
type UserRoleAssigner interface {
|
||||
// UpdateUserRoleAssignment is called by the account resolver middleware. It updates the user's role assignment
|
||||
// based on the user's (OIDC) claims. It adds the user's roles to the opaque data of the cs3.User struct
|
||||
UpdateUserRoleAssignment(ctx context.Context, user *cs3.User, claims map[string]interface{}) (*cs3.User, error)
|
||||
// ApplyUserRole can be called by proxy middlewares, it looks up the user's roles and adds them
|
||||
// the users "roles" key in the user's opaque data
|
||||
ApplyUserRole(ctx context.Context, user *cs3.User) (*cs3.User, error)
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
roleService settingssvc.RoleService
|
||||
rolesClaim string
|
||||
logger log.Logger
|
||||
}
|
||||
|
||||
type Option func(o *Options)
|
||||
|
||||
func WithLogger(l log.Logger) Option {
|
||||
return func(o *Options) {
|
||||
o.logger = l
|
||||
}
|
||||
}
|
||||
|
||||
func WithRoleService(rs settingssvc.RoleService) Option {
|
||||
return func(o *Options) {
|
||||
o.roleService = rs
|
||||
}
|
||||
}
|
||||
|
||||
// loadRolesIDs returns the role-ids assigned to an user
|
||||
func loadRolesIDs(ctx context.Context, opaqueUserID string, rs settingssvc.RoleService) ([]string, error) {
|
||||
req := &settingssvc.ListRoleAssignmentsRequest{AccountUuid: opaqueUserID}
|
||||
assignmentResponse, err := rs.ListRoleAssignments(ctx, req)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
roleIDs := make([]string, 0)
|
||||
|
||||
for _, assignment := range assignmentResponse.Assignments {
|
||||
roleIDs = append(roleIDs, assignment.RoleId)
|
||||
}
|
||||
|
||||
return roleIDs, nil
|
||||
}
|
||||
Reference in New Issue
Block a user