diff --git a/app/libs/openid/extensions/implementations/OpenIdSREGRequest.php b/app/libs/openid/extensions/implementations/OpenIdSREGRequest.php index a001067f..c62d84cc 100644 --- a/app/libs/openid/extensions/implementations/OpenIdSREGRequest.php +++ b/app/libs/openid/extensions/implementations/OpenIdSREGRequest.php @@ -34,35 +34,59 @@ class OpenIdSREGRequest extends OpenIdRequest && $this->message[OpenIdSREGExtension::paramNamespace('_')] == OpenIdSREGExtension::NamespaceUrl ) { + /* + * All of the following request fields are OPTIONAL, though at least one of "openid.sreg.required" + * or "openid.sreg.optional" MUST be specified in the request. + * openid.sreg.required: + * Comma-separated list of field names which, if absent from the response, will prevent the Consumer f + * rom completing the registration without End User interation. The field names are those that are + * specified in the Response Format, with the "openid.sreg." prefix removed. + * openid.sreg.optional: + * Comma-separated list of field names Fields that will be used by the Consumer, but whose absence will + * not prevent the registration from completing. The field names are those that are specified in the + * Response Format, with the "openid.sreg." prefix removed. + * openid.sreg.policy_url: + * A URL which the Consumer provides to give the End User a place to read about the how the profile data + * will be used. The Identity Provider SHOULD display this URL to the End User if it is given. + */ + //check required fields - if (!isset($this->message[OpenIdSREGExtension::param(OpenIdSREGExtension::Required, '_')])) - throw new InvalidOpenIdMessageException("SREG: not set required attributes!"); + if( !isset($this->message[OpenIdSREGExtension::param(OpenIdSREGExtension::Required, '_')]) && + !isset($this->message[OpenIdSREGExtension::param(OpenIdSREGExtension::Optional, '_')])) + throw new InvalidOpenIdMessageException("SREG: at least one of \"openid.sreg.required\" or \"openid.sreg.optional\" MUST be specified in the request."); //get attributes - $attributes = $this->message[OpenIdSREGExtension::param(OpenIdSREGExtension::Required, '_')]; - $attributes = explode(",", $attributes); - if (count($attributes) <= 0) { - throw new InvalidOpenIdMessageException("SREG: not set required attributes!"); + if (isset($this->message[OpenIdSREGExtension::param(OpenIdSREGExtension::Required, '_')])) { + + $attributes = $this->message[OpenIdSREGExtension::param(OpenIdSREGExtension::Required, '_')]; + $attributes = explode(",", $attributes); + + foreach ($attributes as $attr) { + $attr = trim($attr); + + if (!isset(OpenIdSREGExtension::$available_properties[$attr])) + continue; + + $this->attributes[$attr] = $attr; + } } - foreach ($attributes as $attr) { - $attr = trim($attr); - if (!isset(OpenIdSREGExtension::$available_properties[$attr])) - continue; - $this->attributes[$attr] = $attr; - } - - //get attributes + //get optional attributes if (isset($this->message[OpenIdSREGExtension::param(OpenIdSREGExtension::Optional, '_')])) { + $opt_attributes = $this->message[OpenIdSREGExtension::param(OpenIdSREGExtension::Optional, '_')]; $opt_attributes = explode(",", $opt_attributes); + foreach ($opt_attributes as $opt_attr) { $opt_attr = trim($opt_attr); + if (!isset(OpenIdSREGExtension::$available_properties[$opt_attr])) continue; + if (isset($this->attributes[$opt_attr])) - throw new InvalidOpenIdMessageException("SREG: optional attribute is already set as required one!"); + throw new InvalidOpenIdMessageException(sprintf("SREG: optional attribute %s is already set as required one!", $opt_attr)); + $this->optional_attributes[$opt_attr] = $opt_attr; } } @@ -71,6 +95,7 @@ class OpenIdSREGRequest extends OpenIdRequest if (isset($this->message[OpenIdSREGExtension::param(OpenIdSREGExtension::PolicyUrl, '_')])) { $this->policy_url = $this->message[OpenIdSREGExtension::param(OpenIdSREGExtension::PolicyUrl, '_')]; } + return true; } } catch (Exception $ex) { diff --git a/app/tests/OpenIdProtocolTest.php b/app/tests/OpenIdProtocolTest.php index d02c85c6..27461cd3 100644 --- a/app/tests/OpenIdProtocolTest.php +++ b/app/tests/OpenIdProtocolTest.php @@ -572,6 +572,80 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest $this->assertTrue($openid_response['is_valid'] === 'true'); } + public function testCheckSetupSREGExtensionNotRequired() + { + + //set login info + Session::set("openid.authorization.response", IAuthService::AuthorizationResponse_AllowForever); + $sreg_required_params = array('email', 'fullname'); + + $params = array( + OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS) => OpenIdProtocol::OpenID2MessageType, + OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode) => OpenIdProtocol::SetupMode, + OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Realm) => "https://www.test.com/", + OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo) => "https://www.test.com/oauth2", + OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Identity) => "http://specs.openid.net/auth/2.0/identifier_select", + OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ClaimedId) => "http://specs.openid.net/auth/2.0/identifier_select", + //sreg + OpenIdSREGExtension::paramNamespace() => OpenIdSREGExtension::NamespaceUrl, + OpenIdSREGExtension::param(OpenIdSREGExtension::Optional) => implode(",", $sreg_required_params), + + ); + + $response = $this->action("POST", "OpenIdProviderController@endpoint", $params); + + $this->assertResponseStatus(302); + + $openid_response = $this->parseOpenIdResponse($response->getTargetUrl()); + + $this->assertTrue(isset($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode)])); + $this->assertTrue(!empty($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode)])); + + $this->assertTrue(isset($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS)])); + $this->assertTrue(!empty($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS)])); + + $this->assertTrue(isset($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo)])); + $this->assertTrue(!empty($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo)])); + + $this->assertTrue(isset($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Sig)])); + $this->assertTrue(!empty($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Sig)])); + + $this->assertTrue(isset($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Signed)])); + $this->assertTrue(!empty($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Signed)])); + + $this->assertTrue(isset($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Realm)])); + $this->assertTrue(!empty($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Realm)])); + + $this->assertTrue(isset($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_OpEndpoint)])); + $this->assertTrue(!empty($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_OpEndpoint)])); + + $this->assertTrue(isset($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Identity)])); + $this->assertTrue(!empty($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Identity)])); + + $this->assertTrue(isset($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ClaimedId)])); + $this->assertTrue(!empty($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ClaimedId)])); + + //sreg + + $this->assertTrue(isset($openid_response[OpenIdSREGExtension::paramNamespace()])); + $this->assertTrue($openid_response[OpenIdSREGExtension::paramNamespace()] === OpenIdSREGExtension::NamespaceUrl); + + $this->assertTrue(isset($openid_response[OpenIdSREGExtension::param(OpenIdSREGExtension::FullName)])); + $full_name = $openid_response[OpenIdSREGExtension::param(OpenIdSREGExtension::FullName)]; + $this->assertTrue(!empty($full_name) && $full_name === 'Sebastian Marcet'); + + $this->assertTrue(isset($openid_response[OpenIdSREGExtension::param(OpenIdSREGExtension::Email)])); + $email = $openid_response[OpenIdSREGExtension::param(OpenIdSREGExtension::Email)]; + $this->assertTrue(!empty($email) && $email === 'sebastian@tipit.net'); + + //http://openid.net/specs/openid-authentication-2_0.html#check_auth + $response = $this->action("POST", "OpenIdProviderController@endpoint", + $this->prepareCheckAuthenticationParams($openid_response)); + $openid_response = $this->getOpenIdResponseLineBreak($response->getContent()); + $this->assertResponseStatus(200); + $this->assertTrue($openid_response['is_valid'] === 'true'); + } + /** * test openid oauth2 extension * https://developers.google.com/accounts/docs/OpenID#oauth