[smarcet]

Refactoring of nonce/token/auth service

Now nonce and token service use a generator class to
generate the values for nonces, auth codes, access
tokens and refresh token. So in this way, all the
knowlegde on how values are created are on one single
place, also this generator class allows to generate
unique values per class (nonnce, auth code, and so on)

Change-Id: Iaac8406aa23145a1ea1a61040707b72fa4faed1d
This commit is contained in:
Sebastian Marcet 2015-06-29 20:06:35 -03:00
parent 8e1e902743
commit 50bbfa7a8f
24 changed files with 1495 additions and 762 deletions

View File

@ -8,8 +8,8 @@ use Exception;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\UserProviderInterface;
use openid\services\IUserService;
use utils\services\ICheckPointService;
use utils\db\ITransactionService;
use utils\services\ICheckPointService;
use utils\services\ILogService;
/**
@ -20,189 +20,248 @@ use utils\services\ILogService;
class CustomAuthProvider implements UserProviderInterface
{
private $auth_extension_service;
private $user_service;
private $checkpoint_service;
private $user_repository;
private $member_repository;
private $tx_service;
private $log_service;
/**
* @var IAuthenticationExtensionService
*/
private $auth_extension_service;
/**
* @var IUserService
*/
private $user_service;
/**
* @var ICheckPointService
*/
private $checkpoint_service;
/**
* @var IUserService
*/
private $user_repository;
/**
* @var IMemberRepository
*/
private $member_repository;
/**
* @var ITransactionService
*/
private $tx_service;
/**
* @var ILogService
*/
private $log_service;
public function __construct(IUserRepository $user_repository,
IMemberRepository $member_repository,
IAuthenticationExtensionService $auth_extension_service,
IUserService $user_service,
ICheckPointService $checkpoint_service,
ITransactionService $tx_service,
ILogService $log_service){
/**
* @param IUserRepository $user_repository
* @param IMemberRepository $member_repository
* @param IAuthenticationExtensionService $auth_extension_service
* @param IUserService $user_service
* @param ICheckPointService $checkpoint_service
* @param ITransactionService $tx_service
* @param ILogService $log_service
*/
public function __construct(
IUserRepository $user_repository,
IMemberRepository $member_repository,
IAuthenticationExtensionService $auth_extension_service,
IUserService $user_service,
ICheckPointService $checkpoint_service,
ITransactionService $tx_service,
ILogService $log_service
) {
$this->auth_extension_service = $auth_extension_service;
$this->user_service = $user_service;
$this->checkpoint_service = $checkpoint_service;
$this->user_repository = $user_repository;
$this->member_repository = $member_repository;
$this->tx_service = $tx_service;
$this->log_service = $log_service;
}
$this->auth_extension_service = $auth_extension_service;
$this->user_service = $user_service;
$this->checkpoint_service = $checkpoint_service;
$this->user_repository = $user_repository;
$this->member_repository = $member_repository;
$this->tx_service = $tx_service;
$this->log_service = $log_service;
}
/**
* Retrieve a user by their unique identifier.
*
* @param mixed $identifier
* @return \Illuminate\Auth\UserInterface|null
*/
public function retrieveById($identifier)
{
try {
//here we do the manuel join between 2 DB, (openid and SS db)
$user = $this->user_repository->getByExternalId($identifier);
$member = $this->member_repository->get($identifier);
if (!is_null($member) && !is_null($user)) {
$user->setMember($member);
return $user;
}
/**
* Retrieve a user by their unique identifier.
* @param mixed $identifier
* @return \Illuminate\Auth\UserInterface|null
*/
public function retrieveById($identifier)
{
try {
//here we do the manuel join between 2 DB, (openid and SS db)
$user = $this->user_repository->getByExternalId($identifier);
$member = $this->member_repository->get($identifier);
if (!is_null($member) && !is_null($user)) {
$user->setMember($member);
return $user;
}
} catch (Exception $ex) {
$this->log_service->error($ex);
return null;
}
} catch (Exception $ex) {
$this->log_service->error($ex);
return null;
}
return null;
}
}
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
* @return \Illuminate\Auth\UserInterface|null
*/
public function retrieveByCredentials(array $credentials)
{
$user = null;
$user_service = $this->user_service;
$auth_extension_service = $this->auth_extension_service;
$user_repository = $this->user_repository;
$member_repository = $this->member_repository;
/**
* Retrieve a user by the given credentials.
* @param array $credentials
* @return \Illuminate\Auth\UserInterface|null
*/
public function retrieveByCredentials(array $credentials)
{
$user_service = $this->user_service;
$auth_extension_service = $this->auth_extension_service;
$user_repository = $this->user_repository;
$member_repository = $this->member_repository;
try {
try {
$this->tx_service->transaction(function () use ($credentials, &$user,&$user_repository,&$member_repository, &$user_service,&$auth_extension_service) {
$user = $this->tx_service->transaction(function () use (
$credentials,
$user_repository,
$member_repository,
$user_service,
$auth_extension_service
) {
if (!isset($credentials['username']) || !isset($credentials['password']))
throw new AuthenticationException("invalid crendentials");
if (!isset($credentials['username']) || !isset($credentials['password'])) {
throw new AuthenticationException("invalid crendentials");
}
$email = $credentials['username'];
$password = $credentials['password'];
$email = $credentials['username'];
$password = $credentials['password'];
//get SS member
$member = $member_repository->getByEmail($email);
if (is_null($member)) //member must exists
{
throw new AuthenticationException(sprintf("member %s does not exists!", $email));
$user = $user_repository->getByExternalId($member->ID);
//check user status...
if (!is_null($user) && ($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));
}
$valid_password = $member->checkPassword($password);
if(!$valid_password)
throw new AuthenticationInvalidPasswordAttemptException($email, sprintf("invalid login attempt for user %s ", $email));
//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_repository->add($user);
}
$user_name = $member->FirstName . "." . $member->Surname;
//do association between user and member
$user_service->associateUser($user, strtolower($user_name));
//update user fields
$user->last_login_date = gmdate("Y-m-d H:i:s", time());
$user->login_failed_attempt = 0;
$user->active = true;
$user->lock = false;
$user_repository->update($user);
//reload user...
//$user = $user_repository->getByExternalId($identifier);
$user->setMember($member);
$auth_extensions = $auth_extension_service->getExtensions();
foreach($auth_extensions as $auth_extension){
$auth_extension->process($user);
}
});
} catch (Exception $ex) {
$this->checkpoint_service->trackException($ex);
$this->log_service->error($ex);
$user = null;
}
return $user;
}
}
/**
* Validate a user against the given credentials.
* @param UserInterface $user
* @param array $credentials
* @return bool
* @throws exceptions\AuthenticationException
*/
public function validateCredentials(UserInterface $user, array $credentials)
{
if (!isset($credentials['username']) || !isset($credentials['password']))
throw new AuthenticationException("invalid crendentials");
try {
$email = $credentials['username'];
$password = $credentials['password'];
$member = $this->member_repository->getByEmail($email);
if(!$member || !$member->checkPassword($password)) return false;
$user = $this->user_repository->getByExternalId($member->ID);
if (is_null($user) || $user->lock || !$user->active)
return false;
} catch (Exception $ex) {
$this->log_service->error($ex);
return false;
}
$valid_password = $member->checkPassword($password);
if (!$valid_password) {
throw new AuthenticationInvalidPasswordAttemptException($email,
sprintf("invalid login attempt for user %s ", $email));
}
$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);
}
//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));
}
$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->login_failed_attempt = 0;
$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) {
$auth_extension->process($user);
}
return $user;
});
} catch (Exception $ex) {
$this->checkpoint_service->trackException($ex);
$this->log_service->error($ex);
$user = null;
}
return $user;
}
/**
* Validate a user against the given credentials.
* @param UserInterface $user
* @param array $credentials
* @return bool
* @throws exceptions\AuthenticationException
*/
public function validateCredentials(UserInterface $user, array $credentials)
{
if (!isset($credentials['username']) || !isset($credentials['password'])) {
throw new AuthenticationException("invalid crendentials");
}
try {
$email = $credentials['username'];
$password = $credentials['password'];
$member = $this->member_repository->getByEmail($email);
if (!$member || !$member->checkPassword($password)) {
return false;
}
$user = $this->user_repository->getByExternalId($member->ID);
if (is_null($user) || $user->lock || !$user->active) {
return false;
}
} catch (Exception $ex) {
$this->log_service->error($ex);
return false;
}
return true;
}
}
/**
* Retrieve a user by by their unique identifier and "remember me" token.
*
* @param mixed $identifier
* @param string $token
* @return \Illuminate\Auth\UserInterface|null
*/
public function retrieveByToken($identifier, $token)
{
/**
* Retrieve a user by by their unique identifier and "remember me" token.
* @param mixed $identifier
* @param string $token
* @return \Illuminate\Auth\UserInterface|null
*/
public function retrieveByToken($identifier, $token)
{
return $this->user_repository->getByToken($identifier, $token);
}
return $this->user_repository->getByToken($identifier, $token);
}
/**
* Update the "remember me" token for the given user in storage.
*
* @param \Illuminate\Auth\UserInterface $user
* @param string $token
* @return void
*/
public function updateRememberToken(UserInterface $user, $token)
{
$user->setAttribute($user->getRememberTokenName(), $token);
/**
* Update the "remember me" token for the given user in storage.
* @param \Illuminate\Auth\UserInterface $user
* @param string $token
* @return void
*/
public function updateRememberToken(UserInterface $user, $token)
{
$user->setAttribute($user->getRememberTokenName(), $token);
$user->save();
$user->save();
}
}

