Implements: blueprint openid-oauth2-admin.backend-client-administration

[smarcet] - #5033 - Client Administration

Change-Id: If87a611f5f25646480478d7799339a6d5186a37f
This commit is contained in:
smarcet 2014-02-03 20:40:31 -03:00
parent 1523ed3225
commit ebeb5d2dbf
170 changed files with 4007 additions and 1703 deletions

View File

@ -6,11 +6,15 @@ use oauth2\services\IClientService;
use oauth2\services\ITokenService; use oauth2\services\ITokenService;
use oauth2\services\IResourceServerService; use oauth2\services\IResourceServerService;
use oauth2\services\IApiEndpointService; use oauth2\services\IApiEndpointService;
use utils\services\IAuthService;; use utils\services\IAuthService;
use openid\services\IUserService;
use utils\services\IServerConfigurationService;
use \utils\services\IBannedIPService;
/**
* Class AdminController
*/
class AdminController extends BaseController { class AdminController extends BaseController {
private $client_service; private $client_service;
private $scope_service; private $scope_service;
private $token_service; private $token_service;
@ -18,6 +22,9 @@ class AdminController extends BaseController {
private $api_service; private $api_service;
private $endpoint_service; private $endpoint_service;
private $auth_service; private $auth_service;
private $user_service;
private $configuration_service;
private $banned_ips_service;
public function __construct( IClientService $client_service, public function __construct( IClientService $client_service,
IApiScopeService $scope_service, IApiScopeService $scope_service,
@ -25,7 +32,10 @@ class AdminController extends BaseController {
IResourceServerService $resource_server_service, IResourceServerService $resource_server_service,
IApiService $api_service, IApiService $api_service,
IApiEndpointService $endpoint_service, IApiEndpointService $endpoint_service,
IAuthService $auth_service){ IAuthService $auth_service,
IUserService $user_service,
IServerConfigurationService $configuration_service,
IBannedIPService $banned_ips_service){
$this->client_service = $client_service; $this->client_service = $client_service;
$this->scope_service = $scope_service; $this->scope_service = $scope_service;
@ -34,9 +44,12 @@ class AdminController extends BaseController {
$this->api_service = $api_service; $this->api_service = $api_service;
$this->endpoint_service = $endpoint_service; $this->endpoint_service = $endpoint_service;
$this->auth_service = $auth_service; $this->auth_service = $auth_service;
$this->user_service = $user_service;
$this->configuration_service = $configuration_service;
$this->banned_ips_service = $banned_ips_service;
} }
public function getEditRegisteredClient($id) public function editRegisteredClient($id)
{ {
$user = $this->auth_service->getCurrentUser(); $user = $this->auth_service->getCurrentUser();
$client = $this->client_service->getClientByIdentifier($id); $client = $this->client_service->getClientByIdentifier($id);
@ -54,7 +67,7 @@ class AdminController extends BaseController {
array_push($aux_scopes, $scope->id); array_push($aux_scopes, $scope->id);
} }
$scopes = $this->scope_service->getAvailableScopes($user->canUseSystemScopes()); $scopes = $this->scope_service->getAvailableScopes($user->canUseSystemScopes());
$access_tokens = $this->token_service->getAccessTokenByClient($client->client_id); $access_tokens = $this->token_service->getAccessTokenByClient($client->client_id);
@ -77,47 +90,226 @@ class AdminController extends BaseController {
'selected_scopes' => $aux_scopes, 'selected_scopes' => $aux_scopes,
'scopes' => $scopes, 'scopes' => $scopes,
'access_tokens' => $access_tokens, 'access_tokens' => $access_tokens,
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
"is_openstackid_admin" => $user->isOpenstackIdAdmin(),
"use_system_scopes" => $user->canUseSystemScopes(),
'refresh_tokens' => $refresh_tokens, 'refresh_tokens' => $refresh_tokens,
)); ));
} }
public function listResourceServers() { public function listResourceServers() {
$user = $this->auth_service->getCurrentUser();
$resource_servers = $this->resource_server_service->getAll(1,1000); $resource_servers = $this->resource_server_service->getAll(1,1000);
return View::make("oauth2.profile.admin.resource-servers",array('resource_servers'=>$resource_servers)); return View::make("oauth2.profile.admin.resource-servers",array(
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
"is_openstackid_admin" => $user->isOpenstackIdAdmin(),
'resource_servers'=>$resource_servers));
} }
public function editResourceServer($id){ public function editResourceServer($id){
$resource_server = $this->resource_server_service->get($id); $resource_server = $this->resource_server_service->get($id);
if(is_null($resource_server)) if(is_null($resource_server))
return View::make('404'); return View::make('404');
return View::make("oauth2.profile.admin.edit-resource-server",array('resource_server'=>$resource_server)); $user = $this->auth_service->getCurrentUser();
return View::make("oauth2.profile.admin.edit-resource-server",array(
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
"is_openstackid_admin" => $user->isOpenstackIdAdmin(),
'resource_server'=>$resource_server
));
} }
public function editApi($id){ public function editApi($id){
$api = $this->api_service->get($id); $api = $this->api_service->get($id);
if(is_null($api)) if(is_null($api))
return View::make('404'); return View::make('404');
return View::make("oauth2.profile.admin.edit-api",array('api'=>$api)); $user = $this->auth_service->getCurrentUser();
return View::make("oauth2.profile.admin.edit-api",array(
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
"is_openstackid_admin" => $user->isOpenstackIdAdmin(),
'api'=>$api));
} }
public function editScope($id){ public function editScope($id){
$scope = $this->scope_service->get($id); $scope = $this->scope_service->get($id);
if(is_null($scope)) if(is_null($scope))
return View::make('404'); return View::make('404');
return View::make("oauth2.profile.admin.edit-scope",array('scope'=>$scope)); $user = $this->auth_service->getCurrentUser();
return View::make("oauth2.profile.admin.edit-scope",array(
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
"is_openstackid_admin" => $user->isOpenstackIdAdmin(),
'scope'=>$scope));
} }
public function editEndpoint($id){ public function editEndpoint($id){
$endpoint = $this->endpoint_service->get($id); $endpoint = $this->endpoint_service->get($id);
if(is_null($endpoint)) if(is_null($endpoint))
return View::make('404'); return View::make('404');
$user = $this->auth_service->getCurrentUser();
$selected_scopes = array(); $selected_scopes = array();
$list = $endpoint->scopes()->get(array('id')); $list = $endpoint->scopes()->get(array('id'));
foreach($list as $selected_scope){ foreach($list as $selected_scope){
array_push($selected_scopes,$selected_scope->id); array_push($selected_scopes,$selected_scope->id);
} }
return View::make("oauth2.profile.admin.edit-endpoint",array( return View::make("oauth2.profile.admin.edit-endpoint",array(
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
"is_openstackid_admin" => $user->isOpenstackIdAdmin(),
'endpoint' => $endpoint , 'endpoint' => $endpoint ,
'selected_scopes' => $selected_scopes)); 'selected_scopes' => $selected_scopes));
} }
public function editIssuedGrants(){
$user = $this->auth_service->getCurrentUser();
$access_tokens = $this->token_service->getAccessTokenByUserId($user->getId());
$refresh_tokens = $this->token_service->getRefreshTokeByUserId($user->getId());
foreach($access_tokens as $access_token){
$friendly_scopes = $this->scope_service->getFriendlyScopesByName(explode(' ',$access_token->scope));
$access_token->setFriendlyScopes(implode(', ',$friendly_scopes));
}
foreach($refresh_tokens as $refresh_token){
$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(),
));
}
public function listOAuth2Clients(){
$user = $this->auth_service->getCurrentUser();
$clients = $user->getClients();
return View::make("oauth2.profile.clients", array(
"username" => $user->getFullName(),
"user_id" => $user->getId(),
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
"is_openstackid_admin" => $user->isOpenstackIdAdmin(),
"use_system_scopes" => $user->canUseSystemScopes(),
'clients' => $clients,
));
}
public function listLockedClients(){
$user = $this->auth_service->getCurrentUser();
$clients = $this->client_service->getAll(1,1000,array(
array(
'name'=>'locked',
'op' => '=',
'value'=> true
)
));
return View::make("oauth2.profile.admin.clients", array(
"username" => $user->getFullName(),
"user_id" => $user->getId(),
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
"is_openstackid_admin" => $user->isOpenstackIdAdmin(),
'clients' => $clients,
));
}
public function listLockedUsers(){
$user = $this->auth_service->getCurrentUser();
$users = $this->user_service->getAll(1,1000,array(
array(
'name'=>'lock',
'op' => '=',
'value'=> true
)
));
return View::make("admin.users", array(
"username" => $user->getFullName(),
"user_id" => $user->getId(),
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
"is_openstackid_admin" => $user->isOpenstackIdAdmin(),
'users' => $users,
));
}
public function listServerConfig(){
$user = $this->auth_service->getCurrentUser();
$config_values = array();
$config_values['MaxFailed.Login.Attempts'] = $this->configuration_service->getConfigValue('MaxFailed.Login.Attempts');
$config_values['MaxFailed.LoginAttempts.2ShowCaptcha'] = $this->configuration_service->getConfigValue('MaxFailed.LoginAttempts.2ShowCaptcha');
$config_values['OpenId.Private.Association.Lifetime'] = $this->configuration_service->getConfigValue('OpenId.Private.Association.Lifetime');
$config_values['OpenId.Session.Association.Lifetime'] = $this->configuration_service->getConfigValue('OpenId.Session.Association.Lifetime');
$config_values['OpenId.Nonce.Lifetime'] = $this->configuration_service->getConfigValue('OpenId.Nonce.Lifetime');
$config_values['OAuth2.AuthorizationCode.Lifetime'] = $this->configuration_service->getConfigValue('OAuth2.AuthorizationCode.Lifetime');
$config_values['OAuth2.AccessToken.Lifetime'] = $this->configuration_service->getConfigValue('OAuth2.AccessToken.Lifetime');
$config_values['OAuth2.RefreshToken.Lifetime'] = $this->configuration_service->getConfigValue('OAuth2.RefreshToken.Lifetime');
return View::make("admin.server-config", array(
"username" => $user->getFullName(),
"user_id" => $user->getId(),
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
"is_openstackid_admin" => $user->isOpenstackIdAdmin(),
'config_values' => $config_values,
));
}
public function saveServerConfig(){
$values = Input::all();
$rules = array(
'general-max-failed-login-attempts' => 'required|integer',
'general-max-failed-login-attempts-captcha' => 'required|integer',
'openid-private-association-lifetime' => 'required|integer',
'openid-session-association-lifetime' => 'required|integer',
'openid-nonce-lifetime' => 'required|integer',
'oauth2-auth-code-lifetime' => 'required|integer',
'oauth2-refresh-token-lifetime' => 'required|integer',
'oauth2-access-token-lifetime' => 'required|integer',
);
$dictionary = array(
'general-max-failed-login-attempts' => 'MaxFailed.Login.Attempts',
'general-max-failed-login-attempts-captcha' => 'MaxFailed.LoginAttempts.2ShowCaptcha',
'openid-private-association-lifetime' => 'OpenId.Private.Association.Lifetime',
'openid-session-association-lifetime' => 'OpenId.Session.Association.Lifetime',
'openid-nonce-lifetime' => 'OpenId.Nonce.Lifetime',
'oauth2-auth-code-lifetime' => 'OAuth2.AuthorizationCode.Lifetime',
'oauth2-access-token-lifetime' => 'OAuth2.AccessToken.Lifetime',
'oauth2-refresh-token-lifetime' => 'OAuth2.RefreshToken.Lifetime',
);
// Creates a Validator instance and validates the data.
$validation = Validator::make($values, $rules);
if ($validation->fails()) {
return Redirect::action("AdminController@listServerConfig")->withErrors($validation);
}
foreach($values as $field=>$value){
if(array_key_exists($field,$dictionary))
$this->configuration_service->saveConfigValue($dictionary[$field],$value);
}
return Redirect::action("AdminController@listServerConfig");
}
public function listBannedIPs(){
$user = $this->auth_service->getCurrentUser();
$ips = $this->banned_ips_service->getByPage(1,1000);
return View::make("admin.banned-ips", array(
"username" => $user->getFullName(),
"user_id" => $user->getId(),
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
"is_openstackid_admin" => $user->isOpenstackIdAdmin(),
"ips" =>$ips
));
}
} }

View File

@ -17,7 +17,7 @@ class OpenIdProviderController extends BaseController
$this->memento_service = $memento_service; $this->memento_service = $memento_service;
} }
public function op_endpoint() public function endpoint()
{ {
$msg = $this->memento_service->getCurrentRequest(); $msg = $this->memento_service->getCurrentRequest();
if (is_null($msg) || !$msg->isValid()) if (is_null($msg) || !$msg->isValid())

View File

@ -212,12 +212,12 @@ class UserController extends BaseController
$user = $this->auth_service->getCurrentUser(); $user = $this->auth_service->getCurrentUser();
$sites = $this->trusted_sites_service->getAllTrustedSitesByUser($user); $sites = $this->trusted_sites_service->getAllTrustedSitesByUser($user);
$actions = $user->getActions(); $actions = $user->getActions();
$clients = $user->getClients();
return View::make("profile", array( return View::make("profile", array(
"username" => $user->getFullName(), "username" => $user->getFullName(),
"user_id" => $user->getId(), "user_id" => $user->getId(),
"is_server_admin" => $user->IsServerAdmin(), "is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
"is_openstackid_admin" => $user->isOpenstackIdAdmin(),
"use_system_scopes" => $user->canUseSystemScopes(), "use_system_scopes" => $user->canUseSystemScopes(),
"openid_url" => $this->server_configuration_service->getUserIdentityEndpointURL($user->getIdentifier()), "openid_url" => $this->server_configuration_service->getUserIdentityEndpointURL($user->getIdentifier()),
"identifier " => $user->getIdentifier(), "identifier " => $user->getIdentifier(),
@ -226,7 +226,6 @@ class UserController extends BaseController
"show_full_name" => $user->getShowProfileFullName(), "show_full_name" => $user->getShowProfileFullName(),
"show_email" => $user->getShowProfileEmail(), "show_email" => $user->getShowProfileEmail(),
'actions' => $actions, 'actions' => $actions,
'clients' => $clients,
)); ));
} }

View File

