full working version
This commit is contained in:
parent
2178db78f5
commit
308e21941a
22 changed files with 1434 additions and 366 deletions
36
src/Access/AccountRouteAccessCheck.php
Normal file
36
src/Access/AccountRouteAccessCheck.php
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
namespace Drupal\wisski_cloud_account_manager\Access;
|
||||
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Routing\Access\AccessInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Database\Connection;
|
||||
|
||||
class AccountRouteAccessCheck implements AccessInterface {
|
||||
|
||||
protected $currentUser;
|
||||
protected $database;
|
||||
|
||||
public function __construct(AccountInterface $currentUser, Connection $database) {
|
||||
$this->currentUser = $currentUser;
|
||||
$this->database = $database;
|
||||
}
|
||||
|
||||
public function access($aid) {
|
||||
// If the user has the "Administer WissKI Cloud Account Manager" role, allow access.
|
||||
if ($this->currentUser->hasPermission('Administer WissKI Cloud Account Manager')) {
|
||||
return AccessResult::allowed()->cachePerUser();
|
||||
}
|
||||
// Otherwise, check if the aid matches the user's aid in the database.
|
||||
$uid = $this->currentUser->id();
|
||||
$query = $this->database->select('wisski_cloud_account_manager_accounts', 'w')
|
||||
->fields('w', ['aid'])
|
||||
->condition('uid', $uid)
|
||||
->condition('aid', $aid)
|
||||
->execute();
|
||||
|
||||
$result = $query->fetchField();
|
||||
|
||||
return AccessResult::allowedIf($result)->cachePerUser();
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ namespace Drupal\wisski_cloud_account_manager\Controller;
|
|||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\wisski_cloud_account_manager\WisskiCloudAccountManagerDaemonApiActions;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
|
||||
/**
|
||||
* The Wisski Cloud account manager info controller.
|
||||
|
|
@ -39,6 +40,63 @@ class WisskiCloudAccountManagerController extends ControllerBase {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Page list the account statuses.
|
||||
*
|
||||
* @return array
|
||||
* The page build array.
|
||||
*/
|
||||
public function accountManagingPage(): array {
|
||||
$currentUser = \Drupal::currentUser();
|
||||
$healthCheck = $this->wisskiCloudAccountManagerDaemonApiActions->healthCheck();
|
||||
$accounts = $this->wisskiCloudAccountManagerDaemonApiActions->getAccounts();
|
||||
// If the user is not an admin, filter the accounts to only include their own.
|
||||
if (!$currentUser->hasPermission('admister wisski cloud account manager')) {
|
||||
$accounts = array_filter($accounts, function($account) use ($currentUser) {
|
||||
return $account['uid'] === $currentUser->id();
|
||||
});
|
||||
}
|
||||
return [
|
||||
'#theme' => 'wisski_cloud_account_manager_account_managing_page',
|
||||
'#accounts' => $accounts,
|
||||
'#healthCheck' => $healthCheck,
|
||||
'#attached' => [
|
||||
'library' => [
|
||||
'wisski_cloud_account_manager/accountOptions',
|
||||
'wisski_cloud_account_manager/globalStyling',
|
||||
'wisski_cloud_account_manager/provisionStatus'
|
||||
],
|
||||
],
|
||||
'#cache' => [
|
||||
'max-age' => 0,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
// @todo Implement healthcheckPage().
|
||||
public function healthcheckPage(): array {
|
||||
return [
|
||||
'#theme' => 'wisski_cloud_account_manager_healthcheck_page',
|
||||
'#healthCheck' => $this->wisskiCloudAccountManagerDaemonApiActions->healthCheck(),
|
||||
];
|
||||
}
|
||||
|
||||
public function provisionStatusPage($aid) {
|
||||
$accounts = $this->wisskiCloudAccountManagerDaemonApiActions->getAccounts($aid);
|
||||
// Return the status as a JSON response.
|
||||
switch ($accounts[0]['provisioned']) {
|
||||
case '0':
|
||||
return new JsonResponse(['status' => 'no']);
|
||||
case '1':
|
||||
return new JsonResponse(['status' => 'ongoing']);
|
||||
case '2':
|
||||
return new JsonResponse(['status' => 'yes']);
|
||||
case '3':
|
||||
return new JsonResponse(['status' => 'unknown']);
|
||||
}
|
||||
return new JsonResponse(['status' => $accounts[0]['provisioned']]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Info page for terms and conditions.
|
||||
*
|
||||
|
|
@ -63,41 +121,13 @@ class WisskiCloudAccountManagerController extends ControllerBase {
|
|||
* The page build array.
|
||||
*/
|
||||
public function validationPage(string $validationCode): array {
|
||||
$account = $this->wisskiCloudAccountManagerDaemonApiActions->validateAccount($validationCode);
|
||||
$user = $this->wisskiCloudAccountManagerDaemonApiActions->validateAccount($validationCode);
|
||||
|
||||
return [
|
||||
'#theme' => 'wisski_cloud_account_manager_validation_page',
|
||||
'#account' => $account,
|
||||
'#attached' => [
|
||||
'library' => [
|
||||
'wisski_cloud_account_manager/wisski_cloud_account_manager',
|
||||
],
|
||||
],
|
||||
'#cache' => [
|
||||
'max-age' => 0,
|
||||
],
|
||||
'#markup' => $this->t('Your WissKI Cloud account for user :name is now validated. You can now <a href="/user">login</a> and start a provision!.', [
|
||||
':name' => $user['name'],
|
||||
]),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Page list the account statuses.
|
||||
*
|
||||
* @return array
|
||||
* The page build array.
|
||||
*/
|
||||
public function accountManagingPage(): array {
|
||||
$accounts = $this->wisskiCloudAccountManagerDaemonApiActions->getAccounts();
|
||||
return [
|
||||
'#theme' => 'wisski_cloud_account_manager_account_managing_page',
|
||||
'#accounts' => $accounts,
|
||||
'#attached' => [
|
||||
'library' => [
|
||||
'wisski_cloud_account_manager/wisski_cloud_account_manager',
|
||||
],
|
||||
],
|
||||
'#cache' => [
|
||||
'max-age' => 0,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,9 +16,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||
*/
|
||||
class WisskiCloudAccountManagerCreateForm extends FormBase {
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The config factory service.
|
||||
*
|
||||
|
|
@ -126,7 +123,7 @@ class WisskiCloudAccountManagerCreateForm extends FormBase {
|
|||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Username'),
|
||||
'#maxlength' => 20,
|
||||
'#description' => $this->t('WissKI cloud login user. Only small caps (a-z), underscore (_), minus (-) and 20 letter maximum allowed, i.e. "wisski_user".'),
|
||||
'#description' => $this->t('WissKI cloud login - NOT your password for your instance - this will be send separately. Only small caps (a-z), underscore (_), minus (-) and 20 letter maximum allowed, i.e. "wisski_user".'),
|
||||
'#pattern' => '[a-z]+([_-]{1}[a-z]+)*',
|
||||
'#required' => TRUE,
|
||||
];
|
||||
|
|
@ -175,38 +172,54 @@ class WisskiCloudAccountManagerCreateForm extends FormBase {
|
|||
$dataToCheck['email'] = $form_state->getValue('email');
|
||||
$dataToCheck['emailProvider'] = explode('@', $dataToCheck['email'])[1];
|
||||
$dataToCheck['subdomain'] = $form_state->getValue('subdomain');
|
||||
$dataToCheck['usernameBlacklist'] = $this->settings->get('usernameBlacklist') ?? '';
|
||||
$dataToCheck['emailProviderBlacklist'] = $this->settings->get('emailProviderBlacklist') ?? '';
|
||||
$dataToCheck['subdomainBlacklist'] = $this->settings->get('subdomainBlacklist') ?? '';
|
||||
|
||||
$response = $this->wisskiCloudAccountManagerDaemonApiActions->checkAccountData($dataToCheck);
|
||||
// Check if username is too short.
|
||||
if (strlen($dataToCheck['username']) < 2) {
|
||||
$form_state->setErrorByName('username', $this->t('The username "@username" is too short, please use at least 2 characters.', ['@username' => $dataToCheck['username']]));
|
||||
}
|
||||
|
||||
if (!$response['success']) {
|
||||
$this->messenger->addError('Can not communicate with the provision daemon, please try again later or write an email to cloud@wiss-ki.eu.');
|
||||
}
|
||||
if (strlen($dataToCheck['username']) < 3) {
|
||||
$form_state->setErrorByName('username', $this->t('The username "@username" is too short, please use at least 3 characters.', ['@username' => $dataToCheck['username']]));
|
||||
}
|
||||
if (in_array($dataToCheck['username'], preg_split('/\r\n|\r|\n/', $this->settings->get('usernameBlacklist')))) {
|
||||
// Check if username is in blacklist.
|
||||
if (in_array($dataToCheck['username'], preg_split('/\r\n|\r|\n/', $dataToCheck['usernameBlacklist']))) {
|
||||
$form_state->setErrorByName('username', $this->t('The username "@username" is not allowed.', ['@username' => $dataToCheck['username']]));
|
||||
}
|
||||
if ($response['accountData']['accountWithUsername']) {
|
||||
$form_state->setErrorByName('username', $this->t('The username "@username" is already in use.', ['@username' => $dataToCheck['username']]));
|
||||
|
||||
// Check if username only contains lowercase letters, numbers, and underscores
|
||||
if (!preg_match('/^[a-z0-9_]+$/', $dataToCheck['username'])) {
|
||||
$form_state->setErrorByName('username', t('Username can only contain lowercase letters, numbers, and underscores.'));
|
||||
}
|
||||
|
||||
if (in_array($dataToCheck['emailProvider'], preg_split('/\r\n|\r|\n/', $this->settings->get('emailProviderBlacklist')))) {
|
||||
// Check if username is unique
|
||||
$userFromUsername = \Drupal::entityTypeManager()->getStorage('user')->loadByProperties(['name' =>$dataToCheck['username']]);
|
||||
if (!empty($userFromUsername)) {
|
||||
$form_state->setErrorByName('username', $this->t('The username is already taken.'));
|
||||
}
|
||||
|
||||
// Check if email provider is in blacklist.
|
||||
if (in_array($dataToCheck['emailProvider'], preg_split('/\r\n|\r|\n/', $dataToCheck['emailProviderBlacklist']))) {
|
||||
$form_state->setErrorByName('email', $this->t('The email provider "@provider"is not allowed.', ['@provider' => $dataToCheck['emailProvider']]));
|
||||
}
|
||||
|
||||
if ($response['accountData']['accountWithEmail']) {
|
||||
// Check if email is already in use.
|
||||
$userFromEmail = \Drupal::entityTypeManager()->getStorage('user')->loadByProperties(['name' => $dataToCheck['email']]);
|
||||
if (!empty($userFromEmail)) {
|
||||
$form_state->setErrorByName('email', $this->t('The email "@email" is already in use.', ['@email' => $dataToCheck['email']]));
|
||||
}
|
||||
|
||||
// Check if subdomain is too short.
|
||||
if (strlen($dataToCheck['subdomain']) < 3) {
|
||||
$form_state->setErrorByName('subdomain', $this->t('The subdomain "@subdomain" is too short, please use at least 3 characters.', ['@subdomain' => $dataToCheck['subdomain']]));
|
||||
}
|
||||
|
||||
if (in_array($dataToCheck['subdomain'], preg_split('/\r\n|\r|\n/', $this->settings->get('subdomainBlacklist')))) {
|
||||
// Check if subdomain is in blacklist.
|
||||
if (in_array($dataToCheck['subdomain'], preg_split('/\r\n|\r|\n/', $dataToCheck['emailProviderBlacklist']))) {
|
||||
$form_state->setErrorByName('subdomain', $this->t('The subdomain "@subdomain" is not allowed.', ['@subdomain' => $dataToCheck['subdomain']]));
|
||||
}
|
||||
if ($response['accountData']['accountWithSubdomain']) {
|
||||
|
||||
// Check if subdomain is already in use.
|
||||
if ($this->wisskiCloudAccountManagerDaemonApiActions->checkForRedundantAccountData('subdomain', $dataToCheck['subdomain'])) {
|
||||
$form_state->setErrorByName('subdomain', $this->t('The subdomain "@subdomain" is already in use.', ['@subdomain' => $dataToCheck['subdomain']]));
|
||||
}
|
||||
|
||||
|
|
@ -230,11 +243,8 @@ class WisskiCloudAccountManagerCreateForm extends FormBase {
|
|||
$account["password"] = $field['password'];
|
||||
$account["subdomain"] = $field['subdomain'];
|
||||
|
||||
$accountResponse = $this->wisskiCloudAccountManagerDaemonApiActions->addAccount($account);
|
||||
if (!$accountResponse['success']) {
|
||||
throw new Exception('Get no valid response from api daemon. Can not send validiation email.');
|
||||
};
|
||||
$this->wisskiCloudAccountManagerDaemonApiActions->sendValidationEmail($accountResponse['data']['email'], $accountResponse['data']['validationCode']);
|
||||
$user = $this->wisskiCloudAccountManagerDaemonApiActions->addAccount($account);
|
||||
$this->wisskiCloudAccountManagerDaemonApiActions->sendValidationEmail($user['email'], $user['personName'], $user['validationCode']);
|
||||
|
||||
$this->messenger()
|
||||
->addMessage($this->t('The account data has been successfully saved, please check your email for validation!'));
|
||||
|
|
|
|||
111
src/Form/WisskiCloudAccountManagerDeleteForm.php
Executable file
111
src/Form/WisskiCloudAccountManagerDeleteForm.php
Executable file
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\wisski_cloud_account_manager\Form;
|
||||
|
||||
use Drupal\Core\Form\ConfirmFormBase;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\wisski_cloud_account_manager\WisskiCloudAccountManagerDaemonApiActions;
|
||||
use Drupal\Core\Url;
|
||||
|
||||
class WisskiCloudAccountManagerDeleteForm extends ConfirmFormBase {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* The account.
|
||||
*/
|
||||
protected array $account;
|
||||
|
||||
/**
|
||||
* @var \Drupal\wisski_cloud_account_manager\WisskiCloudAccountManagerDaemonApiActions
|
||||
* The WissKi Cloud account manager daemon API actions service.
|
||||
*/
|
||||
protected WisskiCloudAccountManagerDaemonApiActions $wisskiCloudAccountManagerDaemonApiActions;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'wisski_cloud_account_manager_delete_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param \Drupal\wisski_cloud_account_manager\WisskiCloudAccountManagerDaemonApiActions $wisskiCloudAccountManagerDaemonApiActions
|
||||
* The WissKi Cloud account manager daemon API actions service.
|
||||
*/
|
||||
public function __construct(WisskiCloudAccountManagerDaemonApiActions $wisskiCloudAccountManagerDaemonApiActions) {
|
||||
$this->wisskiCloudAccountManagerDaemonApiActions = $wisskiCloudAccountManagerDaemonApiActions;
|
||||
$aid = \Drupal::routeMatch()->getParameter('aid');
|
||||
$this->account = $this->wisskiCloudAccountManagerDaemonApiActions->getAccounts($aid)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the reachable variables from services.
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
|
||||
* The class container.
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('wisski_cloud_account_manager.daemon_api.actions'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getQuestion() {
|
||||
return $this->t('Do you really want to delete your WissKI Cloud Instance?');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCancelUrl() {
|
||||
return Url::fromRoute('wisski_cloud_account_manager.validate')
|
||||
->setRouteParameter('validationCode', $this->account['validation_code']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription() {
|
||||
return $this->t('This will delete your WissKI Cloud instance. This action cannot be undone. Your Drupal user and WissKI Cloud account will remain.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfirmText() {
|
||||
return $this->t('Delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
$form = parent::buildForm($form, $form_state);
|
||||
|
||||
$form['account_table'] = [
|
||||
'#type' => 'table',
|
||||
'#rows' => [
|
||||
[$this->t('Subdomain'), $this->account['subdomain']],
|
||||
],
|
||||
];
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
|
||||
$aid = \Drupal::routeMatch()->getParameter('aid');
|
||||
$this->wisskiCloudAccountManagerDaemonApiActions->crudInstance('delete', $aid);
|
||||
$form_state->setRedirect('wisski_cloud_account_manager.manage');
|
||||
}
|
||||
|
||||
}
|
||||
115
src/Form/WisskiCloudAccountManagerProvisionForm.php
Executable file
115
src/Form/WisskiCloudAccountManagerProvisionForm.php
Executable file
|
|
@ -0,0 +1,115 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\wisski_cloud_account_manager\Form;
|
||||
|
||||
use Drupal\Core\Form\ConfirmFormBase;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\wisski_cloud_account_manager\WisskiCloudAccountManagerDaemonApiActions;
|
||||
use Drupal\Core\Url;
|
||||
|
||||
class WisskiCloudAccountManagerProvisionForm extends ConfirmFormBase {
|
||||
|
||||
/**
|
||||
* @var \Drupal\wisski_cloud_account_manager\WisskiCloudAccountManagerDaemonApiActions
|
||||
* The WissKi Cloud account manager daemon API actions service.
|
||||
*/
|
||||
protected WisskiCloudAccountManagerDaemonApiActions $wisskiCloudAccountManagerDaemonApiActions;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'wisski_cloud_account_manager_provision_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param \Drupal\wisski_cloud_account_manager\WisskiCloudAccountManagerDaemonApiActions $wisskiCloudAccountManagerDaemonApiActions
|
||||
* The WissKi Cloud account manager daemon API actions service.
|
||||
*/
|
||||
public function __construct(WisskiCloudAccountManagerDaemonApiActions $wisskiCloudAccountManagerDaemonApiActions) {
|
||||
$this->wisskiCloudAccountManagerDaemonApiActions = $wisskiCloudAccountManagerDaemonApiActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the reachable variables from services.
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
|
||||
* The class container.
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('wisski_cloud_account_manager.daemon_api.actions'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getQuestion() {
|
||||
return $this->t('Do you really want to start WissKI Cloud provision?');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCancelUrl() {
|
||||
return Url::fromRoute('wisski_cloud_account_manager.settings');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription() {
|
||||
return $this->t('This will start a WissKI Cloud account provision.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfirmText() {
|
||||
return $this->t('Provise a WissKI Cloud account');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
$form = parent::buildForm($form, $form_state);
|
||||
$aid = \Drupal::routeMatch()->getParameter('aid');
|
||||
$account = $this->wisskiCloudAccountManagerDaemonApiActions->getAccounts($aid)[0];
|
||||
$form['info'] = [
|
||||
'#type' => 'table',
|
||||
'#header' => [
|
||||
$this->t('Account id'),
|
||||
$this->t('Account name'),
|
||||
$this->t('Account email'),
|
||||
$this->t('Domain'),
|
||||
|
||||
],
|
||||
'#rows' => [
|
||||
[
|
||||
$account['aid'],
|
||||
$account['name'],
|
||||
$account['mail'],
|
||||
$account['subdomain'] . '.wisski.cloud',
|
||||
],
|
||||
],
|
||||
];
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
|
||||
$aid = \Drupal::routeMatch()->getParameter('aid');
|
||||
|
||||
$result = $this->wisskiCloudAccountManagerDaemonApiActions->crudInstance('create', $aid);
|
||||
$form_state->setRedirect('wisski_cloud_account_manager.manage');
|
||||
}
|
||||
|
||||
}
|
||||
105
src/Form/WisskiCloudAccountManagerPurgeForm.php
Executable file
105
src/Form/WisskiCloudAccountManagerPurgeForm.php
Executable file
|
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\wisski_cloud_account_manager\Form;
|
||||
|
||||
use Drupal\Core\Form\ConfirmFormBase;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\wisski_cloud_account_manager\WisskiCloudAccountManagerDaemonApiActions;
|
||||
use Drupal\Core\Url;
|
||||
|
||||
class WisskiCloudAccountManagerPurgeForm extends ConfirmFormBase {
|
||||
|
||||
/**
|
||||
* @var \Drupal\wisski_cloud_account_manager\WisskiCloudAccountManagerDaemonApiActions
|
||||
* The WissKi Cloud account manager daemon API actions service.
|
||||
*/
|
||||
protected WisskiCloudAccountManagerDaemonApiActions $wisskiCloudAccountManagerDaemonApiActions;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'wisski_cloud_account_manager_purge_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param \Drupal\wisski_cloud_account_manager\WisskiCloudAccountManagerDaemonApiActions $wisskiCloudAccountManagerDaemonApiActions
|
||||
* The WissKi Cloud account manager daemon API actions service.
|
||||
*/
|
||||
public function __construct(WisskiCloudAccountManagerDaemonApiActions $wisskiCloudAccountManagerDaemonApiActions) {
|
||||
$this->wisskiCloudAccountManagerDaemonApiActions = $wisskiCloudAccountManagerDaemonApiActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the reachable variables from services.
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
|
||||
* The class container.
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('wisski_cloud_account_manager.daemon_api.actions'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getQuestion() {
|
||||
return $this->t('Do you really want to purge your WissKI Cloud account?');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCancelUrl() {
|
||||
return Url::fromRoute('wisski_cloud_account_manager.settings');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription() {
|
||||
return $this->t('This will delete your WissKI Cloud account, your Drupal user, your WissKI Cloud instance and all data associated with it. This action cannot be undone.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfirmText() {
|
||||
return $this->t('Purge');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
$form = parent::buildForm($form, $form_state);
|
||||
$aid = \Drupal::routeMatch()->getParameter('aid');
|
||||
$account = $this->wisskiCloudAccountManagerDaemonApiActions->getAccounts($aid)[0];
|
||||
$form['account_table'] = [
|
||||
'#type' => 'table',
|
||||
'#rows' => [
|
||||
[$this->t('Subdomain'), $account['subdomain']],
|
||||
[$this->t('Account name'), $account['name'] ?: $this->t('Seems that Drupal user has already been deleted, delete the remaining account data and instance.')],
|
||||
],
|
||||
];
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
|
||||
$aid = \Drupal::routeMatch()->getParameter('aid');
|
||||
$this->wisskiCloudAccountManagerDaemonApiActions->purgeAccount($aid);
|
||||
|
||||
$form_state->setRedirect('wisski_cloud_account_manager.manage');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -42,32 +42,39 @@ class WisskiCloudAccountManagerSettingsForm extends ConfigFormBase {
|
|||
'#default_value' => $config->get('daemonUrl'),
|
||||
];
|
||||
|
||||
$form['allAccounts'] = [
|
||||
$form['wsUrl'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('All accounts URL path'),
|
||||
'#description' => $this->t('Provide the endpoint to the GET endpoint for all accounts, i. e. "/account/all"'),
|
||||
'#default_value' => $config->get('allAccounts'),
|
||||
'#title' => $this->t('The websocket URL of the WissKI Cloud'),
|
||||
'#description' => $this->t('Provide the complete base URL with protocol, domain (resp. service name in docker), ports and API path, i. e. "wss://panel.wisski.cloud/api/v1/ws"'),
|
||||
'#default_value' => $config->get('wsUrl'),
|
||||
];
|
||||
|
||||
$form['accountPostUrlPath'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('POST URL path'),
|
||||
'#description' => $this->t('Provide the path to the POST endpoint, i. e. "/account"'),
|
||||
'#default_value' => $config->get('accountPostUrlPath'),
|
||||
$form['wsToken'] = [
|
||||
'#type' => 'password',
|
||||
'#title' => $this->t('The websocket access token of the WissKI Cloud provisioning account.'),
|
||||
'#description' => $this->t('Provide the access token for the websocket, i. e. "1234567890"'),
|
||||
'#default_value' => $config->get('wsToken'),
|
||||
];
|
||||
|
||||
$form['accountFilterByData'] = [
|
||||
$form['provisionRoute'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Filter by Data URL path'),
|
||||
'#description' => $this->t('Provide the path to the Get account by data endpoint, i. e. "/account/by_data"'),
|
||||
'#default_value' => $config->get('accountFilterByData'),
|
||||
'#title' => $this->t('Instance provision URL path'),
|
||||
'#description' => $this->t('Provide the path to the account validation PUT endpoint, i. e. "/provision"'),
|
||||
'#default_value' => $config->get('provisionRoute'),
|
||||
];
|
||||
|
||||
$form['accountValidation'] = [
|
||||
$form['deleteRoute'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('User Validation URL path'),
|
||||
'#description' => $this->t('Provide the path to the account validation PUT endpoint, i. e. "/account/validation"'),
|
||||
'#default_value' => $config->get('accountValidation'),
|
||||
'#title' => $this->t('Instance delete URL path'),
|
||||
'#description' => $this->t('Provide the path to the account validation DELETE endpoint, i. e. "/delete"'),
|
||||
'#default_value' => $config->get('deleteRoute'),
|
||||
];
|
||||
|
||||
$form['healthCheckRoute'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Deamon health check URL path'),
|
||||
'#description' => $this->t('Provide the path to the health check GET endpoint, i. e. "/health-check"'),
|
||||
'#default_value' => $config->get('healthCheckRoute'),
|
||||
];
|
||||
|
||||
$form['usernameBlacklist'] = [
|
||||
|
|
@ -121,15 +128,16 @@ class WisskiCloudAccountManagerSettingsForm extends ConfigFormBase {
|
|||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
$config = $this->config('wisski_cloud_account_manager.settings');
|
||||
|
||||
$config->set('daemonUrl', $form_state->getValue('daemonUrl'))
|
||||
->set('accountPostUrlPath', $form_state->getValue('accountPostUrlPath'))
|
||||
->set('allAccounts', $form_state->getValue('allAccounts'))
|
||||
->set('accountFilterByData', $form_state->getValue('accountFilterByData'))
|
||||
->set('accountProvisionAndValidationCheck', $form_state->getValue('accountProvisionAndValidationCheck'))
|
||||
->set('accountValidation', $form_state->getValue('accountValidation'))
|
||||
->set('usernameBlacklist', $form_state->getValue('usernameBlacklist'))
|
||||
$config
|
||||
->set('daemonUrl', $form_state->getValue('daemonUrl'))
|
||||
->set('deleteRoute', $form_state->getValue('deleteRoute'))
|
||||
->set('emailProviderBlacklist', $form_state->getValue('emailProviderBlacklist'))
|
||||
->set('healthCheckRoute', $form_state->getValue('healthCheckRoute'))
|
||||
->set('provisionRoute', $form_state->getValue('provisionRoute'))
|
||||
->set('usernameBlacklist', $form_state->getValue('usernameBlacklist'))
|
||||
->set('subdomainBlacklist', $form_state->getValue('subdomainBlacklist'))
|
||||
->set('wsUrl', $form_state->getValue('wsUrl'))
|
||||
->set('wsToken', $form_state->getValue('wsToken'))
|
||||
->save();
|
||||
|
||||
parent::submitForm($form, $form_state);
|
||||
|
|
|
|||
113
src/Form/WisskiCloudAccountManagerValidationForm.php
Executable file
113
src/Form/WisskiCloudAccountManagerValidationForm.php
Executable file
|
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\wisski_cloud_account_manager\Form;
|
||||
|
||||
use Drupal\Core\Form\ConfirmFormBase;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\wisski_cloud_account_manager\WisskiCloudAccountManagerDaemonApiActions;
|
||||
use Drupal\Core\Url;
|
||||
|
||||
class WisskiCloudAccountManagerValidationForm extends ConfirmFormBase {
|
||||
|
||||
/**
|
||||
* @var \Drupal\wisski_cloud_account_manager\WisskiCloudAccountManagerDaemonApiActions
|
||||
* The WissKi Cloud account manager daemon API actions service.
|
||||
*/
|
||||
protected WisskiCloudAccountManagerDaemonApiActions $wisskiCloudAccountManagerDaemonApiActions;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'wisski_cloud_account_manager_validation_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param \Drupal\wisski_cloud_account_manager\WisskiCloudAccountManagerDaemonApiActions $wisskiCloudAccountManagerDaemonApiActions
|
||||
* The WissKi Cloud account manager daemon API actions service.
|
||||
*/
|
||||
public function __construct(WisskiCloudAccountManagerDaemonApiActions $wisskiCloudAccountManagerDaemonApiActions) {
|
||||
$this->wisskiCloudAccountManagerDaemonApiActions = $wisskiCloudAccountManagerDaemonApiActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the reachable variables from services.
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
|
||||
* The class container.
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('wisski_cloud_account_manager.daemon_api.actions'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getQuestion() {
|
||||
return $this->t('Do you really want to start WissKI Cloud validation?');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCancelUrl() {
|
||||
return Url::fromRoute('wisski_cloud_account_manager.settings');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription() {
|
||||
return $this->t('This will start a WissKI Cloud account validation.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfirmText() {
|
||||
return $this->t('Validate a WissKI Cloud account');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
$form = parent::buildForm($form, $form_state);
|
||||
$aid = \Drupal::routeMatch()->getParameter('aid');
|
||||
$account = $this->wisskiCloudAccountManagerDaemonApiActions->getAccounts($aid)[0];
|
||||
$form['info'] = [
|
||||
'#type' => 'table',
|
||||
'#header' => [
|
||||
$this->t('Account id'),
|
||||
$this->t('Account name'),
|
||||
$this->t('Account email'),
|
||||
$this->t('Domain'),
|
||||
|
||||
],
|
||||
'#rows' => [
|
||||
[
|
||||
$account['aid'],
|
||||
$account['name'],
|
||||
$account['mail'],
|
||||
$account['subdomain'] . '.wisski.cloud',
|
||||
],
|
||||
],
|
||||
];
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
$aid = \Drupal::routeMatch()->getParameter('aid');
|
||||
$this->wisskiCloudAccountManagerDaemonApiActions->validateAccount($aid);
|
||||
$form_state->setRedirect('wisski_cloud_account_manager.manage');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5,13 +5,17 @@ namespace Drupal\wisski_cloud_account_manager;
|
|||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Drupal\Core\Config\Config;
|
||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||
use Drupal\Core\Config\Schema\Undefined;
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
|
||||
use Drupal\Core\Language\LanguageManagerInterface;
|
||||
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
|
||||
use Drupal\Core\Mail\MailManagerInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Render\Markup;
|
||||
use Drupal\Core\Template\TwigEnvironment;
|
||||
use Drupal\Core\StringTranslation\TranslationInterface;
|
||||
use Drupal\user\Entity\User;
|
||||
use GuzzleHttp\ClientInterface;
|
||||
|
||||
/**
|
||||
|
|
@ -22,32 +26,19 @@ class WisskiCloudAccountManagerDaemonApiActions {
|
|||
use DependencySerializationTrait;
|
||||
|
||||
/**
|
||||
* The URL path to all account data GET endpoint.
|
||||
* The admin email address.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private string $ALL_ACCOUNTS = '/account/all';
|
||||
private string $ADMIN_EMAIL;
|
||||
|
||||
/**
|
||||
* The URL path to the POST endpoint.
|
||||
* The URL path to provision PUT endpoint.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private string $ACCOUNT_POST_URL_PART = '/account';
|
||||
private string $PROVISION_ROUTE;
|
||||
|
||||
/**
|
||||
* The URL path to provision and validation GET endpoint.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private string $ACCOUNT_PROVISION_AND_VALIDATION_URL_PART;
|
||||
|
||||
/**
|
||||
* The URL path to provision and validation GET endpoint.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private string $ACCOUNT_VALIDATION_URL_PART = '/account/validation';
|
||||
|
||||
/**
|
||||
* The base URL of the WissKI Cloud account manager daemon.
|
||||
|
|
@ -57,18 +48,34 @@ class WisskiCloudAccountManagerDaemonApiActions {
|
|||
private string $DAEMON_URL;
|
||||
|
||||
/**
|
||||
* The URL path to the filter by account data GET endpoint.
|
||||
* The URL path to delete DELETE endpoint.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private string $FILTER_BY_DATA_URL_PART = '/account/by_data';
|
||||
private string $DELETE_ROUTE;
|
||||
|
||||
|
||||
/**
|
||||
* The settings config.
|
||||
* The database.
|
||||
*
|
||||
* @var \Drupal\Core\Config\Config
|
||||
* @var \Drupal\Core\Database\Connection
|
||||
*/
|
||||
protected Config $settings;
|
||||
protected Connection $database;
|
||||
|
||||
/**
|
||||
* The Route to the health check GET endpoint.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private string $HEALTH_CHECK_ROUTE;
|
||||
|
||||
/**
|
||||
* The Route to the info GET endpoint.
|
||||
*
|
||||
* @var string
|
||||
* @todo not yet implemented
|
||||
*/
|
||||
private string $INFO_ROUTE = '/info';
|
||||
|
||||
/**
|
||||
* The HTTP client.
|
||||
|
|
@ -77,6 +84,13 @@ class WisskiCloudAccountManagerDaemonApiActions {
|
|||
*/
|
||||
protected ClientInterface $httpClient;
|
||||
|
||||
/**
|
||||
* The language manager.
|
||||
*
|
||||
* @var \Drupal\Core\Language\LanguageManagerInterface
|
||||
*/
|
||||
protected LanguageManagerInterface $languageManager;
|
||||
|
||||
/**
|
||||
* The logger factory.
|
||||
*
|
||||
|
|
@ -84,6 +98,13 @@ class WisskiCloudAccountManagerDaemonApiActions {
|
|||
*/
|
||||
protected LoggerChannelFactoryInterface $loggerFactory;
|
||||
|
||||
/**
|
||||
* The mail manager.
|
||||
*
|
||||
* @var \Drupal\Core\Mail\MailManagerInterface
|
||||
*/
|
||||
protected MailManagerInterface $mailManager;
|
||||
|
||||
/**
|
||||
* The messenger service.
|
||||
*
|
||||
|
|
@ -91,20 +112,6 @@ class WisskiCloudAccountManagerDaemonApiActions {
|
|||
*/
|
||||
protected MessengerInterface $messenger;
|
||||
|
||||
/**
|
||||
* The language manager.
|
||||
*
|
||||
* @var \Drupal\Core\Language\LanguageManagerInterface
|
||||
*/
|
||||
protected LanguageManagerInterface $languageManager;
|
||||
|
||||
/**
|
||||
* The mail manager.
|
||||
*
|
||||
* @var \Drupal\Core\Mail\MailManagerInterface
|
||||
*/
|
||||
protected MailManagerInterface $mailManager;
|
||||
|
||||
/**
|
||||
* The request stack.
|
||||
*
|
||||
|
|
@ -112,6 +119,15 @@ class WisskiCloudAccountManagerDaemonApiActions {
|
|||
*/
|
||||
protected RequestStack $requestStack;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The settings config.
|
||||
*
|
||||
* @var \Drupal\Core\Config\Config
|
||||
*/
|
||||
protected Config $settings;
|
||||
|
||||
/**
|
||||
* The string translation service.
|
||||
*
|
||||
|
|
@ -119,61 +135,212 @@ class WisskiCloudAccountManagerDaemonApiActions {
|
|||
*/
|
||||
protected TranslationInterface $stringTranslation;
|
||||
|
||||
/**
|
||||
* The Twig renderer.
|
||||
*
|
||||
* @var \Drupal\Core\Template\TwigEnvironment
|
||||
*/
|
||||
protected TwigEnvironment $twig;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
ConfigFactoryInterface $configFactory,
|
||||
Connection $database,
|
||||
ClientInterface $httpClient,
|
||||
LanguageManagerInterface $languageManager,
|
||||
LoggerChannelFactoryInterface $loggerFactory,
|
||||
MessengerInterface $messenger,
|
||||
MailManagerInterface $mailManager,
|
||||
MessengerInterface $messenger,
|
||||
RequestStack $requestStack,
|
||||
TranslationInterface $stringTranslation,
|
||||
TwigEnvironment $twig
|
||||
) {
|
||||
// Services from container.
|
||||
$settings = $configFactory
|
||||
->getEditable('wisski_cloud_account_manager.settings');
|
||||
->getEditable('wisski_cloud_account_manager.settings');
|
||||
$this->httpClient = $httpClient;
|
||||
$this->database = $database;
|
||||
$this->languageManager = $languageManager;
|
||||
$this->loggerFactory = $loggerFactory;
|
||||
$this->mailManager = $mailManager;
|
||||
$this->messenger = $messenger;
|
||||
$this->requestStack = $requestStack;
|
||||
$this->settings = $settings;
|
||||
$this->stringTranslation = $stringTranslation;
|
||||
$this->loggerFactory = $loggerFactory;
|
||||
$this->messenger = $messenger;
|
||||
$this->httpClient = $httpClient;
|
||||
$this->mailManager = $mailManager;
|
||||
$this->requestStack = $requestStack;
|
||||
$this->languageManager = $languageManager;
|
||||
$this->twig = $twig;
|
||||
|
||||
// Set the daemon URL and the URL parts class variables.
|
||||
$this->DAEMON_URL = $settings->get('daemonUrl') ?: 'http://wisski_cloud_api_daemon:3000/wisski-cloud-daemon/api/v1';
|
||||
$this->ALL_ACCOUNTS = $settings->get('allAccounts') ?: '/account/all';
|
||||
$this->ACCOUNT_POST_URL_PART = $settings->get('accountPostUrlPath') ?: '/account';
|
||||
$this->FILTER_BY_DATA_URL_PART = $settings->get('accountFilterByData') ?: '/account/by_data';
|
||||
$this->ACCOUNT_PROVISION_AND_VALIDATION_URL_PART = $settings->get('accountProvisionAndValidationUrlPart') ?: '/account/provision_and_validation';
|
||||
$this->ACCOUNT_VALIDATION_URL_PART = $settings->get('accountValidationUrlPart') ?: '/account/validation';
|
||||
$this->DAEMON_URL = $settings->get('daemonUrl') ?: 'http://wisski_cloud_api_daemon_app:2912/wisski-cloud-daemon/api/v1';
|
||||
$this->DELETE_ROUTE = $settings->get('deleteRoute') ?: '/delete';
|
||||
$this->PROVISION_ROUTE = $settings->get('provisionRoute') ?: '/provision';
|
||||
$this->ADMIN_EMAIL = \Drupal::config('system.site')->get('mail');
|
||||
$this->HEALTH_CHECK_ROUTE= $settings->get('healthCheckRoute') ?: '/health-check';
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new account to the WissKI Cloud account manager daemon.
|
||||
* Adds a new account to the instance.
|
||||
*
|
||||
* First a new Drupal user is created. Additional data is
|
||||
* stored in the wisski_cloud_account_manager_accounts table.
|
||||
*
|
||||
* @param array $account
|
||||
* The account to add.
|
||||
*
|
||||
* @return array
|
||||
* The response from the daemon (account id with validation code).
|
||||
* The account id with validation code.
|
||||
*/
|
||||
public function addAccount(array $account): array {
|
||||
try {
|
||||
$request = [
|
||||
'headers' => [
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
'body' => json_encode($account),
|
||||
|
||||
// Get current language.
|
||||
$language = $this->languageManager->getCurrentLanguage()->getId();
|
||||
// Create Drupal user object.
|
||||
$user = User::create();
|
||||
|
||||
// Mandatory.
|
||||
$user->setPassword($account['password']);
|
||||
$user->enforceIsNew();
|
||||
$user->setEmail($account['email']);
|
||||
$user->setUsername($account['username']); // This username must be unique and accepts only string. It must be a minimum of two characters and can contain only lowercase letters, numbers, and underscores.
|
||||
|
||||
// Optional.
|
||||
$user->set('init', $account['email']);
|
||||
$user->set('langcode', $language);
|
||||
$user->set('preferred_langcode', $language);
|
||||
$user->set('preferred_admin_langcode', $language);
|
||||
|
||||
// Save user.
|
||||
$result = $user->save();
|
||||
$validationCode = $this->generateValidationCode();
|
||||
|
||||
$database = $this->database;
|
||||
|
||||
// Check if a record with this user ID already exists.
|
||||
$query = $database->select('wisski_cloud_account_manager_accounts', 'w')
|
||||
->fields('w', ['uid'])
|
||||
->condition('w.uid', $user->id(), '=');
|
||||
$result = $query->execute()->fetchField();
|
||||
|
||||
if ($result) {
|
||||
throw new \Exception('A record with this user ID already exists.');
|
||||
}
|
||||
$query = $database->insert('wisski_cloud_account_manager_accounts')
|
||||
->fields([
|
||||
'uid' => $user->id(),
|
||||
'person_name' => $account['personName'],
|
||||
'organisation' => $account['organisation'],
|
||||
'subdomain' => $account['subdomain'],
|
||||
'validation_code' => $validationCode,
|
||||
]);
|
||||
$query->execute();
|
||||
return [
|
||||
'userId' => $user->id(),
|
||||
'username' => $account['username'],
|
||||
'personName' => $account['personName'],
|
||||
'email' => $account['email'],
|
||||
'subdomain' => $account['subdomain'],
|
||||
'validationCode' => $validationCode ,
|
||||
];
|
||||
$accountPostUrl = $this->DAEMON_URL . $this->ACCOUNT_POST_URL_PART;
|
||||
$response = $this->httpClient->post($accountPostUrl, $request);
|
||||
return json_decode($response->getBody()
|
||||
->getContents(), TRUE);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
// Request failed, handle the error.
|
||||
$this->loggerFactory
|
||||
->get('wisski_cloud_account_manager')
|
||||
->error('Can not create account: ' . $e->getMessage());
|
||||
$this->messenger
|
||||
->addError($this->stringTranslation->translate('Error creating account. See logs for details.'));
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for redundant account data.
|
||||
*
|
||||
* @param string $column
|
||||
* The column to check.
|
||||
* @param string $value
|
||||
* The value to check.
|
||||
*/
|
||||
public function checkForRedundantAccountData(string $column, string $value) {
|
||||
$database = \Drupal::database();
|
||||
$query = $database->select('wisski_cloud_account_manager_accounts', 'w');
|
||||
$query->fields('w', [$column]);
|
||||
$query->condition('w.' . $column, $value, '=');
|
||||
if ($query->execute()->fetchField()) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provisions an account in the WissKI Cloud account manager daemon.
|
||||
*
|
||||
* @param string $action
|
||||
* The action to perform: create, delete, get.
|
||||
* @param int $aid
|
||||
* The account ID to provision.
|
||||
*
|
||||
* @return array
|
||||
* The response from the daemon.
|
||||
*/
|
||||
public function crudInstance($action, $aid) {
|
||||
try {
|
||||
|
||||
$aid = trim($aid);
|
||||
// Build the query string from the parameters.
|
||||
$query_string = http_build_query([
|
||||
'aid' => $aid,
|
||||
]);
|
||||
|
||||
// Determine the route part depending on the action.
|
||||
switch ($action) {
|
||||
case 'create':
|
||||
$restMethod = 'put';
|
||||
$routePart = $this->PROVISION_ROUTE;
|
||||
break;
|
||||
case 'delete':
|
||||
$restMethod = 'delete';
|
||||
$routePart = $this->DELETE_ROUTE;
|
||||
break;
|
||||
default:
|
||||
$restMethod = 'get';
|
||||
$routePart = $this->INFO_ROUTE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Combine the base URL and the query string.
|
||||
$request_url = $this->DAEMON_URL . $routePart . '?' . $query_string;
|
||||
// Send the GET request using the `drupal_http_request()` function.
|
||||
$response = $this->httpClient->request($restMethod, $request_url);
|
||||
// Check the response and handle the data accordingly.
|
||||
if ($response->getStatusCode() == 200 || $response->getStatusCode() == 201) {
|
||||
// Request successful, handle the data in $response->data.
|
||||
$resultArray = json_decode($response->getBody()->getContents(), TRUE);
|
||||
$this->messenger
|
||||
->addMessage($this->stringTranslation->translate('@message', ['@message' => $resultArray['message']]));
|
||||
return $resultArray;
|
||||
|
||||
}
|
||||
if ($response->getStatusCode() == 404) {
|
||||
// Request successful, handle the data in $response->data.
|
||||
$resultArray = json_decode($response->getBody()->getContents(), TRUE);
|
||||
$this->messenger
|
||||
->addError($this->stringTranslation->translate('@message', ['@message' => $resultArray['message']]));
|
||||
return $resultArray;
|
||||
}
|
||||
else {
|
||||
// Request failed, handle the error.
|
||||
return [
|
||||
"message" => 'Request failed with code: ' . $response->getStatusCode(),
|
||||
"data" => [],
|
||||
'success' => FALSE,
|
||||
'error' => $response->getBody()->getContents(),
|
||||
];
|
||||
}
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
// Request failed, handle the error.
|
||||
|
|
@ -181,60 +348,130 @@ class WisskiCloudAccountManagerDaemonApiActions {
|
|||
->get('wisski_cloud_account_manager')
|
||||
->error('Request failed with exception: ' . $e->getMessage());
|
||||
$this->messenger
|
||||
->addError($this->stringTranslation->translate('Can not communicate with the WissKI Cloud account manager daemon. Try again later or contact cloud@wiss-ki.eu.'));
|
||||
->addError($this->stringTranslation->translate('Can not communicate with the WissKI Cloud account manager daemon. Try again later or contact @email.',
|
||||
['@email'
|
||||
=> $this->ADMIN_EMAIL]));
|
||||
return [
|
||||
"message" => 'Request failed with exception: ' . $e->getMessage(),
|
||||
"data" => [
|
||||
'email' => NULL,
|
||||
'validationCode' => NULL,
|
||||
],
|
||||
"message" => 'Request failed with exception.',
|
||||
"data" => [],
|
||||
'success' => FALSE,
|
||||
'error' => $e->getMessage(),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an account with the given data already exists.
|
||||
* Deletes an account from the WissKI Cloud account manager daemon.
|
||||
*
|
||||
* @param array $dataToCheck
|
||||
* The data to check. Possible keys are:
|
||||
* - email
|
||||
* - subdomain
|
||||
* - username.
|
||||
* @param int $uid
|
||||
* The user ID of the account to delete.
|
||||
*
|
||||
* @return array
|
||||
* The response from the daemon.
|
||||
*/
|
||||
public function checkAccountData(array $dataToCheck): array {
|
||||
public function deleteAccount(int $aid): array {
|
||||
try {
|
||||
// Build the query string from the parameters.
|
||||
$query_string = http_build_query($dataToCheck);
|
||||
$database = $this->database;
|
||||
|
||||
// Select the user ID from the accounts table.
|
||||
$selectQuery = $database->select('wisski_cloud_account_manager_accounts', 'w')
|
||||
->fields('w', ['uid'])
|
||||
->condition('w.aid', $aid, '=');
|
||||
$uid = $selectQuery->execute()->fetchField();
|
||||
|
||||
// Delete the account from the accounts table.
|
||||
$deleteQuery = $database->delete('wisski_cloud_account_manager_accounts')
|
||||
->condition('aid', $aid, '=');
|
||||
$deleteQuery->execute();
|
||||
|
||||
// Delete the user if exists.
|
||||
$user = User::load($uid);
|
||||
$user ? $user->delete() : NULL;
|
||||
$this->messenger
|
||||
->addMessage($this->stringTranslation->translate('Account deleted successfully.'));
|
||||
return [
|
||||
'message' => 'Account deleted successfully.',
|
||||
'success' => TRUE,
|
||||
];
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
// Request failed, handle the error.
|
||||
$this->loggerFactory
|
||||
->get('wisski_cloud_account_manager')
|
||||
->error('Request failed with exception: ' . $e->getMessage());
|
||||
$this->messenger
|
||||
->addError($this->stringTranslation->translate('Something went wrong!' . $e->getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random validation code with 32 characters.
|
||||
*
|
||||
* @return string
|
||||
* The generated validation code.
|
||||
*/
|
||||
function generateValidationCode() {
|
||||
// Generate 16 random bytes and convert them to a 32 characters hexadecimal string
|
||||
$code = bin2hex(random_bytes(16));
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query accounts from the WissKI Cloud account manager daemon.
|
||||
*
|
||||
* @param int $aid
|
||||
* The account ID to query.
|
||||
*
|
||||
* @return array[aid, name, mail, organisation, person_name, provisioned, status, subdomain, uid, validation_code]
|
||||
* The accounts response from the daemon.
|
||||
*/
|
||||
public function getAccounts($aid = null): array {
|
||||
try {
|
||||
$query = $this->database->select('wisski_cloud_account_manager_accounts', 'w');
|
||||
$query->fields('w', ['aid', 'organisation', 'person_name', 'provisioned', 'subdomain', 'uid', 'validation_code']);
|
||||
$query->leftjoin('users_field_data', 'u', 'w.uid = u.uid');
|
||||
$query->fields('u', ['name', 'mail', 'status']);
|
||||
if ($aid) {
|
||||
$query->condition('w.aid', $aid, '=');
|
||||
}
|
||||
$accounts = $query->execute()->fetchAll(\PDO::FETCH_ASSOC);
|
||||
return $accounts;
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
// Request failed, handle the error.
|
||||
$this->loggerFactory
|
||||
->get('wisski_cloud_account_manager')
|
||||
->error('Request failed with exception: ' . $e->getMessage());
|
||||
$this->messenger
|
||||
->addError($this->stringTranslation->translate('Can not communicate with the WissKI Cloud account manager daemon. Try again later or contact cloud@wiss-ki.eu.'));
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the WissKI Cloud account manager daemon is available.
|
||||
*
|
||||
* @return array[message:string, success:boolean]
|
||||
*
|
||||
*/
|
||||
public function healthCheck() {
|
||||
try {
|
||||
// Combine the base URL and the query string.
|
||||
$request_url = $this->DAEMON_URL . $this->FILTER_BY_DATA_URL_PART . '?' . $query_string;
|
||||
|
||||
$request_url = $this->DAEMON_URL . $this->HEALTH_CHECK_ROUTE;
|
||||
// Send the GET request using the `drupal_http_request()` function.
|
||||
$response = $this->httpClient->get($request_url);
|
||||
|
||||
$response = $this->httpClient->request('get', $request_url);
|
||||
// Check the response and handle the data accordingly.
|
||||
if ($response->getStatusCode() == 200) {
|
||||
// Request successful, handle the data in $response->data.
|
||||
return [
|
||||
"message" => "Get account data",
|
||||
"accountData" => json_decode($response->getBody()->getContents(),
|
||||
TRUE)['data'],
|
||||
"message" => "WissKI Cloud account manager daemon is available.",
|
||||
'success' => TRUE,
|
||||
];
|
||||
}
|
||||
else {
|
||||
// Request failed, handle the error.
|
||||
return [
|
||||
"message" => 'Request failed with code: ' . $response->getStatusCode(),
|
||||
"accountData" => [
|
||||
'accountWithUsername' => NULL,
|
||||
'accountWithEmail' => NULL,
|
||||
'accountWithSubdomain' => NULL,
|
||||
],
|
||||
"message" => 'WissKI Cloud account manager daemon is not available: ' . $response->getStatusCode(),
|
||||
'success' => FALSE,
|
||||
];
|
||||
}
|
||||
|
|
@ -243,90 +480,93 @@ class WisskiCloudAccountManagerDaemonApiActions {
|
|||
// Request failed, handle the error.
|
||||
$this->loggerFactory
|
||||
->get('wisski_cloud_account_manager')
|
||||
->error('Request failed with exception: ' . $e->getMessage());
|
||||
->error('Something went wrong: ' . $e->getMessage());
|
||||
$this->messenger
|
||||
->addError($this->stringTranslation->translate('Can not communicate with the WissKI Cloud account manager daemon. Try again later or contact cloud@wiss-ki.eu.'));
|
||||
return [
|
||||
"message" => 'Request failed with exception: ' . $e->getMessage(),
|
||||
"accountData" => [
|
||||
'accountWithUsername' => NULL,
|
||||
'accountWithEmail' => NULL,
|
||||
'accountWithSubdomain' => NULL,
|
||||
],
|
||||
'success' => FALSE,
|
||||
];
|
||||
->addError($this->stringTranslation->translate('Can not communicate with the WissKI Cloud account manager daemon. Try again later or contact @adminMail.',
|
||||
['@adminMail'
|
||||
=> $this->ADMIN_EMAIL]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all accounts from the WissKI Cloud account manager daemon.
|
||||
*
|
||||
* Purges an account via the WissKI Cloud account manager daemon.
|
||||
* Deletes the account from the accounts table and the Drupal user.
|
||||
* Deletes the instance via the daemon from the WissKI Cloud.
|
||||
* @param int $aid
|
||||
* The account ID to purge.
|
||||
* @return array
|
||||
* The accounts response from the daemon.
|
||||
* The response from the daemon.
|
||||
*/
|
||||
public function getAccounts(): array {
|
||||
public function purgeAccount(int $aid) {
|
||||
try {
|
||||
// Combine the base URL and the query string.
|
||||
$request_url = $this->DAEMON_URL . $this->ALL_ACCOUNTS;
|
||||
// Send the GET request using the `drupal_http_request()` function.
|
||||
$response = $this->httpClient->get($request_url);
|
||||
return json_decode($response->getBody()->getContents(), TRUE);
|
||||
// Get the account ID from the route.
|
||||
|
||||
// @todo Why is there a space in the account ID?
|
||||
$aid = trim($aid);
|
||||
|
||||
|
||||
// Delete the instance via the daemon from the WissKI Cloud.
|
||||
$response = $this->crudInstance('delete', $aid);
|
||||
if ($response['success']) {
|
||||
// Delete the account and Drupal user.
|
||||
$this->deleteAccount($aid);
|
||||
$this->messenger
|
||||
->addMessage($this->stringTranslation->translate('Account purged successfully.'));
|
||||
return [
|
||||
'data' => NULL,
|
||||
'error' => NULL,
|
||||
'message' => 'Account purged successfully.',
|
||||
'success' => TRUE,
|
||||
];
|
||||
|
||||
}
|
||||
else {
|
||||
if (!$response['error']) {
|
||||
// No success and no error.
|
||||
$this->messenger
|
||||
->addMessage($this->stringTranslation->translate('Account not found or already purged.'));
|
||||
return [
|
||||
'data' => NULL,
|
||||
'error' => NULL,
|
||||
'message' => $response['message'],
|
||||
'success' => FALSE,
|
||||
];
|
||||
}
|
||||
else {
|
||||
// No success and error.
|
||||
$this->messenger
|
||||
->addError($this->stringTranslation->translate('Something went wrong: ' . $response['message']));
|
||||
$this->loggerFactory->get('wisski_cloud_account_manager')->error($response['error']);
|
||||
return [
|
||||
'data' => NULL,
|
||||
'error' => $response['error'],
|
||||
'message' => 'Something went wrong: ' . $response['message'],
|
||||
'success' => FALSE,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catch (\Exception $e) {
|
||||
// Request failed, handle the error.
|
||||
$this->loggerFactory
|
||||
->get('wisski_cloud_account_manager')
|
||||
->error('Request failed with exception: ' . $e->getMessage());
|
||||
$this->messenger
|
||||
->addError($this->stringTranslation->translate('Can not communicate with the WissKI Cloud account manager daemon. Try again later or contact cloud@wiss-ki.eu.'));
|
||||
return [
|
||||
"message" => 'Request failed with exception: ' . $e->getMessage(),
|
||||
"accounts" => [],
|
||||
'success' => FALSE,
|
||||
];
|
||||
->addError($this->stringTranslation->translate('Something went wrong!' . $e->getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the validation status of the given validation code.
|
||||
*
|
||||
* @param string $validationCode
|
||||
* The validation code to check.
|
||||
*
|
||||
* @return array
|
||||
* The account data from the daemon.
|
||||
*/
|
||||
public function validateAccount(string $validationCode): array {
|
||||
try {
|
||||
$url = $this->DAEMON_URL . $this->ACCOUNT_VALIDATION_URL_PART . '/' . $validationCode;
|
||||
$validationResponse = $this->httpClient->put($url);
|
||||
return json_decode($validationResponse->getBody()
|
||||
->getContents(), TRUE);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
// Request failed, handle the error.
|
||||
$this->loggerFactory
|
||||
->get('wisski_cloud_account_manager')
|
||||
->error('Request failed with exception: ' . $e->getMessage());
|
||||
$this->messenger
|
||||
->addError($this->stringTranslation->translate('Can not communicate with the WissKI Cloud account manager daemon. Try again later or contact cloud@wiss-ki.eu.'));
|
||||
return [
|
||||
"message" => 'Request failed with exception: ' . $e->getMessage(),
|
||||
"accounts" => [],
|
||||
'success' => FALSE,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Sends a validation email to the given email address.
|
||||
*
|
||||
* @param string $email
|
||||
* The email address to send the validation email to.
|
||||
* @param string $personName
|
||||
* The person name to be used in the validation email.
|
||||
* @param string $validationCode
|
||||
* The validation code to be used in the validation link.
|
||||
*/
|
||||
public function sendValidationEmail(string $email, string $validationCode): void {
|
||||
public function sendValidationEmail(string $email, string $personName, string $validationCode): void {
|
||||
try {
|
||||
$module = 'wisski_cloud_account_manager';
|
||||
$key = 'wisski_cloud_account_validation';
|
||||
|
|
@ -336,17 +576,19 @@ class WisskiCloudAccountManagerDaemonApiActions {
|
|||
$validationLink = $this->requestStack->getCurrentRequest()
|
||||
->getSchemeAndHttpHost() . '/wisski-cloud-account-manager/validate/' . $validationCode;
|
||||
|
||||
$params['message'] = Markup::create($this->stringTranslation->translate('<p>Please validate your account by clicking on this <a href="@validationLink" target="_blank">link</a> or copy this to the address bar of your browser: <p>@validationLink</p>.</p>', ['@validationLink' => $validationLink]));
|
||||
$params['subject'] = $this->stringTranslation->translate('WissKI Cloud account validation');
|
||||
$result = $this->mailManager->mail($module, $key, $to, $langcode, $params, NULL, TRUE);
|
||||
if ($result['result'] === TRUE) {
|
||||
$this->messenger
|
||||
->addMessage($this->stringTranslation->translate('Email send successfully.'));
|
||||
}
|
||||
else {
|
||||
$this->messenger
|
||||
->addMessage($this->stringTranslation->translate('There was an error sending the email.'), 'error');
|
||||
$message = $this->twig->render('@wisski_cloud_account_manager/wisski-cloud-account-manager-validation-email.html.twig', [
|
||||
'personName' => $personName,
|
||||
'validationLink' => $validationLink,
|
||||
]);
|
||||
|
||||
|
||||
$params['subject'] = $this->stringTranslation->translate('WissKI Cloud account validation');
|
||||
$params['message'] = Markup::create($message);
|
||||
$result = $this->mailManager->mail($module, $key, $to, $langcode, $params, NULL, TRUE);
|
||||
if ($result['result'] != TRUE) {
|
||||
$this->loggerFactory
|
||||
->get('wisski_cloud_account_manager')
|
||||
->error('Email sending operation ended with error: ' . $result['message']);
|
||||
}
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
|
|
@ -360,4 +602,58 @@ class WisskiCloudAccountManagerDaemonApiActions {
|
|||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates the account.
|
||||
*
|
||||
* @param string $validationCode
|
||||
* The validation code to check.
|
||||
*
|
||||
* @return array [uid, name]
|
||||
*/
|
||||
public function validateAccount(string $validationCode): array {
|
||||
try {
|
||||
$selectQuery = $this->database->select('wisski_cloud_account_manager_accounts', 'w')
|
||||
->fields('w', ['aid', 'organisation', 'person_name', 'provisioned','subdomain', 'validation_code'])
|
||||
->condition('w.validation_code', $validationCode, '=');
|
||||
$selectQuery->join('users_field_data', 'u', 'w.uid = u.uid');
|
||||
$selectQuery->fields('u', ['uid', 'name', 'mail', 'status']);
|
||||
$account = $selectQuery->execute()->fetchAll(\PDO::FETCH_ASSOC);
|
||||
if (isset($account[0]['status'])) {
|
||||
if ($account[0]['status'] == 0) {
|
||||
$updateQuery = $this->database->update('users_field_data')
|
||||
->fields(['status' => 1])
|
||||
->condition('uid', $account['0']['uid'], '=');
|
||||
$updateQuery->execute();
|
||||
$account = $selectQuery->execute()->fetchAll(\PDO::FETCH_ASSOC);
|
||||
$this->messenger
|
||||
->addMessage($this->stringTranslation->translate('Account validated successfully.'));
|
||||
|
||||
} else {
|
||||
$this->messenger
|
||||
->addMessage($this->stringTranslation->translate('Account already validated.'));
|
||||
}
|
||||
return [
|
||||
'uid' => $account[0]['uid'],
|
||||
'name' => $account[0]['name']];
|
||||
}
|
||||
else {
|
||||
$this->messenger
|
||||
->addError($this->stringTranslation->translate('Account validation failed. Please contact @adminEmail.',
|
||||
['@adminEmail'
|
||||
=> $this->ADMIN_EMAIL]));
|
||||
return [];
|
||||
}
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
// Request failed, handle the error.
|
||||
$this->loggerFactory
|
||||
->get('wisski_cloud_account_manager')
|
||||
->error('Request failed with exception: ' . $e->getMessage());
|
||||
$this->messenger
|
||||
->addError($this->stringTranslation->translate('Can not communicate with the WissKI Cloud account manager daemon. Try again later or contact cloud@wiss-ki.eu.'));
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue