From 7ecc4e09a8d304d2607e7e216710ca4f50d8e0cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Ducoulombier?= Date: Tue, 25 Feb 2020 13:46:43 +0100 Subject: [PATCH] OAuth2-authenticated user creation / update - refs BT#16734 --- plugin/oauth2/lang/english.php | 24 +++++++++++ plugin/oauth2/src/OAuth2.php | 74 ++++++++++++++++++++++++++++++---- 2 files changed, 91 insertions(+), 7 deletions(-) diff --git a/plugin/oauth2/lang/english.php b/plugin/oauth2/lang/english.php index 6dfef631aa..e366cec118 100644 --- a/plugin/oauth2/lang/english.php +++ b/plugin/oauth2/lang/english.php @@ -53,6 +53,24 @@ $strings['response_resource_owner_id_help'] = 'The array key to the user\'s
means the identifier is to be found at $jsonArray["data"][0]["id"]'; + +$strings['update_user_info'] = 'Update user information'; +$strings['create_new_users'] = 'Create new users'; +$strings['response_resource_owner_firstname'] = 'Response Resource Owner firstname key'; +$strings['response_resource_owner_firstname_help'] = 'Same syntax as for the Response Resource Owner Id key'; +$strings['response_resource_owner_lastname'] = 'Response Resource Owner lastname key'; +$strings['response_resource_owner_status'] = 'Response Resource Owner status key'; +$strings['response_resource_owner_status_help'] = 'The value at this array key should be one of these integers:
+
1
Course Manager / Teacher
+
3
Session Administrator
+
4
DRH
+
5
Student
+
6
Anonymous
+
'; +$strings['response_resource_owner_email'] = 'Response Resource Owner email key'; +$strings['response_resource_owner_username'] = 'Response Resource Owner username key'; + + $strings['block_name'] = 'Block name'; $strings['block_name_help'] = 'The title shown above the OAuth2 Login button'; @@ -66,4 +84,10 @@ $strings['management_login_name_help'] = 'Default value is "Management Login".'; $strings['OAuth2Id'] = 'OAuth2 identifier'; $strings['ManagementLogin'] = 'Management Login'; + +$strings['invalid_json_received_from_provider'] = 'The OAuth2 provider did not provide a valid JSON document'; +$strings['wrong_response_resource_owner_id'] = 'OAuth2 resource owner identifier value not found at the configured key'; +$strings['no_user_has_this_oauth_code'] = 'No existing user has this OAuth2 code'; +$strings['FailedUserCreation'] = 'User account creation failed'; +$strings['internal_error_cannot_get_user_info'] = 'Internal error: could not get user information'; $strings['InvalidId'] = 'Login failed - the OAuth2 identifier was not recognized as an existing Chamilo user\'s.'; diff --git a/plugin/oauth2/src/OAuth2.php b/plugin/oauth2/src/OAuth2.php index 6f2e3cc92f..0d849894c3 100644 --- a/plugin/oauth2/src/OAuth2.php +++ b/plugin/oauth2/src/OAuth2.php @@ -37,6 +37,14 @@ class OAuth2 extends Plugin const SETTING_RESPONSE_CODE = 'response_code'; const SETTING_RESPONSE_RESOURCE_OWNER_ID = 'response_resource_owner_id'; + const SETTING_UPDATE_USER_INFO = 'update_user_info'; + const SETTING_CREATE_NEW_USERS = 'create_new_users'; + const SETTING_RESPONSE_RESOURCE_OWNER_FIRSTNAME = 'response_resource_owner_firstname'; + const SETTING_RESPONSE_RESOURCE_OWNER_LASTNAME = 'response_resource_owner_lastname'; + const SETTING_RESPONSE_RESOURCE_OWNER_STATUS = 'response_resource_owner_status'; + const SETTING_RESPONSE_RESOURCE_OWNER_EMAIL = 'response_resource_owner_email'; + const SETTING_RESPONSE_RESOURCE_OWNER_USERNAME = 'response_resource_owner_username'; + const SETTING_BLOCK_NAME = 'block_name'; const SETTING_MANAGEMENT_LOGIN_ENABLE = 'management_login_enable'; @@ -75,6 +83,14 @@ class OAuth2 extends Plugin self::SETTING_RESPONSE_CODE => 'text', self::SETTING_RESPONSE_RESOURCE_OWNER_ID => 'text', + self::SETTING_UPDATE_USER_INFO => 'boolean', + self::SETTING_CREATE_NEW_USERS => 'boolean', + self::SETTING_RESPONSE_RESOURCE_OWNER_FIRSTNAME => 'text', + self::SETTING_RESPONSE_RESOURCE_OWNER_LASTNAME => 'text', + self::SETTING_RESPONSE_RESOURCE_OWNER_STATUS => 'text', + self::SETTING_RESPONSE_RESOURCE_OWNER_EMAIL => 'text', + self::SETTING_RESPONSE_RESOURCE_OWNER_USERNAME => 'text', + self::SETTING_BLOCK_NAME => 'text', self::SETTING_MANAGEMENT_LOGIN_ENABLE => 'boolean', @@ -161,18 +177,62 @@ class OAuth2 extends Plugin } $extraFieldValue = new ExtraFieldValue('user'); $result = $extraFieldValue->get_item_id_from_field_variable_and_field_value( - OAuth2::EXTRA_FIELD_OAUTH2_ID, + self::EXTRA_FIELD_OAUTH2_ID, $resourceOwnerId ); if (false === $result) { - throw new RuntimeException( - get_lang('no_user_has_this_oauth_code') + // authenticated user not found in internal database + if (!$this->get(self::SETTING_CREATE_NEW_USERS)) { + throw new RuntimeException(get_lang('no_user_has_this_oauth_code')); + } + require_once __DIR__.'/../../../main/auth/external_login/functions.inc.php'; + $userId = external_add_user( + [ + 'firstname' => $this->getValueByKey($response, $this->get( + self::SETTING_RESPONSE_RESOURCE_OWNER_FIRSTNAME + )), + 'lastname' => $this->getValueByKey($response, $this->get( + self::SETTING_RESPONSE_RESOURCE_OWNER_LASTNAME + )), + 'status' => $this->getValueByKey($response, $this->get( + self::SETTING_RESPONSE_RESOURCE_OWNER_STATUS + )), + 'email' => $this->getValueByKey($response, $this->get( + self::SETTING_RESPONSE_RESOURCE_OWNER_EMAIL + )), + 'username' => $this->getValueByKey($response, $this->get( + self::SETTING_RESPONSE_RESOURCE_OWNER_USERNAME + )), + 'auth_source' => 'oauth2', + ] ); - } - if (is_array($result) and array_key_exists('item_id', $result)) { - $userId = $result['item_id']; + if (false === $userId) { + throw new RuntimeException(get_lang('FailedUserCreation')); + } + // Not checking function update_extra_field_value return value because not reliable + UserManager::update_extra_field_value($userId, self::EXTRA_FIELD_OAUTH2_ID, $resourceOwnerId); } else { - $userId = $result; + // authenticated user found in internal database + if (is_array($result) and array_key_exists('item_id', $result)) { + $userId = $result['item_id']; + } else { + $userId = $result; + } + if ($this->get(self::SETTING_UPDATE_USER_INFO)) { + $user = UserManager::getRepository()->find($userId); + $user->setFirstname( + $this->getValueByKey($response, $this->get(self::SETTING_RESPONSE_RESOURCE_OWNER_FIRSTNAME)) + )->setLastName( + $this->getValueByKey($response, $this->get(self::SETTING_RESPONSE_RESOURCE_OWNER_LASTNAME)) + )->setUserName( + $this->getValueByKey($response, $this->get(self::SETTING_RESPONSE_RESOURCE_OWNER_USERNAME)) + )->setEmail( + $this->getValueByKey($response, $this->get(self::SETTING_RESPONSE_RESOURCE_OWNER_EMAIL)) + )->setStatus( + $this->getValueByKey($response, $this->get(self::SETTING_RESPONSE_RESOURCE_OWNER_STATUS)) + )->setAuthSource('oauth2'); + UserManager::getManager()->updateUser($user); + } } $userInfo = api_get_user_info($userId); if (empty($userInfo)) {