diff --git a/app/config/app.php b/app/config/app.php index 6f1ecb64..22c67cbc 100644 --- a/app/config/app.php +++ b/app/config/app.php @@ -106,8 +106,9 @@ return array( 'Illuminate\Workbench\WorkbenchServiceProvider', 'Illuminate\Redis\RedisServiceProvider', 'services\utils\UtilsProvider', - 'repositories\RepositoriesProvider', - 'services\oauth2\OAuth2ServiceProvider', + 'repositories\RepositoriesProvider', + 'factories\FactoriesProvider', + 'services\oauth2\OAuth2ServiceProvider', 'services\openid\OpenIdProvider', 'auth\AuthenticationServiceProvider', 'services\ServicesProvider', @@ -182,5 +183,5 @@ return array( 'View' => 'Illuminate\Support\Facades\View', 'RedisLV4' => 'Illuminate\Support\Facades\Redis', ), - + 'version' => 'XX.XX.XX', ); diff --git a/app/controllers/AdminController.php b/app/controllers/AdminController.php index bc4c4308..22ed92d8 100644 --- a/app/controllers/AdminController.php +++ b/app/controllers/AdminController.php @@ -252,13 +252,17 @@ class AdminController extends BaseController { $friendly_scopes = $this->scope_service->getFriendlyScopesByName(explode(' ',$refresh_token->scope)); $refresh_token->setFriendlyScopes(implode(', ',$friendly_scopes)); } - return View::make("oauth2.profile.edit-user-grants",array( - 'user_id' => $user->getId(), - 'access_tokens' => $access_tokens , - 'refresh_tokens' => $refresh_tokens , - "is_oauth2_admin" => $user->isOAuth2ServerAdmin(), - "is_openstackid_admin" => $user->isOpenstackIdAdmin(), - )); + + return View::make("oauth2.profile.edit-user-grants", + array + ( + 'user_id' => $user->getId(), + 'access_tokens' => $access_tokens , + 'refresh_tokens' => $refresh_tokens , + 'is_oauth2_admin' => $user->isOAuth2ServerAdmin(), + 'is_openstackid_admin' => $user->isOpenstackIdAdmin(), + ) + ); } public function listOAuth2Clients(){ diff --git a/app/controllers/apis/ApiScopeGroupController.php b/app/controllers/apis/ApiScopeGroupController.php index 36842ff3..1a886497 100644 --- a/app/controllers/apis/ApiScopeGroupController.php +++ b/app/controllers/apis/ApiScopeGroupController.php @@ -66,10 +66,10 @@ final class ApiScopeGroupController extends AbstractRESTController implements IC { parent::__construct($log_service); - $this->repository = $repository; - $this->user_repository = $user_repository; - $this->scope_service = $scope_service; - $this->service = $service; + $this->repository = $repository; + $this->user_repository = $user_repository; + $this->scope_service = $scope_service; + $this->service = $service; $this->allowed_filter_fields = array(''); $this->allowed_projection_fields = array('*'); } @@ -97,7 +97,7 @@ final class ApiScopeGroupController extends AbstractRESTController implements IC 'name' => 'required|text|max:512', 'active' => 'required|boolean', 'scopes' => 'required', - 'users' => 'required', + 'users' => 'required|user_ids', ); // Creates a Validator instance and validates the data. $validation = Validator::make($values, $rules); @@ -204,7 +204,7 @@ final class ApiScopeGroupController extends AbstractRESTController implements IC 'name' => 'required|text|max:512', 'active' => 'required|boolean', 'scopes' => 'required', - 'users' => 'required', + 'users' => 'required|user_ids', ); // Creates a Validator instance and validates the data. $validation = Validator::make($values, $rules); @@ -253,26 +253,4 @@ final class ApiScopeGroupController extends AbstractRESTController implements IC } } - public function fetchUsers() - { - $values = Input::all(); - if(!isset($values['t'])) return $this->error404(); - $term = $values['t']; - $users = $this->user_repository->getByEmailOrName($term); - if(count($users) > 0) - { - $list = array(); - foreach($users as $u) - { - array_push($list, array - ( - 'id' => $u->id, - 'value' => sprintf('%s (%s)', $u->getFullName(), $u->getEmail()) - ) - ); - } - return $this->ok($list); - } - return $this->updated(); - } } \ No newline at end of file diff --git a/app/controllers/apis/ClientApiController.php b/app/controllers/apis/ClientApiController.php index be5a1167..21d106e0 100644 --- a/app/controllers/apis/ClientApiController.php +++ b/app/controllers/apis/ClientApiController.php @@ -8,7 +8,7 @@ use oauth2\services\ITokenService; use utils\services\ILogService; use utils\exceptions\EntityNotFoundException; use oauth2\exceptions\InvalidApiScope; - +use utils\services\IAuthService; /** * Class ClientApiController * Client REST API @@ -29,25 +29,25 @@ final class ClientApiController extends AbstractRESTController implements ICRUDC */ private $token_service; - /** - * @param IApiScopeService $scope_service - * @param ITokenService $token_service - * @param IClientService $client_service - * @param ILogService $log_service + * @var IAuthService */ + private $auth_service; + public function __construct ( IApiScopeService $scope_service, ITokenService $token_service, IClientService $client_service, + IAuthService $auth_service, ILogService $log_service ) { parent::__construct($log_service); $this->client_service = $client_service; - $this->scope_service = $scope_service; - $this->token_service = $token_service; + $this->scope_service = $scope_service; + $this->token_service = $token_service; + $this->auth_service = $auth_service; //set filters allowed values $this->allowed_filter_fields = array('user_id'); @@ -81,7 +81,6 @@ final class ClientApiController extends AbstractRESTController implements ICRUDC { try { $res = $this->client_service->deleteClientByIdentifier($id); - return $res ? $this->deleted() : $this->error404(array('error' => 'operation failed')); } catch (Exception $ex) { $this->log_service->error($ex); @@ -101,10 +100,10 @@ final class ClientApiController extends AbstractRESTController implements ICRUDC // Build the validation constraint set. $rules = array( - 'user_id' => 'required|integer', 'app_name' => 'required|alpha_dash|max:255', 'app_description' => 'required|freetext', 'website' => 'url', + 'admin_users' => 'user_ids', 'application_type' => 'required|applicationtype', ); @@ -120,47 +119,30 @@ final class ClientApiController extends AbstractRESTController implements ICRUDC if ($this->client_service->existClientAppName($values['app_name'])) { return $this->error400(array('error' => 'application Name already exists!.')); } + $admin_users = trim($values['admin_users']); + $admin_users = empty($admin_users) ? array():explode(',',$admin_users); - $new_client = $this->client_service->addClient($values['application_type'], intval($values['user_id']), - trim($values['app_name']), trim($values['app_description']), trim($values['website'])); + $new_client = $this->client_service->addClient + ( + $values['application_type'], + trim($values['app_name']), + trim($values['app_description']), + trim($values['website']), + $admin_users + ); - return $this->created(array('client_id' => $new_client->id)); + return $this->created + ( + array + ( + 'id' => $new_client->id, + 'client_id' => $new_client->client_id, + 'client_secret' => $new_client->client_secret, + ) + ); } catch (Exception $ex) { $this->log_service->error($ex); - - return $this->error500($ex); - } - } - - - /** - * @return mixed - */ - public function getByPage() - { - try { - //check for optional filters param on querystring - $fields = $this->getProjection(Input::get('fields', null)); - $filters = $this->getFilters(Input::except('fields', 'limit', 'offset')); - $page_nbr = intval(Input::get('offset', 1)); - $page_size = intval(Input::get('limit', 10)); - - $list = $this->client_service->getAll($page_nbr, $page_size, $filters, $fields); - $items = array(); - foreach ($list->getItems() as $client) { - $data = $client->toArray(); - $data['application_type'] = $client->getFriendlyApplicationType(); - array_push($items, $data); - } - - return $this->ok(array( - 'page' => $items, - 'total_items' => $list->getTotal() - )); - } catch (Exception $ex) { - $this->log_service->error($ex); - return $this->error500($ex); } } @@ -207,6 +189,7 @@ final class ClientApiController extends AbstractRESTController implements ICRUDC 'id_token_signed_response_alg' => 'sometimes|required|signing_alg', 'id_token_encrypted_response_alg' => 'sometimes|required|encrypted_alg', 'id_token_encrypted_response_enc' => 'sometimes|required|encrypted_enc', + 'admin_users' => 'user_ids', ); // Creates a Validator instance and validates the data. @@ -240,6 +223,42 @@ final class ClientApiController extends AbstractRESTController implements ICRUDC } } + /** + * @return mixed + */ + public function getByPage() + { + try { + + $items = array(); + $user = $this->auth_service->getCurrentUser(); + $clients = $user->getClients(); + + foreach ($clients as $client) + { + $data = $client->toArray(); + $data['application_type'] = $client->getFriendlyApplicationType(); + $data['is_own'] = $client->isOwner($this->auth_service->getCurrentUser()); + $data['modified_by'] = $client->getEditedByNice(); + array_push($items, $data); + } + + return $this->ok + ( + array + ( + 'page' => $items, + 'total_items' => count($items) + ) + ); + + } + catch (Exception $ex) + { + $this->log_service->error($ex); + return $this->error500($ex); + } + } public function addAllowedScope($id, $scope_id) { @@ -282,12 +301,10 @@ final class ClientApiController extends AbstractRESTController implements ICRUDC } } - public function activate($id) { try { $res = $this->client_service->activateClient($id, true); - return $res ? $this->ok() : $this->error404(array('error' => 'operation failed')); } catch (AbsentClientException $ex1) { $this->log_service->error($ex1); @@ -317,7 +334,6 @@ final class ClientApiController extends AbstractRESTController implements ICRUDC } } - public function regenerateClientSecret($id) { try diff --git a/app/controllers/apis/UserApiController.php b/app/controllers/apis/UserApiController.php index 51e5c5cb..563566c3 100644 --- a/app/controllers/apis/UserApiController.php +++ b/app/controllers/apis/UserApiController.php @@ -16,19 +16,38 @@ use utils\services\ILogService; use openid\services\IUserService; use oauth2\services\ITokenService; use oauth2\exceptions\ExpiredAccessTokenException; - +use auth\IUserRepository; /** * Class UserApiController */ class UserApiController extends AbstractRESTController implements ICRUDController { + /** + * @var IUserService + */ private $user_service; + /** + * @var ITokenService + */ private $token_service; - public function __construct(ILogService $log_service, IUserService $user_service,ITokenService $token_service){ + /** + * @var IUserRepository + */ + private $user_repository; + + public function __construct + ( + IUserRepository $user_repository, + ILogService $log_service, + IUserService $user_service, + ITokenService $token_service + ){ parent::__construct($log_service); - $this->user_service = $user_service; - $this->token_service = $token_service; + + $this->user_service = $user_service; + $this->token_service = $token_service; + $this->user_repository = $user_repository; } /** @@ -129,4 +148,27 @@ class UserApiController extends AbstractRESTController implements ICRUDControlle { // TODO: Implement update() method. } + + public function fetch() + { + $values = Input::all(); + if(!isset($values['t'])) return $this->error404(); + $term = $values['t']; + $users = $this->user_repository->getByEmailOrName($term); + if(count($users) > 0) + { + $list = array(); + foreach($users as $u) + { + array_push($list, array + ( + 'id' => $u->id, + 'value' => sprintf('%s', $u->getFullName()) + ) + ); + } + return $this->ok($list); + } + return $this->updated(); + } } \ No newline at end of file diff --git a/app/database/migrations/2016_02_24_205808_add_oauth_app_admins.php b/app/database/migrations/2016_02_24_205808_add_oauth_app_admins.php new file mode 100644 index 00000000..896c3dc7 --- /dev/null +++ b/app/database/migrations/2016_02_24_205808_add_oauth_app_admins.php @@ -0,0 +1,47 @@ +timestamps(); + + $table->bigInteger("oauth2_client_id")->unsigned(); + $table->index('oauth2_client_id'); + $table->foreign('oauth2_client_id') + ->references('id') + ->on('oauth2_client') + ->onDelete('cascade') + ->onUpdate('no action'); ; + + $table->bigInteger("user_id")->unsigned(); + $table->index('user_id'); + $table->foreign('user_id') + ->references('id') + ->on('openid_users') + ->onDelete('cascade') + ->onUpdate('no action'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('oauth2_client_admin_users'); + } + +} diff --git a/app/database/migrations/2016_02_25_132724_update_oauth2_client_admin_users.php b/app/database/migrations/2016_02_25_132724_update_oauth2_client_admin_users.php new file mode 100644 index 00000000..d93561a2 --- /dev/null +++ b/app/database/migrations/2016_02_25_132724_update_oauth2_client_admin_users.php @@ -0,0 +1,37 @@ +bigInteger('edited_by_id')->unsigned()->nullable(); + $table->index('edited_by_id'); + $table->foreign('edited_by_id')->references('id')->on('openid_users'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('oauth2_client', function($table) + { + $table->dropForeign('edited_by_id'); + $table->dropIndex('edited_by_id'); + $table->dropColumn('edited_by_id'); + }); + } + +} diff --git a/app/factories/FactoriesProvider.php b/app/factories/FactoriesProvider.php new file mode 100644 index 00000000..65a014af --- /dev/null +++ b/app/factories/FactoriesProvider.php @@ -0,0 +1,34 @@ + 0, + 'max_refresh_token_issuance_basis' => 0, + 'max_access_token_issuance_qty' => 0, + 'max_access_token_issuance_basis' => 0, + 'max_refresh_token_issuance_qty' => 0, + 'use_refresh_token' => false, + 'rotate_refresh_token' => false, + ) + ); + + $client->setOwner($owner); + + $client->app_name = $app_name; + $client->active = true; + $client->use_refresh_token = false; + $client->rotate_refresh_token = false; + + $client->application_type = $application_type; + + if ($client->client_type === IClient::ClientType_Confidential) + { + $client->token_endpoint_auth_method = OAuth2Protocol::TokenEndpoint_AuthMethod_ClientSecretBasic; + } + else + { + $client->token_endpoint_auth_method = OAuth2Protocol::TokenEndpoint_AuthMethod_None; + } + + return $client; + } +} \ No newline at end of file diff --git a/app/filters.php b/app/filters.php index 1e9af545..6cfa7e01 100644 --- a/app/filters.php +++ b/app/filters.php @@ -110,6 +110,13 @@ Route::filter('guest', function () { if (Auth::check()) return Redirect::to('/'); }); +Route::filter('user.logged', function () { + if (!Auth::check()) + { + return Response::json(array('error' => 'operation not allowed.'), 400); + } +}); + /* |-------------------------------------------------------------------------- | CSRF Protection Filter @@ -158,7 +165,30 @@ Route::filter('user.owns.client.policy',function($route, $request){ $client = $client_service->getClientByIdentifier($client_id); $user = $authentication_service->getCurrentUser(); - if (is_null($client) || intval($client->getUserId()) !== intval($user->getId())) + if (is_null($client) || !$client->isOwner($user)) + throw new Exception('invalid client id for current user'); + + } catch (Exception $ex) { + Log::error($ex); + return Response::json(array('error' => 'operation not allowed.'), 400); + } +}); + +Route::filter('user.can.edit.client.policy',function($route, $request){ + try{ + $authentication_service = ServiceLocator::getInstance()->getService(UtilsServiceCatalog::AuthenticationService); + $client_service = ServiceLocator::getInstance()->getService(OAuth2ServiceCatalog::ClientService); + $client_id = $route->getParameter('id'); + + if(is_null($client_id)) + $client_id = $route->getParameter('client_id'); + + if(is_null($client_id)) + $client_id = Input::get('client_id',null);; + + $client = $client_service->getClientByIdentifier($client_id); + $user = $authentication_service->getCurrentUser(); + if (is_null($client) || !$client->candEdit($user)) throw new Exception('invalid client id for current user'); } catch (Exception $ex) { diff --git a/app/libs/auth/User.php b/app/libs/auth/User.php index 1824cda9..ef9f12f4 100644 --- a/app/libs/auth/User.php +++ b/app/libs/auth/User.php @@ -217,7 +217,14 @@ class User extends BaseModelEloquent implements UserInterface, IOpenIdUser, IOAu public function getClients() { - return $this->clients()->get(); + $own_clients = $this->clients()->get(); + $managed_clients = $this->managed_clients()->get(); + return $own_clients->merge($managed_clients); + } + + public function managed_clients() + { + return $this->belongsToMany('Client', 'oauth2_client_admin_users', 'user_id', 'oauth2_client_id'); } /** diff --git a/app/libs/oauth2/factories/IOAuth2ClientFactory.php b/app/libs/oauth2/factories/IOAuth2ClientFactory.php new file mode 100644 index 00000000..6a776ba2 --- /dev/null +++ b/app/libs/oauth2/factories/IOAuth2ClientFactory.php @@ -0,0 +1,32 @@ +scopes()->attach($scope->id); + return $this; } /** @@ -47,6 +48,7 @@ class ApiScopeGroup extends BaseModelEloquent implements IEntity public function addUser(IOAuth2User $user) { $this->users()->attach($user->id); + return $this; } /** @@ -55,6 +57,13 @@ class ApiScopeGroup extends BaseModelEloquent implements IEntity public function removeScope(IOAuth2User $scope) { $this->scopes()->detach($scope->id); + return $this; + } + + public function removeAllScopes() + { + $this->scopes()->detach(); + return $this; } /** @@ -63,6 +72,13 @@ class ApiScopeGroup extends BaseModelEloquent implements IEntity public function removeUser(IOAuth2User $user) { $this->users()->detach($user->id); + return $this; + } + + public function removeAllUsers() + { + $this->users()->detach(); + return $this; } /** diff --git a/app/models/oauth2/Client.php b/app/models/oauth2/Client.php index 9968c3fc..5480712e 100644 --- a/app/models/oauth2/Client.php +++ b/app/models/oauth2/Client.php @@ -8,7 +8,7 @@ use oauth2\models\IClientPublicKey; use oauth2\models\JWTResponseInfo; use oauth2\models\TokenEndpointAuthInfo; use utils\model\BaseModelEloquent; - +use oauth2\models\IApiScope; /** * Class Client */ @@ -61,7 +61,8 @@ class Client extends BaseModelEloquent implements IClient 'id_token_encrypted_response_alg', 'id_token_encrypted_response_enc', 'redirect_uris', - 'allowed_origins' + 'allowed_origins', + 'edited_by_id', ); public static $valid_app_types = array @@ -103,6 +104,14 @@ class Client extends BaseModelEloquent implements IClient return $this->hasMany('ClientPublicKey','oauth2_client_id','id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function admin_users() + { + return $this->belongsToMany('auth\User','oauth2_client_admin_users','oauth2_client_id','user_id'); + } + /** * @param string $value */ @@ -129,7 +138,6 @@ class Client extends BaseModelEloquent implements IClient } } - public function access_tokens() { return $this->hasMany('AccessToken'); @@ -145,6 +153,11 @@ class Client extends BaseModelEloquent implements IClient return $this->belongsTo('auth\User'); } + public function edited_by() + { + return $this->belongsTo('auth\User','edited_by_id'); + } + public function resource_server() { return $this->belongsTo('ResourceServer'); @@ -155,6 +168,15 @@ class Client extends BaseModelEloquent implements IClient return $this->belongsToMany('ApiScope','oauth2_client_api_scope','client_id','scope_id'); } + /** + * @return $this + */ + public function removeAllScopes() + { + $this->scopes()->detach(); + return $this; + } + public function getClientId() { return $this->client_id; @@ -586,4 +608,89 @@ class Client extends BaseModelEloquent implements IClient } return false; } + + /** + * @param mixed $user + */ + public function addAdminUser($user) + { + $this->admin_users()->attach($user->id); + return $this; + } + + /** + * @param mixed $user + */ + public function removeAdminUser($user) + { + $this->admin_users()->detach($user->id); + return $this; + } + + public function removeAllAdminUsers(){ + $this->admin_users()->detach(); + return $this; + } + + /** + * @param $user + * @return bool + */ + public function candEdit($user) + { + $is_admin = $this->admin_users()->where('id', '=', $user->id)->count() > 0; + $is_owner = intval($this->user_id) === intval($user->id); + return $is_owner || $is_admin; + } + + /** + * @param $user + * @return bool + */ + public function canDelete($user) + { + return $this->isOwner($user); + } + + public function isOwner($user) + { + return intval($this->user_id) === intval($user->id); + } + + public function setOwner($user) + { + $this->user()->associate($user); + return $this; + } + + /** + * @param IApiScope $scope + * @return $this + */ + public function addScope(IApiScope $scope) + { + $this->scopes()->attach($scope->id); + return $this; + } + + /** + * @param $editing_user + * @return $this + */ + public function setEditedBy($editing_user){ + $this->edited_by()->associate($editing_user); + return $this; + } + + public function getEditedByNice() + { + $user = $this->edited_by()->first(); + return is_null($user)? 'N/A':$user->getEmail(); + } + + public function getOwnerNice() + { + $user = $this->user()->first(); + return is_null($user)? 'N/A':$user->getEmail(); + } } \ No newline at end of file diff --git a/app/repositories/EloquentClientRepository.php b/app/repositories/EloquentClientRepository.php index 1d8006ca..4ff09c15 100644 --- a/app/repositories/EloquentClientRepository.php +++ b/app/repositories/EloquentClientRepository.php @@ -40,7 +40,7 @@ final class EloquentClientRepository implements IClientRepository { * @param ILogService $log_service */ public function __construct(Client $client, ILogService $log_service){ - $this->client = $client; + $this->client = $client; $this->log_service = $log_service; } diff --git a/app/routes.php b/app/routes.php index e8bb587e..654105c3 100644 --- a/app/routes.php +++ b/app/routes.php @@ -80,14 +80,11 @@ Route::group(array("before" => array("ssl", "auth")), function () { Route::group(array('prefix' => 'admin', 'before' => 'ssl|auth'), function () { //client admin UI - Route::get('clients/edit/{id}', - array('before' => 'oauth2.enabled|user.owns.client.policy', 'uses' => 'AdminController@editRegisteredClient')); + Route::get('clients/edit/{id}', array('before' => 'oauth2.enabled|user.can.edit.client.policy', 'uses' => 'AdminController@editRegisteredClient')); Route::get('clients', array('before' => 'oauth2.enabled', 'uses' => 'AdminController@listOAuth2Clients')); - Route::get('/grants', array('before' => 'oauth2.enabled', 'uses' => 'AdminController@editIssuedGrants')); //oauth2 server admin UI Route::group(array('before' => 'oauth2.enabled|oauth2.server.admin'), function () { - Route::get('/api-scope-groups', 'AdminController@listApiScopeGroups'); Route::get('/api-scope-groups/{id}', 'AdminController@editApiScopeGroup'); Route::get('/resource-servers', 'AdminController@listResourceServers'); @@ -111,10 +108,9 @@ Route::group(array('prefix' => 'admin', 'before' => 'ssl|auth'), function () { //Admin Backend API Route::group(array('prefix' => 'admin/api/v1', 'before' => 'ssl|auth'), function () { Route::group(array('prefix' => 'users'), function () { - Route::delete('/{id}/locked', - array('before' => 'openstackid.server.admin.json', 'uses' => 'UserApiController@unlock')); - Route::delete('/{id}/token/{value}', - array('before' => 'is.current.user', 'uses' => 'UserApiController@revokeToken')); + Route::delete('/{id}/locked',array('before' => 'openstackid.server.admin.json', 'uses' => 'UserApiController@unlock')); + Route::delete('/{id}/token/{value}', array('before' => 'is.current.user', 'uses' => 'UserApiController@revokeToken')); + Route::get('/fetch', array('before' => 'user.logged', 'uses' => "UserApiController@fetch")); }); Route::group(array('prefix' => 'banned-ips', 'before' => 'openstackid.server.admin.json'), function () { @@ -127,34 +123,34 @@ Route::group(array('prefix' => 'admin/api/v1', 'before' => 'ssl|auth'), function Route::group(array('prefix' => 'clients'), function () { // public keys - Route::post('/{id}/public_keys', array('before' => 'user.owns.client.policy', 'uses' => 'ClientPublicKeyApiController@create')); - Route::get('/{id}/public_keys', array('before' => 'user.owns.client.policy', 'uses' => 'ClientPublicKeyApiController@getByPage')); - Route::delete('/{id}/public_keys/{public_key_id}', array('before' => 'user.owns.client.policy', 'uses' => 'ClientPublicKeyApiController@delete')); - Route::put('/{id}/public_keys/{public_key_id}', array('before' => 'user.owns.client.policy', 'uses' => 'ClientPublicKeyApiController@update')); + Route::post('/{id}/public_keys', array('before' => 'user.can.edit.client.policy', 'uses' => 'ClientPublicKeyApiController@create')); + Route::get('/{id}/public_keys', array('before' => 'user.can.edit.client.policy', 'uses' => 'ClientPublicKeyApiController@getByPage')); + Route::delete('/{id}/public_keys/{public_key_id}', array('before' => 'user.can.edit.client.policy', 'uses' => 'ClientPublicKeyApiController@delete')); + Route::put('/{id}/public_keys/{public_key_id}', array('before' => 'user.can.edit.client.policy', 'uses' => 'ClientPublicKeyApiController@update')); Route::post('/', array('before' => 'is.current.user', 'uses' => 'ClientApiController@create')); - Route::put('/', array('before' => 'user.owns.client.policy', 'uses' => 'ClientApiController@update')); + Route::put('/', array('before' => 'user.can.edit.client.policy', 'uses' => 'ClientApiController@update')); Route::get('/{id}', "ClientApiController@get"); Route::get('/', array('before' => 'is.current.user', 'uses' => 'ClientApiController@getByPage')); Route::delete('/{id}', array('before' => 'user.owns.client.policy', 'uses' => 'ClientApiController@delete')); //allowed redirect uris endpoints - Route::get('/{id}/uris', array('before' => 'user.owns.client.policy', 'uses' => 'ClientApiController@getRegisteredUris')); - Route::post('/{id}/uris', array('before' => 'user.owns.client.policy', 'uses' => 'ClientApiController@addAllowedRedirectUri')); - Route::delete('/{id}/uris/{uri_id}', array('before' => 'user.owns.client.policy', 'uses' => 'ClientApiController@deleteClientAllowedUri')); + Route::get('/{id}/uris', array('before' => 'user.can.edit.client.policy', 'uses' => 'ClientApiController@getRegisteredUris')); + Route::post('/{id}/uris', array('before' => 'user.can.edit.client.policy', 'uses' => 'ClientApiController@addAllowedRedirectUri')); + Route::delete('/{id}/uris/{uri_id}', array('before' => 'user.can.edit.client.policy', 'uses' => 'ClientApiController@deleteClientAllowedUri')); //allowed origin endpoints endpoints - Route::get('/{id}/origins', array('before' => 'user.owns.client.policy', 'uses' => 'ClientApiController@geAllowedOrigins')); - Route::post('/{id}/origins', array('before' => 'user.owns.client.policy', 'uses' => 'ClientApiController@addAllowedOrigin')); - Route::delete('/{id}/origins/{origin_id}', array('before' => 'user.owns.client.policy', 'uses' => 'ClientApiController@deleteClientAllowedOrigin')); + Route::get('/{id}/origins', array('before' => 'user.can.edit.client.policy', 'uses' => 'ClientApiController@geAllowedOrigins')); + Route::post('/{id}/origins', array('before' => 'user.can.edit.client.policy', 'uses' => 'ClientApiController@addAllowedOrigin')); + Route::delete('/{id}/origins/{origin_id}', array('before' => 'user.can.edit.client.policy', 'uses' => 'ClientApiController@deleteClientAllowedOrigin')); Route::delete('/{id}/lock', array('before' => 'openstackid.server.admin.json', 'uses' => 'ClientApiController@unlock')); Route::put('/{id}/secret', array('before' => 'user.owns.client.policy', 'uses' => 'ClientApiController@regenerateClientSecret')); - Route::put('/{id}/use-refresh-token', array('before' => 'user.owns.client.policy', 'uses' => 'ClientApiController@setRefreshTokenClient')); - Route::put('/{id}/rotate-refresh-token', array('before' => 'user.owns.client.policy', 'uses' => 'ClientApiController@setRotateRefreshTokenPolicy')); - Route::get('/{id}/access-token', array('before' => 'user.owns.client.policy', 'uses' => 'ClientApiController@getAccessTokens')); - Route::get('/{id}/refresh-token', array('before' => 'user.owns.client.policy', 'uses' => 'ClientApiController@getRefreshTokens')); - Route::delete('/{id}/token/{value}/{hint}', array('before' => 'user.owns.client.policy', 'uses' => 'ClientApiController@revokeToken')); - Route::put('/{id}/scopes/{scope_id}', array('before' => 'user.owns.client.policy', 'uses' => 'ClientApiController@addAllowedScope')); - Route::delete('/{id}/scopes/{scope_id}', array('before' => 'user.owns.client.policy', 'uses' => 'ClientApiController@removeAllowedScope')); + Route::put('/{id}/use-refresh-token', array('before' => 'user.can.edit.client.policy', 'uses' => 'ClientApiController@setRefreshTokenClient')); + Route::put('/{id}/rotate-refresh-token', array('before' => 'user.can.edit.client.policy', 'uses' => 'ClientApiController@setRotateRefreshTokenPolicy')); + Route::get('/{id}/access-token', array('before' => 'user.can.edit.client.policy', 'uses' => 'ClientApiController@getAccessTokens')); + Route::get('/{id}/refresh-token', array('before' => 'user.can.edit.client.policy', 'uses' => 'ClientApiController@getRefreshTokens')); + Route::delete('/{id}/token/{value}/{hint}', array('before' => 'user.can.edit.client.policy', 'uses' => 'ClientApiController@revokeToken')); + Route::put('/{id}/scopes/{scope_id}', array('before' => 'user.can.edit.client.policy', 'uses' => 'ClientApiController@addAllowedScope')); + Route::delete('/{id}/scopes/{scope_id}', array('before' => 'user.can.edit.client.policy', 'uses' => 'ClientApiController@removeAllowedScope')); Route::put('/{id}/active', array('before' => 'user.owns.client.policy', 'uses' => 'ClientApiController@activate')); Route::delete('/{id}/active', array('before' => 'user.owns.client.policy', 'uses' => 'ClientApiController@deactivate')); @@ -181,7 +177,6 @@ Route::group(array('prefix' => 'admin/api/v1', 'before' => 'ssl|auth'), function Route::delete('/{id}', "ApiScopeGroupController@delete"); Route::put('/{id}/active', "ApiScopeGroupController@activate"); Route::delete('/{id}/active', "ApiScopeGroupController@deactivate"); - Route::get('/users', "ApiScopeGroupController@fetchUsers"); }); // apis diff --git a/app/services/oauth2/ApiScopeGroupService.php b/app/services/oauth2/ApiScopeGroupService.php index 68d873f9..ff7f9021 100644 --- a/app/services/oauth2/ApiScopeGroupService.php +++ b/app/services/oauth2/ApiScopeGroupService.php @@ -116,8 +116,7 @@ final class ApiScopeGroupService implements IApiScopeGroupService } } else if($param === 'users'){ - $ids = $group->users()->getRelatedIds(); - $group->users()->detach($ids); + $group->removeAllUsers(); $users = explode(',', $params['users']); foreach($users as $user_id) { diff --git a/app/services/oauth2/ClienPublicKeyService.php b/app/services/oauth2/ClienPublicKeyService.php index deccc0b7..a3487c64 100644 --- a/app/services/oauth2/ClienPublicKeyService.php +++ b/app/services/oauth2/ClienPublicKeyService.php @@ -23,6 +23,7 @@ use ClientPublicKey; use oauth2\repositories\IClientRepository; use DB; use ValidationException; +use utils\services\IAuthService; /** * Class ClienPublicKeyService * @package services\oauth2 @@ -35,13 +36,20 @@ final class ClienPublicKeyService extends AssymetricKeyService implements IClien */ private $client_repository; + /** + * @var IAuthService + */ + private $auth_service; + public function __construct( IClientPublicKeyRepository $repository, - IClientRepository $client_repository, - ITransactionService $tx_service) + IClientRepository $client_repository, + IAuthService $auth_service, + ITransactionService $tx_service + ) { - $this->client_repository = $client_repository; + $this->auth_service = $auth_service; parent::__construct($repository, $tx_service); } @@ -52,9 +60,9 @@ final class ClienPublicKeyService extends AssymetricKeyService implements IClien public function register(array $params) { $client_repository = $this->client_repository; - $repository = $this->repository; - - return $this->tx_service->transaction(function() use($params, $repository, $client_repository) + $repository = $this->repository; + $auth_service = $this->auth_service; + return $this->tx_service->transaction(function() use($params, $repository, $client_repository, $auth_service) { if ($repository->getByPEM($params['pem_content'])) @@ -95,6 +103,8 @@ final class ClienPublicKeyService extends AssymetricKeyService implements IClien ); $client->addPublicKey($public_key); + $client->setEditedBy($auth_service->getCurrentUser()); + $client_repository->add($client); return $public_key; }); } diff --git a/app/services/oauth2/ClientService.php b/app/services/oauth2/ClientService.php index 3393fd69..d3f42c4e 100644 --- a/app/services/oauth2/ClientService.php +++ b/app/services/oauth2/ClientService.php @@ -2,6 +2,7 @@ namespace services\oauth2; +use auth\IUserRepository; use Client; use DB; use Event; @@ -21,13 +22,15 @@ use oauth2\services\IApiScopeService; use oauth2\services\IClientCrendentialGenerator; use oauth2\services\IClientService; use oauth2\services\id; -use Request; use URL\Normalizer; use utils\db\ITransactionService; use utils\exceptions\EntityNotFoundException; use utils\http\HttpUtils; use utils\services\IAuthService; - +use openid\model\IOpenIdUser; +use oauth2\repositories\IClientRepository; +use oauth2\factories\IOAuth2ClientFactory; +use Request; /** * Class ClientService * @package services\oauth2 @@ -43,28 +46,42 @@ class ClientService implements IClientService */ private $scope_service; + /** + * @var IUserRepository + */ + private $user_repository; /** * @var IClientCrendentialGenerator */ private $client_credential_generator; /** - * @param IAuthService $auth_service - * @param IApiScopeService $scope_service - * @param IClientCrendentialGenerator $client_credential_generator - * @param ITransactionService $tx_service + * @var IClientRepository */ + private $client_repository; + + /** + * @var IOAuth2ClientFactory + */ + private $client_factory; + public function __construct ( + IUserRepository $user_repository, + IClientRepository $client_repository, IAuthService $auth_service, IApiScopeService $scope_service, IClientCrendentialGenerator $client_credential_generator, + IOAuth2ClientFactory $client_factory, ITransactionService $tx_service ) { $this->auth_service = $auth_service; + $this->user_repository = $user_repository; $this->scope_service = $scope_service; $this->client_credential_generator = $client_credential_generator; + $this->client_repository = $client_repository; + $this->client_factory = $client_factory; $this->tx_service = $tx_service; } @@ -141,55 +158,54 @@ class ClientService implements IClientService throw new InvalidClientAuthMethodException; } - public function addClient($application_type, $user_id, $app_name, $app_description, $app_url = null, $app_logo = '') + /** + * @param string $application_type + * @param string $app_name + * @param string $app_description + * @param null|string $app_url + * @param array $admin_users + * @param string $app_logo + * @return IClient + */ + public function addClient + ( + $application_type, + $app_name, + $app_description, + $app_url = null, + array $admin_users = array(), + $app_logo = '' + ) { - $scope_service = $this->scope_service; + $scope_service = $this->scope_service; $client_credential_generator = $this->client_credential_generator; + $user_repository = $this->user_repository; + $client_repository = $this->client_repository; + $client_factory = $this->client_factory; + $current_user = $this->auth_service->getCurrentUser(); return $this->tx_service->transaction(function () use ( $application_type, - $user_id, + $current_user, $app_name, $app_url, $app_description, $app_logo, + $admin_users, $scope_service, + $user_repository, + $client_repository, + $client_factory, $client_credential_generator ) { - $client = new Client - ( - array - ( - 'max_auth_codes_issuance_basis' => 0, - 'max_refresh_token_issuance_basis' => 0, - 'max_access_token_issuance_qty' => 0, - 'max_access_token_issuance_basis' => 0, - 'max_refresh_token_issuance_qty' => 0, - 'use_refresh_token' => false, - 'rotate_refresh_token' => false, - ) - ); - - $client->app_name = $app_name; - $client->app_logo = $app_logo; - $client->app_description = $app_description; - $client->application_type = $application_type; + $client = $client_factory->build($app_name,$current_user, $application_type); $client = $client_credential_generator->generate($client); - if ($client->client_type === IClient::ClientType_Confidential) { - $client->token_endpoint_auth_method = OAuth2Protocol::TokenEndpoint_AuthMethod_ClientSecretBasic; - } else { - $client->token_endpoint_auth_method = OAuth2Protocol::TokenEndpoint_AuthMethod_None; - } - - $client->user_id = $user_id; - $client->active = true; - $client->use_refresh_token = false; - $client->rotate_refresh_token = false; - $client->website = $app_url; - $client->Save(); - + $client->app_logo = $app_logo; + $client->app_description = $app_description; + $client->website = $app_url; + $client_repository->add($client); //add default scopes $default_scopes = $scope_service->getDefaultScopes(); @@ -204,259 +220,44 @@ class ClientService implements IClientService ) { continue; } - $client->scopes()->attach($default_scope->id); + $client->addScope($default_scope); + } + + //add admin users + foreach($admin_users as $user_id) + { + $user = $user_repository->get(intval($user_id)); + if(is_null($user)) throw new EntityNotFoundException(sprintf('user %s not found.',$user_id)); + $client->addAdminUser($user); } return $client; }); } - public function addClientScope($id, $scope_id) - { - $client = Client::find($id); - if (is_null($client)) { - throw new EntityNotFoundException(sprintf("client id %s not found!.", $id)); - } - $scope = $this->scope_service->get(intval($scope_id)); - if(is_null($scope)) throw new EntityNotFoundException(sprintf("scope %s not found!.", $scope_id)); - $user = $client->user()->first(); - - if($scope->isAssignableByGroups()) { - - $allowed = false; - foreach($user->getGroupScopes() as $group_scope) - { - if(intval($group_scope->id) === intval($scope_id)) - { - $allowed = true; break; - } - } - if(!$allowed) throw new InvalidApiScope(sprintf('you cant assign to this client api scope %s', $scope_id)); - } - if($scope->isSystem() && !$user->canUseSystemScopes()) - throw new InvalidApiScope(sprintf('you cant assign to this client api scope %s', $scope_id)); - return $client->scopes()->attach($scope_id); - } - - public function deleteClientScope($id, $scope_id) - { - $client = Client::find($id); - if (is_null($client)) { - throw new AbsentClientException(sprintf("client id %s does not exists!", $id)); - } - - return $client->scopes()->detach($scope_id); - } - - public function deleteClientByIdentifier($id) - { - $res = false; - $this->tx_service->transaction(function () use ($id, &$res) { - $client = Client::find($id); - if (!is_null($client)) { - $client->scopes()->detach(); - Event::fire('oauth2.client.delete', array($client->client_id)); - $res = $client->delete(); - } - }); - return $res; - } - - /** - * Regenerates Client Secret - * @param $id client id - * @return IClient - */ - public function regenerateClientSecret($id) - { - $client_credential_generator = $this->client_credential_generator; - - return $this->tx_service->transaction(function () use ($id, $client_credential_generator) - { - - $client = Client::find($id); - - if (is_null($client)) - { - throw new AbsentClientException(sprintf("client id %d does not exists!.", $id)); - } - - if ($client->client_type != IClient::ClientType_Confidential) - { - throw new InvalidClientType - ( - sprintf - ( - "client id %d is not confidential type!.", - $id - ) - ); - } - - $client_credential_generator->generate($client, true)->save(); - - Event::fire('oauth2.client.regenerate.secret', array($client->client_id)); - return $client; - }); - } - - /** - * @param client $client_id - * @return mixed - * @throws \oauth2\exceptions\AbsentClientException - */ - public function lockClient($client_id) - { - $res = false; - $this_var = $this; - - $this->tx_service->transaction(function () use ($client_id, &$res, &$this_var) { - - $client = $this_var->getClientByIdentifier($client_id); - if (is_null($client)) { - throw new AbsentClientException($client_id, sprintf("client id %s does not exists!", $client_id)); - } - $client->locked = true; - $res = $client->Save(); - }); - - return $res; - } - - /** - * @param client $client_id - * @return mixed - * @throws \oauth2\exceptions\AbsentClientException - */ - public function unlockClient($client_id) - { - $res = false; - $this_var = $this; - - $this->tx_service->transaction(function () use ($client_id, &$res, &$this_var) { - - $client = $this_var->getClientByIdentifier($client_id); - if (is_null($client)) { - throw new AbsentClientException($client_id, sprintf("client id %s does not exists!", $client_id)); - } - $client->locked = false; - $res = $client->Save(); - }); - - return $res; - } - - /** - * @param $client_id - * @return IClient - */ - public function getClientById($client_id) - { - $client = Client::where('client_id', '=', $client_id)->first(); - - return $client; - } - - public function activateClient($id, $active) - { - $client = $this->getClientByIdentifier($id); - if (is_null($client)) { - throw new AbsentClientException(sprintf("client id %s does not exists!", $id)); - } - $client->active = $active; - - return $client->Save(); - } - - public function getClientByIdentifier($id) - { - $client = Client::where('id', '=', $id)->first(); - - return $client; - } - - public function setRefreshTokenUsage($id, $use_refresh_token) - { - $client = $this->getClientByIdentifier($id); - if (is_null($client)) { - throw new AbsentClientException(sprintf("client id %s does not exists!", $id)); - } - $client->use_refresh_token = $use_refresh_token; - - return $client->Save(); - } - - public function setRotateRefreshTokenPolicy($id, $rotate_refresh_token) - { - $client = $this->getClientByIdentifier($id); - if (is_null($client)) { - throw new AbsentClientException(sprintf("client id %s does not exists!", $id)); - } - - $client->rotate_refresh_token = $rotate_refresh_token; - - return $client->Save(); - } - - public function existClientAppName($app_name) - { - return Client::where('app_name', '=', $app_name)->count() > 0; - } - - /** - * gets an api scope by id - * @param $id id of api scope - * @return IApiScope - */ - public function get($id) - { - return Client::find($id); - } - - /** - * @param int $page_nbr - * @param int $page_size - * @param array $filters - * @param array $fields - * @return mixed - */ - public function getAll($page_nbr = 1, $page_size = 10, array $filters = array(), array $fields = array('*')) - { - DB::getPaginator()->setCurrentPage($page_nbr); - - return Client::Filter($filters)->paginate($page_size, $fields); - } - - /** - * @param IClient $client - * @return bool - */ - public function save(IClient $client) - { - if (!$client->exists() || count($client->getDirty()) > 0) { - return $client->Save(); - } - - return true; - } - /** * @param $id * @param array $params - * @return bool - * @throws \oauth2\exceptions\AbsentClientException + * @throws AbsentClientException + * @throws \ValidationException + * @return mixed */ public function update($id, array $params) { - $this_var = $this; + $this_var = $this; + $client_repository = $this->client_repository; + $user_repository = $this->user_repository; + $editing_user = $this->auth_service->getCurrentUser(); - return $this->tx_service->transaction(function () use ($id, $params, &$this_var) { + return $this->tx_service->transaction(function () use ($id, $editing_user, $params, $client_repository, $user_repository, &$this_var) { + + $client = $client_repository->get($id); - $client = Client::find($id); if (is_null($client)) { throw new AbsentClientException(sprintf('client id %s does not exists.', $id)); } + $current_app_type = $client->getApplicationType(); if($current_app_type !== $params['application_type']) { @@ -558,6 +359,7 @@ class ClientService implements IClientService 'id_token_encrypted_response_enc', 'redirect_uris', 'allowed_origins', + 'admin_users', ); $fields_to_uri_normalize = array @@ -574,32 +376,269 @@ class ClientService implements IClientService foreach ($allowed_update_params as $param) { + if (array_key_exists($param, $params)) { - if(in_array($param, $fields_to_uri_normalize)) - { - $urls = $params[$param]; - if(!empty($urls)) + if($param === 'admin_users'){ + $admin_users = trim($params['admin_users']); + $admin_users = empty($admin_users) ? array():explode(',',$admin_users); + $client->removeAllAdminUsers(); + foreach($admin_users as $user_id) { - $urls = explode(',', $urls); - $normalized_uris = ''; - foreach ($urls as $url) { - $un = new Normalizer($url); - $url = $un->normalize(); - if (!empty($normalized_uris)) { - $normalized_uris .= ','; - } - $normalized_uris .= $url; - } - $params[$param] = $normalized_uris; + $user = $user_repository->get(intval($user_id)); + if(is_null($user)) throw new EntityNotFoundException(sprintf('user %s not found.',$user_id)); + $client->addAdminUser($user); } } - $client->{$param} = $params[$param]; + else { + if (in_array($param, $fields_to_uri_normalize)) { + $urls = $params[$param]; + if (!empty($urls)) { + $urls = explode(',', $urls); + $normalized_uris = ''; + foreach ($urls as $url) { + $un = new Normalizer($url); + $url = $un->normalize(); + if (!empty($normalized_uris)) { + $normalized_uris .= ','; + } + $normalized_uris .= $url; + } + $params[$param] = $normalized_uris; + } + } + $client->{$param} = $params[$param]; + } + } + + } + $client_repository->add($client->setEditedBy($editing_user)); + return $client; + }); + } + + public function addClientScope($id, $scope_id) + { + $client = Client::find($id); + if (is_null($client)) { + throw new EntityNotFoundException(sprintf("client id %s not found!.", $id)); + } + $scope = $this->scope_service->get(intval($scope_id)); + if(is_null($scope)) throw new EntityNotFoundException(sprintf("scope %s not found!.", $scope_id)); + $user = $client->user()->first(); + + if($scope->isAssignableByGroups()) { + + $allowed = false; + foreach($user->getGroupScopes() as $group_scope) + { + if(intval($group_scope->id) === intval($scope_id)) + { + $allowed = true; break; } } - return $this_var->save($client); + if(!$allowed) throw new InvalidApiScope(sprintf('you cant assign to this client api scope %s', $scope_id)); + } + if($scope->isSystem() && !$user->canUseSystemScopes()) + throw new InvalidApiScope(sprintf('you cant assign to this client api scope %s', $scope_id)); + $client->scopes()->attach($scope_id); + $client->setEditedBy($this->auth_service->getCurrentUser()); + $client->save(); + return $client; + } + + public function deleteClientScope($id, $scope_id) + { + $client = Client::find($id); + if (is_null($client)) { + throw new AbsentClientException(sprintf("client id %s does not exists!", $id)); + } + $client->scopes()->detach($scope_id); + $client->setEditedBy($this->auth_service->getCurrentUser()); + $client->save(); + return $client; + } + + public function deleteClientByIdentifier($id) + { + $res = false; + $this->tx_service->transaction(function () use ($id, &$res) { + $client = Client::find($id); + if (!is_null($client)) { + $client->scopes()->detach(); + Event::fire('oauth2.client.delete', array($client->client_id)); + $res = $client->delete(); + } + }); + return $res; + } + + /** + * Regenerates Client Secret + * @param $id client id + * @return IClient + */ + public function regenerateClientSecret($id) + { + $client_credential_generator = $this->client_credential_generator; + $current_user = $this->auth_service->getCurrentUser(); + + return $this->tx_service->transaction(function () use ($id, $current_user, $client_credential_generator) + { + + $client = Client::find($id); + + if (is_null($client)) + { + throw new AbsentClientException(sprintf("client id %d does not exists!.", $id)); + } + + if ($client->client_type != IClient::ClientType_Confidential) + { + throw new InvalidClientType + ( + sprintf + ( + "client id %d is not confidential type!.", + $id + ) + ); + } + + $client = $client_credential_generator->generate($client, true); + $client->setEditedBy($current_user); + $client->save(); + + Event::fire('oauth2.client.regenerate.secret', array($client->client_id)); + return $client; + }); + } + + /** + * @param client $client_id + * @return mixed + * @throws \oauth2\exceptions\AbsentClientException + */ + public function lockClient($client_id) + { + $res = false; + $this_var = $this; + + $this->tx_service->transaction(function () use ($client_id, &$res, &$this_var) { + + $client = $this_var->getClientByIdentifier($client_id); + if (is_null($client)) { + throw new AbsentClientException($client_id, sprintf("client id %s does not exists!", $client_id)); + } + $client->locked = true; + $res = $client->Save(); }); + return $res; + } + + /** + * @param client $client_id + * @return mixed + * @throws \oauth2\exceptions\AbsentClientException + */ + public function unlockClient($client_id) + { + $res = false; + $this_var = $this; + + $this->tx_service->transaction(function () use ($client_id, &$res, &$this_var) { + + $client = $this_var->getClientByIdentifier($client_id); + if (is_null($client)) { + throw new AbsentClientException($client_id, sprintf("client id %s does not exists!", $client_id)); + } + $client->locked = false; + $res = $client->Save(); + }); + + return $res; + } + + /** + * @param $client_id + * @return IClient + */ + public function getClientById($client_id) + { + $client = Client::where('client_id', '=', $client_id)->first(); + + return $client; + } + + public function activateClient($id, $active) + { + $client = $this->getClientByIdentifier($id); + if (is_null($client)) { + throw new AbsentClientException(sprintf("client id %s does not exists!", $id)); + } + $client->active = $active; + + return $client->Save(); + } + + public function getClientByIdentifier($id) + { + $client = Client::where('id', '=', $id)->first(); + + return $client; + } + + public function setRefreshTokenUsage($id, $use_refresh_token) + { + $client = $this->getClientByIdentifier($id); + if (is_null($client)) { + throw new AbsentClientException(sprintf("client id %s does not exists!", $id)); + } + $client->use_refresh_token = $use_refresh_token; + $client->setEditedBy($this->auth_service->getCurrentUser()); + return $client->Save(); + } + + public function setRotateRefreshTokenPolicy($id, $rotate_refresh_token) + { + $client = $this->getClientByIdentifier($id); + if (is_null($client)) { + throw new AbsentClientException(sprintf("client id %s does not exists!", $id)); + } + + $client->rotate_refresh_token = $rotate_refresh_token; + $client->setEditedBy($this->auth_service->getCurrentUser()); + return $client->Save(); + } + + public function existClientAppName($app_name) + { + return Client::where('app_name', '=', $app_name)->count() > 0; + } + + /** + * gets an api scope by id + * @param $id id of api scope + * @return IApiScope + */ + public function get($id) + { + return Client::find($id); + } + + /** + * @param int $page_nbr + * @param int $page_size + * @param array $filters + * @param array $fields + * @return mixed + */ + public function getAll($page_nbr = 1, $page_size = 10, array $filters = array(), array $fields = array('*')) + { + DB::getPaginator()->setCurrentPage($page_nbr); + + return Client::Filter($filters)->paginate($page_size, $fields); } /** diff --git a/app/validators/CustomValidator.php b/app/validators/CustomValidator.php index 594dbff3..bdbabf08 100644 --- a/app/validators/CustomValidator.php +++ b/app/validators/CustomValidator.php @@ -338,4 +338,14 @@ class CustomValidator extends Validator if(is_array($value)) $value = $value[0]; return in_array($value, $valid_values); } + + public function validateUserIds($attribute, $value, $parameters) + { + $user_ids = explode(',',$value); + foreach($user_ids as $id) + { + if(!intval($id)) return false; + } + return true; + } } \ No newline at end of file diff --git a/app/views/layout.blade.php b/app/views/layout.blade.php index 85b875f1..3a6ba319 100644 --- a/app/views/layout.blade.php +++ b/app/views/layout.blade.php @@ -8,6 +8,7 @@ {{ HTML::style('assets/css/main.css') }} {{ HTML::style('bower_assets/jquery-ui/themes/ui-darkness/jquery-ui.css') }} {{ HTML::style('bower_assets/fontawesome/css/font-awesome.min.css') }} + {{ HTML::style('bower_assets/sweetalert/dist/sweetalert.css') }} @yield('css') @@ -31,10 +32,12 @@ {{ HTML::script('bower_assets/jquery-validate/dist/additional-methods.min.js')}} {{ HTML::script('bower_assets/pure-templates/libs/pure.min.js')}} {{ HTML::script('bower_assets/uri.js/src/URI.min.js')}} + {{ HTML::script('bower_assets/sweetalert/dist/sweetalert.min.js')}} {{ HTML::script('assets/js/ajax.utils.js')}} {{ HTML::script('assets/js/jquery.cleanform.js')}} {{ HTML::script('assets/js/jquery.serialize.js')}} {{ HTML::script('assets/js/jquery.validate.additional.custom.methods.js')}} @yield('scripts') + \ No newline at end of file diff --git a/app/views/oauth2/profile/add-client-form.blade.php b/app/views/oauth2/profile/add-client-form.blade.php index 21ff8a25..8212a244 100644 --- a/app/views/oauth2/profile/add-client-form.blade.php +++ b/app/views/oauth2/profile/add-client-form.blade.php @@ -27,7 +27,12 @@ Service Account : The OpenstackId OAuth 2.0 Authorization Server supports server - + + +
+ + +