Skip to content

Commit

Permalink
feat(proxy): Update selected attributes of autoprovisioned users
Browse files Browse the repository at this point in the history
When autoprovisioning is enabled, we now update autoprovisioned users when their
display name or email address claims change.

Closes: #8955
  • Loading branch information
rhafer committed May 14, 2024
1 parent 601c4ef commit 857fd41
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 0 deletions.
7 changes: 7 additions & 0 deletions changelog/unreleased/autoprovision-update-user.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Enhancement: Update selected attributes of autoprovisioned users

When autoprovisioning is enabled, we now update autoprovisioned users when
their display name or email address claims change.

https://github.com/owncloud/ocis/pull/9166
https://github.com/owncloud/ocis/issues/8955
8 changes: 8 additions & 0 deletions services/proxy/pkg/middleware/account_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ func (m accountResolver) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}

if m.autoProvisionAccounts {
if err = m.userProvider.UpdateUserIfNeeded(req.Context(), user, claims); err != nil {
m.logger.Error().Err(err).Str("userid", user.GetId().GetOpaqueId()).Interface("claims", claims).Msg("Failed to update autoprovisioned user")
w.WriteHeader(http.StatusInternalServerError)
return
}
}

// resolve the user's roles
user, err = m.userRoleAssigner.UpdateUserRoleAssignment(ctx, user, claims)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions services/proxy/pkg/user/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ type UserBackend interface {
GetUserByClaims(ctx context.Context, claim, value string) (*cs3.User, string, error)
Authenticate(ctx context.Context, username string, password string) (*cs3.User, string, error)
CreateUserFromClaims(ctx context.Context, claims map[string]interface{}) (*cs3.User, error)
UpdateUserIfNeeded(ctx context.Context, user *cs3.User, claims map[string]interface{}) error
}
56 changes: 56 additions & 0 deletions services/proxy/pkg/user/backend/cs3.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,62 @@ func (c *cs3backend) CreateUserFromClaims(ctx context.Context, claims map[string
return &cs3UserCreated, nil
}

func (c cs3backend) UpdateUserIfNeeded(ctx context.Context, user *cs3.User, claims map[string]interface{}) error {
newUser, err := c.libregraphUserFromClaims(claims)
if err != nil {
c.logger.Error().Err(err).Interface("claims", claims).Msg("Error converting claims to user")
return fmt.Errorf("error converting claims to updated user: %w", err)
}

// Check if the user needs to be updated, only updates of "displayName" and "mail" are supported
// currently.
switch {
case newUser.GetDisplayName() != user.GetDisplayName():
fallthrough
case newUser.GetMail() != user.GetMail():
return c.updateLibregraphUser(user.GetId().GetOpaqueId(), newUser)
}

return nil
}

func (c cs3backend) updateLibregraphUser(userid string, user libregraph.User) error {
gatewayClient, err := c.gatewaySelector.Next()
if err != nil {
c.logger.Error().Err(err).Msg("could not select next gateway client")
return err
}
newctx := context.Background()
authRes, err := gatewayClient.Authenticate(newctx, &gateway.AuthenticateRequest{
Type: "serviceaccounts",
ClientId: c.serviceAccount.ServiceAccountID,
ClientSecret: c.serviceAccount.ServiceAccountSecret,
})
if err != nil {
return err
}
if authRes.GetStatus().GetCode() != rpcv1beta1.Code_CODE_OK {
return fmt.Errorf("error authenticating service user: %s", authRes.GetStatus().GetMessage())
}

lgClient, err := c.setupLibregraphClient(newctx, authRes.GetToken())
if err != nil {
c.logger.Error().Err(err).Msg("Error setting up libregraph client")
return err
}

req := lgClient.UserApi.UpdateUser(newctx, userid).User(user)

_, resp, err := req.Execute()
defer resp.Body.Close()
if err != nil {
c.logger.Error().Err(err).Msg("Failed to update user via libregraph")
return err
}

return nil
}

func (c cs3backend) setupLibregraphClient(ctx context.Context, cs3token string) (*libregraph.APIClient, error) {
// Use micro registry to resolve next graph service endpoint
next, err := c.graphSelector.Select("com.owncloud.graph.graph")
Expand Down
48 changes: 48 additions & 0 deletions services/proxy/pkg/user/backend/mocks/user_backend.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 857fd41

Please sign in to comment.