mirror of
				https://github.com/zitadel/zitadel.git
				synced 2025-11-04 06:38:48 +00:00 
			
		
		
		
	fix: add user info to context for set metadata in actions (#10426)
# Which Problems Are Solved
User information in the context is necessary through the addition of the
resource based API endpoints for user metadata, for the permission
check.
# How the Problems Are Solved
Add user information to the action execution to add metadata to users.
# Additional Changes
None
# Additional Context
Needs to be added to v4 releases, to provide the functionality to add
metadata through actions v1 and actions v2 functions.
Co-authored-by: Marco A. <marco@zitadel.com>
(cherry picked from commit 1579bbc8db)
			
			
This commit is contained in:
		
				
					committed by
					
						
						Livio Spring
					
				
			
			
				
	
			
			
			
						parent
						
							968fc694f9
						
					
				
				
					commit
					bd6d4e35d4
				
			@@ -292,6 +292,8 @@ func (s *Server) userinfoFlows(ctx context.Context, qu *query.OIDCUserInfo, user
 | 
			
		||||
	ctx, span := tracing.NewSpan(ctx)
 | 
			
		||||
	defer func() { span.EndWithError(err) }()
 | 
			
		||||
 | 
			
		||||
	userCtx := authz.SetCtxData(ctx, authz.CtxData{UserID: userInfo.Subject, ResourceOwner: qu.User.ResourceOwner})
 | 
			
		||||
 | 
			
		||||
	queriedActions, err := s.query.GetActiveActionsByFlowAndTriggerType(ctx, domain.FlowTypeCustomiseToken, triggerType, qu.User.ResourceOwner)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
@@ -386,7 +388,7 @@ func (s *Server) userinfoFlows(ctx context.Context, qu *query.OIDCUserInfo, user
 | 
			
		||||
							Key:   key,
 | 
			
		||||
							Value: value,
 | 
			
		||||
						}
 | 
			
		||||
						if _, err = s.command.SetUserMetadata(ctx, metadata, userInfo.Subject, qu.User.ResourceOwner); err != nil {
 | 
			
		||||
						if _, err = s.command.SetUserMetadata(userCtx, metadata, userInfo.Subject, qu.User.ResourceOwner); err != nil {
 | 
			
		||||
							logging.WithError(err).Info("unable to set md in action")
 | 
			
		||||
							panic(err)
 | 
			
		||||
						}
 | 
			
		||||
@@ -451,7 +453,7 @@ func (s *Server) userinfoFlows(ctx context.Context, qu *query.OIDCUserInfo, user
 | 
			
		||||
	}
 | 
			
		||||
	claimLogs := make([]string, 0)
 | 
			
		||||
	for _, metadata := range contextInfoResponse.SetUserMetadata {
 | 
			
		||||
		if _, err = s.command.SetUserMetadata(ctx, metadata, userInfo.Subject, qu.User.ResourceOwner); err != nil {
 | 
			
		||||
		if _, err = s.command.SetUserMetadata(userCtx, metadata, userInfo.Subject, qu.User.ResourceOwner); err != nil {
 | 
			
		||||
			claimLogs = append(claimLogs, fmt.Sprintf("failed to set user metadata key %q", metadata.Key))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -284,6 +284,8 @@ func setUserinfo(user *query.User, userinfo models.AttributeSetter, attributes [
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Storage) getCustomAttributes(ctx context.Context, user *query.User, userGrants *query.UserGrants) (map[string]*customAttribute, error) {
 | 
			
		||||
	userCtx := authz.SetCtxData(ctx, authz.CtxData{UserID: user.ID, ResourceOwner: user.ResourceOwner})
 | 
			
		||||
 | 
			
		||||
	customAttributes := make(map[string]*customAttribute, 0)
 | 
			
		||||
	queriedActions, err := p.query.GetActiveActionsByFlowAndTriggerType(ctx, domain.FlowTypeCustomizeSAMLResponse, domain.TriggerTypePreSAMLResponseCreation, user.ResourceOwner)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -363,7 +365,7 @@ func (p *Storage) getCustomAttributes(ctx context.Context, user *query.User, use
 | 
			
		||||
							Key:   key,
 | 
			
		||||
							Value: value,
 | 
			
		||||
						}
 | 
			
		||||
						if _, err = p.command.SetUserMetadata(ctx, metadata, user.ID, user.ResourceOwner); err != nil {
 | 
			
		||||
						if _, err = p.command.SetUserMetadata(userCtx, metadata, user.ID, user.ResourceOwner); err != nil {
 | 
			
		||||
							logging.WithError(err).Info("unable to set md in action")
 | 
			
		||||
							panic(err)
 | 
			
		||||
						}
 | 
			
		||||
@@ -413,7 +415,7 @@ func (p *Storage) getCustomAttributes(ctx context.Context, user *query.User, use
 | 
			
		||||
	}
 | 
			
		||||
	attributeLogs := make([]string, 0)
 | 
			
		||||
	for _, metadata := range contextInfoResponse.SetUserMetadata {
 | 
			
		||||
		if _, err = p.command.SetUserMetadata(ctx, metadata, user.ID, user.ResourceOwner); err != nil {
 | 
			
		||||
		if _, err = p.command.SetUserMetadata(userCtx, metadata, user.ID, user.ResourceOwner); err != nil {
 | 
			
		||||
			attributeLogs = append(attributeLogs, fmt.Sprintf("failed to set user metadata key %q", metadata.Key))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -510,7 +510,7 @@ func (l *Login) handleExternalUserAuthenticated(
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(externalUser.Metadatas) > 0 {
 | 
			
		||||
		_, err = l.command.BulkSetUserMetadata(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, authReq.UserOrgID, externalUser.Metadatas...)
 | 
			
		||||
		err = l.bulkSetUserMetadata(r.Context(), authReq.UserID, authReq.UserOrgID, externalUser.Metadatas)
 | 
			
		||||
		if err != nil && !userLinked {
 | 
			
		||||
			l.renderError(w, r, authReq, err)
 | 
			
		||||
			return
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								internal/api/ui/login/metadata.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								internal/api/ui/login/metadata.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
package login
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
 | 
			
		||||
	"github.com/zitadel/zitadel/internal/api/authz"
 | 
			
		||||
	"github.com/zitadel/zitadel/internal/domain"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (l *Login) bulkSetUserMetadata(ctx context.Context, userID, orgID string, metadata []*domain.Metadata) error {
 | 
			
		||||
	// user context necessary due to permission check in command
 | 
			
		||||
	userCtx := authz.SetCtxData(ctx, authz.CtxData{UserID: userID, OrgID: orgID})
 | 
			
		||||
	_, err := l.command.BulkSetUserMetadata(userCtx, userID, orgID, metadata...)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
@@ -39,7 +39,7 @@ func (l *Login) handleMFAVerify(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
 | 
			
		||||
		metadata, actionErr := l.runPostInternalAuthenticationActions(authReq, r, authMethodOTP, err)
 | 
			
		||||
		if err == nil && actionErr == nil && len(metadata) > 0 {
 | 
			
		||||
			_, err = l.command.BulkSetUserMetadata(r.Context(), authReq.UserID, authReq.UserOrgID, metadata...)
 | 
			
		||||
			err = l.bulkSetUserMetadata(r.Context(), authReq.UserID, authReq.UserOrgID, metadata)
 | 
			
		||||
		} else if actionErr != nil && err == nil {
 | 
			
		||||
			err = actionErr
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -114,7 +114,7 @@ func (l *Login) handleOTPVerificationCheck(w http.ResponseWriter, r *http.Reques
 | 
			
		||||
 | 
			
		||||
	metadata, actionErr := l.runPostInternalAuthenticationActions(authReq, r, actionType, err)
 | 
			
		||||
	if err == nil && actionErr == nil && len(metadata) > 0 {
 | 
			
		||||
		_, err = l.command.BulkSetUserMetadata(r.Context(), authReq.UserID, authReq.UserOrgID, metadata...)
 | 
			
		||||
		err = l.bulkSetUserMetadata(r.Context(), authReq.UserID, authReq.UserOrgID, metadata)
 | 
			
		||||
	} else if actionErr != nil && err == nil {
 | 
			
		||||
		err = actionErr
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,7 @@ func (l *Login) handleU2FVerification(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
 | 
			
		||||
	metadata, actionErr := l.runPostInternalAuthenticationActions(authReq, r, authMethodU2F, err)
 | 
			
		||||
	if err == nil && actionErr == nil && len(metadata) > 0 {
 | 
			
		||||
		_, err = l.command.BulkSetUserMetadata(r.Context(), authReq.UserID, authReq.UserOrgID, metadata...)
 | 
			
		||||
		err = l.bulkSetUserMetadata(r.Context(), authReq.UserID, authReq.UserOrgID, metadata)
 | 
			
		||||
	} else if actionErr != nil && err == nil {
 | 
			
		||||
		err = actionErr
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ func (l *Login) handlePasswordCheck(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
 | 
			
		||||
	metadata, actionErr := l.runPostInternalAuthenticationActions(authReq, r, authMethodPassword, err)
 | 
			
		||||
	if err == nil && actionErr == nil && len(metadata) > 0 {
 | 
			
		||||
		_, err = l.command.BulkSetUserMetadata(r.Context(), authReq.UserID, authReq.UserOrgID, metadata...)
 | 
			
		||||
		err = l.bulkSetUserMetadata(r.Context(), authReq.UserID, authReq.UserOrgID, metadata)
 | 
			
		||||
	} else if actionErr != nil && err == nil {
 | 
			
		||||
		err = actionErr
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -70,7 +70,7 @@ func (l *Login) handlePasswordlessVerification(w http.ResponseWriter, r *http.Re
 | 
			
		||||
 | 
			
		||||
	metadata, actionErr := l.runPostInternalAuthenticationActions(authReq, r, authMethodPasswordless, err)
 | 
			
		||||
	if err == nil && actionErr == nil && len(metadata) > 0 {
 | 
			
		||||
		_, err = l.command.BulkSetUserMetadata(r.Context(), authReq.UserID, authReq.UserOrgID, metadata...)
 | 
			
		||||
		err = l.bulkSetUserMetadata(r.Context(), authReq.UserID, authReq.UserOrgID, metadata)
 | 
			
		||||
	} else if actionErr != nil && err == nil {
 | 
			
		||||
		err = actionErr
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -600,7 +600,9 @@ func (repo *AuthRequestRepo) AutoRegisterExternalUser(ctx context.Context, regis
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if len(metadatas) > 0 {
 | 
			
		||||
		_, err = repo.Command.BulkSetUserMetadata(ctx, request.UserID, request.UserOrgID, metadatas...)
 | 
			
		||||
		// user context necessary due to permission check in command
 | 
			
		||||
		userCtx := authz.SetCtxData(ctx, authz.CtxData{UserID: request.UserID, OrgID: request.UserOrgID})
 | 
			
		||||
		_, err := repo.Command.BulkSetUserMetadata(userCtx, request.UserID, request.UserOrgID, metadatas...)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user