@ -5,43 +5,41 @@ use utils\services\ILogService;
abstract class AbstractRESTController extends JsonController { abstract class AbstractRESTController extends JsonController {
protected $allowed_filter_fields; protected $allowed_filter_fields;
protected $allowed_filter_op; protected $allowed_projection_fields;
protected $allowed_filter_value;
private $filter_delimiter; private $filter_delimiter;
private $field_delimiter; private $field_delimiter;
public function __construct(ILogService $log_service){ public function __construct(ILogService $log_service){
parent::__construct($log_service); parent::__construct($log_service);
$this->filter_delimiter = '|'; $this->filter_delimiter = '+';
$this->field_delimiter = ':'; $this->field_delimiter = ',';
}
protected function getProjection($fields){
if(!is_string($fields)) return array('*');
if(empty($fields)) return array('*');
$fields_args = explode($this->field_delimiter,$fields);
$res = array();
foreach($fields_args as $exp){
if(in_array($exp,$this->allowed_projection_fields)){
array_push($res,$exp);
}
}
if(!count($res))
$res = array('*');
return $res;
} }
/**
* @param $filters
* @return array
*/
protected function getFilters($filters){ protected function getFilters($filters){
if(!is_array($filters)) return array();
if(!is_string($filters)) return array();
if(empty($filters)) return array();
$filter_args = explode($this->filter_delimiter,$filters);
$res = array(); $res = array();
foreach($filter_args as $exp){ foreach($filters as $fieldname=>$value){
if(in_array($fieldname,$this->allowed_filter_fields)){
$exp = explode($this->field_delimiter,$exp); array_push($res,array('name'=>$fieldname,'op'=>'=','value'=>$value));
}
if(!is_array($exp) || count($exp)!=3) continue;
if(!in_array($exp[0],$this->allowed_filter_fields)) continue;
if(!in_array($exp[1],$this->allowed_filter_op[$exp[0]])) continue;
if(preg_match($this->allowed_filter_value[$exp[0]],$exp[2])!=1) continue;
array_push($res,array(
'name' => $exp[0],
'op' => $exp[1],
'value' => $exp[2],
));
} }
return $res; return $res;
} }

View File

@ -0,0 +1,95 @@
<?php
use utils\services\IBannedIPService;
use utils\services\ILogService;
class ApiBannedIPController extends AbstractRESTController implements ICRUDController
{
private $banned_ip_service;
public function __construct(IBannedIPService $banned_ip_service, ILogService $log_service)
{
parent::__construct($log_service);
$this->banned_ip_service = $banned_ip_service;
$this->allowed_filter_fields = array();
$this->allowed_projection_fields = array('*');
}
public function get($id)
{
try {
$ip = Input::get("ip", null);
if (!is_null($ip)) {
$banned_ip = $this->banned_ip_service->getByIP($ip);
} else {
$banned_ip = $this->banned_ip_service->get($id);
}
if (is_null($banned_ip)) {
return $this->error404(array('error' => 'banned ip not found'));
}
$data = $banned_ip->toArray();
return $this->ok($data);
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
public function create()
{
// TODO: Implement create() method.
}
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->banned_ip_service->getByPage($page_nbr, $page_size, $filters, $fields);
$items = array();
foreach ($list->getItems() as $ip) {
array_push($items, $ip->toArray());
}
return $this->ok(array(
'page' => $items,
'total_items' => $list->getTotal()
));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
public function delete($id = null)
{
try {
if (is_null($id)) {
$ip = Input::get("ip", null);
} else {
$banned_ip = $this->banned_ip_service->get($id);
$ip = $banned_ip->ip;
}
if (is_null($ip))
return $this->error400('invalid request');
$res = $this->banned_ip_service->delete($ip);
return $res ? $this->deleted() : $this->error404(array('error' => 'operation failed'));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
public function update()
{
// TODO: Implement update() method.
}
}

View File

@ -1,28 +1,25 @@
<?php <?php
use oauth2\IResourceServerContext;
use utils\services\ILogService; use utils\services\ILogService;
use oauth2\services\IApiService; use oauth2\services\IApiService;
use oauth2\exceptions\InvalidApi; use oauth2\exceptions\InvalidApi;
/** /**
* Class ApiController * Class ApiController
* REST controller for Api entity CRUD Ops * REST controller for Api entity CRUD Ops
*/ */
class ApiController extends AbstractRESTController implements IRESTController class ApiController extends AbstractRESTController implements ICRUDController
{ {
private $api_service; private $api_service;
public function __construct(IApiService $api_service, ILogService $log_service)
public function __construct(IApiService $api_service, ILogService $log_service)
{ {
parent::__construct($log_service); parent::__construct($log_service);
$this->api_service = $api_service; $this->api_service = $api_service;
//set filters allowed values //set filters allowed values
$this->allowed_filter_fields = array('resource_server_id'); $this->allowed_filter_fields = array('resource_server_id');
$this->allowed_filter_op = array('resource_server_id' => array('=')); $this->allowed_projection_fields = array('*');
$this->allowed_filter_value = array('resource_server_id' => '/^\d+$/');
} }
public function get($id) public function get($id)
@ -44,12 +41,15 @@ class ApiController extends AbstractRESTController implements IRESTController
} }
} }
public function getByPage($page_nbr, $page_size) public function getByPage()
{ {
try { try {
//check for optional filters param on querystring //check for optional filters param on querystring
$filters = Input::get('filters',null); $fields = $this->getProjection(Input::get('fields',null));
$list = $this->api_service->getAll($page_nbr,$page_size, $this->getFilters($filters)); $filters = $this->getFilters(Input::except('fields','limit','offset'));
$page_nbr = intval(Input::get('offset',1));
$page_size = intval(Input::get('limit',10));
$list = $this->api_service->getAll($page_nbr,$page_size, $filters,$fields);
$items = array(); $items = array();
foreach ($list->getItems() as $api) { foreach ($list->getItems() as $api) {
array_push($items, $api->toArray()); array_push($items, $api->toArray());
@ -91,7 +91,7 @@ class ApiController extends AbstractRESTController implements IRESTController
$new_api['resource_server_id'] $new_api['resource_server_id']
); );
return $this->ok(array('api_id' => $new_api_model->id)); return $this->created(array('api_id' => $new_api_model->id));
} }
catch (InvalidApi $ex1) { catch (InvalidApi $ex1) {
$this->log_service->error($ex1); $this->log_service->error($ex1);
@ -107,7 +107,7 @@ class ApiController extends AbstractRESTController implements IRESTController
{ {
try { try {
$res = $this->api_service->delete($id); $res = $this->api_service->delete($id);
return $res?Response::json('ok',200):$this->error404(array('error'=>'operation failed')); return $res?$this->deleted():$this->error404(array('error'=>'operation failed'));
} catch (Exception $ex) { } catch (Exception $ex) {
$this->log_service->error($ex); $this->log_service->error($ex);
return $this->error500($ex); return $this->error500($ex);
@ -136,7 +136,7 @@ class ApiController extends AbstractRESTController implements IRESTController
$res = $this->api_service->update(intval($values['id']),$values); $res = $this->api_service->update(intval($values['id']),$values);
return $res?Response::json('ok',200):$this->error400(array('error'=>'operation failed')); return $res?$this->ok():$this->error400(array('error'=>'operation failed'));
} }
catch(InvalidApi $ex1){ catch(InvalidApi $ex1){
@ -153,7 +153,7 @@ class ApiController extends AbstractRESTController implements IRESTController
try { try {
$active = is_string($active)?( strtoupper(trim($active))==='TRUE'?true:false ):$active; $active = is_string($active)?( strtoupper(trim($active))==='TRUE'?true:false ):$active;
$res = $this->api_service->setStatus($id,$active); $res = $this->api_service->setStatus($id,$active);
return $res?Response::json('ok',200):$this->error400(array('error'=>'operation failed')); return $res?$this->ok():$this->error400(array('error'=>'operation failed'));
} }
catch(InvalidApi $ex1){ catch(InvalidApi $ex1){
$this->log_service->error($ex1); $this->log_service->error($ex1);

View File

@ -1,9 +1,7 @@
<?php <?php
use oauth2\IResourceServerContext;
use utils\services\ILogService; use utils\services\ILogService;
use oauth2\services\IApiEndpointService; use oauth2\services\IApiEndpointService;
use oauth2\exceptions\InvalidApi;
use oauth2\exceptions\InvalidApiEndpoint; use oauth2\exceptions\InvalidApiEndpoint;
use oauth2\exceptions\InvalidApiScope; use oauth2\exceptions\InvalidApiScope;
@ -11,7 +9,7 @@ use oauth2\exceptions\InvalidApiScope;
* Class ApiEndpointController * Class ApiEndpointController
* REST Controller for Api endpoint entity CRUD ops * REST Controller for Api endpoint entity CRUD ops
*/ */
class ApiEndpointController extends AbstractRESTController implements IRESTController { class ApiEndpointController extends AbstractRESTController implements ICRUDController {
private $api_endpoint_service; private $api_endpoint_service;
@ -20,9 +18,8 @@ class ApiEndpointController extends AbstractRESTController implements IRESTContr
parent::__construct($log_service); parent::__construct($log_service);
$this->api_endpoint_service = $api_endpoint_service; $this->api_endpoint_service = $api_endpoint_service;
//set filters allowed values //set filters allowed values
$this->allowed_filter_fields = array('api_id'); $this->allowed_filter_fields = array('api_id');
$this->allowed_filter_op = array('api_id' => array('=')); $this->allowed_projection_fields = array('*');
$this->allowed_filter_value = array('api_id' => '/^\d+$/');
} }
public function get($id) public function get($id)
@ -42,12 +39,15 @@ class ApiEndpointController extends AbstractRESTController implements IRESTContr
} }
} }
public function getByPage($page_nbr, $page_size) public function getByPage()
{ {
try { try {
//check for optional filters param on querystring //check for optional filters param on querystring
$filters = Input::get('filters',null); $fields = $this->getProjection(Input::get('fields',null));
$list = $this->api_endpoint_service->getAll($page_nbr, $page_size, $this->getFilters($filters)); $filters = $this->getFilters(Input::except('fields','limit','offset'));
$page_nbr = intval(Input::get('offset',1));
$page_size = intval(Input::get('limit',10));
$list = $this->api_endpoint_service->getAll($page_nbr, $page_size, $filters,$fields);
$items = array(); $items = array();
foreach ($list->getItems() as $api_endpoint) { foreach ($list->getItems() as $api_endpoint) {
array_push($items, $api_endpoint->toArray()); array_push($items, $api_endpoint->toArray());
@ -92,7 +92,7 @@ class ApiEndpointController extends AbstractRESTController implements IRESTContr
$new_api_endpoint['http_method'], $new_api_endpoint['http_method'],
$new_api_endpoint['api_id'] $new_api_endpoint['api_id']
); );
return $this->ok(array('api_endpoint_id' => $new_api_endpoint_model->id)); return $this->created(array('api_endpoint_id' => $new_api_endpoint_model->id));
} }
catch (InvalidApiEndpoint $ex1) { catch (InvalidApiEndpoint $ex1) {
$this->log_service->error($ex1); $this->log_service->error($ex1);
@ -108,7 +108,7 @@ class ApiEndpointController extends AbstractRESTController implements IRESTContr
{ {
try { try {
$res = $this->api_endpoint_service->delete($id); $res = $this->api_endpoint_service->delete($id);
return $res?Response::json('ok',200):$this->error404(array('error'=>'operation failed')); return $res?$this->deleted():$this->error404(array('error'=>'operation failed'));
} }
catch (InvalidApiEndpoint $ex1) { catch (InvalidApiEndpoint $ex1) {
$this->log_service->error($ex1); $this->log_service->error($ex1);
@ -144,7 +144,7 @@ class ApiEndpointController extends AbstractRESTController implements IRESTContr
$res = $this->api_endpoint_service->update(intval($values['id']),$values); $res = $this->api_endpoint_service->update(intval($values['id']),$values);
return $res?Response::json('ok',200):$this->error400(array('error'=>'operation failed')); return $res?$this->ok():$this->error400(array('error'=>'operation failed'));
} }
catch(InvalidApiEndpoint $ex1){ catch(InvalidApiEndpoint $ex1){
$this->log_service->error($ex1); $this->log_service->error($ex1);
@ -159,7 +159,7 @@ class ApiEndpointController extends AbstractRESTController implements IRESTContr
public function updateStatus($id, $active){ public function updateStatus($id, $active){
try { try {
$res = $this->api_endpoint_service->setStatus($id,$active); $res = $this->api_endpoint_service->setStatus($id,$active);
return $res?Response::json('ok',200):$this->error400(array('error'=>'operation failed')); return $res?$this->ok():$this->error400(array('error'=>'operation failed'));
} }
catch (InvalidApiEndpoint $ex1) { catch (InvalidApiEndpoint $ex1) {
$this->log_service->error($ex1); $this->log_service->error($ex1);
@ -174,7 +174,7 @@ class ApiEndpointController extends AbstractRESTController implements IRESTContr
public function addRequiredScope($id, $scope_id){ public function addRequiredScope($id, $scope_id){
try { try {
$res = $this->api_endpoint_service->addRequiredScope($id,$scope_id); $res = $this->api_endpoint_service->addRequiredScope($id,$scope_id);
return $res?Response::json('ok',200):$this->error400(array('error'=>'operation failed')); return $res?$this->ok():$this->error400(array('error'=>'operation failed'));
} }
catch (InvalidApiEndpoint $ex1) { catch (InvalidApiEndpoint $ex1) {
$this->log_service->error($ex1); $this->log_service->error($ex1);
@ -193,7 +193,7 @@ class ApiEndpointController extends AbstractRESTController implements IRESTContr
public function removeRequiredScope($id, $scope_id){ public function removeRequiredScope($id, $scope_id){
try { try {
$res = $this->api_endpoint_service->removeRequiredScope($id,$scope_id); $res = $this->api_endpoint_service->removeRequiredScope($id,$scope_id);
return $res?Response::json('ok',200):$this->error400(array('error'=>'operation failed')); return $res?$this->ok():$this->error400(array('error'=>'operation failed'));
} }
catch (InvalidApiEndpoint $ex1) { catch (InvalidApiEndpoint $ex1) {
$this->log_service->error($ex1); $this->log_service->error($ex1);

View File

@ -6,7 +6,7 @@ use oauth2\exceptions\InvalidResourceServer;
/** /**
* Class ApiResourceServerController * Class ApiResourceServerController
*/ */
class ApiResourceServerController extends JsonController implements IRESTController class ApiResourceServerController extends AbstractRESTController implements ICRUDController
{ {
/** /**
* @var IResourceServerService $resource_service * @var IResourceServerService $resource_service
@ -17,6 +17,8 @@ class ApiResourceServerController extends JsonController implements IRESTControl
{ {
parent::__construct($log_service); parent::__construct($log_service);
$this->resource_server_service = $resource_server_service; $this->resource_server_service = $resource_server_service;
$this->allowed_filter_fields = array('');
$this->allowed_projection_fields = array('*');
} }
public function get($id) public function get($id)
@ -43,10 +45,15 @@ class ApiResourceServerController extends JsonController implements IRESTControl
} }
} }
public function getByPage($page_nbr, $page_size) public function getByPage()
{ {
try { try {
$list = $this->resource_server_service->getAll($page_nbr, $page_size); $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->resource_server_service->getAll($page_nbr, $page_size,$filters,$fields);
$items = array(); $items = array();
foreach ($list->getItems() as $rs) { foreach ($list->getItems() as $rs) {
array_push($items, $rs->toArray()); array_push($items, $rs->toArray());
@ -86,7 +93,7 @@ class ApiResourceServerController extends JsonController implements IRESTControl
$values['friendly_name'], $values['friendly_name'],
$values['active']); $values['active']);
return $this->ok(array('resource_server_id' => $new_resource_server_model->id)); return $this->created(array('resource_server_id' => $new_resource_server_model->id));
} }
catch(InvalidResourceServer $ex1){ catch(InvalidResourceServer $ex1){
$this->log_service->error($ex1); $this->log_service->error($ex1);
@ -102,7 +109,7 @@ class ApiResourceServerController extends JsonController implements IRESTControl
{ {
try { try {
$res = $this->resource_server_service->delete($id); $res = $this->resource_server_service->delete($id);
return $res?Response::json('ok',200):$this->error404(array('error'=>'operation failed')); return $res?$this->deleted():$this->error404(array('error'=>'operation failed'));
} catch (Exception $ex) { } catch (Exception $ex) {
$this->log_service->error($ex); $this->log_service->error($ex);
return $this->error500($ex); return $this->error500($ex);
@ -113,7 +120,7 @@ class ApiResourceServerController extends JsonController implements IRESTControl
{ {
try { try {
$res = $this->resource_server_service->regenerateClientSecret($id); $res = $this->resource_server_service->regenerateClientSecret($id);
return !is_null($res)?Response::json(array('new_secret'=>$res),200):$this->error404(array('error'=>'operation failed')); return !is_null($res)?$this->ok(array('new_secret'=>$res)):$this->error404(array('error'=>'operation failed'));
} catch (Exception $ex) { } catch (Exception $ex) {
$this->log_service->error($ex); $this->log_service->error($ex);
return $this->error500($ex); return $this->error500($ex);
@ -134,16 +141,12 @@ class ApiResourceServerController extends JsonController implements IRESTControl
); );
// Creates a Validator instance and validates the data. // Creates a Validator instance and validates the data.
$validation = Validator::make($values, $rules); $validation = Validator::make($values, $rules);
if ($validation->fails()) { if ($validation->fails()) {
$messages = $validation->messages()->toArray(); $messages = $validation->messages()->toArray();
return $this->error400(array('error'=>'validation','messages' => $messages)); return $this->error400(array('error'=>'validation','messages' => $messages));
} }
$res = $this->resource_server_service->update(intval($values['id']),$values); $res = $this->resource_server_service->update(intval($values['id']),$values);
return $res?$this->ok():$this->error400(array('error'=>'operation failed'));
return $res?Response::json('ok',200):$this->error400(array('error'=>'operation failed'));
} }
catch(InvalidResourceServer $ex1){ catch(InvalidResourceServer $ex1){
$this->log_service->error($ex1); $this->log_service->error($ex1);
@ -155,10 +158,16 @@ class ApiResourceServerController extends JsonController implements IRESTControl
} }
} }
/**
* @param $id
* @param $active
* @return mixed
*/
public function updateStatus($id, $active){ public function updateStatus($id, $active){
try { try {
$active = is_string($active)?(strtoupper(trim($active))==='TRUE'?true:false ):$active;
$res = $this->resource_server_service->setStatus($id,$active); $res = $this->resource_server_service->setStatus($id,$active);
return $res?Response::json('ok',200):$this->error400(array('error'=>'operation failed')); return $res?$this->ok():$this->error400(array('error'=>'operation failed'));
} catch (Exception $ex) { } catch (Exception $ex) {
$this->log_service->error($ex); $this->log_service->error($ex);
return $this->error500($ex); return $this->error500($ex);

View File

@ -8,7 +8,7 @@ use oauth2\exceptions\InvalidApiScope;
/** /**
* Class ApiScopeController * Class ApiScopeController
*/ */
class ApiScopeController extends AbstractRESTController implements IRESTController { class ApiScopeController extends AbstractRESTController implements ICRUDController {
private $api_scope_service; private $api_scope_service;
@ -17,9 +17,8 @@ class ApiScopeController extends AbstractRESTController implements IRESTControll
parent::__construct($log_service); parent::__construct($log_service);
$this->api_scope_service = $api_scope_service; $this->api_scope_service = $api_scope_service;
//set filters allowed values //set filters allowed values
$this->allowed_filter_fields = array('api_id'); $this->allowed_filter_fields = array('api_id');
$this->allowed_filter_op = array('api_id' => array('=')); $this->allowed_projection_fields = array('*');
$this->allowed_filter_value = array('api_id' => '/^\d+$/');
} }
public function get($id) public function get($id)
@ -37,12 +36,16 @@ class ApiScopeController extends AbstractRESTController implements IRESTControll
} }
} }
public function getByPage($page_nbr, $page_size) public function getByPage()
{ {
try { try {
//check for optional filters param on querystring //check for optional filters param on querystring
$filters = Input::get('filters',null); $fields = $this->getProjection(Input::get('fields',null));
$list = $this->api_scope_service->getAll($page_nbr, $page_size, $this->getFilters($filters)); $filters = $this->getFilters(Input::except('fields','limit','offset'));
$page_nbr = intval(Input::get('offset',1));
$page_size = intval(Input::get('limit',10));
$list = $this->api_scope_service->getAll($page_nbr, $page_size, $filters,$fields);
$items = array(); $items = array();
foreach ($list->getItems() as $scope) { foreach ($list->getItems() as $scope) {
array_push($items, $scope->toArray()); array_push($items, $scope->toArray());
@ -91,7 +94,7 @@ class ApiScopeController extends AbstractRESTController implements IRESTControll
$values['api_id'] $values['api_id']
); );
return $this->ok(array('scope_id' => $new_scope->id)); return $this->created(array('scope_id' => $new_scope->id));
} }
catch(InvalidApi $ex1){ catch(InvalidApi $ex1){
$this->log_service->error($ex1); $this->log_service->error($ex1);
@ -111,7 +114,7 @@ class ApiScopeController extends AbstractRESTController implements IRESTControll
{ {
try { try {
$res = $this->api_scope_service->delete($id); $res = $this->api_scope_service->delete($id);
return $res?Response::json('ok',200):$this->error404(array('error'=>'operation failed')); return $res?$this->deleted():$this->error404(array('error'=>'operation failed'));
} }
catch(InvalidApiScope $ex1){ catch(InvalidApiScope $ex1){
$this->log_service->error($ex1); $this->log_service->error($ex1);
@ -149,7 +152,7 @@ class ApiScopeController extends AbstractRESTController implements IRESTControll
$res = $this->api_scope_service->update(intval($values['id']),$values); $res = $this->api_scope_service->update(intval($values['id']),$values);
return $res?Response::json('ok',200):$this->error400(array('error'=>'operation failed')); return $res?$this->ok():$this->error400(array('error'=>'operation failed'));
} }
catch(InvalidApiScope $ex1){ catch(InvalidApiScope $ex1){
@ -162,10 +165,15 @@ class ApiScopeController extends AbstractRESTController implements IRESTControll
} }
} }
/**
* @param $id
* @param $active
* @return mixed
*/
public function updateStatus($id, $active){ public function updateStatus($id, $active){
try { try {
$res = $this->api_scope_service->setStatus($id,$active); $res = $this->api_scope_service->setStatus($id,$active);
return $res?Response::json('ok',200):$this->error400(array('error'=>'operation failed')); return $res?$this->ok():$this->error400(array('error'=>'operation failed'));
} catch (Exception $ex) { } catch (Exception $ex) {
$this->log_service->error($ex); $this->log_service->error($ex);
return $this->error500($ex); return $this->error500($ex);

View File

@ -1,7 +1,7 @@
<?php <?php
use oauth2\exceptions\AllowedClientUriAlreadyExistsException; use oauth2\exceptions\AllowedClientUriAlreadyExistsException;
use oauth2\exceptions\InvalidClientException; use oauth2\exceptions\AbsentClientException;
use oauth2\services\IApiScopeService; use oauth2\services\IApiScopeService;
use oauth2\services\IClientService; use oauth2\services\IClientService;
use oauth2\services\ITokenService; use oauth2\services\ITokenService;
@ -11,13 +11,19 @@ use utils\services\ILogService;
* Class ClientApiController * Class ClientApiController
* Client REST API * Client REST API
*/ */
class ClientApiController extends AbstractRESTController implements IRESTController class ClientApiController extends AbstractRESTController implements ICRUDController
{ {
private $client_service; private $client_service;
private $scope_service; private $scope_service;
private $token_service; private $token_service;
/**
* @param IApiScopeService $scope_service
* @param ITokenService $token_service
* @param IClientService $client_service
* @param ILogService $log_service
*/
public function __construct(IApiScopeService $scope_service, ITokenService $token_service, IClientService $client_service, ILogService $log_service) public function __construct(IApiScopeService $scope_service, ITokenService $token_service, IClientService $client_service, ILogService $log_service)
{ {
parent::__construct($log_service); parent::__construct($log_service);
@ -27,9 +33,8 @@ class ClientApiController extends AbstractRESTController implements IRESTControl
$this->token_service = $token_service; $this->token_service = $token_service;
//set filters allowed values //set filters allowed values
$this->allowed_filter_fields = array('user_id'); $this->allowed_filter_fields = array('user_id');
$this->allowed_filter_op = array('user_id' => array('=')); $this->allowed_projection_fields = array('*');
$this->allowed_filter_value = array('user_id' => '/^\d+$/');
} }
/** /**
@ -41,7 +46,7 @@ class ClientApiController extends AbstractRESTController implements IRESTControl
{ {
try { try {
$res = $this->client_service->deleteClientByIdentifier($id); $res = $this->client_service->deleteClientByIdentifier($id);
return $res ? Response::json('ok', 200) : $this->error404(array('error' => 'operation failed')); return $res ? $this->deleted() : $this->error404(array('error' => 'operation failed'));
} catch (Exception $ex) { } catch (Exception $ex) {
$this->log_service->error($ex); $this->log_service->error($ex);
return $this->error500($ex); return $this->error500($ex);
@ -59,10 +64,10 @@ class ClientApiController extends AbstractRESTController implements IRESTControl
// Build the validation constraint set. // Build the validation constraint set.
$rules = array( $rules = array(
'user_id' => 'required|integer', 'user_id' => 'required|integer',
'app_name' => 'required|alpha_dash|max:255', 'application_name' => 'required|alpha_dash|max:255',
'app_desc' => 'required|text', 'application_description' => 'required|text',
'app_type' => 'required|integer|applicationtype', 'application_type' => 'required|applicationtype',
); );
// Create a new validator instance. // Create a new validator instance.
@ -73,14 +78,13 @@ class ClientApiController extends AbstractRESTController implements IRESTControl
return $this->error400(array('error'=>'validation','messages' => $messages)); return $this->error400(array('error'=>'validation','messages' => $messages));
} }
if ($this->client_service->existClientAppName($values['application_name'])) {
if ($this->client_service->existClientAppName($values['app_name'])) {
return $this->error400(array('error' => 'application Name already exists!.')); return $this->error400(array('error' => 'application Name already exists!.'));
} }
$new_client = $this->client_service->addClient(intval($values['app_type']), intval($values['user_id']), trim($values['app_name']), trim($values['app_desc'])); $new_client = $this->client_service->addClient($values['application_type'], intval($values['user_id']), trim($values['application_name']), trim($values['application_description']));
return $this->ok(array('client_id' => $new_client->id)); return $this->created(array('client_id' => $new_client->id));
} catch (Exception $ex) { } catch (Exception $ex) {
$this->log_service->error($ex); $this->log_service->error($ex);
@ -88,6 +92,10 @@ class ClientApiController extends AbstractRESTController implements IRESTControl
} }
} }
/**
* @param $id
* @return mixed
*/
public function get($id) public function get($id)
{ {
try { try {
@ -103,15 +111,24 @@ class ClientApiController extends AbstractRESTController implements IRESTControl
} }
} }
public function getByPage($page_nbr, $page_size) /**
* @return mixed
*/
public function getByPage()
{ {
try { try {
//check for optional filters param on querystring //check for optional filters param on querystring
$filters = Input::get('filters',null); $fields = $this->getProjection(Input::get('fields',null));
$list = $this->client_service->getAll($page_nbr, $page_size,$this->getFilters($filters)); $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(); $items = array();
foreach ($list->getItems() as $client) { foreach ($list->getItems() as $client) {
array_push($items, $client->toArray()); $data = $client->toArray();
$data['application_type'] = $client->getFriendlyApplicationType();
array_push($items, $data);
} }
return $this->ok(array( return $this->ok(array(
'page' => $items, 'page' => $items,
@ -123,6 +140,9 @@ class ClientApiController extends AbstractRESTController implements IRESTControl
} }
} }
/**
* @return mixed
*/
public function update() public function update()
{ {
try { try {
@ -149,9 +169,9 @@ class ClientApiController extends AbstractRESTController implements IRESTControl
$res = $this->client_service->update(intval($values['id']), $values); $res = $this->client_service->update(intval($values['id']), $values);
return $res ? Response::json('ok', 200) : $this->error400(array('error' => 'operation failed')); return $res ? $this->ok() : $this->error400(array('error' => 'operation failed'));
} catch (InvalidClientException $ex1) { } catch (AbsentClientException $ex1) {
$this->log_service->error($ex1); $this->log_service->error($ex1);
return $this->error404(array('error' => $ex1->getMessage())); return $this->error404(array('error' => $ex1->getMessage()));
} catch (Exception $ex) { } catch (Exception $ex) {
@ -193,13 +213,13 @@ class ClientApiController extends AbstractRESTController implements IRESTControl
return $this->error400(array('error' => $messages)); return $this->error400(array('error' => $messages));
} }
$res = $this->client_service->addClientAllowedUri($id, $values['redirect_uri']); $res = $this->client_service->addClientAllowedUri($id, $values['redirect_uri']);
return $res ? Response::json('ok', 200) : $this->error404(array('error' => 'operation failed')); return $res ? $this->ok(): $this->error404(array('error' => 'operation failed'));
} catch (AllowedClientUriAlreadyExistsException $ex1) { } catch (AllowedClientUriAlreadyExistsException $ex1) {
$this->log_service->error($ex1); $this->log_service->error($ex1);
return $this->error400(array('error' => $ex1->getMessage())); return $this->error400(array('error' => $ex1->getMessage()));
} catch (InvalidClientException $ex2) { } catch (AbsentClientException $ex2) {
$this->log_service->error($ex2); $this->log_service->error($ex2);
return $this->error400(array('error' => $ex2->getMessage())); return $this->error404(array('error' => $ex2->getMessage()));
} catch (Exception $ex) { } catch (Exception $ex) {
$this->log_service->error($ex); $this->log_service->error($ex);
return $this->error500($ex); return $this->error500($ex);
@ -210,54 +230,52 @@ class ClientApiController extends AbstractRESTController implements IRESTControl
{ {
try { try {
$res = $this->client_service->deleteClientAllowedUri($id, $uri_id); $res = $this->client_service->deleteClientAllowedUri($id, $uri_id);
return $res ? Response::json('ok', 200) : $this->error404(array('error' => 'operation failed')); return $res ? $this->ok() : $this->error404(array('error' => 'operation failed'));
} catch (Exception $ex) { } catch (Exception $ex) {
$this->log_service->error($ex); $this->log_service->error($ex);
return $this->error500($ex); return $this->error500($ex);
} }
} }
public function addAllowedScope($id)
{ public function addAllowedScope($id,$scope_id){
try { try {
$values = Input::All(); $this->client_service->addClientScope($id, $scope_id);
// Build the validation constraint set. return $this->ok();
$rules = array( } catch (AbsentClientException $ex1) {
'scope_id' => 'required|integer',
'checked' => 'required|boolean',
);
// Creates a Validator instance and validates the data.
$validation = Validator::make($values, $rules);
if ($validation->fails()) {
$messages = $validation->messages()->toArray();
return $this->error400(array('error' => $messages));
}
$checked = $values['checked'];
$scope_id = $values['scope_id'];
$res = $checked ? $this->client_service->addClientScope($id, $scope_id) : $this->client_service->deleteClientScope($id, $scope_id);
return Response::json('ok', 200);
} catch (InvalidClientException $ex1) {
$this->log_service->error($ex1); $this->log_service->error($ex1);
return $this->error400(array('error' => $ex1->getMessage())); return $this->error404(array('error' => $ex1->getMessage()));
} catch (Exception $ex) { } catch (Exception $ex) {
$this->log_service->error($ex); $this->log_service->error($ex);
return $this->error500($ex); return $this->error500($ex);
} }
} }
public function removeAllowedScope($id,$scope_id){
try {
$res = $this->client_service->deleteClientScope($id, $scope_id);
return $res ? $this->ok() : $this->error404(array('error' => 'operation failed'));
} catch (AbsentClientException $ex1) {
$this->log_service->error($ex1);
return $this->error404(array('error' => $ex1->getMessage()));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
public function updateStatus($id,$active) public function updateStatus($id,$active)
{ {
try { try {
$res = $this->client_service->activateClient($id, $active); $res = $this->client_service->activateClient($id, $active);
return $res ? Response::json('ok', 200) : $this->error404(array('error' => 'operation failed')); return $res ? $this->ok() : $this->error404(array('error' => 'operation failed'));
} catch (InvalidClientException $ex1) { } catch (AbsentClientException $ex1) {
$this->log_service->error($ex1); $this->log_service->error($ex1);
return $this->error400(array('error' => $ex1->getMessage())); return $this->error404(array('error' => $ex1->getMessage()));
} catch (Exception $ex) { } catch (Exception $ex) {
$this->log_service->error($ex); $this->log_service->error($ex);
return $this->error500($ex); return $this->error500($ex);
@ -268,7 +286,8 @@ class ClientApiController extends AbstractRESTController implements IRESTControl
{ {
try { try {
$res = $this->client_service->regenerateClientSecret($id); $res = $this->client_service->regenerateClientSecret($id);
return !empty($res) ? Response::json(array('new_secret' => $res), 200) : $this->error404(array('error' => 'operation failed')); return !empty($res) ?
$this->ok(array('new_secret' => $res)): $this->error404(array('error' => 'operation failed'));
} catch (Exception $ex) { } catch (Exception $ex) {
$this->log_service->error($ex); $this->log_service->error($ex);
return $this->error500($ex); return $this->error500($ex);
@ -294,11 +313,11 @@ class ClientApiController extends AbstractRESTController implements IRESTControl
$res = $this->client_service->setRefreshTokenUsage($id, $values['use_refresh_token']); $res = $this->client_service->setRefreshTokenUsage($id, $values['use_refresh_token']);
return $res ? Response::json('ok', 200) : $this->error404(array('error' => 'operation failed')); return $res ? $this->ok() : $this->error404(array('error' => 'operation failed'));
} catch (InvalidClientException $ex1) { } catch (AbsentClientException $ex1) {
$this->log_service->error($ex1); $this->log_service->error($ex1);
return $this->error400(array('error' => $ex1->getMessage())); return $this->error404(array('error' => $ex1->getMessage()));
} catch (Exception $ex) { } catch (Exception $ex) {
$this->log_service->error($ex); $this->log_service->error($ex);
return $this->error500($ex); return $this->error500($ex);
@ -322,11 +341,10 @@ class ClientApiController extends AbstractRESTController implements IRESTControl
} }
$res = $this->client_service->setRotateRefreshTokenPolicy($id, $values['rotate_refresh_token']); $res = $this->client_service->setRotateRefreshTokenPolicy($id, $values['rotate_refresh_token']);
return $res ? Response::json('ok', 200) : $this->error404(array('error' => 'operation failed')); return $res ? $this->ok() : $this->error404(array('error' => 'operation failed'));
} catch (AbsentClientException $ex1) {
} catch (InvalidClientException $ex1) {
$this->log_service->error($ex1); $this->log_service->error($ex1);
return $this->error400(array('error' => $ex1->getMessage())); return $this->error404(array('error' => $ex1->getMessage()));
} catch (Exception $ex) { } catch (Exception $ex) {
$this->log_service->error($ex); $this->log_service->error($ex);
return $this->error500($ex); return $this->error500($ex);
@ -367,7 +385,7 @@ class ClientApiController extends AbstractRESTController implements IRESTControl
break; break;
} }
return $res ? Response::json('ok', 200) : $this->error404(array('error' => 'operation failed')); return $res ? $this->ok() : $this->error404(array('error' => 'operation failed'));
} catch (Exception $ex) { } catch (Exception $ex) {
$this->log_service->error($ex); $this->log_service->error($ex);
return $this->error500($ex); return $this->error500($ex);
@ -418,4 +436,22 @@ class ClientApiController extends AbstractRESTController implements IRESTControl
} }
} }
/**
* @param $id
* @return mixed
*/
public function unlock($id){
try {
$res = $this->client_service->unlockClient($id);
return $res ? $this->ok() : $this->error404(array('error' => 'operation failed'));
}
catch (AbsentClientException $ex1) {
$this->log_service->error($ex1);
return $this->error404(array('error' => $ex1->getMessage()));
}
catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
} }

View File

@ -1,12 +1,12 @@
<?php <?php
interface IRESTController { interface ICRUDController {
public function get($id); public function get($id);
public function create(); public function create();
public function getByPage($page_nbr, $page_size); public function getByPage();
public function delete($id); public function delete($id);
public function update(); public function update();
} }

View File

@ -19,7 +19,15 @@ class JsonController extends BaseController {
return Response::json(array('error' => 'server error'), 500); return Response::json(array('error' => 'server error'), 500);
} }
protected function ok($data){ protected function created($data='ok'){
return Response::json($data, 201);
}
protected function deleted($data='ok'){
return Response::json($data, 204);
}
protected function ok($data='ok'){
return Response::json($data, 200); return Response::json($data, 200);
} }

View File

@ -1,11 +1,97 @@
<?php <?php
use utils\services\ILogService; use utils\services\ILogService;
use openid\services\IUserService;
use oauth2\services\ITokenService;
class UserApiController extends AbstractRESTController implements ICRUDController {
class UserApiController extends JsonController{ private $user_service;
private $token_service;
public function __construct(ILogService $log_service) public function __construct(ILogService $log_service, IUserService $user_service,ITokenService $token_service){
{
parent::__construct($log_service); parent::__construct($log_service);
$this->user_service = $user_service;
$this->token_service = $token_service;
} }
}
/**
* @param $id
* @return mixed
*/
public function unlock($id){
try {
$res = $this->user_service->unlockUser($id);
return $res ? $this->ok() : $this->error404(array('error' => 'operation failed'));
}
catch (AbsentClientException $ex1) {
$this->log_service->error($ex1);
return $this->error404(array('error' => $ex1->getMessage()));
}
catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
/**
* @param $id
* @param $value
* @return mixed
*/
public function revokeToken($id,$value){
try{
$hint = Input::get('hint','none');
switch($hint){
case 'access_token':{
$token = $this->token_service->getAccessToken($value,true);
if(is_null($token->getUserId()) || intval($token->getUserId())!=intval($id))
throw new Exception(sprintf("access token %s does not belongs to user id %s!.",$value,$id));
$this->token_service->revokeAccessToken($value,true);
}
break;
case 'refresh_token':
$token = $this->token_service->getRefreshToken($value,true);
if(is_null($token->getUserId()) || intval($token->getUserId())!=intval($id))
throw new Exception(sprintf("refresh token %s does not belongs to user id %s!.",$value,$id));
$this->token_service->revokeRefreshToken($value,true);
break;
default:
throw new Exception(sprintf("hint %s not allowed",$hint));
break;
}
return $this->ok();
}
catch(Exception $ex){
$this->log_service->error($ex);
return $this->error500($ex);
}
}
public function get($id)
{
// TODO: Implement get() method.
}
public function create()
{
// TODO: Implement create() method.
}
public function getByPage()
{
// TODO: Implement getByPage() method.
}
public function delete($id)
{
// TODO: Implement delete() method.
}
public function update()
{
// TODO: Implement update() method.
}
}

View File

@ -1,54 +0,0 @@
<?php
use oauth2\IResourceServerContext;
use utils\services\ILogService;
/**
* Class OAuth2ProtectedApiController
* OAuth2 Protected API
*/
class OAuth2ProtectedApiController extends OAuth2ProtectedController {
private $controller;
public function __construct(ApiController $controller, IResourceServerContext $resource_server_context, ILogService $log_service)
{
parent::__construct($resource_server_context,$log_service);
$this->controller = $controller;
}
public function get($id)
{
return $this->controller->get($id);
}
public function getByPage($page_nbr, $page_size)
{
return $this->controller->getByPage($page_nbr, $page_size);
}
public function create()
{
return $this->controller->create();
}
public function delete($id)
{
return $this->controller->delete($id);
}
public function regenerateClientSecret($id)
{
return $this->controller->regenerateClientSecret($id);
}
public function update()
{
return $this->controller->update();
}
public function updateStatus($id, $active){
return $this->controller->updateStatus($id, $active);
}
}

View File

@ -1,56 +0,0 @@
<?php
use oauth2\IResourceServerContext;
use utils\services\ILogService;
/**
* Class OAuth2ProtectedApiEndpointController
* OAuth2 Protected API
*/
class OAuth2ProtectedApiEndpointController extends OAuth2ProtectedController
{
private $controller;
public function __construct(ApiEndpointController $controller, IResourceServerContext $resource_server_context, ILogService $log_service)
{
parent::__construct($resource_server_context,$log_service);
$this->controller = $controller;
}
public function get($id)
{
return $this->controller->get($id);
}
public function getByPage($page_nbr, $page_size)
{
return $this->controller->getByPage($page_nbr, $page_size);
}
public function create()
{
return $this->controller->create();
}
public function delete($id)
{
return $this->controller->delete($id);
}
public function update()
{
return $this->controller->update();
}
public function updateStatus($id, $active){
return $this->controller->updateStatus($id, $active);
}
public function addRequiredScope($id, $scope_id){
return $this->controller->addRequiredScope($id, $scope_id);
}
public function removeRequiredScope($id, $scope_id){
return $this->controller->removeRequiredScope($id, $scope_id);
}
}

View File

@ -1,54 +0,0 @@
<?php
use oauth2\IResourceServerContext;
use utils\services\ILogService;
/**
* Class OAuth2ProtectedApiResourceServerController
* OAuth2 Protected API
*/
class OAuth2ProtectedApiResourceServerController extends OAuth2ProtectedController {
private $controller;
public function __construct(ApiResourceServerController $controller, IResourceServerContext $resource_server_context, ILogService $log_service)
{
parent::__construct($resource_server_context,$log_service);
$this->controller = $controller;
}
public function get($id)
{
return $this->controller->get($id);
}
public function getByPage($page_nbr, $page_size)
{
return $this->controller->getByPage($page_nbr, $page_size);
}
public function create()
{
return $this->controller->create();
}
public function delete($id)
{
return $this->controller->delete($id);
}
public function regenerateClientSecret($id)
{
return $this->controller->regenerateClientSecret($id);
}
public function update()
{
return $this->controller->update();
}
public function updateStatus($id, $active){
return $this->controller->updateStatus($id, $active);
}
}

View File

@ -1,48 +0,0 @@
<?php
use oauth2\IResourceServerContext;
use utils\services\ILogService;
/**
* Class OAuth2ProtectedApiScopeController
* OAuth2 Protected API
*/
class OAuth2ProtectedApiScopeController extends OAuth2ProtectedController {
private $controller;
public function __construct(ApiScopeController $controller, IResourceServerContext $resource_server_context, ILogService $log_service)
{
parent::__construct($resource_server_context,$log_service);
$this->controller = $controller;
}
public function get($id)
{
return $this->controller->get($id);
}
public function getByPage($page_nbr, $page_size)
{
return $this->controller->getByPage($page_nbr, $page_size);
}
public function create()
{
return $this->controller->create();
}
public function delete($id)
{
return $this->controller->delete($id);
}
public function update()
{
return $this->controller->update();
}
public function updateStatus($id, $active){
return $this->controller->controller($id, $active);
}
}

View File

@ -19,7 +19,7 @@ class CreateOauth2ClientsTable extends Migration {
$table->string('app_logo',255)->nullable(); $table->string('app_logo',255)->nullable();
$table->string('client_id',255)->unique(); $table->string('client_id',255)->unique();
$table->string('client_secret',255)->nullable(); $table->string('client_secret',255)->nullable();
$table->smallInteger('client_type'); $table->enum('client_type', array('PUBLIC', 'CONFIDENTIAL'));
$table->boolean('active')->default(true); $table->boolean('active')->default(true);
$table->boolean('locked')->default(false); $table->boolean('locked')->default(false);
@ -38,7 +38,7 @@ class CreateOauth2ClientsTable extends Migration {
$table->integer('max_refresh_token_issuance_qty')->default(0); $table->integer('max_refresh_token_issuance_qty')->default(0);
$table->smallInteger('max_refresh_token_issuance_basis'); $table->smallInteger('max_refresh_token_issuance_basis');
$table->boolean('use_refresh_token')->default(true); $table->boolean('use_refresh_token')->default(false);
$table->boolean('rotate_refresh_token')->default(false); $table->boolean('rotate_refresh_token')->default(false);
}); });
} }

View File

@ -19,7 +19,7 @@ class CreateTableOauth2ApiEndpoints extends Migration {
$table->string('name',255)->unique(); $table->string('name',255)->unique();
$table->timestamps(); $table->timestamps();
$table->text("route"); $table->text("route");
$table->enum('http_method', array('GET', 'HEAD','POST','PUT','DELETE','TRACE','CONNECT','OPTIONS')); $table->enum('http_method', array('GET', 'HEAD','POST','PUT','DELETE','TRACE','CONNECT','OPTIONS','PATCH'));
$table->bigInteger("api_id")->unsigned(); $table->bigInteger("api_id")->unsigned();
$table->index('api_id'); $table->index('api_id');

View File

@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
class AlterTableOauth2AccessToken extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('oauth2_access_token', function($table)
{
$table->bigInteger("user_id")->unsigned()->nullable();
$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::table('oauth2_access_token', function($table)
{
$table->dropForeign('user_id');
$table->dropColumn('user_id');
});
}
}

View File

@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
class AlterRefreshOauth2AccessToken extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('oauth2_refresh_token', function($table)
{
$table->bigInteger("user_id")->unsigned()->nullable();
$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::table('oauth2_refresh_token', function($table)
{
$table->dropForeign('user_id');
$table->dropColumn('user_id');
});
}
}

View File

@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
class AlterUserExceptionsTrail extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('user_exceptions_trail', function($table)
{
$table->bigInteger("user_id")->unsigned()->nullable();
$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::table('user_exceptions_trail', function($table)
{
$table->dropForeign('user_id');
$table->dropColumn('user_id');
});
}
}

View File

@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
class AlterBannedIps extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('banned_ips', function($table)
{
$table->bigInteger("user_id")->unsigned()->nullable();
$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::table('banned_ips', function($table)
{
$table->dropForeign('user_id');
$table->dropColumn('user_id');
});
}
}

View File

@ -0,0 +1,45 @@
<?php
use Illuminate\Database\Migrations\Migration;
class CreateTableOauth2ExceptionsTrail extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('oauth2_exception_trail', function($table)
{
$table->bigIncrements('id')->unsigned();
$table->string('from_ip',254);
$table->string('exception_type',1024);
$table->timestamps();
$table->bigInteger("client_id")->unsigned()->nullable();
$table->index('client_id');
$table->foreign('client_id')
->references('id')
->on('oauth2_client')
->onDelete('cascade')
->onUpdate('no action');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('oauth2_exception_trail', function($table)
{
$table->dropForeign('client_id');
});
Schema::dropIfExists('oauth2_exception_trail');
}
}

View File

@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
class UpdateOauth2Client extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('oauth2_client', function($table)
{
$table->enum('application_type', array('WEB_APPLICATION', 'JS_CLIENT','SERVICE'));
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('oauth2_client', function($table)
{
$table->dropColumn('application_type');
});
}
}

View File

@ -0,0 +1,55 @@
<?php
use Illuminate\Database\Migrations\Migration;
class CreateTableOauth2UserConsents extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('oauth2_user_consents', function($table)
{
$table->bigIncrements('id')->unsigned();
$table->text('scopes');
$table->bigInteger("client_id")->unsigned();
$table->index('client_id');
$table->foreign('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');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('oauth2_user_consents', function($table)
{
$table->dropForeign('client_id');
$table->dropForeign('openid_users');
});
Schema::dropIfExists('oauth2_user_consents');
}
}

View File

@ -321,12 +321,31 @@ class TestSeeder extends Seeder {
'client_id' => 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client', 'client_id' => 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client',
'client_secret' => 'ITc/6Y5N7kOtGKhg', 'client_secret' => 'ITc/6Y5N7kOtGKhg',
'client_type' => IClient::ClientType_Confidential, 'client_type' => IClient::ClientType_Confidential,
'application_type' => IClient::ApplicationType_Web_App,
'user_id' => $user->id, 'user_id' => $user->id,
'rotate_refresh_token' => true, 'rotate_refresh_token' => true,
'use_refresh_token' => true 'use_refresh_token' => true
) )
); );
Client::create(
array(
'app_name' => 'oauth2.service',
'app_description' => 'oauth2.service',
'app_logo' => null,
'client_id' => '11z87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client',
'client_secret' => '11c/6Y5N7kOtGKhg',
'client_type' => IClient::ClientType_Confidential,
'application_type' => IClient::ApplicationType_Service,
'user_id' => $user->id,
'rotate_refresh_token' => true,
'use_refresh_token' => true
)
);
Client::create( Client::create(
array( array(
'app_name' => 'oauth2_test_app_public', 'app_name' => 'oauth2_test_app_public',
@ -335,6 +354,7 @@ class TestSeeder extends Seeder {
'client_id' => 'Jiz87D8/Vcvr6fvQbH4HyNgwKlfSyQ3x.openstack.client', 'client_id' => 'Jiz87D8/Vcvr6fvQbH4HyNgwKlfSyQ3x.openstack.client',
'client_secret' => null, 'client_secret' => null,
'client_type' => IClient::ClientType_Public, 'client_type' => IClient::ClientType_Public,
'application_type' => IClient::ApplicationType_JS_Client,
'user_id' => $user->id, 'user_id' => $user->id,
'rotate_refresh_token' => false, 'rotate_refresh_token' => false,
'use_refresh_token' => false 'use_refresh_token' => false
@ -349,6 +369,7 @@ class TestSeeder extends Seeder {
'client_id' => 'Jiz87D8/Vcvr6fvQbH4HyNgwKlfSyQ2x.openstack.client', 'client_id' => 'Jiz87D8/Vcvr6fvQbH4HyNgwKlfSyQ2x.openstack.client',
'client_secret' => null, 'client_secret' => null,
'client_type' => IClient::ClientType_Public, 'client_type' => IClient::ClientType_Public,
'application_type' => IClient::ApplicationType_JS_Client,
'user_id' => $user->id, 'user_id' => $user->id,
'rotate_refresh_token' => false, 'rotate_refresh_token' => false,
'use_refresh_token' => false 'use_refresh_token' => false
@ -363,6 +384,7 @@ class TestSeeder extends Seeder {
'client_id' => 'resource.server.1.openstack.client', 'client_id' => 'resource.server.1.openstack.client',
'client_secret' => '123456789', 'client_secret' => '123456789',
'client_type' => IClient::ClientType_Confidential, 'client_type' => IClient::ClientType_Confidential,
'application_type' => IClient::ApplicationType_Service,
'resource_server_id' => $resource_server->id, 'resource_server_id' => $resource_server->id,
'rotate_refresh_token' => false, 'rotate_refresh_token' => false,
'use_refresh_token' => false 'use_refresh_token' => false
@ -371,11 +393,13 @@ class TestSeeder extends Seeder {
$client_confidential = Client::where('app_name','=','oauth2_test_app')->first(); $client_confidential = Client::where('app_name','=','oauth2_test_app')->first();
$client_public = Client::where('app_name','=','oauth2_test_app_public')->first(); $client_public = Client::where('app_name','=','oauth2_test_app_public')->first();
$client_service = Client::where('app_name','=','oauth2.service')->first();
//attach scopes //attach scopes
$scopes = ApiScope::get(); $scopes = ApiScope::get();
foreach($scopes as $scope){ foreach($scopes as $scope){
$client_confidential->scopes()->attach($scope->id); $client_confidential->scopes()->attach($scope->id);
$client_public->scopes()->attach($scope->id); $client_public->scopes()->attach($scope->id);
$client_service->scopes()->attach($scope->id);
} }
//add uris //add uris
ClientAuthorizedUri::create( ClientAuthorizedUri::create(
@ -749,7 +773,7 @@ class TestSeeder extends Seeder {
'name' => 'create-resource-server', 'name' => 'create-resource-server',
'active' => true, 'active' => true,
'api_id' => $resource_server->id, 'api_id' => $resource_server->id,
'route' => 'api/v1/resource-server', 'route' => 'api/v1/resource-servers',
'http_method' => 'POST' 'http_method' => 'POST'
) )
); );
@ -759,7 +783,7 @@ class TestSeeder extends Seeder {
'name' => 'get-resource-server', 'name' => 'get-resource-server',
'active' => true, 'active' => true,
'api_id' => $resource_server->id, 'api_id' => $resource_server->id,
'route' => 'api/v1/resource-server/{id}', 'route' => 'api/v1/resource-servers/{id}',
'http_method' => 'GET' 'http_method' => 'GET'
) )
); );
@ -769,8 +793,8 @@ class TestSeeder extends Seeder {
'name' => 'resource-server-regenerate-secret', 'name' => 'resource-server-regenerate-secret',
'active' => true, 'active' => true,
'api_id' => $resource_server->id, 'api_id' => $resource_server->id,
'route' => 'api/v1/resource-server/regenerate-client-secret/{id}', 'route' => 'api/v1/resource-servers/{id}/client-secret',
'http_method' => 'GET' 'http_method' => 'PUT'
) )
); );
@ -779,7 +803,7 @@ class TestSeeder extends Seeder {
'name' => 'resource-server-get-page', 'name' => 'resource-server-get-page',
'active' => true, 'active' => true,
'api_id' => $resource_server->id, 'api_id' => $resource_server->id,
'route' => 'api/v1/resource-server/{page_nbr}/{page_size}', 'route' => 'api/v1/resource-servers',
'http_method' => 'GET' 'http_method' => 'GET'
) )
); );
@ -789,7 +813,7 @@ class TestSeeder extends Seeder {
'name' => 'resource-server-delete', 'name' => 'resource-server-delete',
'active' => true, 'active' => true,
'api_id' => $resource_server->id, 'api_id' => $resource_server->id,
'route' => 'api/v1/resource-server/{id}', 'route' => 'api/v1/resource-servers/{id}',
'http_method' => 'DELETE' 'http_method' => 'DELETE'
) )
); );
@ -799,7 +823,7 @@ class TestSeeder extends Seeder {
'name' => 'resource-server-update', 'name' => 'resource-server-update',
'active' => true, 'active' => true,
'api_id' => $resource_server->id, 'api_id' => $resource_server->id,
'route' => 'api/v1/resource-server', 'route' => 'api/v1/resource-servers',
'http_method' => 'PUT' 'http_method' => 'PUT'
) )
); );
@ -809,8 +833,8 @@ class TestSeeder extends Seeder {
'name' => 'resource-server-update-status', 'name' => 'resource-server-update-status',
'active' => true, 'active' => true,
'api_id' => $resource_server->id, 'api_id' => $resource_server->id,
'route' => 'api/v1/resource-server/status/{id}/{active}', 'route' => 'api/v1/resource-servers/{id}/status/{active}',
'http_method' => 'GET' 'http_method' => 'PUT'
) )
); );

View File

@ -53,37 +53,17 @@ Route::filter('auth', function () {
Session::put('url.intended', URL::full()); Session::put('url.intended', URL::full());
return Redirect::action('HomeController@index'); return Redirect::action('HomeController@index');
} }
if ($redirect = Session::get('url.intended')) { $redirect = Session::get('url.intended');
if (!empty($redirect)) {
Session::forget('url.intended'); Session::forget('url.intended');
return Redirect::to($redirect); return Redirect::to($redirect);
} }
}); });
Route::filter('auth.server.admin.json',function(){
if (Auth::guest()) {
return Response::json(array('error' => 'you are not allowed to perform this operation'));
}
if(!Auth::user()->IsServerAdmin()){
return Response::json(array('error' => 'you are not allowed to perform this operation'));
}
});
Route::filter('auth.server.admin',function(){
if (Auth::guest()) {
return View::make('404');
}
if(!Auth::user()->IsServerAdmin()){
return View::make('404');
}
});
Route::filter('auth.basic', function () { Route::filter('auth.basic', function () {
return Auth::basic(); return Auth::basic();
}); });
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Guest Filter | Guest Filter
@ -191,8 +171,16 @@ Route::filter('is.current.user',function($route, $request){
try{ try{
$authentication_service = App::make(UtilsServiceCatalog::AuthenticationService); $authentication_service = App::make(UtilsServiceCatalog::AuthenticationService);
$used_id = Input::get('user_id',null); $used_id = Input::get('user_id',null);
if(is_null($used_id))
$used_id = Input::get('id',null);
if(is_null($used_id)) if(is_null($used_id))
$used_id = $route->getParameter('user_id'); $used_id = $route->getParameter('user_id');
if(is_null($used_id))
$used_id = $route->getParameter('id');
$user = $authentication_service->getCurrentUser(); $user = $authentication_service->getCurrentUser();
if (is_null($used_id) || intval($used_id) !== intval($user->getId())) if (is_null($used_id) || intval($used_id) !== intval($user->getId()))
throw new Exception(sprintf('user id %s does not match with current user id %s',$used_id,$user->getId())); throw new Exception(sprintf('user id %s does not match with current user id %s',$used_id,$user->getId()));
@ -207,4 +195,48 @@ Route::filter('is.current.user',function($route, $request){
// filter to protect an api endpoint with oauth2 // filter to protect an api endpoint with oauth2
Route::filter('oauth2.protected.endpoint','OAuth2BearerAccessTokenRequestValidator');
Route::filter('oauth2.protected.endpoint','OAuth2BearerAccessTokenRequestValidator');
//oauth2 server admin filter
Route::filter('oauth2.server.admin.json',function(){
if (Auth::guest()) {
return Response::json(array('error' => 'you are not allowed to perform this operation'));
}
if(!Auth::user()->isOAuth2ServerAdmin()){
return Response::json(array('error' => 'you are not allowed to perform this operation'));
}
});
Route::filter('oauth2.server.admin',function(){
if (Auth::guest()) {
return View::make('404');
}
if(!Auth::user()->isOAuth2ServerAdmin()){
return View::make('404');
}
});
//openstackid server admin
Route::filter('openstackid.server.admin.json',function(){
if (Auth::guest()) {
return Response::json(array('error' => 'you are not allowed to perform this operation'));
}
if(!Auth::user()->isOpenstackIdAdmin()){
return Response::json(array('error' => 'you are not allowed to perform this operation'));
}
});
Route::filter('openstackid.server.admin',function(){
if (Auth::guest()) {
return View::make('404');
}
if(!Auth::user()->isOpenstackIdAdmin()){
return View::make('404');
}
});

View File

@ -38,13 +38,12 @@ class OAuth2BearerAccessTokenRequestValidator {
*/ */
public function filter($route, $request) public function filter($route, $request)
{ {
$url = $route->getPath();
$method = $request->getMethod();
$realm = $request->getHost();
try{ try{
$url = $route->getPath();
$method = $request->getMethod();
$endpoint = $this->api_endpoint_service->getApiEndpointByUrlAndMethod($url, $method); $endpoint = $this->api_endpoint_service->getApiEndpointByUrlAndMethod($url, $method);
$realm = $request->getHost();
//api endpoint must be registered on db and active //api endpoint must be registered on db and active
if(is_null($endpoint) || !$endpoint->isActive()){ if(is_null($endpoint) || !$endpoint->isActive()){
@ -88,12 +87,17 @@ class OAuth2BearerAccessTokenRequestValidator {
implode(' ',$endpoint_scopes)); implode(' ',$endpoint_scopes));
} }
$this->resource_server_context->setAuthorizationContext(array( $context = array(
'access_token' => $access_token_value, 'access_token' => $access_token_value,
'expires_in' => $access_token->getRemainingLifetime(), 'expires_in' => $access_token->getRemainingLifetime(),
'client_id' => $access_token->getClientId(), 'client_id' => $access_token->getClientId(),
'scope' => $access_token->getScope() 'scope' => $access_token->getScope()
)); );
if(!is_null($access_token>getUserId()))
$context['user_id'] = $access_token>getUserId();
$this->resource_server_context->setAuthorizationContext($context);
} }
catch(OAuth2ResourceServerException $ex1){ catch(OAuth2ResourceServerException $ex1){

View File

@ -16,9 +16,11 @@ class AuthHelper
); );
/** /**
* @param $password user password * @param $password
* @param $salt password salt * @param $salt
* @param string $algorithm Name of selected hashing algorithm (i.e. "md5", "sha256", "haval160,4", etc..) * @param string $algorithm
* @return string
* @throws \Exception
*/ */
public static function encrypt_password($password, $salt, $algorithm = "sha1") public static function encrypt_password($password, $salt, $algorithm = "sha1")
{ {

View File

@ -3,7 +3,6 @@
namespace auth; namespace auth;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use openid\services\OpenIdServiceCatalog;
use utils\services\Registry; use utils\services\Registry;
use utils\services\UtilsServiceCatalog; use utils\services\UtilsServiceCatalog;

View File

@ -10,10 +10,13 @@ use openid\services\OpenIdServiceCatalog;
use utils\services\Registry; use utils\services\Registry;
use oauth2\models\IOAuth2User; use oauth2\models\IOAuth2User;
use Eloquent; use Eloquent;
use utils\model\BaseModelEloquent;
class User extends Eloquent implements UserInterface, IOpenIdUser, IOAuth2User /**
* Class User
* @package auth
*/
class User extends BaseModelEloquent implements UserInterface, IOpenIdUser, IOAuth2User
{ {
protected $table = 'openid_users'; protected $table = 'openid_users';
private $member; private $member;
@ -23,6 +26,21 @@ class User extends Eloquent implements UserInterface, IOpenIdUser, IOAuth2User
return $this->hasMany("OpenIdTrustedSite", 'user_id'); return $this->hasMany("OpenIdTrustedSite", 'user_id');
} }
public function access_tokens()
{
return $this->hasMany('AccessToken','user_id');
}
public function refresh_tokens()
{
return $this->hasMany('RefreshToken','user_id');
}
public function consents()
{
return $this->hasMany('UserConsent','user_id');
}
public function clients() public function clients()
{ {
return $this->hasMany("Client", 'user_id'); return $this->hasMany("Client", 'user_id');
@ -207,8 +225,6 @@ class User extends Eloquent implements UserInterface, IOpenIdUser, IOAuth2User
{ {
return $this->clients()->get(); return $this->clients()->get();
} }
/** /**
* Could use system scopes on registered clients * Could use system scopes on registered clients
* @return bool * @return bool
@ -226,7 +242,7 @@ class User extends Eloquent implements UserInterface, IOpenIdUser, IOAuth2User
* Is Server Administrator * Is Server Administrator
* @return bool * @return bool
*/ */
public function IsServerAdmin() public function isOAuth2ServerAdmin()
{ {
if (is_null($this->member)) { if (is_null($this->member)) {
$this->member = Member::where('Email', '=', $this->external_id)->first(); $this->member = Member::where('Email', '=', $this->external_id)->first();
@ -234,4 +250,16 @@ class User extends Eloquent implements UserInterface, IOpenIdUser, IOAuth2User
$group = $this->member->groups()->where('code','=',IOAuth2User::OAuth2ServerAdminGroup)->first(); $group = $this->member->groups()->where('code','=',IOAuth2User::OAuth2ServerAdminGroup)->first();
return !is_null($group); return !is_null($group);
} }
/**
* @return bool
*/
public function isOpenstackIdAdmin()
{
if (is_null($this->member)) {
$this->member = Member::where('Email', '=', $this->external_id)->first();
}
$group = $this->member->groups()->where('code','=',IOpenIdUser::OpenstackIdServerAdminGroup)->first();
return !is_null($group);
}
} }

View File

@ -2,7 +2,6 @@
namespace oauth2; namespace oauth2;
use oauth2\requests\OAuth2Request; use oauth2\requests\OAuth2Request;
use oauth2\OAuth2Message;
interface IOAuth2Protocol { interface IOAuth2Protocol {
/** /**

View File

@ -10,4 +10,5 @@ interface IResourceServerContext {
public function getCurrentAccessTokenLifetime(); public function getCurrentAccessTokenLifetime();
public function getCurrentClientId(); public function getCurrentClientId();
public function setAuthorizationContext($auth_context); public function setAuthorizationContext($auth_context);
public function getCurrentUserId();
} }

View File

@ -15,16 +15,22 @@ use oauth2\exceptions\AccessDeniedException;
use oauth2\exceptions\BearerTokenDisclosureAttemptException; use oauth2\exceptions\BearerTokenDisclosureAttemptException;
use oauth2\exceptions\ExpiredAuthorizationCodeException; use oauth2\exceptions\ExpiredAuthorizationCodeException;
use oauth2\exceptions\InvalidAccessTokenException; use oauth2\exceptions\InvalidAccessTokenException;
use oauth2\exceptions\InvalidApplicationType;
use oauth2\exceptions\InvalidAuthorizationCodeException; use oauth2\exceptions\InvalidAuthorizationCodeException;
use oauth2\exceptions\InvalidClientException; use oauth2\exceptions\InvalidClientException;
use oauth2\exceptions\InvalidClientType;
use oauth2\exceptions\InvalidGrantTypeException; use oauth2\exceptions\InvalidGrantTypeException;
use oauth2\exceptions\InvalidOAuth2Request; use oauth2\exceptions\InvalidOAuth2Request;
use oauth2\exceptions\LockedClientException;
use oauth2\exceptions\MissingClientIdParam;
use oauth2\exceptions\OAuth2GenericException; use oauth2\exceptions\OAuth2GenericException;
use oauth2\exceptions\ReplayAttackException; use oauth2\exceptions\ReplayAttackException;
use oauth2\exceptions\ScopeNotAllowedException; use oauth2\exceptions\ScopeNotAllowedException;
use oauth2\exceptions\UnAuthorizedClientException; use oauth2\exceptions\UnAuthorizedClientException;
use oauth2\exceptions\UnsupportedResponseTypeException; use oauth2\exceptions\UnsupportedResponseTypeException;
use oauth2\exceptions\UriNotAllowedException; use oauth2\exceptions\UriNotAllowedException;
use oauth2\exceptions\MissingClientAuthorizationInfo;
use oauth2\exceptions\InvalidRedeemAuthCodeException;
//grant types //grant types
use oauth2\grant_types\AuthorizationCodeGrantType; use oauth2\grant_types\AuthorizationCodeGrantType;
@ -44,6 +50,7 @@ use oauth2\services\IMementoOAuth2AuthenticationRequestService;
use oauth2\services\ITokenService; use oauth2\services\ITokenService;
use oauth2\strategies\IOAuth2AuthenticationStrategy; use oauth2\strategies\IOAuth2AuthenticationStrategy;
use oauth2\strategies\OAuth2IndirectErrorResponseFactoryMethod; use oauth2\strategies\OAuth2IndirectErrorResponseFactoryMethod;
use oauth2\services\IUserConsentService;
use utils\services\IAuthService; use utils\services\IAuthService;
use utils\services\ICheckPointService; use utils\services\ICheckPointService;
use utils\services\ILogService; use utils\services\ILogService;
@ -65,6 +72,7 @@ class OAuth2Protocol implements IOAuth2Protocol
const OAuth2Protocol_ResponseType_Token = 'token'; const OAuth2Protocol_ResponseType_Token = 'token';
const OAuth2Protocol_ResponseType = 'response_type'; const OAuth2Protocol_ResponseType = 'response_type';
const OAuth2Protocol_ClientId = 'client_id'; const OAuth2Protocol_ClientId = 'client_id';
const OAuth2Protocol_UserId = 'user_id';
const OAuth2Protocol_ClientSecret = 'client_secret'; const OAuth2Protocol_ClientSecret = 'client_secret';
const OAuth2Protocol_Token = 'token'; const OAuth2Protocol_Token = 'token';
const OAuth2Protocol_TokenType = 'token_type'; const OAuth2Protocol_TokenType = 'token_type';
@ -77,6 +85,26 @@ class OAuth2Protocol implements IOAuth2Protocol
const OAuth2Protocol_Scope = 'scope'; const OAuth2Protocol_Scope = 'scope';
const OAuth2Protocol_Audience = 'audience'; const OAuth2Protocol_Audience = 'audience';
const OAuth2Protocol_State = 'state'; const OAuth2Protocol_State = 'state';
/**
* Indicates whether the user should be re-prompted for consent. The default is auto,
* so a given user should only see the consent page for a given set of scopes the first time
* through the sequence. If the value is force, then the user sees a consent page even if they
* previously gave consent to your application for a given set of scopes.
*/
const OAuth2Protocol_Approval_Prompt = 'approval_prompt';
const OAuth2Protocol_Approval_Prompt_Force = 'force';
const OAuth2Protocol_Approval_Prompt_Auto = 'auto';
/**
* Indicates whether your application needs to access an API when the user is not present at
* the browser. This parameter defaults to online. If your application needs to refresh access tokens
* when the user is not present at the browser, then use offline. This will result in your application
* obtaining a refresh token the first time your application exchanges an authorization code for a user.
*/
const OAuth2Protocol_AccessType = 'access_type';
const OAuth2Protocol_AccessType_Online = 'online';
const OAuth2Protocol_AccessType_Offline = 'offline';
const OAuth2Protocol_GrantType = 'grant_type'; const OAuth2Protocol_GrantType = 'grant_type';
const OAuth2Protocol_Error = 'error'; const OAuth2Protocol_Error = 'error';
const OAuth2Protocol_ErrorDescription = 'error_description'; const OAuth2Protocol_ErrorDescription = 'error_description';
@ -138,11 +166,12 @@ class OAuth2Protocol implements IOAuth2Protocol
IMementoOAuth2AuthenticationRequestService $memento_service, IMementoOAuth2AuthenticationRequestService $memento_service,
IOAuth2AuthenticationStrategy $auth_strategy, IOAuth2AuthenticationStrategy $auth_strategy,
ICheckPointService $checkpoint_service, ICheckPointService $checkpoint_service,
IApiScopeService $scope_service) IApiScopeService $scope_service,
IUserConsentService $user_consent_service)
{ {
$authorization_code_grant_type = new AuthorizationCodeGrantType($scope_service, $client_service, $token_service, $auth_service, $memento_service, $auth_strategy, $log_service); $authorization_code_grant_type = new AuthorizationCodeGrantType($scope_service, $client_service, $token_service, $auth_service, $memento_service, $auth_strategy, $log_service,$user_consent_service);
$implicit_grant_type = new ImplicitGrantType($scope_service, $client_service, $token_service, $auth_service, $memento_service, $auth_strategy, $log_service); $implicit_grant_type = new ImplicitGrantType($scope_service, $client_service, $token_service, $auth_service, $memento_service, $auth_strategy, $log_service,$user_consent_service);
$refresh_bearer_token_grant_type = new RefreshBearerTokenGrantType($client_service, $token_service, $log_service); $refresh_bearer_token_grant_type = new RefreshBearerTokenGrantType($client_service, $token_service, $log_service);
$client_credential_grant_type = new ClientCredentialsGrantType($scope_service,$client_service, $token_service, $log_service); $client_credential_grant_type = new ClientCredentialsGrantType($scope_service,$client_service, $token_service, $log_service);
@ -241,7 +270,48 @@ class OAuth2Protocol implements IOAuth2Protocol
throw $ex8; throw $ex8;
return OAuth2IndirectErrorResponseFactoryMethod::buildResponse($request, OAuth2Protocol::OAuth2Protocol_Error_ServerError, $redirect_uri); return OAuth2IndirectErrorResponseFactoryMethod::buildResponse($request, OAuth2Protocol::OAuth2Protocol_Error_ServerError, $redirect_uri);
} catch (Exception $ex) { }
catch(InvalidApplicationType $ex9){
$this->log_service->error($ex9);
$this->checkpoint_service->trackException($ex9);
$redirect_uri = $this->validateRedirectUri($request);
if (is_null($redirect_uri))
throw $ex9;
return OAuth2IndirectErrorResponseFactoryMethod::buildResponse($request, OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient, $redirect_uri);
}
catch(LockedClientException $ex10){
$this->log_service->error($ex10);
$this->checkpoint_service->trackException($ex10);
$redirect_uri = $this->validateRedirectUri($request);
if (is_null($redirect_uri))
throw $ex10;
return OAuth2IndirectErrorResponseFactoryMethod::buildResponse($request, OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient, $redirect_uri);
}
catch(MissingClientIdParam $ex11){
$this->log_service->error($ex11);
$this->checkpoint_service->trackException($ex11);
$redirect_uri = $this->validateRedirectUri($request);
if (is_null($redirect_uri))
throw $ex11;
return OAuth2IndirectErrorResponseFactoryMethod::buildResponse($request, OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient, $redirect_uri);
}
catch(InvalidClientType $ex12){
$this->log_service->error($ex12);
$this->checkpoint_service->trackException($ex12);
$redirect_uri = $this->validateRedirectUri($request);
if (is_null($redirect_uri))
throw $ex12;
return OAuth2IndirectErrorResponseFactoryMethod::buildResponse($request, OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient, $redirect_uri);
}
catch (Exception $ex) {
$this->log_service->error($ex); $this->log_service->error($ex);
$this->checkpoint_service->trackException($ex); $this->checkpoint_service->trackException($ex);
@ -325,7 +395,37 @@ class OAuth2Protocol implements IOAuth2Protocol
catch(ScopeNotAllowedException $ex11){ catch(ScopeNotAllowedException $ex11){
$this->log_service->error($ex11); $this->log_service->error($ex11);
$this->checkpoint_service->trackException($ex11); $this->checkpoint_service->trackException($ex11);
return new OAuth2DirectErrorResponse(OAuth2Protocol::OAuth2Protocol_Error_InvalidRequest); return new OAuth2DirectErrorResponse(OAuth2Protocol::OAuth2Protocol_Error_InvalidScope);
}
catch(InvalidApplicationType $ex12){
$this->log_service->error($ex12);
$this->checkpoint_service->trackException($ex12);
return new OAuth2DirectErrorResponse(OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient);
}
catch(LockedClientException $ex13){
$this->log_service->error($ex13);
$this->checkpoint_service->trackException($ex13);
return new OAuth2DirectErrorResponse(OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient);
}
catch(MissingClientIdParam $ex14){
$this->log_service->error($ex14);
$this->checkpoint_service->trackException($ex14);
return new OAuth2DirectErrorResponse(OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient);
}
catch(InvalidClientType $ex15){
$this->log_service->error($ex15);
$this->checkpoint_service->trackException($ex15);
return new OAuth2DirectErrorResponse(OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient);
}
catch(MissingClientAuthorizationInfo $ex16){
$this->log_service->error($ex16);
$this->checkpoint_service->trackException($ex16);
return new OAuth2DirectErrorResponse(OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient);
}
catch(InvalidRedeemAuthCodeException $ex17){
$this->log_service->error($ex17);
$this->checkpoint_service->trackException($ex17);
return new OAuth2DirectErrorResponse(OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient);
} }
catch (Exception $ex) { catch (Exception $ex) {
$this->log_service->error($ex); $this->log_service->error($ex);

View File

@ -5,7 +5,6 @@ namespace oauth2\endpoints;
use oauth2\requests\OAuth2Request; use oauth2\requests\OAuth2Request;
use oauth2\exceptions\InvalidOAuth2Request; use oauth2\exceptions\InvalidOAuth2Request;
use oauth2\IOAuth2Protocol; use oauth2\IOAuth2Protocol;
use oauth2\exceptions\InvalidGrantTypeException;
/** /**
* Class AuthorizationEndpoint * Class AuthorizationEndpoint

View File

@ -2,8 +2,6 @@
namespace oauth2\endpoints; namespace oauth2\endpoints;
use oauth2\exceptions\InvalidGrantTypeException;
use oauth2\requests\OAuth2Request; use oauth2\requests\OAuth2Request;
use oauth2\IOAuth2Protocol; use oauth2\IOAuth2Protocol;
use oauth2\services\IClientService; use oauth2\services\IClientService;

View File

@ -2,8 +2,6 @@
namespace oauth2\endpoints; namespace oauth2\endpoints;
use oauth2\exceptions\InvalidGrantTypeException;
use oauth2\exceptions\InvalidOAuth2Request; use oauth2\exceptions\InvalidOAuth2Request;
use oauth2\requests\OAuth2Request; use oauth2\requests\OAuth2Request;
use oauth2\IOAuth2Protocol; use oauth2\IOAuth2Protocol;

View File

@ -0,0 +1,15 @@
<?php
namespace oauth2\exceptions;
use Exception;
class AbsentClientException extends Exception
{
public function __construct($message = "")
{
$message = "Absent Client Exception: " . $message;
parent::__construct($message, 0, null);
}
}

View File

@ -2,15 +2,11 @@
namespace oauth2\exceptions; namespace oauth2\exceptions;
use Exception; class BearerTokenDisclosureAttemptException extends OAuth2ClientBaseException
class BearerTokenDisclosureAttemptException extends Exception
{ {
public function __construct($client_id,$message = "")
public function __construct($message = "")
{ {
$message = "Bearer Token Disclosure Attempt Attack: " . $message; $message = "Bearer Token Disclosure Attempt Attack: " . $message;
parent::__construct($message, 0, null); parent::__construct($client_id,$message);
} }
} }

View File

@ -0,0 +1,13 @@
<?php
namespace oauth2\exceptions;
class InvalidApplicationType extends OAuth2ClientBaseException
{
public function __construct($client_id, $message = "")
{
$message = "Invalid Application Type: " . $message;
parent::__construct($client_id,$message);
}
}

View File

@ -1,14 +1,12 @@
<?php <?php
namespace oauth2\exceptions; namespace oauth2\exceptions;
use Exception;
class InvalidClientException extends Exception class InvalidClientException extends OAuth2ClientBaseException
{ {
public function __construct($message = "") public function __construct($client_id, $message = "")
{ {
$message = "Invalid OAuth2 Client : " . $message; $message = "Invalid OAuth2 Client : " . $message;
parent::__construct($message, 0, null); parent::__construct($client_id, $message);
} }
} }

View File

@ -0,0 +1,13 @@
<?php
namespace oauth2\exceptions;
class InvalidClientType extends OAuth2ClientBaseException
{
public function __construct($client_id, $message = "")
{
$message = "Invalid Client Type: " . $message;
parent::__construct($client_id,$message);
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace oauth2\exceptions;
class InvalidRedeemAuthCodeException extends OAuth2ClientBaseException{
public function __construct($client_id, $message = "")
{
$message = "Invalid Redeem AuthCode Exception: " . $message;
parent::__construct($client_id,$message);
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace oauth2\exceptions;
class LockedClientException extends OAuth2ClientBaseException
{
public function __construct($client_id, $message = "")
{
$message = "Locked Client Exception: " . $message;
parent::__construct($client_id,$message);
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace oauth2\exceptions;
use Exception;
class MissingClientAuthorizationInfo extends Exception
{
public function __construct($message = "")
{
$message = "Missing Client Authorization Info: " . $message;
parent::__construct($message, 0, null);
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace oauth2\exceptions;
use Exception;
class MissingClientIdParam extends Exception
{
public function __construct($message = "")
{
$message = "Missing ClientId Param: " . $message;
parent::__construct($message, 0, null);
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace oauth2\exceptions;
use Exception;
class OAuth2ClientBaseException extends Exception
{
protected $client_id;
public function __construct($client_id, $message = "")
{
$this->client_id = $client_id;
$message = "OAuth2 Client Base Exception : " . $message;
parent::__construct($message, 0, null);
}
public function getClientId(){
return $this->client_id;
}
}

View File

@ -6,7 +6,6 @@ use Exception;
class ReplayAttackException extends Exception class ReplayAttackException extends Exception
{ {
private $auth_code; private $auth_code;
public function getAuthCode(){ public function getAuthCode(){
@ -19,5 +18,4 @@ class ReplayAttackException extends Exception
$message = "Possible Replay Attack : " . $message; $message = "Possible Replay Attack : " . $message;
parent::__construct($message, 0, null); parent::__construct($message, 0, null);
} }
} }

View File

@ -1,13 +1,12 @@
<?php <?php
namespace oauth2\exceptions; namespace oauth2\exceptions;
use \Exception;
class UnAuthorizedClientException extends Exception class UnAuthorizedClientException extends OAuth2ClientBaseException
{ {
public function __construct($message = "") public function __construct($client_id, $message = "")
{ {
$message = "UnAuthorized Client: " . $message; $message = "UnAuthorized Client: " . $message;
parent::__construct($message, 0, null); parent::__construct($client_id,$message);
} }
} }

View File

@ -0,0 +1,16 @@
<?php
namespace oauth2\exceptions;
use Exception;
class UseRefreshTokenException extends Exception
{
public function __construct($message = "")
{
$message = "Use Refresh Token Exception: " . $message;
parent::__construct($message, 0, null);
}
}

View File

@ -3,7 +3,10 @@
namespace oauth2\grant_types; namespace oauth2\grant_types;
use oauth2\exceptions\InvalidClientException; use oauth2\exceptions\InvalidClientException;
use oauth2\exceptions\UnAuthorizedClientException; use oauth2\exceptions\InvalidClientType;
use oauth2\exceptions\MissingClientIdParam;
use oauth2\exceptions\LockedClientException;
use oauth2\models\IClient; use oauth2\models\IClient;
use oauth2\requests\OAuth2Request; use oauth2\requests\OAuth2Request;
use oauth2\services\IClientService; use oauth2\services\IClientService;
@ -34,8 +37,11 @@ abstract class AbstractGrantType implements IGrantType
/** /**
* @param OAuth2Request $request * @param OAuth2Request $request
* @return mixed|void * @return mixed|void
* @throws \oauth2\exceptions\UnAuthorizedClientException * @throws \oauth2\exceptions\MissingClientIdParam
* @throws \oauth2\exceptions\InvalidClientType
* @throws \oauth2\exceptions\InvalidClientException * @throws \oauth2\exceptions\InvalidClientException
* @throws \oauth2\exceptions\LockedClientException
* @throws \oauth2\exceptions\MissingClientAuthorizationInfo
*/ */
public function completeFlow(OAuth2Request $request) public function completeFlow(OAuth2Request $request)
{ {
@ -44,21 +50,21 @@ abstract class AbstractGrantType implements IGrantType
//check if we have at least a client id //check if we have at least a client id
if (empty($this->current_client_id)) if (empty($this->current_client_id))
throw new InvalidClientException; throw new MissingClientIdParam();
//retrieve client from storage.. //retrieve client from storage..
$this->current_client = $this->client_service->getClientById($this->current_client_id); $this->current_client = $this->client_service->getClientById($this->current_client_id);
if (is_null($this->current_client)) if (is_null($this->current_client))
throw new InvalidClientException; throw new InvalidClientException($this->current_client_id,sprintf("client id %s does not exists!",$this->current_client_id));
if (!$this->current_client->isActive() || $this->current_client->isLocked()) { if (!$this->current_client->isActive() || $this->current_client->isLocked()) {
throw new UnAuthorizedClientException(sprintf('client id %s',$this->current_client_id)); throw new LockedClientException($this->current_client_id, sprintf('client id %s',$this->current_client_id));
} }
//verify client credentials (only for confidential clients ) //verify client credentials (only for confidential clients )
if ($this->current_client->getClientType() == IClient::ClientType_Confidential && $this->current_client->getClientSecret() !== $this->current_client_secret) if ($this->current_client->getClientType() == IClient::ClientType_Confidential && $this->current_client->getClientSecret() !== $this->current_client_secret)
throw new UnAuthorizedClientException(sprintf('client id %s',$this->current_client_id)); throw new InvalidClientType($this->current_client_id,sprintf('client id %s',$this->current_client_id));
} }
} }

View File

@ -7,10 +7,12 @@ use oauth2\exceptions\AccessDeniedException;
use oauth2\exceptions\InvalidAuthorizationCodeException; use oauth2\exceptions\InvalidAuthorizationCodeException;
use oauth2\exceptions\InvalidClientException; use oauth2\exceptions\InvalidClientException;
use oauth2\exceptions\InvalidOAuth2Request; use oauth2\exceptions\InvalidOAuth2Request;
use oauth2\exceptions\LockedClientException;
use oauth2\exceptions\OAuth2GenericException; use oauth2\exceptions\OAuth2GenericException;
use oauth2\exceptions\ScopeNotAllowedException; use oauth2\exceptions\ScopeNotAllowedException;
use oauth2\exceptions\UnAuthorizedClientException; use oauth2\exceptions\InvalidRedeemAuthCodeException;
use oauth2\exceptions\UnsupportedResponseTypeException; use oauth2\exceptions\UnsupportedResponseTypeException;
use oauth2\exceptions\InvalidApplicationType;
use oauth2\exceptions\UriNotAllowedException; use oauth2\exceptions\UriNotAllowedException;
use oauth2\models\IClient; use oauth2\models\IClient;
@ -29,6 +31,7 @@ use oauth2\services\IApiScopeService;
use ReflectionClass; use ReflectionClass;
use utils\services\IAuthService; use utils\services\IAuthService;
use utils\services\ILogService; use utils\services\ILogService;
use oauth2\services\IUserConsentService;
/** /**
* Class AuthorizationCodeGrantType * Class AuthorizationCodeGrantType
@ -48,16 +51,12 @@ class AuthorizationCodeGrantType extends AbstractGrantType
private $auth_strategy; private $auth_strategy;
private $memento_service; private $memento_service;
private $scope_service; private $scope_service;
private $user_consent_service;
public function __construct(IApiScopeService $scope_service ,IClientService $client_service, ITokenService $token_service, IAuthService $auth_service, IMementoOAuth2AuthenticationRequestService $memento_service, IOAuth2AuthenticationStrategy $auth_strategy, ILogService $log_service) /**
{ * @param OAuth2Request $request
parent::__construct($client_service, $token_service,$log_service); * @return bool
$this->scope_service = $scope_service; */
$this->auth_service = $auth_service;
$this->memento_service = $memento_service;
$this->auth_strategy = $auth_strategy;
}
public function canHandle(OAuth2Request $request) public function canHandle(OAuth2Request $request)
{ {
$reflector = new ReflectionClass($request); $reflector = new ReflectionClass($request);
@ -67,22 +66,46 @@ class AuthorizationCodeGrantType extends AbstractGrantType
($class_name == 'oauth2\requests\OAuth2TokenRequest' && $request->isValid() && $request->getGrantType() === $this->getType()); ($class_name == 'oauth2\requests\OAuth2TokenRequest' && $request->isValid() && $request->getGrantType() === $this->getType());
} }
/**
* @param IApiScopeService $scope_service
* @param IClientService $client_service
* @param ITokenService $token_service
* @param IAuthService $auth_service
* @param IMementoOAuth2AuthenticationRequestService $memento_service
* @param IOAuth2AuthenticationStrategy $auth_strategy
* @param ILogService $log_service
* @param IUserConsentService $user_consent_service
*/
public function __construct(IApiScopeService $scope_service ,IClientService $client_service, ITokenService $token_service, IAuthService $auth_service, IMementoOAuth2AuthenticationRequestService $memento_service, IOAuth2AuthenticationStrategy $auth_strategy, ILogService $log_service, IUserConsentService $user_consent_service)
{
parent::__construct($client_service, $token_service,$log_service);
$this->user_consent_service = $user_consent_service;
$this->scope_service = $scope_service;
$this->auth_service = $auth_service;
$this->memento_service = $memento_service;
$this->auth_strategy = $auth_strategy;
}
/**
* @return mixed|string
*/
public function getType() public function getType()
{ {
return OAuth2Protocol::OAuth2Protocol_GrantType_AuthCode; return OAuth2Protocol::OAuth2Protocol_GrantType_AuthCode;
} }
/** Implements first request processing for Authorization code (Authorization Request processing) /** Implements first request processing for Authorization code (Authorization Request processing)
* http://tools.ietf.org/html/rfc6749#section-4.1.1 and * http://tools.ietf.org/html/rfc6749#section-4.1.1 and
* http://tools.ietf.org/html/rfc6749#section-4.1.2 * http://tools.ietf.org/html/rfc6749#section-4.1.2
* @param OAuth2Request $request * @param OAuth2Request $request
* @return mixed|OAuth2AuthorizationResponse * @return mixed|OAuth2AuthorizationResponse
* @throws \oauth2\exceptions\InvalidClientException
* @throws \oauth2\exceptions\UnsupportedResponseTypeException * @throws \oauth2\exceptions\UnsupportedResponseTypeException
* @throws \oauth2\exceptions\AccessDeniedException * @throws \oauth2\exceptions\LockedClientException
* @throws \oauth2\exceptions\InvalidClientException
* @throws \oauth2\exceptions\ScopeNotAllowedException * @throws \oauth2\exceptions\ScopeNotAllowedException
* @throws \oauth2\exceptions\OAuth2GenericException * @throws \oauth2\exceptions\OAuth2GenericException
* @throws \oauth2\exceptions\UnAuthorizedClientException * @throws \oauth2\exceptions\InvalidApplicationType
* @throws \oauth2\exceptions\AccessDeniedException
* @throws \oauth2\exceptions\UriNotAllowedException * @throws \oauth2\exceptions\UriNotAllowedException
* @throws \oauth2\exceptions\InvalidOAuth2Request * @throws \oauth2\exceptions\InvalidOAuth2Request
*/ */
@ -102,10 +125,15 @@ class AuthorizationCodeGrantType extends AbstractGrantType
$client = $this->client_service->getClientById($client_id); $client = $this->client_service->getClientById($client_id);
if (is_null($client)) if (is_null($client))
throw new InvalidClientException(sprintf("client_id %s", $client_id)); throw new InvalidClientException($client_id, sprintf("client_id %s does not exists!", $client_id));
if (!$client->isActive() || $client->isLocked()) {
throw new LockedClientException(sprintf($client,'client id %s is locked',$client));
}
if ($client->getApplicationType() != IClient::ApplicationType_Web_App)
throw new InvalidApplicationType($client_id,sprintf("client id %s - Application type must be WEB_APPLICATION",$client_id));
if ($client->getClientType() !== IClient::ClientType_Confidential)
throw new UnAuthorizedClientException();
//check redirect uri //check redirect uri
$redirect_uri = $request->getRedirectUri(); $redirect_uri = $request->getRedirectUri();
if (!$client->isUriAllowed($redirect_uri)) if (!$client->isUriAllowed($redirect_uri))
@ -123,19 +151,34 @@ class AuthorizationCodeGrantType extends AbstractGrantType
return $this->auth_strategy->doLogin($this->memento_service->getCurrentAuthorizationRequest()); return $this->auth_strategy->doLogin($this->memento_service->getCurrentAuthorizationRequest());
} }
$approval_prompt = $request->getApprovalPrompt();
$access_type = $request->getAccessType();
$user = $this->auth_service->getCurrentUser();
if(is_null($user))
throw new OAuth2GenericException("Invalid Current User");
$authorization_response = $this->auth_service->getUserAuthorizationResponse(); $authorization_response = $this->auth_service->getUserAuthorizationResponse();
if ($authorization_response === IAuthService::AuthorizationResponse_None) { //check for former user consents
$this->memento_service->saveCurrentAuthorizationRequest(); $former_user_consent = $this->user_consent_service->get($user->getId(),$client->getId(),$scope);
return $this->auth_strategy->doConsent($this->memento_service->getCurrentAuthorizationRequest());
} else if ($authorization_response === IAuthService::AuthorizationResponse_DenyOnce) {
throw new AccessDeniedException;
}
if( !(!is_null($former_user_consent) && $approval_prompt == OAuth2Protocol::OAuth2Protocol_Approval_Prompt_Auto)){
if ($authorization_response == IAuthService::AuthorizationResponse_None) {
$this->memento_service->saveCurrentAuthorizationRequest();
return $this->auth_strategy->doConsent($this->memento_service->getCurrentAuthorizationRequest());
}
else if ($authorization_response == IAuthService::AuthorizationResponse_DenyOnce) {
throw new AccessDeniedException;
}
//save possitive consent
if(is_null($former_user_consent)){
$this->user_consent_service->add($user->getId(),$client->getId(),$scope);
}
}
// build current audience ... // build current audience ...
$audience = $this->scope_service->getStrAudienceByScopeNames(explode(' ',$scope)); $audience = $this->scope_service->getStrAudienceByScopeNames(explode(' ',$scope));
$auth_code = $this->token_service->createAuthorizationCode($client_id, $scope, $audience, $redirect_uri); $auth_code = $this->token_service->createAuthorizationCode($user->getId(), $client_id, $scope, $audience, $redirect_uri,$access_type,$approval_prompt,!is_null($former_user_consent));
if (is_null($auth_code)) if (is_null($auth_code))
throw new OAuth2GenericException("Invalid Auth Code"); throw new OAuth2GenericException("Invalid Auth Code");
@ -147,6 +190,9 @@ class AuthorizationCodeGrantType extends AbstractGrantType
throw new InvalidOAuth2Request; throw new InvalidOAuth2Request;
} }
/**
* @return mixed|string
*/
public function getResponseType() public function getResponseType()
{ {
return OAuth2Protocol::OAuth2Protocol_ResponseType_Code; return OAuth2Protocol::OAuth2Protocol_ResponseType_Code;
@ -167,61 +213,66 @@ class AuthorizationCodeGrantType extends AbstractGrantType
*/ */
public function completeFlow(OAuth2Request $request) public function completeFlow(OAuth2Request $request)
{ {
$reflector = new ReflectionClass($request); $reflector = new ReflectionClass($request);
$class_name = $reflector->getName(); $class_name = $reflector->getName();
if ($class_name == 'oauth2\requests\OAuth2AccessTokenRequestAuthCode') { try{
if ($class_name == 'oauth2\requests\OAuth2AccessTokenRequestAuthCode') {
parent::completeFlow($request); parent::completeFlow($request);
//only confidential clients could use this grant type //only confidential clients could use this grant type
if ($this->current_client->getClientType() !== IClient::ClientType_Confidential)
throw new UnAuthorizedClientException();
if ($this->current_client->getApplicationType() != IClient::ApplicationType_Web_App)
throw new InvalidApplicationType($this->current_client_id,sprintf("client id %s - Application type must be WEB_APPLICATION",$this->current_client_id));
$current_redirect_uri = $request->getRedirectUri(); $current_redirect_uri = $request->getRedirectUri();
//verify redirect uri //verify redirect uri
if (!$this->current_client->isUriAllowed($current_redirect_uri)) if (!$this->current_client->isUriAllowed($current_redirect_uri))
throw new UriNotAllowedException(); throw new UriNotAllowedException(sprintf('redirect url %s is not allowed for cliend id %s',$current_redirect_uri,$this->current_client_id));
$code = $request->getCode(); $code = $request->getCode();
// verify that the authorization code is valid // verify that the authorization code is valid
// The client MUST NOT use the authorization code // The client MUST NOT use the authorization code
// more than once. If an authorization code is used more than // more than once. If an authorization code is used more than
// once, the authorization server MUST deny the request and SHOULD // once, the authorization server MUST deny the request and SHOULD
// revoke (when possible) all tokens previously issued based on // revoke (when possible) all tokens previously issued based on
// that authorization code. The authorization code is bound to // that authorization code. The authorization code is bound to
// the client identifier and redirection URI. // the client identifier and redirection URI.
$auth_code = $this->token_service->getAuthorizationCode($code); $auth_code = $this->token_service->getAuthorizationCode($code);
// verify that the authorization code is valid
if (is_null($auth_code)) { $client_id = $auth_code->getClientId();
throw new InvalidAuthorizationCodeException();
//ensure that the authorization code was issued to the authenticated
//confidential client, or if the client is public, ensure that the
//code was issued to "client_id" in the request
if ($client_id != $this->current_client_id)
throw new InvalidRedeemAuthCodeException($this->current_client_id,sprintf("auth code was issued for another client id!."));
// ensure that the "redirect_uri" parameter is present if the
// "redirect_uri" parameter was included in the initial authorization
// and if included ensure that their values are identical.
$redirect_uri = $auth_code->getRedirectUri();
if (!empty($redirect_uri) && $redirect_uri !== $current_redirect_uri)
throw new UriNotAllowedException();
$access_token = $this->token_service->createAccessToken($auth_code, $current_redirect_uri);
$refresh_token = $access_token->getRefreshToken();
$response = new OAuth2AccessTokenResponse($access_token->getValue(), $access_token->getLifetime(), !is_null($refresh_token) ? $refresh_token->getValue() : null);
return $response;
} }
}
$client_id = $auth_code->getClientId(); catch(InvalidAuthorizationCodeException $ex){
$this->log_service->error($ex);
//ensure that the authorization code was issued to the authenticated throw new InvalidRedeemAuthCodeException($this->current_client_id,$ex->getMessage());
//confidential client, or if the client is public, ensure that the
//code was issued to "client_id" in the request
if ($client_id !== $this->current_client_id)
throw new UnAuthorizedClientException;
// ensure that the "redirect_uri" parameter is present if the
// "redirect_uri" parameter was included in the initial authorization
// and if included ensure that their values are identical.
$redirect_uri = $auth_code->getRedirectUri();
if (!empty($redirect_uri) && $redirect_uri !== $current_redirect_uri)
throw new UriNotAllowedException();
$access_token = $this->token_service->createAccessToken($auth_code, $current_redirect_uri);
$refresh_token = $access_token->getRefreshToken();
$response = new OAuth2AccessTokenResponse($access_token->getValue(), $access_token->getLifetime(), !is_null($refresh_token) ? $refresh_token->getValue() : null);
return $response;
} }
throw new InvalidOAuth2Request; throw new InvalidOAuth2Request;
} }
/**
* @param OAuth2Request $request
* @return mixed|null|OAuth2AccessTokenRequestAuthCode
*/
public function buildTokenRequest(OAuth2Request $request) public function buildTokenRequest(OAuth2Request $request)
{ {
$reflector = new ReflectionClass($request); $reflector = new ReflectionClass($request);

View File

@ -6,8 +6,8 @@ namespace oauth2\grant_types;
use oauth2\exceptions\InvalidGrantTypeException; use oauth2\exceptions\InvalidGrantTypeException;
use oauth2\exceptions\InvalidOAuth2Request; use oauth2\exceptions\InvalidOAuth2Request;
use oauth2\exceptions\ScopeNotAllowedException; use oauth2\exceptions\ScopeNotAllowedException;
use oauth2\exceptions\InvalidApplicationType;
use oauth2\exceptions\UnAuthorizedClientException;
use oauth2\models\IClient; use oauth2\models\IClient;
use oauth2\OAuth2Protocol; use oauth2\OAuth2Protocol;
use oauth2\requests\OAuth2AccessTokenRequestClientCredentials; use oauth2\requests\OAuth2AccessTokenRequestClientCredentials;
@ -80,9 +80,10 @@ class ClientCredentialsGrantType extends AbstractGrantType
/** /**
* @param OAuth2Request $request * @param OAuth2Request $request
* @return mixed|OAuth2AccessTokenResponse|void * @return mixed|OAuth2AccessTokenResponse|void
* @throws \oauth2\exceptions\UnAuthorizedClientException
* @throws \oauth2\exceptions\InvalidOAuth2Request
* @throws \oauth2\exceptions\ScopeNotAllowedException * @throws \oauth2\exceptions\ScopeNotAllowedException
* @throws \oauth2\exceptions\InvalidOAuth2Request
* @throws \oauth2\exceptions\InvalidApplicationType
* @throws \oauth2\exceptions\InvalidGrantTypeException
*/ */
public function completeFlow(OAuth2Request $request) public function completeFlow(OAuth2Request $request)
{ {
@ -96,8 +97,8 @@ class ClientCredentialsGrantType extends AbstractGrantType
parent::completeFlow($request); parent::completeFlow($request);
//only confidential clients could use this grant type //only confidential clients could use this grant type
if ($this->current_client->getClientType() !== IClient::ClientType_Confidential) if ($this->current_client->getApplicationType() != IClient::ApplicationType_Service)
throw new UnAuthorizedClientException(); throw new InvalidApplicationType($this->current_client_id,sprintf('client id %s client type must be SERVICE',$this->current_client_id));
//check requested scope //check requested scope
$scope = $request->getScope(); $scope = $request->getScope();
@ -108,7 +109,7 @@ class ClientCredentialsGrantType extends AbstractGrantType
$audience = $this->scope_service->getStrAudienceByScopeNames(explode(' ', $scope)); $audience = $this->scope_service->getStrAudienceByScopeNames(explode(' ', $scope));
//build access token //build access token
$access_token = $this->token_service->createAccessTokenFromParams($scope, $this->current_client_id, $audience); $access_token = $this->token_service->createAccessTokenFromParams($this->current_client_id,$scope, $audience);
$response = new OAuth2AccessTokenResponse($access_token->getValue(), $access_token->getLifetime(), null); $response = new OAuth2AccessTokenResponse($access_token->getValue(), $access_token->getLifetime(), null);
return $response; return $response;

View File

@ -6,7 +6,9 @@ use oauth2\exceptions\AccessDeniedException;
use oauth2\exceptions\InvalidClientException; use oauth2\exceptions\InvalidClientException;
use oauth2\exceptions\InvalidOAuth2Request; use oauth2\exceptions\InvalidOAuth2Request;
use oauth2\exceptions\ScopeNotAllowedException; use oauth2\exceptions\ScopeNotAllowedException;
use oauth2\exceptions\UnAuthorizedClientException; use oauth2\exceptions\OAuth2GenericException;
use oauth2\exceptions\InvalidApplicationType;
use oauth2\exceptions\LockedClientException;
use oauth2\exceptions\UnsupportedResponseTypeException; use oauth2\exceptions\UnsupportedResponseTypeException;
use oauth2\exceptions\UriNotAllowedException; use oauth2\exceptions\UriNotAllowedException;
@ -24,7 +26,7 @@ use oauth2\strategies\IOAuth2AuthenticationStrategy;
use ReflectionClass; use ReflectionClass;
use utils\services\IAuthService; use utils\services\IAuthService;
use utils\services\ILogService; use utils\services\ILogService;
use oauth2\services\IUserConsentService;
/** /**
* Class ImplicitGrantType * Class ImplicitGrantType
* http://tools.ietf.org/html/rfc6749#section-4.2 * http://tools.ietf.org/html/rfc6749#section-4.2
@ -55,13 +57,14 @@ class ImplicitGrantType extends AbstractGrantType
private $auth_strategy; private $auth_strategy;
private $scope_service; private $scope_service;
public function __construct(IApiScopeService $scope_service, IClientService $client_service, ITokenService $token_service, IAuthService $auth_service, IMementoOAuth2AuthenticationRequestService $memento_service, IOAuth2AuthenticationStrategy $auth_strategy, ILogService $log_service) public function __construct(IApiScopeService $scope_service, IClientService $client_service, ITokenService $token_service, IAuthService $auth_service, IMementoOAuth2AuthenticationRequestService $memento_service, IOAuth2AuthenticationStrategy $auth_strategy, ILogService $log_service, IUserConsentService $user_consent_service)
{ {
parent::__construct($client_service, $token_service, $log_service); parent::__construct($client_service, $token_service, $log_service);
$this->scope_service = $scope_service; $this->user_consent_service = $user_consent_service;
$this->auth_service = $auth_service; $this->scope_service = $scope_service;
$this->memento_service = $memento_service; $this->auth_service = $auth_service;
$this->auth_strategy = $auth_strategy; $this->memento_service = $memento_service;
$this->auth_strategy = $auth_strategy;
} }
/** Given an OAuth2Request, returns true if it can handle it, false otherwise /** Given an OAuth2Request, returns true if it can handle it, false otherwise
@ -87,13 +90,15 @@ class ImplicitGrantType extends AbstractGrantType
/** /**
* @param OAuth2Request $request * @param OAuth2Request $request
* @return mixed|OAuth2AccessTokenFragmentResponse * @return mixed|OAuth2AccessTokenFragmentResponse
* @throws \oauth2\exceptions\InvalidClientException
* @throws \oauth2\exceptions\UnsupportedResponseTypeException * @throws \oauth2\exceptions\UnsupportedResponseTypeException
* @throws \oauth2\exceptions\AccessDeniedException * @throws \oauth2\exceptions\LockedClientException
* @throws \oauth2\exceptions\InvalidClientException
* @throws \oauth2\exceptions\ScopeNotAllowedException * @throws \oauth2\exceptions\ScopeNotAllowedException
* @throws \oauth2\exceptions\InvalidOAuth2Request * @throws \oauth2\exceptions\OAuth2GenericException
* @throws \oauth2\exceptions\UnAuthorizedClientException * @throws \oauth2\exceptions\InvalidApplicationType
* @throws \oauth2\exceptions\AccessDeniedException
* @throws \oauth2\exceptions\UriNotAllowedException * @throws \oauth2\exceptions\UriNotAllowedException
* @throws \oauth2\exceptions\InvalidOAuth2Request
*/ */
public function handle(OAuth2Request $request) public function handle(OAuth2Request $request)
{ {
@ -109,13 +114,18 @@ class ImplicitGrantType extends AbstractGrantType
throw new UnsupportedResponseTypeException(sprintf("response_type %s", $response_type)); throw new UnsupportedResponseTypeException(sprintf("response_type %s", $response_type));
$client = $this->client_service->getClientById($client_id); $client = $this->client_service->getClientById($client_id);
if (is_null($client)) if (is_null($client))
throw new InvalidClientException(sprintf("client_id %s", $client_id)); throw new InvalidClientException($client_id, sprintf("client_id %s", $client_id));
if (!$client->isActive() || $client->isLocked()) {
throw new LockedClientException($client,sprintf('client id %s',$client));
}
//check client type //check client type
// only public clients could use this grant type // only public clients could use this grant type
if ($client->getClientType() !== IClient::ClientType_Public) if ($client->getApplicationType() != IClient::ApplicationType_JS_Client)
throw new UnAuthorizedClientException(); throw new InvalidApplicationType($client_id,sprintf('client id %s client type must be JS CLIENT',$client_id));
//check redirect uri //check redirect uri
$redirect_uri = $request->getRedirectUri(); $redirect_uri = $request->getRedirectUri();
@ -135,19 +145,34 @@ class ImplicitGrantType extends AbstractGrantType
return $this->auth_strategy->doLogin($this->memento_service->getCurrentAuthorizationRequest()); return $this->auth_strategy->doLogin($this->memento_service->getCurrentAuthorizationRequest());
} }
$approval_prompt = $request->getApprovalPrompt();
$user = $this->auth_service->getCurrentUser();
if(is_null($user))
throw new OAuth2GenericException("Invalid Current User");
//validate authorization //validate authorization
//check for former user consents
$authorization_response = $this->auth_service->getUserAuthorizationResponse(); $authorization_response = $this->auth_service->getUserAuthorizationResponse();
if ($authorization_response === IAuthService::AuthorizationResponse_None) { $former_user_consent = $this->user_consent_service->get($user->getId(),$client->getId(),$scope);
$this->memento_service->saveCurrentAuthorizationRequest(); if( !(!is_null($former_user_consent) && $approval_prompt == OAuth2Protocol::OAuth2Protocol_Approval_Prompt_Auto)){
return $this->auth_strategy->doConsent($this->memento_service->getCurrentAuthorizationRequest()); if ($authorization_response == IAuthService::AuthorizationResponse_None) {
} else if ($authorization_response === IAuthService::AuthorizationResponse_DenyOnce) { $this->memento_service->saveCurrentAuthorizationRequest();
throw new AccessDeniedException; return $this->auth_strategy->doConsent($this->memento_service->getCurrentAuthorizationRequest());
}
else if ($authorization_response == IAuthService::AuthorizationResponse_DenyOnce) {
throw new AccessDeniedException;
}
//save possitive consent
if(is_null($former_user_consent))
$this->user_consent_service->add($user->getId(),$client->getId(),$scope);
} }
// build current audience ... // build current audience ...
$audience = $this->scope_service->getStrAudienceByScopeNames(explode(' ',$scope)); $audience = $this->scope_service->getStrAudienceByScopeNames(explode(' ',$scope));
//build access token //build access token
$access_token = $this->token_service->createAccessTokenFromParams($scope, $client_id, $audience); $access_token = $this->token_service->createAccessTokenFromParams($client_id,$scope, $audience,$user->getId());
//clear saved data ... //clear saved data ...
$this->memento_service->clearCurrentRequest(); $this->memento_service->clearCurrentRequest();
$this->auth_service->clearUserAuthorizationResponse(); $this->auth_service->clearUserAuthorizationResponse();
@ -169,9 +194,10 @@ class ImplicitGrantType extends AbstractGrantType
return OAuth2Protocol::OAuth2Protocol_GrantType_Implicit; return OAuth2Protocol::OAuth2Protocol_GrantType_Implicit;
} }
/** builds specific Token request /**
* @param OAuth2Request $request * @param OAuth2Request $request
* @return mixed * @return mixed|void
* @throws \oauth2\exceptions\InvalidOAuth2Request
*/ */
public function buildTokenRequest(OAuth2Request $request) public function buildTokenRequest(OAuth2Request $request)
{ {

View File

@ -3,7 +3,7 @@
namespace oauth2\grant_types; namespace oauth2\grant_types;
use Exception; use Exception;
use oauth2\models\IClient;
use oauth2\requests\OAuth2Request; use oauth2\requests\OAuth2Request;
use oauth2\OAuth2Protocol; use oauth2\OAuth2Protocol;
use oauth2\services\IClientService; use oauth2\services\IClientService;
@ -13,7 +13,8 @@ use oauth2\requests\OAuth2RefreshAccessTokenRequest;
use ReflectionClass; use ReflectionClass;
use oauth2\exceptions\UnAuthorizedClientException; use oauth2\exceptions\InvalidApplicationType;
use oauth2\exceptions\UseRefreshTokenException;
use oauth2\exceptions\InvalidOAuth2Request; use oauth2\exceptions\InvalidOAuth2Request;
use oauth2\exceptions\InvalidGrantTypeException; use oauth2\exceptions\InvalidGrantTypeException;
@ -66,9 +67,10 @@ class RefreshBearerTokenGrantType extends AbstractGrantType {
* o validate the refresh token. * o validate the refresh token.
* *
* @param OAuth2Request $request * @param OAuth2Request $request
* @return OAuth2AccessTokenResponse|void * @return mixed|OAuth2AccessTokenResponse|void
* @throws \oauth2\exceptions\UnAuthorizedClientException * @throws \oauth2\exceptions\UseRefreshTokenException
* @throws \oauth2\exceptions\InvalidOAuth2Request * @throws \oauth2\exceptions\InvalidOAuth2Request
* @throws \oauth2\exceptions\InvalidApplicationType
* @throws \oauth2\exceptions\InvalidGrantTypeException * @throws \oauth2\exceptions\InvalidGrantTypeException
*/ */
public function completeFlow(OAuth2Request $request) public function completeFlow(OAuth2Request $request)
@ -79,8 +81,11 @@ class RefreshBearerTokenGrantType extends AbstractGrantType {
parent::completeFlow($request); parent::completeFlow($request);
if($this->current_client->getApplicationType()!=IClient::ApplicationType_Web_App)
throw new InvalidApplicationType($this->current_client_id,sprintf('client id %s client type must be WEB_APPLICATION',$this->current_client_id));
if(!$this->current_client->use_refresh_token) if(!$this->current_client->use_refresh_token)
throw new UnAuthorizedClientException("current client could not use refresh tokens"); throw new UseRefreshTokenException("current client id %s could not use refresh tokens",$this->current_client_id);
$refresh_token_value = $request->getRefreshToken(); $refresh_token_value = $request->getRefreshToken();
$scope = $request->getScope(); $scope = $request->getScope();

View File

@ -97,7 +97,7 @@ class RevokeBearerTokenGrantType extends AbstractGrantType
//check ownership //check ownership
$access_token = $this->token_service->getAccessToken($token_value); $access_token = $this->token_service->getAccessToken($token_value);
if ($access_token->getClientId() !== $this->current_client_id) if ($access_token->getClientId() !== $this->current_client_id)
throw new BearerTokenDisclosureAttemptException(sprintf('access token %s does not belongs to client id %s',$token_value, $this->current_client_id)); throw new BearerTokenDisclosureAttemptException($this->current_client_id,sprintf('access token %s does not belongs to client id %s',$token_value, $this->current_client_id));
$this->token_service->revokeAccessToken($token_value, false); $this->token_service->revokeAccessToken($token_value, false);
} }
@ -107,7 +107,7 @@ class RevokeBearerTokenGrantType extends AbstractGrantType
//check ownership //check ownership
$refresh_token = $this->token_service->getRefreshToken($token_value); $refresh_token = $this->token_service->getRefreshToken($token_value);
if ($refresh_token->getClientId() !== $this->current_client_id) if ($refresh_token->getClientId() !== $this->current_client_id)
throw new BearerTokenDisclosureAttemptException(sprintf('refresh token %s does not belongs to client id %s',$token_value, $this->current_client_id)); throw new BearerTokenDisclosureAttemptException($this->current_client_id,sprintf('refresh token %s does not belongs to client id %s',$token_value, $this->current_client_id));
$this->token_service->revokeRefreshToken($token_value, false); $this->token_service->revokeRefreshToken($token_value, false);
} }
@ -126,7 +126,7 @@ class RevokeBearerTokenGrantType extends AbstractGrantType
//check ownership //check ownership
$access_token = $this->token_service->getAccessToken($token_value); $access_token = $this->token_service->getAccessToken($token_value);
if ($access_token->getClientId() !== $this->current_client_id) if ($access_token->getClientId() !== $this->current_client_id)
throw new BearerTokenDisclosureAttemptException(sprintf('access token %s does not belongs to client id %s',$token_value, $this->current_client_id)); throw new BearerTokenDisclosureAttemptException($this->current_client_id,sprintf('access token %s does not belongs to client id %s',$token_value, $this->current_client_id));
$this->token_service->revokeAccessToken($token_value, false); $this->token_service->revokeAccessToken($token_value, false);
} }
catch(UnAuthorizedClientException $ex1){ catch(UnAuthorizedClientException $ex1){
@ -139,14 +139,14 @@ class RevokeBearerTokenGrantType extends AbstractGrantType
//check ownership //check ownership
$refresh_token = $this->token_service->getRefreshToken($token_value); $refresh_token = $this->token_service->getRefreshToken($token_value);
if ($refresh_token->getClientId() !== $this->current_client_id) if ($refresh_token->getClientId() !== $this->current_client_id)
throw new BearerTokenDisclosureAttemptException(sprintf('refresh token %s does not belongs to client id %s',$token_value, $this->current_client_id)); throw new BearerTokenDisclosureAttemptException($this->current_client_id,sprintf('refresh token %s does not belongs to client id %s',$token_value, $this->current_client_id));
$this->token_service->revokeRefreshToken($token_value, false); $this->token_service->revokeRefreshToken($token_value, false);
} }
} }
return new OAuth2TokenRevocationResponse; return new OAuth2TokenRevocationResponse;
} }
catch(InvalidGrantTypeException $ex){ catch(InvalidGrantTypeException $ex){
throw new BearerTokenDisclosureAttemptException($ex->getMessage()); throw new BearerTokenDisclosureAttemptException($this->current_client_id,$ex->getMessage());
} }
} }
throw new InvalidOAuth2Request; throw new InvalidOAuth2Request;

View File

@ -2,10 +2,11 @@
namespace oauth2\grant_types; namespace oauth2\grant_types;
use oauth2\exceptions\InvalidApplicationType;
use oauth2\exceptions\InvalidOAuth2Request; use oauth2\exceptions\InvalidOAuth2Request;
use oauth2\exceptions\InvalidAccessTokenException; use oauth2\exceptions\InvalidAccessTokenException;
use oauth2\exceptions\BearerTokenDisclosureAttemptException; use oauth2\exceptions\BearerTokenDisclosureAttemptException;
use oauth2\exceptions\UnAuthorizedClientException; use oauth2\exceptions\LockedClientException;
use oauth2\exceptions\InvalidGrantTypeException; use oauth2\exceptions\InvalidGrantTypeException;
use oauth2\requests\OAuth2Request; use oauth2\requests\OAuth2Request;
@ -83,8 +84,9 @@ class ValidateBearerTokenGrantType extends AbstractGrantType
/** /**
* @param OAuth2Request $request * @param OAuth2Request $request
* @return mixed|OAuth2AccessTokenValidationResponse|void * @return mixed|OAuth2AccessTokenValidationResponse|void
* @throws \oauth2\exceptions\UnAuthorizedClientException
* @throws \oauth2\exceptions\InvalidOAuth2Request * @throws \oauth2\exceptions\InvalidOAuth2Request
* @throws \oauth2\exceptions\LockedClientException
* @throws \oauth2\exceptions\InvalidApplicationType
* @throws \oauth2\exceptions\BearerTokenDisclosureAttemptException * @throws \oauth2\exceptions\BearerTokenDisclosureAttemptException
*/ */
public function completeFlow(OAuth2Request $request) public function completeFlow(OAuth2Request $request)
@ -104,35 +106,35 @@ class ValidateBearerTokenGrantType extends AbstractGrantType
if(!$this->current_client->isResourceServerClient()){ if(!$this->current_client->isResourceServerClient()){
// if current client is not a resource server, then we could only access to our own tokens // if current client is not a resource server, then we could only access to our own tokens
if($access_token->getClientId()!== $this->current_client_id) if($access_token->getClientId()!== $this->current_client_id)
throw new BearerTokenDisclosureAttemptException(sprintf('access token %s does not belongs to client id %s',$token_value, $this->current_client_id)); throw new BearerTokenDisclosureAttemptException($this->current_client_id,sprintf('access token %s does not belongs to client id %s',$token_value, $this->current_client_id));
} }
else{ else{
// current client is a resource server, validate client type (must be confidential) // current client is a resource server, validate client type (must be confidential)
if($this->current_client->getClientType()!== IClient::ClientType_Confidential) if($this->current_client->getClientType()!== IClient::ClientType_Confidential)
throw new UnAuthorizedClientException('resource server client is not of confidential type!'); throw new InvalidApplicationType($this->current_client_id,'resource server client is not of confidential type!');
//validate resource server IP address //validate resource server IP address
$current_ip = IPHelper::getUserIp(); $current_ip = IPHelper::getUserIp();
$resource_server = $this->current_client->getResourceServer(); $resource_server = $this->current_client->getResourceServer();
//check if resource server is active //check if resource server is active
if(!$resource_server->active) if(!$resource_server->active)
throw new UnAuthorizedClientException('resource server is disabled!'); throw new LockedClientException($this->current_client_id,'resource server is disabled!');
//check resource server ip address //check resource server ip address
if($current_ip !== $resource_server->ip) if($current_ip !== $resource_server->ip)
throw new BearerTokenDisclosureAttemptException(sprintf('resource server ip (%s) differs from current request ip %s',$resource_server->ip,$current_ip)); throw new BearerTokenDisclosureAttemptException($this->current_client_id,sprintf('resource server ip (%s) differs from current request ip %s',$resource_server->ip,$current_ip));
// check if current ip belongs to a registered resource server audience // check if current ip belongs to a registered resource server audience
if(!$this->token_service->checkAccessTokenAudience($access_token,$current_ip)) if(!$this->token_service->checkAccessTokenAudience($access_token,$current_ip))
throw new BearerTokenDisclosureAttemptException(sprintf('access token current audience does not match with current request ip %s', $current_ip)); throw new BearerTokenDisclosureAttemptException($this->current_client_id,sprintf('access token current audience does not match with current request ip %s', $current_ip));
} }
return new OAuth2AccessTokenValidationResponse($token_value, $access_token->getScope(), $access_token->getAudience(),$access_token->getClientId(),$access_token->getRemainingLifetime()); return new OAuth2AccessTokenValidationResponse($token_value, $access_token->getScope(), $access_token->getAudience(),$access_token->getClientId(),$access_token->getRemainingLifetime(),$access_token->getUserId());
} }
catch(InvalidAccessTokenException $ex1){ catch(InvalidAccessTokenException $ex1){
$this->log_service->error($ex1); $this->log_service->error($ex1);
throw new BearerTokenDisclosureAttemptException($ex1->getMessage()); throw new BearerTokenDisclosureAttemptException($this->current_client_id,$ex1->getMessage());
} }
catch(InvalidGrantTypeException $ex2){ catch(InvalidGrantTypeException $ex2){
$this->log_service->error($ex2); $this->log_service->error($ex2);
throw new BearerTokenDisclosureAttemptException($ex2->getMessage()); throw new BearerTokenDisclosureAttemptException($this->current_client_id,$ex2->getMessage());
} }
} }
throw new InvalidOAuth2Request; throw new InvalidOAuth2Request;

View File

@ -22,6 +22,7 @@ class AccessToken extends Token {
public static function create(AuthorizationCode $auth_code, $lifetime = 3600){ public static function create(AuthorizationCode $auth_code, $lifetime = 3600){
$instance = new self(); $instance = new self();
$instance->value = Rand::getString($instance->len, OAuth2Protocol::VsChar, true); $instance->value = Rand::getString($instance->len, OAuth2Protocol::VsChar, true);
$instance->user_id = $auth_code->getUserId();
$instance->scope = $auth_code->getScope(); $instance->scope = $auth_code->getScope();
$instance->client_id = $auth_code->getClientId(); $instance->client_id = $auth_code->getClientId();
$instance->auth_code = $auth_code->getValue(); $instance->auth_code = $auth_code->getValue();
@ -31,11 +32,12 @@ class AccessToken extends Token {
return $instance; return $instance;
} }
public static function createFromParams($scope, $client_id, $audience,$lifetime){ public static function createFromParams($scope, $client_id, $audience,$user_id,$lifetime){
$instance = new self(); $instance = new self();
$instance->value = Rand::getString($instance->len,OAuth2Protocol::VsChar,true); $instance->value = Rand::getString($instance->len,OAuth2Protocol::VsChar,true);
$instance->scope = $scope; $instance->scope = $scope;
$instance->client_id = $client_id; $instance->client_id = $client_id;
$instance->user_id = $user_id;
$instance->auth_code = null; $instance->auth_code = null;
$instance->audience = $audience; $instance->audience = $audience;
$instance->refresh_token = null; $instance->refresh_token = null;
@ -49,6 +51,7 @@ class AccessToken extends Token {
$instance->value = Rand::getString($instance->len,OAuth2Protocol::VsChar,true); $instance->value = Rand::getString($instance->len,OAuth2Protocol::VsChar,true);
$instance->scope = $scope; $instance->scope = $scope;
$instance->from_ip = $refresh_token->getFromIp(); $instance->from_ip = $refresh_token->getFromIp();
$instance->user_id = $refresh_token->getUserId();
$instance->client_id = $refresh_token->getClientId(); $instance->client_id = $refresh_token->getClientId();
$instance->auth_code = null; $instance->auth_code = null;
$instance->refresh_token = $refresh_token; $instance->refresh_token = $refresh_token;
@ -63,6 +66,7 @@ class AccessToken extends Token {
$instance->value = $value; $instance->value = $value;
$instance->scope = $auth_code->getScope(); $instance->scope = $auth_code->getScope();
$instance->client_id = $auth_code->getClientId(); $instance->client_id = $auth_code->getClientId();
$instance->user_id = $auth_code->getUserId();
$instance->auth_code = $auth_code->getValue(); $instance->auth_code = $auth_code->getValue();
$instance->audience = $auth_code->getAudience(); $instance->audience = $auth_code->getAudience();
$instance->from_ip = $auth_code->getFromIp(); $instance->from_ip = $auth_code->getFromIp();

View File

@ -13,35 +13,64 @@ use oauth2\OAuth2Protocol;
class AuthorizationCode extends Token { class AuthorizationCode extends Token {
private $redirect_uri; private $redirect_uri;
private $access_type;
private $approval_prompt;
private $has_previous_user_consent;
public function __construct(){ public function __construct(){
parent::__construct(64); parent::__construct(64);
} }
/** /**
* @param $user_id
* @param $client_id * @param $client_id
* @param $scope * @param $scope
* @param $redirect_uri * @param string $audience
* @param null $redirect_uri
* @param string $access_type
* @param string $approval_prompt
* @param bool $has_previous_user_consent
* @param int $lifetime * @param int $lifetime
* @return AuthorizationCode * @return AuthorizationCode
*/ */
public static function create($client_id, $scope, $audience='' ,$redirect_uri = null, $lifetime = 600){ public static function create($user_id, $client_id, $scope, $audience='' ,$redirect_uri = null,$access_type = OAuth2Protocol::OAuth2Protocol_AccessType_Online,$approval_prompt =OAuth2Protocol::OAuth2Protocol_Approval_Prompt_Auto,$has_previous_user_consent=false, $lifetime = 600){
$instance = new self(); $instance = new self();
$instance->value = Rand::getString($instance->len, OAuth2Protocol::VsChar, true); $instance->value = Rand::getString($instance->len, OAuth2Protocol::VsChar, true);
$instance->scope = $scope; $instance->scope = $scope;
$instance->user_id = $user_id;
$instance->redirect_uri = $redirect_uri; $instance->redirect_uri = $redirect_uri;
$instance->client_id = $client_id; $instance->client_id = $client_id;
$instance->lifetime = $lifetime; $instance->lifetime = $lifetime;
$instance->audience = $audience; $instance->audience = $audience;
$instance->is_hashed = false; $instance->is_hashed = false;
$instance->from_ip = IPHelper::getUserIp(); $instance->from_ip = IPHelper::getUserIp();
$instance->access_type = $access_type;
$instance->approval_prompt = $approval_prompt;
$instance->has_previous_user_consent = $has_previous_user_consent;
return $instance; return $instance;
} }
public static function load($value, $client_id, $scope,$audience='', $redirect_uri = null, $issued = null, $lifetime = 600, $from_ip = '127.0.0.1',$is_hashed = false){ /**
* @param $value
* @param $user_id
* @param $client_id
* @param $scope
* @param string $audience
* @param null $redirect_uri
* @param null $issued
* @param int $lifetime
* @param string $from_ip
* @param string $access_type
* @param string $approval_prompt
* @param bool $has_previous_user_consent
* @param bool $is_hashed
* @return AuthorizationCode
*/
public static function load($value, $user_id, $client_id, $scope,$audience='', $redirect_uri = null, $issued = null, $lifetime = 600, $from_ip = '127.0.0.1',$access_type = OAuth2Protocol::OAuth2Protocol_AccessType_Online,$approval_prompt = OAuth2Protocol::OAuth2Protocol_Approval_Prompt_Auto,$has_previous_user_consent=false,$is_hashed = false){
$instance = new self(); $instance = new self();
$instance->value = $value; $instance->value = $value;
$instance->user_id = $user_id;
$instance->scope = $scope; $instance->scope = $scope;
$instance->redirect_uri = $redirect_uri; $instance->redirect_uri = $redirect_uri;
$instance->client_id = $client_id; $instance->client_id = $client_id;
@ -50,6 +79,9 @@ class AuthorizationCode extends Token {
$instance->lifetime = $lifetime; $instance->lifetime = $lifetime;
$instance->from_ip = $from_ip; $instance->from_ip = $from_ip;
$instance->is_hashed = $is_hashed; $instance->is_hashed = $is_hashed;
$instance->access_type = $access_type;
$instance->approval_prompt = $approval_prompt;
$instance->has_previous_user_consent = $has_previous_user_consent;
return $instance; return $instance;
} }
@ -58,25 +90,25 @@ class AuthorizationCode extends Token {
return $this->redirect_uri; return $this->redirect_uri;
} }
public function getAccessType(){
return $this->access_type;
}
public function getApprovalPrompt(){
return $this->approval_prompt;
}
public function getHasPreviousUserConsent(){
return $this->has_previous_user_consent;
}
public function toJSON() public function toJSON()
{ {
$o = array( return '{}';
'value' => $this->value,
'redirect_uri' => $this->redirect_uri,
'client_id' => $this->client_id,
'scope' => $this->scope,
);
return json_encode($o);
} }
public function fromJSON($json) public function fromJSON($json)
{ {
$o = json_decode($json);
$this->value = $o->value;
$this->scope = $o->scope;
$this->client_id = $o->client_id;
$this->scope = $o->redirect_uri;
} }
} }

View File

@ -2,17 +2,24 @@
namespace oauth2\models; namespace oauth2\models;
/**
* Interface IClient
* @package oauth2\models
*/
interface IClient { interface IClient {
const ClientType_Public = 1; const ClientType_Public = 'PUBLIC';
const ClientType_Confidential = 2; const ClientType_Confidential = 'CONFIDENTIAL';
const ApplicationType_Web_App = 'WEB_APPLICATION';
const ApplicationType_JS_Client = 'JS_CLIENT';
const ApplicationType_Service = 'SERVICE';
public function getId(); public function getId();
public function getClientId(); public function getClientId();
public function getClientSecret(); public function getClientSecret();
public function getClientType(); public function getClientType();
public function getFriendlyClientType(); public function getApplicationType();
public function getClientAuthorizedRealms(); public function getClientAuthorizedRealms();
public function getClientScopes(); public function getClientScopes();
public function getClientRegisteredUris(); public function getClientRegisteredUris();
@ -28,5 +35,5 @@ interface IClient {
public function isActive(); public function isActive();
public function isResourceServerClient(); public function isResourceServerClient();
public function getResourceServer(); public function getResourceServer();
public function getFriendlyApplicationType();
} }

View File

@ -34,5 +34,5 @@ interface IOAuth2User {
* Is Server Administrator * Is Server Administrator
* @return bool * @return bool
*/ */
public function IsServerAdmin(); public function isOAuth2ServerAdmin();
} }

View File

@ -0,0 +1,12 @@
<?php
namespace oauth2\models;
/**
* Interface IUserConsent
* @package oauth2\models
*/
interface IUserConsent {
public function getScope();
public function getClient();
public function getUser();
}

View File

@ -37,6 +37,7 @@ class RefreshToken extends Token {
$instance = new self(); $instance = new self();
$instance->value = Rand::getString($instance->len,OAuth2Protocol::VsChar,true); $instance->value = Rand::getString($instance->len,OAuth2Protocol::VsChar,true);
$instance->scope = $access_token->getScope(); $instance->scope = $access_token->getScope();
$instance->user_id = $access_token->getUserId();
$instance->client_id = $access_token->getClientId(); $instance->client_id = $access_token->getClientId();
$instance->audience = $access_token->getAudience(); $instance->audience = $access_token->getAudience();
$instance->from_ip = IPHelper::getUserIp(); $instance->from_ip = IPHelper::getUserIp();
@ -50,6 +51,7 @@ class RefreshToken extends Token {
$instance->value = $params['value']; $instance->value = $params['value'];
$instance->scope = $params['scope']; $instance->scope = $params['scope'];
$instance->client_id = $params['client_id']; $instance->client_id = $params['client_id'];
$instance->user_id = $params['user_id'];
$instance->audience = $params['audience']; $instance->audience = $params['audience'];
$instance->from_ip = $params['from_ip']; $instance->from_ip = $params['from_ip'];
$instance->issued = $params['issued']; $instance->issued = $params['issued'];
@ -60,7 +62,7 @@ class RefreshToken extends Token {
public function toJSON() public function toJSON()
{ {
// TODO: Implement toJSON() method. return '{}';
} }
public function fromJSON($json) public function fromJSON($json)

View File

@ -14,6 +14,7 @@ abstract class Token
{ {
const DefaultByteLength = 32; const DefaultByteLength = 32;
protected $value; protected $value;
protected $lifetime; protected $lifetime;
protected $issued; protected $issued;
@ -23,6 +24,7 @@ abstract class Token
protected $audience; protected $audience;
protected $from_ip; protected $from_ip;
protected $is_hashed; protected $is_hashed;
protected $user_id;
public function __construct($len = self::DefaultByteLength) public function __construct($len = self::DefaultByteLength)
{ {
@ -66,6 +68,10 @@ abstract class Token
return $this->from_ip; return $this->from_ip;
} }
public function getUserId(){
return $this->user_id;
}
public function getRemainingLifetime() public function getRemainingLifetime()
{ {
//check is refresh token is stills alive... (ZERO is infinite lifetime) //check is refresh token is stills alive... (ZERO is infinite lifetime)

View File

@ -25,26 +25,81 @@ class OAuth2AuthorizationRequest extends OAuth2Request {
OAuth2Protocol::OAuth2Protocol_State => OAuth2Protocol::OAuth2Protocol_State OAuth2Protocol::OAuth2Protocol_State => OAuth2Protocol::OAuth2Protocol_State
); );
/**
* @return null|string
*/
public function getResponseType(){ public function getResponseType(){
return $this->getParam(OAuth2Protocol::OAuth2Protocol_ResponseType); return $this->getParam(OAuth2Protocol::OAuth2Protocol_ResponseType);
} }
/**
* Identifies the client that is making the request.
* The value passed in this parameter must exactly match the value shown in the Admin Console.
* @return null|string
*/
public function getClientId(){ public function getClientId(){
return $this->getParam(OAuth2Protocol::OAuth2Protocol_ClientId); return $this->getParam(OAuth2Protocol::OAuth2Protocol_ClientId);
} }
/**
* One of the redirect_uri values registered
* @return null|string
*/
public function getRedirectUri(){ public function getRedirectUri(){
return $this->getParam(OAuth2Protocol::OAuth2Protocol_RedirectUri); return $this->getParam(OAuth2Protocol::OAuth2Protocol_RedirectUri);
} }
/**
* Space-delimited set of permissions that the application requests.
* @return null|string
*/
public function getScope(){ public function getScope(){
return $this->getParam(OAuth2Protocol::OAuth2Protocol_Scope); return $this->getParam(OAuth2Protocol::OAuth2Protocol_Scope);
} }
/**
* Provides any state that might be useful to your application upon receipt of the response.
* The Authorization Server roundtrips this parameter, so your application receives the same value it sent.
* Possible uses include redirecting the user to the correct resource in your site, nonces, and
* cross-site-request-forgery mitigations.
* @return null|string
*/
public function getState(){ public function getState(){
return $this->getParam(OAuth2Protocol::OAuth2Protocol_State); return $this->getParam(OAuth2Protocol::OAuth2Protocol_State);
} }
/**
* Indicates whether the user should be re-prompted for consent. The default is auto,
* so a given user should only see the consent page for a given set of scopes the first time
* through the sequence. If the value is force, then the user sees a consent page even if they
* previously gave consent to your application for a given set of scopes.
* @return null|string
*/
public function getApprovalPrompt(){
$approval = $this->getParam(OAuth2Protocol::OAuth2Protocol_Approval_Prompt);
if(is_null($approval))
$approval = OAuth2Protocol::OAuth2Protocol_Approval_Prompt_Auto;
return $approval;
}
/**
* Indicates whether your application needs to access an API when the user is not present at the browser.
* This parameter defaults to online. If your application needs to refresh access tokens when the user is
* not present at the browser, then use offline. This will result in your application obtaining a refresh
* token the first time your application exchanges an authorization code for a user.
* @return null|string
*/
public function getAccessType(){
$access_type = $this->getParam(OAuth2Protocol::OAuth2Protocol_AccessType);
if(is_null($access_type))
$access_type = OAuth2Protocol::OAuth2Protocol_AccessType_Online;
return $access_type;
}
/**
* Validates current request
* @return bool
*/
public function isValid() public function isValid()
{ {
if(is_null($this->getResponseType())) if(is_null($this->getResponseType()))
@ -55,7 +110,11 @@ class OAuth2AuthorizationRequest extends OAuth2Request {
if(is_null($this->getRedirectUri())) if(is_null($this->getRedirectUri()))
return false; return false;
//approval_prompt
$valid_approvals = array(OAuth2Protocol::OAuth2Protocol_Approval_Prompt_Auto,OAuth2Protocol::OAuth2Protocol_Approval_Prompt_Force);
if(!in_array($this->getApprovalPrompt(),$valid_approvals)){
return false;
}
return true; return true;
} }
} }

View File

@ -6,7 +6,7 @@ use oauth2\OAuth2Protocol;
class OAuth2AccessTokenValidationResponse extends OAuth2DirectResponse { class OAuth2AccessTokenValidationResponse extends OAuth2DirectResponse {
public function __construct($access_token,$scope, $audience,$client_id,$expires_in) public function __construct($access_token,$scope, $audience,$client_id,$expires_in, $user_id = null)
{ {
// Successful Responses: A server receiving a valid request MUST send a // Successful Responses: A server receiving a valid request MUST send a
// response with an HTTP status code of 200. // response with an HTTP status code of 200.
@ -17,5 +17,8 @@ class OAuth2AccessTokenValidationResponse extends OAuth2DirectResponse {
$this[OAuth2Protocol::OAuth2Protocol_Scope] = $scope; $this[OAuth2Protocol::OAuth2Protocol_Scope] = $scope;
$this[OAuth2Protocol::OAuth2Protocol_Audience] = $audience; $this[OAuth2Protocol::OAuth2Protocol_Audience] = $audience;
$this[OAuth2Protocol::OAuth2Protocol_AccessToken_ExpiresIn] = $expires_in; $this[OAuth2Protocol::OAuth2Protocol_AccessToken_ExpiresIn] = $expires_in;
if(!is_null($user_id)){
$this[OAuth2Protocol::OAuth2Protocol_UserId] = $user_id;
}
} }
} }

View File

@ -3,7 +3,6 @@
namespace oauth2\responses; namespace oauth2\responses;
use oauth2\OAuth2Protocol; use oauth2\OAuth2Protocol;
use openid\responses\OpenIdIndirectResponse;
class OAuth2IndirectErrorResponse extends OAuth2IndirectResponse { class OAuth2IndirectErrorResponse extends OAuth2IndirectResponse {

View File

@ -20,12 +20,13 @@ interface IApiEndpointService {
public function get($id); public function get($id);
/** /**
* @param int $page_size
* @param int $page_nbr * @param int $page_nbr
* @param int $page_size
* @param array $filters * @param array $filters
* @param array $fields
* @return mixed * @return mixed
*/ */
public function getAll($page_nbr=1,$page_size=10,array $filters); public function getAll($page_nbr=1,$page_size=10,array $filters=array(),array $fields=array('*'));
/** /**

View File

@ -8,8 +8,6 @@ use oauth2\models\IApiScope;
* @package oauth2\services * @package oauth2\services
*/ */
interface IApiScopeService { interface IApiScopeService {
/** /**
* gets an api scope by id * gets an api scope by id
* @param $id id of api scope * @param $id id of api scope
@ -18,13 +16,13 @@ interface IApiScopeService {
public function get($id); public function get($id);
/** /**
* Gets a paginated list of api scopes
* @param int $page_size
* @param int $page_nbr * @param int $page_nbr
* @param int $page_size
* @param array $filters * @param array $filters
* @param array $fields
* @return mixed * @return mixed
*/ */
public function getAll($page_nbr=1,$page_size=10, array $filters); public function getAll($page_nbr=1,$page_size=10, array $filters=array(), array $fields=array('*'));
/** /**
* @param IApiScope $scope * @param IApiScope $scope
@ -95,7 +93,16 @@ interface IApiScopeService {
*/ */
public function getAudienceByScopeNames(array $scopes_names); public function getAudienceByScopeNames(array $scopes_names);
/**
* gets audience string for a given scopes sets (resource servers)
* @param array $scopes_names
* @return mixed
*/
public function getStrAudienceByScopeNames(array $scopes_names); public function getStrAudienceByScopeNames(array $scopes_names);
/**
* gets a list of default scopes
* @return mixed
*/
public function getDefaultScopes(); public function getDefaultScopes();
} }

View File

@ -58,8 +58,9 @@ interface IApiService {
* @param int $page_nbr * @param int $page_nbr
* @param int $page_size * @param int $page_size
* @param array $filters * @param array $filters
* @param array $fields
* @return mixed * @return mixed
*/ */
public function getAll($page_nbr=1,$page_size=10,array $filters); public function getAll($page_nbr=1,$page_size=10,array $filters=array(),array $fields=array('*'));
} }

View File

@ -3,7 +3,6 @@
namespace oauth2\services; namespace oauth2\services;
use oauth2\models\IClient; use oauth2\models\IClient;
/** /**
* Interface IClientService * Interface IClientService
* @package oauth2\services * @package oauth2\services
@ -32,14 +31,14 @@ interface IClientService {
/** /**
* Creates a new client * Creates a new client
* @param $client_type * @param $application_type
* @param $user_id * @param $user_id
* @param $app_name * @param $app_name
* @param $app_description * @param $app_description
* @param string $app_logo * @param string $app_logo
* @return IClient * @return IClient
*/ */
public function addClient($client_type, $user_id, $app_name, $app_description, $app_logo=''); public function addClient($application_type, $user_id, $app_name, $app_description, $app_logo='');
public function addClientScope($id,$scope_id); public function addClientScope($id,$scope_id);
public function deleteClientScope($id,$scope_id); public function deleteClientScope($id,$scope_id);
@ -74,6 +73,13 @@ interface IClientService {
*/ */
public function lockClient($client_id); public function lockClient($client_id);
/**
* unLock a client application by client id
* @param $client_id client id
* @return mixed
*/
public function unlockClient($client_id);
/** /**
* Activate/Deactivate given client * Activate/Deactivate given client
* @param $id * @param $id
@ -115,13 +121,13 @@ interface IClientService {
public function get($id); public function get($id);
/** /**
* Gets a paginated list of clients
* @param int $page_nbr * @param int $page_nbr
* @param int $page_size * @param int $page_size
* @param array $filters * @param array $filters
* @param array $fields
* @return mixed * @return mixed
*/ */
public function getAll($page_nbr=1,$page_size=10,array $filters); public function getAll($page_nbr=1,$page_size=10,array $filters=array(), array $fields=array('*'));
/** /**
* @param IClient $client * @param IClient $client
@ -136,4 +142,5 @@ interface IClientService {
* @throws \oauth2\exceptions\InvalidClientException * @throws \oauth2\exceptions\InvalidClientException
*/ */
public function update($id, array $params); public function update($id, array $params);
} }

View File

@ -22,7 +22,7 @@ interface IResourceServerService {
* @param int $page_nbr * @param int $page_nbr
* @return mixed * @return mixed
*/ */
public function getAll($page_nbr=1,$page_size=10); public function getAll($page_nbr=1,$page_size=10,array $filters = array(), array $fields=array('*'));
/** /**
* @param IResourceServer $resource_server * @param IResourceServer $resource_server

View File

@ -5,6 +5,7 @@ namespace oauth2\services;
use oauth2\models\AuthorizationCode; use oauth2\models\AuthorizationCode;
use oauth2\models\AccessToken; use oauth2\models\AccessToken;
use oauth2\models\RefreshToken; use oauth2\models\RefreshToken;
use oauth2\OAuth2Protocol;
/** /**
* Interface ITokenService * Interface ITokenService
@ -14,14 +15,19 @@ use oauth2\models\RefreshToken;
*/ */
interface ITokenService { interface ITokenService {
/** Creates a brand new authorization code /**
* Creates a brand new authorization code
* @param $user_id
* @param $client_id * @param $client_id
* @param $scope * @param $scope
* @param string $audience * @param string $audience
* @param null $redirect_uri * @param null $redirect_uri
* @return mixed * @param string $access_type
* @param string $approval_prompt
* @param bool $has_previous_user_consent
* @return AuthorizationCode
*/ */
public function createAuthorizationCode($client_id, $scope, $audience='' , $redirect_uri = null); public function createAuthorizationCode($user_id, $client_id, $scope, $audience='' , $redirect_uri = null,$access_type = OAuth2Protocol::OAuth2Protocol_AccessType_Online,$approval_prompt = OAuth2Protocol::OAuth2Protocol_Approval_Prompt_Auto, $has_previous_user_consent=false);
/** /**
@ -43,12 +49,13 @@ interface ITokenService {
/** /**
* Create a brand new Access Token by params * Create a brand new Access Token by params
* @param $scope
* @param $client_id * @param $client_id
* @param $scope
* @param $audience * @param $audience
* @return mixed * @param null $user_id
* @return AccessToken
*/ */
public function createAccessTokenFromParams($scope, $client_id, $audience); public function createAccessTokenFromParams($client_id,$scope, $audience,$user_id=null);
/** Creates a new Access Token from a given refresh token, and invalidate former associated /** Creates a new Access Token from a given refresh token, and invalidate former associated
@ -113,6 +120,9 @@ interface ITokenService {
public function getRefreshTokenByClient($client_id); public function getRefreshTokenByClient($client_id);
public function getAccessTokenByUserId($user_id);
public function getRefreshTokeByUserId($user_id);
/** /**
* Revokes a given access token * Revokes a given access token

View File

@ -0,0 +1,27 @@
<?php
namespace oauth2\services;
use oauth2\models\IUserConsent;
/**
* Interface IUserConsentService
* @package oauth2\services
*/
interface IUserConsentService {
/**
* @param $user_id
* @param $client_id
* @param $scopes
* @return IUserConsent
*/
public function get($user_id,$client_id,$scopes);
/**
* @param $user_id
* @param $client_id
* @param $scopes
* @return IUserConsent
*/
public function add($user_id,$client_id,$scopes);
}

View File

@ -11,4 +11,5 @@ class OAuth2ServiceCatalog {
const ResourceServerService = 'oauth2\\services\\IResourceServerService'; const ResourceServerService = 'oauth2\\services\\IResourceServerService';
const ApiService = 'oauth2\\services\\IApiService'; const ApiService = 'oauth2\\services\\IApiService';
const ApiEndpointService = 'oauth2\\services\\IApiEndpointService'; const ApiEndpointService = 'oauth2\\services\\IApiEndpointService';
const UserConsentService = 'oauth2\\services\\IUserConsentService';
} }

View File

@ -15,7 +15,8 @@ class OAuth2IndirectErrorResponseFactoryMethod {
* @param OAuth2Request $request * @param OAuth2Request $request
* @param $error * @param $error
* @param $return_url * @param $return_url
* @return OAuth2IndirectResponse * @return null|OAuth2IndirectErrorResponse|OAuth2IndirectFragmentErrorResponse
* @throws Exception
*/ */
public static function buildResponse(OAuth2Request $request = null,$error, $return_url){ public static function buildResponse(OAuth2Request $request = null,$error, $return_url){
$response = null; $response = null;

View File

@ -16,6 +16,8 @@ interface IOpenIdProtocol
* With OpenID 2.0, the relying party discovers the OpenID provider URL by requesting * With OpenID 2.0, the relying party discovers the OpenID provider URL by requesting
* the XRDS document (also called the Yadis document) with the content type application/xrds+xml; * the XRDS document (also called the Yadis document) with the content type application/xrds+xml;
* this document may be available at the target URL and is always available for a target XRI. * this document may be available at the target URL and is always available for a target XRI.
* @param $mode
* @param null $canonical_id
* @return mixed * @return mixed
*/ */
public function getXRDSDiscovery($mode, $canonical_id = null); public function getXRDSDiscovery($mode, $canonical_id = null);

View File

@ -13,7 +13,6 @@ use openid\requests\contexts\RequestContext;
use openid\requests\OpenIdRequest; use openid\requests\OpenIdRequest;
use openid\responses\contexts\ResponseContext; use openid\responses\contexts\ResponseContext;
use openid\responses\OpenIdResponse; use openid\responses\OpenIdResponse;
use openid\services\OpenIdServiceCatalog;
use utils\services\Registry; use utils\services\Registry;
use utils\services\UtilsServiceCatalog; use utils\services\UtilsServiceCatalog;

View File

@ -47,6 +47,12 @@ class OpenIdOAuth2Extension extends OpenIdExtension
private $client_service; private $client_service;
private $scope_service; private $scope_service;
/**
* @param $name
* @param $namespace
* @param $view
* @param $description
*/
public function __construct($name, $namespace, $view, $description) public function __construct($name, $namespace, $view, $description)
{ {
parent::__construct($name, $namespace, $view, $description); parent::__construct($name, $namespace, $view, $description);
@ -57,36 +63,63 @@ class OpenIdOAuth2Extension extends OpenIdExtension
$this->scope_service = Registry::getInstance()->get(OAuth2ServiceCatalog::ScopeService); $this->scope_service = Registry::getInstance()->get(OAuth2ServiceCatalog::ScopeService);
} }
/**
* @param $param
* @param string $separator
* @return string
*/
public static function param($param, $separator = '.') public static function param($param, $separator = '.')
{ {
return OpenIdProtocol::OpenIdPrefix . $separator . self::Prefix . $separator . $param; return OpenIdProtocol::OpenIdPrefix . $separator . self::Prefix . $separator . $param;
} }
/**
* @param string $separator
* @return string
*/
public static function paramNamespace($separator = '.') public static function paramNamespace($separator = '.')
{ {
return OpenIdProtocol::OpenIdPrefix . $separator . OpenIdProtocol::OpenIDProtocol_NS . $separator . self::Prefix; return OpenIdProtocol::OpenIdPrefix . $separator . OpenIdProtocol::OpenIDProtocol_NS . $separator . self::Prefix;
} }
/**
* @param OpenIdRequest $request
* @param RequestContext $context
* @return mixed|void
*/
public function parseRequest(OpenIdRequest $request, RequestContext $context) public function parseRequest(OpenIdRequest $request, RequestContext $context)
{ {
try { try {
$oauth2_request = new OpenIdOAuth2Request($request->getMessage()); $oauth2_request = new OpenIdOAuth2Request($request->getMessage());
if (!$oauth2_request->isValid()) return; if (!$oauth2_request->isValid()){
$this->log_service->warning_msg('OpenIdOAuth2Extension: Invalid OAuth2 Request');
return;
}
$scopes = $oauth2_request->getScope(); $scopes = $oauth2_request->getScope();
$client_id = $oauth2_request->getClientId(); $client_id = $oauth2_request->getClientId();
$client = $this->client_service->getClientById($client_id); $client = $this->client_service->getClientById($client_id);
// do some validations to allow show the oauth2 sub view... // do some validations to allow show the oauth2 sub view...
if(is_null($client)) return; if(is_null($client)){
$this->log_service->warning_msg(sprintf("OpenIdOAuth2Extension: client id %s not found!.",$client_id));
return;
}
//check is redirect uri is allowed for client //check is redirect uri is allowed for client
$redirect_uri = $request->getParam(OpenIdProtocol::OpenIDProtocol_ReturnTo); $redirect_uri = $request->getParam(OpenIdProtocol::OpenIDProtocol_ReturnTo);
if (!$client->isUriAllowed($redirect_uri)) return; if (!$client->isUriAllowed($redirect_uri)){
$this->log_service->warning_msg(sprintf("OpenIdOAuth2Extension: url %s not allowed for client id %s ",$redirect_uri,$client_id));
return;
}
//check if requested client is allowed to use this scopes //check if requested client is allowed to use this scopes
if(!$client->isScopeAllowed($scopes)) return; if(!$client->isScopeAllowed($scopes)){
$this->log_service->warning_msg(sprintf("OpenIdOAuth2Extension: scope %s not allowed for client id %s ",$scopes,$client_id));
return;
}
$scopes = explode(' ', $scopes); $scopes = explode(' ', $scopes);
//get scopes entities //get scopes entities
@ -112,6 +145,12 @@ class OpenIdOAuth2Extension extends OpenIdExtension
} }
} }
/**
* @param OpenIdRequest $request
* @param OpenIdResponse $response
* @param ResponseContext $context
* @return mixed|void
*/
public function prepareResponse(OpenIdRequest $request, OpenIdResponse $response, ResponseContext $context) public function prepareResponse(OpenIdRequest $request, OpenIdResponse $response, ResponseContext $context)
{ {
try{ try{
@ -120,11 +159,13 @@ class OpenIdOAuth2Extension extends OpenIdExtension
//get auth code //get auth code
$oauth2_msg = new OAuth2Message( $oauth2_msg = new OAuth2Message(
array( array(
OAuth2Protocol::OAuth2Protocol_ClientId => $oauth2_request->getClientId(), OAuth2Protocol::OAuth2Protocol_ClientId => $oauth2_request->getClientId(),
OAuth2Protocol::OAuth2Protocol_Scope => $oauth2_request->getScope(), OAuth2Protocol::OAuth2Protocol_Scope => $oauth2_request->getScope(),
OAuth2Protocol::OAuth2Protocol_RedirectUri => $request->getParam(OpenIdProtocol::OpenIDProtocol_ReturnTo), OAuth2Protocol::OAuth2Protocol_RedirectUri => $request->getParam(OpenIdProtocol::OpenIDProtocol_ReturnTo),
OAuth2Protocol::OAuth2Protocol_State => $oauth2_request->getState(), OAuth2Protocol::OAuth2Protocol_State => $oauth2_request->getState(),
OAuth2Protocol::OAuth2Protocol_ResponseType => OAuth2Protocol::OAuth2Protocol_ResponseType_Code OAuth2Protocol::OAuth2Protocol_Approval_Prompt => $oauth2_request->getApprovalPrompt(),
OAuth2Protocol::OAuth2Protocol_AccessType => $oauth2_request->getAccessType(),
OAuth2Protocol::OAuth2Protocol_ResponseType => OAuth2Protocol::OAuth2Protocol_ResponseType_Code
) )
); );
// do oauth2 Authorization Code Grant 1st step (get auth code to exchange for an access token) // do oauth2 Authorization Code Grant 1st step (get auth code to exchange for an access token)
@ -163,6 +204,10 @@ class OpenIdOAuth2Extension extends OpenIdExtension
} }
} }
/**
* @param OpenIdRequest $request
* @return array|mixed
*/
public function getTrustedData(OpenIdRequest $request) public function getTrustedData(OpenIdRequest $request)
{ {
$data = array(); $data = array();

View File

@ -8,13 +8,24 @@ use openid\OpenIdMessage;
use openid\requests\OpenIdRequest; use openid\requests\OpenIdRequest;
use oauth2\OAuth2Protocol; use oauth2\OAuth2Protocol;
/**
* Class OpenIdOAuth2Request
* @package openid\extensions\implementations
*/
class OpenIdOAuth2Request extends OpenIdRequest { class OpenIdOAuth2Request extends OpenIdRequest {
/**
* @param OpenIdMessage $message
*/
public function __construct(OpenIdMessage $message) public function __construct(OpenIdMessage $message)
{ {
parent::__construct($message); parent::__construct($message);
} }
/**
* @return bool
* @throws \openid\exceptions\InvalidOpenIdMessageException
*/
public function isValid() public function isValid()
{ {
//check identifier //check identifier
@ -33,16 +44,49 @@ class OpenIdOAuth2Request extends OpenIdRequest {
return false; return false;
} }
/**
* Indicates whether the user should be re-prompted for consent. The default is auto,
* so a given user should only see the consent page for a given set of scopes the first time
* through the sequence. If the value is force, then the user sees a consent page even if they
* previously gave consent to your application for a given set of scopes.
* @return null|string
*/
public function getApprovalPrompt(){
return isset($this->message[OpenIdOAuth2Extension::param(OAuth2Protocol::OAuth2Protocol_Approval_Prompt, '_')])?
$this->message[OpenIdOAuth2Extension::param(OAuth2Protocol::OAuth2Protocol_Approval_Prompt, '_')]:OAuth2Protocol::OAuth2Protocol_Approval_Prompt_Auto;
}
/**
* Indicates whether your application needs to access an API when the user is not present at the browser.
* This parameter defaults to online. If your application needs to refresh access tokens when the user is
* not present at the browser, then use offline. This will result in your application obtaining a refresh
* token the first time your application exchanges an authorization code for a user.
* @return null|string
*/
public function getAccessType(){
return isset($this->message[OpenIdOAuth2Extension::param(OAuth2Protocol::OAuth2Protocol_AccessType, '_')])?
$this->message[OpenIdOAuth2Extension::param(OAuth2Protocol::OAuth2Protocol_AccessType, '_')]:OAuth2Protocol::OAuth2Protocol_AccessType_Online;
}
/**
* @return null|string
*/
public function getClientId(){ public function getClientId(){
return isset($this->message[OpenIdOAuth2Extension::param(OAuth2Protocol::OAuth2Protocol_ClientId, '_')])? return isset($this->message[OpenIdOAuth2Extension::param(OAuth2Protocol::OAuth2Protocol_ClientId, '_')])?
$this->message[OpenIdOAuth2Extension::param(OAuth2Protocol::OAuth2Protocol_ClientId, '_')]:null; $this->message[OpenIdOAuth2Extension::param(OAuth2Protocol::OAuth2Protocol_ClientId, '_')]:null;
} }
/**
* @return null|string
*/
public function getScope(){ public function getScope(){
return isset($this->message[OpenIdOAuth2Extension::param(OAuth2Protocol::OAuth2Protocol_Scope, '_')])? return isset($this->message[OpenIdOAuth2Extension::param(OAuth2Protocol::OAuth2Protocol_Scope, '_')])?
$this->message[OpenIdOAuth2Extension::param(OAuth2Protocol::OAuth2Protocol_Scope, '_')]:null; $this->message[OpenIdOAuth2Extension::param(OAuth2Protocol::OAuth2Protocol_Scope, '_')]:null;
} }
/**
* @return null|string
*/
public function getState(){ public function getState(){
return isset($this->message[OpenIdOAuth2Extension::param(OAuth2Protocol::OAuth2Protocol_State, '_')])? return isset($this->message[OpenIdOAuth2Extension::param(OAuth2Protocol::OAuth2Protocol_State, '_')])?
$this->message[OpenIdOAuth2Extension::param(OAuth2Protocol::OAuth2Protocol_State, '_')]:null; $this->message[OpenIdOAuth2Extension::param(OAuth2Protocol::OAuth2Protocol_State, '_')]:null;

View File

@ -9,7 +9,6 @@ use openid\requests\contexts\RequestContext;
use openid\requests\OpenIdRequest; use openid\requests\OpenIdRequest;
use openid\responses\contexts\ResponseContext; use openid\responses\contexts\ResponseContext;
use openid\responses\OpenIdResponse; use openid\responses\OpenIdResponse;
use openid\services\OpenIdServiceCatalog;
use utils\services\Registry; use utils\services\Registry;
use utils\services\UtilsServiceCatalog; use utils\services\UtilsServiceCatalog;
use Exception; use Exception;

View File

@ -11,7 +11,6 @@ namespace openid\extensions\implementations;
use Exception; use Exception;
use openid\OpenIdMessage; use openid\OpenIdMessage;
use openid\requests\OpenIdRequest; use openid\requests\OpenIdRequest;
use openid\services\OpenIdServiceCatalog;
use utils\services\Registry; use utils\services\Registry;
use utils\services\UtilsServiceCatalog; use utils\services\UtilsServiceCatalog;

View File

@ -20,8 +20,8 @@ class SessionAssociationRequestFactory
} }
/** /**
* @param OpenIdAssociationSessionRequest $message * @param OpenIdMessage $message
* @return null|ISessionAssociationStrategy * @return null|SessionAssociationDHStrategy|SessionAssociationUnencryptedStrategy
*/ */
public static function buildSessionAssociationStrategy(OpenIdMessage $message) public static function buildSessionAssociationStrategy(OpenIdMessage $message)
{ {

View File

@ -323,6 +323,7 @@ class OpenIdUriHelper
* *
* @static * @static
* @param string $trust_root The trust root to check * @param string $trust_root The trust root to check
* @throws \openid\exceptions\InvalidTLDException
* @return bool $sanity Whether the trust root looks OK * @return bool $sanity Whether the trust root looks OK
*/ */
private static function _isSane($trust_root) private static function _isSane($trust_root)

View File

@ -1,8 +1,21 @@
<?php <?php
namespace openid\model; namespace openid\model;
/**
* Interface IOpenIdUser
* @package openid\model
*/
interface IOpenIdUser { interface IOpenIdUser {
/**
*
*/
const OpenstackIdServerAdminGroup = 'openstackid-server-admin';
/**
* @return bool
*/
public function isOpenstackIdAdmin();
public function getId(); public function getId();
public function getIdentifier(); public function getIdentifier();
public function getEmail(); public function getEmail();

View File

@ -17,6 +17,7 @@ class OpenIdNonce
/** /**
* @param $nonce_str * @param $nonce_str
* @throws InvalidNonce
*/ */
public function __construct($nonce_str) public function __construct($nonce_str)
{ {

View File

@ -9,11 +9,12 @@ use openid\OpenIdProtocol;
use openid\services\OpenIdServiceCatalog; use openid\services\OpenIdServiceCatalog;
use utils\services\Registry; use utils\services\Registry;
use Exception; use Exception;
use utils\services\UtilsServiceCatalog;
class OpenIdAuthenticationRequest extends OpenIdRequest class OpenIdAuthenticationRequest extends OpenIdRequest
{ {
public function __construct(OpenIdMessage $message) public function __construct(OpenIdMessage $message)
{ {
parent::__construct($message); parent::__construct($message);
@ -33,6 +34,7 @@ class OpenIdAuthenticationRequest extends OpenIdRequest
public function isValid() public function isValid()
{ {
$res = true;
try{ try{
$return_to = $this->getReturnTo(); $return_to = $this->getReturnTo();
$claimed_id = $this->getClaimedId(); $claimed_id = $this->getClaimedId();
@ -42,19 +44,29 @@ class OpenIdAuthenticationRequest extends OpenIdRequest
$valid_realm = OpenIdUriHelper::checkRealm($realm, $return_to); $valid_realm = OpenIdUriHelper::checkRealm($realm, $return_to);
$valid_id = $this->isValidIdentifier($claimed_id, $identity); $valid_id = $this->isValidIdentifier($claimed_id, $identity);
return !empty($return_to) $res = !empty($return_to)
&& !empty($realm) && !empty($realm)
&& $valid_realm && $valid_realm
&& !empty($claimed_id) && !empty($claimed_id)
&& !empty($identity) && !empty($identity)
&& $valid_id && $valid_id
&& !empty($mode) && ($mode == OpenIdProtocol::ImmediateMode || $mode == OpenIdProtocol::SetupMode); && !empty($mode) && ($mode == OpenIdProtocol::ImmediateMode || $mode == OpenIdProtocol::SetupMode);
if(!$res){
$msg = sprintf("return_to is empty? %b.",empty($return_to)).PHP_EOL;
$msg = $msg.sprintf("realm is empty? %b.",empty($realm)).PHP_EOL;
$msg = $msg.sprintf("claimed_id is empty? %b.",empty($claimed_id)).PHP_EOL;
$msg = $msg.sprintf("identity is empty? %b.",empty($identity)).PHP_EOL;
$msg = $msg.sprintf("mode is empty? %b.",empty($mode)).PHP_EOL;
$msg = $msg.sprintf("is valid realm? %b.",$valid_realm).PHP_EOL;
$msg = $msg.sprintf("is valid identifier? %b.",$valid_id).PHP_EOL;
$this->log_service->warning_msg($msg);
}
} }
catch(Exception $ex){ catch(Exception $ex){
$log = Registry::getInstance()->get(UtilsServiceCatalog::LogService); $this->log_service->error($ex);
$log->error($ex); $res = false;
return false;
} }
return $res;
} }
public function getReturnTo() public function getReturnTo()

View File

@ -3,15 +3,19 @@
namespace openid\requests; namespace openid\requests;
use openid\OpenIdMessage; use openid\OpenIdMessage;
use utils\services\Registry;
use utils\services\UtilsServiceCatalog;
abstract class OpenIdRequest abstract class OpenIdRequest
{ {
protected $message; protected $message;
protected $log_service;
public function __construct(OpenIdMessage $message) public function __construct(OpenIdMessage $message)
{ {
$this->message = $message; $this->message = $message;
$this->log_service = Registry::getInstance()->get(UtilsServiceCatalog::LogService);
} }
public function getMessage() public function getMessage()

View File

@ -23,9 +23,9 @@ interface INonceService
* To prevent replay attacks, the OP MUST NOT issue more than one verification response * To prevent replay attacks, the OP MUST NOT issue more than one verification response
* for each authentication response it had previously issued. An authentication response * for each authentication response it had previously issued. An authentication response
* and its matching verification request may be identified by their "openid.response_nonce" values. * and its matching verification request may be identified by their "openid.response_nonce" values.
* @param $nonce * @param OpenIdNonce $nonce
* @param $signature * @param $signature
* @throws ReplayAttackException * @param $realm
* @return mixed * @return mixed
*/ */
public function markNonceAsInvalid(OpenIdNonce $nonce, $signature, $realm); public function markNonceAsInvalid(OpenIdNonce $nonce, $signature, $realm);

View File

@ -13,11 +13,9 @@ interface IServerConfigurationService
public function getOPEndpointURL(); public function getOPEndpointURL();
/** /**
* * @param $identifier
* @return mixed * @return mixed
*/ */
public function getUserIdentityEndpointURL($identifier); public function getUserIdentityEndpointURL($identifier);
} }

View File

@ -13,8 +13,9 @@ interface ITrustedSitesService
/** /**
* @param IOpenIdUser $user * @param IOpenIdUser $user
* @param $return_to * @param $realm
* @return \array * @param array $data
* @return mixed
*/ */
public function getTrustedSites(IOpenIdUser $user, $realm, $data = array()); public function getTrustedSites(IOpenIdUser $user, $realm, $data = array());

View File

@ -2,23 +2,71 @@
namespace openid\services; namespace openid\services;
/**
* Interface IUserService
* @package openid\services
*/
interface IUserService interface IUserService
{ {
/**
* @param $id
* @param $proposed_username
* @return mixed
*/
public function associateUser($id, $proposed_username); public function associateUser($id, $proposed_username);
/**
* @param $identifier
* @return mixed
*/
public function updateLastLoginDate($identifier); public function updateLastLoginDate($identifier);
/**
* @param $identifier
* @return mixed
*/
public function updateFailedLoginAttempts($identifier); public function updateFailedLoginAttempts($identifier);
/**
* @param $identifier
* @return mixed
*/
public function lockUser($identifier); public function lockUser($identifier);
/**
* @param $identifier
* @return mixed
*/
public function unlockUser($identifier); public function unlockUser($identifier);
/**
* @param $identifier
* @return mixed
*/
public function activateUser($identifier); public function activateUser($identifier);
/**
* @param $identifier
* @return mixed
*/
public function deActivateUser($identifier); public function deActivateUser($identifier);
/**
* @param $identifier
* @param $show_pic
* @param $show_full_name
* @param $show_email
* @return mixed
*/
public function saveProfileInfo($identifier, $show_pic, $show_full_name, $show_email); public function saveProfileInfo($identifier, $show_pic, $show_full_name, $show_email);
/**
* @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('*'));
} }

View File

@ -1,8 +1,19 @@
<?php <?php
namespace utils\model;
use Eloquent;
/**
* Class BaseModelEloquent
* @package utils\model
*/
abstract class BaseModelEloquent extends Eloquent { abstract class BaseModelEloquent extends Eloquent {
/**
* @param $query
* @param array $filters
* @return mixed
*/
public function scopeFilter($query, array $filters){ public function scopeFilter($query, array $filters){
foreach($filters as $filter){ foreach($filters as $filter){
$query = $query->where($filter['name'],$filter['op'], $filter['value']); $query = $query->where($filter['name'],$filter['op'], $filter['value']);

View File

@ -0,0 +1,16 @@
<?php
namespace utils\services;
/**
* Interface IBannedIPService
* @package utils\services
*/
interface IBannedIPService {
public function add($initial_hits, $exception_type);
public function delete($ip);
public function get($id);
public function getByIP($ip);
public function getByPage($page_nbr=1,$page_size=10,array $filters=array(),array $fields=array('*'));
}

View File

@ -10,4 +10,8 @@ interface IServerConfigurationService {
* @return mixed * @return mixed
*/ */
public function getConfigValue($key); public function getConfigValue($key);
public function getAllConfigValues();
public function saveConfigValue($key,$value);
} }

View File

@ -10,4 +10,5 @@ class UtilsServiceCatalog {
const LockManagerService = 'utils\\services\\ILockManagerService'; const LockManagerService = 'utils\\services\\ILockManagerService';
const ServerConfigurationService = 'utils\\services\\IServerConfigurationService'; const ServerConfigurationService = 'utils\\services\\IServerConfigurationService';
const CacheService = 'utils\\services\\ICacheService'; const CacheService = 'utils\\services\\ICacheService';
const BannedIpService = 'utils\\services\\IBannedIPService';
} }

View File

@ -1,6 +1,12 @@
<?php <?php
use utils\model\BaseModelEloquent;
class BannedIP extends Eloquent class BannedIP extends BaseModelEloquent
{ {
protected $table = 'banned_ips'; protected $table = 'banned_ips';
public function user()
{
return $this->belongsTo('auth\User');
}
} }

View File

@ -1,11 +1,12 @@
<?php <?php
use auth\AuthHelper; use auth\AuthHelper;
use utils\model\BaseModelEloquent;
/** /**
* Class Member * Class Member
*/ */
class Member extends Eloquent class Member extends BaseModelEloquent
{ {
protected $primaryKey ='ID'; protected $primaryKey ='ID';

View File

@ -1,6 +1,8 @@
<?php <?php
class MemberPhoto extends Eloquent use utils\model\BaseModelEloquent;
class MemberPhoto extends BaseModelEloquent
{ {
protected $table = 'File'; protected $table = 'File';
//external os members db (SS) //external os members db (SS)

Some files were not shown because too many files have changed in this diff Show More