From 8d762c5dca0781d29f8af8667525dc9cbec17538 Mon Sep 17 00:00:00 2001 From: Craig Williams Date: Tue, 15 Feb 2022 16:36:54 +0000 Subject: [PATCH] Created a membership approval token repository and required token table & model --- .../OrganisationMembershipApprovalsTable.php | 61 +++++++++ ...teOrganisationMembershipApprovalsTable.php | 64 +++++++++ .../Models/OrganisationMembershipApproval.php | 128 ++++++++++++++++++ ...ganisationMembershipApprovalRepository.php | 53 ++++++++ src/ServicesProvider/ServicesProvider.php | 16 +++ 5 files changed, 322 insertions(+) create mode 100644 src/Database/Migrations/v001/OrganisationMembershipApprovalsTable.php create mode 100644 src/Database/Migrations/v002/UpdateOrganisationMembershipApprovalsTable.php create mode 100644 src/Database/Models/OrganisationMembershipApproval.php create mode 100644 src/Repository/OrganisationMembershipApprovalRepository.php diff --git a/src/Database/Migrations/v001/OrganisationMembershipApprovalsTable.php b/src/Database/Migrations/v001/OrganisationMembershipApprovalsTable.php new file mode 100644 index 0000000..74527c2 --- /dev/null +++ b/src/Database/Migrations/v001/OrganisationMembershipApprovalsTable.php @@ -0,0 +1,61 @@ +schema->hasTable('organisation_membership_approvals')) { + $this->schema->create('organisation_membership_approvals', function (Blueprint $table) { + $table->increments('id'); + $table->integer('requester_id')->unsigned(); + $table->integer('organisation_id')->unsigned(); + $table->string('hash'); + $table->boolean('completed')->default(0); + $table->timestamp('expires_at')->nullable(); + $table->timestamp('completed_at')->nullable(); + $table->integer('approver_id')->unsigned()->nullable(); + $table->timestamps(); + + $table->engine = 'InnoDB'; + $table->collation = 'utf8_unicode_ci'; + $table->charset = 'utf8'; + $table->foreign('requester_id')->references('id')->on('users'); + $table->foreign('approver_id')->references('id')->on('users'); + $table->foreign('organisation_id')->references('id')->on('organisations'); + $table->index('requester_id'); + $table->index('approver_id'); + $table->index('hash'); + }); + } + } + + /** + * {@inheritdoc} + */ + public function down() + { + $this->schema->drop('organisation_membership_approvals'); + } +} diff --git a/src/Database/Migrations/v002/UpdateOrganisationMembershipApprovalsTable.php b/src/Database/Migrations/v002/UpdateOrganisationMembershipApprovalsTable.php new file mode 100644 index 0000000..c298487 --- /dev/null +++ b/src/Database/Migrations/v002/UpdateOrganisationMembershipApprovalsTable.php @@ -0,0 +1,64 @@ +schema->hasTable('organisation_membership_approvals')) { + DB::table('organisation_membership_approvals')->delete(); + $this->schema->table('organisation_membership_approvals', function (Blueprint $table) { + $table->dropForeign(['requester_id']); + $table->dropForeign(['organisation_id']); + $table->dropIndex(['requester_id']); + $table->dropColumn(['requester_id']); + $table->dropColumn(['organisation_id']); + + $table->integer('owner_id')->unsigned(); + $table->index('owner_id'); + }); + } + } + + /** + * {@inheritdoc} + */ + public function down() + { + if ($this->schema->hasTable('organisation_membership_approvals')) { + DB::table('organisation_membership_approvals')->delete(); + $this->schema->table('organisation_membership_approvals', function (Blueprint $table) { + $table->dropIndex(['owner_id']); + $table->dropColumn('owner_id')->unsigned(); + + $table->integer('requester_id')->unsigned(); + $table->integer('organisation_id')->unsigned(); + $table->index('requester_id'); + $table->foreign('requester_id')->references('id')->on('users'); + $table->foreign('organisation_id')->references('id')->on('organisations'); + }); + } + } +} diff --git a/src/Database/Models/OrganisationMembershipApproval.php b/src/Database/Models/OrganisationMembershipApproval.php new file mode 100644 index 0000000..f3f099c --- /dev/null +++ b/src/Database/Models/OrganisationMembershipApproval.php @@ -0,0 +1,128 @@ +token; + } + + /** + * @param string $value + * + * @return self + */ + public function setToken($value) + { + $this->token = $value; + + return $this; + } + + + + /** + * Get the owner. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function owner() + { + /** @var \UserFrosting\Sprinkle\Core\Util\ClassMapper $classMapper */ + $classMapper = static::$ci->classMapper; + + return $this->belongsTo($classMapper->getClassMapping('organisation_member'), 'map_id'); + } + + /** + * Get the organisation of this approval. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function organisation() + { + return $this->owner()->organisation(); + } + + /** + * Get the requester of this approval. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function requester() + { + return $this->owner()->user(); + } + + /** + * Get the user associated with this approval or denial of this request. + * + * @return \Illuminate\Database\Eloquent\Relations\belongsTo + */ + public function approver() + { + /** @var \UserFrosting\Sprinkle\Core\Util\ClassMapper $classMapper */ + $classMapper = static::$ci->classMapper; + + return $this->belongsTo($classMapper->getClassMapping('user'), 'approver_id'); + } +} diff --git a/src/Repository/OrganisationMembershipApprovalRepository.php b/src/Repository/OrganisationMembershipApprovalRepository.php new file mode 100644 index 0000000..e512131 --- /dev/null +++ b/src/Repository/OrganisationMembershipApprovalRepository.php @@ -0,0 +1,53 @@ +classMapper->getClassMapping('organisation_member')::findUnique($owner_id, 'map_id', false); + + if (!$memberMap) { + return false; + } + + // If specified, recored the approver. This assumes the model has an approver_id field which it may not... + if ($args['approver_id']) { + $model->approver_id = $args['approver_id']; + } + + if ($args['approved']) { + // Mark the request as approved + $memberMap->flag_approved = true; + $memberMap->save(); + } else { + // Delete the request + $memberMap->delete(); + } + + return true; + } +} diff --git a/src/ServicesProvider/ServicesProvider.php b/src/ServicesProvider/ServicesProvider.php index c90d15e..63e966c 100644 --- a/src/ServicesProvider/ServicesProvider.php +++ b/src/ServicesProvider/ServicesProvider.php @@ -20,6 +20,7 @@ use UserFrosting\Sprinkle\Core\Log\MixedFormatter; use UserFrosting\Sprinkle\Organisations\Database\Models\Interfaces\OrganisationInterface; use UserFrosting\Sprinkle\Organisations\Twig\OrganisationsExtension; use UserFrosting\Sprinkle\Organisations\Repository\OrganisationApprovalRepository; +use UserFrosting\Sprinkle\Organisations\Repository\OrganisationMembershipApprovalRepository; use UserFrosting\Sprinkle\Organisations\Authorize\AuthorizationManager; @@ -49,6 +50,7 @@ class ServicesProvider $classMapper->setClassMapping('organisation_approval', 'UserFrosting\Sprinkle\Organisations\Database\Models\OrganisationApproval'); $classMapper->setClassMapping('organisation_sprunje', 'UserFrosting\Sprinkle\Organisations\Sprunje\OrganisationSprunje'); $classMapper->setClassMapping('organisation_member', 'UserFrosting\Sprinkle\Organisations\Database\Models\OrganisationMember'); + $classMapper->setClassMapping('organisation_membership_approval', 'UserFrosting\Sprinkle\Organisations\Database\Models\OrganisationMembershipApproval'); $classMapper->setClassMapping('user', 'UserFrosting\Sprinkle\Organisations\Database\Models\User'); $classMapper->setClassMapping('user_sprunje', 'UserFrosting\Sprinkle\Organisations\Sprunje\UserSprunje'); @@ -181,5 +183,19 @@ class ServicesProvider return $repo; }; + + /* + * Repository for membership approval requests. + * + * @return \UserFrosting\Sprinkle\Organisations\Repository\OrganisationMembershipApprovalRepository + */ + $container['repoOrganisationMembershipApproval'] = function ($c) { + $classMapper = $c->classMapper; + $config = $c->config; + + $repo = new OrganisationMembershipApprovalRepository($classMapper, $config['verification.algorithm'], $c['tokenLogger'], $config['debug.tokens']); + + return $repo; + }; } }