OIDC - OpenId Connect Implementation

DB refactoring
Client Admin Rectoring
upgraded layout to use latest bootstrap
Added bower support
Added Behat support
OIDC Discovery suuport added
OIDC JWKS endpoint added
Refactored OpenId workflows
Refactored OAuth2 workflows
Server Keys Admin Added
Authorization Code Flow refactored to support OIDC
Allow native apps to use auth code grant
Allow native apps to use "TokenEndpoint_AuthMethod_PrivateKeyJwt"
Filter on UI public/private keys algs based on the key usage
Set as default auth protocol for private clients "client_secret_basic"
Added feature client_secret_expired
Filtered content of Token Endpoint Authorization Signed Algorithm based on Token Endpoint Authorization Method
Implemented OAuth 2.0 Multiple Response Type Encoding Practices
Implemented OAuth 2.0 Form Post Response Mode
Implicit Flow refactored to support OIDC
UserInfo Endpoint (OIDC/Claims)
Hybrid Flow
OIDC Session Management

Change-Id: If3d38666f3f7f56bd8c94b9df2e6340554512612
This commit is contained in:
Sebastian Marcet 2015-07-03 17:43:14 -03:00
parent 1ee300d9bb
commit ea98eff8cf
430 changed files with 26305 additions and 42535 deletions

4
.bowerrc Normal file
View File

@ -0,0 +1,4 @@
{
"directory": "public/bower_assets",
"interactive": false
}

2
.gitignore vendored
View File

@ -21,3 +21,5 @@ ChangeLog
doc/build
*.egg
*.egg-info
public/bower_assets
public/bower_assets/*

View File

@ -26,7 +26,7 @@ return array(
|
*/
'url' => 'http://localhost',
'url' => '',
/*
|--------------------------------------------------------------------------
@ -65,7 +65,7 @@ return array(
|
*/
'key' => '2mikPhsqqnw9qfEtp3XxHmtkZqoTTvWl',
'key' => '',
/*
|--------------------------------------------------------------------------

View File

@ -1,124 +0,0 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Mail Driver
|--------------------------------------------------------------------------
|
| Laravel supports both SMTP and PHP's "mail" function as drivers for the
| sending of e-mail. You may specify which one you're using throughout
| your application here. By default, Laravel is setup for SMTP mail.
|
| Supported: "smtp", "mail", "sendmail"
|
*/
'driver' => 'mail',
/*
|--------------------------------------------------------------------------
| SMTP Host Address
|--------------------------------------------------------------------------
|
| Here you may provide the host address of the SMTP server used by your
| applications. A default option is provided that is compatible with
| the Postmark mail service, which will provide reliable delivery.
|
*/
'host' => 'smtp.mailgun.org',
/*
|--------------------------------------------------------------------------
| SMTP Host Port
|--------------------------------------------------------------------------
|
| This is the SMTP port used by your application to delivery e-mails to
| users of your application. Like the host we have set this value to
| stay compatible with the Postmark e-mail application by default.
|
*/
'port' => 587,
/*
|--------------------------------------------------------------------------
| Global "From" Address
|--------------------------------------------------------------------------
|
| You may wish for all e-mails sent by your application to be sent from
| the same address. Here, you may specify a name and address that is
| used globally for all e-mails that are sent by your application.
|
*/
'from' => array('address' => null, 'name' => null),
/*
|--------------------------------------------------------------------------
| E-Mail Encryption Protocol
|--------------------------------------------------------------------------
|
| Here you may specify the encryption protocol that should be used when
| the application send e-mail messages. A sensible default using the
| transport layer security protocol should provide great security.
|
*/
'encryption' => 'tls',
/*
|--------------------------------------------------------------------------
| SMTP Server Username
|--------------------------------------------------------------------------
|
| If your SMTP server requires a username for authentication, you should
| set it here. This will get used to authenticate with your server on
| connection. You may also set the "password" value below this one.
|
*/
'username' => null,
/*
|--------------------------------------------------------------------------
| SMTP Server Password
|--------------------------------------------------------------------------
|
| Here you may set the password required by your SMTP server to send out
| messages from your application. This will be given to the server on
| connection so that the application will be able to send messages.
|
*/
'password' => null,
/*
|--------------------------------------------------------------------------
| Sendmail System Path
|--------------------------------------------------------------------------
|
| When using the "sendmail" driver to send e-mails, we will need to know
| the path to where Sendmail lives on this server. A default path has
| been provided here, which will work well on most of your systems.
|
*/
'sendmail' => '/usr/sbin/sendmail -bs',
/*
|--------------------------------------------------------------------------
| Mail "Pretend"
|--------------------------------------------------------------------------
|
| When this option is enabled, e-mail will not actually be sent over the
| web and will instead be written to your application's logs files so
| you may inspect the message. This is great for local development.
|
*/
'pretend' => true,
);

View File

@ -1,187 +0,0 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Application Debug Mode
|--------------------------------------------------------------------------
|
| When your application is in debug mode, detailed error messages with
| stack traces will be shown on every error that occurs within your
| application. If disabled, a simple generic error page is shown.
|
*/
'debug' => true,
/*
|--------------------------------------------------------------------------
| Application URL
|--------------------------------------------------------------------------
|
| This URL is used by the console to properly generate URLs when using
| the Artisan command line tool. You should set this to the root of
| your application so that it is used when running Artisan tasks.
|
*/
'url' => 'https://local.openstackid.openstack.org',
/*
|--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
| Here you may specify the default timezone for your application, which
| will be used by the PHP date and date-time functions. We have gone
| ahead and set this to a sensible default for you out of the box.
|
*/
'timezone' => 'UTC',
/*
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
'locale' => 'en',
/*
|--------------------------------------------------------------------------
| Encryption Key
|--------------------------------------------------------------------------
|
| This key is used by the Illuminate encrypter service and should be set
| to a random, 32 character string, otherwise these encrypted strings
| will not be safe. Please do this before deploying an application!
|
*/
'key' => '2mikPhsqqnw9qfEtp3XxHmtkZqoTTvWl',
/*
|--------------------------------------------------------------------------
| Autoloaded Service Providers
|--------------------------------------------------------------------------
|
| The service providers listed here will be automatically loaded on the
| request to your application. Feel free to add your own services to
| this array to grant expanded functionality to your applications.
|
*/
'providers' => array(
'Illuminate\Foundation\Providers\ArtisanServiceProvider',
'Illuminate\Auth\AuthServiceProvider',
'Illuminate\Cache\CacheServiceProvider',
'Illuminate\Session\CommandsServiceProvider',
'Illuminate\Foundation\Providers\ConsoleSupportServiceProvider',
'Illuminate\Routing\ControllerServiceProvider',
'Illuminate\Cookie\CookieServiceProvider',
'Illuminate\Database\DatabaseServiceProvider',
'Illuminate\Encryption\EncryptionServiceProvider',
'Illuminate\Filesystem\FilesystemServiceProvider',
'Illuminate\Hashing\HashServiceProvider',
'Illuminate\Html\HtmlServiceProvider',
'Illuminate\Log\LogServiceProvider',
'Illuminate\Mail\MailServiceProvider',
'Illuminate\Database\MigrationServiceProvider',
'Illuminate\Pagination\PaginationServiceProvider',
'Illuminate\Queue\QueueServiceProvider',
'Illuminate\Remote\RemoteServiceProvider',
'Illuminate\Auth\Reminders\ReminderServiceProvider',
'Illuminate\Database\SeedServiceProvider',
'Illuminate\Session\SessionServiceProvider',
'Illuminate\Translation\TranslationServiceProvider',
'Illuminate\Validation\ValidationServiceProvider',
'Illuminate\View\ViewServiceProvider',
'Illuminate\Workbench\WorkbenchServiceProvider',
'Illuminate\Redis\RedisServiceProvider',
'services\utils\UtilsProvider',
'repositories\RepositoriesProvider',
'services\oauth2\OAuth2ServiceProvider',
'services\openid\OpenIdProvider',
'auth\AuthenticationServiceProvider',
'services\ServicesProvider',
'strategies\StrategyProvider',
'oauth2\OAuth2ServiceProvider',
'openid\OpenIdServiceProvider',
'Greggilbert\Recaptcha\RecaptchaServiceProvider',
'services\oauth2\CORS\CORSProvider',
),
/*
|--------------------------------------------------------------------------
| Service Provider Manifest
|--------------------------------------------------------------------------
|
| The service provider manifest is used by Laravel to lazy load service
| providers which are not needed for each request, as well to keep a
| list of all of the services. Here, you may set its storage spot.
|
*/
'manifest' => storage_path().'/meta',
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| This array of class aliases will be registered when this application
| is started. However, feel free to register as many as you wish as
| the aliases are "lazy" loaded so they don't hinder performance.
|
*/
'aliases' => array(
'App' => 'Illuminate\Support\Facades\App',
'Artisan' => 'Illuminate\Support\Facades\Artisan',
'Auth' => 'Illuminate\Support\Facades\Auth',
'Blade' => 'Illuminate\Support\Facades\Blade',
'Cache' => 'Illuminate\Support\Facades\Cache',
'ClassLoader' => 'Illuminate\Support\ClassLoader',
'Config' => 'Illuminate\Support\Facades\Config',
'Controller' => 'Illuminate\Routing\Controller',
'Cookie' => 'Illuminate\Support\Facades\Cookie',
'Crypt' => 'Illuminate\Support\Facades\Crypt',
'DB' => 'Illuminate\Support\Facades\DB',
'Eloquent' => 'Illuminate\Database\Eloquent\Model',
'Event' => 'Illuminate\Support\Facades\Event',
'File' => 'Illuminate\Support\Facades\File',
'Form' => 'Illuminate\Support\Facades\Form',
'Hash' => 'Illuminate\Support\Facades\Hash',
'HTML' => 'Illuminate\Support\Facades\HTML',
'Input' => 'Illuminate\Support\Facades\Input',
'Lang' => 'Illuminate\Support\Facades\Lang',
'Log' => 'Illuminate\Support\Facades\Log',
'Mail' => 'Illuminate\Support\Facades\Mail',
'Paginator' => 'Illuminate\Support\Facades\Paginator',
'Password' => 'Illuminate\Support\Facades\Password',
'Queue' => 'Illuminate\Support\Facades\Queue',
'Redirect' => 'Illuminate\Support\Facades\Redirect',
'Request' => 'Illuminate\Support\Facades\Request',
'Response' => 'Illuminate\Support\Facades\Response',
'Route' => 'Illuminate\Support\Facades\Route',
'Schema' => 'Illuminate\Support\Facades\Schema',
'Seeder' => 'Illuminate\Database\Seeder',
'Session' => 'Illuminate\Support\Facades\Session',
'SSH' => 'Illuminate\Support\Facades\SSH',
'Str' => 'Illuminate\Support\Str',
'URL' => 'Illuminate\Support\Facades\URL',
'Validator' => 'Illuminate\Support\Facades\Validator',
'View' => 'Illuminate\Support\Facades\View',
'RedisLV4' => 'Illuminate\Support\Facades\Redis',
),
);

View File

@ -1,124 +0,0 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Mail Driver
|--------------------------------------------------------------------------
|
| Laravel supports both SMTP and PHP's "mail" function as drivers for the
| sending of e-mail. You may specify which one you're using throughout
| your application here. By default, Laravel is setup for SMTP mail.
|
| Supported: "smtp", "mail", "sendmail"
|
*/
'driver' => 'mail',
/*
|--------------------------------------------------------------------------
| SMTP Host Address
|--------------------------------------------------------------------------
|
| Here you may provide the host address of the SMTP server used by your
| applications. A default option is provided that is compatible with
| the Postmark mail service, which will provide reliable delivery.
|
*/
'host' => 'smtp.mailgun.org',
/*
|--------------------------------------------------------------------------
| SMTP Host Port
|--------------------------------------------------------------------------
|
| This is the SMTP port used by your application to delivery e-mails to
| users of your application. Like the host we have set this value to
| stay compatible with the Postmark e-mail application by default.
|
*/
'port' => 587,
/*
|--------------------------------------------------------------------------
| Global "From" Address
|--------------------------------------------------------------------------
|
| You may wish for all e-mails sent by your application to be sent from
| the same address. Here, you may specify a name and address that is
| used globally for all e-mails that are sent by your application.
|
*/
'from' => array('address' => null, 'name' => null),
/*
|--------------------------------------------------------------------------
| E-Mail Encryption Protocol
|--------------------------------------------------------------------------
|
| Here you may specify the encryption protocol that should be used when
| the application send e-mail messages. A sensible default using the
| transport layer security protocol should provide great security.
|
*/
'encryption' => 'tls',
/*
|--------------------------------------------------------------------------
| SMTP Server Username
|--------------------------------------------------------------------------
|
| If your SMTP server requires a username for authentication, you should
| set it here. This will get used to authenticate with your server on
| connection. You may also set the "password" value below this one.
|
*/
'username' => null,
/*
|--------------------------------------------------------------------------
| SMTP Server Password
|--------------------------------------------------------------------------
|
| Here you may set the password required by your SMTP server to send out
| messages from your application. This will be given to the server on
| connection so that the application will be able to send messages.
|
*/
'password' => null,
/*
|--------------------------------------------------------------------------
| Sendmail System Path
|--------------------------------------------------------------------------
|
| When using the "sendmail" driver to send e-mails, we will need to know
| the path to where Sendmail lives on this server. A default path has
| been provided here, which will work well on most of your systems.
|
*/
'sendmail' => '/usr/sbin/sendmail -bs',
/*
|--------------------------------------------------------------------------
| Mail "Pretend"
|--------------------------------------------------------------------------
|
| When this option is enabled, e-mail will not actually be sent over the
| web and will instead be written to your application's logs files so
| you may inspect the message. This is great for local development.
|
*/
'pretend' => true,
);

View File

