From d7ae7d33385c0d0d1c3a2bb2fa9c7ae376b028b3 Mon Sep 17 00:00:00 2001 From: Robert Nasarek Date: Thu, 3 Aug 2023 16:39:36 +0200 Subject: [PATCH] first commit --- README.md | 1 + .../WisskiCloudAccountManagerController.php | 25 +++ .../WisskiCloudAccountManagerCreateForm.php | 201 ++++++++++++++++++ .../WisskiCloudAccountManagerSettingsForm.php | 69 ++++++ ...skiCloudAccountManagerDaemonApiActions.php | 78 +++++++ wisski_cloud_account_manager.info.yml | 6 + wisski_cloud_account_manager.install | 59 +++++ wisski_cloud_account_manager.routing.yml | 23 ++ wisski_cloud_account_manager.services.yml | 8 + 9 files changed, 470 insertions(+) create mode 100644 README.md create mode 100644 src/Controller/WisskiCloudAccountManagerController.php create mode 100644 src/Form/WisskiCloudAccountManagerCreateForm.php create mode 100644 src/Form/WisskiCloudAccountManagerSettingsForm.php create mode 100644 src/WisskiCloudAccountManagerDaemonApiActions.php create mode 100644 wisski_cloud_account_manager.info.yml create mode 100644 wisski_cloud_account_manager.install create mode 100644 wisski_cloud_account_manager.routing.yml create mode 100644 wisski_cloud_account_manager.services.yml diff --git a/README.md b/README.md new file mode 100644 index 0000000..8155ca1 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# WissKI Cloud Account Manager \ No newline at end of file diff --git a/src/Controller/WisskiCloudAccountManagerController.php b/src/Controller/WisskiCloudAccountManagerController.php new file mode 100644 index 0000000..efdd4fc --- /dev/null +++ b/src/Controller/WisskiCloudAccountManagerController.php @@ -0,0 +1,25 @@ + $this->t('Hello World!'), + ]; + return $build; + } + +} diff --git a/src/Form/WisskiCloudAccountManagerCreateForm.php b/src/Form/WisskiCloudAccountManagerCreateForm.php new file mode 100644 index 0000000..38ee37a --- /dev/null +++ b/src/Form/WisskiCloudAccountManagerCreateForm.php @@ -0,0 +1,201 @@ +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 terms and conditions 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()); + } + } + +} diff --git a/src/Form/WisskiCloudAccountManagerSettingsForm.php b/src/Form/WisskiCloudAccountManagerSettingsForm.php new file mode 100644 index 0000000..887efab --- /dev/null +++ b/src/Form/WisskiCloudAccountManagerSettingsForm.php @@ -0,0 +1,69 @@ +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])])); + } + */ + } +} diff --git a/src/WisskiCloudAccountManagerDaemonApiActions.php b/src/WisskiCloudAccountManagerDaemonApiActions.php new file mode 100644 index 0000000..7578f5f --- /dev/null +++ b/src/WisskiCloudAccountManagerDaemonApiActions.php @@ -0,0 +1,78 @@ +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); + } + +} diff --git a/wisski_cloud_account_manager.info.yml b/wisski_cloud_account_manager.info.yml new file mode 100644 index 0000000..a4d1640 --- /dev/null +++ b/wisski_cloud_account_manager.info.yml @@ -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 diff --git a/wisski_cloud_account_manager.install b/wisski_cloud_account_manager.install new file mode 100644 index 0000000..18b5120 --- /dev/null +++ b/wisski_cloud_account_manager.install @@ -0,0 +1,59 @@ + '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; +} diff --git a/wisski_cloud_account_manager.routing.yml b/wisski_cloud_account_manager.routing.yml new file mode 100644 index 0000000..fcf67e4 --- /dev/null +++ b/wisski_cloud_account_manager.routing.yml @@ -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' diff --git a/wisski_cloud_account_manager.services.yml b/wisski_cloud_account_manager.services.yml new file mode 100644 index 0000000..f571156 --- /dev/null +++ b/wisski_cloud_account_manager.services.yml @@ -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'