<?php

/**
 * @file
 * Install, update and uninstall functions for the OpenID Connect module.
 */

use \Drupal\Core\Url;

/**
 * Implements hook_schema().
 */
function openid_connect_schema() {
  $schema['openid_connect_authmap'] = [
    'description' => 'Stores OpenID Connect authentication mapping.',
    'fields' => [
      'aid' => [
        'description' => 'Primary Key: Unique authmap ID.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ],
      'uid' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => "User's {users}.uid.",
      ],
      'client_name' => [
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
        'description' => 'The client name.',
      ],
      'sub' => [
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
        'description' => 'Unique subject identifier.',
      ],
    ],
    'primary key' => ['aid'],
    'indexes' => [
      'uid' => ['uid'],
      'identifier' => ['client_name', 'sub'],
    ],
    'foreign keys' => [
      'user' => [
        'table' => 'users',
        'columns' => ['uid' => 'uid'],
      ],
    ],
  ];

  return $schema;
}

/**
 * Implements hook_requirements().
 */
function openid_connect_requirements($phase) {
  $requirements = [];
  if ($phase == 'runtime') {
    if (\Drupal::config('openid_connect.settings')->get('connect_existing_users')) {
      $requirements['openid_connect_connect_existing_users'] = [
        'title' => t('OpenID Connect'),
        'value' => t('Automatically connect existing users enabled'),
        'description' => t('The "Automatically connect existing users" option is enabled. This can lead to security vulnerabilities. It is <strong>highly recommended</strong> to <a href=":url">disable this option</a>.',
          [':url' => Url::fromRoute('openid_connect.admin_settings', [], ['fragment' => 'edit-connect-existing-users'])->toString()]
        ),
        'severity' => REQUIREMENT_WARNING,
      ];
    }
  }
  return $requirements;
}

/**
 * Add default config for Facebook and LinkedIn provider.
 */
function openid_connect_update_8101() {
  $config_factory = \Drupal::configFactory();

  $config = $config_factory->getEditable('openid_connect.settings.facebook');
  $config->set('enabled', FALSE);
  $config->set('settings', [
    'client_id' => '',
    'client_secret' => '',
    'api_version' => '',
  ]);
  $config->save(TRUE);

  $config = $config_factory->getEditable('openid_connect.settings.linkedin');
  $config->set('enabled', FALSE);
  $config->set('settings', [
    'client_id' => '',
    'client_secret' => '',
  ]);
  $config->save(TRUE);
}

/**
 * Add default config for GitHub provider.
 */
function openid_connect_update_8102() {
  $config_factory = \Drupal::configFactory();

  $config = $config_factory->getEditable('openid_connect.settings.github');
  $config->set('enabled', FALSE);
  $config->set('settings', [
    'client_id' => '',
    'client_secret' => '',
  ]);
  $config->save(TRUE);
}

/**
 * Update the active config with the registration override value.
 */
function openid_connect_update_8103() {
  $config_factory = \Drupal::configFactory();
  $config = $config_factory->getEditable('openid_connect.settings');
  $config->set('override_registration_settings', FALSE);
  $config->save(TRUE);
}

/**
 * Update the active config with the connect existing users value.
 */
function openid_connect_update_8104() {
  $config_factory = \Drupal::configFactory();
  $config = $config_factory->getEditable('openid_connect.settings');
  $config->set('connect_existing_users', FALSE);
  $config->save(TRUE);
}

/**
 * Delete duplicate entries in the openid_connect_authmap table.
 */
function openid_connect_update_8105() {
  $database = \Drupal::database();
  // Get the IDs for the duplicate entries.
  $query = $database->select('openid_connect_authmap', 'a1')->fields('a1', ['aid']);
  $query->innerJoin('openid_connect_authmap', 'a2', 'a1.uid = a2.uid AND a1.client_name = a2.client_name AND a1.sub = a2.sub');
  $query->where('a1.aid > a2.aid');
  $aids = $query->distinct()->execute()->fetchAllAssoc('aid');

  if (!empty($aids)) {
    // If duplicates exist, delete them.
    $database->delete('openid_connect_authmap')->condition('aid', array_keys($aids), 'IN')->execute();
  }
}

/**
 * Add default config for Okta provider.
 */
function openid_connect_update_8106() {
  $config_factory = \Drupal::configFactory();

  $config = $config_factory->getEditable('openid_connect.settings.okta');
  $config->set('enabled', FALSE);
  $config->set('settings', [
    'client_id' => '',
    'client_secret' => '',
    'okta_domain' => '',
  ]);
  $config->save(TRUE);
}
