| 
									
										
										
										
											2019-08-07 18:07:21 +08:00
										 |  |  | <?php namespace BookStack\Auth\Access; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | use BookStack\Auth\Role; | 
					
						
							|  |  |  | use BookStack\Auth\User; | 
					
						
							| 
									
										
										
										
											2019-08-07 21:31:10 +08:00
										 |  |  | use Illuminate\Database\Eloquent\Builder; | 
					
						
							| 
									
										
										
										
											2020-08-04 21:55:01 +08:00
										 |  |  | use Illuminate\Support\Collection; | 
					
						
							|  |  |  | use Illuminate\Support\Facades\DB; | 
					
						
							| 
									
										
										
										
											2019-08-07 18:07:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class ExternalAuthService | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Check a role against an array of group names to see if it matches. | 
					
						
							|  |  |  |      * Checked against role 'external_auth_id' if set otherwise the name of the role. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2019-11-16 23:24:09 +08:00
										 |  |  |     protected function roleMatchesGroupNames(Role $role, array $groupNames): bool | 
					
						
							| 
									
										
										
										
											2019-08-07 18:07:21 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         if ($role->external_auth_id) { | 
					
						
							| 
									
										
										
										
											2019-11-16 23:24:09 +08:00
										 |  |  |             return $this->externalIdMatchesGroupNames($role->external_auth_id, $groupNames); | 
					
						
							| 
									
										
										
										
											2019-08-07 18:07:21 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $roleName = str_replace(' ', '-', trim(strtolower($role->display_name))); | 
					
						
							|  |  |  |         return in_array($roleName, $groupNames); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-16 23:24:09 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Check if the given external auth ID string matches one of the given group names. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function externalIdMatchesGroupNames(string $externalId, array $groupNames): bool | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $externalAuthIds = explode(',', strtolower($externalId)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         foreach ($externalAuthIds as $externalAuthId) { | 
					
						
							|  |  |  |             if (in_array(trim($externalAuthId), $groupNames)) { | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-07 18:07:21 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Match an array of group names to BookStack system roles. | 
					
						
							|  |  |  |      * Formats group names to be lower-case and hyphenated. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-08-04 21:55:01 +08:00
										 |  |  |     protected function matchGroupsToSystemsRoles(array $groupNames): Collection | 
					
						
							| 
									
										
										
										
											2019-08-07 18:07:21 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         foreach ($groupNames as $i => $groupName) { | 
					
						
							|  |  |  |             $groupNames[$i] = str_replace(' ', '-', trim(strtolower($groupName))); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-04 21:55:01 +08:00
										 |  |  |         $roles = Role::query()->get(['id', 'external_auth_id', 'display_name']); | 
					
						
							| 
									
										
										
										
											2019-08-07 18:07:21 +08:00
										 |  |  |         $matchedRoles = $roles->filter(function (Role $role) use ($groupNames) { | 
					
						
							|  |  |  |             return $this->roleMatchesGroupNames($role, $groupNames); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $matchedRoles->pluck('id'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Sync the groups to the user roles for the current user | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-02-03 01:31:00 +08:00
										 |  |  |     public function syncWithGroups(User $user, array $userGroups): void | 
					
						
							| 
									
										
										
										
											2019-08-07 18:07:21 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         // Get the ids for the roles from the names
 | 
					
						
							| 
									
										
										
										
											2019-08-07 21:31:10 +08:00
										 |  |  |         $groupsAsRoles = $this->matchGroupsToSystemsRoles($userGroups); | 
					
						
							| 
									
										
										
										
											2019-08-07 18:07:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Sync groups
 | 
					
						
							|  |  |  |         if ($this->config['remove_from_groups']) { | 
					
						
							| 
									
										
										
										
											2019-08-07 21:31:10 +08:00
										 |  |  |             $user->roles()->sync($groupsAsRoles); | 
					
						
							| 
									
										
										
										
											2020-02-03 01:31:00 +08:00
										 |  |  |             $user->attachDefaultRole(); | 
					
						
							| 
									
										
										
										
											2019-08-07 18:07:21 +08:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2019-08-07 21:31:10 +08:00
										 |  |  |             $user->roles()->syncWithoutDetaching($groupsAsRoles); | 
					
						
							| 
									
										
										
										
											2019-08-07 18:07:21 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |