@@ -111,6 +111,104 @@ class OAuthClientInformationFull(OAuthClientMetadata):
111
111
auth_manager_config .OAUTH_UPDATE_PICTURE_ON_LOGIN = OAUTH_UPDATE_PICTURE_ON_LOGIN
112
112
113
113
114
+ # PATCH OIDC
115
+ def set_aak_groups (user_data : UserInfo ) -> UserInfo :
116
+ """
117
+ Set AAK groups based on AAK claims. AAK groups need to be parsed from a collection of AAK claims,
118
+ so we cannot rely on Open WebUI's claims mapping. Parses the relevant AAK claims and adds them
119
+ to the "groups" list. This enables us to rely on Open WebUI's role management for user role assignment.
120
+
121
+ To ensure unique group names, they are constructed as "<aak_department_name> (<aak_department_id>)".
122
+
123
+ Example claims:
124
+
125
+ "companyname": [
126
+ "Aarhus Kommune"
127
+ ],
128
+ "division": [
129
+ "Kultur og Borgerservice"
130
+ ],
131
+ "department": [
132
+ "Borgerservice og Biblioteker"
133
+ ],
134
+ "extensionAttribute12": [
135
+ "ITK"
136
+ ],
137
+ "Office": [
138
+ "ITK Development"
139
+ ],
140
+ "extensionAttribute7": [
141
+ "1001;1004;1012;1103;6530"
142
+ ]
143
+
144
+ The ID's for the departments are given sequentially in "extensionAttribute7". Users in management postitions will
145
+ not have five levels of AAK groups. This will show in the length of "extensionAttribute7" but will not show in the
146
+ other claims. In the above example a manager will still have the "Office" claim, but it will repeat the value from
147
+ "extensionAttribute12" and "extensionAttribute7 will only contain "1001;1004;1012;1103"
148
+
149
+ Note: ENABLE_OAUTH_GROUP_MANAGEMENT and ENABLE_OAUTH_GROUP_CREATION must be set to 'true'
150
+
151
+ Args:
152
+ user_data (dict): The decoded OIDC token
153
+
154
+ Returns:
155
+ The decoded OIDC token with the AAK group names added to the "groups" list.
156
+ """
157
+
158
+ log .debug ("Running AAK Group management" )
159
+ log .debug (user_data )
160
+
161
+ user_data ['groups' ] = []
162
+
163
+ dept_ids = user_data .get ("extensionAttribute7" , "" ).split (";" )
164
+ dept_depth = len (dept_ids )
165
+
166
+ if "companyname" in user_data and dept_depth >= 1 :
167
+ user_data ['groups' ].append (user_data .get ("companyname" , "" ) + " (" + dept_ids [0 ] + ")" )
168
+ if "division" in user_data and dept_depth >= 2 :
169
+ user_data ['groups' ].append (user_data .get ("division" , "" ) + " (" + dept_ids [1 ] + ")" )
170
+ if "department" in user_data and dept_depth >= 3 :
171
+ user_data ['groups' ].append (user_data .get ("department" , "" ) + " (" + dept_ids [2 ] + ")" )
172
+ if "extensionAttribute12" in user_data and dept_depth >= 4 :
173
+ user_data ['groups' ].append (user_data .get ("extensionAttribute12" , "" ) + " (" + dept_ids [3 ] + ")" )
174
+ if "Office" in user_data and dept_depth >= 5 :
175
+ user_data ['groups' ].append (user_data .get ("Office" , "" ) + " (" + dept_ids [4 ] + ")" )
176
+
177
+ log .debug (f"Using groups { user_data .get ('groups' , '' )} ." )
178
+
179
+ return user_data
180
+
181
+
182
+ def set_aak_role (user_data : UserInfo ) -> UserInfo :
183
+ """
184
+ Set the AAK role based on AAK claims. For "builders" we cannot map to a native Open WebUI role.
185
+ Instead, we add the role "Builder" to the list of groups.
186
+
187
+ Note: ENABLE_OAUTH_GROUP_MANAGEMENT and ENABLE_OAUTH_GROUP_CREATION must be set to 'true'
188
+
189
+ Args:
190
+ user_data (dict): The decoded OIDC token
191
+
192
+ Returns:
193
+ The decoded OIDC token with the AAK role added to the "groups" list.
194
+ """
195
+
196
+ log .debug ("Running AAK Role management" )
197
+ log .debug (user_data )
198
+
199
+ claims_roles = user_data .get ("role" , "" )
200
+
201
+ log .debug (f"Using aak_claims_role { claims_roles } ." )
202
+
203
+ if "builder" in claims_roles :
204
+ user_data ['groups' ].append ("Builder" )
205
+
206
+ log .debug (f"Using role-groups { user_data .get ('groups' , '' )} ." )
207
+
208
+ return user_data
209
+ # //PATCH OIDC
210
+
211
+
114
212
FERNET = None
115
213
116
214
if len (OAUTH_CLIENT_INFO_ENCRYPTION_KEY ) != 44 :
@@ -146,7 +244,6 @@ def decrypt_data(data: str):
146
244
log .error (f"Error decrypting data: { e } " )
147
245
raise
148
246
149
-
150
247
def is_in_blocked_groups (group_name : str , groups : list ) -> bool :
151
248
"""
152
249
Check if a group name matches any blocked pattern.
@@ -1079,6 +1176,12 @@ async def handle_callback(self, request, provider, response):
1079
1176
log .warning (f"OAuth callback failed, user data is missing: { token } " )
1080
1177
raise HTTPException (400 , detail = ERROR_MESSAGES .INVALID_CRED )
1081
1178
1179
+ # PATCH OIDC
1180
+ # Set AAK role and groups
1181
+ user_data = set_aak_groups (user_data = user_data )
1182
+ user_data = set_aak_role (user_data = user_data )
1183
+ # //PATCH OIDC
1184
+
1082
1185
# Extract the "sub" claim, using custom claim if configured
1083
1186
if auth_manager_config .OAUTH_SUB_CLAIM :
1084
1187
sub = user_data .get (auth_manager_config .OAUTH_SUB_CLAIM )
0 commit comments