class OAuth2Storage in OAuth2 Server 8
Same name and namespace in other branches
- 2.0.x src/OAuth2Storage.php \Drupal\oauth2_server\OAuth2Storage
Provides Drupal OAuth2 storage for the library.
@package Drupal\oauth2_server
Hierarchy
- class \Drupal\oauth2_server\OAuth2Storage implements OAuth2StorageInterface
Expanded class hierarchy of OAuth2Storage
1 string reference to 'OAuth2Storage'
1 service uses OAuth2Storage
File
- src/
OAuth2Storage.php, line 19
Namespace
Drupal\oauth2_serverView source
class OAuth2Storage implements OAuth2StorageInterface {
/**
* The entity manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The password hasher.
*
* @var \Drupal\Core\Password\PasswordInterface
*/
protected $passwordHasher;
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The config factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* The time object.
*
* @var \Drupal\Component\Datetime\TimeInterface
*/
protected $time;
/**
* Constructs a new OAuth2Storage.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Password\PasswordInterface $password_hasher
* The password hasher.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory.
* @param \Drupal\Component\Datetime\TimeInterface $time
* The time object.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, PasswordInterface $password_hasher, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory, TimeInterface $time) {
$this->entityTypeManager = $entity_type_manager;
$this->passwordHasher = $password_hasher;
$this->moduleHandler = $module_handler;
$this->configFactory = $config_factory;
$this->time = $time;
}
/**
* Retrieve the account from the storage.
*
* @param string $username
* The username or email address of the account.
*
* @return \Drupal\user\UserInterface|bool
* The account loaded from the storage or false.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function getStorageAccount($username) {
/** @var \Drupal\user\UserInterface[] $users */
$users = $this->entityTypeManager
->getStorage('user')
->loadByProperties([
'name' => $username,
]);
if ($users) {
return reset($users);
}
else {
// An email address might have been supplied instead of the username.
/** @var \Drupal\user\UserInterface[] $users */
$users = $this->entityTypeManager
->getStorage('user')
->loadByProperties([
'mail' => $username,
]);
if ($users) {
return reset($users);
}
}
return FALSE;
}
/**
* Get the client from the entity backend.
*
* @param string $client_id
* The client id to find.
*
* @return \Drupal\oauth2_server\ClientInterface|bool
* A client entity or false.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function getStorageClient($client_id) {
/** @var \Drupal\oauth2_server\ClientInterface[] $clients */
$clients = $this->entityTypeManager
->getStorage('oauth2_server_client')
->loadByProperties([
'client_id' => $client_id,
]);
if ($clients) {
return reset($clients);
}
return FALSE;
}
/**
* Get the token from the entity backend.
*
* @param string $token
* The token to find.
*
* @return \Drupal\oauth2_server\TokenInterface|bool
* Returns the token or FALSE.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function getStorageToken($token) {
/** @var \Drupal\oauth2_server\TokenInterface[] $tokens */
$tokens = $this->entityTypeManager
->getStorage('oauth2_server_token')
->loadByProperties([
'token' => $token,
]);
if ($tokens) {
return reset($tokens);
}
return FALSE;
}
/**
* Get the authorization code from the entity backend.
*
* @param string $code
* The authorization code string.
*
* @return \Drupal\oauth2_server\AuthorizationCodeInterface|bool
* Returns the code or FALSE.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function getStorageAuthorizationCode($code) {
/** @var \Drupal\oauth2_server\AuthorizationCodeInterface[] $codes */
$codes = $this->entityTypeManager
->getStorage('oauth2_server_authorization_code')
->loadByProperties([
'code' => $code,
]);
if ($codes) {
return reset($codes);
}
return FALSE;
}
/**
* Check client credentials.
*
* @param string $client_id
* The client id string.
* @param string|null $client_secret
* The client secret string.
*
* @return bool
* A boolean whether the credentials are correct.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function checkClientCredentials($client_id, $client_secret = NULL) {
$client = $this
->getClientDetails($client_id);
if (!$client) {
return FALSE;
}
// The client may omit the client secret or provide NULL, and expect that to
// be treated the same as an empty string.
// See https://tools.ietf.org/html/rfc6749#section-2.3.1
if ($client['client_secret'] === '' && ($client_secret === '' || $client_secret === NULL)) {
return TRUE;
}
return $this->passwordHasher
->check($client_secret, $client['client_secret']);
}
/**
* Is public client.
*
* @param string $client_id
* The client id string.
*
* @return bool
* Whether this is a public client.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function isPublicClient($client_id) {
$client = $this
->getClientDetails($client_id);
return $client && empty($client['client_secret']);
}
/**
* Get client credentials.
*
* @param string $client_id
* The client id string.
*
* @return array|bool|\Drupal\oauth2_server\Entity\Client
* An client array.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function getClientDetails($client_id) {
/** @var \Drupal\oauth2_server\ClientInterface $client */
$client = $this
->getStorageClient($client_id);
if ($client) {
// Return a client array in the format expected by the library.
$client = [
'client_id' => $client->client_id,
'client_secret' => $client->client_secret,
'public_key' => $client->public_key,
// The library expects multiple redirect uris to be separated by
// a space, but the module separates them by a newline, matching
// Drupal behavior in other areas.
'redirect_uri' => str_replace([
"\r\n",
"\r",
"\n",
], ' ', $client->redirect_uri),
];
}
return $client;
}
/**
* Get client scope.
*
* @param string $client_id
* The client id string.
*
* @return null
* The module doesn't currently support per-client scopes.
*/
public function getClientScope($client_id) {
return NULL;
}
/**
* Check restricted grant type.
*
* @param string $client_id
* The client id string.
* @param string $grant_type
* The grant type string.
*
* @return bool
* Whether the grant type is available.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function checkRestrictedGrantType($client_id, $grant_type) {
/** @var \Drupal\oauth2_server\ClientInterface $client */
$client = $this
->getStorageClient($client_id);
$server = $client
->getServer();
if (!empty($client->settings['override_grant_types'])) {
$grant_types = array_filter($client->settings['grant_types']);
$allow_implicit = $client->settings['allow_implicit'];
}
else {
// Fallback to the global server settings.
$grant_types = array_filter($server->settings['grant_types']);
$allow_implicit = $server->settings['allow_implicit'];
}
// Implicit flow is enabled by a different setting, so it needs to be
// added to the check separately.
if ($allow_implicit) {
$grant_types['implicit'] = 'implicit';
}
return in_array($grant_type, $grant_types);
}
/**
* Get access token.
*
* @param string $access_token
* The access token string.
*
* @return array|bool
* An access token array or false.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function getAccessToken($access_token) {
/** @var \Drupal\oauth2_server\TokenInterface $token */
$token = $this
->getStorageToken($access_token);
if (!$token) {
return FALSE;
}
$user = $token
->getUser();
$enabled_grant_types = array_filter($token
->getClient()
->getServer()
->get('settings')['grant_types']);
if (!in_array('client_credentials', $enabled_grant_types)) {
if ($user && $user
->isBlocked()) {
// If the user is blocked, deny access.
return FALSE;
}
}
$scopes = [];
/** @var \Drupal\oauth2_server\ScopeInterface[] $scope_entities */
$scope_entities = $token->scopes
->referencedEntities();
foreach ($scope_entities as $scope) {
$scopes[] = $scope->scope_id;
}
sort($scopes);
// Return a token array in the format expected by the library.
$token_array = [
'server' => $token
->getClient()
->getServer()
->id(),
'client_id' => $token
->getClient()->client_id,
'user_id' => $user
->id(),
'user_uuid' => $user
->uuid(),
'access_token' => $token->token->value,
'expires' => (int) $token->expires->value,
'scope' => implode(' ', $scopes),
];
// Track last access on the token.
$this
->logAccessTime($token);
return $token_array;
}
/**
* Track the time the token was accessed.
*
* @param \Drupal\oauth2_server\TokenInterface $token
* A token object.
*/
protected function logAccessTime(TokenInterface $token) {
if (empty($token->last_access->value) || $token->last_access->value != $this->time
->getRequestTime()) {
$token->last_access = $this->time
->getRequestTime();
try {
$token
->save();
} catch (\Exception $e) {
// @todo find a way to reliably handle concurrent updates of last_access.
}
}
}
/**
* Set access token.
*
* @param string $access_token
* The access token string.
* @param string $client_id
* The client id string.
* @param int $uid
* The user id.
* @param int $expires
* The timestamp the token expires.
* @param string|null $scope
* The scope string.
*
* @return int
* Whether the access token could be saved or not.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function setAccessToken($access_token, $client_id, $uid, $expires, $scope = NULL) {
$client = $this
->getStorageClient($client_id);
if (!$client) {
throw new \InvalidArgumentException("The supplied client couldn't be loaded.");
}
// If no token was found, start with a new entity.
$token = $this
->getStorageToken($access_token);
if (!$token) {
// The username is not required, the "Client credentials" grant type
// doesn't provide it, for instance.
if (!$uid || !$this->entityTypeManager
->getStorage('user')
->load($uid)) {
$uid = 0;
}
$token = $this->entityTypeManager
->getStorage('oauth2_server_token')
->create([
'type' => 'access',
]);
$token->client_id = $client
->id();
$token->uid = $uid;
$token->token = $access_token;
}
$token->expires = $expires;
$this
->setScopeData($token, $client
->getServer(), $scope);
return $token
->save();
}
/**
* Get authorization code.
*
* @param string $code
* The authorization code string.
*
* @return array|bool
* An authorization code array or false.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function getAuthorizationCode($code) {
/** @var \Drupal\oauth2_server\AuthorizationCodeInterface $code */
$code = $this
->getStorageAuthorizationCode($code);
if (!$code) {
return FALSE;
}
$scopes = [];
/** @var \Drupal\oauth2_server\ScopeInterface[] $scope_entities */
$scope_entities = $code->scopes
->referencedEntities();
foreach ($scope_entities as $scope) {
$scopes[] = $scope->scope_id;
}
sort($scopes);
// Return a code array in the format expected by the library.
$code_array = [
'server' => $code
->getClient()
->getServer()
->id(),
'client_id' => $code
->getClient()->client_id,
'user_id' => $code
->getUser()
->id(),
'user_uuid' => $code
->getUser()
->uuid(),
'authorization_code' => $code->code->value,
'redirect_uri' => $code->redirect_uri->value,
'expires' => (int) $code->expires->value,
'scope' => implode(' ', $scopes),
'id_token' => $code->id_token->value,
];
// Examine the id_token and alter the OpenID Connect 'sub' property if
// necessary. The 'sub' property is usually the user's UID, but this is
// configurable for backwards compatibility reasons. See:
// https://www.drupal.org/node/2274357#comment-9779467
$sub_property = $this->configFactory
->get('oauth2_server.oauth')
->get('user_sub_property');
if (!empty($code_array['id_token']) && $sub_property != 'uid') {
$account = $code
->getUser();
$desired_sub = $account->{$sub_property}->value;
$parts = explode('.', $code_array['id_token']);
$claims = json_decode(Utility::base64urlDecode($parts[1]), TRUE);
if (isset($claims['sub']) && $desired_sub != $claims['sub']) {
$claims['sub'] = $desired_sub;
$parts[1] = Utility::base64urlEncode(json_encode($claims));
$code_array['id_token'] = implode('.', $parts);
}
}
return $code_array;
}
/**
* Set authorization code.
*
* @param string $code
* The authorization code string.
* @param mixed $client_id
* The client id string.
* @param int $uid
* The user uid.
* @param string $redirect_uri
* The redirect uri string.
* @param int $expires
* The timestamp the authorization code expires.
* @param string|null $scope
* The scope string.
* @param string|null $id_token
* The token string.
*
* @return int
* Whether the authorization code could be saved or not.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function setAuthorizationCode($code, $client_id, $uid, $redirect_uri, $expires, $scope = NULL, $id_token = NULL) {
/** @var \Drupal\oauth2_server\ClientInterface $client */
$client = $this
->getStorageClient($client_id);
if (!$client) {
throw new \InvalidArgumentException("The supplied client couldn't be loaded.");
}
// If no code was found, start with a new entity.
/** @var \Drupal\oauth2_server\AuthorizationCodeInterface $authorization_code */
$authorization_code = $this
->getStorageAuthorizationCode($code);
if (!$authorization_code) {
/** @var \Drupal\user\UserInterface $user */
$user = $this->entityTypeManager
->getStorage('user')
->load($uid);
if (!$user) {
throw new \InvalidArgumentException("The supplied user couldn't be loaded.");
}
/** @var \Drupal\oauth2_server\AuthorizationCodeInterface $authorization_code */
$authorization_code = $this->entityTypeManager
->getStorage('oauth2_server_authorization_code')
->create([]);
$authorization_code->client_id = $client
->id();
$authorization_code->uid = $user
->id();
$authorization_code->code = $code;
$authorization_code->id_token = $id_token;
}
$authorization_code->redirect_uri = $redirect_uri;
$authorization_code->expires = $expires;
$this
->setScopeData($authorization_code, $client
->getServer(), $scope);
return $authorization_code
->save();
}
/**
* Expire authorization code.
*
* @param string $code
* The authorization code.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function expireAuthorizationCode($code) {
/** @var \Drupal\oauth2_server\AuthorizationCodeInterface $authorization_code */
$authorization_code = $this
->getStorageAuthorizationCode($code);
if ($authorization_code) {
$authorization_code
->delete();
}
}
/* JwtBearerInterface */
/**
* Get client key.
*
* @param string $client_id
* The client id string.
* @param string $subject
* The subject string.
*
* @return string|bool
* The client id public key or false.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function getClientKey($client_id, $subject) {
// While the API supports a key per user (subject), the module only supports
// one key per client, since it's the simpler and more frequent use case.
$client = $this
->getClientDetails($client_id);
return $client ? $client['public_key'] : FALSE;
}
/**
* Get Jti.
*
* @param string $client_id
* The client id string.
* @param string $subject
* The subject string.
* @param string $audience
* The audience string.
* @param int $expires
* The expiration timestamp.
* @param string $jti
* The jti string.
*
* @return array|void
* An Jti array.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function getJti($client_id, $subject, $audience, $expires, $jti) {
$client = $this
->getStorageClient($client_id);
if (!$client) {
// The client_id should be validated prior to this method being called,
// but the library doesn't do that currently.
// phpcs:ignore Drupal.Commenting.FunctionComment.InvalidReturnNotVoid
return;
}
$found = $this->entityTypeManager
->getStorage('oauth2_server_jti')
->loadByProperties([
'client_id' => $client
->id(),
'subject' => $subject,
'jti' => $jti,
'expires' => $expires,
]);
if ($found) {
// JTI found, return the data back in the expected format.
return [
'issuer' => $client_id,
'subject' => $subject,
'jti' => $jti,
'expires' => $expires,
];
}
}
/**
* Set Jti.
*
* @param string $client_id
* The client id string.
* @param string $subject
* The subject string.
* @param string $audience
* The audience string.
* @param int $expires
* The expiration timestamp.
* @param string $jti
* The jti string.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function setJti($client_id, $subject, $audience, $expires, $jti) {
$client = $this
->getStorageClient($client_id);
if (!$client) {
// The client_id should be validated prior to this method being called,
// but the library doesn't do that currently.
return;
}
$entity = $this->entityTypeManager
->getStorage('oauth2_server_jti')
->create([
'client_id' => $client
->id(),
'subject' => $subject,
'jti' => $jti,
'expires' => $expires,
]);
$entity
->save();
}
/* UserCredentialsInterface */
/**
* Check user credentials.
*
* @param string $username
* The username string.
* @param string $password
* The password string.
*
* @return bool
* Whether the credentials are valid or not.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function checkUserCredentials($username, $password) {
$account = $this
->getStorageAccount($username);
if ($account && $account
->isActive()) {
return $this->passwordHasher
->check($password, $account
->getPassword());
}
return FALSE;
}
/**
* Get user details.
*
* @param string $username
* The username string.
*
* @return array|bool
* The user details array or false.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function getUserDetails($username) {
$account = $this
->getStorageAccount($username);
if ($account) {
return [
'user_id' => $account
->id(),
];
}
return FALSE;
}
/* UserClaimsInterface */
/**
* Get user claims.
*
* @param int $uid
* The user id integer.
* @param string $scope
* The scope string.
*
* @return array
* An associative array of claim strings.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityMalformedException
*/
public function getUserClaims($uid, $scope) {
/** @var \Drupal\user\UserInterface $account */
$account = $this->entityTypeManager
->getStorage('user')
->load($uid);
if (!$account) {
throw new \InvalidArgumentException("The supplied user couldn't be loaded.");
}
$requested_scopes = explode(' ', trim($scope));
// The OpenID Connect 'sub' (Subject Identifier) property is usually the
// user's UID, but this is configurable for backwards compatibility reasons.
// See: https://www.drupal.org/node/2274357#comment-9779467
$sub_property = $this->configFactory
->get('oauth2_server.oauth')
->get('user_sub_property');
// Prepare the default claims.
$claims = [
'sub' => $account->{$sub_property}->value,
];
if (in_array('email', $requested_scopes)) {
$claims['email'] = $account
->getEmail();
$claims['email_verified'] = $this->configFactory
->get('user.settings')
->get('verify_mail');
}
if (in_array('profile', $requested_scopes)) {
if (!empty($account
->label())) {
$claims['name'] = $account
->getDisplayName();
$claims['preferred_username'] = $account
->getAccountName();
}
if (!empty($account->timezone)) {
$claims['zoneinfo'] = $account
->getTimeZone();
}
$anonymous_user = new AnonymousUserSession();
if ($anonymous_user
->hasPermission('access user profiles')) {
$claims['profile'] = $account
->toUrl('canonical', [
'absolute' => TRUE,
]);
}
if ($picture = $this
->getUserPicture($account)) {
$claims['picture'] = $picture;
}
}
// Allow modules to supply additional claims.
$claims += $this->moduleHandler
->invokeAll('oauth2_server_user_claims', [
'account' => $account,
'requested_scopes' => $requested_scopes,
]);
// Finally, allow modules to alter claims.
$context = [
'claims' => &$claims,
'account' => $account,
'requested_scopes' => $requested_scopes,
];
$this->moduleHandler
->alter('oauth2_server_user_claims', $context);
return $claims;
}
/* RefreshTokenInterface */
/**
* Get refresh token.
*
* @param string $refresh_token
* The refresh token string.
*
* @return array|bool
* The token array or false.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function getRefreshToken($refresh_token) {
/** @var \Drupal\oauth2_server\TokenInterface $token */
$token = $this
->getStorageToken($refresh_token);
if (!$token) {
return FALSE;
}
$user = $token
->getUser();
if ($user && $user
->isBlocked()) {
// If the user is blocked, deny access.
return FALSE;
}
$scopes = [];
/** @var \Drupal\oauth2_server\ScopeInterface $token */
$scope_entities = $token->scopes
->referencedEntities();
foreach ($scope_entities as $scope) {
$scopes[] = $scope->scope_id;
}
sort($scopes);
return [
'server' => $token
->getClient()
->getServer()
->id(),
'client_id' => $token
->getClient()->client_id,
'user_id' => $token
->getUser()
->id(),
'user_uuid' => $token
->getUser()
->uuid(),
'refresh_token' => $token->token->value,
'expires' => (int) $token->expires->value,
'scope' => implode(' ', $scopes),
];
}
/**
* Set refresh token.
*
* @param string $refresh_token
* The refresh token string.
* @param string $client_id
* The client id string.
* @param int $uid
* The user id integer.
* @param int $expires
* The expiration timestamp.
* @param string|null $scope
* The scope string.
*
* @return int
* Whether the token was saved or not.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function setRefreshToken($refresh_token, $client_id, $uid, $expires, $scope = NULL) {
/** @var \Drupal\oauth2_server\ClientInterface $client */
$client = $this
->getStorageClient($client_id);
if (!$client) {
throw new \InvalidArgumentException("The supplied client couldn't be loaded.");
}
// If no token was found, start with a new entity.
/** @var \Drupal\oauth2_server\TokenInterface $token */
$token = $this
->getStorageToken($refresh_token);
if (!$token) {
$user = $this->entityTypeManager
->getStorage('user')
->load($uid);
if (!$user) {
throw new \InvalidArgumentException("The supplied user couldn't be loaded.");
}
$token = $this->entityTypeManager
->getStorage('oauth2_server_token')
->create([
'type' => 'refresh',
]);
$token->client_id = $client
->id();
$token->uid = $uid;
$token->token = $refresh_token;
}
$token->expires = $expires;
$this
->setScopeData($token, $client
->getServer(), $scope);
return $token
->save();
}
/**
* Unset refresh token.
*
* @param string $refresh_token
* The refresh token string.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function unsetRefreshToken($refresh_token) {
/** @var \Drupal\oauth2_server\TokenInterface $token */
$token = $this
->getStorageToken($refresh_token);
// Check token exists before trying to delete.
if ($token) {
$token
->delete();
}
}
/**
* Sets the "scopes" entityreference field on the passed entity.
*
* @param object $entity
* The entity containing the "scopes" entityreference field.
* @param object $server
* The machine name of the server.
* @param string $scope
* Scopes in a space-separated string.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
private function setScopeData($entity, $server, $scope) {
$entity->scopes = [];
if ($scope) {
$scopes = preg_split('/\\s+/', $scope);
/** @var \Drupal\oauth2_server\ScopeInterface[] $loaded_scopes */
$loaded_scopes = $this->entityTypeManager
->getStorage('oauth2_server_scope')
->loadByProperties([
'server_id' => $server
->id(),
'scope_id' => $scopes,
]);
ksort($loaded_scopes);
foreach ($loaded_scopes as $loaded_scope) {
$entity->scopes[] = $loaded_scope
->id();
}
}
}
/* PublicKeyInterface */
/**
* Get public key.
*
* @param string|null $client_id
* The client id string.
*
* @return string
* The public key string.
*/
public function getPublicKey($client_id = NULL) {
// The library allows for per-client keys. The module uses global keys that
// are regenerated every day, following Google's example.
$keys = Utility::getKeys();
return $keys['public_key'];
}
/**
* Get private key.
*
* @param string|null $client_id
* The client id string.
*
* @return string
* The private key string.
*/
public function getPrivateKey($client_id = NULL) {
// The library allows for per-client keys. The module uses global keys
// that are regenerated every day, following Google's example.
$keys = Utility::getKeys();
return $keys['private_key'];
}
/**
* Get encryption algorithm.
*
* @param string|null $client_id
* The client id string.
*
* @return string
* The encryption algorithm identifier string.
*/
public function getEncryptionAlgorithm($client_id = NULL) {
return 'RS256';
}
/**
* Get the user's picture to return as an OpenID Connect claim.
*
* @param \Drupal\user\UserInterface $account
* The user account object.
*
* @return string|null
* An absolute URL to the user picture, or NULL if none is found.
*
* @throws \Drupal\Core\Entity\EntityMalformedException
*/
protected function getUserPicture(UserInterface $account) {
if (!user_picture_enabled()) {
return NULL;
}
if ($account->user_picture && $account->user_picture->target_id) {
$file = File::load($account->user_picture->target_id);
if ($file) {
return $file
->toUrl('canonical', [
'absolute' => TRUE,
]);
}
}
return NULL;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
OAuth2Storage:: |
protected | property | The config factory. | |
OAuth2Storage:: |
protected | property | The entity manager. | |
OAuth2Storage:: |
protected | property | The module handler. | |
OAuth2Storage:: |
protected | property | The password hasher. | |
OAuth2Storage:: |
protected | property | The time object. | |
OAuth2Storage:: |
public | function | Check client credentials. | |
OAuth2Storage:: |
public | function | Check restricted grant type. | |
OAuth2Storage:: |
public | function | Check user credentials. | |
OAuth2Storage:: |
public | function | Expire authorization code. | |
OAuth2Storage:: |
public | function | Get access token. | |
OAuth2Storage:: |
public | function | Get authorization code. | |
OAuth2Storage:: |
public | function | Get client credentials. | |
OAuth2Storage:: |
public | function | Get client key. | |
OAuth2Storage:: |
public | function | Get client scope. | |
OAuth2Storage:: |
public | function | Get encryption algorithm. | |
OAuth2Storage:: |
public | function | Get Jti. | |
OAuth2Storage:: |
public | function | Get private key. | |
OAuth2Storage:: |
public | function | Get public key. | |
OAuth2Storage:: |
public | function | Get refresh token. | |
OAuth2Storage:: |
public | function | Retrieve the account from the storage. | |
OAuth2Storage:: |
public | function | Get the authorization code from the entity backend. | |
OAuth2Storage:: |
public | function | Get the client from the entity backend. | |
OAuth2Storage:: |
public | function | Get the token from the entity backend. | |
OAuth2Storage:: |
public | function | Get user claims. | |
OAuth2Storage:: |
public | function | Get user details. | |
OAuth2Storage:: |
protected | function | Get the user's picture to return as an OpenID Connect claim. | |
OAuth2Storage:: |
public | function | Is public client. | |
OAuth2Storage:: |
protected | function | Track the time the token was accessed. | |
OAuth2Storage:: |
public | function | Set access token. | |
OAuth2Storage:: |
public | function | Set authorization code. | |
OAuth2Storage:: |
public | function | Set Jti. | |
OAuth2Storage:: |
public | function | Set refresh token. | |
OAuth2Storage:: |
private | function | Sets the "scopes" entityreference field on the passed entity. | |
OAuth2Storage:: |
public | function | Unset refresh token. | |
OAuth2Storage:: |
public | function | Constructs a new OAuth2Storage. |