New OAUTH2 endpoints to update user info (ME)
PUT /api/v1/users/me payload 'first_name' => 'sometimes|string', 'last_name' => 'sometimes|string', 'email' => 'sometimes|email', 'identifier' => 'sometimes|string', 'bio' => 'nullable|string', 'address1' => 'nullable|string', 'address2' => 'nullable|string', 'city' => 'nullable|string', 'state' => 'nullable|string', 'post_code' => 'nullable|string', 'country_iso_code' => 'nullable|country_iso_alpha2_code', 'second_email' => 'nullable|email', 'third_email' => 'nullable|email', 'gender' => 'nullable|string', 'gender_specify' => 'nullable|string', 'statement_of_interest' => 'nullable|string', 'irc' => 'nullable|string', 'linked_in_profile' => 'nullable|string', 'github_user' => 'nullable|string', 'wechat_user' => 'nullable|string', 'twitter_name' => 'nullable|string', 'language' => 'nullable|string', 'birthday' => 'nullable|date_format:U', 'password' => 'sometimes|string|min:8|confirmed', 'phone_number' => 'nullable|string', 'company' => 'nullable|string', required scopes me/write PUT /api/v1/users/me/pic multiform encoding pic: file (png, jpg, jpeg) required scopes me/write Change-Id: I31a1edd9eb1fcdee228a8f5ba1b44d324116edd9 Signed-off-by: smarcet <smarcet@gmail.com>
This commit is contained in:
parent
55c7d0f9b9
commit
8ff349761d
@ -1,14 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
<?php namespace App\Exceptions;
|
||||
/**
|
||||
* Copyright 2020 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 Exception;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Predis\Connection\ConnectionException as RedisConnectionException;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
|
||||
/**
|
||||
* Class Handler
|
||||
* @package App\Exceptions
|
||||
*/
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
@ -21,6 +34,7 @@ class Handler extends ExceptionHandler
|
||||
HttpException::class,
|
||||
ModelNotFoundException::class,
|
||||
ValidationException::class,
|
||||
RedisConnectionException::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -13,11 +13,13 @@
|
||||
**/
|
||||
|
||||
use App\Http\Controllers\GetAllTrait;
|
||||
use App\Http\Utils\PagingConstants;
|
||||
use App\Http\Controllers\UserValidationRulesFactory;
|
||||
use App\Http\Utils\HTMLCleaner;
|
||||
use App\ModelSerializers\SerializerRegistry;
|
||||
use Auth\Repositories\IUserRepository;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Support\Facades\Response;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use models\exceptions\EntityNotFoundException;
|
||||
@ -26,14 +28,10 @@ use OAuth2\Builders\IdTokenBuilder;
|
||||
use OAuth2\IResourceServerContext;
|
||||
use OAuth2\Repositories\IClientRepository;
|
||||
use OAuth2\ResourceServer\IUserService;
|
||||
use utils\Filter;
|
||||
use utils\FilterParser;
|
||||
use Utils\Http\HttpContentType;
|
||||
use utils\OrderParser;
|
||||
use utils\PagingInfo;
|
||||
use Utils\Services\ILogService;
|
||||
use Exception;
|
||||
|
||||
use OpenId\Services\IUserService as IOpenIdUserService;
|
||||
/**
|
||||
* Class OAuth2UserApiController
|
||||
* @package App\Http\Controllers\Api\OAuth2
|
||||
@ -92,10 +90,18 @@ final class OAuth2UserApiController extends OAuth2ProtectedController
|
||||
private $id_token_builder;
|
||||
|
||||
/**
|
||||
* @var IOpenIdUserService
|
||||
*/
|
||||
private $openid_user_service;
|
||||
|
||||
|
||||
/**
|
||||
* OAuth2UserApiController constructor.
|
||||
* @param IUserRepository $repository
|
||||
* @param IUserService $user_service
|
||||
* @param IResourceServerContext $resource_server_context
|
||||
* @param ILogService $log_service
|
||||
* @param IOpenIdUserService $openid_user_service
|
||||
* @param IClientRepository $client_repository
|
||||
* @param IdTokenBuilder $id_token_builder
|
||||
*/
|
||||
@ -105,6 +111,7 @@ final class OAuth2UserApiController extends OAuth2ProtectedController
|
||||
IUserService $user_service,
|
||||
IResourceServerContext $resource_server_context,
|
||||
ILogService $log_service,
|
||||
IOpenIdUserService $openid_user_service,
|
||||
IClientRepository $client_repository,
|
||||
IdTokenBuilder $id_token_builder
|
||||
)
|
||||
@ -114,6 +121,7 @@ final class OAuth2UserApiController extends OAuth2ProtectedController
|
||||
$this->user_service = $user_service;
|
||||
$this->client_repository = $client_repository;
|
||||
$this->id_token_builder = $id_token_builder;
|
||||
$this->openid_user_service = $openid_user_service;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -131,6 +139,88 @@ final class OAuth2UserApiController extends OAuth2ProtectedController
|
||||
}
|
||||
}
|
||||
|
||||
protected function curateUpdatePayload(array $payload): array
|
||||
{
|
||||
// remove possible fields that an user can not update
|
||||
// from this endpoint
|
||||
if(isset($payload['groups']))
|
||||
unset($payload['groups']);
|
||||
|
||||
if(isset($payload['email_verified']))
|
||||
unset($payload['email_verified']);
|
||||
|
||||
if(isset($payload['active']))
|
||||
unset($payload['active']);
|
||||
|
||||
return HTMLCleaner::cleanData($payload, [
|
||||
'bio', 'statement_of_interest'
|
||||
]);
|
||||
}
|
||||
|
||||
public function UpdateMe(){
|
||||
try {
|
||||
if(!Request::isJson()) return $this->error400();
|
||||
if(!$this->resource_server_context->getCurrentUserId()){
|
||||
return $this->error403();
|
||||
}
|
||||
$payload = Input::json()->all();
|
||||
// Creates a Validator instance and validates the data.
|
||||
|
||||
$validation = Validator::make($payload, UserValidationRulesFactory::build($payload, true));
|
||||
if ($validation->fails()) {
|
||||
$ex = new ValidationException();
|
||||
throw $ex->setMessages($validation->messages()->toArray());
|
||||
}
|
||||
|
||||
$user = $this->openid_user_service->update($this->resource_server_context->getCurrentUserId(), $this->curateUpdatePayload($payload));
|
||||
|
||||
return $this->updated(SerializerRegistry::getInstance()->getSerializer($user, SerializerRegistry::SerializerType_Private)->serialize());
|
||||
}
|
||||
catch (ValidationException $ex1)
|
||||
{
|
||||
Log::warning($ex1);
|
||||
return $this->error412($ex1->getMessages());
|
||||
}
|
||||
catch (EntityNotFoundException $ex2)
|
||||
{
|
||||
Log::warning($ex2);
|
||||
return $this->error404(['message' => $ex2->getMessage()]);
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
Log::error($ex);
|
||||
return $this->error500($ex);
|
||||
}
|
||||
}
|
||||
|
||||
public function UpdateMyPic(){
|
||||
try {
|
||||
if (!$this->resource_server_context->getCurrentUserId()) {
|
||||
return $this->error403();
|
||||
}
|
||||
|
||||
$file = request()->file('pic');
|
||||
|
||||
if (!is_null($file)) {
|
||||
$user = $this->openid_user_service->updateProfilePhoto($this->resource_server_context->getCurrentUserId(), $file);
|
||||
}
|
||||
return $this->updated(SerializerRegistry::getInstance()->getSerializer($user, SerializerRegistry::SerializerType_Private)->serialize());
|
||||
}
|
||||
catch (ValidationException $ex1)
|
||||
{
|
||||
Log::warning($ex1);
|
||||
return $this->error412($ex1->getMessages());
|
||||
}
|
||||
catch (EntityNotFoundException $ex2)
|
||||
{
|
||||
Log::warning($ex2);
|
||||
return $this->error404(['message' => $ex2->getMessage()]);
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
Log::error($ex);
|
||||
return $this->error500($ex);
|
||||
}
|
||||
}
|
||||
|
||||
public function userInfo()
|
||||
{
|
||||
try {
|
||||
|
@ -13,6 +13,7 @@
|
||||
**/
|
||||
|
||||
use App\Http\Controllers\APICRUDController;
|
||||
use App\Http\Controllers\UserValidationRulesFactory;
|
||||
use App\Http\Utils\HTMLCleaner;
|
||||
use App\ModelSerializers\SerializerRegistry;
|
||||
use Auth\Repositories\IUserRepository;
|
||||
@ -173,36 +174,7 @@ final class UserApiController extends APICRUDController
|
||||
*/
|
||||
protected function getUpdatePayloadValidationRules(): array
|
||||
{
|
||||
return [
|
||||
'first_name' => 'required|string',
|
||||
'last_name' => 'required|string',
|
||||
'email' => 'required|email',
|
||||
'identifier' => 'sometimes|string',
|
||||
'bio' => 'nullable|string',
|
||||
'address1' => 'nullable|string',
|
||||
'address2' => 'nullable|string',
|
||||
'city' => 'nullable|string',
|
||||
'state' => 'nullable|string',
|
||||
'post_code' => 'nullable|string',
|
||||
'country_iso_code' => 'nullable|country_iso_alpha2_code',
|
||||
'second_email' => 'nullable|email',
|
||||
'third_email' => 'nullable|email',
|
||||
'gender' => 'nullable|string',
|
||||
'gender_specify' => 'nullable|string',
|
||||
'statement_of_interest' => 'nullable|string',
|
||||
'irc' => 'nullable|string',
|
||||
'linked_in_profile' => 'nullable|string',
|
||||
'github_user' => 'nullable|string',
|
||||
'wechat_user' => 'nullable|string',
|
||||
'twitter_name' => 'nullable|string',
|
||||
'language' => 'nullable|string',
|
||||
'birthday' => 'nullable|date_format:U',
|
||||
'password' => 'sometimes|string|min:8|confirmed',
|
||||
'email_verified' => 'nullable|boolean',
|
||||
'active' => 'nullable|boolean',
|
||||
'phone_number' => 'nullable|string',
|
||||
'company' => 'nullable|string',
|
||||
];
|
||||
return UserValidationRulesFactory::build([], true);
|
||||
}
|
||||
|
||||
protected function curateUpdatePayload(array $payload): array
|
||||
@ -224,38 +196,9 @@ final class UserApiController extends APICRUDController
|
||||
*/
|
||||
protected function getCreatePayloadValidationRules(): array
|
||||
{
|
||||
return [
|
||||
'first_name' => 'required|string',
|
||||
'last_name' => 'required|string',
|
||||
'email' => 'required|email',
|
||||
'identifier' => 'sometimes|string',
|
||||
'bio' => 'nullable|string',
|
||||
'address1' => 'nullable|string',
|
||||
'address2' => 'nullable|string',
|
||||
'city' => 'nullable|string',
|
||||
'state' => 'nullable|string',
|
||||
'post_code' => 'nullable|string',
|
||||
'country_iso_code' => 'nullable|country_iso_alpha2_code',
|
||||
'second_email' => 'nullable|email',
|
||||
'third_email' => 'nullable|email',
|
||||
'gender' => 'nullable|string',
|
||||
'statement_of_interest' => 'nullable|string',
|
||||
'irc' => 'nullable|string',
|
||||
'linked_in_profile' => 'nullable|string',
|
||||
'github_user' => 'nullable|string',
|
||||
'wechat_user' => 'nullable|string',
|
||||
'twitter_name' => 'nullable|string',
|
||||
'language' => 'nullable|string',
|
||||
'birthday' => 'nullable|date_format:U',
|
||||
'password' => 'sometimes|string|min:8|confirmed',
|
||||
'email_verified' => 'nullable|boolean',
|
||||
'active' => 'nullable|boolean',
|
||||
'phone_number' => 'nullable|string',
|
||||
'company' => 'nullable|string',
|
||||
];
|
||||
return UserValidationRulesFactory::build([], false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param LaravelRequest $request
|
||||
* @return \Illuminate\Http\JsonResponse|mixed
|
||||
|
@ -0,0 +1,96 @@
|
||||
<?php namespace App\Http\Controllers;
|
||||
/**
|
||||
* Copyright 2020 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 UserValidationRulesFactory
|
||||
* @package App\Http\Controllers
|
||||
*/
|
||||
final class UserValidationRulesFactory
|
||||
{
|
||||
/**
|
||||
* @param array $data
|
||||
* @param bool $update
|
||||
* @return array
|
||||
*/
|
||||
public static function build(array $data, $update = false){
|
||||
|
||||
if($update){
|
||||
return [
|
||||
'first_name' => 'sometimes|string',
|
||||
'last_name' => 'sometimes|string',
|
||||
'email' => 'sometimes|email',
|
||||
'identifier' => 'sometimes|string',
|
||||
'bio' => 'nullable|string',
|
||||
'address1' => 'nullable|string',
|
||||
'address2' => 'nullable|string',
|
||||
'city' => 'nullable|string',
|
||||
'state' => 'nullable|string',
|
||||
'post_code' => 'nullable|string',
|
||||
'country_iso_code' => 'nullable|country_iso_alpha2_code',
|
||||
'second_email' => 'nullable|email',
|
||||
'third_email' => 'nullable|email',
|
||||
'gender' => 'nullable|string',
|
||||
'gender_specify' => 'nullable|string',
|
||||
'statement_of_interest' => 'nullable|string',
|
||||
'irc' => 'nullable|string',
|
||||
'linked_in_profile' => 'nullable|string',
|
||||
'github_user' => 'nullable|string',
|
||||
'wechat_user' => 'nullable|string',
|
||||
'twitter_name' => 'nullable|string',
|
||||
'language' => 'nullable|string',
|
||||
'birthday' => 'nullable|date_format:U',
|
||||
'password' => 'sometimes|string|min:8|confirmed',
|
||||
'phone_number' => 'nullable|string',
|
||||
'company' => 'nullable|string',
|
||||
// admin fields
|
||||
'email_verified' => 'nullable|boolean',
|
||||
'active' => 'nullable|boolean',
|
||||
'groups' => 'sometimes|int_array',
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'first_name' => 'required|string',
|
||||
'last_name' => 'required|string',
|
||||
'email' => 'required|email',
|
||||
'identifier' => 'sometimes|string',
|
||||
'bio' => 'nullable|string',
|
||||
'address1' => 'nullable|string',
|
||||
'address2' => 'nullable|string',
|
||||
'city' => 'nullable|string',
|
||||
'state' => 'nullable|string',
|
||||
'post_code' => 'nullable|string',
|
||||
'country_iso_code' => 'nullable|country_iso_alpha2_code',
|
||||
'second_email' => 'nullable|email',
|
||||
'third_email' => 'nullable|email',
|
||||
'gender' => 'nullable|string',
|
||||
'statement_of_interest' => 'nullable|string',
|
||||
'irc' => 'nullable|string',
|
||||
'linked_in_profile' => 'nullable|string',
|
||||
'github_user' => 'nullable|string',
|
||||
'wechat_user' => 'nullable|string',
|
||||
'twitter_name' => 'nullable|string',
|
||||
'language' => 'nullable|string',
|
||||
'birthday' => 'nullable|date_format:U',
|
||||
'password' => 'sometimes|string|min:8|confirmed',
|
||||
'phone_number' => 'nullable|string',
|
||||
'company' => 'nullable|string',
|
||||
// admin fields
|
||||
'email_verified' => 'nullable|boolean',
|
||||
'active' => 'nullable|boolean',
|
||||
'groups' => 'sometimes|int_array',
|
||||
];
|
||||
}
|
||||
}
|
@ -168,16 +168,19 @@ Route::group(['namespace' => 'App\Http\Controllers', 'middleware' => 'web' ], fu
|
||||
'middleware' => ['ssl', 'auth']], function () {
|
||||
|
||||
Route::group(['prefix' => 'users'], function () {
|
||||
|
||||
Route::delete('/me/tokens/{value}',"UserApiController@revokeMyToken");
|
||||
Route::get('' , "UserApiController@getAll");
|
||||
Route::post('', ['middleware' => ['openstackid.currentuser.serveradmin.json'], 'uses' => "UserApiController@create"]);
|
||||
Route::put('me', "UserApiController@updateMe");
|
||||
|
||||
Route::group(['prefix' => '{id}'], function(){
|
||||
|
||||
Route::group(['prefix' => 'locked'], function(){
|
||||
Route::put('', ['middleware' => ['openstackid.currentuser.serveradmin.json'], 'uses' => 'UserApiController@unlock']);
|
||||
Route::delete('', ['middleware' => ['openstackid.currentuser.serveradmin.json'], 'uses' => 'UserApiController@lock']);
|
||||
});
|
||||
|
||||
Route::get('', ['middleware' => ['openstackid.currentuser.serveradmin.json'], 'uses' => "UserApiController@get"]);
|
||||
Route::delete('', ['middleware' => ['openstackid.currentuser.serveradmin.json'], 'uses' =>"UserApiController@delete"]);
|
||||
Route::put('', ['middleware' => ['openstackid.currentuser.serveradmin.json'], 'uses' =>"UserApiController@update"]);
|
||||
@ -376,7 +379,15 @@ Route::group(
|
||||
Route::group(['prefix' => 'users'], function () {
|
||||
Route::get('', 'OAuth2UserApiController@getAll');
|
||||
Route::get('/{id}', 'OAuth2UserApiController@get');
|
||||
Route::get('/me', 'OAuth2UserApiController@me');
|
||||
|
||||
Route::group(['prefix' => 'me'], function () {
|
||||
Route::get('', 'OAuth2UserApiController@me');
|
||||
Route::put('','OAuth2UserApiController@UpdateMe');
|
||||
Route::group(['prefix' => 'pic'], function () {
|
||||
Route::put('','OAuth2UserApiController@UpdateMyPic');
|
||||
});
|
||||
});
|
||||
|
||||
Route::get('/info', 'OAuth2UserApiController@userInfo');
|
||||
Route::post('/info', 'OAuth2UserApiController@userInfo');
|
||||
});
|
||||
|
@ -90,7 +90,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
if(!is_array($value)) return false;
|
||||
foreach($value as $element)
|
||||
{
|
||||
if(!is_int($element)) return false;
|
||||
if(!is_integer($element)) return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
@ -12,6 +12,7 @@
|
||||
* limitations under the License.
|
||||
**/
|
||||
use App\Events\UserEmailUpdated;
|
||||
use App\Events\UserPasswordResetSuccessful;
|
||||
use App\Jobs\PublishUserDeleted;
|
||||
use App\Jobs\PublishUserUpdated;
|
||||
use App\libs\Auth\Factories\UserFactory;
|
||||
@ -229,11 +230,14 @@ final class UserService extends AbstractService implements IUserService
|
||||
public function update(int $id, array $payload): IEntity
|
||||
{
|
||||
return $this->tx_service->transaction(function() use($id, $payload){
|
||||
|
||||
$user = $this->repository->getById($id);
|
||||
if(is_null($user) || !$user instanceof User)
|
||||
throw new EntityNotFoundException("user not found");
|
||||
|
||||
$former_email = $user->getEmail();
|
||||
$former_password = $user->getPassword();
|
||||
|
||||
if(isset($payload["email"])){
|
||||
$former_user = $this->repository->getByEmailOrName(trim($payload["email"]));
|
||||
if(!is_null($former_user) && $former_user->getId() != $id)
|
||||
@ -259,11 +263,16 @@ final class UserService extends AbstractService implements IUserService
|
||||
}
|
||||
|
||||
if($former_email != $user->getEmail()){
|
||||
Log::debug(sprintf("UserService::update use id %s - email changed old %s - email new %s", $id, $former_email , $user->getEmail()));
|
||||
Log::warning(sprintf("UserService::update use id %s - email changed old %s - email new %s", $id, $former_email , $user->getEmail()));
|
||||
$user->clearEmailVerification();
|
||||
Event::fire(new UserEmailUpdated($user->getId()));
|
||||
}
|
||||
|
||||
if($former_password != $user->getPassword()){
|
||||
Log::warning(sprintf("UserService::update use id %s - password changed", $id));
|
||||
Event::fire(new UserPasswordResetSuccessful($user->getId()));
|
||||
}
|
||||
|
||||
try {
|
||||
if(Config::get("queue.enable_message_broker", false) == true)
|
||||
PublishUserUpdated::dispatch($user)->onConnection('message_broker');
|
||||
|
@ -26,5 +26,6 @@ interface IUserScopes
|
||||
const Registration = 'user-registration';
|
||||
const ReadAll = 'users-read-all';
|
||||
const SSO = 'sso';
|
||||
|
||||
const MeRead = 'me/read';
|
||||
const MeWrite = 'me/write';
|
||||
}
|
83
database/migrations/Version20200811151509.php
Normal file
83
database/migrations/Version20200811151509.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php namespace Database\Migrations;
|
||||
/**
|
||||
* Copyright 2020 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\libs\OAuth2\IUserScopes;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
use Doctrine\DBAL\Schema\Schema as Schema;
|
||||
use SeedUtils;
|
||||
/**
|
||||
* Class Version20200811151509
|
||||
* @package Database\Migrations
|
||||
*/
|
||||
class Version20200811151509 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
|
||||
SeedUtils::seedScopes([
|
||||
[
|
||||
'name' => IUserScopes::MeRead,
|
||||
'short_description' => 'Allows access to read your Profile',
|
||||
'description' => 'Allows access to read your Profile',
|
||||
'system' => false,
|
||||
'default' => false,
|
||||
'groups' => false,
|
||||
],
|
||||
|
||||
], 'users');
|
||||
|
||||
SeedUtils::seedScopes([
|
||||
[
|
||||
'name' => IUserScopes::MeWrite,
|
||||
'short_description' => 'Allows access to write your Profile',
|
||||
'description' => 'Allows access to write your Profile',
|
||||
'system' => false,
|
||||
'default' => false,
|
||||
'groups' => false,
|
||||
],
|
||||
|
||||
], 'users');
|
||||
|
||||
SeedUtils::seedApiEndpoints('users', [
|
||||
[
|
||||
'name' => 'update-my-user',
|
||||
'active' => true,
|
||||
'route' => '/api/v1/users/me',
|
||||
'http_method' => 'PUT',
|
||||
'scopes' => [
|
||||
\App\libs\OAuth2\IUserScopes::MeWrite
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'update-my-user-pic',
|
||||
'active' => true,
|
||||
'route' => '/api/v1/users/me/pic',
|
||||
'http_method' => 'PUT',
|
||||
'scopes' => [
|
||||
\App\libs\OAuth2\IUserScopes::MeWrite
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -83,7 +83,25 @@ class ApiEndpointSeeder extends Seeder
|
||||
'scopes' => [
|
||||
\App\libs\OAuth2\IUserScopes::ReadAll
|
||||
],
|
||||
]
|
||||
],
|
||||
[
|
||||
'name' => 'update-my-user',
|
||||
'active' => true,
|
||||
'route' => '/api/v1/users/me',
|
||||
'http_method' => 'PUT',
|
||||
'scopes' => [
|
||||
\App\libs\OAuth2\IUserScopes::MeWrite
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'update-my-user-pic',
|
||||
'active' => true,
|
||||
'route' => '/api/v1/users/me/pic',
|
||||
'http_method' => 'PUT',
|
||||
'scopes' => [
|
||||
\App\libs\OAuth2\IUserScopes::MeWrite
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@ -65,6 +65,22 @@ class ApiScopeSeeder extends Seeder {
|
||||
'system' => false,
|
||||
'default' => false,
|
||||
'groups' => true,
|
||||
],
|
||||
[
|
||||
'name' => IUserScopes::MeRead,
|
||||
'short_description' => 'Allows access to read your Profile',
|
||||
'description' => 'Allows access to read your Profile',
|
||||
'system' => false,
|
||||
'default' => false,
|
||||
'groups' => false,
|
||||
],
|
||||
[
|
||||
'name' => IUserScopes::MeWrite,
|
||||
'short_description' => 'Allows access to write your Profile',
|
||||
'description' => 'Allows access to write your Profile',
|
||||
'system' => false,
|
||||
'default' => false,
|
||||
'groups' => false,
|
||||
]
|
||||
], 'users');
|
||||
|
||||
|
@ -1373,14 +1373,32 @@ PPK;
|
||||
'system' => false,
|
||||
'active' => true,
|
||||
),
|
||||
array(
|
||||
[
|
||||
'name' => 'address',
|
||||
'short_description' => 'This scope value requests access to the address Claim.',
|
||||
'description' => 'This scope value requests access to the address Claim.',
|
||||
'api' => $api,
|
||||
'system' => false,
|
||||
'active' => true,
|
||||
)
|
||||
],
|
||||
[
|
||||
'name' => IUserScopes::MeRead,
|
||||
'short_description' => 'Allows access to read your Profile',
|
||||
'description' => 'Allows access to read your Profile',
|
||||
'api' => $api,
|
||||
'system' => false,
|
||||
'default' => false,
|
||||
'active' => true,
|
||||
],
|
||||
[
|
||||
'name' => IUserScopes::MeWrite,
|
||||
'short_description' => 'Allows access to write your Profile',
|
||||
'description' => 'Allows access to write your Profile',
|
||||
'api' => $api,
|
||||
'system' => false,
|
||||
'default' => false,
|
||||
'active' => true,
|
||||
]
|
||||
];
|
||||
|
||||
foreach($api_scope_payloads as $payload) {
|
||||
@ -1645,28 +1663,41 @@ PPK;
|
||||
$users = $api_repository->findOneBy(['name' => 'users']);
|
||||
|
||||
$api_scope_payloads = [
|
||||
array(
|
||||
[
|
||||
'name' => 'get-user-info',
|
||||
'active' => true,
|
||||
'api' => $users,
|
||||
'route' => '/api/v1/users/me',
|
||||
'http_method' => 'GET'
|
||||
),
|
||||
array(
|
||||
],
|
||||
[
|
||||
'name' => 'get-user-claims-get',
|
||||
'active' => true,
|
||||
'api' => $users,
|
||||
'route' => '/api/v1/users/info',
|
||||
'http_method' => 'GET'
|
||||
),
|
||||
array(
|
||||
],
|
||||
[
|
||||
'name' => 'get-user-claims-post',
|
||||
'active' => true,
|
||||
'api' => $users,
|
||||
'route' => '/api/v1/users/info',
|
||||
'http_method' => 'POST'
|
||||
)
|
||||
|
||||
],
|
||||
[
|
||||
'name' => 'update-my-user',
|
||||
'active' => true,
|
||||
'route' => '/api/v1/users/me',
|
||||
'api' => $users,
|
||||
'http_method' => 'PUT',
|
||||
],
|
||||
[
|
||||
'name' => 'update-my-user-pic',
|
||||
'active' => true,
|
||||
'route' => '/api/v1/users/me/pic',
|
||||
'api' => $users,
|
||||
'http_method' => 'PUT',
|
||||
],
|
||||
];
|
||||
|
||||
foreach($api_scope_payloads as $payload) {
|
||||
@ -1678,12 +1709,14 @@ PPK;
|
||||
$profile_scope = $api_scope_repository->findOneBy(['name' => 'profile']);
|
||||
$email_scope = $api_scope_repository->findOneBy(['name' => 'email']);
|
||||
$address_scope = $api_scope_repository->findOneBy(['name' => 'address']);
|
||||
$me_write = $api_scope_repository->findOneBy(['name' => IUserScopes::MeWrite]);
|
||||
|
||||
foreach($api_scope_payloads as $payload) {
|
||||
$endpoint = $endpoint_repository->findOneBy(['name' => $payload['name']]);
|
||||
$endpoint->addScope($address_scope);
|
||||
$endpoint->addScope($email_scope);
|
||||
$endpoint->addScope($profile_scope);
|
||||
$endpoint->addScope($me_write);
|
||||
EntityManager::persist($endpoint);
|
||||
}
|
||||
|
||||
|
@ -11,13 +11,50 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
use App\libs\OAuth2\IUserScopes;
|
||||
use OAuth2\ResourceServer\IUserService;
|
||||
/**
|
||||
* Class OAuth2UserServiceApiTest
|
||||
*/
|
||||
final class OAuth2UserServiceApiTest extends OAuth2ProtectedApiTest {
|
||||
|
||||
/**
|
||||
* @covers OAuth2UserApiController::get()
|
||||
*/
|
||||
public function testUpdateMe(){
|
||||
|
||||
$first_name_val = 'test_'. str_random(16);
|
||||
$data = [
|
||||
'first_name' => $first_name_val,
|
||||
];
|
||||
|
||||
$params = [
|
||||
];
|
||||
|
||||
$headers = [
|
||||
"HTTP_Authorization" => " Bearer " . $this->access_token,
|
||||
"CONTENT_TYPE" => "application/json"
|
||||
];
|
||||
|
||||
$response = $this->action
|
||||
(
|
||||
"PUT",
|
||||
"Api\\OAuth2\\OAuth2UserApiController@UpdateMe",
|
||||
$params,
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
$headers,
|
||||
json_encode($data)
|
||||
);
|
||||
|
||||
$this->assertResponseStatus(201);
|
||||
$content = $response->getContent();
|
||||
$user = json_decode($content);
|
||||
|
||||
$this->assertTrue($user->first_name == $first_name_val);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers OAuth2UserApiController::get()
|
||||
@ -58,7 +95,8 @@ final class OAuth2UserServiceApiTest extends OAuth2ProtectedApiTest {
|
||||
$scope = array(
|
||||
IUserService::UserProfileScope_Address,
|
||||
IUserService::UserProfileScope_Email,
|
||||
IUserService::UserProfileScope_Profile
|
||||
IUserService::UserProfileScope_Profile,
|
||||
IUserScopes::MeWrite,
|
||||
);
|
||||
|
||||
return $scope;
|
||||
|
Loading…
x
Reference in New Issue
Block a user