@@ -111,6 +111,104 @@ class OAuthClientInformationFull(OAuthClientMetadata):
111111auth_manager_config .OAUTH_UPDATE_PICTURE_ON_LOGIN = OAUTH_UPDATE_PICTURE_ON_LOGIN
112112
113113
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+
114212FERNET = None
115213
116214if len (OAUTH_CLIENT_INFO_ENCRYPTION_KEY ) != 44 :
@@ -146,7 +244,6 @@ def decrypt_data(data: str):
146244 log .error (f"Error decrypting data: { e } " )
147245 raise
148246
149-
150247def is_in_blocked_groups (group_name : str , groups : list ) -> bool :
151248 """
152249 Check if a group name matches any blocked pattern.
@@ -1079,6 +1176,12 @@ async def handle_callback(self, request, provider, response):
10791176 log .warning (f"OAuth callback failed, user data is missing: { token } " )
10801177 raise HTTPException (400 , detail = ERROR_MESSAGES .INVALID_CRED )
10811178
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+
10821185 # Extract the "sub" claim, using custom claim if configured
10831186 if auth_manager_config .OAUTH_SUB_CLAIM :
10841187 sub = user_data .get (auth_manager_config .OAUTH_SUB_CLAIM )
0 commit comments