@ -17,6 +17,7 @@ return array(
*/
'BlacklistSecurityPolicy_BannedIpLifeTimeSeconds' => 21600,
'BlacklistSecurityPolicy_MinutesWithoutExceptions' => 5,
'BlacklistSecurityPolicy_MaxReplayAttackExceptionAttempts' => 3,
'BlacklistSecurityPolicy_ReplayAttackExceptionInitialDelay' => 10,
'BlacklistSecurityPolicy_MaxInvalidNonceAttempts' => 10,
'BlacklistSecurityPolicy_InvalidNonceInitialDelay' => 10,
@ -41,6 +42,8 @@ return array(
//oauth2 default config values
'OAuth2_AuthorizationCode_Lifetime' => 240,
'OAuth2_AccessToken_Lifetime' => 3600,
// in seconds , should be equal to session.lifetime (120 minutes)
'OAuth2_IdToken_Lifetime' => 7200,
'OAuth2_RefreshToken_Lifetime' => 0,
'OAuth2_Enable' => true,
//oauth2 security policy configuration
@ -49,4 +52,5 @@ return array(
'OAuth2SecurityPolicy_MaxInvalidClientExceptionAttempts' => 10,
'OAuth2SecurityPolicy_MaxInvalidRedeemAuthCodeAttempts' => 10,
'OAuth2SecurityPolicy_MaxInvalidInvalidClientCredentialsAttempts' => 5,
'Banning_Enable' => true,
);

View File

@ -16,6 +16,6 @@ return array(
|
*/
'driver' => 'array',
'driver' => 'redis',
);

View File

@ -9,23 +9,64 @@ use oauth2\services\IApiEndpointService;
use utils\services\IAuthService;
use openid\services\IUserService;
use utils\services\IServerConfigurationService;
use \utils\services\IBannedIPService;
use utils\services\IBannedIPService;
use oauth2\repositories\IServerPrivateKeyRepository;
use oauth2\repositories\IApiScopeGroupRepository;
use auth\User;
/**
* Class AdminController
*/
class AdminController extends BaseController {
/**
* @var IClientService
*/
private $client_service;
/**
* @var IApiScopeService
*/
private $scope_service;
/**
* @var ITokenService
*/
private $token_service;
/**
* @var IResourceServerService
*/
private $resource_server_service;
/**
* @var IApiService
*/
private $api_service;
/**
* @var IApiEndpointService
*/
private $endpoint_service;
/**
* @var IAuthService
*/
private $auth_service;
/**
* @var IUserService
*/
private $user_service;
/**
* @var IServerConfigurationService
*/
private $configuration_service;
/**
* @var IBannedIPService
*/
private $banned_ips_service;
private $private_keys_repository;
/**
* @var IApiScopeGroupRepository
*/
private $group_repository;
public function __construct( IClientService $client_service,
IApiScopeService $scope_service,
ITokenService $token_service,
@ -35,7 +76,10 @@ class AdminController extends BaseController {
IAuthService $auth_service,
IUserService $user_service,
IServerConfigurationService $configuration_service,
IBannedIPService $banned_ips_service){
IBannedIPService $banned_ips_service,
IServerPrivateKeyRepository $private_keys_repository,
IApiScopeGroupRepository $group_repository)
{
$this->client_service = $client_service;
$this->scope_service = $scope_service;
@ -47,6 +91,8 @@ class AdminController extends BaseController {
$this->user_service = $user_service;
$this->configuration_service = $configuration_service;
$this->banned_ips_service = $banned_ips_service;
$this->private_keys_repository = $private_keys_repository;
$this->group_repository = $group_repository;
}
public function editRegisteredClient($id)
@ -59,8 +105,6 @@ class AdminController extends BaseController {
return View::make("404");
}
$allowed_uris = $client->getClientRegisteredUris();
$allowed_origins = $client->getClientAllowedOrigins();
$selected_scopes = $client->getClientScopes();
$aux_scopes = array();
@ -68,7 +112,8 @@ class AdminController extends BaseController {
array_push($aux_scopes, $scope->id);
}
$scopes = $this->scope_service->getAvailableScopes($user->canUseSystemScopes());
$scopes = $this->scope_service->getAvailableScopes();
$group_scopes = $user->getGroupScopes();
$access_tokens = $this->token_service->getAccessTokenByClient($client->client_id);
@ -86,32 +131,69 @@ class AdminController extends BaseController {
return View::make("oauth2.profile.edit-client",
array(
'client' => $client,
'allowed_uris' => $allowed_uris,
'allowed_origins' => $allowed_origins,
'selected_scopes' => $aux_scopes,
'scopes' => $scopes,
'access_tokens' => $access_tokens,
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
'client' => $client,
'selected_scopes' => $aux_scopes,
'scopes' => array_merge($scopes, $group_scopes),
'access_tokens' => $access_tokens,
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
"is_openstackid_admin" => $user->isOpenstackIdAdmin(),
"use_system_scopes" => $user->canUseSystemScopes(),
'refresh_tokens' => $refresh_tokens,
"use_system_scopes" => $user->canUseSystemScopes(),
'refresh_tokens' => $refresh_tokens,
));
}
public function listResourceServers() {
// Api Scope Groups
public function listApiScopeGroups()
{
$user = $this->auth_service->getCurrentUser();
$groups = $this->group_repository->getAll(1,1000);
$non_selected_scopes = $this->scope_service->getAssignedByGroups();
$non_selected_users = User::where('active', '=', true)->get();
return View::make("oauth2.profile.admin.api-scope-groups",array
(
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
"is_openstackid_admin" => $user->isOpenstackIdAdmin(),
'groups' => $groups,
'non_selected_scopes' => $non_selected_scopes,
'non_selected_users' => $non_selected_users,
));
}
public function editApiScopeGroup($id){
$group = $this->group_repository->get($id);
if(is_null($group))
return Response::view('404', array(), 404);
$user = $this->auth_service->getCurrentUser();
$non_selected_scopes = $this->scope_service->getAssignedByGroups();
$non_selected_users = User::where('active', '=', true)->get();
return View::make("oauth2.profile.admin.edit-api-scope-group",
array
(
'is_oauth2_admin' => $user->isOAuth2ServerAdmin(),
'is_openstackid_admin' => $user->isOpenstackIdAdmin(),
'group' => $group,
'non_selected_scopes' => $non_selected_scopes,
'non_selected_users' => $non_selected_users,
)
);
}
// Resource servers
public function listResourceServers() {
$user = $this->auth_service->getCurrentUser();
$resource_servers = $this->resource_server_service->getAll(1,1000);
return View::make("oauth2.profile.admin.resource-servers",array(
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
"is_openstackid_admin" => $user->isOpenstackIdAdmin(),
'resource_servers'=>$resource_servers));
'resource_servers' => $resource_servers));
}
public function editResourceServer($id){
$resource_server = $this->resource_server_service->get($id);
if(is_null($resource_server))
return View::make('404');
return Response::view('404', array(), 404);
$user = $this->auth_service->getCurrentUser();
return View::make("oauth2.profile.admin.edit-resource-server",array(
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
@ -123,7 +205,7 @@ class AdminController extends BaseController {
public function editApi($id){
$api = $this->api_service->get($id);
if(is_null($api))
return View::make('404');
return Response::view('404', array(), 404);
$user = $this->auth_service->getCurrentUser();
return View::make("oauth2.profile.admin.edit-api",array(
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
@ -134,7 +216,7 @@ class AdminController extends BaseController {
public function editScope($id){
$scope = $this->scope_service->get($id);
if(is_null($scope))
return View::make('404');
return Response::view('404', array(), 404);
$user = $this->auth_service->getCurrentUser();
return View::make("oauth2.profile.admin.edit-scope",array(
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
@ -145,7 +227,7 @@ class AdminController extends BaseController {
public function editEndpoint($id){
$endpoint = $this->endpoint_service->get($id);
if(is_null($endpoint))
return View::make('404');
return Response::view('404', array(), 404);
$user = $this->auth_service->getCurrentUser();
$selected_scopes = array();
$list = $endpoint->scopes()->get(array('id'));
@ -235,31 +317,32 @@ class AdminController extends BaseController {
));
}
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.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['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');
$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.IdToken.Lifetime'] = $this->configuration_service->getConfigValue('OAuth2.IdToken.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,
));
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(){
@ -275,6 +358,7 @@ class AdminController extends BaseController {
'oauth2-auth-code-lifetime' => 'required|integer',
'oauth2-refresh-token-lifetime' => 'required|integer',
'oauth2-access-token-lifetime' => 'required|integer',
'oauth2-id-token-lifetime' => 'required|integer',
);
$dictionary = array(
@ -285,6 +369,7 @@ class AdminController extends BaseController {
'openid-nonce-lifetime' => 'OpenId.Nonce.Lifetime',
'oauth2-auth-code-lifetime' => 'OAuth2.AuthorizationCode.Lifetime',
'oauth2-access-token-lifetime' => 'OAuth2.AccessToken.Lifetime',
'oauth2-id-token-lifetime' => 'OAuth2.IdToken.Lifetime',
'oauth2-refresh-token-lifetime' => 'OAuth2.RefreshToken.Lifetime',
);
@ -314,4 +399,15 @@ class AdminController extends BaseController {
"ips" =>$ips
));
}
public function listServerPrivateKeys(){
$user = $this->auth_service->getCurrentUser();
return View::make("oauth2.profile.admin.server-private-keys", array(
'private_keys' => $this->private_keys_repository->getAll(1,4294967296),
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
"is_openstackid_admin" => $user->isOpenstackIdAdmin(),
));
}
}

View File

@ -2,23 +2,30 @@
use utils\services\ILogService;
abstract class AbstractRESTController extends JsonController {
/**
* Class AbstractRESTController
*/
abstract class AbstractRESTController extends JsonController
{
protected $allowed_filter_fields;
protected $allowed_projection_fields;
private $filter_delimiter;
private $field_delimiter;
protected $filter_delimiter;
protected $field_delimiter;
public function __construct(ILogService $log_service){
public function __construct(ILogService $log_service)
{
parent::__construct($log_service);
$this->filter_delimiter = '+';
$this->field_delimiter = ',';
}
protected function getProjection($fields){
protected function getProjection($fields)
{
if(!is_string($fields)) return array('*');
if(empty($fields)) return array('*');
$fields_args = explode($this->field_delimiter,$fields);
@ -33,7 +40,8 @@ abstract class AbstractRESTController extends JsonController {
return $res;
}
protected function getFilters($filters){
protected function getFilters($filters)
{
if(!is_array($filters)) return array();
$res = array();
foreach($filters as $fieldname=>$value){

View File

@ -1,8 +1,9 @@
<?php
use oauth2\exceptions\InvalidResourceServer;
use oauth2\services\IResourceServerService;
use utils\services\ILogService;
use oauth2\exceptions\InvalidResourceServer;
/**
* Class ApiResourceServerController
*/
@ -17,7 +18,7 @@ class ApiResourceServerController extends AbstractRESTController implements ICRU
{
parent::__construct($log_service);
$this->resource_server_service = $resource_server_service;
$this->allowed_filter_fields = array('');
$this->allowed_filter_fields = array('');
$this->allowed_projection_fields = array('*');
}
@ -29,18 +30,20 @@ class ApiResourceServerController extends AbstractRESTController implements ICRU
return $this->error404(array('error' => 'resource server not found'));
}
$data = $resource_server->toArray();
$apis = $resource_server->apis()->get(array('id','name'));
$data = $resource_server->toArray();
$apis = $resource_server->apis()->get(array('id', 'name'));
$data['apis'] = $apis->toArray();
$client = $resource_server->getClient();
if(!is_null($client)){
$data['client_id'] = $client->getClientId();
$data['client_secret'] = $client->getClientSecret();
$client = $resource_server->getClient();
if (!is_null($client)) {
$data['client_id'] = $client->getClientId();
$data['client_secret'] = $client->getClientSecret();
}
return $this->ok($data);
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
@ -48,22 +51,24 @@ class ApiResourceServerController extends AbstractRESTController implements ICRU
public function getByPage()
{
try {
$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));
$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);
$list = $this->resource_server_service->getAll($page_nbr, $page_size, $filters, $fields);
$items = array();
foreach ($list->getItems() as $rs) {
array_push($items, $rs->toArray());
}
return $this->ok( array(
return $this->ok(array(
'page' => $items,
'total_items' => $list->getTotal()
));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
@ -74,17 +79,18 @@ class ApiResourceServerController extends AbstractRESTController implements ICRU
$values = Input::all();
$rules = array(
'host' => 'required|host|max:255',
'ip' => 'required|ip|max:16',
'host' => 'required|host|max:255',
'ip' => 'required|ip|max:16',
'friendly_name' => 'required|text|max:512',
'active' => 'required|boolean',
'active' => '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'=>'validation','messages' => $messages));
return $this->error400(array('error' => 'validation', 'messages' => $messages));
}
$new_resource_server_model = $this->resource_server_service->add(
@ -94,13 +100,13 @@ class ApiResourceServerController extends AbstractRESTController implements ICRU
$values['active']);
return $this->created(array('resource_server_id' => $new_resource_server_model->id));
}
catch(InvalidResourceServer $ex1){
} catch (InvalidResourceServer $ex1) {
$this->log_service->error($ex1);
return $this->error400(array('error'=>$ex1->getMessage()));
}
catch (Exception $ex) {
return $this->error400(array('error' => $ex1->getMessage()));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
@ -109,9 +115,11 @@ class ApiResourceServerController extends AbstractRESTController implements ICRU
{
try {
$res = $this->resource_server_service->delete($id);
return $res?$this->deleted():$this->error404(array('error'=>'operation failed'));
return $res ? $this->deleted() : $this->error404(array('error' => 'operation failed'));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
@ -120,9 +128,11 @@ class ApiResourceServerController extends AbstractRESTController implements ICRU
{
try {
$res = $this->resource_server_service->regenerateClientSecret($id);
return !is_null($res)?$this->ok(array('new_secret'=>$res)):$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) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
@ -134,48 +144,55 @@ class ApiResourceServerController extends AbstractRESTController implements ICRU
$values = Input::all();
$rules = array(
'id' => 'required|integer',
'host' => 'sometimes|required|host|max:255',
'ip' => 'sometimes|required|ip|max:16',
'id' => 'required|integer',
'host' => 'sometimes|required|host|max:255',
'ip' => 'sometimes|required|ip|max:16',
'friendly_name' => 'sometimes|required|text|max:512',
);
// 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'=>'validation','messages' => $messages));
return $this->error400(array('error' => 'validation', 'messages' => $messages));
}
$res = $this->resource_server_service->update(intval($values['id']),$values);
return $res?$this->ok():$this->error400(array('error'=>'operation failed'));
}
catch(InvalidResourceServer $ex1){
$res = $this->resource_server_service->update(intval($values['id']), $values);
return $res ? $this->ok() : $this->error400(array('error' => 'operation failed'));
} catch (InvalidResourceServer $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 activate($id){
try {
$res = $this->resource_server_service->setStatus($id,true);
return $res?$this->ok():$this->error400(array('error'=>'operation failed'));
return $this->error404(array('error' => $ex1->getMessage()));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
public function deactivate($id){
try {
$res = $this->resource_server_service->setStatus($id,false);
return $res?$this->ok():$this->error400(array('error'=>'operation failed'));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
public function activate($id)
{
try {
$res = $this->resource_server_service->setStatus($id, true);
return $res ? $this->ok() : $this->error400(array('error' => 'operation failed'));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
public function deactivate($id)
{
try {
$res = $this->resource_server_service->setStatus($id, false);
return $res ? $this->ok() : $this->error400(array('error' => 'operation failed'));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
}

View File

@ -10,6 +10,9 @@ use oauth2\exceptions\InvalidApiScope;
*/
class ApiScopeController extends AbstractRESTController implements ICRUDController {
/**
* @var IApiScopeService
*/
private $api_scope_service;
public function __construct(IApiScopeService $api_scope_service, ILogService $log_service)
@ -74,6 +77,7 @@ class ApiScopeController extends AbstractRESTController implements ICRUDControll
'default' => 'required|boolean',
'system' => 'required|boolean',
'api_id' => 'required|integer',
'assigned_by_groups' => 'required|boolean',
);
// Creates a Validator instance and validates the data.
@ -91,7 +95,8 @@ class ApiScopeController extends AbstractRESTController implements ICRUDControll
$values['active'],
$values['default'],
$values['system'],
$values['api_id']
$values['api_id'],
$values['assigned_by_groups']
);
return $this->created(array('scope_id' => $new_scope->id));
@ -140,6 +145,7 @@ class ApiScopeController extends AbstractRESTController implements ICRUDControll
'active' => 'sometimes|required|boolean',
'system' => 'sometimes|required|boolean',
'default' => 'sometimes|required|boolean',
'assigned_by_groups' => 'sometimes|boolean',
);
// Creates a Validator instance and validates the data.

View File

@ -0,0 +1,278 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use utils\services\ILogService;
use oauth2\repositories\IApiScopeGroupRepository;
use oauth2\exceptions\InvalidApiScopeGroup;
use oauth2\services\IApiScopeGroupService;
use auth\IUserRepository;
use oauth2\services\IApiScopeService;
use utils\exceptions\EntityNotFoundException;
/**
* Class ApiScopeGroupController
*/
final class ApiScopeGroupController extends AbstractRESTController implements ICRUDController
{
/**
* @var IApiScopeGroupRepository
*/
private $repository;
/**
* @var IApiScopeGroupService
*/
private $service;
/**
* @var IUserRepository
*/
private $user_repository;
/**
* @var IApiScopeService
*/
private $scope_service;
/**
* ApiScopeGroupController constructor.
* @param IApiScopeGroupService $service
* @param IApiScopeGroupRepository $repository
* @param IUserRepository $user_repository
* @param IApiScopeService $scope_service
* @param ILogService $log_service
*/
public function __construct
(
IApiScopeGroupService $service,
IApiScopeGroupRepository $repository,
IUserRepository $user_repository,
IApiScopeService $scope_service,
ILogService $log_service
)
{
parent::__construct($log_service);
$this->repository = $repository;
$this->user_repository = $user_repository;
$this->scope_service = $scope_service;
$this->service = $service;
$this->allowed_filter_fields = array('');
$this->allowed_projection_fields = array('*');
}
/**
* @param $id
* @return mixed
*/
public function get($id)
{
// TODO: Implement get() method.
}
/**
* @return mixed
*/
public function create()
{
try
{
$values = Input::all();
$rules = array
(
'name' => 'required|text|max:512',
'active' => 'required|boolean',
'scopes' => 'required',
'users' => 'required',
);
// 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' => 'validation', 'messages' => $messages));
}
$new_group = $this->service->register
(
$values['name'],
$values['active'],
$values['scopes'],
$values['users']
);
return $this->created(array('group_id' => $new_group->id));
} catch (InvalidApiScopeGroup $ex1) {
$this->log_service->error($ex1);
return $this->error400(array('error' => $ex1->getMessage()));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
/**
* @return mixed
*/
public function getByPage()
{
try
{
$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->repository->getAll($page_nbr, $page_size, $filters, $fields);
$items = array();
foreach ($list->getItems() as $g)
{
array_push($items, $g->toArray());
}
return $this->ok(
array
(
'page' => $items,
'total_items' => $list->getTotal()
)
);
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
/**
* @param $id
* @return mixed
*/
public function delete($id)
{
try {
$group = $this->repository->get(intval($id));
if(is_null($group)) return $this->error404();
foreach($group->users()->get() as $user)
{
foreach($user->clients()->get() as $client)
{
foreach($group->scopes()->get() as $scope)
$client->scopes()->detach(intval($scope->id));
}
}
$this->repository->delete($group);
return $this->deleted();
}
catch (Exception $ex)
{
$this->log_service->error($ex);
return $this->error500($ex);
}
}
/**
* @return mixed
*/
public function update()
{
try {
$values = Input::all();
$rules = array
(
'id' => 'required|integer',
'name' => 'required|text|max:512',
'active' => 'required|boolean',
'scopes' => 'required',
'users' => 'required',
);
// 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' => 'validation', 'messages' => $messages));
}
$res = $this->service->update(intval($values['id']), $values);
return $res ? $this->ok() : $this->error400(array('error' => 'operation failed'));
}
catch (InvalidApiScopeGroup $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 activate($id){
try
{
$res = $this->service->setStatus($id, true);
return $res?$this->ok():$this->error400(array('error'=>'operation failed'));
}
catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
public function deactivate($id){
try
{
$res = $this->service->setStatus($id, false);
return $res?$this->ok():$this->error400(array('error'=>'operation failed'));
}
catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
public function fetchUsers()
{
$values = Input::all();
if(!isset($values['t'])) return $this->error404();
$term = $values['t'];
$users = $this->user_repository->getByEmailOrName($term);
if(count($users) > 0)
{
$list = array();
foreach($users as $u)
{
array_push($list, array
(
'id' => $u->id,
'value' => sprintf('%s (%s)', $u->getFullName(), $u->getEmail())
)
);
}
return $this->ok($list);
}
return $this->updated();
}
}

View File

@ -0,0 +1,131 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use oauth2\services\IAssymetricKeyService;
use utils\services\ILogService;
use oauth2\repositories\IAssymetricKeyRepository;
class AssymetricKeyApiController extends AbstractRESTController
{
/**
* @var IAssymetricKeyService
*/
protected $service;
/**
* @var IAssymetricKeyRepository
*/
protected $repository;
/**
* @param IAssymetricKeyRepository $repository
* @param IAssymetricKeyService $service
* @param ILogService $log_service
*/
public function __construct(
IAssymetricKeyRepository $repository,
IAssymetricKeyService $service,
ILogService $log_service
) {
parent::__construct($log_service);
$this->repository = $repository;
$this->service = $service;
//set filters allowed values
$this->allowed_filter_fields = array('*');
$this->allowed_projection_fields = array('*');
}
/**
* @param $id
* @return mixed
*/
protected function _delete($id)
{
try {
$res = $this->service->delete($id);
return $res ? $this->deleted() : $this->error404(array('error' => 'operation failed'));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
protected function _update($id)
{
try {
$values = Input::all();
$rules = array(
'id' => 'required|integer',
'active' => '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' => 'validation', 'messages' => $messages));
}
$res = $this->service->update(intval($id), $values);
return $res ? $this->ok() : $this->error400(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);
}
}
/**
* @return mixed
*/
protected 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->repository->getAll($page_nbr, $page_size, $filters, $fields);
$items = array();
foreach ($list->getItems() as $private_key) {
$data = $private_key->toArray();
$data['sha_256'] = $private_key->getSHA_256_Thumbprint();
array_push($items, $data);
}
return $this->ok(array(
'page' => $items,
'total_items' => $list->getTotal()
));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
}

View File

@ -1,21 +1,32 @@
<?php
use oauth2\exceptions\AllowedClientUriAlreadyExistsException;
use oauth2\exceptions\AbsentClientException;
use oauth2\exceptions\AllowedClientUriAlreadyExistsException;
use oauth2\services\IApiScopeService;
use oauth2\services\IClientService;
use oauth2\services\ITokenService;
use utils\services\ILogService;
use utils\exceptions\EntityNotFoundException;
use oauth2\exceptions\InvalidApiScope;
/**
* Class ClientApiController
* Client REST API
*/
class ClientApiController extends AbstractRESTController implements ICRUDController
final class ClientApiController extends AbstractRESTController implements ICRUDController
{
/**
* @var IClientService
*/
private $client_service;
/**
* @var IApiScopeService
*/
private $scope_service;
/**
* @var ITokenService
*/
private $token_service;
@ -25,31 +36,56 @@ class ClientApiController extends AbstractRESTController implements ICRUDControl
* @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);
$this->client_service = $client_service;
$this->scope_service = $scope_service;
$this->token_service = $token_service;
$this->scope_service = $scope_service;
$this->token_service = $token_service;
//set filters allowed values
$this->allowed_filter_fields = array('user_id');
$this->allowed_filter_fields = array('user_id');
$this->allowed_projection_fields = array('*');
}
public function get($id)
{
try {
$client = $this->client_service->get($id);
if (is_null($client))
{
return $this->error404(array('error' => 'client not found'));
}
$data = $client->toArray();
return $this->ok($data);
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
/**
* Deletes an existing client
* @param $id client id
* @param $id
* @return mixed
*/
public function delete($id)
{
try {
$res = $this->client_service->deleteClientByIdentifier($id);
return $res ? $this->deleted() : $this->error404(array('error' => 'operation failed'));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
@ -65,11 +101,11 @@ class ClientApiController extends AbstractRESTController implements ICRUDControl
// Build the validation constraint set.
$rules = array(
'user_id' => 'required|integer',
'app_name' => 'required|alpha_dash|max:255',
'app_description' => 'required|freetext',
'website' => 'required|url',
'application_type' => 'required|applicationtype',
'user_id' => 'required|integer',
'app_name' => 'required|alpha_dash|max:255',
'app_description' => 'required|freetext',
'website' => 'url',
'application_type' => 'required|applicationtype',
);
// Create a new validator instance.
@ -77,41 +113,26 @@ class ClientApiController extends AbstractRESTController implements ICRUDControl
if ($validation->fails()) {
$messages = $validation->messages()->toArray();
return $this->error400(array('error'=>'validation','messages' => $messages));
return $this->error400(array('error' => 'validation', 'messages' => $messages));
}
if ($this->client_service->existClientAppName($values['app_name'])) {
return $this->error400(array('error' => 'application Name already exists!.'));
}
$new_client = $this->client_service->addClient($values['application_type'], intval($values['user_id']), trim($values['app_name']), trim($values['app_description']), trim($values['website']));
$new_client = $this->client_service->addClient($values['application_type'], intval($values['user_id']),
trim($values['app_name']), trim($values['app_description']), trim($values['website']));
return $this->created(array('client_id' => $new_client->id));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
/**
* @param $id
* @return mixed
*/
public function get($id)
{
try {
$client = $this->client_service->get($id);
if (is_null($client)) {
return $this->error404(array('error' => 'client not found'));
}
$data = $client->toArray();
return $this->ok($data);
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
/**
* @return mixed
@ -120,24 +141,26 @@ class ClientApiController extends AbstractRESTController implements ICRUDControl
{
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));
$fields = $this->getProjection(Input::get('fields', null));
$filters = $this->getFilters(Input::except('fields', 'limit', 'offset'));
$page_nbr = intval(Input::get('offset', 1));
$page_size = intval(Input::get('limit', 10));
$list = $this->client_service->getAll($page_nbr, $page_size,$filters,$fields);
$list = $this->client_service->getAll($page_nbr, $page_size, $filters, $fields);
$items = array();
foreach ($list->getItems() as $client) {
$data = $client->toArray();
$data['application_type'] = $client->getFriendlyApplicationType();
array_push($items, $data);
}
return $this->ok(array(
'page' => $items,
'total_items' => $list->getTotal()
));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
@ -152,14 +175,38 @@ class ClientApiController extends AbstractRESTController implements ICRUDControl
$values = Input::all();
$rules = array(
'id' => 'required|integer',
'app_name' => 'sometimes|required|alpha_dash|max:255',
'app_description' => 'sometimes|required|freetext',
'website' => 'sometimes|required|url',
'active' => 'sometimes|required|boolean',
'locked' => 'sometimes|required|boolean',
'use_refresh_token' => 'sometimes|required|boolean',
'id' => 'required|integer',
'application_type' =>'required|application_type',
'app_name' => 'sometimes|required|alpha_dash|max:255',
'app_description' => 'sometimes|required|freetext',
'website' => 'url',
'active' => 'sometimes|required|boolean',
'locked' => 'sometimes|required|boolean',
'use_refresh_token' => 'sometimes|required|boolean',
'rotate_refresh_token' => 'sometimes|required|boolean',
'contacts' => 'email_set',
'logo_uri' => 'url',
'tos_uri' => 'url',
'redirect_uris' => 'custom_url_set:application_type',
'post_logout_redirect_uris' => 'ssl_url_set',
'allowed_origins' => 'ssl_url_set',
'logout_uri' => 'url',
'logout_session_required' => 'sometimes|required|boolean',
'logout_use_iframe' => 'sometimes|required|boolean',
'policy_uri' => 'url',
'jwks_uri' => 'url',
'default_max_age' => 'sometimes|required|integer',
'logout_use_iframe' => 'sometimes|required|boolean',
'require_auth_time' => 'sometimes|required|boolean',
'token_endpoint_auth_method' => 'sometimes|required|token_endpoint_auth_method',
'token_endpoint_auth_signing_alg' => 'sometimes|required|signing_alg',
'subject_type' => 'sometimes|required|subject_type',
'userinfo_signed_response_alg' => 'sometimes|required|signing_alg',
'userinfo_encrypted_response_alg' => 'sometimes|required|encrypted_alg',
'userinfo_encrypted_response_enc' => 'sometimes|required|encrypted_enc',
'id_token_signed_response_alg' => 'sometimes|required|signing_alg',
'id_token_encrypted_response_alg' => 'sometimes|required|encrypted_alg',
'id_token_encrypted_response_enc' => 'sometimes|required|encrypted_enc',
);
// Creates a Validator instance and validates the data.
@ -167,115 +214,70 @@ class ClientApiController extends AbstractRESTController implements ICRUDControl
if ($validation->fails()) {
$messages = $validation->messages()->toArray();
return $this->error400(array('error'=>'validation','messages' => $messages));
return $this->error400(array('error' => 'validation', 'messages' => $messages));
}
$res = $this->client_service->update(intval($values['id']), $values);
return $res ? $this->ok() : $this->error400(array('error' => 'operation failed'));
} catch (AbsentClientException $ex1) {
}
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
* @return mixed
*/
public function getRegisteredUris($id)
{
try {
$client = $this->client_service->getClientByIdentifier($id);
$allowed_uris = $client->authorized_uris()->get(array('id', 'uri'));
$data = array();
foreach ($allowed_uris as $uri) {
array_push($data, $uri->toArray());
}
return $this->ok(array('allowed_uris' => $data));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
/**
* @param $id
* @return mixed
*/
public function addAllowedRedirectUri($id)
{
try {
$values = Input::All();
// Build the validation constraint set.
$rules = array(
'redirect_uri' => 'sslurl|required',
);
// 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'=>'validation','messages' => $messages));
}
$res = $this->client_service->addClientAllowedUri($id, $values['redirect_uri']);
return $res ? $this->ok(): $this->error404(array('error' => 'operation failed'));
} catch (AllowedClientUriAlreadyExistsException $ex1) {
$this->log_service->error($ex1);
return $this->error400(array('error' => $ex1->getMessage()));
} catch (AbsentClientException $ex2) {
catch(ValidationException $ex2)
{
$this->log_service->error($ex2);
return $this->error404(array('error' => $ex2->getMessage()));
} catch (Exception $ex) {
return $this->error412(array($ex2->getMessage()));
}
catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
/**
* @param $id
* @param $uri_id
* @return mixed
*/
public function deleteClientAllowedUri($id, $uri_id)
public function addAllowedScope($id, $scope_id)
{
try {
$res = $this->client_service->deleteClientAllowedUri($id, $uri_id);
return $res ? $this->ok() : $this->error404(array('error' => 'operation failed'));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
public function addAllowedScope($id,$scope_id){
try {
try
{
$this->client_service->addClientScope($id, $scope_id);
return $this->ok();
} catch (AbsentClientException $ex1) {
}
catch (EntityNotFoundException $ex1)
{
$this->log_service->error($ex1);
return $this->error404(array('error' => $ex1->getMessage()));
} catch (Exception $ex) {
}
catch (InvalidApiScope $ex2)
{
$this->log_service->error($ex2);
return $this->error412(array('messages' => $ex2->getMessage()));
}
catch (Exception $ex)
{
$this->log_service->error($ex);
return $this->error500($ex);
}
}
public function removeAllowedScope($id,$scope_id){
try {
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);
}
}
@ -285,39 +287,56 @@ class ClientApiController extends AbstractRESTController implements ICRUDControl
{
try {
$res = $this->client_service->activateClient($id, true);
return $res ? $this->ok() : $this->error404(array('error' => 'operation failed'));
} catch (AbsentClientException $ex1) {
$this->log_service->error($ex1);
return $this->error404(array('error' => $ex1->getMessage()));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
public function deactivate($id)
{
try {
$res = $this->client_service->activateClient($id, false);
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 regenerateClientSecret($id)
public function deactivate($id)
{
try {
$res = $this->client_service->regenerateClientSecret($id);
return !empty($res) ?
$this->ok(array('new_secret' => $res)): $this->error404(array('error' => 'operation failed'));
$res = $this->client_service->activateClient($id, false);
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 regenerateClientSecret($id)
{
try
{
$client = $this->client_service->regenerateClientSecret($id);
return !is_null($client) ?
$this->ok
(
array
(
'new_secret' => $client->getClientSecret(),
'new_expiration_date' => $client->getClientSecretExpiration(),
)
) : $this->error404(array('error' => 'operation failed'));
}
catch (Exception $ex)
{
$this->log_service->error($ex);
return $this->error500($ex);
}
}
@ -336,7 +355,8 @@ class ClientApiController extends AbstractRESTController implements ICRUDControl
$validation = Validator::make($values, $rules);
if ($validation->fails()) {
$messages = $validation->messages()->toArray();
return $this->error400(array('error'=>'validation','messages' => $messages));
return $this->error400(array('error' => 'validation', 'messages' => $messages));
}
$res = $this->client_service->setRefreshTokenUsage($id, $values['use_refresh_token']);
@ -345,9 +365,11 @@ class ClientApiController extends AbstractRESTController implements ICRUDControl
} 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);
}
}
@ -365,16 +387,20 @@ class ClientApiController extends AbstractRESTController implements ICRUDControl
$validation = Validator::make($values, $rules);
if ($validation->fails()) {
$messages = $validation->messages()->toArray();
return $this->error400(array('error'=>'validation','messages' => $messages));
return $this->error400(array('error' => 'validation', 'messages' => $messages));
}
$res = $this->client_service->setRotateRefreshTokenPolicy($id, $values['rotate_refresh_token']);
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);
}
}
@ -385,26 +411,28 @@ class ClientApiController extends AbstractRESTController implements ICRUDControl
$res = false;
$client = $this->client_service->getClientByIdentifier($id);
switch ($hint) {
case 'access-token':
{
$token = $this->token_service->getAccessToken($value,true);
case 'access-token': {
$token = $this->token_service->getAccessToken($value, true);
if (is_null($token)) {
return $this->error404(array('error' => sprintf('access token %s does not exists!', $value)));
}
if ($token->getClientId() !== $client->client_id) {
return $this->error404(array('error' => sprintf('access token %s does not belongs to client id !', $value, $id)));
return $this->error404(array(
'error' => sprintf('access token %s does not belongs to client id !', $value, $id)
));
}
$res = $this->token_service->revokeAccessToken($value, true);
}
break;
case 'refresh-token':
{
$token = $this->token_service->getRefreshToken($value,true);
case 'refresh-token': {
$token = $this->token_service->getRefreshToken($value, true);
if (is_null($token)) {
return $this->error404(array('error' => sprintf('refresh token %s does not exists!', $value)));
}
if ($token->getClientId() !== $client->client_id) {
return $this->error404(array('error' => sprintf('refresh token %s does not belongs to client id !', $value, $id)));
return $this->error404(array(
'error' => sprintf('refresh token %s does not belongs to client id !', $value, $id)
));
}
$res = $this->token_service->revokeRefreshToken($value, true);
}
@ -416,6 +444,7 @@ class ClientApiController extends AbstractRESTController implements ICRUDControl
return $res ? $this->ok() : $this->error404(array('error' => 'operation failed'));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
@ -427,17 +456,18 @@ class ClientApiController extends AbstractRESTController implements ICRUDControl
$access_tokens = $this->token_service->getAccessTokenByClient($client->client_id);
$res = array();
foreach ($access_tokens as $token) {
$friendly_scopes = $this->scope_service->getFriendlyScopesByName(explode(' ', $token->scope));
array_push($res, array(
'value' => $token->value,
'scope' => implode(',', $friendly_scopes),
'value' => $token->value,
'scope' => $token->scope,
'lifetime' => $token->getRemainingLifetime(),
'issued' => $token->created_at->format('Y-m-d H:i:s')
'issued' => $token->created_at->format('Y-m-d H:i:s')
));
}
return $this->ok(array('access_tokens' => $res));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
@ -449,17 +479,18 @@ class ClientApiController extends AbstractRESTController implements ICRUDControl
$refresh_tokens = $this->token_service->getRefreshTokenByClient($client->client_id);
$res = array();
foreach ($refresh_tokens as $token) {
$friendly_scopes = $this->scope_service->getFriendlyScopesByName(explode(' ', $token->scope));
array_push($res, array(
'value' => $token->value,
'scope' => implode(',', $friendly_scopes),
'scope' => $token->scope,
'lifetime' => $token->getRemainingLifetime(),
'issued' => $token->created_at->format('Y-m-d H:i:s')
));
}
return $this->ok(array('refresh_tokens' => $res));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
@ -468,87 +499,19 @@ class ClientApiController extends AbstractRESTController implements ICRUDControl
* @param $id
* @return mixed
*/
public function unlock($id){
public function unlock($id)
{
try {
$res = $this->client_service->unlockClient($id);
return $res ? $this->ok() : $this->error404(array('error' => 'operation failed'));
}
catch (AbsentClientException $ex1) {
} 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
* @return mixed
*/
public function geAllowedOrigins($id)
{
try {
$client = $this->client_service->getClientByIdentifier($id);
$allowed_origins = $client->allowed_origins()->get(array('id', 'allowed_origin'));
$data = array();
foreach ($allowed_origins as $origin) {
array_push($data, $origin->toArray());
}
return $this->ok(array('allowed_origins' => $data));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
/**
* @param $id
* @return mixed
*/
public function addAllowedOrigin($id)
{
try {
$values = Input::All();
// Build the validation constraint set.
$rules = array(
'origin' => 'sslorigin|required',
);
// 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'=>'validation','messages' => $messages));
}
$res = $this->client_service->addClientAllowedOrigin($id, $values['origin']);
return $res ? $this->ok(): $this->error404(array('error' => 'operation failed'));
} catch (AllowedClientUriAlreadyExistsException $ex1) {
$this->log_service->error($ex1);
return $this->error400(array('error' => $ex1->getMessage()));
} catch (AbsentClientException $ex2) {
$this->log_service->error($ex2);
return $this->error404(array('error' => $ex2->getMessage()));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
/**
* @param $id
* @param $origin_id
* @return mixed
*/
public function deleteClientAllowedOrigin($id, $origin_id)
{
try {
$res = $this->client_service->deleteClientAllowedOrigin($id, $origin_id);
return $res ? $this->ok() : $this->error404(array('error' => 'operation failed'));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}

View File

@ -0,0 +1,154 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use oauth2\services\IClienPublicKeyService;
use utils\services\ILogService;
use oauth2\repositories\IClientPublicKeyRepository;
/**
* Class ClientPublicKeyApiController
*/
final class ClientPublicKeyApiController extends AssymetricKeyApiController
{
/**
* @param IClientPublicKeyRepository $repository
* @param IClienPublicKeyService $service
* @param ILogService $log_service
*/
public function __construct
(
IClientPublicKeyRepository $repository,
IClienPublicKeyService $service,
ILogService $log_service
)
{
parent::__construct($repository, $service, $log_service);
}
/**
* @param int $id
* @return mixed
*/
public function get($id)
{
return $this->error404();
}
/**
* @param int $client_id
* @return mixed
*/
public function create($client_id)
{
try
{
$values = Input::All();
$values['client_id'] = $client_id;
// Build the validation constraint set.
$rules = array(
'client_id' => 'required|integer',
'kid' => 'required|text|max:255',
'active' => 'required|boolean',
'valid_from' => 'date_format:m/d/Y',
'valid_to' => 'date_format:m/d/Y|after:valid_from',
'pem_content' => 'required|public_key_pem|public_key_pem_length',
'usage' => 'required|public_key_usage',
'type' => 'required|public_key_type',
'alg' => 'required|key_alg:usage',
);
// Create a new validator instance.
$validation = Validator::make($values, $rules);
if ($validation->fails())
{
$messages = $validation->messages()->toArray();
return $this->error400(array('error' => 'validation', 'messages' => $messages));
}
$public_key = $this->service->register($values);
return $this->created(array('id' => $public_key->getId()));
}
catch(ValidationException $ex1)
{
return $this->error400(array('error' => $ex1->getMessage()));
}
catch (Exception $ex)
{
$this->log_service->error($ex);
return $this->error500($ex);
}
}
/**
* @return mixed
*/
public function getByPage($client_id)
{
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));
array_push($filters, array
(
'name' => 'oauth2_client_id',
'op' => '=',
'value' => $client_id
)
);
$list = $this->repository->getAll($page_nbr, $page_size, $filters, $fields);
$items = array();
foreach ($list->getItems() as $private_key) {
$data = $private_key->toArray();
$data['sha_256'] = $private_key->getSHA_256_Thumbprint();
array_push($items, $data);
}
return $this->ok(array(
'page' => $items,
'total_items' => $list->getTotal()
));
} catch (Exception $ex) {
$this->log_service->error($ex);
return $this->error500($ex);
}
}
/**
* @param int $client_id
* @param int $public_key_id
* @return mixed
*/
public function update($client_id, $public_key_id)
{
return $this->_update($public_key_id);
}
/**
* @param int $client_id
* @param int $public_key_id
* @return mixed
*/
public function delete($client_id, $public_key_id){
return $this->_delete($public_key_id);
}
}

View File

@ -1,12 +1,35 @@
<?php
/**
* Interface ICRUDController
*/
interface ICRUDController {
/**
* @param $id
* @return mixed
*/
public function get($id);
/**
* @return mixed
*/
public function create();
/**
* @return mixed
*/
public function getByPage();
/**
* @param $id
* @return mixed
*/
public function delete($id);
/**
* @return mixed
*/
public function update();
}

View File

@ -16,7 +16,7 @@ abstract class JsonController extends BaseController {
protected function error500(Exception $ex){
$this->log_service->error($ex);
return Response::json(array('message' => 'server error'), 500);
return Response::json(array( 'error' => 'server error'), 500);
}
protected function created($data='ok'){
@ -27,6 +27,15 @@ abstract class JsonController extends BaseController {
return $res;
}
protected function updated()
{
$res = Response::json($data, 204);
//jsonp
if(Input::has('callback'))
$res->setCallback(Input::get('callback'));
return $res;
}
protected function deleted($data='ok'){
$res = Response::json($data, 204);
//jsonp
@ -35,7 +44,7 @@ abstract class JsonController extends BaseController {
return $res;
}
protected function ok($data='ok'){
protected function ok($data = 'ok'){
$res = Response::json($data, 200);
//jsonp
if(Input::has('callback'))
@ -67,6 +76,6 @@ abstract class JsonController extends BaseController {
*/
protected function error412($messages){
return Response::json(array('message' => 'Validation Failed', 'errors' => $messages), 412);
return Response::json(array('error'=>'validation' , 'messages' => $messages), 412);
}
}

View File

@ -0,0 +1,110 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use oauth2\services\IServerPrivateKeyService;
use oauth2\repositories\IServerPrivateKeyRepository;
use utils\services\ILogService;
/**
* Class ServerPrivateKeyApiController
*/
final class ServerPrivateKeyApiController extends AssymetricKeyApiController
{
/**
* @param IServerPrivateKeyRepository $repository
* @param IServerPrivateKeyService $service
* @param ILogService $log_service
*/
public function __construct
(
IServerPrivateKeyRepository $repository,
IServerPrivateKeyService $service,
ILogService $log_service
)
{
parent::__construct($repository, $service, $log_service);
}
/**
* @return mixed
*/
public function create()
{
try
{
$values = Input::All();
// Build the validation constraint set.
$rules = array(
'kid' => 'required|text|min:5|max:255',
'active' => 'required|boolean',
'valid_from' => 'date_format:m/d/Y',
'valid_to' => 'date_format:m/d/Y|after:valid_from',
'pem_content' => 'sometimes|required|private_key_pem:password|private_key_pem_length:password',
'usage' => 'required|public_key_usage',
'type' => 'required|public_key_type',
'alg' => 'required|key_alg:usage',
'password' => 'min:5|max:255|private_key_password:pem_content',
);
// Create a new validator instance.
$validation = Validator::make($values, $rules);
if ($validation->fails())
{
$messages = $validation->messages()->toArray();
return $this->error400(array('error' => 'validation', 'messages' => $messages));
}
$private_key = $this->service->register($values);
return $this->created(array('id' => $private_key->getId()));
}
catch(ValidationException $ex1)
{
return $this->error400(array('error' => $ex1->getMessage()));
}
catch (Exception $ex)
{
$this->log_service->error($ex);
return $this->error500($ex);
}
}
public function getByPage()
{
return $this->_getByPage();
}
/**
* @param int $id
* @return mixed
*/
public function update($id)
{
return $this->_update($id);
}
/**
* @param int $id
* @return mixed
*/
public function delete($id)
{
return $this->_delete($id);
}
}

View File

@ -7,13 +7,24 @@ use utils\services\ILogService;
* Class OAuth2ProtectedController
* OAuth2 Protected Base API
*/
abstract class OAuth2ProtectedController extends JsonController {
abstract class OAuth2ProtectedController extends JsonController
{
/**
* @var IResourceServerContext
*/
protected $resource_server_context;
/**
* @var
*/
protected $repository;
public function __construct(IResourceServerContext $resource_server_context, ILogService $log_service)
public function __construct
(
IResourceServerContext $resource_server_context,
ILogService $log_service
)
{
parent::__construct($log_service);
$this->resource_server_context = $resource_server_context;

View File

@ -3,30 +3,111 @@
use oauth2\IResourceServerContext;
use utils\services\ILogService;
use oauth2\resource_server\IUserService;
use oauth2\services\IClientService;
use oauth2\heuristics\SigningKeyFinder;
use oauth2\heuristics\EncryptionKeyFinder;
use oauth2\builders\IdTokenBuilder;
use utils\http\HttpContentType;
/**
* Class OAuth2UserApiController
* OAUTH2 Protected User REST API
*/
class OAuth2UserApiController extends OAuth2ProtectedController {
class OAuth2UserApiController extends OAuth2ProtectedController
{
/**
* @var IUserService
*/
private $user_service;
public function __construct (IUserService $user_service, IResourceServerContext $resource_server_context, ILogService $log_service){
/**
* @var IClientService
*/
private $client_service;
/**
* @var IdTokenBuilder
*/
private $id_token_builder;
/**
* @param IUserService $user_service
* @param IResourceServerContext $resource_server_context
* @param ILogService $log_service
* @param IClientService $client_service
* @param IdTokenBuilder $id_token_builder
*/
public function __construct
(
IUserService $user_service,
IResourceServerContext $resource_server_context,
ILogService $log_service,
IClientService $client_service,
IdTokenBuilder $id_token_builder
)
{
parent::__construct($resource_server_context,$log_service);
$this->user_service = $user_service;
$this->user_service = $user_service;
$this->client_service = $client_service;
$this->id_token_builder = $id_token_builder;
}
/**
* Gets User Basic Info
* @return mixed
*/
public function me(){
try{
public function me()
{
try
{
$data = $this->user_service->getCurrentUserInfo();
return $this->ok($data);
}
catch(Exception $ex){
catch(Exception $ex)
{
$this->log_service->error($ex);
return $this->error500($ex);
}
}
public function userInfo()
{
try
{
$claims = $this->user_service->getCurrentUserInfoClaims();
$client_id = $this->resource_server_context->getCurrentClientId();
$client = $this->client_service->getClientById($client_id);
// The UserInfo Claims MUST be returned as the members of a JSON object unless a signed or encrypted response
// was requested during Client Registration.
$user_info_response_info = $client->getUserInfoResponseInfo();
$sig_alg = $user_info_response_info->getSigningAlgorithm();
$enc_alg = $user_info_response_info->getEncryptionKeyAlgorithm();
$enc = $user_info_response_info->getEncryptionContentAlgorithm();
if($sig_alg || ($enc_alg && $enc) )
{
$jwt = $this->id_token_builder->buildJWT($claims, $user_info_response_info, $client);
$http_response = Response::make($jwt->toCompactSerialization(), 200);
$http_response->header('Content-Type', HttpContentType::JWT);
$http_response->header('Cache-Control','no-cache, no-store, max-age=0, must-revalidate');
$http_response->header('Pragma','no-cache');
return $http_response;
}
else
{
// return plain json
return $this->ok( $claims->toArray() );
}
}
catch(Exception $ex)
{
$this->log_service->error($ex);
return $this->error500($ex);
}
}
}

View File

@ -1,56 +1,132 @@
<?php
use oauth2\IOAuth2Protocol;
use oauth2\services\IMementoOAuth2AuthenticationRequestService;
use oauth2\requests\OAuth2TokenRequest;
use oauth2\strategies\OAuth2ResponseStrategyFactoryMethod;
use oauth2\OAuth2Message;
use oauth2\requests\OAuth2TokenRevocationRequest;
use oauth2\requests\OAuth2AccessTokenValidationRequest;
use oauth2\responses\OAuth2Response;
use oauth2\factories\OAuth2AuthorizationRequestFactory;
use oauth2\services\IMementoOAuth2SerializerService;
use oauth2\exceptions\InvalidAuthorizationRequestException;
use utils\services\IAuthService;
use utils\http\HttpContentType;
use oauth2\requests\OAuth2LogoutRequest;
use oauth2\exceptions\UriNotAllowedException;
use \oauth2\services\IClientService;
/**
* Class OAuth2ProviderController
*/
class OAuth2ProviderController extends BaseController {
final class OAuth2ProviderController extends BaseController
{
/**
* @var IOAuth2Protocol
*/
private $oauth2_protocol;
/**
* @var IMementoOAuth2SerializerService
*/
private $memento_service;
/**
* @param IOAuth2Protocol $oauth2_protocol
* @param IMementoOAuth2AuthenticationRequestService $memento_service
* @var IAuthService
*/
public function __construct(IOAuth2Protocol $oauth2_protocol, IMementoOAuth2AuthenticationRequestService $memento_service){
private $auth_service;
/**
* @var IClientService
*/
private $client_service;
/**
* @param IOAuth2Protocol $oauth2_protocol
* @param IMementoOAuth2SerializerService $memento_service
* @param IClientService $client_service
* @param IAuthService $auth_service
*/
public function __construct
(
IOAuth2Protocol $oauth2_protocol,
IMementoOAuth2SerializerService $memento_service,
IClientService $client_service,
IAuthService $auth_service
)
{
$this->oauth2_protocol = $oauth2_protocol;
$this->memento_service = $memento_service;
$this->auth_service = $auth_service;
$this->client_service = $client_service;
}
/**
* Authorize HTTP Endpoint
* The authorization server MUST support the use of the HTTP "GET"
* method [RFC2616] for the authorization endpoint and MAY support the
* use of the "POST" method as well.
* @return mixed
*/
public function authorize(){
$request = $this->memento_service->getCurrentAuthorizationRequest();
$response = $this->oauth2_protocol->authorize($request);
$reflector = new ReflectionClass($response);
if ($reflector->isSubclassOf('oauth2\\responses\\OAuth2Response')) {
$strategy = OAuth2ResponseStrategyFactoryMethod::buildStrategy($response);
return $strategy->handle($response);
public function authorize()
{
try
{
$msg = new OAuth2Message(Input::all());
if ($this->memento_service->exists()) {
$msg = OAuth2Message::buildFromMemento($this->memento_service->load());
}
$request = OAuth2AuthorizationRequestFactory::getInstance()->build($msg);
$response = $this->oauth2_protocol->authorize($request);
if ($response instanceof OAuth2Response) {
$strategy = OAuth2ResponseStrategyFactoryMethod::buildStrategy($request, $response);
return $strategy->handle($response);
}
return $response;
}
catch(UriNotAllowedException $ex1)
{
return Response::view
(
'400',
array
(
'error_code' => $ex1->getError(),
'error_description' => $ex1->getMessage()
),
400
);
}
return $response;
}
/**
* Token HTTP Endpoint
* @return mixed
*/
public function token(){
$response = $this->oauth2_protocol->token(new OAuth2TokenRequest(new OAuth2Message(Input::all())));
$reflector = new ReflectionClass($response);
if ($reflector->isSubclassOf('oauth2\\responses\\OAuth2Response')) {
$strategy = OAuth2ResponseStrategyFactoryMethod::buildStrategy($response);
public function token()
{
$request = new OAuth2TokenRequest
(
new OAuth2Message
(
Input::all()
)
);
$response = $this->oauth2_protocol->token($request);
if ($response instanceof OAuth2Response)
{
$strategy = OAuth2ResponseStrategyFactoryMethod::buildStrategy($request, $response);
return $strategy->handle($response);
}
return $response;
}
@ -58,13 +134,24 @@ class OAuth2ProviderController extends BaseController {
* Revoke Token HTTP Endpoint
* @return mixed
*/
public function revoke(){
$response = $this->oauth2_protocol->revoke(new OAuth2TokenRevocationRequest(new OAuth2Message(Input::all())));
$reflector = new ReflectionClass($response);
if ($reflector->isSubclassOf('oauth2\\responses\\OAuth2Response')) {
$strategy = OAuth2ResponseStrategyFactoryMethod::buildStrategy($response);
public function revoke()
{
$request = new OAuth2TokenRevocationRequest
(
new OAuth2Message
(
Input::all()
)
);
$response = $this->oauth2_protocol->revoke($request);
if ($response instanceof OAuth2Response)
{
$strategy = OAuth2ResponseStrategyFactoryMethod::buildStrategy($request, $response);
return $strategy->handle($response);
}
return $response;
}
@ -73,13 +160,124 @@ class OAuth2ProviderController extends BaseController {
* Introspection Token HTTP Endpoint
* @return mixed
*/
public function introspection(){
$response = $this->oauth2_protocol->introspection(new OAuth2AccessTokenValidationRequest(new OAuth2Message(Input::all())));
$reflector = new ReflectionClass($response);
if ($reflector->isSubclassOf('oauth2\\responses\\OAuth2Response')) {
$strategy = OAuth2ResponseStrategyFactoryMethod::buildStrategy($response);
public function introspection()
{
$request = new OAuth2AccessTokenValidationRequest
(
new OAuth2Message
(
Input::all()
)
);
$response = $this->oauth2_protocol->introspection($request);
if ($response instanceof OAuth2Response)
{
$strategy = OAuth2ResponseStrategyFactoryMethod::buildStrategy($request, $response);
return $strategy->handle($response);
}
return $response;
}
/**
* OP's JSON Web Key Set [JWK] document.
* @return string
*/
public function certs()
{
$doc = $this->oauth2_protocol->getJWKSDocument();
$response = Response::make($doc, 200);
$response->header('Content-Type', HttpContentType::Json);
return $response;
}
public function discovery()
{
$doc = $this->oauth2_protocol->getDiscoveryDocument();
$response = Response::make($doc, 200);
$response->header('Content-Type', HttpContentType::Json);
return $response;
}
/**
* http://openid.net/specs/openid-connect-session-1_0.html#OPiframe
*/
public function checkSessionIFrame()
{
$data = array();
return View::make("oauth2.session.check-session", $data);
}
/**
* http://openid.net/specs/openid-connect-session-1_0.html#RPLogout
*/
public function endSession()
{
if(!$this->auth_service->isUserLogged())
return Response::view('404', array(), 404);
$request = new OAuth2LogoutRequest
(
new OAuth2Message
(
Input::all()
)
);
if(!$request->isValid())
{
Log::error('invalid OAuth2LogoutRequest!');
return Response::view('404', array(), 404);
}
if(Request::isMethod('get') )
{
$rps = $this->auth_service->getLoggedRPs();
$clients = array();
foreach($this->auth_service->getLoggedRPs() as $client_id)
{
$client = $this->client_service->getClientById($client_id);
if(!is_null($client)) array_push($clients, $client);
}
// At the logout endpoint, the OP SHOULD ask the End-User whether he wants to log out of the OP as well.
// If the End-User says "yes", then the OP MUST log out the End-User.
return View::make('oauth2.session.session-logout', array
(
'clients' => $clients,
'id_token_hint' => $request->getIdTokenHint(),
'post_logout_redirect_uri' => $request->getPostLogoutRedirectUri(),
'state' => $request->getState(),
));
}
$consent = Input::get('oidc_endsession_consent');
if($consent === '1')
{
$response = $this->oauth2_protocol->endSession($request);
if (!is_null($response) && $response instanceof OAuth2Response) {
$strategy = OAuth2ResponseStrategyFactoryMethod::buildStrategy($request, $response);
return $strategy->handle($response);
}
return View::make('oauth2.session.session-ended');
}
Log::error('invalid consent response!');
return Response::view('404', array(), 404);
}
public function cancelLogout()
{
return Redirect::action('HomeController@index');
}
}

View File

@ -3,34 +3,54 @@
use openid\exceptions\InvalidOpenIdMessageException;
use openid\helpers\OpenIdErrorMessages;
use openid\IOpenIdProtocol;
use openid\services\IMementoOpenIdRequestService;
use openid\services\IMementoOpenIdSerializerService;
use openid\strategies\OpenIdResponseStrategyFactoryMethod;
use openid\OpenIdMessage;
use openid\responses\OpenIdResponse;
/**
* Class OpenIdProviderController
*/
class OpenIdProviderController extends BaseController
{
/**
* @var IOpenIdProtocol
*/
private $openid_protocol;
/**
* @var IMementoOpenIdSerializerService
*/
private $memento_service;
public function __construct(IOpenIdProtocol $openid_protocol, IMementoOpenIdRequestService $memento_service)
/**
* @param IOpenIdProtocol $openid_protocol
* @param IMementoOpenIdSerializerService $memento_service
*/
public function __construct(IOpenIdProtocol $openid_protocol, IMementoOpenIdSerializerService $memento_service)
{
$this->openid_protocol = $openid_protocol;
$this->memento_service = $memento_service;
}
/**
* @return OpenIdResponse
* @throws Exception
* @throws InvalidOpenIdMessageException
*/
public function endpoint()
{
$input = Input::all();
Log::debug(print_r($input, true));
$msg = $this->memento_service->getCurrentRequest();
if (is_null($msg) || !$msg->isValid())
$msg = new OpenIdMessage( Input::all() );
if($this->memento_service->exists()){
$msg = OpenIdMessage::buildFromMemento( $this->memento_service->load());
}
if (!$msg->isValid())
throw new InvalidOpenIdMessageException(OpenIdErrorMessages::InvalidOpenIdMessage);
//get response and manage it taking in consideration its type (direct or indirect)
$response = $this->openid_protocol->handleOpenIdMessage($msg);
$reflector = new ReflectionClass($response);
if ($reflector->isSubclassOf('openid\\responses\\OpenIdResponse')) {
if ($response instanceof OpenIdResponse) {
$strategy = OpenIdResponseStrategyFactoryMethod::buildStrategy($response);
return $strategy->handle($response);
}

View File

@ -2,24 +2,24 @@
use oauth2\services\IApiScopeService;
use oauth2\services\IClientService;
use oauth2\services\IMementoOAuth2AuthenticationRequestService;
use oauth2\services\ITokenService;
use oauth2\services\IResourceServerService;
use openid\services\IMementoOpenIdRequestService;
use oauth2\services\ITokenService;
use openid\requests\OpenIdAuthenticationRequest;
use openid\services\IMementoOpenIdSerializerService;
use openid\services\IServerConfigurationService;
use openid\services\ITrustedSitesService;
use openid\services\IUserService;
use openid\services\IServerConfigurationService;
use openid\requests\OpenIdAuthenticationRequest;
use openid\XRDS\XRDSDocumentBuilder;
use strategies\OpenIdLoginStrategy;
use strategies\OpenIdConsentStrategy;
use utils\IPHelper;
use services\IUserActionService;
use strategies\DefaultLoginStrategy;
use strategies\OAuth2ConsentStrategy;
use strategies\OAuth2LoginStrategy;
use strategies\OpenIdConsentStrategy;
use strategies\OpenIdLoginStrategy;
use utils\IPHelper;
use utils\services\IAuthService;
use utils\services\IServerConfigurationService as IUtilsServerConfigurationService;
use oauth2\services\IMementoOAuth2SerializerService;
use oauth2\services\ISecurityContextService;
/**
* Class UserController
@ -27,36 +27,97 @@ use utils\services\IServerConfigurationService as IUtilsServerConfigurationServi
class UserController extends OpenIdController
{
/**
* @var IMementoOpenIdSerializerService
*/
private $openid_memento_service;
/**
* @var IMementoOAuth2SerializerService
*/
private $oauth2_memento_service;
/**
* @var IAuthService
*/
private $auth_service;
/**
* @var IServerConfigurationService
*/
private $server_configuration_service;
/**
* @var DiscoveryController
*/
private $discovery;
/**
* @var IUserService
*/
private $user_service;
/**
* @var IUserActionService
*/
private $user_action_service;
/**
* @var DefaultLoginStrategy
*/
private $login_strategy;
/**
* @var null
*/
private $consent_strategy;
/**
* @var IClientService
*/
private $client_service;
/**
* @var IApiScopeService
*/
private $scope_service;
/**
* @var ITokenService
*/
private $token_service;
/**
* @var IResourceServerService
*/
private $resource_server_service;
private $utils_configuration_service;
/**
* @var IUtilsServerConfigurationService
*/
private $utils_configuration_service;
public function __construct(IMementoOpenIdRequestService $openid_memento_service,
IMementoOAuth2AuthenticationRequestService $oauth2_memento_service,
IAuthService $auth_service,
IServerConfigurationService $server_configuration_service,
ITrustedSitesService $trusted_sites_service,
DiscoveryController $discovery,
IUserService $user_service,
IUserActionService $user_action_service,
IClientService $client_service,
IApiScopeService $scope_service,
ITokenService $token_service,
IResourceServerService $resource_server_service,
IUtilsServerConfigurationService $utils_configuration_service
)
/**
* @param IMementoOpenIdSerializerService $openid_memento_service
* @param IMementoOAuth2SerializerService $oauth2_memento_service
* @param IAuthService $auth_service
* @param IServerConfigurationService $server_configuration_service
* @param ITrustedSitesService $trusted_sites_service
* @param DiscoveryController $discovery
* @param IUserService $user_service
* @param IUserActionService $user_action_service
* @param IClientService $client_service
* @param IApiScopeService $scope_service
* @param ITokenService $token_service
* @param IResourceServerService $resource_server_service
* @param IUtilsServerConfigurationService $utils_configuration_service
*/
public function __construct
(
IMementoOpenIdSerializerService $openid_memento_service,
IMementoOAuth2SerializerService $oauth2_memento_service,
IAuthService $auth_service,
IServerConfigurationService $server_configuration_service,
ITrustedSitesService $trusted_sites_service,
DiscoveryController $discovery,
IUserService $user_service,
IUserActionService $user_action_service,
IClientService $client_service,
IApiScopeService $scope_service,
ITokenService $token_service,
IResourceServerService $resource_server_service,
IUtilsServerConfigurationService $utils_configuration_service,
ISecurityContextService $security_context_service
)
{
$this->openid_memento_service = $openid_memento_service;
$this->oauth2_memento_service = $oauth2_memento_service;
$this->auth_service = $auth_service;
@ -69,25 +130,50 @@ class UserController extends OpenIdController
$this->scope_service = $scope_service;
$this->token_service = $token_service;
$this->resource_server_service = $resource_server_service;
$this->utils_configuration_service = $utils_configuration_service;
$this->utils_configuration_service = $utils_configuration_service;
//filters
$this->beforeFilter('csrf', array('only' => array('postLogin', 'postConsent')));
$openid_msg = $this->openid_memento_service->getCurrentRequest();
$oauth2_msg = $this->oauth2_memento_service->getCurrentAuthorizationRequest();
if (!is_null($openid_msg) && $openid_msg->isValid() && OpenIdAuthenticationRequest::IsOpenIdAuthenticationRequest($openid_msg)) {
if ($this->openid_memento_service->exists())
{
//openid stuff
$this->beforeFilter('openid.save.request');
$this->beforeFilter('openid.needs.auth.request', array('only' => array('getConsent')));
$this->login_strategy = new OpenIdLoginStrategy($openid_memento_service, $user_action_service, $auth_service);
$this->consent_strategy = new OpenIdConsentStrategy($openid_memento_service, $auth_service, $server_configuration_service, $user_action_service);
} else if (!is_null($oauth2_msg) && $oauth2_msg->isValid()) {
$this->beforeFilter('oauth2.save.request');
$this->beforeFilter('oauth2.needs.auth.request', array('only' => array('getConsent')));
$this->login_strategy = new OAuth2LoginStrategy($auth_service, $oauth2_memento_service ,$user_action_service);
$this->consent_strategy = new OAuth2ConsentStrategy($auth_service, $oauth2_memento_service, $scope_service, $client_service);
} else {
$this->login_strategy = new OpenIdLoginStrategy
(
$openid_memento_service,
$user_action_service,
$auth_service
);
$this->consent_strategy = new OpenIdConsentStrategy
(
$openid_memento_service,
$auth_service,
$server_configuration_service,
$user_action_service
);
}
else if ($this->oauth2_memento_service->exists())
{
$this->login_strategy = new OAuth2LoginStrategy
(
$auth_service,
$oauth2_memento_service,
$user_action_service,
$security_context_service
);
$this->consent_strategy = new OAuth2ConsentStrategy
(
$auth_service,
$oauth2_memento_service,
$scope_service,
$client_service
);
}
else
{
//default stuff
$this->login_strategy = new DefaultLoginStrategy($user_action_service, $auth_service);
$this->consent_strategy = null;
@ -106,46 +192,54 @@ class UserController extends OpenIdController
public function postLogin()
{
try {
try
{
$max_login_attempts_2_show_captcha = $this->server_configuration_service->getConfigValue("MaxFailed.LoginAttempts.2ShowCaptcha");
$data = Input::all();
$login_attempts = intval(Input::get('login_attempts'));
// Build the validation constraint set.
$rules = array(
$rules = array
(
'username' => 'required|email',
'password' => 'required',
);
if ($login_attempts >= $max_login_attempts_2_show_captcha) {
$rules['recaptcha_response_field'] = 'required|recaptcha';
if ($login_attempts >= $max_login_attempts_2_show_captcha)
{
$rules['g-recaptcha-response'] = 'required|recaptcha';
}
// Create a new validator instance.
$validator = Validator::make($data, $rules);
if ($validator->passes()) {
$username = Input::get("username");
$password = Input::get("password");
$remember = Input::get("remember");
if ($validator->passes())
{
$username = Input::get("username");
$password = Input::get("password");
$remember = Input::get("remember");
$remember = !is_null($remember);
if ($this->auth_service->login($username, $password, $remember)) {
if ($this->auth_service->login($username, $password, $remember))
{
return $this->login_strategy->postLogin();
}
//failed login attempt...
$user = $this->auth_service->getUserByUsername($username);
if ($user) {
if ($user)
{
$login_attempts = $user->login_failed_attempt;
}
return Redirect::action('UserController@getLogin')
->with('max_login_attempts_2_show_captcha', $max_login_attempts_2_show_captcha)
->with('login_attempts', $login_attempts)
->with('username',$username)
->with('flash_notice', "We're sorry, your username or password does not match an existing record.");
->with('max_login_attempts_2_show_captcha', $max_login_attempts_2_show_captcha)
->with('login_attempts', $login_attempts)
->with('username', $username)
->with('flash_notice', "We're sorry, your username or password does not match an existing record.");
}
return Redirect::action('UserController@getLogin')
->withErrors($validator);
} catch (Exception $ex) {
->withErrors($validator);
}
catch (Exception $ex)
{
Log::error($ex);
return Redirect::action('UserController@getLogin');
}
@ -154,19 +248,26 @@ class UserController extends OpenIdController
public function getConsent()
{
if (is_null($this->consent_strategy))
{
return View::make("404");
}
return $this->consent_strategy->getConsent();
}
public function postConsent()
{
try {
try
{
$trust_action = input::get("trust");
if (!is_null($trust_action) && !is_null($this->consent_strategy)) {
if (!is_null($trust_action) && !is_null($this->consent_strategy))
{
return $this->consent_strategy->postConsent($trust_action);
}
return Redirect::action('UserController@getConsent');
} catch (Exception $ex) {
}
catch (Exception $ex)
{
Log::error($ex);
return Redirect::action('UserController@getConsent');
}
@ -174,12 +275,16 @@ class UserController extends OpenIdController
public function getIdentity($identifier)
{
try {
try
{
$user = $this->auth_service->getUserByOpenId($identifier);
if (is_null($user))
{
return View::make("404");
}
if ($this->isDiscoveryRequest()) {
if ($this->isDiscoveryRequest())
{
/*
* If the Claimed Identifier was not previously discovered by the Relying Party
* (the "openid.identity" in the request was "http://specs.openid.net/auth/2.0/identifier_select"
@ -191,15 +296,17 @@ class UserController extends OpenIdController
}
$current_user = $this->auth_service->getCurrentUser();
$another_user = false;
if ($current_user && $current_user->getIdentifier() != $user->getIdentifier()) {
if ($current_user && $current_user->getIdentifier() != $user->getIdentifier())
{
$another_user = true;
}
$assets_url = $this->utils_configuration_service->getConfigValue("Assets.Url");
$pic_url = $user->getPic();
$pic_url = str_contains($pic_url,'http')?$pic_url:$assets_url.$pic_url;
$assets_url = $this->utils_configuration_service->getConfigValue("Assets.Url");
$pic_url = $user->getPic();
$pic_url = str_contains($pic_url, 'http') ? $pic_url : $assets_url . $pic_url;
$params = array(
$params = array
(
'show_fullname' => $user->getShowProfileFullName(),
'username' => $user->getFullName(),
'show_email' => $user->getShowProfileEmail(),
@ -209,8 +316,11 @@ class UserController extends OpenIdController
'pic' => $pic_url,
'another_user' => $another_user,
);
return View::make("identity", $params);
} catch (Exception $ex) {
}
catch (Exception $ex)
{
Log::error($ex);
return View::make("404");
}
@ -218,8 +328,15 @@ class UserController extends OpenIdController
public function logout()
{
$this->user_action_service->addUserAction($this->auth_service->getCurrentUser(), IPHelper::getUserIp(), IUserActionService::LogoutAction);
Auth::logout();
$this->user_action_service->addUserAction
(
$this->auth_service->getCurrentUser(),
IPHelper::getUserIp(),
IUserActionService::LogoutAction
);
$this->auth_service->logout();
return Redirect::action("UserController@getLogin");
}
@ -229,7 +346,8 @@ class UserController extends OpenIdController
$sites = $user->getTrustedSites();
$actions = $user->getActions();
return View::make("profile", array(
return View::make("profile", array
(
"username" => $user->getFullName(),
"user_id" => $user->getId(),
"is_oauth2_admin" => $user->isOAuth2ServerAdmin(),
@ -252,13 +370,15 @@ class UserController extends OpenIdController
$show_pic = Input::get("show_pic");
$user = $this->auth_service->getCurrentUser();
$this->user_service->saveProfileInfo($user->getId(), $show_pic, $show_full_name, $show_email);
return Redirect::action("UserController@getProfile");
}
public function deleteTrustedSite($id)
{
$this->trusted_sites_service->delTrustedSite($id);
return Redirect::action("UserController@getProfile");
}
}
}

View File

@ -24,7 +24,7 @@ class InsertMarketplaceApiEndpointsScopes extends Migration {
'active' => true,
'Description' => 'Marketplace Public Clouds',
'resource_server_id' => $resource_server->id,
'logo' => asset('img/apis/server.png')
'logo' => asset('/assets/img/apis/server.png')
)
);
// private clouds
@ -35,7 +35,7 @@ class InsertMarketplaceApiEndpointsScopes extends Migration {
'active' => true,
'Description' => 'Marketplace Private Clouds',
'resource_server_id' => $resource_server->id,
'logo' => asset('img/apis/server.png')
'logo' => asset('/assets/img/apis/server.png')
)
);
// consultants
@ -46,7 +46,7 @@ class InsertMarketplaceApiEndpointsScopes extends Migration {
'active' => true,
'Description' => 'Marketplace Consultants',
'resource_server_id' => $resource_server->id,
'logo' => asset('img/apis/server.png')
'logo' => asset('/assets/img/apis/server.png')
)
);

View File

@ -0,0 +1,95 @@
<?php
use Illuminate\Database\Migrations\Migration;
use oauth2\OAuth2Protocol;
use oauth2\models\IClient;
use jwa\JSONWebSignatureAndEncryptionAlgorithms;
/**
* Class UpdateOauth2Client
*/
class UpdateOauth2ClientOIDC extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::table('oauth2_client', function($table) {
$table->dateTime('client_secret_expires_at')->nullable();
$table->text('contacts')->nullable();
$table->text('allowed_origins')->nullable();
$table->text('redirect_uris')->nullable();
$table->string('logo_uri')->nullable();
$table->string('tos_uri')->nullable();
// http://openid.net/specs/openid-connect-session-1_0.html#ClientMetadata
$table->text('post_logout_redirect_uris')->nullable();
$table->text('logout_uri')->nullable();
$table->boolean('logout_session_required')->default(false);
$table->boolean('logout_use_iframe')->default(false);
$table->string('policy_uri')->nullable();
$table->string('jwks_uri')->nullable();
$table->integer('default_max_age')->default(-1);
$table->boolean('require_auth_time')->default(false);
// http://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication
$table->enum('token_endpoint_auth_method', array_merge(OAuth2Protocol::$token_endpoint_auth_methods, array (
OAuth2Protocol::TokenEndpoint_AuthMethod_None)))->default(OAuth2Protocol::TokenEndpoint_AuthMethod_None);
$table->enum("token_endpoint_auth_signing_alg", OAuth2Protocol::$supported_signing_algorithms)->default(JSONWebSignatureAndEncryptionAlgorithms::None);
$table->enum('subject_type', Client::$valid_subject_types)->default(IClient::SubjectType_Public);
$table->enum("userinfo_signed_response_alg", OAuth2Protocol::$supported_signing_algorithms)->default(JSONWebSignatureAndEncryptionAlgorithms::None);
// encryption
$table->enum("userinfo_encrypted_response_alg", OAuth2Protocol::$supported_key_management_algorithms)->default(JSONWebSignatureAndEncryptionAlgorithms::None);
$table->enum("userinfo_encrypted_response_enc", OAuth2Protocol::$supported_content_encryption_algorithms)->default(JSONWebSignatureAndEncryptionAlgorithms::None);
$table->enum("id_token_signed_response_alg", OAuth2Protocol::$supported_signing_algorithms)->default(JSONWebSignatureAndEncryptionAlgorithms::None);
// encryption
$table->enum("id_token_encrypted_response_alg", OAuth2Protocol::$supported_key_management_algorithms)->default(JSONWebSignatureAndEncryptionAlgorithms::None);
$table->enum("id_token_encrypted_response_enc", OAuth2Protocol::$supported_content_encryption_algorithms)->default(JSONWebSignatureAndEncryptionAlgorithms::None);
});
DB::statement("ALTER TABLE oauth2_client MODIFY COLUMN client_type ENUM('PUBLIC','CONFIDENTIAL') default 'CONFIDENTIAL';");
DB::statement("ALTER TABLE oauth2_client MODIFY COLUMN application_type ENUM('WEB_APPLICATION','JS_CLIENT','SERVICE', 'NATIVE') default 'WEB_APPLICATION';");
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::table('oauth2_client', function($table) {
$table->dropColumn('client_secret_expires_at');
$table->dropColumn('contacts');
$table->dropColumn('allowed_origins');
$table->dropColumn('redirect_uris');
$table->dropColumn('logo_uri');
$table->dropColumn('tos_uri');
$table->dropColumn('post_logout_redirect_uris');
$table->dropColumn('logout_uri');
$table->dropColumn('logout_session_required');
$table->dropColumn('logout_use_iframe');
$table->dropColumn('policy_uri');
$table->dropColumn('jwks_uri');
$table->dropColumn('default_max_age');
$table->dropColumn('require_auth_time');
$table->dropColumn('token_endpoint_auth_method');
$table->dropColumn('token_endpoint_auth_signing_alg');
$table->dropColumn('subject_type');
$table->dropColumn('userinfo_signed_response_alg');
$table->dropColumn('userinfo_encrypted_response_alg');
$table->dropColumn('userinfo_encrypted_response_enc');
$table->dropColumn('id_token_signed_response_alg');
$table->dropColumn('id_token_encrypted_response_alg');
$table->dropColumn('id_token_encrypted_response_enc');
});
DB::statement("ALTER TABLE oauth2_client MODIFY COLUMN application_type ENUM('WEB_APPLICATION','JS_CLIENT','SERVICE') default 'WEB_APPLICATION';");
}
}

View File

@ -0,0 +1,87 @@
<?php
use Illuminate\Database\Migrations\Migration;
use jwk\JSONWebKeyPublicKeyUseValues;
use jwk\JSONWebKeyTypes;
use jwa\JSONWebSignatureAndEncryptionAlgorithms;
use oauth2\OAuth2Protocol;
/**
* Class CreateAssymetricKeys
*/
final class CreateAssymetricKeys extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('oauth2_assymetric_keys', function ($table) {
$table->bigIncrements('id');
$table->timestamps();
$table->text('pem_content');
$table->string('kid');
$table->boolean('active')->default(true);
$table->enum
(
'usage',
JSONWebKeyPublicKeyUseValues::$valid_uses
)->default(JSONWebKeyPublicKeyUseValues::Signature);
$table->enum('class_name', array('ClientPublicKey', 'ServerPrivateKey'))->default('ClientPublicKey');
$table->enum(
'type',
array
(
JSONWebKeyTypes::RSA,
JSONWebKeyTypes::EllipticCurve
)
)->default(JSONWebKeyTypes::RSA);
$table->dateTime('last_use')->nullable();
$table->text('password')->nullable();
$table->dateTime('valid_from');
$table->dateTime('valid_to');
$table->enum
(
'alg',
array_merge
(
OAuth2Protocol::$supported_signing_algorithms_rsa,
OAuth2Protocol::$supported_key_management_algorithms
)
)
->default
(
JSONWebSignatureAndEncryptionAlgorithms::None
);
// FK
$table->bigInteger("oauth2_client_id")->unsigned()->nullable();
$table->index('oauth2_client_id');
$table->foreign('oauth2_client_id')
->references('id')
->on('oauth2_client')
->onDelete('cascade')
->onUpdate('no action');
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::table('oauth2_assymetric_keys', function ($table) {
$table->dropForeign('oauth2_client_id');
});
Schema::dropIfExists('oauth2_assymetric_keys');
}
}

View File

@ -0,0 +1,54 @@
<?php
use Illuminate\Database\Migrations\Migration;
class MigrateRedirectUris extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
$uris = DB::table('oauth2_client_authorized_uri')->orderBy('client_id', 'desc')->get();
foreach($uris as $uri)
{
$client = Client::find($uri->client_id);
$redirect_uris = $client->redirect_uris;
if(!empty($redirect_uris))
$redirect_uris = $redirect_uris.','.$uri->uri;
else
$redirect_uris = $uri->uri;
$client->redirect_uris = $redirect_uris;
$client->save();
}
$uris = DB::table('oauth2_client_allowed_origin')->orderBy('client_id', 'desc')->get();
foreach($uris as $uri)
{
$client = Client::find($uri->client_id);
$allowed_origins = $client->allowed_origins;
if(!empty($allowed_origins))
$allowed_origins = $redirect_uris.','.$uri->allowed_origin;
else
$allowed_origins = $uri->allowed_origin;
$client->allowed_origins = $allowed_origins;
$client->save();
}
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
//
}
}

View File

@ -0,0 +1,50 @@
<?php
use Illuminate\Database\Migrations\Migration;
use oauth2\OAuth2Protocol;
class AddNewDefaultScopes extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
ApiScope::create(
array(
'name' => OAuth2Protocol::OpenIdConnect_Scope,
'short_description' => 'OpenId Connect Protocol',
'description' => 'OpenId Connect Protocol',
'api_id' => null,
'system' => true,
'default' => true,
'active' => true,
)
);
ApiScope::create(
array(
'name' => OAuth2Protocol::OfflineAccess_Scope,
'short_description' => 'allow to emit refresh tokens (offline access without user presence)',
'description' => 'allow to emit refresh tokens (offline access without user presence)',
'api_id' => null,
'system' => true,
'default' => true,
'active' => true,
)
);
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
ApiScope::where('name', '=', OAuth2Protocol::OpenIdConnect_Scope)->first()-delete();
ApiScope::where('name', '=', OAuth2Protocol::OfflineAccess_Scope)->first()-delete();
}
}

View File

@ -0,0 +1,43 @@
<?php
use Illuminate\Database\Migrations\Migration;
use oauth2\OAuth2Protocol;
use oauth2\models\IClient;
class UpdateOauth2ClientScopes extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
$clients = Client::get();
$scope_openid = ApiScope::where('name', '=', OAuth2Protocol::OpenIdConnect_Scope)->first();
$scope_offline = ApiScope::where('name', '=', OAuth2Protocol::OfflineAccess_Scope)->first();
foreach($clients as $client)
{
$client->scopes()->attach($scope_openid->id);
if($client->application_type === IClient::ApplicationType_Native || $client->application_type === IClient::ApplicationType_Web_App)
$client->scopes()->attach($scope_offline->id);
if ($client->client_type === IClient::ClientType_Confidential)
{
$client->token_endpoint_auth_method = OAuth2Protocol::TokenEndpoint_AuthMethod_ClientSecretBasic;
$client->save();
}
}
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
//
}
}

View File

@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use oauth2\models\IClient;
class Oauth2ClientsUpdateSecretExpirationDate extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
$clients = Client::get();
$now = new \DateTime();
foreach ($clients as $client)
{
if ($client->client_type !== IClient::ClientType_Confidential) continue;
// default 6 months
$client->client_secret_expires_at = $now->add(new \DateInterval('P6M'));
$client->save();
}
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
//
}
}

View File

@ -0,0 +1,66 @@
<?php
use Illuminate\Database\Migrations\Migration;
class AddUserInfoOIDCEndpoint extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
$users = Api::where('name', '=', 'users')->first();
if(is_null($users)) return;
ApiEndpoint::create(
array(
'name' => 'get-user-claims-get',
'active' => true,
'api_id' => $users->id,
'route' => '/api/v1/users/info',
'http_method' => 'GET',
'allow_cors' => true,
)
);
ApiEndpoint::create(
array(
'name' => 'get-user-claims-post',
'active' => true,
'api_id' => $users->id,
'route' => '/api/v1/users/info',
'http_method' => 'POST',
'allow_cors' => true,
)
);
$profile_scope = ApiScope::where('name', '=', 'profile')->first();
$email_scope = ApiScope::where('name', '=', 'email')->first();
$address_scope = ApiScope::where('name', '=', 'address')->first();
$get_user_info_endpoint = ApiEndpoint::where('name', '=', 'get-user-claims-get')->first();
$get_user_info_endpoint->scopes()->attach($profile_scope->id);
$get_user_info_endpoint->scopes()->attach($email_scope->id);
$get_user_info_endpoint->scopes()->attach($address_scope->id);
$get_user_info_endpoint = ApiEndpoint::where('name', '=', 'get-user-claims-post')->first();
$get_user_info_endpoint->scopes()->attach($profile_scope->id);
$get_user_info_endpoint->scopes()->attach($email_scope->id);
$get_user_info_endpoint->scopes()->attach($address_scope->id);
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
//
}
}

View File

@ -0,0 +1,75 @@
<?php
use Illuminate\Database\Migrations\Migration;
class AddApiScopesGroups extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('oauth2_api_scope_group', function ($table) {
$table->bigIncrements('id')->unsigned();
$table->string('name', 512);
$table->text('description');
$table->boolean('active')->default(true);
$table->timestamps();
});
Schema::create('oauth2_api_scope_group_scope', function($table)
{
$table->timestamps();
$table->bigInteger("group_id")->unsigned();
$table->index('group_id');
$table->foreign('group_id')
->references('id')
->on('oauth2_api_scope_group')
->onDelete('cascade')
->onUpdate('no action'); ;
$table->bigInteger("scope_id")->unsigned();
$table->index('scope_id');
$table->foreign('scope_id')
->references('id')
->on('oauth2_api_scope')
->onDelete('cascade')
->onUpdate('no action');
});
Schema::create('oauth2_api_scope_group_users', function($table)
{
$table->timestamps();
$table->bigInteger("group_id")->unsigned();
$table->index('group_id');
$table->foreign('group_id')
->references('id')
->on('oauth2_api_scope_group')
->onDelete('cascade')
->onUpdate('no action'); ;
$table->bigInteger("user_id")->unsigned();
$table->index('user_id');
$table->foreign('user_id')
->references('id')
->on('openid_users')
->onDelete('cascade')
->onUpdate('no action');
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('oauth2_api_scope_group');
Schema::dropIfExists('oauth2_api_scope_group_scope');
Schema::dropIfExists('oauth2_api_scope_group_users');
}
}

View File

@ -0,0 +1,26 @@
<?php
use Illuminate\Database\Migrations\Migration;
class UpdateApiScope extends Migration
{
public function up()
{
Schema::table('oauth2_api_scope', function ($table) {
$table->boolean('assigned_by_groups')->default(false);
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::table('oauth2_api_scope', function ($table) {
$table->dropColumn('assigned_by_groups');
});
}
}

View File

@ -37,6 +37,36 @@ class ApiEndpointSeeder extends Seeder
$get_user_info_endpoint->scopes()->attach($profile_scope->id);
$get_user_info_endpoint->scopes()->attach($email_scope->id);
$get_user_info_endpoint->scopes()->attach($address_scope->id);
ApiEndpoint::create(
array(
'name' => 'get-user-claims-get',
'active' => true,
'api_id' => $users->id,
'route' => '/api/v1/users/info',
'http_method' => 'GET'
)
);
ApiEndpoint::create(
array(
'name' => 'get-user-claims-post',
'active' => true,
'api_id' => $users->id,
'route' => '/api/v1/users/info',
'http_method' => 'POST'
)
);
$get_user_info_endpoint = ApiEndpoint::where('name','=','get-user-claims-get')->first();
$get_user_info_endpoint->scopes()->attach($profile_scope->id);
$get_user_info_endpoint->scopes()->attach($email_scope->id);
$get_user_info_endpoint->scopes()->attach($address_scope->id);
$get_user_info_endpoint = ApiEndpoint::where('name','=','get-user-claims-post')->first();
$get_user_info_endpoint->scopes()->attach($profile_scope->id);
$get_user_info_endpoint->scopes()->attach($email_scope->id);
$get_user_info_endpoint->scopes()->attach($address_scope->id);
}
}

View File

@ -1,5 +1,7 @@
<?php
use oauth2\OAuth2Protocol;
/**
* Class ApiScopeSeeder
*/
@ -47,6 +49,31 @@ class ApiScopeSeeder extends Seeder {
)
);
ApiScope::create(
array(
'name' => OAuth2Protocol::OpenIdConnect_Scope,
'short_description' => 'OpenId Connect Protocol',
'description' => 'OpenId Connect Protocol',
'api_id' => null,
'system' => true,
'default' => true,
'active' => true,
)
);
ApiScope::create(
array(
'name' => OAuth2Protocol::OfflineAccess_Scope,
'short_description' => 'allow to emit refresh tokens (offline access without user presence)',
'description' => 'allow to emit refresh tokens (offline access without user presence)',
'api_id' => null,
'system' => true,
'default' => true,
'active' => true,
)
);
}
}

View File

@ -22,7 +22,7 @@ class ApiSeeder extends Seeder {
'active' => true,
'Description' => 'User Info',
'resource_server_id' => $resource_server->id,
'logo' => asset('img/apis/server.png')
'logo' => asset('/assets/img/apis/server.png')
)
);
}

View File

@ -3,17 +3,248 @@
use oauth2\models\IClient;
use auth\User;
use utils\services\IAuthService;
use \jwk\JSONWebKeyPublicKeyUseValues;
use \jwk\JSONWebKeyTypes;
use \oauth2\OAuth2Protocol;
use \jwa\JSONWebSignatureAndEncryptionAlgorithms;
/**
* Class OAuth2ApplicationSeeder
* This seeder is only for testing purposes
*/
class TestSeeder extends Seeder {
static $client_private_key_1 = <<<PPK
-----BEGIN RSA PRIVATE KEY-----
MIIJJwIBAAKCAgEAkjiUI6n3Fq140AipaLxNIPCzEItQFcY8G5Xd17u7InM3H542
+34PdBpwR66miQUgJK+rtfaot/v4QPj4/0BnYc78BhI0Mp3tVEH95jjIrhDMZoRF
fSQsAhiom5NTP1B5XiiyRjzkO1+7a29JST5tIQUIS2U345DMWyf3GNlC1cBAfgI+
PrRo3gLby/iW5EF/Mqq0ZUIOuggZ7r8kU2aUhXILFx2w9V/y90DwruJdzZ0Tesbs
Fit2nM3Axie7HX2wIpbl2hyvvhX/AxZ0NPudVh58wNogsKOMUN6guU+RzL5L6vF+
QjfzBCtOE+CRmUD60E0LdQHzElBcF0tbc2cj2YelZ0Dp+4NEBDjCNsSv//5hHacU
xxXQdwwotLUV85iErEZgcGyMNnTMsw7JIh39UBgOEmQgfpfOUlH+/5WmRO+kskvP
CACz1SR8gzAKz9Nu9r3UyE+gWaZzM2+CpQ1szEd94MIapHxJw9vHogL7sNkjmZ34
Y9eQmoCVevqDVpYEdTtLsg9H49+pEndQHI6lGAB7QlsPLN8A17L2l3p68BFcYkSZ
R4GuXAyQguq3KzWYDZ9PjWAV5lhVg6K3GaV7fvn2pKCk4P5Y5hZt08fholt3k/5G
c82CP6rfgQFi7HnpBJKRauoIdsvUPvXZYTLlTaE5jLBAwxm+wF6Ue/nRPJMCAwEA
AQKCAgBj6pOX9zmn3mwyw+h3cEzIGJJT2M6lwmsqcnNASsEqXk6ppWRu4ApRTQuy
f+6+rKj1SLFuSxmpd12BkGAdk/XRCS6AO4o9mFsne1yzJ9RB1arG1tXhGImV+SGm
BbsaBbSZmfeQNWXECLu6QzZx/V129chgNM9HCpgKJjocWcHo7FFlicTc9ky+gHeP
XtRFL1hq1+kjVEtZ5dVKpoR9FRiiQ3a+mgRk9+a//Dk7V+W/bfl0qV+EGrkXlyWG
gnnDQjLMwA5ax8Vzf/ZdNse7uMAfq/+VjLhP28IzNJ3hYzT/En4wEkszlqXSEIFu
5cK4VYXONweAMg/WUOFM7aqVJkKBAifM2panOPW0cQX+dd9dJp0xT/7+7EvHkpYj
Pm0giGv9ktvYHm7loYowAqpDdZzcd9WMd4O/7XlG+ZM275mOLBjrV/xi7FPT7daI
RCsAOf2GbVC71q90UaNuotSKqojAGhmkYl89jCvxuaEE1bCAlqVaTyCRH2gGH+fX
Q4LW6nCONgkkWGqBG/yCU3bezaRnGedaSyqWBawA8w8MP8c20Jo83mnbEczjDf5o
p6UYAAfWgF1TdBCBCaVWEKjzNl1NIA7PwKOB89a/nXyecNkr6CFf8FwXbXvuYpHA
l52whE1W6ZRrtViSqV8RdA91yICM1sDVVeictHhl8ZC1hOg7aQKCAQEA691dZ469
d5E19yv/eQMxcRWHNheUzHrQPN1YLligaP/F3Uia4r8tiiL04YcMzbzT9wa4ON3p
VIwKcqn8/NXOOp0UUT759H/AImGC16yIK3KdUeYwBZ6sDYcKj5DG3K8EOHSFuTIB
RUe0qgJGGA3Qjx7hoEudVBis18kF7LvLSvwJeySnGh82qNdkXov5YyPVA/iuKOhJ
+m3b1OQ00ZtnxW2zO/8v68ABV1EYP9w2qpsShOw5kx1vTorYlKlDu597AzRvJWke
E7yznoorl8GFQgrb4K9lKCaKzfpO4wlJCq9xGAjF3rCBvjWF/2dMpoleCK8A9Xz5
DHMJcWIXyKPhpQKCAQEAnrQfTnAdPb2f6KLhgnCOJoXbHK/NQ3uNbTUXUdfToCFc
BBkdYBlq8J7iWfKkFp9azcem7GgL0hsx3WkGuDTOUcwbNa2ZGKqvg7TQO0On95JX
SlAH7damfE03wNLKWpbQgi3Ip0kHZLVSfyZ8FIO1YuQcwIs5YVFJrXO5t8ZaR1Nw
n5QAgTlttQ1P9VQn/eAAfxx/wDq3Md81kDPI7ZOb2RJCn366/J2yK6ICp/ywqMiG
DUIfGqnEFuinE4ZMl04f4wC/fb3RnIlY7tjteAAqcg0NzogEuAgmWsDyYjnJGyAP
9HVIC21/LiMCC/xYVY8tIETT0jyjKB3lEepl2iDf1wKCAQBivpk1Gqgtn4h1Q2FA
G1semcGynqq39I6rfItHU+lMLBB9NMFLPnhlRX85z91HYM9ostJ7VEQ0FjDlkk8M
1sHw/gQcg34Ho1gfzK0Hd/7GGcTNHc5q++PSAgAk3Jq0lzzwGbBGOS4ZAA0dw7fu
qBHxaR9SiXWDWJU7/bfSRUi1ytB5Un32zKyIgSxO/NDadYzfjcPz8lPOWSHYffWy
7xnBqMyJyKsaSpcFJDk/uwTT5foZ1f/AnGkV+8Dyc+6cZQcN72y8v8ZMwwp7zCK1
9NnCLWOiLCvwZDpmQ221VRTUOWDijAGy2jhnFmdT5r5LVmUcw49mNvzY/mwsoMGO
STXVAoIBAClpXOXt0WOD8I8WuXt8/UrGEOfKY+hg/AVsHhqoE7usGMOk/gpOd540
B2JrMzAIAvzBRShY+gSoPfnFZxB4DwI/HTaDhvhtyYC3lMJyJAkw8YAdpAQGx8iV
qZ+yIUVEJ0JgygQExV4dBlrRYv1DZPhaB7qiWaWwPWZ6VRLEOlh0SGYLi5osrxjY
UW31uL3BTr/cYuV5LMZhtStcp+h+ZONepW3S9t3mFFDYZJMLF9njAT/CajVd6SIF
MVuh5qhwpVdpoY4hEuoi2MbyafyvJmQ+TcT/ryOKVN/HizfgVj6yvhcO52678rzK
O8V+4lnpE2BhNVidpAFa06Q6Irupal8CggEAVnyezf7hb0MK2zlKYc9FeRnt8iqe
+LTzTn9dCpKap7+dh2kKefx55+zY4SzmPRD7p0mofUlMUPAfuXZQcHux8QpV8qOj
iSAuUYqr7wOlQa7ok0AEc6+OuSwrdS5ztpx9H8S1ulh8Sk+FyEjfR9+9lSuE8Zwx
65EGSILsE/YBtdfO4UVl/6V3ZI8kBAUSKOGJr7qNwIPUUPEO/uo3zSp1ZKR87O5I
sMxkIDGm1b1YX3BHbuF55yApF6w9hBrkHx3s6J8DrbYjML/R31dZaBMzPXd/fdZl
6mWz6D9w9b62peOJ7hhZqMWWhvPzM6tw9UGBpb/XeCVA4udl6lrDgXZFcA==
-----END RSA PRIVATE KEY-----
PPK;
static $client_public_key_1 = <<<PPK
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAkjiUI6n3Fq140AipaLxN
IPCzEItQFcY8G5Xd17u7InM3H542+34PdBpwR66miQUgJK+rtfaot/v4QPj4/0Bn
Yc78BhI0Mp3tVEH95jjIrhDMZoRFfSQsAhiom5NTP1B5XiiyRjzkO1+7a29JST5t
IQUIS2U345DMWyf3GNlC1cBAfgI+PrRo3gLby/iW5EF/Mqq0ZUIOuggZ7r8kU2aU
hXILFx2w9V/y90DwruJdzZ0TesbsFit2nM3Axie7HX2wIpbl2hyvvhX/AxZ0NPud
Vh58wNogsKOMUN6guU+RzL5L6vF+QjfzBCtOE+CRmUD60E0LdQHzElBcF0tbc2cj
2YelZ0Dp+4NEBDjCNsSv//5hHacUxxXQdwwotLUV85iErEZgcGyMNnTMsw7JIh39
UBgOEmQgfpfOUlH+/5WmRO+kskvPCACz1SR8gzAKz9Nu9r3UyE+gWaZzM2+CpQ1s
zEd94MIapHxJw9vHogL7sNkjmZ34Y9eQmoCVevqDVpYEdTtLsg9H49+pEndQHI6l
GAB7QlsPLN8A17L2l3p68BFcYkSZR4GuXAyQguq3KzWYDZ9PjWAV5lhVg6K3GaV7
fvn2pKCk4P5Y5hZt08fholt3k/5Gc82CP6rfgQFi7HnpBJKRauoIdsvUPvXZYTLl
TaE5jLBAwxm+wF6Ue/nRPJMCAwEAAQ==
-----END PUBLIC KEY-----
PPK;
static $client_private_key_2 = <<<PPK
-----BEGIN RSA PRIVATE KEY-----
MIIJJwIBAAKCAgBHhlSRoBMo9uYJyHPr0g54EzzKrpjNBUDqnTztggsIfXR3A73T
olGmeXTECu+QIAyEtGGDylp4cJhyworIwzdAfMCY9Xux5B+Vo0Kyte2JMvwzanNL
hiT21rVw56ZfyxkCJKUxz3wba0kIWQyW+kvwLhvbQzmexHnQs15qsfP4o2MEFVTC
H2ohQ57OJ8BOSU8XfddCWommmFAQcQwGXYh9woky4NOpGBqbnGBXgWF2rnbD0GYL
1Sd3OSrgTHG3WrG95UizOcV9uijI8vWxczVlP7sriaY7Xetcbh+Z5AbAf9TMOucc
RFaM/KlovR7sOcQDO1NzqlL/PRzCfzcNId22Q6uV3QE2hzRKfd+lKI1YmFrVJ0Sn
WlSdeX7kkWn/+eQ4WfkK9hmv4/0bzQYo1XCopEpjefZoWiErCAt4nEt2wr6f6BmS
jTGVajGlhn7q8wwBBHfjAUfCgIAk8uGNGWkegvytTYywLnyNEF8tHcdg+We+W6it
qJ5bQNFHa9uxX+haURoTOcGqxN8n2LPcLoLU7xqZY23wpeXO7anzqheGSQUHb56r
WqcCRQ9jF/1RLCyyVd9eOEZF6Ke53qpLQxibhqnZfba0zOKqhbxod6RSOswSF3ww
HoIj+6SRNKgui4DDcMMc+bsndr/KUDxaYpiuIn2KVE6kd5a0t8BHgdu/yQIDAQAB
AoICADyfO3COZ47x7Tnff3kh+geF7qGvaG1lBYeVK/32mdlhU+RH9I2650+dY/2B
c1kKAPI9XOVyDkpEzMF/6FePNnZfBnLepi+5tZeD39VO43zFDQObNwuNMClTBEgk
31wT7Sdm3ekg/gTTYvxDVatljBWPTycBjIXn64Obc+wk1i8odJUSa1t5et+ky6Xa
BWGVOwcjLt7blA3yzPGSj2mZv0UwLE9GRb/tYSgBW5rvWydXaew/5y4iRSgE+TVR
NZT9tubHvl3CGoSc01K2ss3rYxdk9ARLz+xDh2g5Immx3pMsBbXwOtA3j9BBmmje
2qXHtD40+19uvpf9OTIU1xk3Wg3rXIWzi8cE8uSo9L9JiiSNyTb7XA3wLUAYWFtO
g5UU3OeHLBtxhBa/gEn71RKZ6gUNUiwk7eygCbO/N71NZNY9L2NDOLLsBUjVTdei
ggnmsg7HIi9ydHKjCQPg+DdbqmZFWNXearNDdqWHumUvRt2xkB/t4N4znd8LAsqV
R2Cfr/pr9VMCbWUHdgq0AnyaFr8oRxXkNhekg1jR/INz3UwCfAa9OIyPYdIEm4zy
/a2n0ZcM4IcGlc/KZSE1R5MxQgP5T2cn+LFZ1XiAWl8ToMcqZQ/o00PlVE7LScZS
yrYul1UKwQCyHursJegnJveK8dR/Mh24bubYi2S0Gg2l4ILxAoIBAQCIGDm/zupU
5r+V7uccuL4r5NNdMr3Bmo9dZElbrjI5/5VuqQUhfUbDpSJ3B8aXA30ZQO/utW/u
Q9cpvdcsx+66qfBdeCAKlebeDNvZtWCVJ786MVsJgVpyNBwd9KwJ7vDqp6cXQsgb
7cjDbWVXB+uY1MWFnsmUxGM++wWlxE8Jc9h/ssYgi8kl6HdgC3INJdWHlOQhZhGp
5LADaEiNlSailH5aNkinxRYTmQkoiKbde1vpHisHu+PKZkezrTpfySfsVfZlCdOx
GdfMj7eOmWTjXEToWAW9DP4obY86pYkLHQxAvRjFj/U5C8X/ndwQJZa+nO7obwxq
5jeVuSyuY1rlAoIBAQCGionYkOOIsY2sBB3DX/5DMhW7sfsXFmc3aJBwn8xm24Xv
Re1G7EdDcFVX+HbUvcNDzusobvsvzpSqzaPFh7Vj8E/MITt6l7bi8Oc5cSXuLTvV
tbtkvT5yOYMymfxByqo3OeMexJBv5yS45jL3nSIKYzD2AD/Hh+cuavHrGXaOSp0J
jXdOYkePyW0ri0e0iUSO1oxzd+xbJ+Wb3F8d2f/mjkie1pElSZDpQBvc3toAKe4A
zV4OAO5vG0rTerc1M5meW8siTIq/g6nNrLlAiPxJa6uyoa4xELIchxFBqDzQM2ZJ
MQN7+DgYAmQkv42ZsHV7P/rqefYdqrL5ZNVRXG8VAoIBACqdu2euuX5Ai3m9x60c
xKAmFXG3s+fuKDqMbtRApgW3XOm8D5k/C2u0SCiRzMP5GbFQvlE3i4dGwxeVFM43
BTB6ioQaW5409ohN6oIv48CRI7ZrQiCl2tasLqnKthyeL96rBQ2podPtD9LybKtm
FYZUCk4fPOxS2ukb3dbctAs3tXG3X4dNfn1aYBc5PkuTr1u3agBzX9CdhehrPVzo
eaKrcS16liHC+3jDkTSaJfZw7IUBJ2RSl7AHeyhudDsOWGwPNwrImvt4JjUuQ8Jp
kkgH2qQO/C0I5oVuWU16DIHoZK/ZBurGe3mTkDrNCd4chynFJqKuM2s+D+XYiH9L
KWkCggEBAIKYcau9IJAsQSerKzTdthKFyGDUJ7XGclRvdF1OT/u7tOuIhgTlD1uf
68ejj717odHtRYiPCdXjAZ42VHVGAMXMm7i6vWCHaegqDVhNw5LJZ55PdGIZ7Ea2
GusAW8OFNOq8jwDrroRg6t1r3idK6KMKm5j+rupAuh/tgXxC0DjYpkyCfD+i2HHz
BLxSyzysTdcU3WqsCsqFFLTRGacBWAv1Kvq7rlJycW5oY2NnElc8XCF9N4ICV2+U
H3LeWH4U41W7JpfZkojKBgZ2VbAWCEZAdH7FwC8yVKGqXg7MfpNegTgkkoxAajqr
/4dIROvdRHxpo2b9EfDEJEw/G22Jeu0CggEAY5RvSLR91s+QR8sg8/y3GEUPfdEB
bUzdAf7TaJAzER4rhlWliC//aNHEC9JO+wCNMbCdV56F6ajDbrGXYiSDfZrB2nnA
XgPCIPgyy92NDMzSKGvCHwNXvJRrG5OmK02qLP4akmz2ZyAw+xWaudNxoZR5aqlN
bgZP149ecpJTiQVkfT4U2IID2Lj7nSaAn0BS9c6dKfh28yFO+wB8a1A5YFKWRgf0
SzdaPvasTSwmstL2Q7fm2d+PsRchnc+u8B+TlDVkHPI0K2ALC92Mhl7Tw4KwENds
pedgcMaklTsqGgEkbCKQ9VlJUWQuhkSRGhYzg4qucl1uoU2VU2d2X/qOWg==
-----END RSA PRIVATE KEY-----
PPK;
static $client_public_key_2 = <<<PPK
-----BEGIN PUBLIC KEY-----
MIICITANBgkqhkiG9w0BAQEFAAOCAg4AMIICCQKCAgBHhlSRoBMo9uYJyHPr0g54
EzzKrpjNBUDqnTztggsIfXR3A73TolGmeXTECu+QIAyEtGGDylp4cJhyworIwzdA
fMCY9Xux5B+Vo0Kyte2JMvwzanNLhiT21rVw56ZfyxkCJKUxz3wba0kIWQyW+kvw
LhvbQzmexHnQs15qsfP4o2MEFVTCH2ohQ57OJ8BOSU8XfddCWommmFAQcQwGXYh9
woky4NOpGBqbnGBXgWF2rnbD0GYL1Sd3OSrgTHG3WrG95UizOcV9uijI8vWxczVl
P7sriaY7Xetcbh+Z5AbAf9TMOuccRFaM/KlovR7sOcQDO1NzqlL/PRzCfzcNId22
Q6uV3QE2hzRKfd+lKI1YmFrVJ0SnWlSdeX7kkWn/+eQ4WfkK9hmv4/0bzQYo1XCo
pEpjefZoWiErCAt4nEt2wr6f6BmSjTGVajGlhn7q8wwBBHfjAUfCgIAk8uGNGWke
gvytTYywLnyNEF8tHcdg+We+W6itqJ5bQNFHa9uxX+haURoTOcGqxN8n2LPcLoLU
7xqZY23wpeXO7anzqheGSQUHb56rWqcCRQ9jF/1RLCyyVd9eOEZF6Ke53qpLQxib
hqnZfba0zOKqhbxod6RSOswSF3wwHoIj+6SRNKgui4DDcMMc+bsndr/KUDxaYpiu
In2KVE6kd5a0t8BHgdu/yQIDAQAB
-----END PUBLIC KEY-----
PPK;
public function run()
{
Eloquent::unguard();
$member_table = <<<SQL
CREATE TABLE Member
(
ID integer primary key,
FirstName varchar(50),
Surname varchar(50),
Email varchar(254),
Password varchar(254),
PasswordEncryption varchar(50),
Salt varchar(50),
Locale varchar(6),
Address varchar(255),
City varchar(64),
Suburb varchar(64),
State varchar(64),
Postcode varchar(64),
Country varchar(2),
Gender varchar(32)
);
SQL;
DB::connection('os_members')->statement($member_table);
Member::create(
array(
'ID' => 1,
'FirstName' => 'Sebastian',
'Surname' => 'Marcet',
'Email' => 'sebastian@tipit.net',
'Password' => '1qaz2wsx',
'PasswordEncryption' => 'none',
'Salt' => 'none',
'Gender' => 'male',
'Address' => 'Av. Siempre Viva 111',
'Suburb' => 'Lanus Este',
'State' => 'Buenos Aires',
'City' => 'Lanus',
'Postcode' => '1824',
'Country' => 'AR',
'Locale' => 'ESP',
)
);
Member::create(
array(
'ID' => 2,
'FirstName' => 'Sebastian',
'Surname' => 'Marcet',
'Email' => 'sebastian+1@tipit.net',
'Password' => '1qaz2wsx',
'PasswordEncryption' => 'none',
'Salt' => 'none',
'Gender' => 'male',
'Address' => 'Av. Siempre Viva 111',
'Suburb' => 'Lanus Este',
'State' => 'Buenos Aires',
'City' => 'Lanus',
'Postcode' => '1824',
'Country' => 'AR',
'Locale' => 'ESP',
)
);
Member::create(
array(
'ID' => 3,
'FirstName' => 'Sebastian',
'Surname' => 'Marcet',
'Email' => 'sebastian+2@tipit.net',
'Password' => '1qaz2wsx',
'PasswordEncryption' => 'none',
'Salt' => 'none',
'Gender' => 'male',
'Address' => 'Av. Siempre Viva 111',
'Suburb' => 'Lanus Este',
'State' => 'Buenos Aires',
'City' => 'Lanus',
'Postcode' => '1824',
'Country' => 'AR',
'Locale' => 'ESP',
)
);
DB::table('banned_ips')->delete();
DB::table('user_exceptions_trail')->delete();
DB::table('server_configuration')->delete();
@ -23,10 +254,12 @@ class TestSeeder extends Seeder {
DB::table('oauth2_client_authorized_uri')->delete();
DB::table('oauth2_access_token')->delete();
DB::table('oauth2_refresh_token')->delete();
DB::table('oauth2_assymetric_keys')->delete();
DB::table('oauth2_client')->delete();
DB::table('openid_trusted_sites')->delete();
DB::table('openid_associations')->delete();
DB::table('user_actions')->delete();
DB::table('openid_users')->delete();
DB::table('oauth2_api_endpoint_api_scope')->delete();
@ -53,6 +286,31 @@ class TestSeeder extends Seeder {
$this->seedApis();
//scopes
ApiScope::create(
array(
'name' => OAuth2Protocol::OpenIdConnect_Scope,
'short_description' => 'OIDC',
'description' => 'OIDC',
'api_id' => null,
'system' => true,
'default' => true,
'active' => true,
)
);
ApiScope::create(
array(
'name' => OAuth2Protocol::OfflineAccess_Scope,
'short_description' => 'allow to emit refresh tokens (offline access without user presence)',
'description' => 'allow to emit refresh tokens (offline access without user presence)',
'api_id' => null,
'system' => true,
'default' => true,
'active' => true,
)
);
$this->seedResourceServerScopes();
$this->seedApiScopes();
$this->seedApiEndpointScopes();
@ -308,7 +566,7 @@ class TestSeeder extends Seeder {
User::create(
array(
'identifier' => 'sebastian.marcet',
'external_identifier' => 13867,
'external_identifier' => 1,
'last_login_date' => gmdate("Y-m-d H:i:s", time())
)
);
@ -323,18 +581,72 @@ class TestSeeder extends Seeder {
)
);
$now = new \DateTime();
Client::create(
array(
'app_name' => 'oauth2_test_app',
'app_description' => 'oauth2_test_app',
'app_logo' => null,
'client_id' => 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client',
'client_secret' => 'ITc/6Y5N7kOtGKhg',
'client_secret' => 'ITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhg',
'client_type' => IClient::ClientType_Confidential,
'application_type' => IClient::ApplicationType_Web_App,
'token_endpoint_auth_method' => OAuth2Protocol::TokenEndpoint_AuthMethod_ClientSecretBasic,
'user_id' => $user->id,
'rotate_refresh_token' => true,
'use_refresh_token' => true
'use_refresh_token' => true,
'redirect_uris' => 'https://www.test.com/oauth2,https://op.certification.openid.net:60393/authz_cb',
'id_token_signed_response_alg' => JSONWebSignatureAndEncryptionAlgorithms::HS512,
'id_token_encrypted_response_alg' => JSONWebSignatureAndEncryptionAlgorithms::RSA_OAEP_256,
'id_token_encrypted_response_enc' => JSONWebSignatureAndEncryptionAlgorithms::A256CBC_HS512,
'client_secret_expires_at' => $now->add(new \DateInterval('P6M')),
)
);
Client::create(
array
(
'app_name' => 'oauth2_test_app2',
'app_description' => 'oauth2_test_app2',
'app_logo' => null,
'client_id' => 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x2.openstack.client',
'client_secret' => 'ITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhg',
'client_type' => IClient::ClientType_Confidential,
'application_type' => IClient::ApplicationType_Web_App,
'token_endpoint_auth_method' => OAuth2Protocol::TokenEndpoint_AuthMethod_ClientSecretJwt,
'token_endpoint_auth_signing_alg' => JSONWebSignatureAndEncryptionAlgorithms::HS512,
'subject_type' => IClient::SubjectType_Pairwise,
'user_id' => $user->id,
'rotate_refresh_token' => true,
'use_refresh_token' => true,
'redirect_uris' => 'https://www.test.com/oauth2',
'id_token_signed_response_alg' => JSONWebSignatureAndEncryptionAlgorithms::HS512,
'id_token_encrypted_response_alg' => JSONWebSignatureAndEncryptionAlgorithms::RSA_OAEP_256,
'id_token_encrypted_response_enc' => JSONWebSignatureAndEncryptionAlgorithms::A256CBC_HS512,
'client_secret_expires_at' => $now->add(new \DateInterval('P6M')),
)
);
Client::create
(
array(
'app_name' => 'oauth2_test_app3',
'app_description' => 'oauth2_test_app3',
'app_logo' => null,
'client_id' => 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ33.openstack.client',
'client_secret' => 'ITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N7kOtGKhgITc/6Y5N585OtGKhg55',
'client_type' => IClient::ClientType_Confidential,
'application_type' => IClient::ApplicationType_Web_App,
'token_endpoint_auth_method' => OAuth2Protocol::TokenEndpoint_AuthMethod_ClientSecretBasic,
'user_id' => $user->id,
'rotate_refresh_token' => true,
'use_refresh_token' => true,
'redirect_uris' => 'https://www.test.com/oauth2',
'id_token_signed_response_alg' => JSONWebSignatureAndEncryptionAlgorithms::HS512,
'userinfo_signed_response_alg' => JSONWebSignatureAndEncryptionAlgorithms::RS512,
'client_secret_expires_at' => $now->add(new \DateInterval('P6M')),
)
);
@ -344,12 +656,15 @@ class TestSeeder extends Seeder {
'app_description' => 'oauth2.service',
'app_logo' => null,
'client_id' => '11z87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client',
'client_secret' => '11c/6Y5N7kOtGKhg',
'client_secret' => '11c/6Y5N7kOtGKhg11c/6Y5N7kOtGKhg11c/6Y5N7kOtGKhg11c/6Y5N7kOtGKhg',
'client_type' => IClient::ClientType_Confidential,
'application_type' => IClient::ApplicationType_Service,
'token_endpoint_auth_method' => OAuth2Protocol::TokenEndpoint_AuthMethod_ClientSecretBasic,
'user_id' => $user->id,
'rotate_refresh_token' => true,
'use_refresh_token' => true
'use_refresh_token' => true,
'redirect_uris' => 'https://www.test.com/oauth2',
'client_secret_expires_at' => $now->add(new \DateInterval('P6M')),
)
);
@ -360,11 +675,49 @@ class TestSeeder extends Seeder {
'app_logo' => null,
'client_id' => 'Jiz87D8/Vcvr6fvQbH4HyNgwKlfSyQ3x.openstack.client',
'client_secret' => null,
'client_type' => IClient::ClientType_Public,
'application_type' => IClient::ApplicationType_JS_Client,
'token_endpoint_auth_method' => OAuth2Protocol::TokenEndpoint_AuthMethod_PrivateKeyJwt,
'token_endpoint_auth_signing_alg' => JSONWebSignatureAndEncryptionAlgorithms::RS512,
'user_id' => $user->id,
'rotate_refresh_token' => false,
'use_refresh_token' => false
'use_refresh_token' => false,
'redirect_uris' => 'https://www.test.com/oauth2',
)
);
Client::create(
array(
'app_name' => 'oauth2_native_app',
'app_description' => 'oauth2_native_app',
'app_logo' => null,
'client_id' => 'Jiz87D8/Vcvr6fvQbH4HyNgwKlfSyQ3x.android.openstack.client',
'client_secret' => '11c/6Y5N7kOtGKhg11c/6Y5N7kOtGKhg11c/6Y5N7kOtGKhg11c/6Y5N7kOtGKhgfdfdfdf',
'client_type' => IClient::ClientType_Confidential,
'application_type' => IClient::ApplicationType_Native,
'token_endpoint_auth_method' => OAuth2Protocol::TokenEndpoint_AuthMethod_ClientSecretBasic,
'user_id' => $user->id,
'rotate_refresh_token' => true,
'use_refresh_token' => true,
'redirect_uris' => 'androipapp://oidc_endpoint_callback',
)
);
Client::create(
array(
'app_name' => 'oauth2_native_app2',
'app_description' => 'oauth2_native_app2',
'app_logo' => null,
'client_id' => 'Jiz87D8/Vcvr6fvQbH4HyNgwKlfSyQ3x.android2.openstack.client',
'client_secret' => '11c/6Y5N7kOtGKhg11c/6Y5N7kOtGKhg11c/6Y5N7kOtGKhg11c/6Y5N7kOtGKhgfdfdfdf',
'client_type' => IClient::ClientType_Confidential,
'application_type' => IClient::ApplicationType_Native,
'token_endpoint_auth_method' => OAuth2Protocol::TokenEndpoint_AuthMethod_PrivateKeyJwt,
'token_endpoint_auth_signing_alg' => JSONWebSignatureAndEncryptionAlgorithms::RS512,
'user_id' => $user->id,
'rotate_refresh_token' => true,
'use_refresh_token' => true,
'redirect_uris' => 'androipapp://oidc_endpoint_callback2',
)
);
@ -379,7 +732,8 @@ class TestSeeder extends Seeder {
'application_type' => IClient::ApplicationType_JS_Client,
'user_id' => $user->id,
'rotate_refresh_token' => false,
'use_refresh_token' => false
'use_refresh_token' => false,
'redirect_uris' => 'https://www.test.com/oauth2'
)
);
@ -389,47 +743,158 @@ class TestSeeder extends Seeder {
'app_description' => 'resource_server_client',
'app_logo' => null,
'client_id' => 'resource.server.1.openstack.client',
'client_secret' => '123456789',
'client_secret' => '123456789123456789123456789123456789123456789',
'client_type' => IClient::ClientType_Confidential,
'application_type' => IClient::ApplicationType_Service,
'token_endpoint_auth_method' => OAuth2Protocol::TokenEndpoint_AuthMethod_ClientSecretBasic,
'resource_server_id' => $resource_server->id,
'rotate_refresh_token' => false,
'use_refresh_token' => false
'use_refresh_token' => false,
'client_secret_expires_at' => $now->add(new \DateInterval('P6M')),
)
);
$client_confidential = Client::where('app_name','=','oauth2_test_app')->first();
$client_public = Client::where('app_name','=','oauth2_test_app_public')->first();
$client_service = Client::where('app_name','=','oauth2.service')->first();
//attach scopes
$client_confidential = Client::where('app_name','=','oauth2_test_app')->first();
$client_confidential2 = Client::where('app_name','=','oauth2_test_app2')->first();
$client_confidential3 = Client::where('app_name','=','oauth2_test_app3')->first();
$client_public = Client::where('app_name','=','oauth2_test_app_public')->first();
$client_service = Client::where('app_name','=','oauth2.service')->first();
$client_native = Client::where('app_name','=','oauth2_native_app')->first();
$client_native2 = Client::where('app_name','=','oauth2_native_app2')->first();
//attach all scopes
$scopes = ApiScope::get();
foreach($scopes as $scope){
foreach($scopes as $scope)
{
$client_confidential->scopes()->attach($scope->id);
$client_confidential2->scopes()->attach($scope->id);
$client_confidential3->scopes()->attach($scope->id);
$client_public->scopes()->attach($scope->id);
$client_service->scopes()->attach($scope->id);
$client_native->scopes()->attach($scope->id);
$client_native2->scopes()->attach($scope->id);
}
//add uris
ClientAuthorizedUri::create(
array(
'uri' => 'https://www.test.com/oauth2',
'client_id' => $client_confidential->id
)
$now = new \DateTime('now');
$to = new \DateTime('now');
$to->add(new \DateInterval('P31D'));
$public_key_1 = ClientPublicKey::buildFromPEM(
'public_key_1',
JSONWebKeyTypes::RSA,
JSONWebKeyPublicKeyUseValues::Encryption,
self::$client_public_key_1,
JSONWebSignatureAndEncryptionAlgorithms::RSA_OAEP_256,
true,
$now,
$to
);
//add uris
ClientAllowedOrigin::create(
array(
'allowed_origin' => 'https://www.test.com/oauth2',
'client_id' => $client_confidential->id
)
$public_key_1->oauth2_client_id = $client_confidential->id;
$public_key_1->save();
$public_key_2 = ClientPublicKey::buildFromPEM(
'public_key_2',
JSONWebKeyTypes::RSA,
JSONWebKeyPublicKeyUseValues::Signature,
self::$client_public_key_2,
JSONWebSignatureAndEncryptionAlgorithms::RS512,
true,
$now,
$to
);
ClientAuthorizedUri::create(
array(
'uri'=>'https://www.test.com/oauth2',
'client_id'=>$client_public->id
)
$public_key_2->oauth2_client_id = $client_confidential->id;
$public_key_2->save();
// confidential client 2
$public_key_11 = ClientPublicKey::buildFromPEM(
'public_key_1',
JSONWebKeyTypes::RSA,
JSONWebKeyPublicKeyUseValues::Encryption,
self::$client_public_key_1,
JSONWebSignatureAndEncryptionAlgorithms::RSA_OAEP_256,
true,
$now,
$to
);
$public_key_11->oauth2_client_id = $client_confidential2->id;
$public_key_11->save();
$public_key_22 = ClientPublicKey::buildFromPEM(
'public_key_2',
JSONWebKeyTypes::RSA,
JSONWebKeyPublicKeyUseValues::Signature,
self::$client_public_key_2,
JSONWebSignatureAndEncryptionAlgorithms::RS512,
true,
$now,
$to
);
$public_key_22->oauth2_client_id = $client_confidential2->id;
$public_key_22->save();
// public native client
$public_key_33 = ClientPublicKey::buildFromPEM(
'public_key_33',
JSONWebKeyTypes::RSA,
JSONWebKeyPublicKeyUseValues::Encryption,
self::$client_public_key_1,
JSONWebSignatureAndEncryptionAlgorithms::RSA_OAEP_256,
true,
$now,
$to
);
$public_key_33->oauth2_client_id = $client_native2->id;
$public_key_33->save();
$public_key_44 = ClientPublicKey::buildFromPEM(
'public_key_44',
JSONWebKeyTypes::RSA,
JSONWebKeyPublicKeyUseValues::Signature,
self::$client_public_key_2,
JSONWebSignatureAndEncryptionAlgorithms::RS512,
true,
$now,
$to
);
$public_key_44->oauth2_client_id = $client_native2->id;
$public_key_44->save();
// server private keys
$pkey_1 = ServerPrivateKey::build
(
'server_key_enc',
$now,
$to,
JSONWebKeyTypes::RSA,
JSONWebKeyPublicKeyUseValues::Encryption,
JSONWebSignatureAndEncryptionAlgorithms::RSA1_5,
true,
TestKeys::$private_key_pem
);
$pkey_1->save();
$pkey_2 = ServerPrivateKey::build
(
'server_key_sig',
$now,
$to,
JSONWebKeyTypes::RSA,
JSONWebKeyPublicKeyUseValues::Signature,
JSONWebSignatureAndEncryptionAlgorithms::RS512,
true,
TestKeys::$private_key_pem
);
$pkey_2->save();
}
private function seedApis(){
@ -442,7 +907,7 @@ class TestSeeder extends Seeder {
'active' => true,
'Description' => 'Resource Server CRUD operations',
'resource_server_id' => $resource_server->id,
'logo' => asset('img/apis/server.png')
'logo' => asset('/assets/img/apis/server.png')
)
);
@ -453,7 +918,7 @@ class TestSeeder extends Seeder {
'active' => true,
'Description' => 'Api CRUD operations',
'resource_server_id' => $resource_server->id,
'logo' => asset('img/apis/server.png')
'logo' => asset('/assets/img/apis/server.png')
)
);
@ -465,7 +930,7 @@ class TestSeeder extends Seeder {
'active' => true,
'Description' => 'Api Endpoints CRUD operations',
'resource_server_id' => $resource_server->id,
'logo' => asset('img/apis/server.png')
'logo' => asset('/assets/img/apis/server.png')
)
);
@ -476,7 +941,7 @@ class TestSeeder extends Seeder {
'active' => true,
'Description' => 'Api Scopes CRUD operations',
'resource_server_id' => $resource_server->id,
'logo' => asset('img/apis/server.png')
'logo' => asset('/assets/img/apis/server.png')
)
);
@ -487,7 +952,7 @@ class TestSeeder extends Seeder {
'active' => true,
'Description' => 'User Info',
'resource_server_id' => $resource_server->id,
'logo' => asset('img/apis/server.png')
'logo' => asset('/assets/img/apis/server.png')
)
);
@ -498,7 +963,7 @@ class TestSeeder extends Seeder {
'active' => true,
'Description' => 'Marketplace Public Clouds',
'resource_server_id' => $resource_server->id,
'logo' => asset('img/apis/server.png')
'logo' => asset('/assets/img/apis/server.png')
)
);
@ -509,7 +974,7 @@ class TestSeeder extends Seeder {
'active' => true,
'Description' => 'Marketplace Private Clouds',
'resource_server_id' => $resource_server->id,
'logo' => asset('img/apis/server.png')
'logo' => asset('/assets/img/apis/server.png')
)
);
@ -520,7 +985,7 @@ class TestSeeder extends Seeder {
'active' => true,
'Description' => 'Marketplace Consultants',
'resource_server_id' => $resource_server->id,
'logo' => asset('img/apis/server.png')
'logo' => asset('/assets/img/apis/server.png')
)
);
@ -667,6 +1132,7 @@ class TestSeeder extends Seeder {
)
);
}
private function seedApiEndpointScopes(){
@ -1363,6 +1829,27 @@ class TestSeeder extends Seeder {
'http_method' => 'GET'
)
);
ApiEndpoint::create(
array(
'name' => 'get-user-claims-get',
'active' => true,
'api_id' => $users->id,
'route' => '/api/v1/users/info',
'http_method' => 'GET'
)
);
ApiEndpoint::create(
array(
'name' => 'get-user-claims-post',
'active' => true,
'api_id' => $users->id,
'route' => '/api/v1/users/info',
'http_method' => 'POST'
)
);
$profile_scope = ApiScope::where('name','=','profile')->first();
$email_scope = ApiScope::where('name','=','email')->first();
$address_scope = ApiScope::where('name','=','address')->first();
@ -1371,6 +1858,16 @@ class TestSeeder extends Seeder {
$get_user_info_endpoint->scopes()->attach($profile_scope->id);
$get_user_info_endpoint->scopes()->attach($email_scope->id);
$get_user_info_endpoint->scopes()->attach($address_scope->id);
$get_user_info_endpoint = ApiEndpoint::where('name','=','get-user-claims-get')->first();
$get_user_info_endpoint->scopes()->attach($profile_scope->id);
$get_user_info_endpoint->scopes()->attach($email_scope->id);
$get_user_info_endpoint->scopes()->attach($address_scope->id);
$get_user_info_endpoint = ApiEndpoint::where('name','=','get-user-claims-post')->first();
$get_user_info_endpoint->scopes()->attach($profile_scope->id);
$get_user_info_endpoint->scopes()->attach($email_scope->id);
$get_user_info_endpoint->scopes()->attach($address_scope->id);
}
private function seedPublicCloudsEndpoints(){

View File

@ -1,4 +1,5 @@
<?php
use openid\exceptions\InvalidOpenIdMessageException;
use openid\requests\OpenIdAuthenticationRequest;
use openid\services\OpenIdServiceCatalog;
@ -6,6 +7,9 @@ use utils\services\ServiceLocator;
use utils\services\UtilsServiceCatalog;
use oauth2\services\OAuth2ServiceCatalog;
use oauth2\exceptions\InvalidAuthorizationRequestException;
use oauth2\strategies\ClientAuthContextValidatorFactory;
use services\oauth2\HttpIClientJWKSetReader;
/*
|--------------------------------------------------------------------------
| Application & Route Filters
@ -19,15 +23,30 @@ use oauth2\exceptions\InvalidAuthorizationRequestException;
//SAP (single access point)
App::before(function($request){
try {
//checkpoint security pattern entry point
$checkpoint_service = ServiceLocator::getInstance()->getService(UtilsServiceCatalog::CheckPointService);
if (!$checkpoint_service->check()) {
return View::make('404');
ClientAuthContextValidatorFactory::setTokenEndpointUrl
(
URL::action("OAuth2ProviderController@token")
);
ClientAuthContextValidatorFactory::setJWKSetReader
(
App::make('oauth2\services\IClientJWKSetReader')
);
if(Config::get('server.Banning_Enable', true))
{
try {
//checkpoint security pattern entry point
$checkpoint_service = ServiceLocator::getInstance()->getService(UtilsServiceCatalog::CheckPointService);
if (!$checkpoint_service->check()) {
return Response::view('404', array(), 404);
}
} catch (Exception $ex) {
Log::error($ex);
return Response::view('404', array(), 404);
}
} catch (Exception $ex) {
Log::error($ex);
return View::make('404');
}
$cors = ServiceLocator::getInstance()->getService('CORSMiddleware');
@ -39,15 +58,6 @@ App::after(function($request, $response){
// https://www.owasp.org/index.php/List_of_useful_HTTP_headers
$response->headers->set('X-content-type-options','nosniff');
$response->headers->set('X-xss-protection','1; mode=block');
// http://tools.ietf.org/html/rfc6797
/**
* The HSTS header field below stipulates that the HSTS Policy is to
* remain in effect for one year (there are approximately 31536000
* seconds in a year)
* applies to the domain of the issuing HSTS Host and all of its
* subdomains:
*/
$response->headers->set('Strict-Transport-Security','max-age=31536000; includeSubDomains');
//cache
$response->headers->set('pragma','no-cache');
$response->headers->set('Expires','-1');
@ -70,11 +80,13 @@ App::after(function($request, $response){
Route::filter('auth', function () {
if (Auth::guest()) {
Session::put('url.intended', URL::full());
Session::save();
return Redirect::action('HomeController@index');
}
$redirect = Session::get('url.intended');
if (!empty($redirect)) {
Session::forget('url.intended');
Session::save();
return Redirect::to($redirect);
}
});
@ -120,57 +132,15 @@ Route::filter('ajax', function()
if (!Request::ajax()) App::abort(404);
});
Route::filter("openid.needs.auth.request", function () {
$memento_service = ServiceLocator::getInstance()->getService(OpenIdServiceCatalog::MementoService);
$openid_message = $memento_service->getCurrentRequest();
if ($openid_message == null || !$openid_message->isValid())
throw new InvalidOpenIdMessageException();
$configuration_service = ServiceLocator::getInstance()->getService(OpenIdServiceCatalog::ServerConfigurationService);
$auth_request = new OpenIdAuthenticationRequest($openid_message, $configuration_service->getUserIdentityEndpointURL('@identifier'));
if (!$auth_request->isValid())
throw new InvalidOpenIdMessageException();
});
Route::filter("openid.save.request", function () {
$memento_service = ServiceLocator::getInstance()->getService(OpenIdServiceCatalog::MementoService);
$memento_service->saveCurrentRequest();
});
Route::filter("oauth2.save.request", function () {
$memento_service = ServiceLocator::getInstance()->getService(OAuth2ServiceCatalog::MementoService);
$memento_service->saveCurrentAuthorizationRequest();
});
Route::filter("oauth2.needs.auth.request", function () {
$memento_service = ServiceLocator::getInstance()->getService(OAuth2ServiceCatalog::MementoService);
$oauth2_message = $memento_service->getCurrentAuthorizationRequest();
if ($oauth2_message == null || !$oauth2_message->isValid())
throw new InvalidAuthorizationRequestException();
});
Route::filter("ssl", function () {
if ((!Request::secure()) && (ServerConfigurationService::getConfigValue("SSL.Enable"))) {
$openid_memento_service = ServiceLocator::getInstance()->getService(OpenIdServiceCatalog::MementoService);
$openid_memento_service->saveCurrentRequest();
$oauth2_memento_service = ServiceLocator::getInstance()->getService(OAuth2ServiceCatalog::MementoService);
$oauth2_memento_service->saveCurrentAuthorizationRequest();
return Redirect::secure(Request::getRequestUri());
}
});
Route::filter("oauth2.enabled",function(){
if(!ServerConfigurationService::getConfigValue("OAuth2.Enable")){
return View::make('404');
return Response::view('404', array(), 404);
}
});
@ -179,6 +149,13 @@ Route::filter('user.owns.client.policy',function($route, $request){
$authentication_service = ServiceLocator::getInstance()->getService(UtilsServiceCatalog::AuthenticationService);
$client_service = ServiceLocator::getInstance()->getService(OAuth2ServiceCatalog::ClientService);
$client_id = $route->getParameter('id');
if(is_null($client_id))
$client_id = $route->getParameter('client_id');
if(is_null($client_id))
$client_id =Input::get('client_id',null);;
$client = $client_service->getClientByIdentifier($client_id);
$user = $authentication_service->getCurrentUser();
if (is_null($client) || intval($client->getUserId()) !== intval($user->getId()))
@ -215,8 +192,6 @@ Route::filter('is.current.user',function($route, $request){
});
// filter to protect an api endpoint with oauth2
Route::filter('oauth2.protected.endpoint','OAuth2BearerAccessTokenRequestValidator');
@ -235,10 +210,10 @@ Route::filter('oauth2.server.admin.json',function(){
Route::filter('oauth2.server.admin',function(){
if (Auth::guest()) {
return View::make('404');
return Response::view('404', array(), 404);
}
if(!Auth::user()->isOAuth2ServerAdmin()){
return View::make('404');
return Response::view('404', array(), 404);
}
});
@ -257,9 +232,9 @@ Route::filter('openstackid.server.admin.json',function(){
Route::filter('openstackid.server.admin',function(){
if (Auth::guest()) {
return View::make('404');
return Response::view('404', array(), 404);
}
if(!Auth::user()->isOpenstackIdAdmin()){
return View::make('404');
return Response::view('404', array(), 404);
}
});
});

View File

@ -13,6 +13,8 @@ use utils\services\ICheckPointService;
use oauth2\IResourceServerContext;
use oauth2\services\IClientService;
use oauth2\models\IClient;
use utils\http\HttpContentType;
use oauth2\exceptions\RevokedAccessTokenException;
/**
* Class OAuth2BearerAccessTokenRequestValidator
@ -20,8 +22,7 @@ use oauth2\models\IClient;
* http://tools.ietf.org/html/rfc6750
* http://tools.ietf.org/html/rfc6749#section-7
*/
class OAuth2BearerAccessTokenRequestValidator {
final class OAuth2BearerAccessTokenRequestValidator {
protected function getHeaders()
{
@ -49,15 +50,53 @@ class OAuth2BearerAccessTokenRequestValidator {
return $headers;
}
/**
* @var IApiEndpointService
*/
private $api_endpoint_service;
/**
* @var ITokenService
*/
private $token_service;
/**
* @var ILogService
*/
private $log_service;
/**
* @var ICheckPointService
*/
private $checkpoint_service;
/**
* @var IResourceServerContext
*/
private $resource_server_context;
/**
* @var array
*/
private $headers;
/**
* @var IClientService
*/
private $client_service;
public function __construct(IResourceServerContext $resource_server_context, IApiEndpointService $api_endpoint_service, ITokenService $token_service, ILogService $log_service, ICheckPointService $checkpoint_service, IClientService $client_service){
/**
* @param IResourceServerContext $resource_server_context
* @param IApiEndpointService $api_endpoint_service
* @param ITokenService $token_service
* @param ILogService $log_service
* @param ICheckPointService $checkpoint_service
* @param IClientService $client_service
*/
public function __construct
(
IResourceServerContext $resource_server_context,
IApiEndpointService $api_endpoint_service,
ITokenService $token_service,
ILogService $log_service,
ICheckPointService $checkpoint_service,
IClientService $client_service
)
{
$this->api_endpoint_service = $api_endpoint_service;
$this->token_service = $token_service;
$this->log_service = $log_service;
@ -75,7 +114,8 @@ class OAuth2BearerAccessTokenRequestValidator {
{
$url = $route->getPath();
if(strpos($url, '/') != 0){
if(strpos($url, '/') != 0)
{
$url = '/'.$url;
}
$method = $request->getMethod();
@ -83,28 +123,54 @@ class OAuth2BearerAccessTokenRequestValidator {
// http://tools.ietf.org/id/draft-abarth-origin-03.html
$origin = $request->headers->has('Origin') ? $request->headers->get('Origin') : null;
try{
try
{
$endpoint = $this->api_endpoint_service->getApiEndpointByUrlAndMethod($url, $method);
//api endpoint must be registered on db and active
if(is_null($endpoint) || !$endpoint->isActive()){
throw new OAuth2ResourceServerException(400,OAuth2Protocol::OAuth2Protocol_Error_InvalidRequest,sprintf('API endpoint does not exits! (%s:%s)',$url,$method));
if(is_null($endpoint) || !$endpoint->isActive())
{
throw new OAuth2ResourceServerException
(
400,
OAuth2Protocol::OAuth2Protocol_Error_InvalidRequest,
sprintf
(
'API endpoint does not exits! (%s:%s)',
$url,
$method
)
);
}
//check first http basic auth header
$auth_header = isset($this->headers['authorization'])?$this->headers['authorization']:null;
if(!is_null($auth_header) && !empty($auth_header))
$access_token_value = BearerAccessTokenAuthorizationHeaderParser::getInstance()->parse($auth_header);
else{
else
{
// http://tools.ietf.org/html/rfc6750#section-2- 2
// if access token is not on authorization header check on POST/GET params
if($request->headers->get('content-type') !== HttpContentType::Form)
throw new OAuth2ResourceServerException
(
400,
OAuth2Protocol::OAuth2Protocol_Error_InvalidRequest,
'invalid content-type'
);
$access_token_value = Input::get(OAuth2Protocol::OAuth2Protocol_AccessToken, '');
}
if(is_null($access_token_value) || empty($access_token_value))
{
//if access token value is not set, then error
throw new OAuth2ResourceServerException(400,OAuth2Protocol::OAuth2Protocol_Error_InvalidRequest,'missing access token');
throw new OAuth2ResourceServerException
(
400,
OAuth2Protocol::OAuth2Protocol_Error_InvalidRequest,
'missing access token'
);
}
// get access token from service
@ -112,36 +178,68 @@ class OAuth2BearerAccessTokenRequestValidator {
if(is_null($access_token))
throw new ExpiredAccessTokenException(sprintf('Access token %s is expired!', $access_token_value));
//check token audience
$audience = explode(' ',$access_token->getAudience());
if((!in_array($realm,$audience)))
throw new OAuth2ResourceServerException(401,OAuth2Protocol::OAuth2Protocol_Error_InvalidToken,'access token audience does not match');
$audience = explode(' ', $access_token->getAudience());
if((!in_array($realm , $audience)))
throw new OAuth2ResourceServerException
(
401,
OAuth2Protocol::OAuth2Protocol_Error_InvalidToken,
sprintf('access token audience does not match - current_realm %s - access token audience %s',$realm, $access_token->getAudience())
);
//check client existence
$client_id = $access_token->getClientId();
$client = $this->client_service->getClientById($client_id);
if(is_null($client))
throw new OAuth2ResourceServerException(400,OAuth2Protocol::OAuth2Protocol_Error_InvalidRequest, 'invalid client');
throw new OAuth2ResourceServerException
(
400,
OAuth2Protocol::OAuth2Protocol_Error_InvalidRequest,
'invalid client'
);
//if js client , then check if the origin is allowed ....
if($client->getApplicationType() == IClient::ApplicationType_JS_Client){
if($client->getApplicationType() == IClient::ApplicationType_JS_Client)
{
if(!$client->isOriginAllowed($origin))
throw new OAuth2ResourceServerException(403,OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient, 'invalid origin');
throw new OAuth2ResourceServerException
(
403,
OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient,
'invalid origin'
);
}
//check scopes
$endpoint_scopes = explode(' ',$endpoint->getScope());
$token_scopes = explode(' ',$access_token->getScope());
//check token available scopes vs. endpoint scopes
if (count(array_intersect($endpoint_scopes, $token_scopes)) == 0)
{
$this->log_service->error_msg(sprintf('access token scopes (%s) does not allow to access to api url %s , needed scopes %s',$access_token->getScope(),$url,implode(' OR ',$endpoint_scopes) ));
$this->log_service->error_msg
(
sprintf
(
'access token scopes (%s) does not allow to access to api url %s , needed scopes %s',
$access_token->getScope(),
$url,
implode(' OR ',$endpoint_scopes)
)
);
throw new OAuth2ResourceServerException(403,OAuth2Protocol::OAuth2Protocol_Error_InsufficientScope,
throw new OAuth2ResourceServerException
(
403,
OAuth2Protocol::OAuth2Protocol_Error_InsufficientScope,
'the request requires higher privileges than provided by the access token',
implode(' ',$endpoint_scopes));
implode(' ',$endpoint_scopes)
);
}
$context = array(
$context = array
(
'access_token' => $access_token_value,
'expires_in' => $access_token->getRemainingLifetime(),
'client_id' => $client_id,
@ -154,7 +252,8 @@ class OAuth2BearerAccessTokenRequestValidator {
$this->resource_server_context->setAuthorizationContext($context);
}
catch(OAuth2ResourceServerException $ex1){
catch(OAuth2ResourceServerException $ex1)
{
$this->log_service->error($ex1);
$this->checkpoint_service->trackException($ex1);
$response = new OAuth2WWWAuthenticateErrorResponse($realm,
@ -167,7 +266,8 @@ class OAuth2BearerAccessTokenRequestValidator {
$http_response->header('WWW-Authenticate',$response->getWWWAuthenticateHeaderValue());
return $http_response;
}
catch(InvalidGrantTypeException $ex2){
catch(InvalidGrantTypeException $ex2)
{
$this->log_service->error($ex2);
$this->checkpoint_service->trackException($ex2);
$response = new OAuth2WWWAuthenticateErrorResponse($realm,
@ -180,7 +280,8 @@ class OAuth2BearerAccessTokenRequestValidator {
$http_response->header('WWW-Authenticate',$response->getWWWAuthenticateHeaderValue());
return $http_response;
}
catch(ExpiredAccessTokenException $ex3){
catch(ExpiredAccessTokenException $ex3)
{
$this->log_service->error($ex3);
$this->checkpoint_service->trackException($ex3);
$response = new OAuth2WWWAuthenticateErrorResponse($realm,
@ -193,7 +294,22 @@ class OAuth2BearerAccessTokenRequestValidator {
$http_response->header('WWW-Authenticate',$response->getWWWAuthenticateHeaderValue());
return $http_response;
}
catch(Exception $ex){
catch(RevokedAccessTokenException $ex4)
{
$this->log_service->error($ex4);
$this->checkpoint_service->trackException($ex4);
$response = new OAuth2WWWAuthenticateErrorResponse($realm,
OAuth2Protocol::OAuth2Protocol_Error_InvalidToken,
'the access token provided is expired, revoked, malformed, or invalid for other reasons.',
null,
401
);
$http_response = Response::json($response->getContent(), $response->getHttpCode());
$http_response->header('WWW-Authenticate',$response->getWWWAuthenticateHeaderValue());
return $http_response;
}
catch(Exception $ex)
{
$this->log_service->error($ex);
$this->checkpoint_service->trackException($ex);
$response = new OAuth2WWWAuthenticateErrorResponse($realm,

View File

@ -2,107 +2,113 @@
return array(
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| such as the size rules. Feel free to tweak each of these messages.
|
*/
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| such as the size rules. Feel free to tweak each of these messages.
|
*/
"accepted" => "The :attribute must be accepted.",
"active_url" => "The :attribute is not a valid URL.",
"after" => "The :attribute must be a date after :date.",
"alpha" => "The :attribute may only contain letters.",
"alpha_dash" => "The :attribute may only contain letters, numbers, and dashes.",
"alpha_num" => "The :attribute may only contain letters and numbers.",
"array" => "The :attribute must be an array.",
"before" => "The :attribute must be a date before :date.",
"between" => array(
"numeric" => "The :attribute must be between :min - :max.",
"file" => "The :attribute must be between :min - :max kilobytes.",
"string" => "The :attribute must be between :min - :max characters.",
"array" => "The :attribute must have between :min - :max items.",
),
"confirmed" => "The :attribute confirmation does not match.",
"date" => "The :attribute is not a valid date.",
"date_format" => "The :attribute does not match the format :format.",
"different" => "The :attribute and :other must be different.",
"digits" => "The :attribute must be :digits digits.",
"digits_between" => "The :attribute must be between :min and :max digits.",
"email" => "The :attribute format is invalid.",
"exists" => "The selected :attribute is invalid.",
"image" => "The :attribute must be an image.",
"in" => "The selected :attribute is invalid.",
"integer" => "The :attribute must be an integer.",
"ip" => "The :attribute must be a valid IP address.",
"max" => array(
"numeric" => "The :attribute may not be greater than :max.",
"file" => "The :attribute may not be greater than :max kilobytes.",
"string" => "The :attribute may not be greater than :max characters.",
"array" => "The :attribute may not have more than :max items.",
),
"mimes" => "The :attribute must be a file of type: :values.",
"min" => array(
"numeric" => "The :attribute must be at least :min.",
"file" => "The :attribute must be at least :min kilobytes.",
"string" => "The :attribute must be at least :min characters.",
"array" => "The :attribute must have at least :min items.",
),
"not_in" => "The selected :attribute is invalid.",
"numeric" => "The :attribute must be a number.",
"regex" => "The :attribute format is invalid.",
"required" => "The :attribute field is required.",
"required_if" => "The :attribute field is required when :other is :value.",
"required_with" => "The :attribute field is required when :values is present.",
"required_without" => "The :attribute field is required when :values is not present.",
"same" => "The :attribute and :other must match.",
"size" => array(
"numeric" => "The :attribute must be :size.",
"file" => "The :attribute must be :size kilobytes.",
"string" => "The :attribute must be :size characters.",
"array" => "The :attribute must contain :size items.",
),
"unique" => "The :attribute has already been taken.",
"url" => "The :attribute format is invalid.",
"accepted" => "The :attribute must be accepted.",
"active_url" => "The :attribute is not a valid URL.",
"after" => "The :attribute must be a date after :date.",
"alpha" => "The :attribute may only contain letters.",
"alpha_dash" => "The :attribute may only contain letters, numbers, and dashes.",
"alpha_num" => "The :attribute may only contain letters and numbers.",
"array" => "The :attribute must be an array.",
"before" => "The :attribute must be a date before :date.",
"between" => array(
"numeric" => "The :attribute must be between :min - :max.",
"file" => "The :attribute must be between :min - :max kilobytes.",
"string" => "The :attribute must be between :min - :max characters.",
"array" => "The :attribute must have between :min - :max items.",
),
"confirmed" => "The :attribute confirmation does not match.",
"date" => "The :attribute is not a valid date.",
"date_format" => "The :attribute does not match the format :format.",
"different" => "The :attribute and :other must be different.",
"digits" => "The :attribute must be :digits digits.",
"digits_between" => "The :attribute must be between :min and :max digits.",
"email" => "The :attribute format is invalid.",
"exists" => "The selected :attribute is invalid.",
"image" => "The :attribute must be an image.",
"in" => "The selected :attribute is invalid.",
"integer" => "The :attribute must be an integer.",
"ip" => "The :attribute must be a valid IP address.",
"max" => array(
"numeric" => "The :attribute may not be greater than :max.",
"file" => "The :attribute may not be greater than :max kilobytes.",
"string" => "The :attribute may not be greater than :max characters.",
"array" => "The :attribute may not have more than :max items.",
),
"mimes" => "The :attribute must be a file of type: :values.",
"min" => array(
"numeric" => "The :attribute must be at least :min.",
"file" => "The :attribute must be at least :min kilobytes.",
"string" => "The :attribute must be at least :min characters.",
"array" => "The :attribute must have at least :min items.",
),
"not_in" => "The selected :attribute is invalid.",
"numeric" => "The :attribute must be a number.",
"regex" => "The :attribute format is invalid.",
"required" => "The :attribute field is required.",
"required_if" => "The :attribute field is required when :other is :value.",
"required_with" => "The :attribute field is required when :values is present.",
"required_without" => "The :attribute field is required when :values is not present.",
"same" => "The :attribute and :other must match.",
"size" => array(
"numeric" => "The :attribute must be :size.",
"file" => "The :attribute must be :size kilobytes.",
"string" => "The :attribute must be :size characters.",
"array" => "The :attribute must contain :size items.",
),
"unique" => "The :attribute has already been taken.",
"url" => "The :attribute format is invalid.",
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom' => array(),
/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap attribute place-holders
| with something more reader friendly such as E-Mail Address instead
| of "email". This simply helps us make messages a little cleaner.
|
*/
'custom' => array(),
/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap attribute place-holders
| with something more reader friendly such as E-Mail Address instead
| of "email". This simply helps us make messages a little cleaner.
|
*/
'attributes' => array(),
'attributes' => array(),
//custom messages
'boolean' => "The :attribute must be a boolean.",
'text' => "The :attribute may only contain text.",
'httpmethod' => "The :attribute must be one of the following values 'GET', 'HEAD','POST','PUT','DELETE','TRACE','CONNECT' OR 'OPTIONS'.",
'route' => "The :attribute may be a valid http route.",
'host' => "The :attribute may be a valid host name.",
'scopename' => "The :attribute may be a valid scope name.",
'boolean' => "The :attribute must be a boolean.",
'text' => "The :attribute may only contain text.",
'httpmethod' => "The :attribute must be one of the following values 'GET', 'HEAD','POST','PUT','DELETE','TRACE','CONNECT' OR 'OPTIONS'.",
'route' => "The :attribute may be a valid http route.",
'host' => "The :attribute may be a valid host name.",
'scopename' => "The :attribute may be a valid scope name.",
'applicationtype' => "The :attribute may be a valid application type.",
'sslurl' => "The :attribute may be a valid URL under ssl schema.",
'sslorigin' => "The :attribute may be a valid HTTP origin under ssl schema.",
'freetext' => "The :attribute may only contain text."
'sslurl' => "The :attribute may be a valid URL under ssl schema.",
'sslorigin' => "The :attribute may be a valid HTTP origin under ssl schema.",
'freetext' => "The :attribute may only contain text.",
'public_key_pem' => "The :attribute has not a valid PCK#1/PCK#8 public key format.",
'private_key_pem' => "The :attribute has not a valid PCK#1/PCK#8 private key format.",
'public_key_usage' => "The :attribute has not a valid key usage (enc, sig).",
'public_key_type'=> "The :attribute has not a valid key type (RSA).",
'private_key_password' => "The :attribute is not the right password of the PEM private key.",
'private_key_pem_length'=> "The :attribute has not a valid private key length ( at least 2048 bits ).",
'public_key_pem_length'=> "The :attribute has not a valid public key length ( at least 2048 bits ).",
'key_alg' => "The :attribute has not a valid alg parameter for the key usage.",
);

View File

@ -3,42 +3,69 @@
namespace auth;
use Auth;
use Config;
use Crypt;
use Cookie;
use jwe\compression_algorithms\CompressionAlgorithms_Registry;
use jwe\compression_algorithms\CompressionAlgorithmsNames;
use Member;
use oauth2\models\IClient;
use oauth2\services\IPrincipalService;
use openid\model\IOpenIdUser;
use openid\services\IUserService;
use Session;
use utils\Base64UrlRepresentation;
use utils\services\IAuthService;
use utils\services\ICacheService;
class AuthService implements IAuthService
/**
* Class AuthService
* @package auth
*/
final class AuthService implements IAuthService
{
/**
* @var IPrincipalService
*/
private $principal_service;
/**
* @var IUserService
*/
private $user_service;
/**
* @var ICacheService
*/
private $cache_service;
public function __construct
(
IPrincipalService $principal_service,
IUserService $user_service,
ICacheService $cache_service
)
{
$this->principal_service = $principal_service;
$this->user_service = $user_service;
$this->cache_service = $cache_service;
}
/**
* @return mixed
*/
public function isUserLogged()
{
$res = Auth::check();
if ($res) {
$user = $this->getCurrentUser();
if (!$user->hasAssociatedMember()) {
$this->logout();
$res = false;
}
}
return $res;
return Auth::check();
}
/**
* @return mixed
* @return IOpenIdUser
*/
public function getCurrentUser()
{
$user = Auth::user();
if (!is_null($user) && !$user->hasAssociatedMember()) {
$this->logout();
$user = null;
}
return $user;
return Auth::user();
}
/**
@ -49,12 +76,26 @@ class AuthService implements IAuthService
*/
public function login($username, $password, $remember_me)
{
return Auth::attempt(array('username' => $username, 'password' => $password), $remember_me);
$res = Auth::attempt(array('username' => $username, 'password' => $password), $remember_me);
if ($res)
{
$this->principal_service->clear();
$this->principal_service->register
(
$this->getCurrentUser()->getId(),
time()
);
}
return $res;
}
public function logout()
{
Auth::logout();
$this->principal_service->clear();
Cookie::queue('rps', null, $minutes = -2628000, $path = '/', $domain = null, $secure = false, $httpOnly = false);
}
/**
@ -62,7 +103,8 @@ class AuthService implements IAuthService
*/
public function getUserAuthorizationResponse()
{
if (Session::has("openid.authorization.response")) {
if (Session::has("openid.authorization.response"))
{
$value = Session::get("openid.authorization.response");
return $value;
@ -73,16 +115,23 @@ class AuthService implements IAuthService
public function clearUserAuthorizationResponse()
{
if (Session::has("openid.authorization.response")) {
if (Session::has("openid.authorization.response"))
{
Session::remove("openid.authorization.response");
Session::save();
}
}
public function setUserAuthorizationResponse($auth_response)
{
Session::set("openid.authorization.response", $auth_response);
Session::save();
}
/**
* @param string $openid
* @return IOpenIdUser
*/
public function getUserByOpenId($openid)
{
$user = User::where('identifier', '=', $openid)->first();
@ -90,16 +139,32 @@ class AuthService implements IAuthService
return $user;
}
/**
* @param string $username
* @return bool|IOpenIdUser
*/
public function getUserByUsername($username)
{
$member = Member::where('Email', '=', $username)->first();
if (!is_null($member)) {
return User::where('external_identifier', '=', $member->ID)->first();
if (!is_null($member))
{
$user = User::where('external_identifier', '=', $member->ID)->first();
if(!$user)
{
$user = $this->user_service->buildUser($member);
}
return $user;
}
return false;
}
/**
* @param int $id
* @return IOpenIdUser
*/
public function getUserById($id)
{
return User::find($id);
@ -111,22 +176,164 @@ class AuthService implements IAuthService
{
if (Session::has("openstackid.authentication.response")) {
$value = Session::get("openstackid.authentication.response");
return $value;
}
return IAuthService::AuthenticationResponse_None;
}
public function setUserAuthenticationResponse($auth_response)
{
Session::set("openstackid.authentication.response", $auth_response);
Session::save();
}
public function clearUserAuthenticationResponse()
{
if (Session::has("openstackid.authentication.response")) {
if (Session::has("openstackid.authentication.response"))
{
Session::remove("openstackid.authentication.response");
Session::save();
}
}
/**
* @param int $user_id
* @return string
*/
public function unwrapUserId($user_id)
{
$user = $this->getUserByExternaldId($user_id);
if(!is_null($user))
return $user_id;
$unwrapped_name = $this->decrypt($user_id);
$parts = explode(':', $unwrapped_name);
return intval($parts[1]);
}
/**
* @param int $user_id
* @param IClient $client
* @return string
*/
public function wrapUserId($user_id, IClient $client)
{
if($client->getSubjectType() === IClient::SubjectType_Public)
return $user_id;
else
{
$wrapped_name = sprintf('%s:%s', $client->getClientId(), $user_id);
return $this->encrypt($wrapped_name);
}
}
/**
* @param string $value
* @return String
*/
private function encrypt($value)
{
return base64_encode(Crypt::encrypt($value));
}
/**
* @param string $value
* @return String
*/
private function decrypt($value)
{
$value = base64_decode($value);
return Crypt::decrypt($value);
}
/**
* @param int $external_id
* @return IOpenIdUser
*/
public function getUserByExternaldId($external_id)
{
$member = Member::where('ID', '=', $external_id)->first();
if (!is_null($member))
{
$user = User::where('external_identifier', '=', $member->ID)->first();
if(!$user)
{
$user = $this->user_service->buildUser($member);
}
return $user;
}
return false;
}
/**
* @return string
*/
public function getSessionId()
{
return Session::getId();
}
/**
* @param $client_id
* @return void
*/
public function registerRPLogin($client_id)
{
$rps = Cookie::get('rps');
$zlib = CompressionAlgorithms_Registry::getInstance()->get(CompressionAlgorithmsNames::ZLib);
if(!empty($rps))
{
$rps = $this->decrypt($rps);
$rps = $zlib->uncompress($rps);
$rps .= '|';
}
if(!str_contains($rps, $client_id))
$rps .= $client_id;
$rps = $zlib->compress($rps);
$rps = $this->encrypt($rps);
Cookie::queue('rps', $rps, $minutes = 2628000, $path = '/', $domain = null, $secure = false, $httpOnly = false);
}
/**
* @return string[]
*/
public function getLoggedRPs()
{
$rps = Cookie::get('rps');
$zlib = CompressionAlgorithms_Registry::getInstance()->get(CompressionAlgorithmsNames::ZLib);
if(!empty($rps))
{
$rps = $this->decrypt($rps);
$rps = $zlib->uncompress($rps);
return explode('|', $rps);
}
return null;
}
/**
* @param string $jti
* @return void
*/
public function reloadSession($jti)
{
$session_id = $this->cache_service->getSingleValue($jti);
if(empty($session_id)) throw new \Exception('session not found!');
Session::setId(Crypt::decrypt($session_id));
Session::start();
if(!Auth::check())
{
$user_id = $this->principal_service->get()->getUserId();
$user = $this->getUserById($user_id);
if(is_null($user)) throw new \Exception('user not found!');
Auth::login($user);
}
}
}

View File

@ -2,9 +2,9 @@
namespace auth;
use App;
use Illuminate\Support\ServiceProvider;
use utils\services\UtilsServiceCatalog;
use App;
class AuthenticationServiceProvider extends ServiceProvider
{
@ -16,7 +16,7 @@ class AuthenticationServiceProvider extends ServiceProvider
public function register()
{
App::singleton(UtilsServiceCatalog::AuthenticationService, 'auth\\AuthService');
App::singleton('auth\\IAuthenticationExtensionService', 'auth\\AuthenticationExtensionService');
App::singleton('auth\\IAuthenticationExtensionService', 'auth\\AuthenticationExtensionService');
}
public function provides()

View File

@ -86,11 +86,10 @@ class CustomAuthProvider implements UserProviderInterface
{
try {
//here we do the manuel join between 2 DB, (openid and SS db)
$user = $this->user_repository->getByExternalId($identifier);
$user = $this->user_repository->getByExternalId($identifier);
$member = $this->member_repository->get($identifier);
if (!is_null($member) && !is_null($user)) {
if (!is_null($member) && $member->canLogin() && !is_null($user)) {
$user->setMember($member);
return $user;
}
@ -110,27 +109,35 @@ class CustomAuthProvider implements UserProviderInterface
*/
public function retrieveByCredentials(array $credentials)
{
$user_service = $this->user_service;
$user_service = $this->user_service;
$auth_extension_service = $this->auth_extension_service;
$user_repository = $this->user_repository;
$member_repository = $this->member_repository;
try {
$user_repository = $this->user_repository;
$member_repository = $this->member_repository;
$log_service = $this->log_service;
$checkpoint_service = $this->checkpoint_service;
$user = $this->tx_service->transaction(function () use (
$credentials,
$user_repository,
$member_repository,
$user_service,
$auth_extension_service
) {
return $this->tx_service->transaction(function () use (
$credentials,
$user_repository,
$member_repository,
$user_service,
$auth_extension_service,
$log_service,
$checkpoint_service
) {
if (!isset($credentials['username']) || !isset($credentials['password'])) {
$user = null;
try
{
if (!isset($credentials['username']) || !isset($credentials['password']))
{
throw new AuthenticationException("invalid crendentials");
}
$email = $credentials['username'];
$email = $credentials['username'];
$password = $credentials['password'];
//get SS member
@ -142,10 +149,15 @@ class CustomAuthProvider implements UserProviderInterface
throw new AuthenticationException(sprintf("member %s does not exists!", $email));
}
if(!$member->canLogin())
{
throw new AuthenticationException(sprintf("member %s does not exists!", $email));
}
$valid_password = $member->checkPassword($password);
if (!$valid_password) {
if (!$valid_password)
{
throw new AuthenticationInvalidPasswordAttemptException($email,
sprintf("invalid login attempt for user %s ", $email));
}
@ -153,54 +165,44 @@ class CustomAuthProvider implements UserProviderInterface
$user = $user_repository->getByExternalId($member->ID);
//if user does not exists, then create it
if (is_null($user)) {
//create user
$user = new User();
$user->external_identifier = $member->ID;
$user->identifier = $member->ID;
$user->last_login_date = gmdate("Y-m-d H:i:s", time());
$user->active = true;
$user->lock = false;
$user->login_failed_attempt = 0;
$user_repository->add($user);
if (!$user) {
$user = $user_service->buildUser($member);
}
//check user status...
if ($user->lock || !$user->active) {
Log::warning(sprintf("user %s is on lock state", $email));
throw new AuthenticationLockedUserLoginAttempt($email, sprintf("user %s is on lock state", $email));
throw new AuthenticationLockedUserLoginAttempt($email,
sprintf("user %s is on lock state", $email));
}
$user_name = strtolower($member->FirstName . "." . $member->Surname);
//do association between user and member
$user_service->associateUser($user, $user_name);
//update user fields
$user->last_login_date = gmdate("Y-m-d H:i:s", time());
$user->last_login_date = gmdate("Y-m-d H:i:s", time());
$user->login_failed_attempt = 0;
$user->active = true;
$user->lock = false;
$user->active = true;
$user->lock = false;
$user_repository->update($user);
$user->setMember($member);
$auth_extensions = $auth_extension_service->getExtensions();
foreach ($auth_extensions as $auth_extension) {
foreach ($auth_extensions as $auth_extension)
{
$auth_extension->process($user);
}
return $user;
});
} catch (Exception $ex) {
$this->checkpoint_service->trackException($ex);
$this->log_service->error($ex);
$user = null;
}
}
catch (Exception $ex)
{
$checkpoint_service->trackException($ex);
$log_service->error($ex);
$user = null;
}
return $user;
});
return $user;
}
@ -217,12 +219,12 @@ class CustomAuthProvider implements UserProviderInterface
throw new AuthenticationException("invalid crendentials");
}
try {
$email = $credentials['username'];
$email = $credentials['username'];
$password = $credentials['password'];
$member = $this->member_repository->getByEmail($email);
$member = $this->member_repository->getByEmail($email);
if (!$member || !$member->checkPassword($password)) {
if (!$member || !$member->canLogin() || !$member->checkPassword($password)) {
return false;
}
@ -248,7 +250,6 @@ class CustomAuthProvider implements UserProviderInterface
*/
public function retrieveByToken($identifier, $token)
{
return $this->user_repository->getByToken($identifier, $token);
}
@ -263,5 +264,5 @@ class CustomAuthProvider implements UserProviderInterface
$user->setAttribute($user->getRememberTokenName(), $token);
$user->save();
}
}
}

View File

@ -1,17 +1,24 @@
<?php
namespace auth;
use Member;
interface IMemberRepository {
/**
* @param $id
* @return Member
*/
public function get($id);
/**
* Interface IMemberRepository
* @package auth
*/
interface IMemberRepository
{
/**
* @param $id
* @return Member
*/
public function get($id);
/**
* @param $email
* @return Member
*/
public function getByEmail($email);
/**
* @param $email
* @return Member
*/
public function getByEmail($email);
}

View File

@ -2,69 +2,51 @@
namespace auth;
use utils\db\IBaseRepository;
/**
* Interface IUserRepository
* @package auth
*/
interface IUserRepository {
/**
* @param $id
* @return User
*/
public function get($id);
interface IUserRepository extends IBaseRepository
{
/**
* @param $external_id
* @return User
*/
public function getByExternalId($external_id);
/**
* @param $filters
* @return array
*/
public function getByCriteria($filters);
/**
* @param $filters
* @return User
*/
public function getOneByCriteria($filters);
/**
* @param $external_id
* @return User
*/
public function getByExternalId($external_id);
/**
* @param array $filters
* @return int
*/
public function getCount(array $filters = array());
/**
* @param $filters
* @return array
*/
public function getByCriteria($filters);
/**
* @param $filters
* @return User
*/
public function getOneByCriteria($filters);
/**
* @param User $u
* @return bool
*/
public function update(User $u);
/**
* @param User $u
* @return bool
*/
public function add(User $u);
/**
* @param int $page_nbr
* @param int $page_size
* @param array $filters
* @param array $fields
* @return array
*/
public function getByPage($page_nbr = 1, $page_size = 10, array $filters = array(), array $fields = array('*'));
/**
* @param mixed $identifier
* @param string $token
* @return User
*/
public function getByToken($identifier, $token);
/**
* @param array $filters
* @return int
*/
public function getCount(array $filters = array());
/**
* @param mixed $identifier
* @param string $token
* @return User
*/
public function getByToken($identifier, $token);
/**
* @param string $term
* @return array
*/
public function getByEmailOrName($term);
}

View File

@ -6,15 +6,18 @@ use Eloquent;
use Illuminate\Auth\UserInterface;
use Member;
use MemberPhoto;
use oauth2\models\IApiScope;
use oauth2\models\IApiScopeGroup;
use oauth2\models\IOAuth2User;
use openid\model\IOpenIdUser;
use utils\model\BaseModelEloquent;
use utils\model\IEntity;
/**
* Class User
* @package auth
*/
class User extends BaseModelEloquent implements UserInterface, IOpenIdUser, IOAuth2User
class User extends BaseModelEloquent implements UserInterface, IOpenIdUser, IOAuth2User, IEntity
{
protected $table = 'openid_users';
@ -60,7 +63,6 @@ class User extends BaseModelEloquent implements UserInterface, IOpenIdUser, IOAu
$this->member = $member;
}
private function getAssociatedMember()
{
if (is_null($this->member)) {
@ -70,15 +72,6 @@ class User extends BaseModelEloquent implements UserInterface, IOpenIdUser, IOAu
return $this->member;
}
/**
* @return bool
*/
public function hasAssociatedMember()
{
$this->getAssociatedMember();
return !is_null($this->member);
}
/**
* Get the unique identifier for the user.
* the one that is saved as session id on vendor/laravel/framework/src/Illuminate/Auth/Guard.php
@ -110,10 +103,18 @@ class User extends BaseModelEloquent implements UserInterface, IOpenIdUser, IOAu
public function getEmail()
{
$this->getAssociatedMember();
if(is_null($this->member)) return false;
return $this->member->Email;
}
/**
* @return string
*/
public function getEmailAttribute()
{
return $this->getEmail();
}
public function getFullName()
{
return $this->getFirstName() . " " . $this->getLastName();
@ -175,7 +176,7 @@ class User extends BaseModelEloquent implements UserInterface, IOpenIdUser, IOAu
public function getId()
{
return $this->id;
return (int)$this->id;
}
public function getShowProfileFullName()
@ -264,7 +265,11 @@ class User extends BaseModelEloquent implements UserInterface, IOpenIdUser, IOAu
{
$this->getAssociatedMember();
return sprintf("%s, %s ", $this->member->Address, $this->member->Suburb);
$street_address = $this->member->Address;
$suburb = $this->member->Suburb;
if(!empty($suburb))
$street_address .= ', '.$suburb;
return $street_address;
}
public function getRegion()
@ -307,4 +312,73 @@ class User extends BaseModelEloquent implements UserInterface, IOpenIdUser, IOAu
{
return 'remember_token';
}
/**
* @return int
*/
public function getExternalIdentifier()
{
return $this->getAuthIdentifier();
}
/**
* @return string
*/
public function getFormattedAddress()
{
$street = $this->getStreetAddress();
$region = $this->getRegion();
$city = $this->getLocality();
$zip_code = $this->getPostalCode();
$country = $this->getCountry();
$complete = $street;
if(!empty($city))
$complete .= ', '.$city;
if(!empty($region))
$complete .= ', '.$region;
if(!empty($zip_code))
$complete .= ', '.$zip_code;
if(!empty($country))
$complete .= ', '.$country;
return $complete;
}
/**
* @return IApiScopeGroup[]
*/
public function getGroups()
{
return $this->groups()->where('active','=',true)->get();
}
/**
* @return mixed
*/
public function groups()
{
return $this->belongsToMany('ApiScopeGroup','oauth2_api_scope_group_users','user_id', 'group_id');
}
/**
* @return IApiScope[]
*/
public function getGroupScopes()
{
$scopes = array();
$map = array();
foreach($this->groups()->where('active','=',true)->get() as $group){
foreach($group->scopes()->get() as $scope)
{
if(!isset($map[$scope->id]))
array_push($scopes, $scope);
}
}
return $scopes;
}
}

View File

@ -0,0 +1,66 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2;
/**
* Class AddressClaim
* @package oauth2
* http://openid.net/specs/openid-connect-core-1_0.html#AddressClaim
*
* The Address Claim represents a physical mailing address. Implementations MAY return only a subset of the fields of an
* address, depending upon the information available and the End-User's privacy preferences. For example, the country
* and region might be returned without returning more fine-grained address information.
* Implementations MAY return just the full address as a single string in the formatted sub-field, or they MAY return
* just the individual component fields using the other sub-fields, or they MAY return both. If both variants are
* returned, they SHOULD be describing the same address, with the formatted address indicating how the component fields
* are combined.
*/
abstract class AddressClaim
{
/**
* Full mailing address, formatted for display or use on a mailing label. This field MAY contain multiple lines,
* separated by newlines. Newlines can be represented either as a carriage return/line feed pair ("\r\n") or as a
* single line feed character ("\n").
*/
const Formatted = 'formatted';
/**
* Full street address component, which MAY include house number, street name, Post Office Box, and multi-line
* extended street address information. This field MAY contain multiple lines, separated by newlines. Newlines
* can be represented either as a carriage return/line feed pair ("\r\n") or as a single line feed character ("\n").
*/
const StreetAddress = 'street_address';
/**
* City or locality component.
*/
const Locality = 'locality';
/**
* State, province, prefecture, or region component.
*/
const Region = 'region';
/**
* Zip code or postal code component.
*/
const PostalCode = 'postal_code';
/**
* Country name component.
*/
const Country = 'country';
}

View File

@ -41,11 +41,27 @@ interface IOAuth2Protocol {
*/
public function introspection(OAuth2Request $request = null);
/**
* Get all available grant types set on the protocol
* @return mixed
*/
public function getAvailableGrants();
/**
* @return string
*/
public function getJWKSDocument();
/**
* http://openid.net/specs/openid-connect-discovery-1_0.html
* @return string
*/
public function getDiscoveryDocument();
/**
* http://openid.net/specs/openid-connect-session-1_0.html#RPLogout
*/
public function endSession(OAuth2Request $request = null);
}

View File

@ -3,6 +3,7 @@
namespace oauth2;
use utils\http\HttpMessage;
use oauth2\requests\OAuth2RequestMemento;
/**
* Class OAuth2Message
@ -10,7 +11,7 @@ use utils\http\HttpMessage;
*/
class OAuth2Message extends HttpMessage
{
public function __construct(array $values)
public function __construct(array $values = array())
{
parent::__construct($values);
}
@ -23,7 +24,44 @@ class OAuth2Message extends HttpMessage
public function getParam($param)
{
return isset($this->container[$param])?$this->container[$param]:null;
return isset($this->container[$param])? $this->container[$param] : null;
}
/**
* @param string $param
* @param mixed $value
* @return $this
*/
public function setParam($param, $value)
{
$this->container[$param] = $value;
return $this;
}
/**
* @return OAuth2RequestMemento
*/
public function createMemento(){
return OAuth2RequestMemento::buildFromRequest($this);
}
/**
* @param OAuth2RequestMemento $memento
* @return $this
*/
public function setMemento(OAuth2RequestMemento $memento){
$this->container = $memento->getState();
return $this;
}
/**
* @param OAuth2RequestMemento $memento
* @return OAuth2Message
*/
static public function buildFromMemento(OAuth2RequestMemento $memento){
$msg = new self;
$msg->setMemento($memento);
return $msg;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,157 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2;
/**
* Class StandardClaims
* @package oauth2
* http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
*/
abstract class StandardClaims
{
/**
* Subject - Identifier for the End-User at the Issuer.
*/
const SubjectIdentifier = 'sub';
/**
* End-User's full name in displayable form including all name parts, possibly including titles and suffixes,
* ordered according to the End-User's locale and preferences.
*/
const Name = 'name';
/**
* Given name(s) or first name(s) of the End-User. Note that in some cultures, people can have multiple given names;
* all can be present, with the names being separated by space characters.
*/
const GivenName = 'given_name';
/**
* Surname(s) or last name(s) of the End-User. Note that in some cultures, people can have multiple family names or
* no family name; all can be present, with the names being separated by space characters.
*/
const FamilyName = 'family_name';
/**
* Middle name(s) of the End-User. Note that in some cultures, people can have multiple middle names; all can
* be present, with the names being separated by space characters. Also note that in some cultures, middle names are
* not used.
*/
const MiddleName = 'middle_name';
/**
* Casual name of the End-User that may or may not be the same as the given_name. For instance, a nickname value of
* Mike might be returned alongside a given_name value of Michael.
*/
const NickName = 'nickname';
/**
* string Shorthand name by which the End-User wishes to be referred to at the RP, such as janedoe or j.doe.
* This value MAY be any valid JSON string including special characters such as @, /, or whitespace. The RP MUST
* NOT rely upon this value being unique, as discussed in Section 5.7.
*/
const PreferredUserName = 'preferred_username';
/**
* URL of the End-User's profile page. The contents of this Web page SHOULD be about the End-User.
*/
const Profile = 'profile';
/**
* URL of the End-User's profile picture. This URL MUST refer to an image file (for example, a PNG, JPEG, or GIF
* image file), rather than to a Web page containing an image. Note that this URL SHOULD specifically reference a
* profile photo of the End-User suitable for displaying when describing the End-User, rather than an arbitrary
* photo taken by the End-User.
*/
const Picture = 'picture';
/**
* URL of the End-User's Web page or blog. This Web page SHOULD contain information published by the End-User or an
* organization that the End-User is affiliated with.
*/
const Website = 'website';
/**
* End-User's preferred e-mail address. Its value MUST conform to the RFC 5322 [RFC5322] addr-spec syntax. The RP
* MUST NOT rely upon this value being unique, as discussed in Section 5.7.
*/
const Email = 'email';
/**
* True if the End-User's e-mail address has been verified; otherwise false. When this Claim Value is true, this
* means that the OP took affirmative steps to ensure that this e-mail address was controlled by the End-User at
* the time the verification was performed. The means by which an e-mail address is verified is context-specific,
* and dependent upon the trust framework or contractual agreements within which the parties are operating.
*/
const EmailVerified = 'email_verified';
/**
* End-User's gender. Values defined by this specification are female and male. Other values MAY be used when
* neither of the defined values are applicable.
*/
const Gender = 'gender';
/**
* End-User's birthday, represented as an ISO 8601:2004 [ISO86012004] YYYY-MM-DD format. The year MAY be 0000,
* indicating that it is omitted. To represent only the year, YYYY format is allowed. Note that depending on the
* underlying platform's date related function, providing just year can result in varying month and day, so the
* implementers need to take this factor into account to correctly process the dates.
*/
const Birthdate = 'birthdate';
/**
* String from zoneinfo [zoneinfo] time zone database representing the End-User's time zone. For example,
* Europe/Paris or America/Los_Angeles.
*/
const ZoneInfo = 'zoneinfo';
/**
* End-User's locale, represented as a BCP47 [RFC5646] language tag. This is typically an ISO 639-1 Alpha-2
* [ISO6391] language code in lowercase and an ISO 3166-1 Alpha-2 [ISO31661] country code in uppercase, separated
* by a dash. For example, en-US or fr-CA. As a compatibility note, some implementations have used an underscore as
* the separator rather than a dash, for example, en_US; Relying Parties MAY choose to accept this locale syntax as
* well.
*/
const Locale = 'locale';
/**
* End-User's preferred telephone number. E.164 [E.164] is RECOMMENDED as the format of this Claim, for example,
* +1 (425) 555-1212 or +56 (2) 687 2400. If the phone number contains an extension, it is RECOMMENDED that the
* extension be represented using the RFC 3966 [RFC3966] extension syntax, for example, +1 (604) 555-1234;ext=5678.
*/
const PhoneNumber = 'phone_number';
/**
* True if the End-User's phone number has been verified; otherwise false. When this Claim Value is true, this
* means that the OP took affirmative steps to ensure that this phone number was controlled by the End-User at the
* time the verification was performed. The means by which a phone number is verified is context-specific, and
* dependent upon the trust framework or contractual agreements within which the parties are operating. When true,
* the phone_number Claim MUST be in E.164 format and any extensions MUST be represented in RFC 3966 format.
*/
const PhoneNumberVerified = 'phone_number_verified';
/**
* JSON object
* End-User's preferred postal address. The value of the address member is a JSON [RFC4627] structure containing
* some or all of the members defined in Section 5.1.1.
*/
const Address = 'address';
/**
* Time the End-User's information was last updated. Its value is a JSON number representing the number of
* seconds from 1970-01-01T0:0:0Z as measured in UTC until the date/time.
*/
const UpdatedAt = 'updated_at';
}

View File

@ -0,0 +1,35 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\builders;
use jwt\IBasicJWT;
use jwt\impl\JWTClaimSet;
use oauth2\models\IClient;
use oauth2\models\JWTResponseInfo;
/**
* Interface IdTokenBuilder
* @package oauth2\builders
*/
interface IdTokenBuilder
{
/**
* @param JWTClaimSet $claim_set
* @param JWTResponseInfo $info
* @param IClient $client
* @return IBasicJWT
*/
public function buildJWT(JWTClaimSet $claim_set, JWTResponseInfo $info, IClient $client);
}

View File

@ -0,0 +1,260 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\discovery;
/**
* Class DiscoveryDocumentBuilder
* @package oauth2\discovery
*/
final class DiscoveryDocumentBuilder
{
/**
* @var array
*/
private $set = array();
/**
* @param string $issuer
* @return $this
*/
public function setIssuer($issuer)
{
$this->set[OpenIDProviderMetadata::Issuer] = $issuer;
return $this;
}
/**
* @param string $auth_endpoint
* @return $this
*/
public function setAuthEndpoint($auth_endpoint)
{
$this->set[OpenIDProviderMetadata::AuthEndpoint] = $auth_endpoint;
return $this;
}
/**
* @param string $token_endpoint
* @return $this
*/
public function setTokenEndpoint($token_endpoint)
{
$this->set[OpenIDProviderMetadata::TokenEndpoint] = $token_endpoint;
return $this;
}
/**
* @param string $user_info_endpoint
* @return $this
*/
public function setUserInfoEndpoint($user_info_endpoint)
{
$this->set[OpenIDProviderMetadata::UserInfoEndpoint] = $user_info_endpoint;
return $this;
}
/**
* @param string $end_session_endpoint
* @return $this
*/
public function setEndSessionEndpoint($end_session_endpoint)
{
$this->set[OpenIDProviderMetadata::EndSessionEndPoint] = $end_session_endpoint;
return $this;
}
/**
* @param string $check_session_iframe
* @return $this
*/
public function setCheckSessionIframe($check_session_iframe)
{
$this->set[OpenIDProviderMetadata::CheckSessionIFrame] = $check_session_iframe;
return $this;
}
/**
* @param string $jwks_url
* @return $this
*/
public function setJWKSUrl($jwks_url)
{
$this->set[OpenIDProviderMetadata::JWKSUrl] = $jwks_url;
return $this;
}
/**
* @param string $revocation_endpoint
* @return $this
*/
public function setRevocationEndpoint($revocation_endpoint)
{
$this->set[OpenIDProviderMetadata::RevocationEndpoint] = $revocation_endpoint;
return $this;
}
/**
* @param string $introspection_endpoint
* @return $this
*/
public function setIntrospectionEndpoint($introspection_endpoint)
{
$this->set[OpenIDProviderMetadata::IntrospectionEndpoint] = $introspection_endpoint;
return $this;
}
/**
* @param string $key
* @param string $value
*/
private function addArrayValue($key, $value)
{
if( !isset($this->set[$key]))
$this->set[$key] = array();
array_push($this->set[$key], $value);
}
/**
* @param string $response_type
* @return $this
*/
public function addResponseTypeSupported($response_type)
{
$this->addArrayValue(OpenIDProviderMetadata::ResponseTypesSupported, $response_type);
return $this;
}
/**
* @param string $response_mode
* @return $this
*/
public function addResponseModeSupported($response_mode)
{
$this->addArrayValue(OpenIDProviderMetadata::ResponseModesSupported, $response_mode);
return $this;
}
/**
* @param string $subject_type
* @return $this
*/
public function addSubjectTypeSupported($subject_type)
{
$this->addArrayValue(OpenIDProviderMetadata::SubjectTypesSupported, $subject_type);
return $this;
}
/**
* @param string $scope
* @return $this
*/
public function addScopeSupported($scope){
$this->addArrayValue(OpenIDProviderMetadata::ScopesSupported, $scope);
return $this;
}
/**
* @param string $claim
* @return $this
*/
public function addClaimSupported($claim)
{
$this->addArrayValue(OpenIDProviderMetadata::ClaimsSupported, $claim);
return $this;
}
/**
* @param string $auth_method
* @return $this
*/
public function addTokenEndpointAuthMethodSupported($auth_method)
{
$this->addArrayValue(OpenIDProviderMetadata::TokenEndpointAuthMethodsSupported, $auth_method);
return $this;
}
/**
* @param string $alg
* @return $this
*/
public function addIdTokenSigningAlgSupported($alg)
{
$this->addArrayValue(OpenIDProviderMetadata::IdTokenSigningAlgValuesSupported, $alg);
return $this;
}
/**
* @param string $alg
* @return $this
*/
public function addIdTokenEncryptionAlgSupported($alg)
{
$this->addArrayValue(OpenIDProviderMetadata::IdTokenEncryptionAlgValuesSupported, $alg);
return $this;
}
/**
* @param string $enc
* @return $this
*/
public function addIdTokenEncryptionEncSupported($enc)
{
$this->addArrayValue(OpenIDProviderMetadata::IdTokenEncryptionEncValuesSupported, $enc);
return $this;
}
/**
* @param string $alg
* @return $this
*/
public function addUserInfoSigningAlgSupported($alg)
{
$this->addArrayValue(OpenIDProviderMetadata::UserInfoSigningAlgValuesSupported, $alg);
return $this;
}
/**
* @param string $alg
* @return $this
*/
public function addUserInfoEncryptionAlgSupported($alg)
{
$this->addArrayValue(OpenIDProviderMetadata::UserInfoEncryptionAlgValuesSupported, $alg);
return $this;
}
/**
* @param string $enc
* @return $this
*/
public function addUserInfoEncryptionEncSupported($enc)
{
$this->addArrayValue(OpenIDProviderMetadata::UserInfoEncryptionEncValuesSupported, $enc);
return $this;
}
/**
* @return string
*/
public function render()
{
$json = json_encode($this->set);
$json = str_replace('\/','/', $json);
return $json;
}
}

View File

@ -0,0 +1,67 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\discovery;
/**
* Interface IOpenIDProviderConfigurationService
* @package oauth2\discovery
*/
interface IOpenIDProviderConfigurationService
{
/**
* @return string
*/
public function getIssuerUrl();
/**
* @return string
*/
public function getAuthEndpoint();
/**
* @return string
*/
public function getTokenEndpoint();
/**
* @return string
*/
public function getUserInfoEndpoint();
/**
* @return string
*/
public function getJWKSUrl();
/**
* @return string
*/
public function getRevocationEndpoint();
/**
* @return string
*/
public function getIntrospectionEndpoint();
/**
* @return string
*/
public function getCheckSessionIFrame();
/**
* @return string
*/
public function getEndSessionEndpoint();
}

View File

@ -0,0 +1,276 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\discovery;
/**
* Class OpenIDProviderMetadata
* @package oauth2\discovery
* http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
*/
abstract class OpenIDProviderMetadata
{
/**
* REQUIRED. URL using the https scheme with no query or fragment component that the OP asserts as its Issuer
* Identifier. If Issuer discovery is supported (see Section 2), this value MUST be identical to the issuer value
* returned by WebFinger. This also MUST be identical to the iss Claim value in ID Tokens issued from this Issuer.
*/
const Issuer = 'issuer';
/**
* REQUIRED. URL of the OP's OAuth 2.0 Authorization Endpoint [OpenID.Core].
*/
const AuthEndpoint = 'authorization_endpoint';
/**
* URL of the OP's OAuth 2.0 Token Endpoint [OpenID.Core]. This is REQUIRED unless only the Implicit Flow is used.
*/
const TokenEndpoint = 'token_endpoint';
/**
* RECOMMENDED. URL of the OP's UserInfo Endpoint [OpenID.Core]. This URL MUST use the https scheme and MAY contain
* port, path, and query parameter components.
*/
const UserInfoEndpoint = 'userinfo_endpoint';
/**
* REQUIRED. URL of the OP's JSON Web Key Set [JWK] document. This contains the signing key(s) the RP uses to
* validate signatures from the OP. The JWK Set MAY also contain the Server's encryption key(s), which are used by
* RPs to encrypt requests to the Server. When both signing and encryption keys are made available, a use (Key Use)
* parameter value is REQUIRED for all keys in the referenced JWK Set to indicate each key's intended usage.
* Although some algorithms allow the same key to be used for both signatures and encryption,
* doing so is NOT RECOMMENDED, as it is less secure. The JWK x5c parameter MAY be used to provide X.509
* representations of keys provided. When used, the bare key values MUST still be present and MUST match those in the certificate.
*/
const JWKSUrl = 'jwks_uri';
/**
* RECOMMENDED. URL of the OP's Dynamic Client Registration Endpoint [OpenID.Registration].
*/
const RegistrationEndpoint = 'registration_endpoint';
/**
* RECOMMENDED. JSON array containing a list of the OAuth 2.0 [RFC6749] scope values that this server supports.
* The server MUST support the openid scope value. Servers MAY choose not to advertise some supported scope values
* even when this parameter is used, although those defined in [OpenID.Core] SHOULD be listed, if supported.
*/
const ScopesSupported = 'scopes_supported';
/**
* REQUIRED. JSON array containing a list of the OAuth 2.0 response_type values that this OP supports. Dynamic
* OpenID Providers MUST support the code, id_token, and the token id_token Response Type values.
*/
const ResponseTypesSupported = 'response_types_supported';
/**
* OPTIONAL. JSON array containing a list of the OAuth 2.0 response_mode values that this OP supports, as specified
* in OAuth 2.0 Multiple Response Type Encoding Practices [OAuth.Responses]. If omitted, the default for Dynamic
* OpenID Providers is ["query", "fragment"].
*/
const ResponseModesSupported = 'response_modes_supported';
/**
* OPTIONAL. JSON array containing a list of the OAuth 2.0 Grant Type values that this OP supports. Dynamic OpenID
* Providers MUST support the authorization_code and implicit Grant Type values and MAY support other Grant Types.
* If omitted, the default value is ["authorization_code", "implicit"].
*/
const GrantTypesSupported = 'grant_types_supported';
/**
* OPTIONAL. JSON array containing a list of the Authentication Context Class References that this OP supports.
*/
const AcrValuesSupported = 'acr_values_supported';
/**
* REQUIRED. JSON array containing a list of the Subject Identifier types that this OP supports.
* Valid types include pairwise and public.
*/
const SubjectTypesSupported = 'subject_types_supported';
/**
* REQUIRED. JSON array containing a list of the JWS signing algorithms (alg values) supported by the OP for the
* ID Token to encode the Claims in a JWT [JWT]. The algorithm RS256 MUST be included. The value none MAY be
* supported, but MUST NOT be used unless the Response Type used returns no ID Token from the Authorization Endpoint
* (such as when using the Authorization Code Flow).
*/
const IdTokenSigningAlgValuesSupported = 'id_token_signing_alg_values_supported';
/**
* OPTIONAL. JSON array containing a list of the JWE encryption algorithms (alg values) supported by the OP for the
* ID Token to encode the Claims in a JWT [JWT].
*/
const IdTokenEncryptionAlgValuesSupported = 'id_token_encryption_alg_values_supported';
/**
* OPTIONAL. JSON array containing a list of the JWE encryption algorithms (enc values) supported by the OP for the
* ID Token to encode the Claims in a JWT [JWT].
*/
const IdTokenEncryptionEncValuesSupported = 'id_token_encryption_enc_values_supported';
/**
* OPTIONAL. JSON array containing a list of the JWS [JWS] signing algorithms (alg values) [JWA] supported by the
* UserInfo Endpoint to encode the Claims in a JWT [JWT]. The value none MAY be included.
*/
const UserInfoSigningAlgValuesSupported = 'userinfo_signing_alg_values_supported';
/**
* OPTIONAL. JSON array containing a list of the JWE [JWE] encryption algorithms (alg values) [JWA] supported by
* the UserInfo Endpoint to encode the Claims in a JWT [JWT].
*/
const UserInfoEncryptionAlgValuesSupported = 'userinfo_encryption_alg_values_supported';
/**
* OPTIONAL. JSON array containing a list of the JWE encryption algorithms (enc values) [JWA] supported by the
* UserInfo Endpoint to encode the Claims in a JWT [JWT].
*/
const UserInfoEncryptionEncValuesSupported = 'userinfo_encryption_enc_values_supported';
/**
* OPTIONAL. JSON array containing a list of the JWS signing algorithms (alg values) supported by the OP for Request
* Objects, which are described in Section 6.1 of OpenID Connect Core 1.0 [OpenID.Core]. These algorithms are used
* both when the Request Object is passed by value (using the request parameter) and when it is passed by reference
* (using the request_uri parameter). Servers SHOULD support none and RS256.
*/
const RequestObjectSigningAlgValuesSupported = 'request_object_signing_alg_values_supported';
/**
* OPTIONAL. JSON array containing a list of the JWE encryption algorithms (alg values) supported by the OP for
* Request Objects. These algorithms are used both when the Request Object is passed by value and when it is passed
* by reference.
*/
const RequestObjectEncryptionAlgValuesSupported = 'request_object_encryption_alg_values_supported';
/**
* OPTIONAL. JSON array containing a list of the JWE encryption algorithms (enc values) supported by the OP for
* Request Objects. These algorithms are used both when the Request Object is passed by value and when it is passed
* by reference.
*/
const RequestObjectEncryptionEncValuesSupported = 'request_object_encryption_enc_values_supported';
/**
* OPTIONAL. JSON array containing a list of Client Authentication methods supported by this Token Endpoint.
* The options are client_secret_post, client_secret_basic, client_secret_jwt, and private_key_jwt, as described
* in Section 9 of OpenID Connect Core 1.0 [OpenID.Core]. Other authentication methods MAY be defined by extensions.
* If omitted, the default is client_secret_basic -- the HTTP Basic Authentication Scheme specified in Section 2.3.1
* of OAuth 2.0 [RFC6749].
*/
const TokenEndpointAuthMethodsSupported = 'token_endpoint_auth_methods_supported';
/**
* OPTIONAL. JSON array containing a list of the JWS signing algorithms (alg values) supported by the Token Endpoint
* for the signature on the JWT [JWT] used to authenticate the Client at the Token Endpoint for the private_key_jwt
* and client_secret_jwt authentication methods. Servers SHOULD support RS256. The value none MUST NOT be used.
*/
const TokenEndpointAuthSigningAlgValuesSupported = 'token_endpoint_auth_signing_alg_values_supported';
/**
* OPTIONAL. JSON array containing a list of the display parameter values that the OpenID Provider supports. These
* values are described in Section 3.1.2.1 of OpenID Connect Core 1.0 [OpenID.Core].
*/
const DisplayValuesSupported = 'display_values_supported';
/**
* OPTIONAL. JSON array containing a list of the Claim Types that the OpenID Provider supports. These Claim Types
* are described in Section 5.6 of OpenID Connect Core 1.0 [OpenID.Core]. Values defined by this specification are
* normal, aggregated, and distributed. If omitted, the implementation supports only normal Claims.
*/
const ClaimTypesSupported = 'claim_types_supported';
/**
* RECOMMENDED. JSON array containing a list of the Claim Names of the Claims that the OpenID Provider MAY be able
* to supply values for. Note that for privacy or other reasons, this might not be an exhaustive list.
*/
const ClaimsSupported = 'claims_supported';
/**
* OPTIONAL. URL of a page containing human-readable information that developers might want or need to know when
* using the OpenID Provider. In particular, if the OpenID Provider does not support Dynamic Client Registration,
* then information on how to register Clients needs to be provided in this documentation.
*/
const ServiceDocumentation = 'service_documentation';
/**
* OPTIONAL. Languages and scripts supported for values in Claims being returned, represented as a JSON array of
* BCP47 [RFC5646] language tag values. Not all languages and scripts are necessarily supported for all Claim values.
*/
const ClaimsLocalesSupported = 'claims_locales_supported';
/**
* OPTIONAL. Languages and scripts supported for the user interface, represented as a JSON array of BCP47 [RFC5646]
* language tag values.
*/
const UILocalesSupported = 'ui_locales_supported';
/**
* OPTIONAL. Boolean value specifying whether the OP supports use of the claims parameter, with true indicating
* support. If omitted, the default value is false.
*/
const ClaimsParameterSupported = 'claims_parameter_supported';
/**
* OPTIONAL. Boolean value specifying whether the OP supports use of the request parameter, with true indicating
* support. If omitted, the default value is false.
*/
const RequestParameterSupported = 'request_parameter_supported';
/**
* OPTIONAL. Boolean value specifying whether the OP supports use of the request_uri parameter, with true indicating
* support. If omitted, the default value is true.
*/
const RequestUrlParameterSupported = 'request_uri_parameter_supported';
/**
* OPTIONAL. Boolean value specifying whether the OP requires any request_uri values used to be pre-registered using
* the request_uris registration parameter. Pre-registration is REQUIRED when the value is true. If omitted, the
* default value is false.
*/
const RequireRequestUrlRegistration = 'require_request_uri_registration';
/**
* OPTIONAL. URL that the OpenID Provider provides to the person registering the Client to read about the OP's
* requirements on how the Relying Party can use the data provided by the OP. The registration process SHOULD
* display this URL to the person registering the Client if it is given.
*/
const PolicyUrl = 'op_policy_uri';
/**
* OPTIONAL. URL that the OpenID Provider provides to the person registering the Client to read about
* OpenID Provider's terms of service. The registration process SHOULD display this URL to the person registering
* the Client if it is given.
*/
const TOSUrl = 'op_tos_uri';
// http://openid.net/specs/openid-connect-session-1_0.html#OPMetadata
/**
* REQUIRED. URL of an OP iframe that supports cross-origin communications for session state information with the
* RP Client, using the HTML5 postMessage API. The page is loaded from an invisible iframe embedded in an RP page
* so that it can run in the OP's security context. It accepts postMessage requests from the relevant RP iframe and
* uses postMessage to post back the login status of the End-User at the OP.
*/
const CheckSessionIFrame = 'check_session_iframe';
/**
* REQUIRED. URL at the OP to which an RP can perform a redirect to request that the End-User be logged out at the OP.
*/
const EndSessionEndPoint = 'end_session_endpoint';
// extensions
const RevocationEndpoint = 'revocation_endpoint';
const IntrospectionEndpoint = 'introspection_endpoint';
}

View File

@ -18,11 +18,19 @@ use oauth2\IOAuth2Protocol;
* http://tools.ietf.org/html/rfc6749#section-3.1
* @package oauth2\endpoints
*/
class AuthorizationEndpoint implements IOAuth2Endpoint {
class AuthorizationEndpoint implements IOAuth2Endpoint
{
/**
* @var IOAuth2Protocol
*/
private $protocol;
public function __construct(IOAuth2Protocol $protocol){
/**
* @param IOAuth2Protocol $protocol
*/
public function __construct(IOAuth2Protocol $protocol)
{
$this->protocol = $protocol;
}

View File

@ -8,6 +8,11 @@ use oauth2\requests\OAuth2Request;
* Interface IOAuth2Endpoint
* @package oauth2\endpoints
*/
interface IOAuth2Endpoint {
interface IOAuth2Endpoint
{
/**
* @param OAuth2Request $request
* @return mixed
*/
public function handle(OAuth2Request $request);
}

View File

@ -20,13 +20,24 @@ use oauth2\requests\OAuth2Request;
class TokenEndpoint implements IOAuth2Endpoint
{
/**
* @var IOAuth2Protocol
*/
private $protocol;
/**
* @param IOAuth2Protocol $protocol
*/
public function __construct(IOAuth2Protocol $protocol)
{
$this->protocol = $protocol;
}
/**
* @param OAuth2Request $request
* @return mixed
* @throws InvalidGrantTypeException
*/
public function handle(OAuth2Request $request)
{
foreach ($this->protocol->getAvailableGrants() as $key => $grant) {

View File

@ -6,22 +6,58 @@ use oauth2\requests\OAuth2Request;
use oauth2\IOAuth2Protocol;
use oauth2\services\IClientService;
use oauth2\services\ITokenService;
use utils\services\IAuthService;
use utils\services\ILogService;
use oauth2\grant_types\ValidateBearerTokenGrantType;
use oauth2\exceptions\InvalidOAuth2Request;
/**
* Class TokenIntrospectionEndpoint
* @package oauth2\endpoints
*/
class TokenIntrospectionEndpoint implements IOAuth2Endpoint
{
class TokenIntrospectionEndpoint implements IOAuth2Endpoint {
/**
* @var IOAuth2Protocol
*/
private $protocol;
/**
* @var ValidateBearerTokenGrantType
*/
private $grant_type;
public function __construct(IOAuth2Protocol $protocol, IClientService $client_service, ITokenService $token_service, ILogService $log_service)
/**
* @param IOAuth2Protocol $protocol
* @param IClientService $client_service
* @param ITokenService $token_service
* @param IAuthService $auth_service
* @param ILogService $log_service
*/
public function __construct
(
IOAuth2Protocol $protocol,
IClientService $client_service,
ITokenService $token_service,
IAuthService $auth_service,
ILogService $log_service
)
{
$this->protocol = $protocol;
$this->grant_type = new ValidateBearerTokenGrantType($client_service, $token_service, $log_service);
$this->grant_type = new ValidateBearerTokenGrantType($client_service, $token_service, $auth_service, $log_service);
}
/**
* @param OAuth2Request $request
* @return mixed|\oauth2\responses\OAuth2AccessTokenValidationResponse|void
* @throws InvalidOAuth2Request
* @throws \oauth2\exceptions\BearerTokenDisclosureAttemptException
* @throws \oauth2\exceptions\ExpiredAccessTokenException
* @throws \oauth2\exceptions\InvalidApplicationType
* @throws \oauth2\exceptions\InvalidOAuth2Request
* @throws \oauth2\exceptions\LockedClientException
*/
public function handle(OAuth2Request $request)
{
if($this->grant_type->canHandle($request))

View File

@ -10,18 +10,48 @@ use oauth2\services\ITokenService;
use utils\services\ILogService;
use oauth2\grant_types\RevokeBearerTokenGrantType;
class TokenRevocationEndpoint implements IOAuth2Endpoint {
/**
* Class TokenRevocationEndpoint
* @package oauth2\endpoints
*/
class TokenRevocationEndpoint implements IOAuth2Endpoint
{
/**
* @var IOAuth2Protocol
*/
private $protocol;
/**
* @var RevokeBearerTokenGrantType
*/
private $grant_type;
public function __construct(IOAuth2Protocol $protocol, IClientService $client_service, ITokenService $token_service, ILogService $log_service)
/**
* @param IOAuth2Protocol $protocol
* @param IClientService $client_service
* @param ITokenService $token_service
* @param ILogService $log_service
*/
public function __construct(
IOAuth2Protocol $protocol,
IClientService $client_service,
ITokenService $token_service,
ILogService $log_service
)
{
$this->protocol = $protocol;
$this->grant_type = new RevokeBearerTokenGrantType($client_service, $token_service, $log_service);
}
/**
* @param OAuth2Request $request
* @return \oauth2\responses\OAuth2TokenRevocationResponse
* @throws InvalidOAuth2Request
* @throws \Exception
* @throws \oauth2\exceptions\BearerTokenDisclosureAttemptException
* @throws \oauth2\exceptions\ExpiredAccessTokenException
* @throws \oauth2\exceptions\UnAuthorizedClientException
*/
public function handle(OAuth2Request $request)
{
if($this->grant_type->canHandle($request))

View File

@ -0,0 +1,32 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\exceptions;
use Exception;
/**
* Class AbsentCurrentUserException
* @package oauth2\exceptions
*/
class AbsentCurrentUserException extends Exception
{
public function __construct($message = "")
{
$message = "Absent Current User Exception: " . $message;
parent::__construct($message, 0, null);
}
}

View File

@ -2,15 +2,19 @@
namespace oauth2\exceptions;
use Exception;
use oauth2\OAuth2Protocol;
class AccessDeniedException extends Exception
/**
* Class AccessDeniedException
* @package oauth2\exceptions
*/
final class AccessDeniedException extends OAuth2BaseException
{
public function __construct($message = "")
/**
* @return string
*/
public function getError()
{
$message = "Access Denied : " . $message;
parent::__construct($message, 0, null);
return OAuth2Protocol::OAuth2Protocol_Error_AccessDenied;
}
}

View File

@ -2,11 +2,19 @@
namespace oauth2\exceptions;
class BearerTokenDisclosureAttemptException extends OAuth2ClientBaseException
use oauth2\OAuth2Protocol;
/**
* Class BearerTokenDisclosureAttemptException
* @package oauth2\exceptions
*/
final class BearerTokenDisclosureAttemptException extends OAuth2BaseException
{
public function __construct($client_id,$message = "")
/**
* @return string
*/
public function getError()
{
$message = "Bearer Token Disclosure Attempt Attack: " . $message;
parent::__construct($client_id,$message);
return OAuth2Protocol::OAuth2Protocol_Error_InvalidGrant;
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\exceptions;
use Exception;
use oauth2\OAuth2Protocol;
/**
* Class InteractionRequiredException
* @package oauth2\exceptions
*/
final class ConsentRequiredException extends OAuth2BaseException
{
/**
* @return string
*/
public function getError()
{
return OAuth2Protocol::OAuth2Protocol_Error_Consent_Required;
}
}

View File

@ -14,19 +14,19 @@
namespace oauth2\exceptions;
use Exception;
use oauth2\OAuth2Protocol;
/**
* Class ExpiredAccessTokenException
* @package oauth2\exceptions
*/
class ExpiredAccessTokenException extends Exception
final class ExpiredAccessTokenException extends OAuth2BaseException
{
public function __construct($message = "")
/**
* @return string
*/
public function getError()
{
$message = "Expired Access Token: " . $message;
parent::__construct($message, 0, null);
return OAuth2Protocol::OAuth2Protocol_Error_InvalidToken;
}
}

View File

@ -3,14 +3,20 @@
namespace oauth2\exceptions;
use Exception;
use oauth2\OAuth2Protocol;
class ExpiredAuthorizationCodeException extends Exception
/**
* Class ExpiredAuthorizationCodeException
* @package oauth2\exceptions
*/
final class ExpiredAuthorizationCodeException extends OAuth2BaseException
{
public function __construct($message = "")
/**
* @return string
*/
public function getError()
{
$message = "Expired Authorization Code : " . $message;
parent::__construct($message, 0, null);
return OAuth2Protocol::OAuth2Protocol_Error_InvalidRequest;
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\exceptions;
use oauth2\OAuth2Protocol;
/**
* Class InteractionRequiredException
* @package oauth2\exceptions
*/
final class InteractionRequiredException extends OAuth2BaseException
{
/**
* @return string
*/
public function getError()
{
return OAuth2Protocol::OAuth2Protocol_Error_Interaction_Required;
}
}

View File

@ -2,15 +2,19 @@
namespace oauth2\exceptions;
use Exception;
use oauth2\OAuth2Protocol;
class InvalidAccessTokenException extends Exception
/**
* Class InvalidAccessTokenException
* @package oauth2\exceptions
*/
final class InvalidAccessTokenException extends OAuth2BaseException
{
public function __construct($message = "")
/**
* @return string
*/
public function getError()
{
$message = "Invalid Access Token : " . $message;
parent::__construct($message, 0, null);
return OAuth2Protocol::OAuth2Protocol_Error_InvalidGrant;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
* Copyright 2015 Openstack Foundation
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@ -12,13 +12,13 @@
* limitations under the License.
**/
namespace oauth2\exceptions;
/**
* Interface IBaseRepository
* Class InvalidApiScopeGroup
* @package oauth2\exceptions
*/
interface IBaseRepository {
/**
* @param int $id
* @return IEntity
*/
public function getById($id);
final class InvalidApiScopeGroup extends \Exception
{
}

View File

@ -2,11 +2,19 @@
namespace oauth2\exceptions;
class InvalidApplicationType extends OAuth2ClientBaseException
use oauth2\OAuth2Protocol;
/**
* Class InvalidApplicationType
* @package oauth2\exceptions
*/
final class InvalidApplicationType extends OAuth2BaseException
{
public function __construct($client_id, $message = "")
/**
* @return string
*/
public function getError()
{
$message = "Invalid Application Type: " . $message;
parent::__construct($client_id,$message);
return OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient;
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\exceptions;
use oauth2\OAuth2Protocol;
/**
* Class InvalidAuthenticationRequestException
* @package oauth2\exceptions
*/
final class InvalidAuthenticationRequestException extends OAuth2BaseException
{
/**
* @return string
*/
public function getError()
{
return OAuth2Protocol::OAuth2Protocol_Error_InvalidRequest;
}
}

View File

@ -2,15 +2,20 @@
namespace oauth2\exceptions;
use Exception;
use oauth2\OAuth2Protocol;
class InvalidAuthorizationCodeException extends Exception
/**
* Class InvalidAuthorizationCodeException
* @package oauth2\exceptions
*/
final class InvalidAuthorizationCodeException extends OAuth2BaseException
{
public function __construct($message = "")
/**
* @return string
*/
public function getError()
{
$message = "Invalid Authorization Code : " . $message;
parent::__construct($message, 0, null);
return OAuth2Protocol::OAuth2Protocol_Error_InvalidGrant;
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\exceptions;
use Exception;
/**
* Class InvalidClientAssertionAlgorithmException
* @package oauth2\exceptions
*/
final class InvalidClientAssertionAlgorithmException extends Exception
{
/**
* @param string $message
*/
public function __construct($message = "")
{
$message = "Invalid Client Assertion Algorithm : " . $message;
parent::__construct($message, 0, null);
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\exceptions;
use Exception;
/**
* Class InvalidClientAssertionException
* @package oauth2\exceptions
*/
final class InvalidClientAssertionException extends Exception
{
/**
* @param string $message
*/
public function __construct($message = "")
{
$message = "Invalid Client Assertion : " . $message;
parent::__construct($message, 0, null);
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\exceptions;
use Exception;
/**
* Class InvalidClientAssertionTypeException
* @package oauth2\exceptions
*/
final class InvalidClientAssertionTypeException extends Exception
{
/**
* @param string $message
*/
public function __construct($message = "")
{
$message = "Invalid Client Assertion Type : " . $message;
parent::__construct($message, 0, null);
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\exceptions;
use oauth2\OAuth2Protocol;
/**
* Class InvalidClientAuthMethodException
* @package oauth2\exceptions
*/
final class InvalidClientAuthMethodException extends OAuth2BaseException
{
/**
* @return string
*/
public function getError()
{
return OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient;
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\exceptions;
use Exception;
/**
* Class InvalidClientAuthenticationContextException
* @package oauth2\exceptions
*/
final class InvalidClientAuthenticationContextException extends Exception
{
/**
* @param string $message
*/
public function __construct($message = "")
{
$message = "Invalid Client Authentication Context : " . $message;
parent::__construct($message, 0, null);
}
}

View File

@ -2,11 +2,19 @@
namespace oauth2\exceptions;
class InvalidClientCredentials extends OAuth2ClientBaseException
use oauth2\OAuth2Protocol;
/**
* Class InvalidClientCredentials
* @package oauth2\exceptions
*/
final class InvalidClientCredentials extends OAuth2BaseException
{
public function __construct($client_id, $message = "")
/**
* @return string
*/
public function getError()
{
$message = "Invalid Client Credentials : " . $message;
parent::__construct($client_id, $message);
return OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient;
}
}

View File

@ -2,11 +2,20 @@
namespace oauth2\exceptions;
class InvalidClientException extends OAuth2ClientBaseException
use oauth2\OAuth2Protocol;
/**
* Class InvalidClientException
* @package oauth2\exceptions
*/
final class InvalidClientException extends OAuth2BaseException
{
public function __construct($client_id, $message = "")
/**
* @return string
*/
public function getError()
{
$message = "Invalid OAuth2 Client : " . $message;
parent::__construct($client_id, $message);
return OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient;
}
}

View File

@ -2,11 +2,19 @@
namespace oauth2\exceptions;
class InvalidClientType extends OAuth2ClientBaseException
use oauth2\OAuth2Protocol;
/**
* Class InvalidClientType
* @package oauth2\exceptions
*/
final class InvalidClientType extends OAuth2BaseException
{
public function __construct($client_id, $message = "")
/**
* @return string
*/
public function getError()
{
$message = "Invalid Client Type: " . $message;
parent::__construct($client_id,$message);
return OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient;
}
}

View File

@ -1,15 +1,20 @@
<?php
namespace oauth2\exceptions;
use Exception;
class InvalidGrantTypeException extends Exception
use oauth2\OAuth2Protocol;
/**
* Class InvalidGrantTypeException
* @package oauth2\exceptions
*/
final class InvalidGrantTypeException extends OAuth2BaseException
{
public function __construct($message = "")
/**
* @return string
*/
public function getError()
{
$message = "Invalid Grant Type : " . $message;
parent::__construct($message, 0, null);
return OAuth2Protocol::OAuth2Protocol_Error_InvalidGrant;
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\exceptions;
use oauth2\OAuth2Protocol;
/***
* Class InvalidLoginHint
* @package oauth2\exceptions
*/
final class InvalidLoginHint extends OAuth2BaseException
{
/**
* @return string
*/
public function getError()
{
return OAuth2Protocol::OAuth2Protocol_Error_InvalidRequest;
}
}

View File

@ -2,15 +2,21 @@
namespace oauth2\exceptions;
use Exception;
use oauth2\OAuth2Protocol;
class InvalidOAuth2Request extends Exception
/**
* Class InvalidOAuth2Request
* @package oauth2\exceptions
*/
final class InvalidOAuth2Request extends OAuth2BaseException
{
public function __construct($message = "")
/**
* @return string
*/
public function getError()
{
$message = "Invalid OAuth2 Request : " . $message;
parent::__construct($message, 0, null);
return OAuth2Protocol::OAuth2Protocol_Error_InvalidRequest;
}
}

View File

@ -2,11 +2,19 @@
namespace oauth2\exceptions;
class InvalidRedeemAuthCodeException extends OAuth2ClientBaseException{
use oauth2\OAuth2Protocol;
public function __construct($client_id, $message = "")
/**
* Class InvalidRedeemAuthCodeException
* @package oauth2\exceptions
*/
final class InvalidRedeemAuthCodeException extends OAuth2BaseException
{
/**
* @return string
*/
public function getError()
{
$message = "Invalid Redeem AuthCode Exception: " . $message;
parent::__construct($client_id,$message);
return OAuth2Protocol::OAuth2Protocol_Error_InvalidGrant;
}
}
}

View File

@ -0,0 +1,30 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\exceptions;
use Exception;
/**
* Class InvalidTokenEndpointAuthMethodException
* @package oauth2\exceptions
*/
final class InvalidTokenEndpointAuthMethodException extends Exception
{
public function __construct($message = "")
{
$message = "Invalid Token Endpoint Auth Method : " . $message;
parent::__construct($message, 0, null);
}
}

View File

@ -2,11 +2,19 @@
namespace oauth2\exceptions;
class LockedClientException extends OAuth2ClientBaseException
use oauth2\OAuth2Protocol;
/**
* Class LockedClientException
* @package oauth2\exceptions
*/
final class LockedClientException extends OAuth2BaseException
{
public function __construct($client_id, $message = "")
/**
* @return string
*/
public function getError()
{
$message = "Locked Client Exception: " . $message;
parent::__construct($client_id,$message);
return OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient;
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\exceptions;
use oauth2\OAuth2Protocol;
/**
* Class InteractionRequiredException
* @package oauth2\exceptions
*/
final class LoginRequiredException extends OAuth2BaseException
{
/**
* @return string
*/
public function getError()
{
return OAuth2Protocol::OAuth2Protocol_Error_Login_Required;
}
}

View File

@ -3,14 +3,19 @@
namespace oauth2\exceptions;
use Exception;
use oauth2\OAuth2Protocol;
class MissingClientAuthorizationInfo extends Exception
/**
* Class MissingClientAuthorizationInfo
* @package oauth2\exceptions
*/
final class MissingClientAuthorizationInfo extends OAuth2BaseException
{
public function __construct($message = "")
/**
* @return string
*/
public function getError()
{
$message = "Missing Client Authorization Info: " . $message;
parent::__construct($message, 0, null);
return OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient;
}
}

View File

@ -3,14 +3,19 @@
namespace oauth2\exceptions;
use Exception;
use oauth2\OAuth2Protocol;
class MissingClientIdParam extends Exception
/**
* Class MissingClientIdParam
* @package oauth2\exceptions
*/
final class MissingClientIdParam extends OAuth2BaseException
{
public function __construct($message = "")
/**
* @return string
*/
public function getError()
{
$message = "Missing ClientId Param: " . $message;
parent::__construct($message, 0, null);
return OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient;
}
}

View File

@ -0,0 +1,39 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\exceptions;
use Exception;
/**
* Class OAuth2BaseException
* @package oauth2\exceptions
*/
abstract class OAuth2BaseException extends Exception
{
/**
* @param string $description
*/
public function __construct($description = null)
{
parent::__construct($description);
}
/**
* @return string
*/
abstract public function getError();
}

View File

@ -2,15 +2,19 @@
namespace oauth2\exceptions;
use Exception;
use oauth2\OAuth2Protocol;
class OAuth2GenericException extends Exception
/**
* Class OAuth2GenericException
* @package oauth2\exceptions
*/
final class OAuth2GenericException extends OAuth2BaseException
{
public function __construct($message = "")
/**
* @return string
*/
public function getError()
{
$message = "OAuth2 Generic Exception : " . $message;
parent::__construct($message, 0, null);
return OAuth2Protocol::OAuth2Protocol_Error_ServerError;
}
}

View File

@ -4,13 +4,36 @@ namespace oauth2\exceptions;
use Exception;
class OAuth2ResourceServerException extends Exception{
/**
* Class OAuth2ResourceServerException
* @package oauth2\exceptions
*/
class OAuth2ResourceServerException extends Exception
{
/**
* @var string
*/
private $http_code;
/**
* @var int
*/
private $error;
/**
* @var Exception
*/
private $error_description;
/**
* @var null
*/
private $scope;
/**
* @param string $http_code
* @param int $error
* @param Exception $error_description
* @param null $scope
*/
public function __construct($http_code,$error,$error_description,$scope = null)
{
$this->http_code = $http_code;
@ -21,19 +44,23 @@ class OAuth2ResourceServerException extends Exception{
parent::__construct($message, 0, null);
}
public function getError(){
public function getError()
{
return $this->error;
}
public function getErrorDescription(){
public function getErrorDescription()
{
return $this->error_description;
}
public function getScope(){
public function getScope()
{
return $this->scope;
}
public function getHttpCode(){
public function getHttpCode()
{
return $this->http_code;
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\exceptions;
use oauth2\OAuth2Protocol;
/**
* Class RecipientKeyNotFoundException
* @package oauth2\exceptions
*/
final class RecipientKeyNotFoundException extends OAuth2BaseException
{
/**
* @return string
*/
public function getError()
{
return OAuth2Protocol::OAuth2Protocol_Error_Invalid_Recipient_Keys;
}
}

View File

@ -2,20 +2,41 @@
namespace oauth2\exceptions;
use Exception;
use oauth2\OAuth2Protocol;
class ReplayAttackException extends Exception
/**
* Class ReplayAttackException
* @package oauth2\exceptions
*/
final class ReplayAttackException extends OAuth2BaseException
{
private $auth_code;
public function getAuthCode(){
return $this->auth_code;
}
public function __construct($auth_code,$message = "")
/**
* @param null|string $code
* @param null $description
*/
public function __construct($token, $description = null)
{
$this->auth_code = $auth_code;
$message = "Possible Replay Attack : " . $message;
parent::__construct($message, 0, null);
$this->token = $token;
parent::__construct($description);
}
/**
* @var string
*/
private $token;
/**
* @return string
*/
public function getToken()
{
return $this->token;
}
/**
* @return string
*/
public function getError()
{
return OAuth2Protocol::OAuth2Protocol_Error_InvalidGrant;
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\exceptions;
use oauth2\OAuth2Protocol;
/**
* Class RevokedAccessTokenException
* @package oauth2\exceptions
*/
final class RevokedAccessTokenException extends OAuth2BaseException
{
/**
* @return string
*/
public function getError()
{
return OAuth2Protocol::OAuth2Protocol_Error_InvalidToken;
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\exceptions;
use oauth2\OAuth2Protocol;
/**
* Class RevokedRefreshTokenException
* @package oauth2\exceptions
*/
class RevokedRefreshTokenException extends OAuth2BaseException
{
/**
* @return string
*/
public function getError()
{
return OAuth2Protocol::OAuth2Protocol_Error_InvalidToken;
}
}

View File

@ -2,13 +2,20 @@
namespace oauth2\exceptions;
use Exception;
use oauth2\OAuth2Protocol;
class ScopeNotAllowedException extends Exception
/**
* Class ScopeNotAllowedException
* @package oauth2\exceptions
*/
final class ScopeNotAllowedException extends OAuth2BaseException
{
public function __construct($message = "")
/**
* @return string
*/
public function getError()
{
$message = "Scope Not Allowed : " . $message;
parent::__construct($message, 0, null);
return OAuth2Protocol::OAuth2Protocol_Error_InvalidScope;
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
namespace oauth2\exceptions;
use oauth2\OAuth2Protocol;
/**
* Class ServerKeyNotFoundException
* @package oauth2\exceptions
*/
final class ServerKeyNotFoundException extends OAuth2BaseException
{
/**
* @return string
*/
public function getError()
{
return OAuth2Protocol::OAuth2Protocol_Error_Invalid_Server_Keys;
}
}

View File

@ -2,11 +2,19 @@
namespace oauth2\exceptions;
class UnAuthorizedClientException extends OAuth2ClientBaseException
use oauth2\OAuth2Protocol;
/**
* Class UnAuthorizedClientException
* @package oauth2\exceptions
*/
final class UnAuthorizedClientException extends OAuth2BaseException
{
public function __construct($client_id, $message = "")
/**
* @return string
*/
public function getError()
{
$message = "UnAuthorized Client: " . $message;
parent::__construct($client_id,$message);
return OAuth2Protocol::OAuth2Protocol_Error_UnauthorizedClient;
}
}

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