diff --git a/application/common/models/User.php b/application/common/models/User.php index 3f8c5760..9472d7c7 100644 --- a/application/common/models/User.php +++ b/application/common/models/User.php @@ -641,6 +641,34 @@ public function getNagState() return $this->nagState->getState(); } + public static function listExternalGroups($appPrefix): array + { + /** @var User[] $users */ + $users = User::find()->where( + ['like', 'groups_external', $appPrefix . '-'] + )->all(); + + $responseData = []; + foreach ($users as $user) { + $userIsMatch = false; + $externalGroups = explode(',', $user->groups_external); + $externalGroupsWithAppPrefix = []; + foreach ($externalGroups as $externalGroup) { + if (str_starts_with($externalGroup, $appPrefix . '-')) { + $userIsMatch = true; + $externalGroupsWithAppPrefix[] = $externalGroup; + } + } + if ($userIsMatch) { + $responseData[] = [ + 'email' => $user->email, + 'groups' => $externalGroupsWithAppPrefix, + ]; + } + } + return $responseData; + } + public function loadMfaData(string $rpOrigin = '') { $verifiedMfaOptions = $this->getVerifiedMfaOptions($rpOrigin); diff --git a/application/features/bootstrap/GroupsExternalListContext.php b/application/features/bootstrap/GroupsExternalListContext.php index 0c1f3a38..0caad006 100644 --- a/application/features/bootstrap/GroupsExternalListContext.php +++ b/application/features/bootstrap/GroupsExternalListContext.php @@ -2,8 +2,8 @@ namespace Sil\SilIdBroker\Behat\Context; -use Behat\Behat\Tester\Exception\PendingException; use Behat\Gherkin\Node\TableNode; +use Webmozart\Assert\Assert; class GroupsExternalListContext extends GroupsExternalContext { @@ -35,7 +35,7 @@ public function iGetTheListOfUsersWithExternalGroups($appPrefix) $this->cleanRequestBody(); $urlPath = sprintf( - '/user/external-groups/?app_prefix=%s', + '/user/external-groups?app_prefix=%s', urlencode($appPrefix), ); @@ -43,10 +43,20 @@ public function iGetTheListOfUsersWithExternalGroups($appPrefix) } /** - * @Then the response body should contain only the following entries: + * @Then the response should only include the following users and groups: */ - public function theResponseBodyShouldContainOnlyTheFollowingEntries(TableNode $table) + public function theResponseShouldOnlyIncludeTheFollowingUsersAndGroups(TableNode $table) { - throw new PendingException(); + $expected = []; + foreach ($table as $row) { + $expected[] = [ + 'email' => $row['email'], + 'groups' => explode(',', $row['groups']), + ]; + } + Assert::eq( + json_encode($this->getResponseBody(), JSON_PRETTY_PRINT), + json_encode($expected, JSON_PRETTY_PRINT) + ); } } diff --git a/application/features/groups-external-list.feature b/application/features/groups-external-list.feature index 8a75e9ea..782a9d90 100644 --- a/application/features/groups-external-list.feature +++ b/application/features/groups-external-list.feature @@ -11,7 +11,7 @@ Feature: Getting a list of Users with external groups with a given prefix | bob_mcmanager@example.org | map-america,map-europe | When I get the list of users with "wiki" external groups Then the response status code should be 200 - And the response body should contain only the following entries: + And the response should only include the following users and groups: | email | groups | | john_smith@example.org | wiki-one | | jane_doe@example.org | wiki-one,wiki-two | diff --git a/application/frontend/config/main.php b/application/frontend/config/main.php index f86e6de6..e66ed678 100644 --- a/application/frontend/config/main.php +++ b/application/frontend/config/main.php @@ -48,6 +48,7 @@ 'GET user' => 'user/index', 'GET user/' => 'user/view', 'POST user' => 'user/create', + 'GET user/external-groups' => 'user/list-external-groups', 'PUT user/external-groups/' => 'user/update-external-groups', 'PUT user/' => 'user/update', 'PUT user//password' => 'user/update-password', diff --git a/application/frontend/controllers/UserController.php b/application/frontend/controllers/UserController.php index bf8425d0..4672d4a7 100644 --- a/application/frontend/controllers/UserController.php +++ b/application/frontend/controllers/UserController.php @@ -56,6 +56,17 @@ public function actionCreate(): User return $user; } + public function actionListExternalGroups() + { + $appPrefix = Yii::$app->request->getQueryParam('app_prefix'); + + if (empty($appPrefix)) { + throw new UnprocessableEntityHttpException('No app prefix provided.'); + } + + return User::listExternalGroups($appPrefix); + } + public function actionUpdate(string $employeeId) { $user = User::findOne(['employee_id' => $employeeId]);