Skip to content

Commit

Permalink
Merge pull request #530 from ADIRE/develop
Browse files Browse the repository at this point in the history
Add PublicKeyInterface and  UserClaimsInterface to Cassandra Storage engine
  • Loading branch information
bshaffer committed Mar 3, 2015
2 parents e3d1d24 + 4f6cb5c commit edd37cc
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 4 deletions.
93 changes: 90 additions & 3 deletions src/OAuth2/Storage/Cassandra.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use phpcassa\ColumnFamily;
use phpcassa\ColumnSlice;
use phpcassa\Connection\ConnectionPool;
use OAuth2\OpenID\Storage\UserClaimsInterface;
use OAuth2\OpenID\Storage\AuthorizationCodeInterface as OpenIDAuthorizationCodeInterface;

/**
Expand Down Expand Up @@ -35,6 +36,8 @@ class Cassandra implements AuthorizationCodeInterface,
RefreshTokenInterface,
JwtBearerInterface,
ScopeInterface,
PublicKeyInterface,
UserClaimsInterface,
OpenIDAuthorizationCodeInterface
{

Expand All @@ -58,7 +61,7 @@ public function __construct($connection = array(), array $config = array())
$this->cassandra = $connection;
} else {
if (!is_array($connection)) {
throw new \InvalidArgumentException('First argument to OAuth2\Storage\Mongo must be an instance of MongoDB or a configuration array');
throw new \InvalidArgumentException('First argument to OAuth2\Storage\Cassandra must be an instance of phpcassa\Connection\ConnectionPool or a configuration array');
}
$connection = array_merge(array(
'keyspace' => 'oauth2',
Expand All @@ -80,6 +83,7 @@ public function __construct($connection = array(), array $config = array())
'user_key' => 'oauth_users:',
'jwt_key' => 'oauth_jwt:',
'scope_key' => 'oauth_scopes:',
'public_key_key' => 'oauth_public_keys:',
), $config);
}

Expand All @@ -88,11 +92,11 @@ protected function getValue($key)
if (isset($this->cache[$key])) {
return $this->cache[$key];
}

$cf = new ColumnFamily($this->cassandra, $this->config['column_family']);

try {
$value = array_shift($cf->get($key, new ColumnSlice("", "")));
$value = $cf->get($key, new ColumnSlice("", ""));
$value = array_shift($value);
} catch (\cassandra\NotFoundException $e) {
return false;
}
Expand Down Expand Up @@ -363,4 +367,87 @@ public function setJti($client_id, $subject, $audience, $expiration, $jti)
//TODO: Needs cassandra implementation.
throw new \Exception('setJti() for the Cassandra driver is currently unimplemented.');
}

/* PublicKeyInterface */
public function getPublicKey($client_id = '')
{
$public_key = $this->getValue($this->config['public_key_key'] . $client_id);
if (is_array($public_key)) {
return $public_key['public_key'];
}
$public_key = $this->getValue($this->config['public_key_key']);
if (is_array($public_key)) {
return $public_key['public_key'];
}
}

public function getPrivateKey($client_id = '')
{
$public_key = $this->getValue($this->config['public_key_key'] . $client_id);
if (is_array($public_key)) {
return $public_key['private_key'];
}
$public_key = $this->getValue($this->config['public_key_key']);
if (is_array($public_key)) {
return $public_key['private_key'];
}
}

public function getEncryptionAlgorithm($client_id = null)
{
$public_key = $this->getValue($this->config['public_key_key'] . $client_id);
if (is_array($public_key)) {
return $public_key['encryption_algorithm'];
}
$public_key = $this->getValue($this->config['public_key_key']);
if (is_array($public_key)) {
return $public_key['encryption_algorithm'];
}
return 'RS256';
}

/* UserClaimsInterface */
public function getUserClaims($user_id, $claims)
{
$userDetails = $this->getUserDetails($user_id);
if (!is_array($userDetails)) {
return false;
}

$claims = explode(' ', trim($claims));
$userClaims = array();

// for each requested claim, if the user has the claim, set it in the response
$validClaims = explode(' ', self::VALID_CLAIMS);
foreach ($validClaims as $validClaim) {
if (in_array($validClaim, $claims)) {
if ($validClaim == 'address') {
// address is an object with subfields
$userClaims['address'] = $this->getUserClaim($validClaim, $userDetails['address'] ?: $userDetails);
} else {
$userClaims = array_merge($userClaims, $this->getUserClaim($validClaim, $userDetails));
}
}
}

return $userClaims;
}

protected function getUserClaim($claim, $userDetails)
{
$userClaims = array();
$claimValuesString = constant(sprintf('self::%s_CLAIM_VALUES', strtoupper($claim)));
$claimValues = explode(' ', $claimValuesString);

foreach ($claimValues as $value) {
if ($value == 'email_verified') {
$userClaims[$value] = $userDetails[$value]=='true' ? true : false;
} else {
$userClaims[$value] = isset($userDetails[$value]) ? $userDetails[$value] : null;
}
}

return $userClaims;
}

}
12 changes: 11 additions & 1 deletion test/lib/OAuth2/Storage/Bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -258,12 +258,15 @@ private function createCassandraDb(Cassandra $storage)
));

$sys->create_column_family('oauth2_test', 'auth');
$cassandra = new \phpcassa\Connection\ConnectionPool('oauth2_test', array('127.0.0.1:9160'));
$cf = new \phpcassa\ColumnFamily($cassandra, 'auth');

// populate the data
$storage->setClientDetails("oauth_test_client", "testpass", "http://example.com", 'implicit password');
$storage->setAccessToken("testtoken", "Some Client", '', time() + 1000);
$storage->setAuthorizationCode("testcode", "Some Client", '', '', time() + 1000);
$storage->setUser("testuser", "password");



$storage->setScope('supportedscope1 supportedscope2 supportedscope3 supportedscope4');
$storage->setScope('defaultscope1 defaultscope2', null, 'default');
Expand All @@ -281,6 +284,13 @@ private function createCassandraDb(Cassandra $storage)
$storage->setScope('clientscope3', 'Test Default Scope Client ID 2', 'default');

$storage->setClientKey('oauth_test_client', $this->getTestPublicKey(), 'test_subject');

$cf->insert("oauth_public_keys:ClientID_One", array('__data' => json_encode(array("public_key" => "client_1_public", "private_key" => "client_1_private", "encryption_algorithm" => "RS256"))));
$cf->insert("oauth_public_keys:ClientID_Two", array('__data' => json_encode(array("public_key" => "client_2_public", "private_key" => "client_2_private", "encryption_algorithm" => "RS256"))));
$cf->insert("oauth_public_keys:", array('__data' => json_encode(array("public_key" => $this->getTestPublicKey(), "private_key" => $this->getTestPrivateKey(), "encryption_algorithm" => "RS256"))));

$cf->insert("oauth_users:testuser", array('__data' =>json_encode(array("password" => "password", "email" => "testuser@test.com", "email_verified" => true))));

}

private function createSqliteDb(\PDO $pdo)
Expand Down

0 comments on commit edd37cc

Please sign in to comment.