Added new endpoint to create tags

POST /api/v1/tags

payload
tag : required|string

required scopes

%s/summits/write
%s/tags/write

Change-Id: Ibe0a619df5feb01db4506e940df3eb47d855f6c1
This commit is contained in:
smarcet
2019-06-06 15:18:17 -03:00
parent fa90b07484
commit 013df1b675
10 changed files with 212 additions and 15 deletions

View File

@@ -1,6 +1,4 @@
<?php namespace App\Http\Controllers;
/**
* Copyright 2017 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,6 +15,7 @@ use models\main\ITagRepository;
use models\oauth2\IResourceServerContext;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Validator;
use ModelSerializers\SerializerRegistry;
use utils\Filter;
use utils\FilterParser;
use utils\FilterParserException;
@@ -26,6 +25,7 @@ use Illuminate\Support\Facades\Log;
use utils\PagingInfo;
use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use App\Services\Model\ITagService;
/**
* Class OAuth2TagsApiController
* @package App\Http\Controllers
@@ -33,29 +33,36 @@ use models\exceptions\ValidationException;
final class OAuth2TagsApiController extends OAuth2ProtectedController
{
/**
* OAuth2MembersApiController constructor.
* @var ITagService
*/
private $tag_service;
/**
* OAuth2TagsApiController constructor.
* @param ITagService $tag_service
* @param ITagRepository $tag_repository
* @param IResourceServerContext $resource_server_context
*/
public function __construct
(
ITagService $tag_service,
ITagRepository $tag_repository,
IResourceServerContext $resource_server_context
)
{
parent::__construct($resource_server_context);
$this->repository = $tag_repository;
$this->tag_service = $tag_service;
}
public function getAll(){
$values = Input::all();
$rules = array
(
$rules = [
'page' => 'integer|min:1',
'per_page' => 'required_with:page|integer|min:5|max:100',
);
];
try {
@@ -78,21 +85,20 @@ final class OAuth2TagsApiController extends OAuth2ProtectedController
$filter = null;
if (Input::has('filter')) {
$filter = FilterParser::parse(Input::get('filter'), array
(
$filter = FilterParser::parse(Input::get('filter'), [
'tag' => ['=@', '=='],
));
]);
}
$order = null;
if (Input::has('order'))
{
$order = OrderParser::parse(Input::get('order'), array
(
$order = OrderParser::parse(Input::get('order'), [
'tag',
'id',
));
]);
}
if(is_null($filter)) $filter = new Filter();
@@ -132,4 +138,47 @@ final class OAuth2TagsApiController extends OAuth2ProtectedController
}
}
public function addTag(){
try {
if(!Request::isJson()) return $this->error400();
$data = Input::json();
$rules = [
'tag' => 'required|string',
];
// 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
);
}
$tag = $this->tag_service->addTag($data->all());
return $this->created(SerializerRegistry::getInstance()->getSerializer($tag)->serialize
(
Input::get('expand','')
));
}
catch (ValidationException $ex1) {
Log::warning($ex1);
return $this->error412([$ex1->getMessage()]);
}
catch(EntityNotFoundException $ex2)
{
Log::warning($ex2);
return $this->error404(['message'=> $ex2->getMessage()]);
}
catch (Exception $ex) {
Log::error($ex);
return $this->error500($ex);
}
}
}

View File

@@ -64,6 +64,7 @@ Route::group([
// tags
Route::group(['prefix'=>'tags'], function(){
Route::get('', 'OAuth2TagsApiController@getAll');
Route::post('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators|summit-room-administrators', 'uses' => 'OAuth2TagsApiController@addTag']);
});
// companies

View File

@@ -53,6 +53,7 @@ class Tag extends SilverstripeBaseModel
*/
public function __construct($tag)
{
parent::__construct();
$this->tag = $tag;
}

View File

@@ -58,4 +58,7 @@ final class SummitScopes
const WriteSummitSpeakerAssistanceData = '%s/summit-speaker-assistance/write';
const WriteTicketTypeData = '%s/ticket-types/write';
const WritePresentationData = '%s/summits/write-presentation';
const WriteTagsData = '%s/tags/write';
const ReadTagsData = '%s/tags/read';
}

View File

@@ -0,0 +1,26 @@
<?php namespace App\Services\Model;
/**
* Copyright 2019 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\Tag;
/**
* Interface ITagService
* @package App\Services\Model
*/
interface ITagService
{
/**
* @param array $payload
* @return Tag
*/
public function addTag(array $payload):Tag;
}

View File

