@@ -179,51 +179,60 @@ func (s *Service) OAuthUserCheck(ctx context.Context, userClaims OIDCCLaims) (*e
179179
180180 log .Debug ().Msgf ("OAuth user not found, creating user: %v" , userClaims .PreferredUsername )
181181
182- // Determine role from groups
183- role := utils .UserRole
184- for _ , group := range userClaims .Groups {
185- if strings .HasPrefix (group , "ganymede-" ) {
186- groupRole := strings .TrimPrefix (group , "ganymede-" )
187- if utils .IsValidRole (groupRole ) {
188- log .Debug ().Msgf ("Found Ganymede role in user group %v" , group )
189- role = utils .Role (groupRole )
190- break
191- }
192- }
182+ // Determine role from groups for newly created users.
183+ // If no mapped role is present, default to user.
184+ role , ok := roleFromGroups (userClaims .Groups )
185+ if ! ok {
186+ role = utils .UserRole
193187 }
194188
195- // Create new user
196- if _ , err := s .Store .Client .User .Create ().
189+ createdUser , err := s .Store .Client .User .Create ().
197190 SetSub (userClaims .Sub ).
198191 SetUsername (userClaims .PreferredUsername ).
199192 SetRole (role ).
200193 SetOauth (true ).
201- Save (ctx ); err != nil {
194+ Save (ctx )
195+ if err != nil {
202196 return nil , fmt .Errorf ("failed to create user: %w" , err )
203197 }
204- return user , nil
205- }
206-
207- // Determine role from groups
208- newRole := utils .UserRole
209- for _ , group := range userClaims .Groups {
210- if strings .HasPrefix (group , "ganymede-" ) {
211- groupRole := strings .TrimPrefix (group , "ganymede-" )
212- if utils .IsValidRole (groupRole ) {
213- log .Debug ().Msgf ("Found Ganymede role in user group %v" , group )
214- newRole = utils .Role (groupRole )
215- break
216- }
217- }
198+ return createdUser , nil
218199 }
219200
220- // Update existing user
221- if _ , err := s .Store .Client .User .UpdateOne (user ).
222- SetUsername (userClaims .PreferredUsername ).
223- SetRole (newRole ).
224- Save (ctx ); err != nil {
201+ // Always keep username in sync with OIDC claim.
202+ update := s .Store .Client .User .UpdateOne (user ).SetUsername (userClaims .PreferredUsername )
203+
204+ // Only sync role when provider explicitly sends a ganymede-* or ganymede_* role group.
205+ // This prevents manual role changes from being reset on each login.
206+ if newRole , ok := roleFromGroups (userClaims .Groups ); ok {
207+ update = update .SetRole (newRole )
208+ }
209+
210+ updatedUser , err := update .Save (ctx )
211+ if err != nil {
225212 return nil , fmt .Errorf ("failed to update user: %w" , err )
226213 }
227214
228- return user , nil
215+ return updatedUser , nil
216+ }
217+
218+ func roleFromGroups (groups []string ) (utils.Role , bool ) {
219+ for _ , group := range groups {
220+ var groupRole string
221+ switch {
222+ case strings .HasPrefix (group , "ganymede-" ):
223+ groupRole = strings .TrimPrefix (group , "ganymede-" )
224+ case strings .HasPrefix (group , "ganymede_" ):
225+ groupRole = strings .TrimPrefix (group , "ganymede_" )
226+ default :
227+ continue
228+ }
229+ if ! utils .IsValidRole (groupRole ) {
230+ continue
231+ }
232+
233+ log .Debug ().Msgf ("Found Ganymede role in user group %v" , group )
234+ return utils .Role (groupRole ), true
235+ }
236+
237+ return "" , false
229238}
0 commit comments