first commit

This commit is contained in:
Robert Nasarek 2023-08-03 16:39:36 +02:00
commit d7ae7d3338
9 changed files with 470 additions and 0 deletions

1
README.md Normal file
View file

@ -0,0 +1 @@
# WissKI Cloud Account Manager

View file

@ -0,0 +1,25 @@
<?php
namespace Drupal\wisski_cloud_account_manager\Controller;
use Drupal\Core\Controller\ControllerBase;
/**
* The Wisski Cloud account manager info controller.
*/
class WisskiCloudAccountManagerController extends ControllerBase {
/**
* Info page for terms and conditions.
*
* @return array
* The page build array.
*/
public function termsAndConditions(): array {
$build = [
'#markup' => $this->t('Hello World!'),
];
return $build;
}
}

View file

@ -0,0 +1,201 @@
<?php
namespace Drupal\wisski_cloud_account_manager\Form;
use Drupal\Core\Database\Database;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\wisski_cloud_account_manager\WisskiCloudAccountManagerDaemonApiActions;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* WissKI cloud create account form.
*/
class WisskiCloudAccountManagerCreateForm extends FormBase {
/**
* @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_create';
}
/**
* 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 buildForm(array $form, FormStateInterface $form_state) {
$form['personname'] = [
'#type' => 'textfield',
'#title' => $this->t('Person name'),
'#description' => $this->t('Your first and last name.'),
'#required' => TRUE,
];
$form['organisation'] = [
'#type' => 'textfield',
'#title' => $this->t('Organisation'),
'#description' => $this->t('Your organisation, employer, affiliation - if any.'),
];
$form['email'] = [
'#type' => 'email',
'#title' => $this->t('Email'),
'#description' => $this->t('For communication and opt in.'),
'#required' => TRUE,
];
$form['username'] = [
'#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".'),
'#pattern' => '[a-z]+([_-]{1}[a-z]+)*',
'#required' => TRUE,
];
$form['password'] = [
'#type' => 'password_confirm',
'#size' => 32,
'#description' => $this->t('Your Password'),
'#required' => TRUE,
];
// @todo Add '.wisski.cloud' text as prefix.
$form['subdomain'] = [
'#type' => 'textfield',
'#title' => $this->t('Subdomain'),
'#maxlength' => 12,
'#description' => $this->t('WissKI cloud subdomain. Only small caps (a-z), underscore (_), minus (-) and 12 letter maximum allowed, i.e. "my_wisski" will end in "my_wisski.wisski.cloud".'),
'#pattern' => '[a-z]+([_-]{1}[a-z]+)*',
'#required' => TRUE,
];
$form['termsConditions'] = [
'#type' => 'checkbox',
'#title' => $this->t('Terms & Conditions'),
'#description' => $this->t('You have to agree to our <a href="@termsConditions" target="_blank">terms and conditions</a> to use the WissKI Cloud.', ['@termsConditions' => '/wisski-cloud-account-manager/terms-and-conditions']),
'#required' => TRUE,
];
$form['actions']['#type'] = 'actions';
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Save'),
'#button_type' => 'primary',
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
// Check if username is in database.
// @todo Check if username is WissKI Cloud accounts, i.e add direct by admin?.
$username = $form_state->getValue('username');
$conn = Database::getConnection();
$accountWithUsername = $conn
->select('wisski_cloud_accounts', 'wca')
->fields('wca', ['username'])
->condition('username', $username)
->execute()
->fetchCol();
if (!empty($accountWithUsername)) {
$form_state->setErrorByName('username', $this->t('The username @username is already in use.', ['@username' => $username]));
}
// Check if email is in valid form.
$email = $form_state->getValue('email');
if (!\Drupal::service('email.validator')->isValid($email)) {
$form_state->setErrorByName('email', $this->t('Email not in valid form, i.e. "name@example.com".'));
}
// Check if email is in database.
$accountWithEmail = $conn
->select('wisski_cloud_accounts', 'wca')
->fields('wca', ['email'])
->condition('email', $email)
->execute()
->fetchCol();
if (!empty($accountWithEmail)) {
$form_state->setErrorByName('email', $this->t('The email @email is already in use.', ['@email' => $email]));
}
// Check if subdomain is in database.
$subdomain = $form_state->getValue('subdomain');
$accountWithSubdomain = $conn
->select('wisski_cloud_accounts', 'wca')
->fields('wca', ['subdomain'])
->condition('subdomain', $subdomain)
->execute()
->fetchCol();
if (!empty($accountWithSubdomain)) {
$form_state->setErrorByName('subdomain', $this->t('The subdomain @subdomain is already in use.', ['@subdomain' => $subdomain]));
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
try {
$conn = Database::getConnection();
$field = $form_state->getValues();
$account["personname"] = $field['personname'];
$account["organisation"] = $field['organisation'];
$account["email"] = $field['email'];
$account["username"] = $field['username'];
$account["password"] = $field['password'];
$account["subdomain"] = $field['subdomain'];
$daemonResponse = $this->wisskiCloudAccountManagerDaemonApiActions->addAccount($account);
dpm($daemonResponse, 'Daemon response');
unset($account["password"]);
dpm($account);
/*
$conn->insert('wisski_cloud_accounts')
->fields($account)->execute();
\Drupal::messenger()
->addMessage($this->t('The account data has been succesfully saved'));
*/
}
catch (\Exception $ex) {
\Drupal::logger('wisski_cloud_account_manager')->error($ex->getMessage());
}
}
}

View file

