Skip to content
Snippets Groups Projects
Commit 4b160476 authored by Elmar Ludwig's avatar Elmar Ludwig
Browse files

add implementation for /institutes/{id}/memberships route, fixes #3429

Closes #3429

Merge request studip/studip!2334
parent 279363bc
No related branches found
No related tags found
No related merge requests found
......@@ -253,6 +253,7 @@ class RouteMap
$group->get('/institutes/{id}', Routes\Institutes\InstitutesShow::class);
$group->get('/institutes', Routes\Institutes\InstitutesIndex::class);
$group->get('/institutes/{id}/memberships', Routes\Institutes\InstituteMembershipsIndex::class);
$group->get('/institutes/{id}/status-groups', Routes\Institutes\StatusGroupsOfInstitutes::class);
}
......
......@@ -22,7 +22,7 @@ class InstituteMembershipsShow extends JsonApiController
}
$user = $this->getUser($request);
if ($user->id !== $membership->user_id) {
if ($user->id !== $membership->user_id && !get_visibility_by_id($membership->user_id)) {
throw new AuthorizationFailedException();
}
......
......@@ -2,10 +2,19 @@
namespace JsonApi\Routes\Institutes;
use Institute;
use User;
class Authority
{
/**
* @SuppressWarnings(PHPMD.Superglobals)
*/
public static function canEditInstitute(User $user, Institute $institute)
{
return $GLOBALS['perm']->have_studip_perm('admin', $institute->id, $user->id);
}
/**
* @SuppressWarnings(PHPMD.Superglobals)
*/
......
<?php
namespace JsonApi\Routes\Institutes;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use JsonApi\Errors\AuthorizationFailedException;
use JsonApi\Errors\BadRequestException;
use JsonApi\Errors\RecordNotFoundException;
use JsonApi\JsonApiController;
use JsonApi\Schemas\InstituteMember;
/**
* Returns all institute-memberships of the institute.
*/
class InstituteMembershipsIndex extends JsonApiController
{
protected $allowedFilteringParameters = ['permission'];
protected $allowedIncludePaths = [InstituteMember::REL_INSTITUTE, InstituteMember::REL_USER];
protected $allowedPagingParameters = ['offset', 'limit'];
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameters)
*/
public function __invoke(Request $request, Response $response, $args)
{
$institute = \Institute::find($args['id']);
if (!$institute) {
throw new RecordNotFoundException();
}
$this->validateFilters();
$user = $this->getUser($request);
$memberships = $this->getMemberships($institute, $user, $this->getFilters());
list($offset, $limit) = $this->getOffsetAndLimit();
return $this->getPaginatedContentResponse($memberships->limit($offset, $limit), count($memberships));
}
private function getMemberships(\Institute $institute, \User $user, array $filters)
{
$memberships = $institute->members;
$visibleMemberships = Authority::canEditInstitute($user, $institute)
? $memberships
: $memberships->filter(function ($membership) use ($user) {
return $membership->user_id === $user->id || get_visibility_by_id($membership->user_id);
});
return isset($filters['permission'])
? $visibleMemberships->filter(function ($membership) use ($filters) {
return $membership->inst_perms === $filters['permission'];
})
: $visibleMemberships;
}
private function validateFilters()
{
$filtering = $this->getQueryParameters()->getFilteringParameters() ?? [];
if (array_key_exists('permission', $filtering)) {
if (!in_array($filtering['permission'], ['user', 'autor', 'tutor', 'dozent', 'admin'])) {
throw new BadRequestException('Filter `permission` must be one of `user`, `autor`, `tutor`, `dozent`, `admin`.');
}
}
}
private function getFilters()
{
$filtering = $this->getQueryParameters()->getFilteringParameters() ?? [];
$filters['permission'] = $filtering['permission'] ?? null;
return $filters;
}
}
......@@ -12,6 +12,7 @@ class Institute extends SchemaProvider
const REL_BLUBBER = 'blubber-threads';
const REL_FILES = 'file-refs';
const REL_FOLDERS = 'folders';
const REL_MEMBERSHIPS = 'memberships';
const REL_STATUS_GROUPS = 'status-groups';
public function getId($institute): ?string
......@@ -60,6 +61,12 @@ class Institute extends SchemaProvider
],
];
$relationships[self::REL_MEMBERSHIPS] = [
self::RELATIONSHIP_LINKS => [
Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_MEMBERSHIPS),
],
];
$relationships = $this->addStatusGroupsRelationship(
$relationships,
$resource,
......
<?php
use JsonApi\Routes\Institutes\InstituteMembershipsIndex;
class InstituteMembershipsIndexTest extends \Codeception\Test\Unit
{
/**
* @var \UnitTester
*/
protected $tester;
protected function _before()
{
\DBManager::getInstance()->setConnection('studip', $this->getModule('\\Helper\\StudipDb')->dbh);
}
protected function _after()
{
}
public function testIndexMemberships()
{
$credentials = $this->tester->getCredentialsForTestAutor();
$instituteId = '2560f7c7674942a7dce8eeb238e15d93';
$institute = \Institute::find($instituteId);
$app = $this->tester->createApp($credentials, 'get', '/institutes/{id}/memberships', InstituteMembershipsIndex::class);
$requestBuilder = $this->tester->createRequestBuilder($credentials);
$requestBuilder->setUri('/institutes/'.$instituteId.'/memberships')->fetch();
$response = $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
$this->tester->assertTrue($response->isSuccessfulDocument([200]));
$document = $response->document();
$this->tester->assertTrue($document->isResourceCollectionDocument());
$resources = $document->primaryResources();
$this->tester->assertCount(count($institute->members), $resources);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment