Added missing legal docs endpoints

Change-Id: I4987ea068941955265c54f00fef29c137a43bea0
Signed-off-by: smarcet <smarcet@gmail.com>
This commit is contained in:
smarcet 2021-01-18 19:13:38 -03:00
parent bd94b62c12
commit 83012ea9bf
13 changed files with 423 additions and 33 deletions

View File

@ -0,0 +1,74 @@
<?php namespace App\Http\Controllers;
/**
* Copyright 2021 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Models\Foundation\Main\Repositories\ILegalDocumentRepository;
use Illuminate\Support\Facades\Log;
use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use models\oauth2\IResourceServerContext;
use ModelSerializers\SerializerRegistry;
use Exception;
/**
* Class OAuth2LegalDocumentsApiController
* @package App\Http\Controllers
*/
final class OAuth2LegalDocumentsApiController extends OAuth2ProtectedController
{
/**
* OAuth2LegalDocumentsApiController constructor.
* @param ILegalDocumentRepository $repository
* @param IResourceServerContext $resource_server_context
*/
public function __construct
(
ILegalDocumentRepository $repository,
IResourceServerContext $resource_server_context
)
{
parent::__construct($resource_server_context);
$this->repository = $repository;
}
/**
* @param $id
* @return \Illuminate\Http\JsonResponse|mixed
*/
public function getById($id){
try{
$document = $this->repository->getBySlug(trim($id));
if(is_null($document))
$document = $this->repository->getById(intval($id));
if(is_null($document)) return $this->error404();
return $this->ok(SerializerRegistry::getInstance()->getSerializer
(
$document
)->serialize());
}
catch (ValidationException $ex1) {
Log::warning($ex1);
return $this->error412(array($ex1->getMessage()));
}
catch(EntityNotFoundException $ex2)
{
Log::warning($ex2);
return $this->error404(array('message'=> $ex2->getMessage()));
}
catch (Exception $ex) {
Log::error($ex);
return $this->error500($ex);
}
}
}

View File

@ -44,6 +44,11 @@ Route::group([
Route::get('', 'OAuth2MembersApiController@getAll');
});
// members
Route::group(['prefix' => 'legal-documents'], function () {
Route::get('{id}', 'OAuth2LegalDocumentsApiController@getById');
});
// speakers
Route::group(['prefix' => 'speakers'], function () {
Route::group(['prefix' => '{speaker_id}'], function () {

View File

@ -0,0 +1,49 @@
<?php namespace ModelSerializers;
/**
* Copyright 2021 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Models\Foundation\Main\Repositories\ILegalDocumentRepository;
use Illuminate\Support\Facades\App;
use models\main\LegalAgreement;
/**
* Class LegalAgreementSerializer
* @package ModelSerializers
*/
final class LegalAgreementSerializer extends SilverStripeSerializer
{
protected static $array_mappings = [
'OwnerId' => 'owner_id:json_int',
'DocumentId' => 'document_id:json_int',
];
public function serialize($expand = null, array $fields = array(), array $relations = array(), array $params = array())
{
$legal_agreement = $this->object;
if (!$legal_agreement instanceof LegalAgreement) return [];
$values = parent::serialize($expand, $fields, $relations, $params);
if (!empty($expand)) {
$exp_expand = explode(',', $expand);
foreach ($exp_expand as $relation) {
switch (trim($relation)) {
case 'document':
{
$document = App::make(ILegalDocumentRepository::class)->getById($values['document_id']);
unset($values['document_id']);
$values['document'] = SerializerRegistry::getInstance()->getSerializer($document)->serialize($expand, [], ['none']);
}
break;
}
}
}
return $values;
}
}

View File

@ -0,0 +1,28 @@
<?php namespace ModelSerializers;
/**
* Copyright 2021 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use Libs\ModelSerializers\AbstractSerializer;
/**
* Class LegalDocumentSerializer
* @package ModelSerializers
*/
final class LegalDocumentSerializer extends AbstractSerializer
{
protected static $array_mappings = [
'Id' => 'id:json_int',
'Title' => 'title:json_string',
'Slug' => 'slug:json_string',
'Content' => 'content:json_string',
];
}

View File

@ -45,6 +45,7 @@ final class OwnMemberSerializer extends AbstractMemberSerializer
'summit_tickets',
'rsvp',
'sponsor_memberships',
'legal_agreements',
];
private static $expand_group_events = [
@ -138,6 +139,13 @@ final class OwnMemberSerializer extends AbstractMemberSerializer
$values['summit_tickets'] = $res;
}
if(in_array('legal_agreements', $relations)){
$res = [];
foreach ($member->getLegalAgreements() as $agreement)
$res[] = intval($agreement->getId());
$values['legal_agreements'] = $res;
}
if (!empty($expand)) {
foreach (explode(',', $expand) as $relation) {
$relation = trim($relation);
@ -223,6 +231,18 @@ final class OwnMemberSerializer extends AbstractMemberSerializer
$values['rsvp'] = $rsvps;
}
break;
case 'legal_agreements':{
if(!in_array('legal_agreements', $relations)) break;
if(is_null($summit)) break;
$res = [];
foreach ($member->getLegalAgreements() as $agreement){
$rsvps[] = SerializerRegistry::getInstance()
->getSerializer($agreement)
->serialize(AbstractSerializer::filterExpandByPrefix($expand, $relation));
}
$values['legal_agreements'] = $res;
}
break;
}
}
}

View File

@ -80,6 +80,7 @@ use App\ModelSerializers\Summit\SummitLocationBannerSerializer;
use App\ModelSerializers\Summit\TrackTagGroups\TrackTagGroupAllowedTagSerializer;
use App\ModelSerializers\Summit\TrackTagGroups\TrackTagGroupSerializer;
use Libs\ModelSerializers\IModelSerializer;
use models\main\LegalDocument;
use models\oauth2\IResourceServerContext;
use ModelSerializers\ChatTeams\ChatTeamInvitationSerializer;
use ModelSerializers\ChatTeams\ChatTeamMemberSerializer;
@ -353,6 +354,9 @@ final class SerializerRegistry
self::SerializerType_Admin => AdminMemberSerializer::class
];
$this->registry['LegalAgreement'] = LegalAgreementSerializer::class;
$this->registry['LegalDocument'] = LegalDocumentSerializer::class;
$this->registry['Group'] = GroupSerializer::class;
$this->registry['Affiliation'] = AffiliationSerializer::class;
$this->registry['Organization'] = OrganizationSerializer::class;

View File

@ -67,11 +67,23 @@ class LegalAgreement extends SilverstripeBaseModel
}
/**
* @param int $document_id
* @return int
*/
public function setDocumentId(int $document_id): void
public function getOwnerId(){
try {
return $this->owner->getId();
}
catch(\Exception $ex){
return 0;
}
}
/**
* @param LegalDocument $document
*/
public function setDocument(LegalDocument $document): void
{
$this->document_id = $document_id;
$this->document_id = $document->getId();
}
/**
@ -90,31 +102,12 @@ class LegalAgreement extends SilverstripeBaseModel
$this->owner = $owner;
}
/**
* this is for legacy reasons
* @param string $slug
* @return int|null
*/
public static function getLegalAgreementIDBySlug(string $slug):?int {
try {
$sql = <<<SQL
select ID FROM SiteTree
where SiteTree.URLSegment = :url_segment AND SiteTree.ClassName = :class_name
SQL;
$stmt = self::prepareRawSQLStatic($sql);
$stmt->execute([
'url_segment' => trim($slug),
'class_name' => "LegalDocumentPage"
]);
$res = $stmt->fetchAll();
if(count($res) == 0 ) return null;
$id = intval($res[0]['ID']);
return $id;
public function getContent():?String{
}
public function getTitle():?string{
} catch (\Exception $ex) {
return null;
}
return null;
}
}

View File

@ -0,0 +1,84 @@
<?php namespace models\main;
/**
* Copyright 2021 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
class LegalDocument
{
/**
* @var int
*/
private $id;
/**
* @var string
*/
private $title;
/**
* @var string
*/
private $slug;
/**
* @var string
*/
private $content;
/**
* LegalDocument constructor.
* @param int $id
* @param string $title
* @param string $slug
* @param string $content
*/
public function __construct(int $id, string $title, string $slug, string $content)
{
$this->id = $id;
$this->title = $title;
$this->slug = $slug;
$this->content = $content;
}
/**
* @return int
*/
public function getId(): int
{
return $this->id;
}
/**
* @return string
*/
public function getTitle(): string
{
return $this->title;
}
/**
* @return string
*/
public function getSlug(): string
{
return $this->slug;
}
/**
* @return string
*/
public function getContent(): string
{
return $this->content;
}
}

View File

@ -1841,16 +1841,13 @@ SQL;
$this->resign_date = new \DateTime('now', new \DateTimeZone(self::DefaultTimeZone));
}
public function signFoundationMembership()
public function signFoundationMembership(LegalDocument $document)
{
if (!$this->isFoundationMember()) {
// Set up member with legal agreement for becoming an OpenStack Foundation Member
$legalAgreement = new LegalAgreement();
$legalAgreement->setOwner($this);
$documentId = LegalAgreement::getLegalAgreementIDBySlug(LegalAgreement::Slug);
if(is_null($documentId))
throw new ValidationException(sprintf("LegalAgreement %s does not exists.", LegalAgreement::Slug));
$legalAgreement->setDocumentId($documentId);
$legalAgreement->setDocument($document);
$this->legal_agreements->add($legalAgreement);
$this->membership_type = self::MembershipTypeFoundation;
$this->resign_date = null;

View File

@ -0,0 +1,32 @@
<?php namespace App\Models\Foundation\Main\Repositories;
/**
* Copyright 2021 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use models\main\LegalDocument;
/**
* Interface ILegalDocumentRepository
* @package App\Models\Foundation\Main\Repositories
*/
interface ILegalDocumentRepository
{
/**
* @param string $slug
* @return LegalDocument|null
*/
public function getBySlug(string $slug):?LegalDocument;
/**
* @param int $id
* @return LegalDocument|null
*/
public function getById(int $id):?LegalDocument;
}

View File

@ -0,0 +1,84 @@
<?php namespace repositories\main;
/**
* Copyright 2021 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Models\Foundation\Main\Repositories\ILegalDocumentRepository;
use LaravelDoctrine\ORM\Facades\Registry;
use models\main\LegalDocument;
use models\utils\SilverstripeBaseModel;
/**
* Class DoctrineLegalDocumentRepository
* @package repositories\main
*/
final class DoctrineLegalDocumentRepository implements ILegalDocumentRepository
{
/**
* @param string $slug
* @return LegalDocument|null
*/
public function getBySlug(string $slug): ?LegalDocument
{
try {
$sql = <<<SQL
select ID,Title,Content,URLSegment FROM SiteTree
where SiteTree.URLSegment = :url_segment AND SiteTree.ClassName = :class_name
SQL;
$stmt = Registry::getManager(SilverstripeBaseModel::EntityManager)->getConnection()->prepare($sql);
$stmt->execute([
'url_segment' => trim($slug),
'class_name' => "LegalDocumentPage"
]);
$res = $stmt->fetchAll();
if(count($res) == 0 ) return null;
new LegalDocument(
$res[0]['ID'],
trim($res[0]['Title']),
trim($res[0]['URLSegment']),
trim($res[0]['Content'])
);
} catch (\Exception $ex) {
return null;
}
return null;
}
/**
* @param int $id
* @return LegalDocument|null
*/
public function getById(int $id): ?LegalDocument
{
try {
$sql = <<<SQL
select ID,Title,Content,URLSegment FROM SiteTree
where SiteTree.ID = :id AND SiteTree.ClassName = :class_name
SQL;
$stmt = Registry::getManager(SilverstripeBaseModel::EntityManager)->getConnection()->prepare($sql);
$stmt->execute([
'id' => $id,
'class_name' => "LegalDocumentPage"
]);
$res = $stmt->fetchAll();
if(count($res) == 0 ) return null;
new LegalDocument(
$res[0]['ID'],
trim($res[0]['Title']),
trim($res[0]['URLSegment']),
trim($res[0]['Content'])
);
} catch (\Exception $ex) {
return null;
}
return null;
}
}

View File

@ -14,6 +14,7 @@
use App\Models\Foundation\Main\Language;
use App\Models\Foundation\Main\Repositories\ILanguageRepository;
use App\Models\Foundation\Main\Repositories\ILegalDocumentRepository;
use App\Models\Foundation\Main\Repositories\IProjectSponsorshipTypeRepository;
use App\Models\Foundation\Main\Repositories\ISponsoredProjectRepository;
use App\Models\Foundation\Main\Repositories\ISummitAdministratorPermissionGroupRepository;
@ -112,6 +113,7 @@ use models\summit\SummitRegistrationPromoCode;
use models\summit\SummitRoomReservation;
use models\summit\SummitTaxType;
use models\summit\SummitTicketType;
use repositories\main\DoctrineLegalDocumentRepository;
/**
* Class RepositoriesProvider
@ -636,5 +638,10 @@ final class RepositoriesProvider extends ServiceProvider
return EntityManager::getRepository(SupportingCompany::class);
}
);
App::singleton(
ILegalDocumentRepository::class,
DoctrineLegalDocumentRepository::class
);
}
}

View File

@ -14,6 +14,7 @@
use App\Events\NewMember;
use App\Models\Foundation\Main\IGroup;
use App\Models\Foundation\Main\Repositories\ILegalDocumentRepository;
use App\Services\Apis\IExternalUserApi;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Log;
@ -26,6 +27,7 @@ use models\main\Group;
use models\main\IGroupRepository;
use models\main\IMemberRepository;
use models\main\IOrganizationRepository;
use models\main\LegalAgreement;
use models\main\Member;
use DateTime;
use models\main\Organization;
@ -77,6 +79,11 @@ final class MemberService
*/
private $speaker_registration_request_repository;
/**
* @var ILegalDocumentRepository
*/
private $legal_document_repository;
/**
* MemberService constructor.
* @param IMemberRepository $member_repository
@ -86,6 +93,7 @@ final class MemberService
* @param ICacheService $cache_service
* @param IExternalUserApi $external_user_api
* @param ISpeakerRegistrationRequestRepository $speaker_registration_request_repository
* @param ILegalDocumentRepository $legal_document_repository
* @param ITransactionService $tx_service
*/
public function __construct
@ -97,6 +105,7 @@ final class MemberService
ICacheService $cache_service,
IExternalUserApi $external_user_api,
ISpeakerRegistrationRequestRepository $speaker_registration_request_repository,
ILegalDocumentRepository $legal_document_repository,
ITransactionService $tx_service
)
{
@ -108,6 +117,7 @@ final class MemberService
$this->cache_service = $cache_service;
$this->external_user_api = $external_user_api;
$this->speaker_registration_request_repository = $speaker_registration_request_repository;
$this->legal_document_repository = $legal_document_repository;
}
/**
@ -507,7 +517,10 @@ final class MemberService
throw new EntityNotFoundException(sprintf("Group %s not found", IGroup::FoundationMembers));
$member->add2Group($group);
$member->signFoundationMembership();
$document = $this->legal_document_repository->getBySlug(LegalAgreement::Slug);
if(is_null($document))
throw new EntityNotFoundException(sprintf("Legal Document %s not found.",LegalAgreement::Slug));
$member->signFoundationMembership($document);
return $member;
});