@ -0,0 +1,69 @@
<?php
namespace Drupal\wisski_cloud_account_manager\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* WissKI cloud opt in settings form.
*/
class WisskiCloudAccountManagerSettingsForm extends ConfigFormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'wisski_cloud_account_manager_settings';
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return [
'wisski_cloud_account_manager.settings',
];
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form = parent::buildForm($form, $form_state);
/** @var \Drupal\Core\Config\ImmutableConfig $config */
$config = $this->config('wisski_cloud_account_manager.settings');
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$config = $this->config('wisski_cloud_account_manager.settings');
/*
$config->set('', $form_state->getValue(''))
->save();
*/
parent::submitForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
/*
// Hash expiration validation.
$hash_expiration = intval($form_state->getValue('hash_expiration'));
if ($hash_expiration < 1) {
$form_state->setErrorByName('hash_expiration', $this->t('The miminum hash expiration time is @min_value.', ['@min_value' => $this->t('one hour')]));
}
elseif ($hash_expiration > 48) {
$form_state->setErrorByName('hash_expiration', $this->t('The maximum hash expiration time is @max_value.', ['@max_value' => $this->t('@count days', ['@count' => 2])]));
}
*/
}
}

View file

@ -0,0 +1,78 @@
<?php
namespace Drupal\wisski_cloud_account_manager;
use Drupal\Core\Config\Config;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\StringTranslation\TranslationInterface;
use GuzzleHttp\ClientInterface;
/**
* Handles the communication with the WissKI Cloud account manager daemon.
*/
class WisskiCloudAccountManagerDaemonApiActions {
const DAEMON_URL = 'http://wisski_cloud_api_daemon:3000/wisski-cloud-daemon/api/v1/user/';
/**
* The string translation service.
*
* @var \Drupal\Core\StringTranslation\TranslationInterface
*/
protected TranslationInterface $stringTranslation;
/**
* The messenger service.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected MessengerInterface $messenger;
/**
* The HTTP client.
*
* @var \GuzzleHttp\ClientInterface
*/
protected ClientInterface $httpClient;
/**
* The settings config.
*
* @var \Drupal\Core\Config\Config
*/
protected Config $settings;
/**
* Class constructor.
*/
public function __construct(TranslationInterface $stringTranslation, MessengerInterface $messenger, ClientInterface $httpClient, ConfigFactoryInterface $configFactory) {
$this->stringTranslation = $stringTranslation;
$this->messenger = $messenger;
$this->httpClient = $httpClient;
$this->settings = $configFactory
->getEditable('wisski_cloud_account_manager.settings');
}
/**
* Adds a new account to the WissKI Cloud account manager daemon.
*
* @param array $account
* The account to add.
*
* @return array
* The response from the daemon (user id with validation code).
*/
public function addAccount(array $account): array {
dpm($account, 'account');
$request = [
'headers' => [
'Content-Type' => 'application/json',
],
'body' => json_encode($account),
];
dpm($request, 'request');
$response = $this->httpClient->post(self::DAEMON_URL, $request);
return json_decode($response->getBody()->getContents(), TRUE);
}
}

View file

@ -0,0 +1,6 @@
name: 'WissKI cloud account manager'
type: module
description: 'WissKI cloud manager with opt in service. Provides a common API for creating users for the WissKI Cloud.'
package: WissKI Cloud
configure: wisski_cloud_account_manager.settings
core_version_requirement: ^9 || ^10

View file

@ -0,0 +1,59 @@
<?php
use Drupal\Core\Database\Database;
/**
* Implements hook_schema().
*/
function wisski_cloud_account_manager_schema(): array {
$schema['wisski_cloud_accounts'] = [
'description' => 'The table for storing the WissKI Cloud users data.',
'fields' => [
'id' => [
'description' => 'The primary identifier for user. Same as in mongo db.',
'type' => 'char',
'length' => 24,
'not null' => TRUE,
],
'personname' => [
'description' => 'Real person name.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
],
'organisation' => [
'description' => 'Organisation.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
],
'email' => [
'description' => 'Email',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
],
'username' => [
'description' => 'User name.',
'type' => 'varchar',
'length' => 20,
'not null' => TRUE,
],
'subdomain' => [
'description' => 'Subdomain.',
'type' => 'varchar',
'length' => 20,
'not null' => TRUE,
],
'created' => [
'description' => 'Timestamp when the user was created.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
],
],
'primary key' => ['id'],
];
return $schema;
}

View file

@ -0,0 +1,23 @@
wisski_cloud_account.settings:
path: '/admin/config/system/wisski-cloud-account-manager/settings'
defaults:
_form: '\Drupal\wisski_cloud_account_manager\Form\WisskiCloudAccountManagerSettingsForm'
_title: 'WissKI cloud account settings'
requirements:
_permission: 'administer site configuration'
wisski_cloud_account.create:
path: '/wisski-cloud-account-manager/create'
defaults:
_form: '\Drupal\wisski_cloud_account_manager\Form\WisskiCloudAccountManagerCreateForm'
_title: 'Create WissKI cloud account'
requirements:
_access: 'TRUE'
wisski_cloud_account.terms_and_conditions:
path: '/wisski-cloud-account-manager/terms-and-conditions'
defaults:
_controller: '\Drupal\wisski_cloud_account_manager\Controller\WisskiCloudAccountManagerController::termsAndConditions'
_title: 'Terms and Conditions'
requirements:
_access: 'TRUE'

View file

@ -0,0 +1,8 @@
services:
wisski_cloud_account_manager.daemon_api.actions:
class: Drupal\wisski_cloud_account_manager\WisskiCloudAccountManagerDaemonApiActions
arguments:
- '@string_translation'
- '@messenger'
- '@http_client'
- '@config.factory'