Files
farmOS-dev/web/modules/simple_oauth/simple_oauth.install
2024-12-10 15:08:16 +01:00

383 lines
14 KiB
PHP

<?php
/**
* @file
* Installation and updating routines.
*/
use Drupal\Core\Config\FileStorage;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\simple_oauth\Entity\Oauth2Scope;
use Drupal\simple_oauth\Entity\Oauth2TokenStorageSchema;
use Drupal\simple_oauth\Oauth2ScopeInterface;
use Drupal\simple_oauth\Plugin\Oauth2GrantManager;
/**
* Define the default batch size.
*/
function simple_oauth_update_8001() {
\Drupal::configFactory()
->getEditable('simple_oauth.settings')
->set('token_cron_batch_size', 0)
->save();
}
/**
* Define the default authorization code expiration value.
*/
function simple_oauth_update_8401() {
\Drupal::configFactory()
->getEditable('simple_oauth.settings')
->set('authorization_code_expiration', 300)
->save();
}
/**
* Install the PKCE basefield for consumer entities.
*/
function simple_oauth_update_8403() {
$field_storage_definition = BaseFieldDefinition::create('boolean')
->setLabel(new TranslatableMarkup('Use PKCE?'))
->setDescription(new TranslatableMarkup('A boolean indicating whether the client uses @pkce (e.g., a native client or SPA)'))
->setRevisionable(TRUE)
->setTranslatable(TRUE)
->setDefaultValue(FALSE);
\Drupal::entityDefinitionUpdateManager()
->installFieldStorageDefinition('pkce', 'consumer', 'simple_oauth', $field_storage_definition);
return t('Field pkce installed for the consumer entity.');
}
/**
* Merge simple_oauth_extras module into simple_oauth.
*/
function simple_oauth_update_8404() {
$use_implicit = \Drupal::config('simple_oauth_extras.settings')->get('use_implicit');
if ($use_implicit === NULL) {
$config_path = \Drupal::service('extension.list.module')->getPath('simple_oauth') . '/config/install';
// Because of custom config_path, we don't call service here.
$source = new FileStorage($config_path);
$config_default = $source->read('simple_oauth.settings');
$use_implicit = $config_default['use_implicit'];
}
else {
\Drupal::configFactory()
->getEditable('simple_oauth_extras.settings')
->delete();
}
\Drupal::configFactory()
->getEditable('simple_oauth.settings')
->set('use_implicit', $use_implicit)
->save();
$deleted = \Drupal::database()->delete('key_value')
->condition('collection', 'system.schema')
->condition('name', 'simple_oauth_extras')
->execute();
$field_names = ['redirect', 'user_id'];
$field_definitions = [
'redirect' => BaseFieldDefinition::create('uri')
->setLabel(new TranslatableMarkup('Redirect URI'))
->setDescription(new TranslatableMarkup('The URI this client will redirect to when needed.'))
->setTranslatable(TRUE)
// URIs are not length limited by RFC 2616, but we can only store 255
// characters in our entity DB schema.
->setSetting('max_length', 255)
->setProvider('simple_oauth'),
'user_id' => BaseFieldDefinition::create('entity_reference')
->setLabel(new TranslatableMarkup('User'))
->setDescription(new TranslatableMarkup('When no specific user is authenticated Drupal will use this user as the author of all the actions made.'))
->setRevisionable(TRUE)
->setTranslatable(FALSE)
->setCardinality(1)
->setProvider('simple_oauth'),
];
$entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();
foreach ($field_names as $field_name) {
$field_definition = $entity_definition_update_manager->getFieldStorageDefinition($field_name, 'consumer');
// If simple_oauth_extras was installed, we need at least to update
// field provider.
if ($field_definition && $deleted) {
$field_definition->setProvider('simple_oauth');
$entity_definition_update_manager->updateFieldStorageDefinition($field_definition);
}
// If the field storage definition is not installed, install it.
elseif (!$field_definition) {
$entity_definition_update_manager->installFieldStorageDefinition($field_name, 'consumer', 'simple_oauth', $field_definitions[$field_name]);
}
// If the field has been installed by a different module, don't interfere.
}
}
/**
* Set default value for the flag to disable OpenID Connect.
*/
function simple_oauth_update_8501() {
$config = \Drupal::configFactory()
->getEditable('simple_oauth.settings');
$config->set('disable_openid_connect', FALSE);
$config->save();
}
/**
* Set default value for the scope provider to dynamic (entity).
*/
function simple_oauth_update_8601() {
$config = \Drupal::configFactory()
->getEditable('simple_oauth.settings');
$config
->set('scope_provider', 'dynamic')
->save();
}
/**
* Install new config entity type "oauth2_scope".
*/
function simple_oauth_update_8602() {
$type_manager = \Drupal::entityTypeManager();
$type_manager->clearCachedDefinitions();
$entity_type = $type_manager->getDefinition('oauth2_scope');
\Drupal::entityDefinitionUpdateManager()->installEntityType($entity_type);
}
/**
* Install/update/delete BaseFields for the consumer entity.
*/
function simple_oauth_update_8603() {
$entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();
$entity_type_id = 'consumer';
$provider = 'simple_oauth';
// Add new fields.
$new_field_definitions['grant_types'] = BaseFieldDefinition::create('list_string')
->setLabel(new TranslatableMarkup('Grant types'))
->setDescription(new TranslatableMarkup('Enabled grant types.'))
->setRevisionable(TRUE)
->setTranslatable(FALSE)
->setRequired(TRUE)
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
$new_field_definitions['scopes'] = BaseFieldDefinition::create('oauth2_scope_reference')
->setLabel(new TranslatableMarkup('Scopes'))
->setDescription(new TranslatableMarkup('Here you can select scopes that would be the default scopes when authorizing.'))
->setRevisionable(TRUE)
->setTranslatable(FALSE)
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
$new_field_definitions['automatic_authorization'] = BaseFieldDefinition::create('boolean')
->setLabel(new TranslatableMarkup('Automatic authorization'))
->setDescription(new TranslatableMarkup('This will cause the authorization form to be skipped.'))
->setRevisionable(TRUE)
->setTranslatable(FALSE)
->setDefaultValue(FALSE);
$new_field_definitions['remember_approval'] = BaseFieldDefinition::create('boolean')
->setLabel(new TranslatableMarkup('Remember previous approval'))
->setDescription(new TranslatableMarkup('When enabled, if previous authorization request with the same scopes got approved, authorization will be automatically accepted.'))
->setRevisionable(TRUE)
->setTranslatable(FALSE)
->setDefaultValue(TRUE);
$new_field_definitions['access_token_expiration'] = BaseFieldDefinition::create('integer')
->setLabel(new TranslatableMarkup('Access token expiration time'))
->setDescription(new TranslatableMarkup('The number of seconds that the access token will be valid.'))
->setRevisionable(TRUE)
->setTranslatable(FALSE)
->setRequired(TRUE)
->setSetting('unsigned', TRUE)
->setDefaultValue(300);
$new_field_definitions['refresh_token_expiration'] = BaseFieldDefinition::create('integer')
->setLabel(new TranslatableMarkup('Refresh token expiration time'))
->setDescription(new TranslatableMarkup('The number of seconds that the refresh token will be valid.'))
->setRevisionable(TRUE)
->setTranslatable(FALSE)
->setSetting('unsigned', TRUE)
->setDefaultValue(1209600);
foreach ($new_field_definitions as $field_name => $field_definition) {
$entity_definition_update_manager->installFieldStorageDefinition($field_name, $entity_type_id, $provider, $field_definition);
}
// Update fields.
$update_field_definitions['confidential'] = $entity_definition_update_manager->getFieldStorageDefinition('confidential', $entity_type_id);
$update_field_definitions['confidential']->setTranslatable(FALSE);
$database = \Drupal::database();
$redirect_values = $database->select('consumer_field_data', 'c')
->fields('c', ['id', 'redirect', 'langcode'])
->isNotNull('c.redirect')
->execute()
->fetchAll();
if (!empty($redirect_values)) {
// Remove data from the storage.
$database->update('consumer_field_data')
->fields(['redirect' => NULL])
->execute();
}
$update_field_definitions['redirect'] = $entity_definition_update_manager->getFieldStorageDefinition('redirect', $entity_type_id);
$update_field_definitions['redirect']
->setLabel(new TranslatableMarkup('Redirect URIs'))
->setDescription(new TranslatableMarkup('The absolute URIs to validate against.'))
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
->setRequired(TRUE)
->addConstraint('Oauth2RedirectUri');
$update_field_definitions['pkce'] = $entity_definition_update_manager->getFieldStorageDefinition('pkce', $entity_type_id);
$update_field_definitions['pkce']->setTranslatable(FALSE);
foreach ($update_field_definitions as $field_definition) {
$entity_definition_update_manager->updateFieldStorageDefinition($field_definition);
}
// Migrate redirect values.
$insert_query = $database->insert('consumer__redirect')
->fields(['bundle', 'deleted', 'entity_id', 'revision_id', 'langcode', 'delta', 'redirect_value']);
foreach ($redirect_values as $redirect_value) {
$insert_query->values([
'consumer',
0,
$redirect_value->id,
$redirect_value->id,
$redirect_value->langcode,
0,
$redirect_value->redirect,
]);
}
$insert_query->execute();
}
/**
* Migrate roles used as scope and migrate settings to the consumer.
*/
function simple_oauth_update_8604() {
$scopes = [];
$consumers = \Drupal::entityTypeManager()->getStorage('consumer')->loadMultiple();
$grant_types = array_keys(Oauth2GrantManager::getAvailablePluginsAsOptions());
$config = \Drupal::configFactory()->get('simple_oauth.settings');
$database = \Drupal::database();
$role_values = $database->select('consumer__roles', 'r')
->fields('r', ['entity_id', 'roles_target_id', 'langcode', 'delta', 'roles_target_id'])
->execute()
->fetchAll();
$scopes = [];
foreach ($role_values as $role_value) {
/** @var \Drupal\user\RoleInterface $role */
$role = \Drupal::entityTypeManager()->getStorage('user_role')->load($role_value->roles_target_id);
// Scope doesn't exist, so we need to create one.
if (!isset($scopes[$role->id()])) {
$scope = Oauth2Scope::create([
'name' => $role->id(),
'description' => $role->label(),
'grant_types' => [
'authorization_code' => ['status' => TRUE],
'client_credentials' => ['status' => TRUE],
'refresh_token' => ['status' => TRUE],
],
'granularity' => Oauth2ScopeInterface::GRANULARITY_ROLE,
'role' => $role->id(),
]);
$scope->save();
$scopes[$role->id()] = $scope;
}
$insert_query = $database->insert('consumer__scopes')
->fields([
'bundle',
'deleted',
'entity_id',
'revision_id',
'langcode',
'delta',
'scopes_scope_id',
]);
$insert_query->values([
'consumer',
0,
$role_value->entity_id,
$role_value->entity_id,
$role_value->langcode,
$role_value->delta,
$role->id(),
]);
$insert_query->execute();
}
foreach ($consumers as $consumer) {
foreach ($grant_types as $delta => $grant_type) {
$insert_query = $database->insert('consumer__grant_types')
->fields([
'bundle',
'deleted',
'entity_id',
'revision_id',
'langcode',
'delta',
'grant_types_value',
]);
$insert_query->values([
'consumer',
0,
$consumer->id(),
$consumer->id(),
$consumer->language()->getId(),
$delta,
$grant_type,
]);
$insert_query->execute();
}
$database->update('consumer_field_data')
->fields([
'remember_approval' => (int) $config->get('remember_clients'),
'access_token_expiration' => (int) $config->get('access_token_expiration'),
'refresh_token_expiration' => (int) $config->get('refresh_token_expiration'),
])
->condition('id', $consumer->id())
->execute();
}
// Remove roles field.
$entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();
$roles_field_definition = $entity_definition_update_manager->getFieldStorageDefinition('roles', 'consumer');
$entity_definition_update_manager->uninstallFieldStorageDefinition($roles_field_definition);
}
/**
* Install/delete scopes BaseField for the oauth2_token entity.
*/
function simple_oauth_update_8605() {
$field_name = 'scopes';
$entity_type_id = 'oauth2_token';
$provider = 'simple_oauth';
$entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();
$field_definition = $entity_definition_update_manager->getFieldStorageDefinition($field_name, $entity_type_id);
// Remove existing scopes field.
$entity_definition_update_manager->uninstallFieldStorageDefinition($field_definition);
// Install new scopes field.
$field_definition = BaseFieldDefinition::create('oauth2_scope_reference')
->setLabel(t('Scopes'))
->setDescription(t('The scopes for this Access Token.'))
->setRevisionable(TRUE)
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
->setTranslatable(FALSE);
$entity_definition_update_manager->installFieldStorageDefinition($field_name, $entity_type_id, $provider, $field_definition);
}
/**
* Add indexes to oauth2_token value field.
*/
function simple_oauth_update_8606() {
$entity_type_manager = \Drupal::entityTypeManager();
$definition_update_manager = \Drupal::entityDefinitionUpdateManager();
$entity_type = $entity_type_manager->getDefinition('oauth2_token')
->setHandlerClass('storage_schema', Oauth2TokenStorageSchema::class);
// Regenerate entity type indexes.
$definition_update_manager->updateEntityType($entity_type);
}