Split organisation member management out of the organisation controller into a sub-controller

This commit is contained in:
2022-02-07 12:04:10 +00:00
parent feaf3d5813
commit ae0c884e44
4 changed files with 148 additions and 56 deletions

View File

@@ -0,0 +1,17 @@
<?php
/*
* AVSDev UF Organisations (https://avsdev.uk)
*
* @link https://git.avsdev.uk/avsdev/sprinkle-organisations
* @license https://git.avsdev.uk/avsdev/sprinkle-organisations/blob/master/LICENSE.md (LGPL-3.0 License)
*/
use UserFrosting\Sprinkle\Core\Util\NoCache;
/*
* Routes for administrative organisation member management.
*/
$app->group('/api/organisations/o/{slug}/members', function () {
$this->get('', 'UserFrosting\Sprinkle\Organisations\Controller\OrganisationMembersController:getList');
})->add('authGuard')->add(new NoCache());

View File

@@ -31,9 +31,6 @@ $app->group('/api/organisations', function () {
$this->put('/o/{slug}', 'UserFrosting\Sprinkle\Organisations\Controller\OrganisationController:update'); $this->put('/o/{slug}', 'UserFrosting\Sprinkle\Organisations\Controller\OrganisationController:update');
$this->delete('/o/{slug}', 'UserFrosting\Sprinkle\Organisations\Controller\OrganisationController:delete'); $this->delete('/o/{slug}', 'UserFrosting\Sprinkle\Organisations\Controller\OrganisationController:delete');
$this->get('/o/{slug}/members', 'UserFrosting\Sprinkle\Organisations\Controller\OrganisationController:getMembers');
})->add('authGuard')->add(new NoCache()); })->add('authGuard')->add(new NoCache());
$app->group('/modals/organisations', function () { $app->group('/modals/organisations', function () {

View File

@@ -589,59 +589,7 @@ class OrganisationController extends SimpleController
], ],
]); ]);
} }
/**
* Members List API.
*
* @param Request $request
* @param Response $response
* @param array $args
*
* @throws NotFoundException If organisation is not found
* @throws ForbiddenException If user is not authorized to access page
*/
public function getMembers(Request $request, Response $response, $args)
{
$organisation = $this->getOrganisationFromParams($args);
// If the organisation no longer exists, forward to main organisation listing page
if (!$organisation) {
throw new NotFoundException();
}
// GET parameters
$params = $request->getQueryParams();
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager $authorizer */
$authorizer = $this->ci->authorizer;
/** @var \UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface $currentUser */
$currentUser = $this->ci->currentUser;
// Access-controlled page
if (!$authorizer->checkAccess($currentUser, 'view_organisation_field', [
'organisation' => $organisation,
'property' => 'members',
])) {
throw new ForbiddenException();
}
/** @var \UserFrosting\Sprinkle\Core\Util\ClassMapper $classMapper */
$classMapper = $this->ci->classMapper;
$sprunje = $classMapper->createInstance('user_sprunje', $classMapper, $params);
$sprunje->extendQuery(function ($query) use ($classMapper, $organisation) {
return $query
->join('organisation_members', function($join) use($organisation) {
$join->on('organisation_members.user_id', '=', 'users.id')->where('organisation_id', $organisation->id);
});
});
// Be careful how you consume this data - it has not been escaped and contains untrusted user-supplied content.
// For example, if you plan to insert it into an HTML DOM, you must escape it on the client side (or use client-side templating).
return $sprunje->toResponse($response);
}
/** /**
* Renders a page displaying a organisation's information, in read-only mode. * Renders a page displaying a organisation's information, in read-only mode.

View File

@@ -0,0 +1,130 @@
<?php
/*
* AVSDev UF Organisations (https://avsdev.uk)
*
* @link https://git.avsdev.uk/avsdev/sprinkle-organisations
* @license https://git.avsdev.uk/avsdev/sprinkle-organisations/blob/master/LICENSE.md (LGPL-3.0 License)
*/
namespace UserFrosting\Sprinkle\Organisations\Controller;
use Illuminate\Database\Capsule\Manager as Capsule;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use UserFrosting\Fortress\Adapter\JqueryValidationAdapter;
use UserFrosting\Fortress\RequestDataTransformer;
use UserFrosting\Fortress\RequestSchema;
use UserFrosting\Fortress\ServerSideValidator;
use UserFrosting\Sprinkle\Organisations\Database\Models\Organisation;
use UserFrosting\Sprinkle\Core\Controller\SimpleController;
use UserFrosting\Support\Exception\BadRequestException;
use UserFrosting\Support\Exception\ForbiddenException;
use UserFrosting\Support\Exception\NotFoundException;
/**
* Controller class for organisation member-related requests, including listing members, CRUD for members, etc.
*
* @author Craig Williams (https://avsdev.uk)
*/
class OrganisationMembersController extends SimpleController
{
/**
* Returns a list of organisation members.
*
* Generates a list of organisation members, optionally paginated, sorted and/or filtered.
* This page requires authentication.
*
* Request type: GET
*
* @param Request $request
* @param Response $response
* @param array $args
*
* @throws ForbiddenException If user is not authorized to access page
*/
public function getList(Request $request, Response $response, $args)
{
$organisation = $this->getOrganisationFromParams($args);
// If the organisation no longer exists, forward to main organisation listing page
if (!$organisation) {
throw new NotFoundException();
}
// GET parameters
$params = $request->getQueryParams();
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager $authorizer */
$authorizer = $this->ci->authorizer;
/** @var \UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface $currentUser */
$currentUser = $this->ci->currentUser;
// Access-controlled page
if (!$authorizer->checkAccess($currentUser, 'view_organisation_field', [
'organisation' => $organisation,
'property' => 'members',
])) {
throw new ForbiddenException();
}
/** @var \UserFrosting\Sprinkle\Core\Util\ClassMapper $classMapper */
$classMapper = $this->ci->classMapper;
$sprunje = $classMapper->createInstance('user_sprunje', $classMapper, $params);
$sprunje->extendQuery(function ($query) use ($classMapper, $organisation) {
return $query
->join('organisation_members', function($join) use($organisation) {
$join->on('organisation_members.user_id', '=', 'users.id')->where('organisation_id', $organisation->id);
});
});
// Be careful how you consume this data - it has not been escaped and contains untrusted user-supplied content.
// For example, if you plan to insert it into an HTML DOM, you must escape it on the client side (or use client-side templating).
return $sprunje->toResponse($response);
}
/**
* Get organisation from params.
*
* @param array $params
*
* @throws BadRequestException
*
* @return Organisation
*/
protected function getOrganisationFromParams($params)
{
// Load the request schema
$schema = new RequestSchema('schema://requests/organisation/get-by-slug.yaml');
// Whitelist and set parameter defaults
$transformer = new RequestDataTransformer($schema);
$data = $transformer->transform($params);
// Validate, and throw exception on validation errors.
$validator = new ServerSideValidator($schema, $this->ci->translator);
if (!$validator->validate($data)) {
// TODO: encapsulate the communication of error messages from ServerSideValidator to the BadRequestException
$e = new BadRequestException();
foreach ($validator->errors() as $idx => $field) {
foreach ($field as $eidx => $error) {
$e->addUserMessage($error);
}
}
throw $e;
}
/** @var \UserFrosting\Sprinkle\Core\Util\ClassMapper $classMapper */
$classMapper = $this->ci->classMapper;
// Get the organisation
$organisation = $classMapper->getClassMapping('organisation')::where('slug', $data['slug'])
->first();
return $organisation;
}
}