added new endpoint ADD Organization

POST /api/v1/organizations

payload

Change-Id: I713fcb70f380693b8b20a21a569064a0b3c3ed84
name: required|string|max:255
This commit is contained in:
Sebastian Marcet 2018-09-04 12:30:28 -03:00
parent d395d6e3f9
commit d2f7d110ec
13 changed files with 338 additions and 10 deletions

View File

@ -11,8 +11,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Services\Model\IOrganizationService;
use models\main\IOrganizationRepository;
use models\oauth2\IResourceServerContext;
use ModelSerializers\SerializerRegistry;
use utils\Filter;
use utils\FilterParser;
use utils\FilterParserException;
@ -31,18 +33,26 @@ use Illuminate\Support\Facades\Validator;
final class OAuth2OrganizationsApiController extends OAuth2ProtectedController
{
/**
* OAuth2MembersApiController constructor.
* @param IOrganizationRepository $organization_repository
* @var IOrganizationService
*/
private $service;
/**
* OAuth2OrganizationsApiController constructor.
* @param IOrganizationRepository $company_repository
* @param IResourceServerContext $resource_server_context
* @param IOrganizationService $service
*/
public function __construct
(
IOrganizationRepository $company_repository,
IResourceServerContext $resource_server_context
IResourceServerContext $resource_server_context,
IOrganizationService $service
)
{
parent::__construct($resource_server_context);
$this->repository = $company_repository;
$this->service = $service;
}
public function getAll(){
@ -128,4 +138,47 @@ final class OAuth2OrganizationsApiController extends OAuth2ProtectedController
return $this->error500($ex);
}
}
public function addOrganization(){
try {
if(!Request::isJson()) return $this->error400();
$data = Input::json();
$rules = [
'name' => 'required|string|max:255',
];
// Creates a Validator instance and validates the data.
$validation = Validator::make($data->all(), $rules);
if ($validation->fails()) {
$messages = $validation->messages()->toArray();
return $this->error412
(
$messages
);
}
$organization = $this->service->addOrganization($data->all());
return $this->created(SerializerRegistry::getInstance()->getSerializer($organization)->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

@ -74,6 +74,7 @@ Route::group([
// organizations
Route::group(['prefix'=>'organizations'], function(){
Route::get('', 'OAuth2OrganizationsApiController@getAll');
Route::post('', 'OAuth2OrganizationsApiController@addOrganization');
});
// groups

View File

@ -18,5 +18,9 @@ use models\utils\IBaseRepository;
*/
interface IOrganizationRepository extends IBaseRepository
{
/**
* @param string $name
* @return Organization|null
*/
public function getByName($name);
}

View File

@ -51,4 +51,23 @@ final class DoctrineOrganizationRepository
'name' => 'e.name',
];
}
/**
* @param string $name
* @return Organization|null
*/
public function getByName($name)
{
try {
return $this->getEntityManager()->createQueryBuilder()
->select("t")
->from(\models\main\Organization::class, "o")
->where('UPPER(TRIM(o.name)) = UPPER(TRIM(:name))')
->setParameter('name', $name)
->getQuery()->getOneOrNullResult();
}
catch(\Exception $ex){
return null;
}
}
}

View File

@ -0,0 +1,23 @@
<?php namespace App\Security;
/**
* Copyright 2018 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 OrganizationScopes
* @package App\Security
*/
final class OrganizationScopes
{
const ReadOrganizationData = '%s/organizations/read';
const WriteOrganizationData = '%s/organizations/write';
}

View File

@ -0,0 +1,46 @@
<?php namespace App\Services\Model;
/**
* Copyright 2018 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\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use models\main\Organization;
/**
* Interface IOrganizationService
* @package App\Services\Model
*/
interface IOrganizationService
{
/**
* @param array $data
* @return Organization
* @throws EntityNotFoundException
* @throws ValidationException
*/
public function addOrganization(array $data);
/**
* @param array $data
* @param int $organization_id
* @return Organization
* @throws EntityNotFoundException
* @throws ValidationException
*/
public function updateOrganization(array $data, $organization_id);
/**
* @param int $organization_id
* @return void
* @throws EntityNotFoundException
*/
public function deleteOrganization($organization_id);
}

View File

@ -0,0 +1,94 @@
<?php namespace App\Services\Model;
use libs\utils\ITransactionService;
use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use models\main\IOrganizationRepository;
use models\main\Organization;
/**
* Copyright 2018 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 OrganizationService
* @package App\Services\Model
*/
final class OrganizationService
extends AbstractService
implements IOrganizationService
{
/**
* @var IOrganizationRepository
*/
private $organization_repository;
/**
* MemberService constructor.
* @param IOrganizationRepository $organization_repository
* @param ITransactionService $tx_service
*/
public function __construct
(
IOrganizationRepository $organization_repository,
ITransactionService $tx_service
)
{
parent::__construct($tx_service);
$this->organization_repository = $organization_repository;
}
/**
* @param array $data
* @return Organization
* @throws EntityNotFoundException
* @throws ValidationException
*/
public function addOrganization(array $data)
{
return $this->tx_service->transaction(function () use($data){
$name = trim( $data['name']);
$old_organization = $this->organization_repository->getByName($name);
if(!is_null($old_organization))
throw new ValidationException(trans("validation_errors.OrganizationService.addOrganization.alreadyExistName", ["name" => $name]));
$new_organization = new Organization();
$new_organization->setName($name);
$this->organization_repository->add($new_organization);
return $new_organization;
});
}
/**
* @param array $data
* @param int $organization_id
* @return Organization
* @throws EntityNotFoundException
* @throws ValidationException
*/
public function updateOrganization(array $data, $organization_id)
{
// TODO: Implement updateOrganization() method.
}
/**
* @param int $organization_id
* @return void
* @throws EntityNotFoundException
*/
public function deleteOrganization($organization_id)
{
// TODO: Implement deleteOrganization() method.
}
}

View File

@ -22,6 +22,7 @@ use App\Services\Model\IAttendeeService;
use App\Services\Model\IFolderService;
use App\Services\Model\ILocationService;
use App\Services\Model\IMemberService;
use App\Services\Model\IOrganizationService;
use App\Services\Model\IPresentationCategoryGroupService;
use App\Services\Model\IRSVPTemplateService;
use App\Services\Model\ISummitEventTypeService;
@ -29,6 +30,7 @@ use App\Services\Model\ISummitPushNotificationService;
use App\Services\Model\ISummitSelectionPlanService;
use App\Services\Model\ISummitTicketTypeService;
use App\Services\Model\ISummitTrackService;
use App\Services\Model\OrganizationService;
use App\Services\Model\PresentationCategoryGroupService;
use App\Services\Model\SummitLocationService;
use App\Services\Model\MemberService;
@ -236,5 +238,10 @@ final class ServicesProvider extends ServiceProvider
ISummitSelectionPlanService::class,
SummitSelectionPlanService::class
);
App::singleton(
IOrganizationService::class,
OrganizationService::class
);
}
}

View File

@ -16,6 +16,7 @@ use Illuminate\Support\Facades\Config;
use App\Models\ResourceServer\ApiEndpoint;
use LaravelDoctrine\ORM\Facades\EntityManager;
use App\Security\SummitScopes;
use App\Security\OrganizationScopes;
/**
* Class ApiEndpointsSeeder
*/
@ -1866,9 +1867,20 @@ class ApiEndpointsSeeder extends Seeder
'route' => '/api/v1/organizations',
'http_method' => 'GET',
'scopes' => [
sprintf(SummitScopes::ReadAllSummitData, $current_realm),
sprintf(SummitScopes::ReadSummitData, $current_realm),
sprintf('%s/organizations/read', $current_realm)
sprintf(OrganizationScopes::ReadOrganizationData, $current_realm)
],
]
]
);
$this->seedApiEndpoints('organizations', [
// organizations
[
'name' => 'add-organizations',
'route' => '/api/v1/organizations',
'http_method' => 'POST',
'scopes' => [
sprintf(OrganizationScopes::WriteOrganizationData, $current_realm)
],
]
]

View File

@ -17,6 +17,7 @@ use App\Models\ResourceServer\ApiScope;
use LaravelDoctrine\ORM\Facades\EntityManager;
use Illuminate\Support\Facades\DB;
use App\Security\SummitScopes;
use App\Security\OrganizationScopes;
/**
* Class ApiScopesSeeder
*/
@ -34,6 +35,7 @@ final class ApiScopesSeeder extends Seeder
$this->seedTagsScopes();
$this->seedCompaniesScopes();
$this->seedGroupsScopes();
$this->seedOrganizationScopes();
}
private function seedSummitScopes()
@ -208,14 +210,14 @@ final class ApiScopesSeeder extends Seeder
private function seedTagsScopes(){
$current_realm = Config::get('app.url');
$api = EntityManager::getRepository(\App\Models\ResourceServer\Api::class)->findOneBy(['name' => 'tags']);
$api = EntityManager::getRepository(\App\Models\ResourceServer\Api::class)->findOneBy(['name' => 'organizations']);
$scopes = [
array(
[
'name' => sprintf('%s/tags/read', $current_realm),
'short_description' => 'Get Tags Data',
'description' => 'Grants read only access for Tags Data',
),
],
];
foreach ($scopes as $scope_info) {
@ -232,6 +234,36 @@ final class ApiScopesSeeder extends Seeder
EntityManager::flush();
}
private function seedOrganizationScopes(){
$current_realm = Config::get('app.url');
$api = EntityManager::getRepository(\App\Models\ResourceServer\Api::class)->findOneBy(['name' => 'companies']);
$scopes = [
[
'name' => sprintf(OrganizationScopes::ReadOrganizationData, $current_realm),
'short_description' => 'Get Organizations Data',
'description' => 'Grants read only access for Organization Data',
],
[
'name' => sprintf(OrganizationScopes::WriteOrganizationData, $current_realm),
'short_description' => 'Write Companies Data',
'description' => 'Grants write access for Organization Data',
],
];
foreach ($scopes as $scope_info) {
$scope = new ApiScope();
$scope->setName($scope_info['name']);
$scope->setShortDescription($scope_info['short_description']);
$scope->setDescription($scope_info['description']);
$scope->setActive(true);
$scope->setDefault(false);
$scope->setApi($api);
EntityManager::persist($scope);
}
EntityManager::flush();
}
private function seedCompaniesScopes(){
$current_realm = Config::get('app.url');

View File

@ -83,4 +83,6 @@ return [
'PresentationService.saveOrUpdatePresentation.notAvailableCFP' => 'type id :type_id is not a available for CFP',
'PresentationService.saveOrUpdatePresentation.trackDontBelongToSelectionPlan' => 'track :track_id does not belongs to selection plan :selection_plan_id',
'PresentationService.submitPresentation.limitReached' => 'You reached the limit :limit of presentations.',
// organizations
'OrganizationService.addOrganization.alreadyExistName' => 'Organization name :name already exists!',
];

View File

@ -41,4 +41,34 @@ class OAuth2OrganizationsApiTest extends ProtectedApiTest
$this->assertResponseStatus(200);
}
public function testAddOrganization(){
$name = str_random(16).'_org_name';
$data = [
'name' => $name,
];
$headers = [
"HTTP_Authorization" => " Bearer " . $this->access_token,
"CONTENT_TYPE" => "application/json"
];
$response = $this->action(
"POST",
"OAuth2OrganizationsApiController@addOrganization",
[],
[],
[],
[],
$headers,
json_encode($data)
);
$content = $response->getContent();
$this->assertResponseStatus(201);
$org = json_decode($content);
$this->assertTrue(!is_null($org));
return $org;
}
}

View File

@ -16,6 +16,7 @@ use Illuminate\Support\Facades\Config;
use models\oauth2\AccessToken;
use App\Models\ResourceServer\IAccessTokenService;
use App\Security\SummitScopes;
use App\Security\OrganizationScopes;
/**
* Class AccessTokenServiceStub
*/
@ -61,6 +62,8 @@ class AccessTokenServiceStub implements IAccessTokenService
sprintf(SummitScopes::WriteAttendeesData, $url),
sprintf(SummitScopes::WriteMemberData, $url),
sprintf(SummitScopes::WritePromoCodeData, $url),
sprintf(OrganizationScopes::WriteOrganizationData, $url),
sprintf(OrganizationScopes::ReadOrganizationData, $url),
);
return AccessToken::createFromParams('123456789', implode(' ', $scopes), '1', $realm, '1','11624', 3600, 'WEB_APPLICATION', '', '');
@ -110,6 +113,8 @@ class AccessTokenServiceStub2 implements IAccessTokenService
sprintf(SummitScopes::WriteAttendeesData, $url),
sprintf(SummitScopes::WriteMemberData, $url),
sprintf(SummitScopes::WritePromoCodeData, $url),
sprintf(OrganizationScopes::WriteOrganizationData, $url),
sprintf(OrganizationScopes::ReadOrganizationData, $url),
);
return AccessToken::createFromParams('123456789', implode(' ', $scopes), '1', $realm, null,null, 3600, 'SERVICE', '', '');