@@ -0,0 +1,61 @@
<?php namespace App\Services\Model;
/**
* Copyright 2019 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\utils\ITransactionService;
use models\exceptions\ValidationException;
use models\main\ITagRepository;
use models\main\Tag;
/**
* Class TagService
* @package App\Services\Model
*/
final class TagService
extends AbstractService
implements ITagService
{
/**
* @var ITagRepository
*/
private $tag_repository;
/**
* TagService constructor.
* @param ITagRepository $tag_repository
* @param ITransactionService $rx_service
*/
public function __construct(ITagRepository $tag_repository, ITransactionService $rx_service)
{
parent::__construct($rx_service);
$this->tag_repository = $tag_repository;
}
/**
* @param array $payload
* @return Tag
*/
public function addTag(array $payload): Tag
{
return $this->tx_service->transaction(function () use ($payload){
$former_tag = $this->tag_repository->getByTag(trim($payload['tag']));
if(!is_null($former_tag)){
throw new ValidationException(sprintf("tag %s already exists!", $payload['tag']));
}
$tag = new Tag(trim($payload['tag']));
$this->tag_repository->add($tag);
return $tag;
});
}
}

View File

@@ -33,6 +33,7 @@ use App\Services\Model\ISummitSelectionPlanService;
use App\Services\Model\ISummitTicketTypeService;
use App\Services\Model\ISummitTrackService;
use App\Services\Model\ISummitTrackTagGroupService;
use App\Services\Model\ITagService;
use App\Services\Model\ITrackQuestionTemplateService;
use App\Services\Model\OrganizationService;
use App\Services\Model\PresentationCategoryGroupService;
@@ -45,11 +46,13 @@ use App\Services\Model\SummitSelectionPlanService;
use App\Services\Model\SummitTicketTypeService;
use App\Services\Model\SummitTrackService;
use App\Services\Model\SummitTrackTagGroupService;
use App\Services\Model\TagService;
use App\Services\Model\TrackQuestionTemplateService;
use App\Services\SummitEventTypeService;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\ServiceProvider;
use models\main\ITagRepository;
use models\utils\SilverstripeBaseModel;
use ModelSerializers\BaseSerializerTypeSelector;
use ModelSerializers\ISerializerTypeSelector;
@@ -268,5 +271,10 @@ final class ServicesProvider extends ServiceProvider
ITrackQuestionTemplateService::class,
TrackQuestionTemplateService::class
);
App::singleton(
ITagService::class,
TagService::class
);
}
}

View File

@@ -2277,7 +2277,7 @@ class ApiEndpointsSeeder extends Seeder
$current_realm = Config::get('app.scope_base_realm');
$this->seedApiEndpoints('tags', [
// members
// tags
[
'name' => 'get-tags',
'route' => '/api/v1/tags',
@@ -2285,7 +2285,16 @@ class ApiEndpointsSeeder extends Seeder
'scopes' => [
sprintf(SummitScopes::ReadAllSummitData, $current_realm),
sprintf(SummitScopes::ReadSummitData, $current_realm),
sprintf('%s/tags/read', $current_realm)
sprintf(SummitScopes::ReadTagsData, $current_realm)
],
],
[
'name' => 'add-tag',
'route' => '/api/v1/tags',
'http_method' => 'POST',
'scopes' => [
sprintf(SummitScopes::WriteSummitData, $current_realm),
sprintf(SummitScopes::WriteTagsData, $current_realm)
],
]
]

View File

@@ -260,10 +260,15 @@ final class ApiScopesSeeder extends Seeder
$scopes = [
[
'name' => sprintf('%s/tags/read', $current_realm),
'name' => sprintf(SummitScopes::ReadTagsData, $current_realm),
'short_description' => 'Get Tags Data',
'description' => 'Grants read only access for Tags Data',
],
[
'name' => sprintf(SummitScopes::WriteTagsData, $current_realm),
'short_description' => 'Write Tags Data',
'description' => 'Grants write access to Tags Data',
],
];
foreach ($scopes as $scope_info) {

View File

@@ -41,4 +41,38 @@ class OAuth2TagsApiTest extends ProtectedApiTest
$this->assertResponseStatus(200);
}
public function testAddTag(){
$params = [
];
$tag = str_random(16).'_tag';
$data = [
'tag' => $tag,
];
$headers = [
"HTTP_Authorization" => " Bearer " . $this->access_token,
"CONTENT_TYPE" => "application/json"
];
$response = $this->action(
"POST",
"OAuth2TagsApiController@addTag",
$params,
[],
[],
[],
$headers,
json_encode($data)
);
$content = $response->getContent();
$this->assertResponseStatus(201);
$tag = json_decode($content);
$this->assertTrue(!is_null($tag));
return $tag;
}
}