File tree Expand file tree Collapse file tree 7 files changed +70
-0
lines changed Expand file tree Collapse file tree 7 files changed +70
-0
lines changed Original file line number Diff line number Diff line change @@ -87,6 +87,15 @@ admin_role::
8787 +realm_access.roles+.
8888
8989 Example: ROLES/REDMINE/ADMIN
90+ groups_claim::
91+ The claim which provides the set of groups (optional).
92+
93+ Example: +groups+
94+ group_names_pattern::
95+ A regex pattern to filter names of user groups that should be synchronized.
96+ Default is +.*+ (match all).
97+
98+ Example: +^(Red|Blue)$+
9099
91100
92101== Mapping users
Original file line number Diff line number Diff line change @@ -86,16 +86,42 @@ def create_user
8686 user . activate
8787 user . random_password
8888 user . last_login_on = Time . now
89+ update_groups ( user )
8990 user . save ? successful_login ( user ) : unsuccessful_login ( user )
9091 end
9192
9293 def update_user ( user )
9394 user . update ( @oidc_session . user_attributes )
9495 user . activate
9596 user . update_last_login_on!
97+ update_groups ( user )
9698 user . save ? successful_login ( user ) : unsuccessful_login ( user )
9799 end
98100
101+ def update_groups ( user )
102+ return unless settings . update_groups?
103+
104+ current = user . groups . select { |group | settings . group_names_regexp . match? ( group . name ) }
105+
106+ target = @oidc_session . groups . map do |name |
107+ begin
108+ Group . named ( name ) . first_or_create! ( name : name )
109+ rescue ActiveRecord ::RecordInvalid => e
110+ logger . error "Failed to create group #{ name } : #{ e } "
111+ end
112+ end
113+
114+ unless ( added = target - current ) . empty?
115+ logger . info "Adding user #{ user . login } to groups: #{ added . map ( &:name ) . join ( ', ' ) } "
116+ user . groups += added
117+ end
118+
119+ unless ( removed = current - target ) . empty?
120+ logger . info "Removing user #{ user . login } from groups: #{ removed . map ( &:name ) . join ( ', ' ) } "
121+ user . groups -= removed
122+ end
123+ end
124+
99125 def successful_login ( user )
100126 logger . info "Successful authentication for '#{ user . login } ' from #{ request . remote_ip } at #{ Time . now . utc } "
101127 oidc_session = OidcSession . spawn ( session )
@@ -110,4 +136,7 @@ def unsuccessful_login(user)
110136 end
111137 end
112138
139+ def settings
140+ @settings ||= RedmineOidc . settings
141+ end
113142end
Original file line number Diff line number Diff line change @@ -103,6 +103,16 @@ def user_attributes
103103 }
104104 end
105105
106+ def groups
107+ @groups ||= if settings . update_groups?
108+ ( decoded_id_token . raw_attributes [ settings . groups_claim ] || [ ] )
109+ . select { |name | settings . group_names_regexp . match? ( name ) }
110+ . to_set
111+ else
112+ Set . new
113+ end
114+ end
115+
106116 def refresh_token_expiration_timestamp
107117 decoded_refresh_token [ 'exp' ]
108118 end
Original file line number Diff line number Diff line change 3838 <%= label_tag 'settings[admin_role]' , l ( 'oidc.settings.admin_role' ) %>
3939 <%= text_field_tag 'settings[admin_role]' , oidc_settings . admin_role , size : 60 %>
4040</ p >
41+ < p >
42+ <%= label_tag 'settings[groups_claim]' , l ( 'oidc.settings.groups_claim' ) %>
43+ <%= text_field_tag 'settings[groups_claim]' , oidc_settings . groups_claim , size : 60 %>
44+ </ p >
45+ < p >
46+ <%= label_tag 'settings[group_names_pattern]' , l ( 'oidc.settings.group_names_pattern' ) %>
47+ <%= text_field_tag 'settings[group_names_pattern]' , oidc_settings . group_names_pattern , size : 60 %>
48+ </ p >
4149< p >
4250 <%= label_tag 'settings[session_check_enabled]' , l ( 'oidc.settings.session_check_enabled' ) %>
4351 <%= check_box_tag 'settings[session_check_enabled]' , 1 , oidc_settings . session_check_enabled %>
Original file line number Diff line number Diff line change 3434 roles_claim_placeholder : roles
3535 access_roles : Leerzeichen-separierte Liste der autorisierten Rollen
3636 admin_role : Administrationsrolle
37+ groups_claim : Gruppe-Claim (optional)
38+ group_names_pattern : Regex zum Filtern der Namen von Gruppen, die synchronisiert werden sollen
3739 session_check_enabled : Session Check aktivieren
3840 session_check_users_csv : Komma-separierte Liste der Logins mit Session Check (* = alle)
3941 error :
Original file line number Diff line number Diff line change 3434 roles_claim_placeholder : roles
3535 access_roles : Space-separated list of authorized roles
3636 admin_role : Administration role
37+ groups_claim : Groups claim (optional)
38+ group_names_pattern : Regex to filter names of groups that should be synchronized
3739 session_check_enabled : Enable session check
3840 session_check_users_csv : Comma-separated list of logins with session check (* = all)
3941 error :
Original file line number Diff line number Diff line change @@ -31,6 +31,8 @@ class Settings
3131 roles_claim
3232 access_roles
3333 admin_role
34+ groups_claim
35+ group_names_pattern
3436 session_check_enabled
3537 session_check_users_csv
3638 )
@@ -70,6 +72,14 @@ def to_h
7072 serializable_hash
7173 end
7274
75+ def group_names_regexp
76+ @group_names_regexp ||= Regexp . new ( @group_names_pattern || '.*' , Regexp ::IGNORECASE )
77+ end
78+
79+ def update_groups?
80+ !!@groups_claim
81+ end
82+
7383 def session_check_users
7484 @session_check_users ||= @session_check_users_csv . split ( ',' ) . map ( &:strip )
7585 end
You can’t perform that action at this time.
0 commit comments