From d1e6d73f8f0bc59ca5959bf31dad3da890f1bf32 Mon Sep 17 00:00:00 2001 From: smarcet Date: Thu, 17 Oct 2013 18:43:55 -0300 Subject: [PATCH] [smarcet] - Refs #4578- OpenId - Server Core Logic - Authentication Workflow --- .idea/workspace.xml | 617 ++++++++++++------ app/config/app.php | 3 +- app/controllers/UserController.php | 29 +- ...13_10_14_155702_create_extension_table.php | 2 +- .../2013_10_17_210518_create_users_table.php | 35 + ...10_17_210730_create_associations_table.php | 31 + ...0_17_211051_create_trusted_sites_table.php | 28 + ...10_17_211839_alter_trusted_sites_table.php | 33 + app/libs/auth/AuthService.php | 17 +- app/libs/auth/CustomUser.php | 35 - app/libs/auth/OpenIdUser.php | 91 +++ app/libs/openid/OpenIdMessage.php | 19 +- app/libs/openid/OpenIdProtocol.php | 95 ++- ...InvalidOpenIdAuthenticationRequestMode.php | 20 + .../exceptions/InvalidOpenIdMessageMode.php | 20 + .../InvalidRequestContextException.php | 20 + .../openid/extensions/IOpenIdExtension.php | 21 + .../implementations/OpenIdAXExtension.php | 30 + .../implementations/OpenIdOAuthExtension.php | 28 + .../implementations/OpenIdPAPEExtension.php | 28 + .../implementations/OpenIdSREGExtension.php | 29 + .../IOpenIdAuthenticationStrategy.php | 7 +- .../OpenIdAuthenticationRequestHandler.php | 183 +++++- .../handlers/OpenIdVoidRequestHandler.php | 15 - .../openid/helpers/OpenIdCryptoHelper.php | 124 ++++ .../openid/helpers/OpenIdErrorMessages.php | 15 + .../openid/helpers/OpenIdSignatureBuilder.php | 39 ++ app/libs/openid/helpers/OpenIdUriHelper.php | 214 ++++++ app/libs/openid/model/IAssociation.php | 35 + app/libs/openid/model/IOpenIdUser.php | 26 + app/libs/openid/model/ITrustedSite.php | 25 + .../IServerExtensionsRepository.php | 4 +- .../requests/OpenIdAuthenticationRequest.php | 45 +- .../openid/requests/contexts/PartialView.php | 30 + .../requests/contexts/RequestContext.php | 48 ++ .../OpenIdDirectGenericErrorResponse.php | 8 +- .../OpenIdImmediateNegativeAssertion.php | 21 + .../OpenIdIndirectGenericErrorResponse.php | 28 + .../responses/OpenIdIndirectResponse.php | 13 +- .../OpenIdNonImmediateNegativeAssertion.php | 19 + .../OpenIdPositiveAssertionResponse.php | 45 ++ app/libs/openid/responses/OpenIdResponse.php | 7 +- .../responses/contexts/ResponseContext.php | 33 + .../openid/services/IAssociationService.php | 31 + app/libs/openid/services/IAuthService.php | 15 +- .../services/IServerConfigurationService.php | 15 + .../services/IServerExtensionsService.php | 15 + .../openid/services/ITrustedSitesService.php | 23 + .../strategies/IOpenIdResponseStrategy.php | 4 +- app/models/OpenIdAssociation.php | 67 ++ app/models/OpenIdTrustedSite.php | 47 ++ app/models/User.php | 52 -- .../ServerExtensionsRepositoryEloquent.php | 2 +- app/services/AuthenticationStrategy.php | 10 +- app/services/ServerExtensionsService.php | 20 + app/services/ServicesProvider.php | 2 + .../OpenIdDirectResponseStrategy.php | 22 + .../OpenIdIndirectResponseStrategy.php | 22 + .../OpenIdResponseStrategyProvider.php | 19 + app/views/extensions/ax.blade.php | 0 app/views/extensions/oauth.blade.php | 0 app/views/extensions/pape.blade.php | 4 + app/views/extensions/sreg.blade.php | 0 app/views/login.blade.php | 4 + composer.json | 3 +- 65 files changed, 2208 insertions(+), 384 deletions(-) create mode 100644 app/database/migrations/2013_10_17_210518_create_users_table.php create mode 100644 app/database/migrations/2013_10_17_210730_create_associations_table.php create mode 100644 app/database/migrations/2013_10_17_211051_create_trusted_sites_table.php create mode 100644 app/database/migrations/2013_10_17_211839_alter_trusted_sites_table.php delete mode 100644 app/libs/auth/CustomUser.php create mode 100644 app/libs/auth/OpenIdUser.php create mode 100644 app/libs/openid/exceptions/InvalidOpenIdAuthenticationRequestMode.php create mode 100644 app/libs/openid/exceptions/InvalidOpenIdMessageMode.php create mode 100644 app/libs/openid/exceptions/InvalidRequestContextException.php create mode 100644 app/libs/openid/extensions/IOpenIdExtension.php create mode 100644 app/libs/openid/extensions/implementations/OpenIdAXExtension.php create mode 100644 app/libs/openid/extensions/implementations/OpenIdOAuthExtension.php create mode 100644 app/libs/openid/extensions/implementations/OpenIdPAPEExtension.php create mode 100644 app/libs/openid/extensions/implementations/OpenIdSREGExtension.php delete mode 100644 app/libs/openid/handlers/OpenIdVoidRequestHandler.php create mode 100644 app/libs/openid/helpers/OpenIdCryptoHelper.php create mode 100644 app/libs/openid/helpers/OpenIdErrorMessages.php create mode 100644 app/libs/openid/helpers/OpenIdSignatureBuilder.php create mode 100644 app/libs/openid/helpers/OpenIdUriHelper.php create mode 100644 app/libs/openid/model/IAssociation.php create mode 100644 app/libs/openid/model/IOpenIdUser.php create mode 100644 app/libs/openid/model/ITrustedSite.php create mode 100644 app/libs/openid/requests/contexts/PartialView.php create mode 100644 app/libs/openid/requests/contexts/RequestContext.php create mode 100644 app/libs/openid/responses/OpenIdImmediateNegativeAssertion.php create mode 100644 app/libs/openid/responses/OpenIdIndirectGenericErrorResponse.php create mode 100644 app/libs/openid/responses/OpenIdNonImmediateNegativeAssertion.php create mode 100644 app/libs/openid/responses/OpenIdPositiveAssertionResponse.php create mode 100644 app/libs/openid/responses/contexts/ResponseContext.php create mode 100644 app/libs/openid/services/IAssociationService.php create mode 100644 app/libs/openid/services/IServerConfigurationService.php create mode 100644 app/libs/openid/services/IServerExtensionsService.php create mode 100644 app/libs/openid/services/ITrustedSitesService.php create mode 100644 app/models/OpenIdAssociation.php create mode 100644 app/models/OpenIdTrustedSite.php delete mode 100644 app/models/User.php create mode 100644 app/services/ServerExtensionsService.php create mode 100644 app/strategies/OpenIdDirectResponseStrategy.php create mode 100644 app/strategies/OpenIdIndirectResponseStrategy.php create mode 100644 app/strategies/OpenIdResponseStrategyProvider.php create mode 100644 app/views/extensions/ax.blade.php create mode 100644 app/views/extensions/oauth.blade.php create mode 100644 app/views/extensions/pape.blade.php create mode 100644 app/views/extensions/sreg.blade.php diff --git a/.idea/workspace.xml b/.idea/workspace.xml index cee070cd..aac0ba07 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,126 +1,273 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + - - - - - - + - + - + - - + + - - + + - + - + - + - + - + - + - - - - - - - - - - - + + + + + + + + + + + - + - - + + - + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -161,22 +354,22 @@ @@ -215,7 +408,7 @@ - + @@ -234,6 +427,7 @@ + @@ -252,6 +446,20 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - + + @@ -332,8 +597,8 @@ - - + + @@ -373,19 +638,23 @@ 1381763171476 1381763171476 + + 1381940958233 + 1381940958233 + + - + - - - + + @@ -393,6 +662,8 @@ + + @@ -440,7 +711,7 @@ - - file://$PROJECT_DIR$/app/libs/auth/AuthService.php - 21 - file://$PROJECT_DIR$/app/libs/auth/CustomAuthProvider.php 43 @@ -473,21 +740,6 @@ 57 - - file://$PROJECT_DIR$/app/libs/auth/CustomUser.php - 31 - - - file://$PROJECT_DIR$/app/libs/auth/CustomUser.php - 21 - - - file://$PROJECT_DIR$/app/controllers/UserController.php - 33 - file://$PROJECT_DIR$/vendor/laravel/framework/src/Illuminate/Auth/Guard.php 271 @@ -498,11 +750,6 @@ 61 - - file://$PROJECT_DIR$/app/filters.php - 100 - file://$PROJECT_DIR$/app/controllers/HomeController.php 7 @@ -518,134 +765,140 @@ 297 + + file://$PROJECT_DIR$/vendor/laravel/framework/src/Illuminate/Routing/Redirector.php + 114 + - - + - + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - diff --git a/app/config/app.php b/app/config/app.php index e6fb4102..5d5fd808 100644 --- a/app/config/app.php +++ b/app/config/app.php @@ -116,7 +116,8 @@ return array( 'openid\OpenIdServiceProvider', 'repositories\RepositoriesServiceProvider', 'auth\AuthenticationServiceProvider', - 'services\ServicesProvider' + 'services\ServicesProvider', + 'strategies\OpenIdResponseStrategyProvider' ), /* diff --git a/app/controllers/UserController.php b/app/controllers/UserController.php index 49ee4d48..460abdd8 100644 --- a/app/controllers/UserController.php +++ b/app/controllers/UserController.php @@ -9,7 +9,7 @@ use openid\services\IMementoOpenIdRequestService; use openid\services\IAuthService; use openid\requests\OpenIdAuthenticationRequest; - +use openid\exceptions\InvalidRequestContextException; class UserController extends BaseController{ @@ -25,13 +25,26 @@ class UserController extends BaseController{ $this->beforeFilter('openid.needs.auth.request',array('only' => array('getLogin', 'getConsent'))); } - public function getLogin(){ + private function getViewData(){ + $context = Session::get('context'); + if(is_null($context)) + throw new InvalidRequestContextException(); + $partial_views = $context->getPartials(); + $data = array(); + $views = array(); + foreach($partial_views as $partial){ + $views[$partial->getName()] = View::make($partial->getName(),$partial->getData()); + } + $data["views"]=$views; + return $data; + } - return View::make("login"); + public function getLogin(){ + $data = $this->getViewData(); + return View::make("login",$data); } public function postLogin(){ - $data = Input::all(); // Build the validation constraint set. $rules = array( @@ -44,7 +57,8 @@ class UserController extends BaseController{ $username = Input::get("username"); $password = Input::get("password"); if($this->auth_service->Login($username,$password)){ - return Redirect::to('/accounts/user/consent'); + //go to authentication flow again + return Redirect::action("OpenIdProviderController@op_endpoint"); } return Redirect::action('UserController@getLogin')->with('flash_notice', 'Authentication Failed!'); } @@ -52,11 +66,12 @@ class UserController extends BaseController{ } public function getConsent(){ - return View::make("consent")->with("realm","test"); + $data = $this->getViewData(); + $data["realm"] ="test"; + return View::make("consent",$data); } public function postConsent(){ - return Redirect::to('/accounts/openid/v2'); } } \ No newline at end of file diff --git a/app/database/migrations/2013_10_14_155702_create_extension_table.php b/app/database/migrations/2013_10_14_155702_create_extension_table.php index 2777cae7..239d65f8 100644 --- a/app/database/migrations/2013_10_14_155702_create_extension_table.php +++ b/app/database/migrations/2013_10_14_155702_create_extension_table.php @@ -13,7 +13,7 @@ class CreateExtensionTable extends Migration { { Schema::create('server_extensions', function($table) { - $table->increments('id'); + $table->bigIncrements('id'); $table->string('name',100); $table->string('namespace',255); $table->boolean('active'); diff --git a/app/database/migrations/2013_10_17_210518_create_users_table.php b/app/database/migrations/2013_10_17_210518_create_users_table.php new file mode 100644 index 00000000..01237a09 --- /dev/null +++ b/app/database/migrations/2013_10_17_210518_create_users_table.php @@ -0,0 +1,35 @@ +bigIncrements('id'); + $table->string('identifier',255); + $table->string('external_id',100); + $table->boolean('active'); + $table->dateTime('last_login_date'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('openid_users'); + } + +} \ No newline at end of file diff --git a/app/database/migrations/2013_10_17_210730_create_associations_table.php b/app/database/migrations/2013_10_17_210730_create_associations_table.php new file mode 100644 index 00000000..df37f303 --- /dev/null +++ b/app/database/migrations/2013_10_17_210730_create_associations_table.php @@ -0,0 +1,31 @@ +bigIncrements('id'); + $table->string('identifier',255); + $table->string('mac_function',100); + $table->string('secret',1024); + $table->smallInteger('type'); + $table->integer('lifetime'); + $table->dateTime('issued'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('openid_associations'); + } + +} \ No newline at end of file diff --git a/app/database/migrations/2013_10_17_211051_create_trusted_sites_table.php b/app/database/migrations/2013_10_17_211051_create_trusted_sites_table.php new file mode 100644 index 00000000..2cf9b9b7 --- /dev/null +++ b/app/database/migrations/2013_10_17_211051_create_trusted_sites_table.php @@ -0,0 +1,28 @@ +bigIncrements('id'); + $table->string('realm',255); + $table->string('data',1024); + $table->string('policy',100); + $table->bigInteger("user_id")->unsigned(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('openid_trusted_sites'); + } +} \ No newline at end of file diff --git a/app/database/migrations/2013_10_17_211839_alter_trusted_sites_table.php b/app/database/migrations/2013_10_17_211839_alter_trusted_sites_table.php new file mode 100644 index 00000000..9e33b1df --- /dev/null +++ b/app/database/migrations/2013_10_17_211839_alter_trusted_sites_table.php @@ -0,0 +1,33 @@ +index('user_id'); + $table->foreign('user_id')->references('id')->on('openid_users'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('openid_trusted_sites', function($table) + { + $table->dropForeign('user_id'); + }); + } +} \ No newline at end of file diff --git a/app/libs/auth/AuthService.php b/app/libs/auth/AuthService.php index 5695bdc6..29d24bde 100644 --- a/app/libs/auth/AuthService.php +++ b/app/libs/auth/AuthService.php @@ -8,6 +8,7 @@ */ namespace auth; +use openid\services\AuthorizationResponse_; use openid\services\IAuthService; use \Auth; use \Session; @@ -40,15 +41,15 @@ class AuthService implements IAuthService { return Auth::attempt(array('username' => $username, 'password' => $password), true); } - /** - * @return mixed - */ - public function isUserAuthorized() - { - return Session::get("authorized_state"); - } - public function logout(){ Auth::logout(); } + + /** + * @return AuthorizationResponse_* + */ + public function getUserAuthorizationResponse() + { + return Session::get("openid.authorization.response"); + } } \ No newline at end of file diff --git a/app/libs/auth/CustomUser.php b/app/libs/auth/CustomUser.php deleted file mode 100644 index 9547263d..00000000 --- a/app/libs/auth/CustomUser.php +++ /dev/null @@ -1,35 +0,0 @@ -container = $values; } @@ -45,13 +42,19 @@ class OpenIdMessage implements \ArrayAccess { public function getMode(){ - return $this->container[self::ModeType]; + return $this->container[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode,"_")]; + } + + protected function setMode($mode){ + if(!OpenIdProtocol::isValidMode($mode)) + throw new InvalidOpenIdMessageMode($mode); + $this->container[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode)]=$mode;; } public function IsValid(){ - if (isset($this->container[self::NSType]) - && $this->container[self::NSType] == self::OpenID2MessageType - && isset($this->container[self::ModeType])){ + if (isset($this->container[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS,"_")]) + && $this->container[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS,"_")] == OpenIdProtocol::OpenID2MessageType + && isset($this->container[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode,"_")])){ return true; } return false; diff --git a/app/libs/openid/OpenIdProtocol.php b/app/libs/openid/OpenIdProtocol.php index dcdd78d6..34b8dd69 100644 --- a/app/libs/openid/OpenIdProtocol.php +++ b/app/libs/openid/OpenIdProtocol.php @@ -23,8 +23,84 @@ use openid\IOpenIdProtocol; class OpenIdProtocol implements IOpenIdProtocol { - const OPIdentifierType = "http://specs.openid.net/auth/2.0/server"; - const ClaimedIdentifierType = "http://specs.openid.net/auth/2.0/signon"; + const OpenIdPrefix = "openid"; + //protocol constants + const OPIdentifierType = "http://specs.openid.net/auth/2.0/server"; + const ClaimedIdentifierType = "http://specs.openid.net/auth/2.0/signon"; + const OpenID2MessageType = "http://specs.openid.net/auth/2.0"; + const IdentifierSelectType = "http://specs.openid.net/auth/2.0/identifier_select"; + + const ImmediateMode = "checkid_immediate"; + const SetupMode = "checkid_setup"; + const IdMode = "id_res"; + const SetupNeededMode = "setup_needed"; + const CancelMode = "cancel"; + const CheckAuthenticationMode = "check_authentication"; + const ErrorMode = "error"; + const AssociateMode = "associate"; + + const SignatureAlgorithmHMAC_SHA1 = "HMAC-SHA1"; + const SignatureAlgorithmHMAC_SHA256 = "HMAC-SHA256"; + + const OpenIDProtocol_Mode = "mode"; + const OpenIDProtocol_NS = "ns"; + const OpenIDProtocol_ReturnTo = "return_to"; + const OpenIDProtocol_ClaimedId = "claimed_id"; + const OpenIDProtocol_Identity = "identity"; + const OpenIDProtocol_AssocHandle = "assoc_handle"; + const OpenIDProtocol_Realm = "realm"; + const OpenIDProtocol_OpEndpoint = "op_endpoint"; + const OpenIDProtocol_Nonce = "response_nonce"; + const OpenIDProtocol_InvalidateHandle = "invalidate_handle"; + const OpenIDProtocol_Signed = "signed"; + const OpenIDProtocol_Sig = "sig"; + const OpenIDProtocol_Error = "error"; + const OpenIDProtocol_Contact = "contact"; + const OpenIDProtocol_Reference = "reference"; + + + + private static $OpenIDProtocol_ValidModes = array( + self::ImmediateMode, + self::SetupMode, + self::IdMode, + self::SetupNeededMode, + self::CancelMode, + self::CheckAuthenticationMode, + self::ErrorMode, + self::AssociateMode, + ); + + private static $protocol_definition = array( + self::OpenIDProtocol_Mode => self::OpenIDProtocol_Mode, + self::OpenIDProtocol_NS => self::OpenIDProtocol_NS, + self::OpenIDProtocol_ReturnTo => self::OpenIDProtocol_ReturnTo, + self::OpenIDProtocol_ClaimedId => self::OpenIDProtocol_ClaimedId, + self::OpenIDProtocol_Identity => self::OpenIDProtocol_Identity, + self::OpenIDProtocol_AssocHandle => self::OpenIDProtocol_AssocHandle, + self::OpenIDProtocol_Realm => self::OpenIDProtocol_Realm, + self::OpenIDProtocol_OpEndpoint => self::OpenIDProtocol_OpEndpoint, + self::OpenIDProtocol_Nonce => self::OpenIDProtocol_Nonce, + self::OpenIDProtocol_InvalidateHandle => self::OpenIDProtocol_InvalidateHandle, + self::OpenIDProtocol_Signed => self::OpenIDProtocol_Signed, + self::OpenIDProtocol_Sig => self::OpenIDProtocol_Sig, + self::OpenIDProtocol_Error => self::OpenIDProtocol_Error, + self::OpenIDProtocol_Contact => self::OpenIDProtocol_Contact, + self::OpenIDProtocol_Reference => self::OpenIDProtocol_Reference, + ); + + /** + * check if a provide message mode is valid or not in openid 2.0 protocol + * @param $mode + * @return bool + */ + public static function isValidMode($mode){ + return in_array($mode,self::$OpenIDProtocol_ValidModes); + } + + public static function param($param, $separator='.'){ + return Self::OpenIdPrefix.$separator.self::$protocol_definition[$param]; + } private $server_extension_repository; private $server_configuration; @@ -33,18 +109,19 @@ class OpenIdProtocol implements IOpenIdProtocol { public function __construct(IServerConfigurationRepository $server_configuration,IServerExtensionsRepository $server_extension_repository){ $this->server_extension_repository = $server_extension_repository; $this->server_configuration = $server_configuration; - //create chain of responsibility - $authService = \App::make("openid\\services\\IAuthService"); - $mementoRequestService = \App::make("openid\\services\\IMementoOpenIdRequestService"); - $auth_strategy = \App::make("openid\\handlers\\IOpenIdAuthenticationStrategy"); + $auth_service = \App::make("openid\\services\\IAuthService"); + $memento_request_service = \App::make("openid\\services\\IMementoOpenIdRequestService"); + $auth_strategy = \App::make("openid\\handlers\\IOpenIdAuthenticationStrategy"); + $server_extension_service = \App::make("openid\\services\\IServerExtensionsService"); + $association_service = \App::make("openid\\services\\IAssociationService"); + $trusted_sites_service = \App::make("openid\\services\\ITrustedSitesService"); - $successor = new OpenIdSessionAssociationRequestHandler(new OpenIdCheckAuthenticationRequestHandler(null)); - $this->request_handlers = new OpenIdAuthenticationRequestHandler($authService,$mementoRequestService,$auth_strategy,$successor); + $successor = new OpenIdSessionAssociationRequestHandler(new OpenIdCheckAuthenticationRequestHandler(null)); + $this->request_handlers = new OpenIdAuthenticationRequestHandler($auth_service,$memento_request_service,$auth_strategy,$server_extension_service,$association_service,$trusted_sites_service,$successor); } public function getXRDSDiscovery(){ - $active_extensions = $this->server_extension_repository->GetAllExtensions(); $extensions = array(); foreach($active_extensions as $ext){ diff --git a/app/libs/openid/exceptions/InvalidOpenIdAuthenticationRequestMode.php b/app/libs/openid/exceptions/InvalidOpenIdAuthenticationRequestMode.php new file mode 100644 index 00000000..f5811114 --- /dev/null +++ b/app/libs/openid/exceptions/InvalidOpenIdAuthenticationRequestMode.php @@ -0,0 +1,20 @@ +authService = $authService; - $this->mementoRequestService = $mementoRequestService; - $this->auth_strategy = $auth_strategy; + + $this->authService = $authService; + $this->mementoRequestService = $mementoRequestService; + $this->auth_strategy = $auth_strategy; + $this->server_extensions_service = $server_extensions_service; + $this->association_service = $association_service; + $this->trusted_sites_service = $trusted_sites_service; + $this->server_configuration_service = $server_configuration_service; + } + + + private function doAssertion(OpenIdAuthenticationRequest $request,$extensions){ + $currentUser = $this->authService->getCurrentUser(); + $context = new ResponseContext; + $op_endpoint = $this->server_configuration_service->getOPEndpointURL(); + $identity = $currentUser->getIdentifier(); + $response = new OpenIdPositiveAssertionResponse($op_endpoint,$identity,$identity,$request->getReturnTo()); + foreach($extensions as $ext){ + $ext->transform($request,$response,$context); + } + //check former assoc handle... + $assoc_handle = $request->getAssocHandle(); + $association = $this->association_service->getAssociation($assoc_handle); + if(empty($assoc_handle) || is_null($association)){ + // if not present or if it already void then enter on dumb mode + $new_secret = OpenIdCryptoHelper::generateSecret(OpenIdProtocol::SignatureAlgorithmHMAC_SHA256); + $new_handle = uniqid(); + //todo: get from somewhere? + $lifetime = 120; + $issued = gmdate("Y-m-d H:i:s", time()); + $this->association_service->addAssociation($new_handle,$new_secret,$lifetime,$issued,IAssociation::TypePrivate); + $response->setAssocHandle($new_handle); + if(!empty($assoc_handle)){ + $response->setInvalidateHandle($assoc_handle); + } + $association = $this->association_service->getAssociation($new_handle); + } + else{ + $response->setAssocHandle($assoc_handle); + } + OpenIdSignatureBuilder::build($context,$association->getMacFunction(),$association->getSecret(),$response); + return $response; } protected function InternalHandle(OpenIdMessage $message) { - $request = new OpenIdAuthenticationRequest($message); - //validate request? - if(!$this->authService->isUserLogged()){ - //do login process - $this->mementoRequestService->saveCurrentRequest(); - return $this->auth_strategy->doLogin($request); - } - else { - //user already logged - $currentUser = $this->authService->getCurrentUser(); - if($this->authService->isUserAuthorized()){ - // make assertion about identity - // factory response and return + $request = new OpenIdAuthenticationRequest($message); + $extensions = $this->server_extensions_service->getAllActiveExtensions(); + $context = new RequestContext; + $mode = $request->getMode(); + switch($mode){ + case OpenIdProtocol::SetupMode: + { + if(!$this->authService->isUserLogged()){ + //do login process + $context->setStage(RequestContext::StageLogin); + foreach($extensions as $ext){ + $ext->apply($request,$context); + } + $this->mementoRequestService->saveCurrentRequest(); + return $this->auth_strategy->doLogin($request,$context); + } + else { + //user already logged + $currentUser = $this->authService->getCurrentUser(); + $site = $this->trusted_sites_service->getTrustedSite($currentUser,$request->getTrustedRoot()); + $authorization_response = $this->authService->getUserAuthorizationResponse(); + if($authorization_response == IAuthService::AuthorizationResponse_None){ + if(is_null($site)){ + //do consent process + $this->mementoRequestService->saveCurrentRequest(); + $context->setStage(RequestContext::StageConsent); + foreach($extensions as $ext){ + $ext->apply($request,$context); + } + $this->auth_strategy->doConsent($request,$context); + } + else{ + $policy = $site->getAuthorizationPolicy(); + switch($policy){ + case IAuthService::AuthorizationResponse_AllowForever: + return $this->doAssertion($request,$extensions); + break; + case IAuthService::AuthorizationResponse_DenyForever: + // black listed site + return new OpenIdIndirectGenericErrorResponse(sprintf(OpenIdErrorMessages::RealmNotAllowedByUserMessage,$site->getRealm())); + break; + default: + throw new \Exception("Invalid Realm Policy"); + break; + } + } + } + else { + // check response + switch ($authorization_response){ + case IAuthService::AuthorizationResponse_AllowForever: + $this->trusted_sites_service->addTrustedSite($currentUser,$request->getTrustedRoot(),IAuthService::AuthorizationResponse_AllowForever); + return $this->doAssertion($request,$extensions); + break; + case IAuthService::AuthorizationResponse_AllowOnce: + return $this->doAssertion($request,$extensions); + break; + case IAuthService::AuthorizationResponse_DenyOnce: + return new OpenIdNonImmediateNegativeAssertion; + break; + case IAuthService::AuthorizationResponse_DenyForever: + $this->trusted_sites_service->addTrustedSite($currentUser,$request->getTrustedRoot(),IAuthService::AuthorizationResponse_DenyForever); + return new OpenIdNonImmediateNegativeAssertion; + break; + default: + throw new \Exception("Invalid Authorization response!"); + break; + } + } + } } - else{ - //do consent process - $this->mementoRequestService->saveCurrentRequest(); - $this->auth_strategy->doConsent($request); + break; + case OpenIdProtocol::ImmediateMode: + { + if(!$this->authService->isUserLogged()){ + return new OpenIdImmediateNegativeAssertion; + } + $currentUser = $this->authService->getCurrentUser(); + $site = $this->trusted_sites_service->getTrustedSite($currentUser,$request->getTrustedRoot()); + if(is_null($site)){ + return new OpenIdImmediateNegativeAssertion; + } + $policy = $site->getAuthorizationPolicy(); + if($policy == IAuthService::AuthorizationResponse_DenyForever){ + // black listed site + return new OpenIdIndirectGenericErrorResponse(sprintf(OpenIdErrorMessages::RealmNotAllowedByUserMessage,$site->getRealm())); + } + return $this->doAssertion($request,$extensions); } + break; + default: + throw new InvalidOpenIdAuthenticationRequestMode; + break; } } diff --git a/app/libs/openid/handlers/OpenIdVoidRequestHandler.php b/app/libs/openid/handlers/OpenIdVoidRequestHandler.php deleted file mode 100644 index e2bfd63a..00000000 --- a/app/libs/openid/handlers/OpenIdVoidRequestHandler.php +++ /dev/null @@ -1,15 +0,0 @@ - 64) { + $secret = self::digest($macFunc, $secret); + } + $secret = str_pad($secret, 64, chr(0x00)); + $ipad = str_repeat(chr(0x36), 64); + $opad = str_repeat(chr(0x5c), 64); + $hash1 = self::digest($macFunc, ($secret ^ $ipad) . $data); + return self::digest($macFunc, ($secret ^ $opad) . $hash1); + } + } + + /** + * Returns lenght of binary string in bytes + * + * @param string $str + * @return int the string lenght + */ + static public function strlen($str) + { + if (extension_loaded('mbstring') && + (((int)ini_get('mbstring.func_overload')) & 2) + ) { + return mb_strlen($str, 'latin1'); + } else { + return strlen($str); + } + } + + /** + * Generates a hash value (message digest) according to given algorithm. + * It returns RAW binary string. + * + * This is a wrapper function that uses one of available internal function + * dependent on given PHP configuration. It may use various functions from + * ext/openssl, ext/hash, ext/mhash or ext/standard. + * + * @param string $func digest algorithm + * @param string $data data to sign + * @return string RAW digital signature + * @throws \Exception + */ + static public function digest($func, $data) + { + if (function_exists('openssl_digest')) { + return openssl_digest($data, $func, true); + } else if (function_exists('hash')) { + return hash($func, $data, true); + } else if ($func === 'sha1') { + return sha1($data, true); + } else if ($func === 'sha256') { + if (function_exists('mhash')) { + return mhash(MHASH_SHA256, $data); + } + } + throw new \Exception('Unsupported digest algorithm "' . $func . '".'); + } + + /** + * Takes an arbitrary precision integer and returns its shortest big-endian + * two's complement representation. + * + * Arbitrary precision integers MUST be encoded as big-endian signed two's + * complement binary strings. Henceforth, "btwoc" is a function that takes + * an arbitrary precision integer and returns its shortest big-endian two's + * complement representation. All integers that are used with + * Diffie-Hellman Key Exchange are positive. This means that the left-most + * bit of the two's complement representation MUST be zero. If it is not, + * implementations MUST add a zero byte at the front of the string. + * + * @param string $str binary representation of arbitrary precision integer + * @return string big-endian signed representation + */ + static public function btwoc($str) + { + if (ord($str[0]) > 127) { + return "\0" . $str; + } + return $str; + } +} \ No newline at end of file diff --git a/app/libs/openid/helpers/OpenIdErrorMessages.php b/app/libs/openid/helpers/OpenIdErrorMessages.php new file mode 100644 index 00000000..c8787f4e --- /dev/null +++ b/app/libs/openid/helpers/OpenIdErrorMessages.php @@ -0,0 +1,15 @@ +getSignParams(); + + foreach($params as $key => $val){ + if (strpos($key, 'openid.') === 0) { + $key = substr($key, strlen('openid.')); + if (!empty($signed)) { + $signed .= ','; + } + $signed .= $key; + $data .= $key . ':' . $val . "\n"; + } + } + $signed .= ',signed'; + $data .= 'signed:' . $signed . "\n"; + $sig = base64_encode(OpenIdCryptoHelper::computeHMAC($macAlg, $data, $secret)); + + $response->setSigned($signed); + $response->setSig($sig); + } +} \ No newline at end of file diff --git a/app/libs/openid/helpers/OpenIdUriHelper.php b/app/libs/openid/helpers/OpenIdUriHelper.php new file mode 100644 index 00000000..a2105730 --- /dev/null +++ b/app/libs/openid/helpers/OpenIdUriHelper.php @@ -0,0 +1,214 @@ + 1 ? $dir : '') + . '/' + . $url; + } + } + } + return $url; + } + + /** + * Normalizes URL according to RFC 3986 to use it in comparison operations. + * The function gets URL argument by reference and modifies it. + * It returns true on success and false of failure. + * + * @param string &$id url to be normalized + * @return bool + */ + static public function normalizeUrl(&$id) + { + // RFC 3986, 6.2.2. Syntax-Based Normalization + + // RFC 3986, 6.2.2.2 Percent-Encoding Normalization + $i = 0; + $n = strlen($id); + $res = ''; + while ($i < $n) { + if ($id[$i] == '%') { + if ($i + 2 >= $n) { + return false; + } + ++$i; + if ($id[$i] >= '0' && $id[$i] <= '9') { + $c = ord($id[$i]) - ord('0'); + } else if ($id[$i] >= 'A' && $id[$i] <= 'F') { + $c = ord($id[$i]) - ord('A') + 10; + } else if ($id[$i] >= 'a' && $id[$i] <= 'f') { + $c = ord($id[$i]) - ord('a') + 10; + } else { + return false; + } + ++$i; + if ($id[$i] >= '0' && $id[$i] <= '9') { + $c = ($c << 4) | (ord($id[$i]) - ord('0')); + } else if ($id[$i] >= 'A' && $id[$i] <= 'F') { + $c = ($c << 4) | (ord($id[$i]) - ord('A') + 10); + } else if ($id[$i] >= 'a' && $id[$i] <= 'f') { + $c = ($c << 4) | (ord($id[$i]) - ord('a') + 10); + } else { + return false; + } + ++$i; + $ch = chr($c); + if (($ch >= 'A' && $ch <= 'Z') || + ($ch >= 'a' && $ch <= 'z') || + $ch == '-' || + $ch == '.' || + $ch == '_' || + $ch == '~') { + $res .= $ch; + } else { + $res .= '%'; + if (($c >> 4) < 10) { + $res .= chr(($c >> 4) + ord('0')); + } else { + $res .= chr(($c >> 4) - 10 + ord('A')); + } + $c = $c & 0xf; + if ($c < 10) { + $res .= chr($c + ord('0')); + } else { + $res .= chr($c - 10 + ord('A')); + } + } + } else { + $res .= $id[$i++]; + } + } + + if (!preg_match('|^([^:]+)://([^:@]*(?:[:][^@]*)?@)?([^/:@?#]*)(?:[:]([^/?#]*))?(/[^?#]*)?((?:[?](?:[^#]*))?)((?:#.*)?)$|', $res, $reg)) { + return false; + } + $scheme = $reg[1]; + $auth = $reg[2]; + $host = $reg[3]; + $port = $reg[4]; + $path = $reg[5]; + $query = $reg[6]; + $fragment = $reg[7]; /* strip it */ /* ZF-4358 Fragment retained under OpenID 2.0 */ + + if (empty($scheme) || empty($host)) { + return false; + } + + // RFC 3986, 6.2.2.1. Case Normalization + $scheme = strtolower($scheme); + $host = strtolower($host); + + // RFC 3986, 6.2.2.3. Path Segment Normalization + if (!empty($path)) { + $i = 0; + $n = strlen($path); + $res = ""; + while ($i < $n) { + if ($path[$i] == '/') { + ++$i; + while ($i < $n && $path[$i] == '/') { + ++$i; + } + if ($i < $n && $path[$i] == '.') { + ++$i; + if ($i < $n && $path[$i] == '.') { + ++$i; + if ($i == $n || $path[$i] == '/') { + if (($pos = strrpos($res, '/')) !== false) { + $res = substr($res, 0, $pos); + } + } else { + $res .= '/..'; + } + } else if ($i != $n && $path[$i] != '/') { + $res .= '/.'; + } + } else { + $res .= '/'; + } + } else { + $res .= $path[$i++]; + } + } + $path = $res; + } + + // RFC 3986,6.2.3. Scheme-Based Normalization + if ($scheme == 'http') { + if ($port == 80) { + $port = ''; + } + } else if ($scheme == 'https') { + if ($port == 443) { + $port = ''; + } + } + if (empty($path)) { + $path = '/'; + } + + $id = $scheme + . '://' + . $auth + . $host + . (empty($port) ? '' : (':' . $port)) + . $path + . $query + . $fragment; + return true; + } + + static public function checkRealmWildcard($root,$realm){ + $n = strpos($realm, '://*.'); + if ($n != false) { + $regex = '/^'. preg_quote(substr($realm, 0, $n+3), '/'). '[A-Za-z1-9_\.]+?'. preg_quote(substr($realm, $n+4), '/'). '/'; + if (preg_match($regex, $root)) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/app/libs/openid/model/IAssociation.php b/app/libs/openid/model/IAssociation.php new file mode 100644 index 00000000..706d7ac0 --- /dev/null +++ b/app/libs/openid/model/IAssociation.php @@ -0,0 +1,35 @@ +getMode(); - if($mode==self::ImmediateMode || $mode==self::SetupMode) return true; + if($mode==OpenIdProtocol::ImmediateMode || $mode==OpenIdProtocol::SetupMode) return true; return false; } public function getClaimedId(){ - return isset($this->message[self::ClaimedIdType])?$this->message[self::ClaimedIdType]:null; + return isset($this->message[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ClaimedId,"_")])?$this->message[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ClaimedId,"_")]:null; } public function getIdentity(){ - return isset($this->message[self::IdentityType])?$this->message[self::IdentityType]:null; + return isset($this->message[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Identity,"_")])?$this->message[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Identity,"_")]:null; } public function getAssocHandle(){ - return isset($this->message[self::AssocHandleType])?$this->message[self::AssocHandleType]:null; + return isset($this->message[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_AssocHandle,"_")])?$this->message[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_AssocHandle,"_")]:null; } public function getReturnTo(){ - return isset($this->message[self::ReturnToType])?$this->message[self::ReturnToType]:null; + return isset($this->message[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo,"_")])?$this->message[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo,"_")]:null; } public function getRealm(){ - return isset($this->message[self::RealmType])?$this->message[self::RealmType]:null; + return isset($this->message[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Realm,"_")])?$this->message[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Realm,"_")]:null; + } + + + public function getTrustedRoot() { + if (isset($this[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Realm,"_")])) { + $root = $this[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Realm,"_")]; + } else if (isset($this[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo,"_")])) { + $root = $this[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo,"_")]; + } else { + return null; + } + if (OpenIdUriHelper::normalizeUrl($root) && !empty($root)) { + return $root; + } + return null; } public function IsValid(){ @@ -55,9 +64,9 @@ class OpenIdAuthenticationRequest extends OpenIdRequest{ $mode = $this->getMode(); //todo: validate url(format-regex) - white list /black list? return !empty($return_to) - && !empty($claimed_id) && $claimed_id==self::IdentifierSelectType - && !empty($identity) && $identity==self::IdentifierSelectType - && !empty($mode) && ($mode == self::ImmediateMode || $mode == self::SetupMode); + && !empty($claimed_id) && $claimed_id == OpenIdProtocol::IdentifierSelectType + && !empty($identity) && $identity == OpenIdProtocol::IdentifierSelectType + && !empty($mode) && ($mode == OpenIdProtocol::ImmediateMode || $mode == OpenIdProtocol::SetupMode); } } \ No newline at end of file diff --git a/app/libs/openid/requests/contexts/PartialView.php b/app/libs/openid/requests/contexts/PartialView.php new file mode 100644 index 00000000..e97b398a --- /dev/null +++ b/app/libs/openid/requests/contexts/PartialView.php @@ -0,0 +1,30 @@ +name = $name; + $this->data = $data; + } + + public function getData(){ + return $this->data; + } + + public function getName(){ + return $this->name; + } +} \ No newline at end of file diff --git a/app/libs/openid/requests/contexts/RequestContext.php b/app/libs/openid/requests/contexts/RequestContext.php new file mode 100644 index 00000000..659e86ed --- /dev/null +++ b/app/libs/openid/requests/contexts/RequestContext.php @@ -0,0 +1,48 @@ +partial_views = array(); + $this->stage = self::StageNull; + } + + public function addPartialView(PartialView $partial_view) + { + $this->partial_views[$partial_view->getName()] = $partial_view; + } + + public function getPartials() + { + return $this->partial_views; + } + + public function setStage($stage) + { + $this->stage = $stage; + } + + public function getStage() + { + return $this->stage; + } +} \ No newline at end of file diff --git a/app/libs/openid/responses/OpenIdDirectGenericErrorResponse.php b/app/libs/openid/responses/OpenIdDirectGenericErrorResponse.php index 626e28b6..da93700d 100644 --- a/app/libs/openid/responses/OpenIdDirectGenericErrorResponse.php +++ b/app/libs/openid/responses/OpenIdDirectGenericErrorResponse.php @@ -9,7 +9,7 @@ namespace openid\responses; use openid\responses\OpenIdDirectResponse; - +use openid\OpenIdProtocol; /** * Class OpenIdDirectGenericErrorResponse * implements 5.1.2.2. Error Responses @@ -27,11 +27,11 @@ class OpenIdDirectGenericErrorResponse extends OpenIdDirectResponse { public function __construct($error, $contact=null, $reference=null){ parent::__construct(); $this->setHttpCode(self::HttpErrorResponse); - $this["error"] = $error; + $this[OpenIdProtocol::OpenIDProtocol_Error] = $error; //opt values if(!is_null($contact)) - $this["contact"] = $contact; + $this[OpenIdProtocol::OpenIDProtocol_Contact] = $contact; if(!is_null($reference)) - $this["reference"] = $reference; + $this[OpenIdProtocol::OpenIDProtocol_Reference] = $reference; } } \ No newline at end of file diff --git a/app/libs/openid/responses/OpenIdImmediateNegativeAssertion.php b/app/libs/openid/responses/OpenIdImmediateNegativeAssertion.php new file mode 100644 index 00000000..7c460ea9 --- /dev/null +++ b/app/libs/openid/responses/OpenIdImmediateNegativeAssertion.php @@ -0,0 +1,21 @@ +setMode(OpenIdProtocol::SetupNeededMode); + } +} \ No newline at end of file diff --git a/app/libs/openid/responses/OpenIdIndirectGenericErrorResponse.php b/app/libs/openid/responses/OpenIdIndirectGenericErrorResponse.php new file mode 100644 index 00000000..a5911561 --- /dev/null +++ b/app/libs/openid/responses/OpenIdIndirectGenericErrorResponse.php @@ -0,0 +1,28 @@ +setHttpCode(self::HttpErrorResponse); + $this[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Error)] = $error; + //opt values + if(!is_null($contact)) + $this[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Contact)] = $contact; + if(!is_null($reference)) + $this[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Reference)] = $reference; + } + +} \ No newline at end of file diff --git a/app/libs/openid/responses/OpenIdIndirectResponse.php b/app/libs/openid/responses/OpenIdIndirectResponse.php index 892fd557..ab42aee8 100644 --- a/app/libs/openid/responses/OpenIdIndirectResponse.php +++ b/app/libs/openid/responses/OpenIdIndirectResponse.php @@ -8,9 +8,10 @@ */ namespace openid\responses; +use openid\OpenIdProtocol; use openid\responses\OpenIdResponse; -class OpenIdIndirectResponse extends OpenIdResponse{ +class OpenIdIndirectResponse extends OpenIdResponse { const IndirectResponseContentType ="application/x-www-form-urlencoded"; @@ -23,7 +24,7 @@ class OpenIdIndirectResponse extends OpenIdResponse{ * response. Future versions of the specification may define different values in order * to allow message recipients to properly interpret the request. */ - $this["openid.ns"] = self::OpenId2ResponseType; + $this[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS)] = OpenIdProtocol::OpenID2MessageType; } @@ -48,4 +49,12 @@ class OpenIdIndirectResponse extends OpenIdResponse{ { return "indirect"; } + + public function setReturnTo($return_to){ + $this[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo)] = $return_to; + } + + public function getReturnTo(){ + return $this[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo)]; + } } \ No newline at end of file diff --git a/app/libs/openid/responses/OpenIdNonImmediateNegativeAssertion.php b/app/libs/openid/responses/OpenIdNonImmediateNegativeAssertion.php new file mode 100644 index 00000000..54867232 --- /dev/null +++ b/app/libs/openid/responses/OpenIdNonImmediateNegativeAssertion.php @@ -0,0 +1,19 @@ +setMode(OpenIdProtocol::CancelMode); + } +} \ No newline at end of file diff --git a/app/libs/openid/responses/OpenIdPositiveAssertionResponse.php b/app/libs/openid/responses/OpenIdPositiveAssertionResponse.php new file mode 100644 index 00000000..377cc644 --- /dev/null +++ b/app/libs/openid/responses/OpenIdPositiveAssertionResponse.php @@ -0,0 +1,45 @@ +setMode(OpenIdProtocol::IdMode); + $this[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_OpEndpoint)] = $op_endpoint; + $this[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ClaimedId)] = $claimed_id; + $this[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Identity)] = $identity; + $this[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo)] = $return_to; + $this[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Nonce)] = $this->generateNonce(); + } + + public function setAssocHandle($assoc_handle){ + $this[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_AssocHandle)] = $assoc_handle; + } + + public function setSigned($signed){ + $this[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Signed)] = $signed; + } + + public function setSig($sig){ + $this[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Sig)] = $sig; + } + + public function setInvalidateHandle($invalidate_handle){ + $this[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_InvalidateHandle)] = $invalidate_handle; + } + + private function generateNonce(){ + return gmdate('Y-m-d\TH:i:s\Z') . uniqid(); + } +} diff --git a/app/libs/openid/responses/OpenIdResponse.php b/app/libs/openid/responses/OpenIdResponse.php index 153a8602..c4790def 100644 --- a/app/libs/openid/responses/OpenIdResponse.php +++ b/app/libs/openid/responses/OpenIdResponse.php @@ -14,7 +14,7 @@ abstract class OpenIdResponse extends OpenIdMessage { const HttpOkResponse = 200; const HttpErrorResponse = 400; - const OpenId2ResponseType = "http://specs.openid.net/auth/2.0"; + protected $http_code; protected $content_type; @@ -39,4 +39,9 @@ abstract class OpenIdResponse extends OpenIdMessage { } abstract public function getType(); + + public function addParam($name,$value){ + //todo: validate if $name is a valid openid 2.0 param name? + $this[$name] = $value; + } } \ No newline at end of file diff --git a/app/libs/openid/responses/contexts/ResponseContext.php b/app/libs/openid/responses/contexts/ResponseContext.php new file mode 100644 index 00000000..1f422e4b --- /dev/null +++ b/app/libs/openid/responses/contexts/ResponseContext.php @@ -0,0 +1,33 @@ +sign_params = array(); + } + + public function addSignParam(string $param) + { + array_push($this->sign_params, $param); + } + + public function getSignParams() + { + ksort($this->sign_params); + return $this->sign_params; + } +} \ No newline at end of file diff --git a/app/libs/openid/services/IAssociationService.php b/app/libs/openid/services/IAssociationService.php new file mode 100644 index 00000000..f6b98d18 --- /dev/null +++ b/app/libs/openid/services/IAssociationService.php @@ -0,0 +1,31 @@ +getKey(); - } - - /** - * Get the password for the user. - * - * @return string - */ - public function getAuthPassword() - { - return $this->password; - } - - /** - * Get the e-mail address where password reminders are sent. - * - * @return string - */ - public function getReminderEmail() - { - return $this->email; - } - -} \ No newline at end of file diff --git a/app/repositories/ServerExtensionsRepositoryEloquent.php b/app/repositories/ServerExtensionsRepositoryEloquent.php index eaf5a42c..55b55dc9 100644 --- a/app/repositories/ServerExtensionsRepositoryEloquent.php +++ b/app/repositories/ServerExtensionsRepositoryEloquent.php @@ -17,7 +17,7 @@ class ServerExtensionsRepositoryEloquent implements IServerExtensionsRepository /** * @return all active server extensions */ - public function GetAllExtensions() + public function getAllActiveExtensions() { $extensions = array(); diff --git a/app/services/AuthenticationStrategy.php b/app/services/AuthenticationStrategy.php index 3826700a..11cc5777 100644 --- a/app/services/AuthenticationStrategy.php +++ b/app/services/AuthenticationStrategy.php @@ -12,15 +12,17 @@ namespace services; use openid\handlers\IOpenIdAuthenticationStrategy; use openid\requests\OpenIdAuthenticationRequest; use \Redirect; +use openid\requests\contexts\RequestContext; + class AuthenticationStrategy implements IOpenIdAuthenticationStrategy{ - public function doLogin(OpenIdAuthenticationRequest $request) + public function doLogin(OpenIdAuthenticationRequest $request,RequestContext $context) { - return Redirect::action('UserController@getLogin'); + return Redirect::action('UserController@getLogin')->with('context', $context); } - public function doConsent(OpenIdAuthenticationRequest $request) + public function doConsent(OpenIdAuthenticationRequest $request,RequestContext $context) { - return Redirect::action('UserController@getConsent'); + return Redirect::action('UserController@getConsent')->with('context', $context);; } } \ No newline at end of file diff --git a/app/services/ServerExtensionsService.php b/app/services/ServerExtensionsService.php new file mode 100644 index 00000000..d26c591b --- /dev/null +++ b/app/services/ServerExtensionsService.php @@ -0,0 +1,20 @@ +app->singleton('openid\\services\\IMementoOpenIdRequestService','services\\MementoRequestService'); $this->app->singleton('openid\\handlers\\IOpenIdAuthenticationStrategy','services\\AuthenticationStrategy'); + $this->app->singleton('openid\\services\\IServerExtensionsService','services\\ServerExtensionsService'); + } } \ No newline at end of file diff --git a/app/strategies/OpenIdDirectResponseStrategy.php b/app/strategies/OpenIdDirectResponseStrategy.php new file mode 100644 index 00000000..00ee1ea5 --- /dev/null +++ b/app/strategies/OpenIdDirectResponseStrategy.php @@ -0,0 +1,22 @@ +getContent(), $response->getHttpCode()); + $response->header('Content-Type', $response->getContentType()); + return $response; + } +} \ No newline at end of file diff --git a/app/strategies/OpenIdIndirectResponseStrategy.php b/app/strategies/OpenIdIndirectResponseStrategy.php new file mode 100644 index 00000000..2c71a745 --- /dev/null +++ b/app/strategies/OpenIdIndirectResponseStrategy.php @@ -0,0 +1,22 @@ +getContent(); + $return_to = $response->getReturnTo(); + $return_to = (strpos($return_to,"?")===false)?$return_to."?".$query_string:$return_to."&".$query_string; + return Redirect::to($return_to); + } +} \ No newline at end of file diff --git a/app/strategies/OpenIdResponseStrategyProvider.php b/app/strategies/OpenIdResponseStrategyProvider.php new file mode 100644 index 00000000..89c3cf9f --- /dev/null +++ b/app/strategies/OpenIdResponseStrategyProvider.php @@ -0,0 +1,19 @@ +app->singleton('OpenIdDirectResponseStrategy','strategies\\OpenIdDirectResponseStrategy'); + $this->app->singleton('OpenIdIndirectResponseStrategy','strategies\\OpenIdIndirectResponseStrategy'); + } +} \ No newline at end of file diff --git a/app/views/extensions/ax.blade.php b/app/views/extensions/ax.blade.php new file mode 100644 index 00000000..e69de29b diff --git a/app/views/extensions/oauth.blade.php b/app/views/extensions/oauth.blade.php new file mode 100644 index 00000000..e69de29b diff --git a/app/views/extensions/pape.blade.php b/app/views/extensions/pape.blade.php new file mode 100644 index 00000000..7dabe852 --- /dev/null +++ b/app/views/extensions/pape.blade.php @@ -0,0 +1,4 @@ +

PAPE

+@foreach ($links as $link) +{{$link}} +@endforeach \ No newline at end of file diff --git a/app/views/extensions/sreg.blade.php b/app/views/extensions/sreg.blade.php new file mode 100644 index 00000000..e69de29b diff --git a/app/views/login.blade.php b/app/views/login.blade.php index 4f446b20..4fe84834 100644 --- a/app/views/login.blade.php +++ b/app/views/login.blade.php @@ -26,5 +26,9 @@
{{ Session::get('flash_notice') }}
@endif {{ Form::close() }} + @foreach ($views as $view) + {{ $view}} + @endforeach + @stop \ No newline at end of file diff --git a/composer.json b/composer.json index 99e6dbc0..fce481e2 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,8 @@ "app/libs", "app/repositories", "app/tests/mocks", - "app/services" + "app/services", + "app/strategies" ] }, "scripts": {