Organisation registration process implemented with configurable approval workflow

This commit is contained in:
2022-02-10 13:00:51 +00:00
parent fade1f8441
commit b64b4d72f9
23 changed files with 1453 additions and 7 deletions

View File

@@ -0,0 +1,205 @@
<?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\Repository;
use Carbon\Carbon;
use Illuminate\Database\Capsule\Manager as Capsule;
use UserFrosting\Sprinkle\Organisations\Database\Models\Interfaces\OrganisationInterface;
use UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface;
use UserFrosting\Sprinkle\Account\Repository\TokenRepository;
use UserFrosting\Sprinkle\Core\Database\Models\Model;
use UserFrosting\Sprinkle\Core\Util\ClassMapper;
/**
* Token repository class for new organisation approval.
*
* @author Craig Williams (https://avsdev.uk)
*/
class OrganisationApprovalRepository extends TokenRepository
{
/**
* {@inheritdoc}
*/
protected $modelIdentifier = 'organisation_approval';
/**
* {@inheritdoc}
*/
public function complete($token, UserInterface $approver, $params = [])
{
// Hash the token for the stored version
$hash = hash($this->algorithm, $token);
// Find an unexpired, incomplete token for the specified hash
$model = $this->classMapper->getClassMapping($this->modelIdentifier)::where('hash', $hash)
->where('completed', false)
->where(function($query) {
return $query->where('expires_at', '>', Carbon::now())->orWhereNull('expires_at');
})
->first();
if ($model === null) {
return false;
}
// Fetch user for this token
$organisation = $this->classMapper->getClassMapping('organisation')::find($model->organisation_id);
$requester = $this->classMapper->getClassMapping('user')::find($model->requester_id);
if (!$organisation || !$requester) {
return false;
}
// Begin transaction - DB will be rolled back if an exception occurs
Capsule::transaction(function () use ($model, $organisation, $requester, $approver, $params) {
$this->updateOrganisation($organisation, $requester, $approver, $params);
$model->fill([
'completed' => true,
'completed_at' => Carbon::now(),
]);
$model->approver_id = $approver->id;
$model->save();
});
return $model;
}
/**
* Completes a token request without requiring the token (admin overrride)
*/
public function completeWithoutToken(OrganisationInterface $organisation, UserInterface $approver, $params = [])
{
$model = $this->classMapper->getClassMapping($this->modelIdentifier)::where('organisation_id', $organisation->id)
->where('completed', false)
->first();
if ($model === null) {
return false;
}
// Fetch user for this token
$requester = $this->classMapper->getClassMapping('user')::find($model->requester_id);
if (!$requester) {
return false;
}
// Begin transaction - DB will be rolled back if an exception occurs
Capsule::transaction(function () use ($model, $organisation, $requester, $approver, $params) {
$this->updateOrganisation($organisation, $requester, $approver, $params);
$model->fill([
'completed' => true,
'completed_at' => Carbon::now(),
]);
$model->approver_id = $approver->id;
$model->save();
});
return $model;
}
/**
* {@inheritdoc}
*/
public function create(OrganisationInterface $organisation, UserInterface $requester, $timeout)
{
// Remove any previous tokens for this organisation
$this->removeExisting($organisation);
// Compute expiration time
$expiresAt = Carbon::now()->addSeconds($timeout);
$model = $this->classMapper->createInstance($this->modelIdentifier);
// Generate a random token
$model->setToken($this->generateRandomToken());
// Hash the password reset token for the stored version
$hash = hash($this->algorithm, $model->getToken());
$model->fill([
'hash' => $hash,
'completed' => false,
'expires_at' => ($timeout >= 0 ? $expiresAt : null),
]);
$model->organisation_id = $organisation->id;
$model->requester_id = $requester->id;
$model->save();
return $model;
}
/**
* {@inheritdoc}
*/
public function exists(OrganisationInterface $organisation, UserInterface $requester = null, $token = null)
{
$model = $this->classMapper->getClassMapping($this->modelIdentifier)::where('organisation_id', $organisation->id)
->where('completed', false)
->where(function($query) {
return $query->where('expires_at', '>', Carbon::now())->orWhereNull('expires_at');
});
if ($token) {
// get token hash
$hash = hash($this->algorithm, $token);
$model->where('hash', $hash);
}
if ($requester) {
$model->where('requester_id', $requester->id);
}
return $model->first() ?: false;
}
/**
* {@inheritdoc}
*/
protected function removeExisting(OrganisationInterface $organisation, UserInterface $requester = null)
{
$model = $this->classMapper->getClassMapping($this->modelIdentifier)::where('organisation_id', $organisation->id);
if ($requester) {
$model->where('requester_id', $requester->id);
}
return $model->delete();
}
/**
* {@inheritdoc}
*/
protected function updateOrganisation(OrganisationInterface $organisation, UserInterface $requester, UserInterface $approver, $args)
{
if ($args['approved']) {
$organisation->flag_approved = 1;
$organisation->save();
}
}
/**
* Overridden
*/
protected function updateUser(UserInterface $user, $args)
{
return false;
}
}