View File

@ -21,7 +21,6 @@ class AccessToken extends Token {
public static function create(AuthorizationCode $auth_code, $lifetime = 3600){
$instance = new self();
$instance->value = Rand::getString($instance->len, OAuth2Protocol::VsChar, true);
$instance->user_id = $auth_code->getUserId();
$instance->scope = $auth_code->getScope();
$instance->client_id = $auth_code->getClientId();
@ -34,7 +33,6 @@ class AccessToken extends Token {
public static function createFromParams($scope, $client_id, $audience,$user_id,$lifetime){
$instance = new self();
$instance->value = Rand::getString($instance->len,OAuth2Protocol::VsChar,true);
$instance->scope = $scope;
$instance->client_id = $client_id;
$instance->user_id = $user_id;
@ -48,7 +46,6 @@ class AccessToken extends Token {
public static function createFromRefreshToken(RefreshToken $refresh_token,$scope = null, $lifetime = 3600){
$instance = new self();
$instance->value = Rand::getString($instance->len,OAuth2Protocol::VsChar,true);
$instance->scope = $scope;
$instance->from_ip = $refresh_token->getFromIp();
$instance->user_id = $refresh_token->getUserId();

View File

@ -21,7 +21,6 @@ class AuthorizationCode extends Token {
parent::__construct(64);
}
/**
* @param $user_id
* @param $client_id
@ -36,7 +35,6 @@ class AuthorizationCode extends Token {
*/
public static function create($user_id, $client_id, $scope, $audience='' ,$redirect_uri = null,$access_type = OAuth2Protocol::OAuth2Protocol_AccessType_Online,$approval_prompt =OAuth2Protocol::OAuth2Protocol_Approval_Prompt_Auto,$has_previous_user_consent=false, $lifetime = 600){
$instance = new self();
$instance->value = Rand::getString($instance->len, OAuth2Protocol::VsChar, true);
$instance->scope = $scope;
$instance->user_id = $user_id;
$instance->redirect_uri = $redirect_uri;

View File

@ -35,7 +35,6 @@ class RefreshToken extends Token {
public static function create(AccessToken $access_token, $lifetime = 0){
$instance = new self();
$instance->value = Rand::getString($instance->len,OAuth2Protocol::VsChar,true);
$instance->scope = $access_token->getScope();
$instance->user_id = $access_token->getUserId();
$instance->client_id = $access_token->getClientId();

View File

@ -2,23 +2,22 @@
namespace oauth2\models;
use DateTime;
use DateInterval;
use DateTime;
use DateTimeZone;
use utils\IPHelper;
use utils\model\Identifier;
/**
* Class Token
* Defines the common behavior for all emitted tokens
* @package oauth2\models
*/
abstract class Token
abstract class Token extends Identifier
{
const DefaultByteLength = 32;
protected $value;
protected $lifetime;
protected $issued;
protected $client_id;
protected $len;
@ -30,10 +29,11 @@ abstract class Token
public function __construct($len = self::DefaultByteLength)
{
$this->len = $len;
parent::__construct($len);
$this->is_hashed = false;
$this->issued = gmdate("Y-m-d H:i:s", time());
$this->from_ip = IPHelper::getUserIp();
$this->issued = gmdate("Y-m-d H:i:s", time());
$this->from_ip = IPHelper::getUserIp();
}
public function getIssued()
@ -41,16 +41,6 @@ abstract class Token
return $this->issued;
}
public function getValue()
{
return $this->value;
}
public function getLifetime()
{
return intval($this->lifetime);
}
public function getScope()
{
return $this->scope;
@ -71,25 +61,31 @@ abstract class Token
return $this->from_ip;
}
public function getUserId(){
public function getUserId()
{
return $this->user_id;
}
public function getRemainingLifetime()
{
//check is refresh token is stills alive... (ZERO is infinite lifetime)
if (intval($this->lifetime) == 0) return 0;
if (intval($this->lifetime) == 0) {
return 0;
}
$created_at = new DateTime($this->issued, new DateTimeZone("UTC"));
$created_at->add(new DateInterval('PT' . intval($this->lifetime) . 'S'));
$now = new DateTime(gmdate("Y-m-d H:i:s", time()), new DateTimeZone("UTC"));
//check validity...
if ($now > $created_at)
if ($now > $created_at) {
return -1;
}
$seconds = abs($created_at->getTimestamp() - $now->getTimestamp());;
return $seconds;
}
public function isHashed(){
public function isHashed()
{
return $this->is_hashed;
}

View File

@ -3,7 +3,7 @@ namespace oauth2\requests;
use oauth2\OAuth2Message;
abstract class OAuth2Request extends OAuth2Message {
abstract class OAuth2Request extends OAuth2Message {
protected $message;

View File

@ -0,0 +1,37 @@
<?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\services;
use oauth2\OAuth2Protocol;
use utils\model\Identifier;
use utils\services\UniqueIdentifierGenerator;
use Zend\Math\Rand;
/**
* Class AccessTokenGenerator
* @package oauth2\services
*/
final class AccessTokenGenerator extends UniqueIdentifierGenerator {
/**
* @param Identifier $identifier
* @return Identifier
*/
protected function _generate(Identifier $identifier)
{
$identifier->setValue(Rand::getString($identifier->getLenght(), OAuth2Protocol::VsChar, true));
return $identifier;
}
}

View File

@ -0,0 +1,38 @@
<?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\services;
use oauth2\OAuth2Protocol;
use utils\model\Identifier;
use utils\services\IdentifierGenerator;
use utils\services\UniqueIdentifierGenerator;
use Zend\Math\Rand;
/**
* Class AuthorizationCodeGenerator
* @package oauth2\services
*/
final class AuthorizationCodeGenerator extends UniqueIdentifierGenerator {
/**
* @param Identifier $identifier
* @return Identifier
*/
protected function _generate(Identifier $identifier)
{
$identifier->setValue(Rand::getString($identifier->getLenght(), OAuth2Protocol::VsChar, true));
return $identifier;
}
}

View File

@ -0,0 +1,37 @@
<?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\services;
use oauth2\OAuth2Protocol;
use utils\model\Identifier;
use utils\services\UniqueIdentifierGenerator;
use Zend\Math\Rand;
/**
* Class RefreshTokenGenerator
* @package oauth2\services
*/
final class RefreshTokenGenerator extends UniqueIdentifierGenerator {
/**
* @param Identifier $identifier
* @return Identifier
*/
protected function _generate(Identifier $identifier)
{
$identifier->setValue(Rand::getString($identifier->getLenght(), OAuth2Protocol::VsChar, true));
return $identifier;
}
}

View File

@ -92,10 +92,10 @@ final class OpenIdCheckAuthenticationRequestHandler extends OpenIdMessageHandler
if (is_null($stored_assoc) || $stored_assoc->getType() != IAssociation::TypePrivate)
throw new InvalidAssociationTypeException(OpenIdErrorMessages::InvalidAssociationTypeMessage);
$claimed_nonce = new OpenIdNonce($this->current_request->getNonce());
$claimed_nonce = OpenIdNonce::fromValue($this->current_request->getNonce());
if(!$claimed_nonce->isValid(intval($this->configuration_service->getConfigValue('Nonce.Lifetime'))))
throw new InvalidNonce();
if(!$claimed_nonce->isValid(intval($this->configuration_service->getConfigValue('Nonce.Lifetime'))))
throw new InvalidNonce();
$this->nonce_service->lockNonce($claimed_nonce);

View File

@ -3,31 +3,79 @@ namespace openid\model;
use openid\exceptions\InvalidNonce;
use openid\helpers\OpenIdErrorMessages;
use utils\model\Identifier;
/**
* Class OpenIdNonce
* @package openid\model
*/
class OpenIdNonce
final class OpenIdNonce extends Identifier
{
const NonceRegexFormat = '/(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z(.*)/';
const NonceTimeFormat = '%Y-%m-%dT%H:%M:%SZ';
private $timestamp;
private $unique_id;
private $raw_format;
/**
* @param $nonce_str
* @param int $len
* @param int $lifetime
*/
public function __construct($len, $lifetime = 0)
{
parent::__construct($len, $lifetime);
}
public function getRawFormat()
{
return $this->value;
}
public function getTimestamp()
{
return $this->timestamp;
}
public function getUniqueId()
{
return $this->$unique_id;
}
/**
* The time-stamp MAY be used to reject responses that are too far away from the current time,
* limiting the amount of time that nonces must be stored to prevent attacks.
* The acceptable range is out of the scope of this specification.
* A larger range requires storing more nonces for a longer time.
* A shorter range increases the chance that clock-skew and transaction time will cause
* a spurious rejection.
* @param $allowed_skew
* @return bool
*/
public function isValid($allowed_skew)
{
$now = time();
// Time after which we should not use the nonce
$past = $now - $allowed_skew;
// Time that is too far in the future for us to allow
$future = $now + $allowed_skew;
// the stamp is not too far in the future and is not too far
// in the past
return (($past <= $this->timestamp) && ($this->timestamp <= $future));
}
/**
* @param string $value
* @return $this
* @throws InvalidNonce
*/
public function __construct($nonce_str)
public function setValue($value)
{
// Extract a timestamp from the given nonce string
$result = preg_match(self::NonceRegexFormat, $nonce_str, $matches);
$result = preg_match(self::NonceRegexFormat, $value, $matches);
if ($result != 1 || count($matches) != 8) {
throw new InvalidNonce(sprintf(OpenIdErrorMessages::InvalidNonceFormatMessage, $nonce_str));
throw new InvalidNonce(sprintf(OpenIdErrorMessages::InvalidNonceFormatMessage, $value));
}
list($unused,
@ -42,49 +90,20 @@ class OpenIdNonce
$timestamp = @gmmktime($tm_hour, $tm_min, $tm_sec, $tm_mon, $tm_mday, $tm_year);
if ($timestamp == false || $timestamp < 0) {
throw new InvalidNonce(sprintf(OpenIdErrorMessages::InvalidNonceTimestampMessage, $nonce_str));
throw new InvalidNonce(sprintf(OpenIdErrorMessages::InvalidNonceTimestampMessage, $value));
}
$this->timestamp = $timestamp;
$this->unique_id = $unique_id;
$this->raw_format = $nonce_str;
$this->len = strlen($value);
return parent::setValue($value);
}
public function getRawFormat()
static public function fromValue($value)
{
return $this->raw_format;
}
$nonce = new OpenIdNonce(255);
public function getTimestamp()
{
return $this->timestamp;
}
public function getUniqueId()
{
return $this->$unique_id;
}
/**
* The time-stamp MAY be used to reject responses that are too far away from the current time,
* limiting the amount of time that nonces must be stored to prevent attacks.
* The acceptable range is out of the scope of this specification.
* A larger range requires storing more nonces for a longer time.
* A shorter range increases the chance that clock-skew and transaction time will cause
* a spurious rejection.
* @param $allowed_skew
* @return bool
*/
public function isValid($allowed_skew)
{
$now = time();
// Time after which we should not use the nonce
$past = $now - $allowed_skew;
// Time that is too far in the future for us to allow
$future = $now + $allowed_skew;
// the stamp is not too far in the future and is not too far
// in the past
return (($past <= $this->timestamp) && ($this->timestamp <= $future));
return $nonce->setValue($value);
}
}

View File

@ -0,0 +1,49 @@
<?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 openid\services;
use utils\model\Identifier;
use utils\services\UniqueIdentifierGenerator;
use Zend\Math\Rand;
/**
* Class NonceUniqueIdentifierGenerator
* @package openid\services
*/
final class NonceUniqueIdentifierGenerator extends UniqueIdentifierGenerator {
/*
* MAY contain additional ASCII characters in the range 33-126 inclusive (printable non-whitespace characters), as necessary to make each response unique
*/
const NoncePopulation = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
/**
* Nonce Salt Length
*/
const NonceSaltLength = 32;
/**
* @param Identifier $identifier
* @return Identifier
*/
protected function _generate(Identifier $identifier){
$salt = Rand::getString(self::NonceSaltLength, self::NoncePopulation, true);
$raw_nonce = gmdate('Y-m-d\TH:i:s\Z') . $salt;
$identifier->setValue($raw_nonce);
return $identifier;
}
}

View File

@ -0,0 +1,85 @@
<?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 utils\model;
use utils\services\IdentifierGenerator;
/**
* Class Identifier
* @package utils\model
*/
abstract class Identifier {
/**
* @param int $len
* @param int $lifetime
*/
public function __construct($len, $lifetime = 0 ){
$this->lifetime = $lifetime;
$this->len = $len;
}
/**
* @var int
*/
protected $len;
/**
* @var int
*/
protected $lifetime;
/**
* @var string
*/
protected $value;
/**
* @param IdentifierGenerator $generator
* @return $this
*/
public function generate(IdentifierGenerator $generator){
return $generator->generate($this);
}
/**
* @return int
*/
public function getLenght(){
return $this->len;
}
/**
* @return int
*/
public function getLifetime(){
return intval($this->lifetime);
}
/**
* @return string
*/
public function getValue(){
return $this->value;
}
/**
* @param string $value
* @return $this
*/
public function setValue($value){
$this->value = $value;
return $this;
}
}

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 utils\services;
use utils\model\Identifier;
/**
* Interface IdentifierGenerator
* @package utils\services
*/
interface IdentifierGenerator {
/**
* @param Identifier $identifier
* @return Identifier
*/
public function generate(Identifier $identifier);
}

View File

@ -0,0 +1,60 @@
<?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 utils\services;
use utils\model\Identifier;
/**
* Class UniqueIdentifierGenerator
* @package utils\services
*/
abstract class UniqueIdentifierGenerator implements IdentifierGenerator {
/**
* @var ICacheService
*/
private $cache_service;
/**
* @param ICacheService $cache_service
*/
public function __construct(ICacheService $cache_service)
{
$this->cache_service = $cache_service;
}
/**
* @param Identifier $identifier
* @return Identifier
*/
public function generate(Identifier $identifier){
$reflect = new \ReflectionClass($identifier);
$class_name = strtolower($reflect->getShortName());
do {
$value = $this->_generate($identifier)->getValue();
} while(!$this->cache_service->addSingleValue($class_name.'.value.'.$value, $class_name.'.value.'.$value));
return $identifier;
}
/**
* @param Identifier $identifier
* @return Identifier
*/
abstract protected function _generate(Identifier $identifier);
}

View File

@ -3,9 +3,13 @@
namespace services\oauth2;
use Illuminate\Support\ServiceProvider;
use oauth2\services\AccessTokenGenerator;
use oauth2\services\AuthorizationCodeGenerator;
use oauth2\services\OAuth2ServiceCatalog;
use oauth2\services\RefreshTokenGenerator;
use services\oauth2\ResourceServer;
use App;
use utils\services\UtilsServiceCatalog;
/**
* Class OAuth2ServiceProvider
@ -21,16 +25,30 @@ class OAuth2ServiceProvider extends ServiceProvider
public function register(){
App::singleton('oauth2\\IResourceServerContext', 'services\\oauth2\\ResourceServerContext');
App::singleton(OAuth2ServiceCatalog::MementoService, 'services\\oauth2\\MementoOAuth2AuthenticationRequestService');
App::singleton(OAuth2ServiceCatalog::ClientService, 'services\\oauth2\\ClientService');
App::singleton(OAuth2ServiceCatalog::TokenService, 'services\\oauth2\\TokenService');
App::singleton(OAuth2ServiceCatalog::ScopeService, 'services\\oauth2\\ApiScopeService');
App::singleton(OAuth2ServiceCatalog::ResourceServerService, 'services\\oauth2\\ResourceServerService');
App::singleton(OAuth2ServiceCatalog::ApiService, 'services\\oauth2\\ApiService');
App::singleton(OAuth2ServiceCatalog::ApiEndpointService, 'services\\oauth2\\ApiEndpointService');
App::singleton(OAuth2ServiceCatalog::UserConsentService, 'services\\oauth2\\UserConsentService');
App::singleton(OAuth2ServiceCatalog::AllowedOriginService, 'services\\oauth2\\AllowedOriginService');
App::singleton(OAuth2ServiceCatalog::TokenService, function(){
return new TokenService(
App::make(OAuth2ServiceCatalog::ClientService),
App::make(UtilsServiceCatalog::LockManagerService),
App::make(UtilsServiceCatalog::ServerConfigurationService),
App::make(UtilsServiceCatalog::CacheService),
App::make(UtilsServiceCatalog::AuthenticationService),
App::make(OAuth2ServiceCatalog::UserConsentService),
new AuthorizationCodeGenerator(App::make(UtilsServiceCatalog::CacheService)),
new AccessTokenGenerator(App::make(UtilsServiceCatalog::CacheService)),
new RefreshTokenGenerator(App::make(UtilsServiceCatalog::CacheService)),
App::make(UtilsServiceCatalog::TransactionService)
);
});
//OAUTH2 resource server endpoints
App::singleton('oauth2\resource_server\IUserService', 'services\oauth2\resource_server\UserService');
}

File diff suppressed because it is too large Load Diff

View File

@ -9,34 +9,51 @@ use openid\helpers\OpenIdErrorMessages;
use openid\model\OpenIdNonce;
use openid\services\INonceService;
use utils\exceptions\UnacquiredLockException;
use utils\services\IdentifierGenerator;
use utils\services\ILockManagerService;
use utils\services\ICacheService;
use utils\services\IServerConfigurationService;
use Zend\Math\Rand;
class NonceService implements INonceService
/**
* Class NonceService
* @package services\openid
*/
final class NonceService implements INonceService
{
private $cache_service;
private $lock_manager_service;
private $configuration_service;
/*
* MAY contain additional ASCII characters in the range 33-126 inclusive (printable non-whitespace characters), as necessary to make each response unique
*/
const NoncePopulation = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
/**
* Nonce Salt Length
* @var ICacheService
*/
const NonceSaltLength = 32;
private $cache_service;
/**
* @var ILockManagerService
*/
private $lock_manager_service;
/**
* @var IServerConfigurationService
*/
private $configuration_service;
/**
* @var IdentifierGenerator
*/
private $nonce_generator;
/**
* @param ILockManagerService $lock_manager_service
* @param ICacheService $cache_service
* @param IServerConfigurationService $configuration_service
* @param IdentifierGenerator $nonce_generator
*/
public function __construct(ILockManagerService $lock_manager_service,
ICacheService $cache_service,
IServerConfigurationService $configuration_service)
IServerConfigurationService $configuration_service,
IdentifierGenerator $nonce_generator)
{
$this->lock_manager_service = $lock_manager_service;
$this->cache_service = $cache_service;
$this->configuration_service = $configuration_service;
$this->nonce_generator = $nonce_generator;
}
/**
@ -75,13 +92,7 @@ class NonceService implements INonceService
*/
public function generateNonce()
{
$raw_nonce = null;
do {
$raw_nonce = gmdate('Y-m-d\TH:i:s\Z') . $this->makeNonceSalt();
} while(!$this->cache_service->addSingleValue($raw_nonce.'.mk_nonce', $raw_nonce.'.mk_nonce'));
return new OpenIdNonce($raw_nonce);
return $this->nonce_generator->generate(new OpenIdNonce(255));
}
/**

View File

@ -2,8 +2,10 @@
namespace services\openid;
use Illuminate\Support\ServiceProvider;
use openid\services\NonceUniqueIdentifierGenerator;
use openid\services\OpenIdServiceCatalog;
use App;
use utils\services\UtilsServiceCatalog;
class OpenIdProvider extends ServiceProvider {
@ -22,7 +24,16 @@ class OpenIdProvider extends ServiceProvider {
App::singleton(OpenIdServiceCatalog::TrustedSitesService, 'services\\openid\\TrustedSitesService');
App::singleton(OpenIdServiceCatalog::ServerConfigurationService, 'services\\utils\\ServerConfigurationService');
App::singleton(OpenIdServiceCatalog::UserService, 'services\\openid\\UserService');
App::singleton(OpenIdServiceCatalog::NonceService, 'services\\openid\\NonceService');
App::singleton(OpenIdServiceCatalog::NonceService, function(){
return new NonceService(
App::make(UtilsServiceCatalog::LockManagerService),
App::make(UtilsServiceCatalog::CacheService),
App::make(UtilsServiceCatalog::ServerConfigurationService),
new NonceUniqueIdentifierGenerator(App::make(UtilsServiceCatalog::CacheService))
);
});
}
public function provides()

View File

@ -0,0 +1,43 @@
<?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 auth\CustomAuthProvider;
use utils\services\UtilsServiceCatalog;
use openid\services\OpenIdServiceCatalog;
/**
* Class CustomAuthProviderTest
*/
final class CustomAuthProviderTest extends TestCase {
/**
* @return CustomAuthProvider
*/
public function testCreateProvider(){
$provider = new CustomAuthProvider(
App::make('auth\\IUserRepository'),
App::make('auth\\IMemberRepository'),
App::make('auth\\IAuthenticationExtensionService'),
App::make(OpenIdServiceCatalog::UserService),
App::make(UtilsServiceCatalog::CheckPointService),
App::make(UtilsServiceCatalog::TransactionService),
App::make(UtilsServiceCatalog::LogService)
);
$this->assertTrue(!is_null($provider));
return $provider;
}
}

View File

@ -1,21 +1,25 @@
<?php
use auth\User;
use Illuminate\Support\Facades\App;
use oauth2\OAuth2Protocol;
use services\utils\ServerConfigurationService;
use utils\services\IAuthService;
use utils\services\UtilsServiceCatalog;
use Illuminate\Support\Facades\App;
use services\utils\ServerConfigurationService;
class StubServerConfigurationService extends ServerConfigurationService {
class StubServerConfigurationService extends ServerConfigurationService
{
public function getConfigValue($value){
if($value === 'OAuth2.AccessToken.Lifetime' && isset( $_ENV['access.token.lifetime'])){
return intval($_ENV['access.token.lifetime']);
public function getConfigValue($value)
{
if ($value === 'OAuth2.AccessToken.Lifetime' && isset($_ENV['access.token.lifetime'])) {
return intval($_ENV['access.token.lifetime']);
}
return parent::getConfigValue($value);
}
}
/**
* Class OAuth2ProtocolTest
* Test Suite for OAuth2 Protocol
@ -25,16 +29,16 @@ class OAuth2ProtocolTest extends OpenStackIDBaseTest
private $current_realm;
protected function prepareForTests()
{
parent::prepareForTests();
protected function prepareForTests()
{
parent::prepareForTests();
App::singleton(UtilsServiceCatalog::ServerConfigurationService, 'StubServerConfigurationService');
//Route::enableFilters();
$this->current_realm = Config::get('app.url');
$user = User::where('identifier','=','sebastian.marcet')->first();
$this->be($user);
Session::start();
}
//Route::enableFilters();
$this->current_realm = Config::get('app.url');
$user = User::where('identifier', '=', 'sebastian.marcet')->first();
$this->be($user);
Session::start();
}
/**
* Get Auth Code Test
@ -80,7 +84,7 @@ class OAuth2ProtocolTest extends OpenStackIDBaseTest
'redirect_uri' => 'https://www.test.com/oauth2',
'response_type' => OAuth2Protocol::OAuth2Protocol_ResponseType_Code,
'scope' => sprintf('%s/resource-server/read', $this->current_realm),
OAuth2Protocol::OAuth2Protocol_AccessType =>OAuth2Protocol::OAuth2Protocol_AccessType_Offline,
OAuth2Protocol::OAuth2Protocol_AccessType => OAuth2Protocol::OAuth2Protocol_AccessType_Offline,
);
@ -150,7 +154,7 @@ class OAuth2ProtocolTest extends OpenStackIDBaseTest
'client_id' => $client_id,
'redirect_uri' => 'https://www.test.com/oauth2',
'response_type' => OAuth2Protocol::OAuth2Protocol_ResponseType_Code,
OAuth2Protocol::OAuth2Protocol_AccessType =>OAuth2Protocol::OAuth2Protocol_AccessType_Offline,
OAuth2Protocol::OAuth2Protocol_AccessType => OAuth2Protocol::OAuth2Protocol_AccessType_Offline,
'scope' => sprintf('%s/resource-server/read', $this->current_realm),
);
@ -246,7 +250,7 @@ class OAuth2ProtocolTest extends OpenStackIDBaseTest
'client_id' => $client_id,
'redirect_uri' => 'https://www.test.com/oauth2',
'response_type' => OAuth2Protocol::OAuth2Protocol_ResponseType_Code,
OAuth2Protocol::OAuth2Protocol_AccessType =>OAuth2Protocol::OAuth2Protocol_AccessType_Offline,
OAuth2Protocol::OAuth2Protocol_AccessType => OAuth2Protocol::OAuth2Protocol_AccessType_Offline,
'scope' => sprintf('%s/resource-server/read', $this->current_realm),
);
@ -350,7 +354,7 @@ class OAuth2ProtocolTest extends OpenStackIDBaseTest
OAuth2Protocol::OAuth2Protocol_RedirectUri => 'https://www.test.com/oauth2',
OAuth2Protocol::OAuth2Protocol_ResponseType => OAuth2Protocol::OAuth2Protocol_ResponseType_Code,
OAuth2Protocol::OAuth2Protocol_Scope => sprintf('%s/resource-server/read', $this->current_realm),
OAuth2Protocol::OAuth2Protocol_AccessType =>OAuth2Protocol::OAuth2Protocol_AccessType_Offline
OAuth2Protocol::OAuth2Protocol_AccessType => OAuth2Protocol::OAuth2Protocol_AccessType_Offline
);
$response = $this->action("POST", "OAuth2ProviderController@authorize",
@ -448,7 +452,7 @@ class OAuth2ProtocolTest extends OpenStackIDBaseTest
'redirect_uri' => 'https://www.test.com/oauth2',
'response_type' => OAuth2Protocol::OAuth2Protocol_ResponseType_Code,
'scope' => sprintf('%s/resource-server/read', $this->current_realm),
OAuth2Protocol::OAuth2Protocol_AccessType =>OAuth2Protocol::OAuth2Protocol_AccessType_Offline
OAuth2Protocol::OAuth2Protocol_AccessType => OAuth2Protocol::OAuth2Protocol_AccessType_Offline
);
$response = $this->action("POST", "OAuth2ProviderController@authorize",
@ -586,7 +590,7 @@ class OAuth2ProtocolTest extends OpenStackIDBaseTest
'redirect_uri' => 'https://www.test.com/oauth2',
'response_type' => OAuth2Protocol::OAuth2Protocol_ResponseType_Token,
'scope' => sprintf('%s/resource-server/read', $this->current_realm),
OAuth2Protocol::OAuth2Protocol_AccessType =>OAuth2Protocol::OAuth2Protocol_AccessType_Offline,
OAuth2Protocol::OAuth2Protocol_AccessType => OAuth2Protocol::OAuth2Protocol_AccessType_Offline,
'state' => '123456'
);
@ -640,7 +644,7 @@ class OAuth2ProtocolTest extends OpenStackIDBaseTest
'redirect_uri' => 'https://www.test.com/oauth2',
'response_type' => OAuth2Protocol::OAuth2Protocol_ResponseType_Token,
'scope' => sprintf('%s/resource-server/read', $this->current_realm),
OAuth2Protocol::OAuth2Protocol_AccessType =>OAuth2Protocol::OAuth2Protocol_AccessType_Offline,
OAuth2Protocol::OAuth2Protocol_AccessType => OAuth2Protocol::OAuth2Protocol_AccessType_Offline,
'state' => '123456'
);
@ -695,7 +699,7 @@ class OAuth2ProtocolTest extends OpenStackIDBaseTest
'redirect_uri' => 'https://www.test.com/oauth2',
'response_type' => OAuth2Protocol::OAuth2Protocol_ResponseType_Token,
'scope' => sprintf('%s/resource-server/read', $this->current_realm),
OAuth2Protocol::OAuth2Protocol_AccessType =>OAuth2Protocol::OAuth2Protocol_AccessType_Offline,
OAuth2Protocol::OAuth2Protocol_AccessType => OAuth2Protocol::OAuth2Protocol_AccessType_Offline,
'state' => '123456'
);
@ -750,7 +754,7 @@ class OAuth2ProtocolTest extends OpenStackIDBaseTest
'redirect_uri' => 'https://www.test.com/oauth2',
'response_type' => OAuth2Protocol::OAuth2Protocol_ResponseType_Token,
'scope' => sprintf('%s/resource-server/read', $this->current_realm),
OAuth2Protocol::OAuth2Protocol_AccessType =>OAuth2Protocol::OAuth2Protocol_AccessType_Offline,
OAuth2Protocol::OAuth2Protocol_AccessType => OAuth2Protocol::OAuth2Protocol_AccessType_Offline,
'state' => '123456'
);

View File

@ -1,13 +1,11 @@
<?php
use openid\OpenIdProtocol;
use auth\User;
use utils\services\IAuthService;
use openid\extensions\implementations\OpenIdOAuth2Extension;
use openid\extensions\implementations\OpenIdSREGExtension;
use openid\helpers\OpenIdCryptoHelper;
use openid\OpenIdProtocol;
use utils\services\IAuthService;
use Zend\Crypt\PublicKey\DiffieHellman;
/**
@ -23,14 +21,16 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
private $mod;
private $oauth2_client_id;
private $oauth2_client_secret;
private $user;
public function __construct(){
private $user;
public function __construct()
{
//DH openid values
$this->g = '2';
$this->private = '84009535308644335779530519631942543663544485189066558731295758689838227409144125540638118058012144795574289866857191302071807568041343083679600155026066530597177004145874642611724010339353151653679189142289183802715816551715563883085859667759854344959305451172754264893136955464706052993052626766687910313992';
$this->public = '93500922748114712465435925279613158240858799671601934136793652488458659380414896628304484614933937038790006320444306607890979422427297815641372302594684991758687126229761033142429422299990743006497200988301031430937819368909849994628108111270360657896230712920491471398605159969300956278883668998797148755353';
$this->mod = '155172898181473697471232257763715539915724801966915404479707795314057629378541917580651227423698188993727816152646631438561595825688188889951272158842675419950341258706556549803580104870537681476726513255747040765857479291291572334510643245094715007229621094194349783925984760375594985848253359305585439638443';
$this->oauth2_client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client';
$this->g = '2';
$this->private = '84009535308644335779530519631942543663544485189066558731295758689838227409144125540638118058012144795574289866857191302071807568041343083679600155026066530597177004145874642611724010339353151653679189142289183802715816551715563883085859667759854344959305451172754264893136955464706052993052626766687910313992';
$this->public = '93500922748114712465435925279613158240858799671601934136793652488458659380414896628304484614933937038790006320444306607890979422427297815641372302594684991758687126229761033142429422299990743006497200988301031430937819368909849994628108111270360657896230712920491471398605159969300956278883668998797148755353';
$this->mod = '155172898181473697471232257763715539915724801966915404479707795314057629378541917580651227423698188993727816152646631438561595825688188889951272158842675419950341258706556549803580104870537681476726513255747040765857479291291572334510643245094715007229621094194349783925984760375594985848253359305585439638443';
$this->oauth2_client_id = 'Jiz87D8/Vcvr6fvQbH4HyNgwTlfSyQ3x.openstack.client';
$this->oauth2_client_secret = 'ITc/6Y5N7kOtGKhg';
}
@ -40,10 +40,10 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
Route::enableFilters();
$this->current_realm = Config::get('app.url');
$this->user = User::where('identifier','=','sebastian.marcet')->first();
$this->user = User::where('identifier', '=', 'sebastian.marcet')->first();
$this->be($this->user);
Session::start();
$this->be($this->user);
Session::start();
}
/**
@ -51,7 +51,8 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
* @param $url
* @return array
*/
private function parseOpenIdResponse($url){
private function parseOpenIdResponse($url)
{
$url_parts = @parse_url($url);
$openid_response = array();
$query_params = explode('&', $url_parts['query']);
@ -59,17 +60,22 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
$aux = explode('=', $param, 2);
$openid_response[$aux[0]] = @urldecode($aux[1]);
}
return $openid_response;
}
private function getOpenIdResponseLineBreak($content){
$params = explode("\n",$content);
private function getOpenIdResponseLineBreak($content)
{
$params = explode("\n", $content);
$res = array();
foreach($params as $param){
if(empty($param)) continue;
$openid_param = explode(':',$param,2);
foreach ($params as $param) {
if (empty($param)) {
continue;
}
$openid_param = explode(':', $param, 2);
$res[$openid_param[0]] = $openid_param[1];
}
return $res;
}
@ -78,38 +84,43 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
* @param $openid_response
* @return array
*/
private function prepareCheckAuthenticationParams($openid_response){
private function prepareCheckAuthenticationParams($openid_response)
{
$params = array(
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS) => OpenIdProtocol::OpenID2MessageType,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode) => OpenIdProtocol::CheckAuthenticationMode,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS) => OpenIdProtocol::OpenID2MessageType,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode) => OpenIdProtocol::CheckAuthenticationMode,
);
$encode = array(
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo) =>OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo),
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ClaimedId) =>OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ClaimedId),
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_OpEndpoint) =>OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_OpEndpoint),
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Realm) =>OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Realm),
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Identity) =>OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Identity),
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo) => OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo),
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ClaimedId) => OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ClaimedId),
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_OpEndpoint) => OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_OpEndpoint),
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Realm) => OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Realm),
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Identity) => OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Identity),
);
foreach($openid_response as $key => $value){
if(!array_key_exists($key,$params))
$params[$key] = array_key_exists($key,$encode)? @urldecode($value):$value;
foreach ($openid_response as $key => $value) {
if (!array_key_exists($key, $params)) {
$params[$key] = array_key_exists($key, $encode) ? @urldecode($value) : $value;
}
}
return $params;
}
// test for session associations
public function testAssociationSessionRequestDiffieHellmanSha1(){
public function testAssociationSessionRequestDiffieHellmanSha1()
{
$b64_public = base64_encode(OpenIdCryptoHelper::convert($this->public,DiffieHellman::FORMAT_NUMBER,DiffieHellman::FORMAT_BTWOC));
$b64_public = base64_encode(OpenIdCryptoHelper::convert($this->public, DiffieHellman::FORMAT_NUMBER,
DiffieHellman::FORMAT_BTWOC));
$this->assertTrue($b64_public === 'AIUmVPMheb/hEupD5m6veEEstnBVteyZPy+mlYX7ygxygLG/XuHFa8q4lZERJ9u1DNFOpXHRDq5RbjsaUYRDOtyrbkGbeKo5tPqjsynjXtoMAItxkxCU4jpQLvH85P+u7DeA0h3kKNHFa90ijZTIGSSDRF5wW9N+QPCUCt4G4xWZ');
$params = array(
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS) => OpenIdProtocol::OpenID2MessageType,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode) => OpenIdProtocol::AssociateMode,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS) => OpenIdProtocol::OpenID2MessageType,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode) => OpenIdProtocol::AssociateMode,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_AssocType) => OpenIdProtocol::SignatureAlgorithmHMAC_SHA1,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_SessionType) => OpenIdProtocol::AssociationSessionTypeDHSHA1,
OpenIdProtocol::param(OpenIdProtocol::OpenIdProtocol_DHConsumerPublic) => $b64_public,
@ -134,15 +145,17 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
}
public function testAssociationSessionRequestDiffieHellmanSha256(){
public function testAssociationSessionRequestDiffieHellmanSha256()
{
$b64_public = base64_encode(OpenIdCryptoHelper::convert($this->public,DiffieHellman::FORMAT_NUMBER,DiffieHellman::FORMAT_BTWOC));
$b64_public = base64_encode(OpenIdCryptoHelper::convert($this->public, DiffieHellman::FORMAT_NUMBER,
DiffieHellman::FORMAT_BTWOC));
$this->assertTrue($b64_public === 'AIUmVPMheb/hEupD5m6veEEstnBVteyZPy+mlYX7ygxygLG/XuHFa8q4lZERJ9u1DNFOpXHRDq5RbjsaUYRDOtyrbkGbeKo5tPqjsynjXtoMAItxkxCU4jpQLvH85P+u7DeA0h3kKNHFa90ijZTIGSSDRF5wW9N+QPCUCt4G4xWZ');
$params = array(
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS) => OpenIdProtocol::OpenID2MessageType,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode) => OpenIdProtocol::AssociateMode,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS) => OpenIdProtocol::OpenID2MessageType,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode) => OpenIdProtocol::AssociateMode,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_AssocType) => OpenIdProtocol::SignatureAlgorithmHMAC_SHA256,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_SessionType) => OpenIdProtocol::AssociationSessionTypeDHSHA256,
OpenIdProtocol::param(OpenIdProtocol::OpenIdProtocol_DHConsumerPublic) => $b64_public,
@ -167,11 +180,12 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
}
public function testAssociationSessionRequestNoEncryption(){
public function testAssociationSessionRequestNoEncryption()
{
$params = array(
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS) => OpenIdProtocol::OpenID2MessageType,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode) => OpenIdProtocol::AssociateMode,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS) => OpenIdProtocol::OpenID2MessageType,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode) => OpenIdProtocol::AssociateMode,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_AssocType) => OpenIdProtocol::AssociationSessionTypeNoEncryption,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_SessionType) => OpenIdProtocol::AssociationSessionTypeNoEncryption,
);
@ -188,7 +202,7 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
$this->assertTrue($openid_response['assoc_type'] === OpenIdProtocol::AssociationSessionTypeNoEncryption);
$this->assertTrue(isset($openid_response['session_type']));
$this->assertTrue($openid_response['session_type'] === OpenIdProtocol::AssociationSessionTypeNoEncryption);
$this->assertTrue(isset($openid_response['assoc_handle']) && ! empty($openid_response['assoc_handle']));
$this->assertTrue(isset($openid_response['assoc_handle']) && !empty($openid_response['assoc_handle']));
$this->assertTrue(isset($openid_response['expires_in']));
$this->assertTrue(isset($openid_response['mac_key']) && !empty($openid_response['mac_key']));
@ -196,16 +210,17 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
// test for authentication
public function testAuthenticationSetupModePrivateAssociation(){
public function testAuthenticationSetupModePrivateAssociation()
{
//set login info
Session::set("openid.authorization.response", IAuthService::AuthorizationResponse_AllowOnce);
$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_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",
);
@ -220,22 +235,25 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
$this->assertTrue(isset($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo)]));
//http://openid.net/specs/openid-authentication-2_0.html#check_auth
$response = $this->action("POST", "OpenIdProviderController@endpoint", $this->prepareCheckAuthenticationParams($openid_response));
$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');
}
public function testAuthenticationSetupModeSessionAssociationDHSha256(){
public function testAuthenticationSetupModeSessionAssociationDHSha256()
{
$b64_public = base64_encode(OpenIdCryptoHelper::convert($this->public,DiffieHellman::FORMAT_NUMBER,DiffieHellman::FORMAT_BTWOC));
$b64_public = base64_encode(OpenIdCryptoHelper::convert($this->public, DiffieHellman::FORMAT_NUMBER,
DiffieHellman::FORMAT_BTWOC));
$this->assertTrue($b64_public === 'AIUmVPMheb/hEupD5m6veEEstnBVteyZPy+mlYX7ygxygLG/XuHFa8q4lZERJ9u1DNFOpXHRDq5RbjsaUYRDOtyrbkGbeKo5tPqjsynjXtoMAItxkxCU4jpQLvH85P+u7DeA0h3kKNHFa90ijZTIGSSDRF5wW9N+QPCUCt4G4xWZ');
$params = array(
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS) => OpenIdProtocol::OpenID2MessageType,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode) => OpenIdProtocol::AssociateMode,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS) => OpenIdProtocol::OpenID2MessageType,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode) => OpenIdProtocol::AssociateMode,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_AssocType) => OpenIdProtocol::SignatureAlgorithmHMAC_SHA256,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_SessionType) => OpenIdProtocol::AssociationSessionTypeDHSHA256,
OpenIdProtocol::param(OpenIdProtocol::OpenIdProtocol_DHConsumerPublic) => $b64_public,
@ -261,11 +279,11 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
Session::set("openid.authorization.response", IAuthService::AuthorizationResponse_AllowOnce);
$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_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",
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_AssocHandle) => $openid_response['assoc_handle'],
);
@ -305,24 +323,25 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
}
public function testAuthenticationCheckImmediateAuthenticationPrivateSession(){
public function testAuthenticationCheckImmediateAuthenticationPrivateSession()
{
//set login info
Session::set("openid.authorization.response", IAuthService::AuthorizationResponse_AllowOnce);
//add trusted site
$site = new OpenIdTrustedSite;
$site->realm = 'https://www.test.com/';
$site->policy = IAuthService::AuthorizationResponse_AllowForever;
$site->user_id = $this->user->getId();
$site->data = json_encode(array());
$site->Save();
//add trusted site
$site = new OpenIdTrustedSite;
$site->realm = 'https://www.test.com/';
$site->policy = IAuthService::AuthorizationResponse_AllowForever;
$site->user_id = $this->user->getId();
$site->data = json_encode(array());
$site->Save();
$params = array(
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS) => OpenIdProtocol::OpenID2MessageType,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode) => OpenIdProtocol::ImmediateMode,
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_NS) => OpenIdProtocol::OpenID2MessageType,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode) => OpenIdProtocol::ImmediateMode,
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",
);
@ -361,60 +380,61 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
}
/**
*/
public function testAuthenticationCheckImmediateAuthenticationPrivateSession_SetupNeeded(){
//set login info
Session::set("openid.authorization.response", IAuthService::AuthorizationResponse_AllowOnce);
$this->user->trusted_sites()->delete();
$params = array(
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS) => OpenIdProtocol::OpenID2MessageType,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode) => OpenIdProtocol::ImmediateMode,
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",
);
/**
*/
public function testAuthenticationCheckImmediateAuthenticationPrivateSession_SetupNeeded()
{
//set login info
Session::set("openid.authorization.response", IAuthService::AuthorizationResponse_AllowOnce);
$this->user->trusted_sites()->delete();
$params = array(
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS) => OpenIdProtocol::OpenID2MessageType,
OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode) => OpenIdProtocol::ImmediateMode,
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",
);
$response = $this->action("POST", "OpenIdProviderController@endpoint", $params);
$response = $this->action("POST", "OpenIdProviderController@endpoint", $params);
$this->assertResponseStatus(302);
$this->assertResponseStatus(302);
$openid_response = $this->parseOpenIdResponse($response->getTargetUrl());
$openid_response = $this->parseOpenIdResponse($response->getTargetUrl());
$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_NS)]));
$this->assertTrue(!empty($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_NS)]));
$this->assertTrue(isset($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode)]));
$this->assertTrue(!empty($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode)]));
$this->assertTrue($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode)]==OpenIdProtocol::SetupNeededMode );
$this->assertTrue(isset($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode)]));
$this->assertTrue(!empty($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode)]));
$this->assertTrue($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Mode)] == OpenIdProtocol::SetupNeededMode);
$this->assertTrue(isset($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo)]));
$this->assertTrue(!empty($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo)]));
$this->assertTrue($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo)]=='https://www.test.com/oauth2');
}
$this->assertTrue(isset($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo)]));
$this->assertTrue(!empty($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo)]));
$this->assertTrue($openid_response[OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo)] == 'https://www.test.com/oauth2');
}
//extension tests
public function testCheckSetupSREGExtension(){
public function testCheckSetupSREGExtension()
{
//set login info
Session::set("openid.authorization.response", IAuthService::AuthorizationResponse_AllowForever);
$sreg_required_params = array('email','fullname');
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_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::Required) => implode(",",$sreg_required_params),
OpenIdSREGExtension::paramNamespace() => OpenIdSREGExtension::NamespaceUrl,
OpenIdSREGExtension::param(OpenIdSREGExtension::Required) => implode(",", $sreg_required_params),
);
@ -459,14 +479,15 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
$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(!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 ==='smarcet@gmail.com');
$this->assertTrue(!empty($email) && $email === 'smarcet@gmail.com');
//http://openid.net/specs/openid-authentication-2_0.html#check_auth
$response = $this->action("POST", "OpenIdProviderController@endpoint", $this->prepareCheckAuthenticationParams($openid_response));
$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');
@ -477,33 +498,34 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
* https://developers.google.com/accounts/docs/OpenID#oauth
*/
public function testCheckSetupOAuth2Extension(){
public function testCheckSetupOAuth2Extension()
{
//set login info
Session::set("openid.authorization.response", IAuthService::AuthorizationResponse_AllowForever);
$scope = array(
sprintf('%s/resource-server/read',$this->current_realm),
sprintf('%s/resource-server/read.page',$this->current_realm),
sprintf('%s/resource-server/write',$this->current_realm),
sprintf('%s/resource-server/delete',$this->current_realm),
sprintf('%s/resource-server/update',$this->current_realm),
sprintf('%s/resource-server/update.status',$this->current_realm),
sprintf('%s/resource-server/regenerate.secret',$this->current_realm),
sprintf('%s/resource-server/read', $this->current_realm),
sprintf('%s/resource-server/read.page', $this->current_realm),
sprintf('%s/resource-server/write', $this->current_realm),
sprintf('%s/resource-server/delete', $this->current_realm),
sprintf('%s/resource-server/update', $this->current_realm),
sprintf('%s/resource-server/update.status', $this->current_realm),
sprintf('%s/resource-server/regenerate.secret', $this->current_realm),
);
$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_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",
//oauth2
OpenIdOAuth2Extension::paramNamespace() => OpenIdOAuth2Extension::NamespaceUrl,
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::ClientId) => $this->oauth2_client_id,
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::Scope) => implode(' ',$scope),
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::State) => uniqid(),
OpenIdOAuth2Extension::paramNamespace() => OpenIdOAuth2Extension::NamespaceUrl,
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::ClientId) => $this->oauth2_client_id,
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::Scope) => implode(' ', $scope),
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::State) => uniqid(),
);
$response = $this->action("POST", "OpenIdProviderController@endpoint", $params);
@ -553,39 +575,41 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
//http://openid.net/specs/openid-authentication-2_0.html#check_auth
$response = $this->action("POST", "OpenIdProviderController@endpoint", $this->prepareCheckAuthenticationParams($openid_response));
$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');
}
public function testCheckSetupOAuth2ExtensionWrongClientId(){
public function testCheckSetupOAuth2ExtensionWrongClientId()
{
//set login info
Session::set("openid.authorization.response", IAuthService::AuthorizationResponse_AllowOnce);
$scope = array(
sprintf('%s/resource-server/read',$this->current_realm),
sprintf('%s/resource-server/read.page',$this->current_realm),
sprintf('%s/resource-server/write',$this->current_realm),
sprintf('%s/resource-server/delete',$this->current_realm),
sprintf('%s/resource-server/update',$this->current_realm),
sprintf('%s/resource-server/update.status',$this->current_realm),
sprintf('%s/resource-server/regenerate.secret',$this->current_realm),
sprintf('%s/resource-server/read', $this->current_realm),
sprintf('%s/resource-server/read.page', $this->current_realm),
sprintf('%s/resource-server/write', $this->current_realm),
sprintf('%s/resource-server/delete', $this->current_realm),
sprintf('%s/resource-server/update', $this->current_realm),
sprintf('%s/resource-server/update.status', $this->current_realm),
sprintf('%s/resource-server/regenerate.secret', $this->current_realm),
);
$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_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",
//oauth2
OpenIdOAuth2Extension::paramNamespace() => OpenIdOAuth2Extension::NamespaceUrl,
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::ClientId) => 'wrong_client_id',
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::Scope) => implode(' ',$scope),
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::State) => uniqid(),
OpenIdOAuth2Extension::paramNamespace() => OpenIdOAuth2Extension::NamespaceUrl,
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::ClientId) => 'wrong_client_id',
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::Scope) => implode(' ', $scope),
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::State) => uniqid(),
);
$response = $this->action("POST", "OpenIdProviderController@endpoint", $params);
@ -632,40 +656,42 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
//http://openid.net/specs/openid-authentication-2_0.html#check_auth
$response = $this->action("POST", "OpenIdProviderController@endpoint", $this->prepareCheckAuthenticationParams($openid_response));
$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');
}
public function testCheckSetupOAuth2ExtensionBadRequest(){
public function testCheckSetupOAuth2ExtensionBadRequest()
{
//set login info
Session::set("openid.authorization.response", IAuthService::AuthorizationResponse_AllowOnce);
$scope = array(
sprintf('%s/resource-server/read',$this->current_realm),
sprintf('%s/resource-server/read.page',$this->current_realm),
sprintf('%s/resource-server/write',$this->current_realm),
sprintf('%s/resource-server/delete',$this->current_realm),
sprintf('%s/resource-server/update',$this->current_realm),
sprintf('%s/resource-server/update.status',$this->current_realm),
sprintf('%s/resource-server/regenerate.secret',$this->current_realm),
sprintf('%s/resource-server/read', $this->current_realm),
sprintf('%s/resource-server/read.page', $this->current_realm),
sprintf('%s/resource-server/write', $this->current_realm),
sprintf('%s/resource-server/delete', $this->current_realm),
sprintf('%s/resource-server/update', $this->current_realm),
sprintf('%s/resource-server/update.status', $this->current_realm),
sprintf('%s/resource-server/regenerate.secret', $this->current_realm),
);
$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_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",
//oauth2
OpenIdOAuth2Extension::paramNamespace() => OpenIdOAuth2Extension::NamespaceUrl,
OpenIdOAuth2Extension::paramNamespace() => OpenIdOAuth2Extension::NamespaceUrl,
//missing client id
//OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::ClientId) => 'wrong_client_id',
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::Scope) => implode(' ',$scope),
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::State) => uniqid(),
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::Scope) => implode(' ', $scope),
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::State) => uniqid(),
);
$response = $this->action("POST", "OpenIdProviderController@endpoint", $params);
@ -712,40 +738,42 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
//http://openid.net/specs/openid-authentication-2_0.html#check_auth
$response = $this->action("POST", "OpenIdProviderController@endpoint", $this->prepareCheckAuthenticationParams($openid_response));
$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');
}
public function testCheckSetupOAuth2ExtensionSubView(){
public function testCheckSetupOAuth2ExtensionSubView()
{
//set login info
$user = User::where('identifier','=','sebastian.marcet')->first();
$user = User::where('identifier', '=', 'sebastian.marcet')->first();
Auth::login($user);
$scope = array(
sprintf('%s/resource-server/read',$this->current_realm),
sprintf('%s/resource-server/read.page',$this->current_realm),
sprintf('%s/resource-server/write',$this->current_realm),
sprintf('%s/resource-server/delete',$this->current_realm),
sprintf('%s/resource-server/update',$this->current_realm),
sprintf('%s/resource-server/update.status',$this->current_realm),
sprintf('%s/resource-server/regenerate.secret',$this->current_realm),
sprintf('%s/resource-server/read', $this->current_realm),
sprintf('%s/resource-server/read.page', $this->current_realm),
sprintf('%s/resource-server/write', $this->current_realm),
sprintf('%s/resource-server/delete', $this->current_realm),
sprintf('%s/resource-server/update', $this->current_realm),
sprintf('%s/resource-server/update.status', $this->current_realm),
sprintf('%s/resource-server/regenerate.secret', $this->current_realm),
);
$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_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",
//oauth2
OpenIdOAuth2Extension::paramNamespace() => OpenIdOAuth2Extension::NamespaceUrl,
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::ClientId) => $this->oauth2_client_id,
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::Scope) => implode(' ',$scope),
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::State) => uniqid(),
OpenIdOAuth2Extension::paramNamespace() => OpenIdOAuth2Extension::NamespaceUrl,
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::ClientId) => $this->oauth2_client_id,
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::Scope) => implode(' ', $scope),
OpenIdOAuth2Extension::param(OpenIdOAuth2Extension::State) => uniqid(),
);
$response = $this->action("POST", "OpenIdProviderController@endpoint", $params);
@ -755,7 +783,8 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
$content = $response->getContent();
}
public function testDiscovery(){
public function testDiscovery()
{
$response = $this->action("GET", "HomeController@index",
array(),
array(),
@ -769,8 +798,8 @@ class OpenIdProtocolTest extends OpenStackIDBaseTest
$content = $response->getContent();
$this->assertTrue(strpos($content,'<xrds:XRDS')!==false);
$this->assertTrue(strpos($content,'http://specs.openid.net/auth/2.0/server')!==false);
$this->assertTrue(strpos($content, '<xrds:XRDS') !== false);
$this->assertTrue(strpos($content, 'http://specs.openid.net/auth/2.0/server') !== false);
}
}

View File

@ -8,9 +8,13 @@ class XRDSDocumentTest extends TestCase
public function testBuildDocument()
{
$services = array();
array_push($services, new XRDSService(0, "http://specs.openid.net/auth/2.0/server", "https://dev.openstackid.com", array("http://openid.net/srv/ax/1.0", "http://specs.openid.net/extensions/pape/1.0")));
array_push($services,
new XRDSService(0, "http://specs.openid.net/auth/2.0/server", "https://dev.openstackid.com",
array("http://openid.net/srv/ax/1.0", "http://specs.openid.net/extensions/pape/1.0")));
$builder = new XRDSDocumentBuilder($services);
$xrds = $builder->render();
$this->assertTrue(!empty($xrds) && str_contains($xrds, "http://specs.openid.net/auth/2.0/server") && str_contains($xrds, "http://openid.net/srv/ax/1.0") && str_contains($xrds, "http://specs.openid.net/extensions/pape/1.0"));
$this->assertTrue(!empty($xrds) && str_contains($xrds,
"http://specs.openid.net/auth/2.0/server") && str_contains($xrds,
"http://openid.net/srv/ax/1.0") && str_contains($xrds, "http://specs.openid.net/extensions/pape/1.0"));
}
}

View File

@ -11,7 +11,8 @@
"greggilbert/recaptcha": "1.0.*",
"mockery/mockery": "0.9.4",
"doctrine/dbal": "~2.3",
"way/laravel-test-helpers": "dev-master"
"way/laravel-test-helpers": "dev-master",
"smarcet/jose4php" : "dev-master"
},
"autoload": {
"classmap": [
@ -21,7 +22,7 @@
"app/database/migrations",
"app/database/seeds",
"app/tests",
"app/tests/TestCase.php",
"app/tests/TestCase.php",
"app/libs",
"app/services",
"app/repositories",