diff --git a/src/Constants.php b/src/Constants.php index be5ac48..972b6eb 100644 --- a/src/Constants.php +++ b/src/Constants.php @@ -51,4 +51,19 @@ abstract class Constants { */ const KEY_VALUE_CLIENT_SECRET = 'client_secret'; + /** + * The name of the value in Graph API key types containing the grant type. + */ + const KEY_VALUE_GRANT_TYPE = 'grant_type'; + + /** + * The name of the value in Graph API key types containing the username. + */ + const KEY_VALUE_USERNAME = 'username'; + + /** + * The name of the value in Graph API key types containing the password. + */ + const KEY_VALUE_PASSWORD = 'password'; + } diff --git a/src/GraphApiGraphFactory.php b/src/GraphApiGraphFactory.php index 3618d41..244a5fb 100644 --- a/src/GraphApiGraphFactory.php +++ b/src/GraphApiGraphFactory.php @@ -137,6 +137,9 @@ class GraphApiGraphFactory implements GraphApiGraphFactoryInterface { $tenant_id = $key_config[Constants::KEY_VALUE_TENANT_ID] ?? NULL; $client_id = $key_config[Constants::KEY_VALUE_CLIENT_ID] ?? NULL; $client_secret = $key_config[Constants::KEY_VALUE_CLIENT_SECRET] ?? NULL; + $grant_type = $key_config[Constants::KEY_VALUE_GRANT_TYPE] ?? NULL; + $username = $key_config[Constants::KEY_VALUE_USERNAME] ?? NULL; + $password = $key_config[Constants::KEY_VALUE_PASSWORD] ?? NULL; if (empty($tenant_id)) { throw new ConfigValueException( @@ -165,8 +168,26 @@ class GraphApiGraphFactory implements GraphApiGraphFactoryInterface { ); } + if (empty($username) && $grant_type === 'password') { + throw new ConfigValueException( + sprintf( + "There is no 'Username' value defined in the provided MS Graph API key (%s).", + $key_id + ) + ); + } + + if (empty($password) && $grant_type === 'password') { + throw new ConfigValueException( + sprintf( + "There is no 'Password' value defined in the provided MS Graph API key (%s).", + $key_id + ) + ); + } + $access_token = - $this->obtainAccessToken($tenant_id, $client_id, $client_secret); + $this->obtainAccessToken($tenant_id, $client_id, $client_secret, $grant_type, $username, $password); $graph = new Graph(); $graph->setAccessToken($access_token); @@ -250,6 +271,12 @@ class GraphApiGraphFactory implements GraphApiGraphFactoryInterface { * The UUID that identifies the application that is authenticating. * @param string $client_secret * The secret key for the client. + * @param string $grant_type + * The grant type for the client. + * @param string $username + * The username for the client (optional). + * @param string $password + * The password for the client (optional). * * @throws \Drupal\ms_graph_api\Exception\AccessTokenRequestException * If the connection to Microsoft's authentication servers cannot be @@ -261,7 +288,10 @@ class GraphApiGraphFactory implements GraphApiGraphFactoryInterface { */ protected function obtainAccessToken(string $tenant_id, string $client_id, - string $client_secret) { + string $client_secret, + string $grant_type, + string $username = '', + string $password = '') { $endpoint_uri = UriTemplate::expand( self::MS_TOKEN_ENDPOINT_URI, @@ -275,10 +305,15 @@ class GraphApiGraphFactory implements GraphApiGraphFactoryInterface { 'client_id' => $client_id, 'client_secret' => $client_secret, 'resource' => self::MS_GRAPH_RESOURCE, - 'grant_type' => 'client_credentials', + 'grant_type' => $grant_type, ], ]; + if ($grant_type === 'password') { + $request_options['form_params']['username'] = $username; + $request_options['form_params']['password'] = $password; + } + try { $response = $http_client->post($endpoint_uri, $request_options); } diff --git a/src/Plugin/KeyInput/GraphApiKeyInput.php b/src/Plugin/KeyInput/GraphApiKeyInput.php index a0c8383..edfdf16 100644 --- a/src/Plugin/KeyInput/GraphApiKeyInput.php +++ b/src/Plugin/KeyInput/GraphApiKeyInput.php @@ -20,6 +20,9 @@ use Drupal\ms_graph_api\Constants; * - Tenant ID. * - Client ID. * - Client Secret. + * - Grant Type. + * - Username (optional). + * - Password (optional). * * @KeyInput( * id = "ms_graph_api", @@ -46,6 +49,9 @@ class GraphApiKeyInput extends KeyInputBase { 'tenant_id' => '', 'client_id' => '', 'client_secret' => '', + 'grant_type' => '', + 'username' => '', + 'password' => '', ]; } @@ -72,7 +78,7 @@ class GraphApiKeyInput extends KeyInputBase { $form[Constants::KEY_VALUE_CLIENT_ID] = [ '#type' => 'textfield', '#title' => $this->t('Client ID'), - '#description' => $this->t('The GUID/UUID for the graph API client (an app registration).'), + '#description' => $this->t('The GUID/UUID for the Graph API client (an app registration).'), '#placeholder' => '123e4567-e89b-12d3-a456-426614174000', '#required' => TRUE, ]; @@ -85,6 +91,46 @@ class GraphApiKeyInput extends KeyInputBase { '#sensitive' => TRUE, ]; + $form[Constants::KEY_VALUE_GRANT_TYPE] = [ + '#type' => 'select', + '#title' => $this->t('Grant type'), + '#description' => $this->t('The grant type for the Graph API authentication.'), + '#options' => [ + 'client_credentials' => $this->t('Client Credentials'), + 'password' => $this->t('Password Credentials'), + ], + '#required' => TRUE, + ]; + + $form[Constants::KEY_VALUE_USERNAME] = [ + '#type' => 'textfield', + '#title' => $this->t('Username'), + '#description' => $this->t('The username for the Graph API authentication.'), + '#states' => [ + 'visible' => [ + ':input[name="key_input_settings[' . Constants::KEY_VALUE_GRANT_TYPE . ']"]' => ['value' => 'password'], + ], + 'required' => [ + ':input[name="key_input_settings[' . Constants::KEY_VALUE_GRANT_TYPE . ']"]' => ['value' => 'password'], + ], + ], + ]; + + $form[Constants::KEY_VALUE_PASSWORD] = [ + '#type' => 'textfield', + '#title' => $this->t('Password'), + '#description' => $this->t('The password for the Graph API authentication.'), + '#sensitive' => TRUE, + '#states' => [ + 'visible' => [ + ':input[name="key_input_settings[' . Constants::KEY_VALUE_GRANT_TYPE . ']"]' => ['value' => 'password'], + ], + 'required' => [ + ':input[name="key_input_settings[' . Constants::KEY_VALUE_GRANT_TYPE . ']"]' => ['value' => 'password'], + ], + ], + ]; + $this->obscureAndPopulateDefaults($form, $form_state); return $form; diff --git a/src/Plugin/KeyType/GraphApiKeyType.php b/src/Plugin/KeyType/GraphApiKeyType.php index 56d8524..1ab7b8b 100644 --- a/src/Plugin/KeyType/GraphApiKeyType.php +++ b/src/Plugin/KeyType/GraphApiKeyType.php @@ -32,6 +32,18 @@ use Drupal\key\Plugin\KeyType\AuthenticationMultivalueKeyType; * "label" = @Translation("Client secret"), * "required" = true * }, + * "grant_type" = { + * "label" = @Translation("Grant type"), + * "required" = true + * }, + * "username" = { + * "label" = @Translation("Username"), + * "required" = false + * }, + * "password" = { +* "label" = @Translation("Password"), +* "required" = false +* }, * } * } * )