diff --git a/core/config.class.inc.php b/core/config.class.inc.php index 8aac1721b..af1e05c36 100644 --- a/core/config.class.inc.php +++ b/core/config.class.inc.php @@ -555,46 +555,6 @@ class Config 'source_of_value' => '', 'show_in_conf_sample' => false, ), - 'email_transport_smtp.oauth.provider' => [ - 'type' => 'string', - 'description' => 'Email OAuth provider', - 'default' => '', - 'value' => '', - 'source_of_value' => '', - 'show_in_conf_sample' => false, - ], - 'email_transport_smtp.oauth.client_id' => [ - 'type' => 'string', - 'description' => 'Email OAuth client id', - 'default' => '', - 'value' => '', - 'source_of_value' => '', - 'show_in_conf_sample' => false, - ], - 'email_transport_smtp.oauth.client_secret' => [ - 'type' => 'string', - 'description' => 'Email OAuth client secret', - 'default' => '', - 'value' => '', - 'source_of_value' => '', - 'show_in_conf_sample' => false, - ], - 'email_transport_smtp.oauth.access_token' => [ - 'type' => 'string', - 'description' => 'Email OAuth access token', - 'default' => '', - 'value' => '', - 'source_of_value' => '', - 'show_in_conf_sample' => false, - ], - 'email_transport_smtp.oauth.refresh_token' => [ - 'type' => 'string', - 'description' => 'Email OAuth refresh token', - 'default' => '', - 'value' => '', - 'source_of_value' => '', - 'show_in_conf_sample' => false, - ], 'email_css' => array( 'type' => 'string', 'description' => 'CSS that will override the standard stylesheet used for the notifications', diff --git a/datamodels/2.x/installation.xml b/datamodels/2.x/installation.xml index 6f7fc2760..167125d93 100755 --- a/datamodels/2.x/installation.xml +++ b/datamodels/2.x/installation.xml @@ -20,6 +20,7 @@ combodo-db-tools itop-core-update itop-hub-connector + itop-remote-authent-oauth true diff --git a/datamodels/2.x/itop-remote-authent-oauth/README.md b/datamodels/2.x/itop-remote-authent-oauth/README.md new file mode 100644 index 000000000..200c96ef9 --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/README.md @@ -0,0 +1,2 @@ +# Extension Remote authentication for OAuth 2.0 + diff --git a/datamodels/2.x/itop-remote-authent-oauth/ajax.php b/datamodels/2.x/itop-remote-authent-oauth/ajax.php new file mode 100644 index 000000000..da6859faf --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/ajax.php @@ -0,0 +1,24 @@ += 0) { + $sTemplates = MODULESROOT.'itop-remote-authent-oauth/templates'; +} else { + $sTemplates = MODULESROOT.'itop-remote-authent-oauth/templates/legacy'; +} + +$oUpdateController = new AjaxRemoteAuthentOauthController($sTemplates, 'itop-remote-authent-oauth'); +$oUpdateController->AllowOnlyAdmin(); +$oUpdateController->SetDefaultOperation('CreateMailbox'); +$oUpdateController->HandleOperation(); + + diff --git a/images/icons/icons8-azure.svg b/datamodels/2.x/itop-remote-authent-oauth/assets/img/icons8-azure.svg similarity index 100% rename from images/icons/icons8-azure.svg rename to datamodels/2.x/itop-remote-authent-oauth/assets/img/icons8-azure.svg diff --git a/images/icons/icons8-google.svg b/datamodels/2.x/itop-remote-authent-oauth/assets/img/icons8-google.svg similarity index 100% rename from images/icons/icons8-google.svg rename to datamodels/2.x/itop-remote-authent-oauth/assets/img/icons8-google.svg diff --git a/datamodels/2.x/itop-remote-authent-oauth/assets/js/oauth_connect.js b/datamodels/2.x/itop-remote-authent-oauth/assets/js/oauth_connect.js new file mode 100644 index 000000000..1ce571112 --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/assets/js/oauth_connect.js @@ -0,0 +1,99 @@ +/** + * @copyright Copyright (C) 2010-2022 Combodo SARL + * @license http://opensource.org/licenses/AGPL-3.0 + */ + +// Function used to open OAuth popup +var oWindowObjectReference = null; +var sPreviousUrl = null; +var oListener = null; +var sOAuthAjaxURI = null; +var sOAuthObjClass = null; +var sOAuthObjKey = null; +var sOAuthReturnURI = null; + + +const oOnOauthSuccess = function (event) { + if (oListener !== null) { + clearInterval(oListener); + } + + $.post( + sOAuthAjaxURI, + { + operation: 'GetDisplayAuthenticationResults', + class: sOAuthObjClass, + id: sOAuthObjKey, + redirect_url: event.data + }, + function (oData) { + window.location = oData.data; + } + ); +} +const oOpenSignInWindow = function (url, name) { + // Remove any existing event listener + window.removeEventListener('message', oOnOauthSuccess); + if (oListener !== null) { + clearInterval(oListener); + } + + // Window features + const sWindowFeatures = 'toolbar=no, menubar=no, width=600, height=700, top=100, left=100'; + + if (oWindowObjectReference === null || oWindowObjectReference.closed) { + /* If the pointer to the window object in memory does not exist + or if such pointer exists but the window was closed */ + oWindowObjectReference = window.open(url, name, sWindowFeatures); + } else if (sPreviousUrl !== url) { + /* If the resource to load is different, + then we load it in the already opened secondary window, and then + we bring such window back on top/in front of its parent window. */ + oWindowObjectReference = window.open(url, name, sWindowFeatures); + oWindowObjectReference.focus(); + } else { + /* Else the window reference must exist and the window + is not closed; therefore, we can bring it back on top of any other + window with the focus() method. There would be no need to re-create + the window or to reload the referenced resource. */ + oWindowObjectReference.focus(); + } + /* Let know every second our child window that we're waiting for it to complete, + once we reach our landing page, it'll send us a reply + */ + oListener = window.setInterval(function () { + if (oWindowObjectReference.closed) { + clearInterval(oListener); + } + oWindowObjectReference.postMessage('anyone', sOAuthReturnURI); + }, 1000); + + /* Once we receive a response, transmit it to the server to get authenticate and display + results + */ + window.addEventListener('message', oOnOauthSuccess, false); + // Assign the previous URL + sPreviousUrl = url; +}; + + +const OAuthConnect = function(sClass, sId, sAjaxUri, sReturnUri) { + sOAuthAjaxURI = sAjaxUri; + sOAuthObjClass = sClass; + sOAuthObjKey = sId; + sOAuthReturnURI = sReturnUri; + + $.post( + sOAuthAjaxURI, + { + operation: 'GetOAuthAuthorizationUrl', + class: sOAuthObjClass, + id: sOAuthObjKey + }, + function (oData) { + if (oData.status === 'success') { + oOpenSignInWindow(oData.data.authorization_url, 'OAuth authorization') + } + } + ); +} \ No newline at end of file diff --git a/datamodels/2.x/itop-remote-authent-oauth/composer.json b/datamodels/2.x/itop-remote-authent-oauth/composer.json new file mode 100644 index 000000000..4dce44506 --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/composer.json @@ -0,0 +1,16 @@ +{ + "config": { + "classmap-authoritative": true + }, + "autoload": { + "psr-4": { + "Combodo\\iTop\\RemoteAuthentOAuth\\": "src" + } + }, + "name": "combodo/itop-remote-authent-oauth", + "type": "itop-extension", + "description": "Remote authentication for OAuth 2.0", + "require": { + "composer-runtime-api": "^2.0" + } +} \ No newline at end of file diff --git a/datamodels/2.x/itop-remote-authent-oauth/datamodel.itop-remote-authent-oauth.xml b/datamodels/2.x/itop-remote-authent-oauth/datamodel.itop-remote-authent-oauth.xml new file mode 100644 index 000000000..cac68d114 --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/datamodel.itop-remote-authent-oauth.xml @@ -0,0 +1,225 @@ + + + + + + cmdbAbstractObject + + cloud,searchable + true + autoincrement + priv_remote_authent_oauth + id + + + + + + + + + + + + + + + + + + + + + + false + true + + + + + + + + + + false + true + + + + + + provider + + false + + + name + + false + + + scope + + true + + + description + + true + + + client_id + + false + + + client_secret + + false + + + refresh_token + + true + none + + + refresh_token_expiration + + true + none + + + token + + true + none + + + token_expiration + + true + none + + + redirect_url + + _blank + true + + + MailInboxOAuth + remote_authent_oauth_id + 0 + 0 + + + + + false + public + Overload-DBObject + Get('email_transport_smtp.username') == $this->Get('name')) { + $sLabel = Dict::S('itop-remote-authent-oauth:UsedForSMTP'); + $sTestLabel = Dict::S('itop-remote-authent-oauth:TestSMTP'); + $sTestURL = utils::GetAbsoluteUrlAppRoot().'setup/email.test.php'; + $oPage->p("$sLabel $sTestLabel"); + } + } + } + ]]> + + + false + public + Get('provider').'.com'; + } + ]]> + + + false + public + + + + +
+ + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + + 7 + + + 8 + + +
+ + + + 1 + + + 2 + + + + + + + 1 + + + 2 + + + +
+
+
+ + + 100 + ConfigurationTools + RemoteAuthentOAuth + + + + + + + + +
diff --git a/datamodels/2.x/itop-remote-authent-oauth/en.dict.itop-remote-authent-oauth.php b/datamodels/2.x/itop-remote-authent-oauth/en.dict.itop-remote-authent-oauth.php new file mode 100644 index 000000000..eabc2b146 --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/en.dict.itop-remote-authent-oauth.php @@ -0,0 +1,54 @@ + 'Create a mailbox', + 'Menu:RemoteOAuth' => 'Remote OAuth', + 'Menu:GenerateTokens' => 'Generate tokens', + 'Menu:RegenerateTokens' => 'Regenerate tokens', + + 'itop-remote-authent-oauth/Operation:CreateMailBox/Title' => 'Mailbox creation', + + 'itop-remote-authent-oauth:UsedForSMTP' => 'This connection is used for SMTP', + 'itop-remote-authent-oauth:TestSMTP' => 'Email test', + 'itop-remote-authent-oauth:MissingRemoteAuthentOAuth' => 'Missing Remote Authentication (OAuth) for user name %1$s', + + 'Class:RemoteAuthentOAuthGoogle' => 'Remote Google Authentication (OAuth)', + 'Class:RemoteAuthentOAuthAzure' => 'Remote Microsoft Azure Authentication (OAuth)', +]); + +// +// Class: RemoteAuthentOAuth +// + +Dict::Add('EN US', 'English', 'English', [ + 'Class:RemoteAuthentOAuth' => 'Remote Authentication (OAuth)', + 'Class:RemoteAuthentOAuth/Name' => '%1$s-%%2$s', + 'Class:RemoteAuthentOAuth/Attribute:provider' => 'Provider', + 'Class:RemoteAuthentOAuth/Attribute:provider+' => '', + 'Class:RemoteAuthentOAuth/Attribute:name' => 'Login', + 'Class:RemoteAuthentOAuth/Attribute:name+' => '', + 'Class:RemoteAuthentOAuth/Attribute:scope' => 'Scope', + 'Class:RemoteAuthentOAuth/Attribute:scope+' => '', + 'Class:RemoteAuthentOAuth/Attribute:description' => 'Description', + 'Class:RemoteAuthentOAuth/Attribute:description+' => '', + 'Class:RemoteAuthentOAuth/Attribute:client_id' => 'Client id', + 'Class:RemoteAuthentOAuth/Attribute:client_id+' => '', + 'Class:RemoteAuthentOAuth/Attribute:client_secret' => 'Client secret', + 'Class:RemoteAuthentOAuth/Attribute:client_secret+' => '', + 'Class:RemoteAuthentOAuth/Attribute:refresh_token' => 'Refresh token', + 'Class:RemoteAuthentOAuth/Attribute:refresh_token+' => '', + 'Class:RemoteAuthentOAuth/Attribute:refresh_token_expiration' => 'Refresh token expiration', + 'Class:RemoteAuthentOAuth/Attribute:refresh_token_expiration+' => '', + 'Class:RemoteAuthentOAuth/Attribute:token' => 'Token', + 'Class:RemoteAuthentOAuth/Attribute:token+' => '', + 'Class:RemoteAuthentOAuth/Attribute:token_expiration' => 'Token expiration', + 'Class:RemoteAuthentOAuth/Attribute:token_expiration+' => '', + 'Class:RemoteAuthentOAuth/Attribute:redirect_url' => 'Redirect url', + 'Class:RemoteAuthentOAuth/Attribute:redirect_url+' => '', +]); diff --git a/datamodels/2.x/itop-remote-authent-oauth/index.php b/datamodels/2.x/itop-remote-authent-oauth/index.php new file mode 100644 index 000000000..eb7364ca7 --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/index.php @@ -0,0 +1,24 @@ += 0) { + $sTemplates = MODULESROOT.'itop-remote-authent-oauth/templates'; +} else { + $sTemplates = MODULESROOT.'itop-remote-authent-oauth/templates/legacy'; +} + +$oUpdateController = new RemoteAuthentOauthController($sTemplates, 'itop-remote-authent-oauth'); +$oUpdateController->AllowOnlyAdmin(); +$oUpdateController->SetDefaultOperation('CreateMailbox'); +$oUpdateController->HandleOperation(); + + diff --git a/datamodels/2.x/itop-remote-authent-oauth/model.itop-remote-authent-oauth.php b/datamodels/2.x/itop-remote-authent-oauth/model.itop-remote-authent-oauth.php new file mode 100644 index 000000000..e8410c24c --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/model.itop-remote-authent-oauth.php @@ -0,0 +1,137 @@ + 'cloud,searchable', + 'key_type' => 'autoincrement', + 'name_attcode' => array('provider', 'name'), + 'state_attcode' => '', + 'reconc_keys' => array('provider', 'name'), + 'db_table' => 'priv_remote_authent_oauth', + 'db_key_field' => 'id', + 'db_finalclass_field' => '', + 'uniqueness_rules' => array ( + 'Username' => + array ( + 'attributes' => + array ( + 0 => 'name', + ), + 'filter' => NULL, + 'disabled' => false, + 'is_blocking' => true, + ), + 'OAuth Server' => + array ( + 'attributes' => + array ( + 0 => 'provider', + 1 => 'scope', + 2 => 'client_id', + 3 => 'client_secret', + ), + 'filter' => NULL, + 'disabled' => false, + 'is_blocking' => true, + ), +),); + MetaModel::Init_Params($aParams); + MetaModel::Init_InheritAttributes(); + MetaModel::Init_AddAttribute(new AttributeString("provider", array("allowed_values"=>null, "sql"=>'provider', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array(), "always_load_in_tables"=>false))); + MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>'name', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array(), "always_load_in_tables"=>false))); + MetaModel::Init_AddAttribute(new AttributeString("scope", array("allowed_values"=>null, "sql"=>'scope', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false))); + MetaModel::Init_AddAttribute(new AttributeText("description", array("allowed_values"=>null, "sql"=>'description', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false))); + MetaModel::Init_AddAttribute(new AttributeText("client_id", array("allowed_values"=>null, "sql"=>'client_id', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array(), "always_load_in_tables"=>false))); + MetaModel::Init_AddAttribute(new AttributeText("client_secret", array("allowed_values"=>null, "sql"=>'client_secret', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array(), "always_load_in_tables"=>false))); + MetaModel::Init_AddAttribute(new AttributeText("refresh_token", array("allowed_values"=>null, "sql"=>'refresh_token', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false, "tracking_level"=>ATTRIBUTE_TRACKING_NONE))); + MetaModel::Init_AddAttribute(new AttributeDateTime("refresh_token_expiration", array("allowed_values"=>null, "sql"=>'refresh_token_expiration', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false, "tracking_level"=>ATTRIBUTE_TRACKING_NONE))); + MetaModel::Init_AddAttribute(new AttributeText("token", array("allowed_values"=>null, "sql"=>'token', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false, "tracking_level"=>ATTRIBUTE_TRACKING_NONE))); + MetaModel::Init_AddAttribute(new AttributeDateTime("token_expiration", array("allowed_values"=>null, "sql"=>'token_expiration', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false, "tracking_level"=>ATTRIBUTE_TRACKING_NONE))); + MetaModel::Init_AddAttribute(new AttributeURL("redirect_url", array("target"=>'_blank', "allowed_values"=>null, "sql"=>'redirect_url', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false))); + MetaModel::Init_AddAttribute(new AttributeLinkedSet("mailbox_list", array("linked_class"=>'MailInboxOAuth', "ext_key_to_me"=>'remote_authent_oauth_id', "count_min"=>0, "count_max"=>0, "allowed_values"=>null, "depends_on"=>array(), "always_load_in_tables"=>false))); + + + + MetaModel::Init_SetZListItems('details', array ( + 0 => 'name', + 1 => 'description', + 2 => 'provider', + 3 => 'scope', + 4 => 'redirect_url', + 5 => 'client_id', + 6 => 'client_secret', + 7 => 'mailbox_list', +)); + MetaModel::Init_SetZListItems('standard_search', array ( + 0 => 'name', + 1 => 'provider', +)); + MetaModel::Init_SetZListItems('default_search', array ( + 0 => 'name', + 1 => 'provider', +)); +; + } + + + + + public function DisplayBareHeader(WebPage $oPage, $bEditMode = false) + { + parent::DisplayBareHeader($oPage, $bEditMode); + if (!$bEditMode) { + $oConfig = utils::GetConfig(); + if ($oConfig->Get('email_transport_smtp.username') == $this->Get('name')) { + $sLabel = Dict::S('itop-remote-authent-oauth:UsedForSMTP'); + $sTestLabel = Dict::S('itop-remote-authent-oauth:TestSMTP'); + $sTestURL = utils::GetAbsoluteUrlAppRoot().'setup/email.test.php'; + $oPage->p("$sLabel $sTestLabel"); + } + } + } + + + + + public function GetDefaultMailServer() + { + return 'imap.'.$this->Get('provider').'.com'; + } + + + + + public function GetDefaultMailServerPort() + { + return 993; + } + + +} +// +// Menus +// +class MenuCreation_itop_remote_authent_oauth extends ModuleHandlerAPI +{ + public static function OnMenuCreation() + { + global $__comp_menus__; // ensure that the global variable is indeed global ! + $__comp_menus__['ConfigurationTools'] = new MenuGroup('ConfigurationTools', 90 , null, UR_ACTION_MODIFY, UR_ALLOWED_YES, null); + $__comp_menus__['RemoteOAuth'] = new SearchMenuNode('RemoteOAuth', 'RemoteAuthentOAuth', $__comp_menus__['ConfigurationTools']->GetIndex(), 100, null , null, UR_ACTION_MODIFY, UR_ALLOWED_YES, null); + } +} // class MenuCreation_itop_remote_authent_oauth diff --git a/datamodels/2.x/itop-remote-authent-oauth/module.itop-remote-authent-oauth.php b/datamodels/2.x/itop-remote-authent-oauth/module.itop-remote-authent-oauth.php new file mode 100644 index 000000000..569531811 --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/module.itop-remote-authent-oauth.php @@ -0,0 +1,55 @@ + 'Remote authentication for OAuth 2.0', + 'category' => 'business', + + // Setup + // + 'dependencies' => array( + 'itop-welcome-itil/2.7.7,' + ), + 'mandatory' => false, + 'visible' => true, + + // Components + // + 'datamodel' => array( + 'vendor/autoload.php', + 'model.itop-remote-authent-oauth.php', // Contains the PHP code generated by the "compilation" of datamodel.remote-authent-oauth.xml + 'src/Model/RemoteAuthentOAuthGoogle.php', + 'src/Model/RemoteAuthentOAuthAzure.php', + 'src/Service/PopupMenuExtension.php', + 'src/Service/ApplicationObjectExtension.php', + ), + 'webservice' => array( + + ), + 'data.struct' => array( + // add your 'structure' definition XML files here, + ), + 'data.sample' => array( + // add your sample data XML files here, + ), + + // Documentation + // + 'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any + 'doc.more_information' => '', // hyperlink to more information, if any + + // Default settings + // + 'settings' => array( + // Module specific settings go here, if any + ), + ) +); + diff --git a/datamodels/2.x/itop-remote-authent-oauth/src/Controller/AjaxRemoteAuthentOauthController.php b/datamodels/2.x/itop-remote-authent-oauth/src/Controller/AjaxRemoteAuthentOauthController.php new file mode 100644 index 000000000..c3193c648 --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/src/Controller/AjaxRemoteAuthentOauthController.php @@ -0,0 +1,89 @@ + 'success', 'data' => []]; + $sProvider = $oObject->Get('provider'); + $sClientId = $oObject->Get('client_id'); + $sClientSecret = $oObject->Get('client_secret'); + $sScope = $oObject->Get('scope'); + $aAdditional = []; + $sAuthorizationUrl = OAuthClientProviderFactory::getVendorProviderForAccessUrl($sProvider, $sClientId, $sClientSecret, $sScope, $aAdditional); + $aResult['data']['authorization_url'] = $sAuthorizationUrl; + + $this->DisplayJSONPage($aResult); + + } + + public function OperationGetDisplayAuthenticationResults() + { + $sClass = utils::ReadParam('class'); + $sId = utils::ReadParam('id'); + + IssueLog::Debug("GetDisplayAuthenticationResults for $sClass::$sId", self::LOG_CHANNEL); + + $oObject = MetaModel::GetObject($sClass, $sId); + $bIsCreation = empty($oObject->Get('token')); + + $sProvider = $oObject->Get('provider'); + $sClientId = $oObject->Get('client_id'); + $sClientSecret = $oObject->Get('client_secret'); + $sScope = $oObject->Get('scope'); + $aAdditional = []; + + $sRedirectUrl = utils::ReadParam('redirect_url', '', false, 'raw'); + + $sRedirectUrlQuery = parse_url($sRedirectUrl)['query']; + + $aQuery = []; + parse_str($sRedirectUrlQuery, $aQuery); + $sCode = $aQuery['code']; + $oProvider = OAuthClientProviderFactory::getVendorProvider($sProvider, $sClientId, $sClientSecret, $sScope, $aAdditional); + $oAccessToken = OAuthClientProviderFactory::getAccessTokenFromCode($oProvider, $sCode); + + $oObject->Set('token', $oAccessToken->getToken()); + $oObject->Set('refresh_token', $oAccessToken->getRefreshToken()); + $oObject->DBUpdate(); + + cmdbAbstractObject::SetSessionMessage( + $sClass, + $sId, + "$sClass:$sId:TokenCreated", + $bIsCreation ? Dict::S("RemoteAuthentOAuth:Message:TokenCreated") : Dict::S('RemoteAuthentOAuth:Message:TokenRecreated'), + 'ok', + 1, + true + ); + + $aResult = ['status' => 'success']; + $aResult['data'] = utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=details&class=$sClass&id=$sId"; + + $this->DisplayJSONPage($aResult); + } + +} \ No newline at end of file diff --git a/datamodels/2.x/itop-remote-authent-oauth/src/Controller/RemoteAuthentOauthController.php b/datamodels/2.x/itop-remote-authent-oauth/src/Controller/RemoteAuthentOauthController.php new file mode 100644 index 000000000..fbeec1b87 --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/src/Controller/RemoteAuthentOauthController.php @@ -0,0 +1,42 @@ +Get('name'); + $sDefaultServer = $oRemoteAuthentOAuth->GetDefaultMailServer(); + $sDefaultPort = $oRemoteAuthentOAuth->GetDefaultMailServerPort(); + + $aParams['sURL'] = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=new&class=MailInboxOAuth'. + '&default[protocol]=imap'. + '&default[mailbox]=INBOX'. + '&default[server]='.$sDefaultServer. + '&default[port]='.$sDefaultPort. + '&default[remote_authent_oauth_id]='.$sId. + '&default[login]='.$sLogin; + + $this->DisplayPage($aParams); + } +} \ No newline at end of file diff --git a/datamodels/2.x/itop-remote-authent-oauth/src/Model/RemoteAuthentOAuthAzure.php b/datamodels/2.x/itop-remote-authent-oauth/src/Model/RemoteAuthentOAuthAzure.php new file mode 100644 index 000000000..0ded7dc46 --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/src/Model/RemoteAuthentOAuthAzure.php @@ -0,0 +1,59 @@ + 'cloud', + 'key_type' => 'autoincrement', + 'name_attcode' => ['provider','name'], + 'state_attcode' => '', + 'reconc_keys' => ['provider','name'], + 'db_table' => 'priv_remote_authent_oauth_azure', + 'db_key_field' => 'id', + 'icon' => utils::GetAbsoluteUrlModulesRoot().'itop-remote-authent-oauth/assets/img/icons8-azure.svg', + 'db_finalclass_field' => '', + ); + MetaModel::Init_Params($aParams); + MetaModel::Init_InheritAttributes(); + + MetaModel::Init_SetZListItems('details', [ + 0 => 'name', + 1 => 'description', + 2 => 'provider', + 3 => 'scope', + 4 => 'redirect_url', + 5 => 'client_id', + 6 => 'client_secret', + 7 => 'mailbox_list', + ]); + MetaModel::Init_SetZListItems('standard_search', [ + 0 => 'name', + 2 => 'provider', + ]); + MetaModel::Init_SetZListItems('list', [ + ]); + } + + public function PrefillCreationForm(&$aContextParam) + { + $this->Set('provider', 'Azure'); + $this->Set('scope', ''); + $this->Set('redirect_url', OAuthClientProviderAbstract::GetRedirectUri()); + + parent::PrefillCreationForm($aContextParam); + } + + public function GetDefaultMailServer() + { + return 'imap.office365.com'; + } +} \ No newline at end of file diff --git a/datamodels/2.x/itop-remote-authent-oauth/src/Model/RemoteAuthentOAuthGoogle.php b/datamodels/2.x/itop-remote-authent-oauth/src/Model/RemoteAuthentOAuthGoogle.php new file mode 100644 index 000000000..d137ca59d --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/src/Model/RemoteAuthentOAuthGoogle.php @@ -0,0 +1,60 @@ + 'cloud', + 'key_type' => 'autoincrement', + 'name_attcode' => ['provider','name'], + 'state_attcode' => '', + 'reconc_keys' => ['provider','name'], + 'db_table' => 'priv_remote_authent_oauth_google', + 'db_key_field' => 'id', + 'icon' => utils::GetAbsoluteUrlModulesRoot().'itop-remote-authent-oauth/assets/img/icons8-google.svg', + 'db_finalclass_field' => '', + ); + MetaModel::Init_Params($aParams); + MetaModel::Init_InheritAttributes(); + + MetaModel::Init_SetZListItems('details', [ + 0 => 'name', + 1 => 'description', + 2 => 'provider', + 3 => 'scope', + 4 => 'redirect_url', + 5 => 'client_id', + 6 => 'client_secret', + 7 => 'mailbox_list', + ]); + MetaModel::Init_SetZListItems('standard_search', [ + 0 => 'name', + 2 => 'provider', + ]); + MetaModel::Init_SetZListItems('list', [ + ]); + } + + public function PrefillCreationForm(&$aContextParam) + { + $this->Set('provider', 'Google'); + $this->Set('scope', 'https://mail.google.com/'); + $this->Set('redirect_url', OAuthClientProviderAbstract::GetRedirectUri()); + + parent::PrefillCreationForm($aContextParam); + } + + public function GetDefaultMailServer() + { + return 'imap.gmail.com'; + } + +} \ No newline at end of file diff --git a/datamodels/2.x/itop-remote-authent-oauth/src/Service/ApplicationObjectExtension.php b/datamodels/2.x/itop-remote-authent-oauth/src/Service/ApplicationObjectExtension.php new file mode 100644 index 000000000..1d2aeb448 --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/src/Service/ApplicationObjectExtension.php @@ -0,0 +1,30 @@ +Get('token')); + $aResult[] = new SeparatorPopupMenuItem(); + + $oAppContext = new ApplicationContext(); + $sMenu = $bHasToken ? 'Menu:RegenerateTokens' : 'Menu:GenerateTokens'; + $sObjClass = get_class($oObj); + $sClass = $sObjClass; + $sId = $oObj->GetKey(); + $sAjaxUri = utils::GetAbsoluteUrlModulePage(static::MODULE_CODE, 'ajax.php'); + // Add a new menu item that triggers a custom JS function defined in our own javascript file: js/sample.js + $sJSFileUrl = utils::GetAbsoluteUrlModulesRoot().static::MODULE_CODE.'/assets/js/oauth_connect.js'; + $sRedirectUri = OAuthClientProviderAbstract::GetRedirectUri(); + $aResult[] = new JSPopupMenuItem( + $sMenu.' from '.$sObjClass, + Dict::S($sMenu), + "OAuthConnect('$sClass', $sId, '$sAjaxUri', '$sRedirectUri')", + [$sJSFileUrl] + ); + + if ($bHasToken) { + $aParams = $oAppContext->GetAsHash(); + $sMenu = 'Menu:CreateMailbox'; + $sObjClass = get_class($oObj); + $aParams['class'] = $sObjClass; + $aParams['id'] = $oObj->GetKey(); + $aParams['operation'] = 'CreateMailBox'; + $aResult[] = new URLPopupMenuItem( + $sMenu.' from '.$sObjClass, + Dict::S($sMenu), + utils::GetAbsoluteUrlModulePage(static::MODULE_CODE, 'index.php', $aParams) + ); + } + } + break; + + default: + // Unknown type of menu, do nothing + break; + } + + return $aResult; + } +} \ No newline at end of file diff --git a/datamodels/2.x/itop-remote-authent-oauth/src/Service/RemoteAuthentOAuthService.php b/datamodels/2.x/itop-remote-authent-oauth/src/Service/RemoteAuthentOAuthService.php new file mode 100644 index 000000000..fe8a127f8 --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/src/Service/RemoteAuthentOAuthService.php @@ -0,0 +1,47 @@ +oRemoteAuthentOAuth = $oRemoteAuthentOAuth; + } + + public function Authenticate(WebPage $oPage) + { + + } + + + public function DisplayAuthentForm(WebPage $oPage) + { + $sForm = "
\n"; + $sForm .= "\n"; + + foreach (['provider', 'client_id', 'client_secret', 'scope'] as $sAttCode) { + $sValue = $this->oRemoteAuthentOAuth->Get($sAttCode); + $sForm .= "\n"; + } + $sForm .= "\n"; + + $sForm .= "
\n"; + $oPage->add($sForm); + } +} \ No newline at end of file diff --git a/datamodels/2.x/itop-remote-authent-oauth/templates/legacy/CreateMailbox.html.twig b/datamodels/2.x/itop-remote-authent-oauth/templates/legacy/CreateMailbox.html.twig new file mode 100644 index 000000000..578bce7b0 --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/templates/legacy/CreateMailbox.html.twig @@ -0,0 +1,3 @@ +{# @copyright Copyright (C) 2010-2022 Combodo SARL #} +{# @license http://opensource.org/licenses/AGPL-3.0 #} + diff --git a/datamodels/2.x/itop-remote-authent-oauth/templates/legacy/CreateMailbox.ready.js.twig b/datamodels/2.x/itop-remote-authent-oauth/templates/legacy/CreateMailbox.ready.js.twig new file mode 100644 index 000000000..8b3d10330 --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/templates/legacy/CreateMailbox.ready.js.twig @@ -0,0 +1,4 @@ +{# @copyright Copyright (C) 2010-2022 Combodo SARL #} +{# @license http://opensource.org/licenses/AGPL-3.0 #} + +window.location.href = '{{ sURL|raw }}' \ No newline at end of file diff --git a/datamodels/2.x/itop-remote-authent-oauth/vendor/autoload.php b/datamodels/2.x/itop-remote-authent-oauth/vendor/autoload.php new file mode 100644 index 000000000..d7cdc470f --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/vendor/autoload.php @@ -0,0 +1,7 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + /** @var ?string */ + private $vendorDir; + + // PSR-4 + /** + * @var array[] + * @psalm-var array> + */ + private $prefixLengthsPsr4 = array(); + /** + * @var array[] + * @psalm-var array> + */ + private $prefixDirsPsr4 = array(); + /** + * @var array[] + * @psalm-var array + */ + private $fallbackDirsPsr4 = array(); + + // PSR-0 + /** + * @var array[] + * @psalm-var array> + */ + private $prefixesPsr0 = array(); + /** + * @var array[] + * @psalm-var array + */ + private $fallbackDirsPsr0 = array(); + + /** @var bool */ + private $useIncludePath = false; + + /** + * @var string[] + * @psalm-var array + */ + private $classMap = array(); + + /** @var bool */ + private $classMapAuthoritative = false; + + /** + * @var bool[] + * @psalm-var array + */ + private $missingClasses = array(); + + /** @var ?string */ + private $apcuPrefix; + + /** + * @var self[] + */ + private static $registeredLoaders = array(); + + /** + * @param ?string $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + } + + /** + * @return string[] + */ + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + } + + return array(); + } + + /** + * @return array[] + * @psalm-return array> + */ + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + /** + * @return array[] + * @psalm-return array + */ + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + /** + * @return array[] + * @psalm-return array + */ + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + /** + * @return string[] Array of classname => path + * @psalm-var array + */ + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param string[] $classMap Class to filename map + * @psalm-param array $classMap + * + * @return void + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param string[]|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param string[]|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param string[]|string $paths The PSR-0 base directories + * + * @return void + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param string[]|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + * + * @return void + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + * + * @return void + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + * + * @return void + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + return; + } + + if ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } + } + + /** + * Unregisters this instance as an autoloader. + * + * @return void + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return true|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + + return null; + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + /** + * Returns the currently registered loaders indexed by their corresponding vendor directories. + * + * @return self[] + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + /** + * @param string $class + * @param string $ext + * @return string|false + */ + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + * @private + */ +function includeFile($file) +{ + include $file; +} diff --git a/datamodels/2.x/itop-remote-authent-oauth/vendor/composer/LICENSE b/datamodels/2.x/itop-remote-authent-oauth/vendor/composer/LICENSE new file mode 100644 index 000000000..f27399a04 --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/datamodels/2.x/itop-remote-authent-oauth/vendor/composer/autoload_classmap.php b/datamodels/2.x/itop-remote-authent-oauth/vendor/composer/autoload_classmap.php new file mode 100644 index 000000000..540c0b846 --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/vendor/composer/autoload_classmap.php @@ -0,0 +1,15 @@ + $baseDir . '/src/Controller/AjaxRemoteAuthentOauthController.php', + 'Combodo\\iTop\\RemoteAuthentOAuth\\Controller\\RemoteAuthentOauthController' => $baseDir . '/src/Controller/RemoteAuthentOauthController.php', + 'Combodo\\iTop\\RemoteAuthentOAuth\\Service\\ApplicationObjectExtension' => $baseDir . '/src/Service/ApplicationObjectExtension.php', + 'Combodo\\iTop\\RemoteAuthentOAuth\\Service\\PopupMenuExtension' => $baseDir . '/src/Service/PopupMenuExtension.php', + 'Combodo\\iTop\\RemoteAuthentOAuth\\Service\\RemoteAuthentOAuthService' => $baseDir . '/src/Service/RemoteAuthentOAuthService.php', + 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', +); diff --git a/datamodels/2.x/itop-remote-authent-oauth/vendor/composer/autoload_namespaces.php b/datamodels/2.x/itop-remote-authent-oauth/vendor/composer/autoload_namespaces.php new file mode 100644 index 000000000..b7fc0125d --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + array($baseDir . '/src'), +); diff --git a/datamodels/2.x/itop-remote-authent-oauth/vendor/composer/autoload_real.php b/datamodels/2.x/itop-remote-authent-oauth/vendor/composer/autoload_real.php new file mode 100644 index 000000000..ad033ac9f --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/vendor/composer/autoload_real.php @@ -0,0 +1,46 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInitd52424b43ff18219f2ec935428aff074::getInitializer($loader)); + } else { + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->setClassMapAuthoritative(true); + $loader->register(true); + + return $loader; + } +} diff --git a/datamodels/2.x/itop-remote-authent-oauth/vendor/composer/autoload_static.php b/datamodels/2.x/itop-remote-authent-oauth/vendor/composer/autoload_static.php new file mode 100644 index 000000000..ef1787691 --- /dev/null +++ b/datamodels/2.x/itop-remote-authent-oauth/vendor/composer/autoload_static.php @@ -0,0 +1,41 @@ + + array ( + 'Combodo\\iTop\\RemoteAuthentOAuth\\' => 32, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'Combodo\\iTop\\RemoteAuthentOAuth\\' => + array ( + 0 => __DIR__ . '/../..' . '/src', + ), + ); + + public static $classMap = array ( + 'Combodo\\iTop\\RemoteAuthentOAuth\\Controller\\AjaxRemoteAuthentOauthController' => __DIR__ . '/../..' . '/src/Controller/AjaxRemoteAuthentOauthController.php', + 'Combodo\\iTop\\RemoteAuthentOAuth\\Controller\\RemoteAuthentOauthController' => __DIR__ . '/../..' . '/src/Controller/RemoteAuthentOauthController.php', + 'Combodo\\iTop\\RemoteAuthentOAuth\\Service\\ApplicationObjectExtension' => __DIR__ . '/../..' . '/src/Service/ApplicationObjectExtension.php', + 'Combodo\\iTop\\RemoteAuthentOAuth\\Service\\PopupMenuExtension' => __DIR__ . '/../..' . '/src/Service/PopupMenuExtension.php', + 'Combodo\\iTop\\RemoteAuthentOAuth\\Service\\RemoteAuthentOAuthService' => __DIR__ . '/../..' . '/src/Service/RemoteAuthentOAuthService.php', + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInitd52424b43ff18219f2ec935428aff074::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitd52424b43ff18219f2ec935428aff074::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInitd52424b43ff18219f2ec935428aff074::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/datamodels/2.x/itop-welcome-itil/datamodel.itop-welcome-itil.xml b/datamodels/2.x/itop-welcome-itil/datamodel.itop-welcome-itil.xml index 2e3e204d8..70534c9ad 100644 --- a/datamodels/2.x/itop-welcome-itil/datamodel.itop-welcome-itil.xml +++ b/datamodels/2.x/itop-welcome-itil/datamodel.itop-welcome-itil.xml @@ -186,10 +186,5 @@ Trigger UR_ACTION_MODIFY - - 45 - ConfigurationTools - $pages/oauth.wizard.php - diff --git a/dictionaries/cs.dictionary.itop.ui.php b/dictionaries/cs.dictionary.itop.ui.php index 7d91469f9..fa113c528 100755 --- a/dictionaries/cs.dictionary.itop.ui.php +++ b/dictionaries/cs.dictionary.itop.ui.php @@ -1595,20 +1595,3 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array( 'UI:Newsroom:DisplayMessagesFor_Provider' => 'Display messages from %1$s~~', 'UI:Newsroom:DisplayAtMost_X_Messages' => 'Display up to %1$s messages in the %2$s menu.~~', )); - - -// OAuth -Dict::Add('CS CZ', 'Czech', 'Čeština', array( - 'Menu:OAuthWizardMenu' => 'OAuth 2.0~~', - 'core/Operation:Wizard/Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Page:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Panel:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Input:ClientId:Label' => 'Client Id~~', - 'UI:OAuth:Wizard:Form:Input:ClientSecret:Label' => 'Client Secret~~', - 'UI:OAuth:Wizard:Form:Input:Scope:Label' => 'Scope~~', - 'UI:OAuth:Wizard:Form:Input:Additional:Label' => 'Additional parameters~~', - 'UI:OAuth:Wizard:Form:Input:RedirectUri:Label' => 'Redirect Uri~~', - 'UI:OAuth:Wizard:Form:Button:Submit:Label' => 'Authentication~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Title' => 'Configuration for SMTP~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Description' => 'Paste this content into your configuration file to use this OAuth connection for your outgoing emails~~', -)); \ No newline at end of file diff --git a/dictionaries/da.dictionary.itop.ui.php b/dictionaries/da.dictionary.itop.ui.php index 945a1fa12..10bc1aa4a 100644 --- a/dictionaries/da.dictionary.itop.ui.php +++ b/dictionaries/da.dictionary.itop.ui.php @@ -1584,20 +1584,3 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'UI:Newsroom:DisplayMessagesFor_Provider' => 'Display messages from %1$s~~', 'UI:Newsroom:DisplayAtMost_X_Messages' => 'Display up to %1$s messages in the %2$s menu.~~', )); - - -// OAuth -Dict::Add('DA DA', 'Danish', 'Dansk', array( - 'Menu:OAuthWizardMenu' => 'OAuth 2.0~~', - 'core/Operation:Wizard/Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Page:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Panel:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Input:ClientId:Label' => 'Client Id~~', - 'UI:OAuth:Wizard:Form:Input:ClientSecret:Label' => 'Client Secret~~', - 'UI:OAuth:Wizard:Form:Input:Scope:Label' => 'Scope~~', - 'UI:OAuth:Wizard:Form:Input:Additional:Label' => 'Additional parameters~~', - 'UI:OAuth:Wizard:Form:Input:RedirectUri:Label' => 'Redirect Uri~~', - 'UI:OAuth:Wizard:Form:Button:Submit:Label' => 'Authentication~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Title' => 'Configuration for SMTP~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Description' => 'Paste this content into your configuration file to use this OAuth connection for your outgoing emails~~', -)); \ No newline at end of file diff --git a/dictionaries/de.dictionary.itop.ui.php b/dictionaries/de.dictionary.itop.ui.php index 21193745a..95477addc 100644 --- a/dictionaries/de.dictionary.itop.ui.php +++ b/dictionaries/de.dictionary.itop.ui.php @@ -1582,20 +1582,3 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'UI:Newsroom:DisplayMessagesFor_Provider' => 'Nachrichten von %1$s anzeigen', 'UI:Newsroom:DisplayAtMost_X_Messages' => 'Zeigen Sie höchstens %1$s Beiträge im Menü (%2$s) an.', )); - - -// OAuth -Dict::Add('DE DE', 'German', 'Deutsch', array( - 'Menu:OAuthWizardMenu' => 'OAuth 2.0~~', - 'core/Operation:Wizard/Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Page:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Panel:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Input:ClientId:Label' => 'Client Id~~', - 'UI:OAuth:Wizard:Form:Input:ClientSecret:Label' => 'Client Secret~~', - 'UI:OAuth:Wizard:Form:Input:Scope:Label' => 'Scope~~', - 'UI:OAuth:Wizard:Form:Input:Additional:Label' => 'Additional parameters~~', - 'UI:OAuth:Wizard:Form:Input:RedirectUri:Label' => 'Redirect Uri~~', - 'UI:OAuth:Wizard:Form:Button:Submit:Label' => 'Authentication~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Title' => 'Configuration for SMTP~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Description' => 'Paste this content into your configuration file to use this OAuth connection for your outgoing emails~~', -)); \ No newline at end of file diff --git a/dictionaries/en.dictionary.itop.ui.php b/dictionaries/en.dictionary.itop.ui.php index b6ddfcf7f..e870ca93c 100644 --- a/dictionaries/en.dictionary.itop.ui.php +++ b/dictionaries/en.dictionary.itop.ui.php @@ -1601,20 +1601,3 @@ Dict::Add('EN US', 'English', 'English', array( 'UI:Newsroom:DisplayMessagesFor_Provider' => 'Display messages from %1$s', 'UI:Newsroom:DisplayAtMost_X_Messages' => 'Display up to %1$s messages in the %2$s menu.', )); - - -// OAuth -Dict::Add('EN US', 'English', 'English', array( - 'Menu:OAuthWizardMenu' => 'OAuth 2.0', - 'core/Operation:Wizard/Title' => 'OAuth 2.0 Configuration', - 'UI:OAuth:Wizard:Page:Title' => 'OAuth 2.0 Configuration', - 'UI:OAuth:Wizard:Form:Panel:Title' => 'OAuth 2.0 Configuration', - 'UI:OAuth:Wizard:Form:Input:ClientId:Label' => 'Client Id', - 'UI:OAuth:Wizard:Form:Input:ClientSecret:Label' => 'Client Secret', - 'UI:OAuth:Wizard:Form:Input:Scope:Label' => 'Scope', - 'UI:OAuth:Wizard:Form:Input:Additional:Label' => 'Additional parameters', - 'UI:OAuth:Wizard:Form:Input:RedirectUri:Label' => 'Redirect Uri', - 'UI:OAuth:Wizard:Form:Button:Submit:Label' => 'Authentication', - 'UI:OAuth:Wizard:ResultConf:Panel:Title' => 'Configuration for SMTP', - 'UI:OAuth:Wizard:ResultConf:Panel:Description' => 'Paste this content into your configuration file to use this OAuth connection for your outgoing emails', -)); \ No newline at end of file diff --git a/dictionaries/es_cr.dictionary.itop.ui.php b/dictionaries/es_cr.dictionary.itop.ui.php index c940bb277..47ebd9aef 100644 --- a/dictionaries/es_cr.dictionary.itop.ui.php +++ b/dictionaries/es_cr.dictionary.itop.ui.php @@ -1598,20 +1598,3 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array( 'UI:Newsroom:DisplayMessagesFor_Provider' => 'Desplegar mensajes de %1$s', 'UI:Newsroom:DisplayAtMost_X_Messages' => 'Desplegar hasta %1$s mensajes en el menú %2$s.', )); - - -// OAuth -Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array( - 'Menu:OAuthWizardMenu' => 'OAuth 2.0~~', - 'core/Operation:Wizard/Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Page:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Panel:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Input:ClientId:Label' => 'Client Id~~', - 'UI:OAuth:Wizard:Form:Input:ClientSecret:Label' => 'Client Secret~~', - 'UI:OAuth:Wizard:Form:Input:Scope:Label' => 'Scope~~', - 'UI:OAuth:Wizard:Form:Input:Additional:Label' => 'Additional parameters~~', - 'UI:OAuth:Wizard:Form:Input:RedirectUri:Label' => 'Redirect Uri~~', - 'UI:OAuth:Wizard:Form:Button:Submit:Label' => 'Authentication~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Title' => 'Configuration for SMTP~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Description' => 'Paste this content into your configuration file to use this OAuth connection for your outgoing emails~~', -)); \ No newline at end of file diff --git a/dictionaries/fr.dictionary.itop.ui.php b/dictionaries/fr.dictionary.itop.ui.php index c39162895..11f8cbaf1 100644 --- a/dictionaries/fr.dictionary.itop.ui.php +++ b/dictionaries/fr.dictionary.itop.ui.php @@ -1581,20 +1581,3 @@ Dict::Add('FR FR', 'French', 'Français', array( 'UI:Newsroom:DisplayMessagesFor_Provider' => 'Afficher les messages de %1$s', 'UI:Newsroom:DisplayAtMost_X_Messages' => 'Afficher au plus %1$s messages dans le menu %2$s.', )); - - -// OAuth -Dict::Add('FR FR', 'French', 'Français', array( - 'Menu:OAuthWizardMenu' => 'OAuth 2.0~~', - 'core/Operation:Wizard/Title' => 'Configuration OAuth 2.0', - 'UI:OAuth:Wizard:Page:Title' => 'Configuration OAuth 2.0', - 'UI:OAuth:Wizard:Form:Panel:Title' => 'Configuration OAuth 2.0', - 'UI:OAuth:Wizard:Form:Input:ClientId:Label' => 'Id client', - 'UI:OAuth:Wizard:Form:Input:ClientSecret:Label' => 'Secret client', - 'UI:OAuth:Wizard:Form:Input:Scope:Label' => 'Scope', - 'UI:OAuth:Wizard:Form:Input:Additional:Label' => 'Paramètres additionnels', - 'UI:OAuth:Wizard:Form:Input:RedirectUri:Label' => 'URI de redirection', - 'UI:OAuth:Wizard:Form:Button:Submit:Label' => 'Authentification', - 'UI:OAuth:Wizard:ResultConf:Panel:Title' => 'Configuration pour SMTP', - 'UI:OAuth:Wizard:ResultConf:Panel:Description' => 'Copier ces lignes dans la configuration pour utiliser cette connexion OAyth 2.0 pour les mails sortants', -)); \ No newline at end of file diff --git a/dictionaries/hu.dictionary.itop.ui.php b/dictionaries/hu.dictionary.itop.ui.php index 8c8d2d0a6..8434f2921 100755 --- a/dictionaries/hu.dictionary.itop.ui.php +++ b/dictionaries/hu.dictionary.itop.ui.php @@ -1581,20 +1581,3 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array( 'UI:Newsroom:DisplayMessagesFor_Provider' => 'Display messages from %1$s~~', 'UI:Newsroom:DisplayAtMost_X_Messages' => 'Display up to %1$s messages in the %2$s menu.~~', )); - - -// OAuth -Dict::Add('HU HU', 'Hungarian', 'Magyar', array( - 'Menu:OAuthWizardMenu' => 'OAuth 2.0~~', - 'core/Operation:Wizard/Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Page:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Panel:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Input:ClientId:Label' => 'Client Id~~', - 'UI:OAuth:Wizard:Form:Input:ClientSecret:Label' => 'Client Secret~~', - 'UI:OAuth:Wizard:Form:Input:Scope:Label' => 'Scope~~', - 'UI:OAuth:Wizard:Form:Input:Additional:Label' => 'Additional parameters~~', - 'UI:OAuth:Wizard:Form:Input:RedirectUri:Label' => 'Redirect Uri~~', - 'UI:OAuth:Wizard:Form:Button:Submit:Label' => 'Authentication~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Title' => 'Configuration for SMTP~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Description' => 'Paste this content into your configuration file to use this OAuth connection for your outgoing emails~~', -)); \ No newline at end of file diff --git a/dictionaries/it.dictionary.itop.ui.php b/dictionaries/it.dictionary.itop.ui.php index 010995b19..94c15a1f8 100644 --- a/dictionaries/it.dictionary.itop.ui.php +++ b/dictionaries/it.dictionary.itop.ui.php @@ -1596,20 +1596,3 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array( 'UI:Newsroom:DisplayMessagesFor_Provider' => 'Display messages from %1$s~~', 'UI:Newsroom:DisplayAtMost_X_Messages' => 'Display up to %1$s messages in the %2$s menu.~~', )); - - -// OAuth -Dict::Add('IT IT', 'Italian', 'Italiano', array( - 'Menu:OAuthWizardMenu' => 'OAuth 2.0~~', - 'core/Operation:Wizard/Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Page:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Panel:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Input:ClientId:Label' => 'Client Id~~', - 'UI:OAuth:Wizard:Form:Input:ClientSecret:Label' => 'Client Secret~~', - 'UI:OAuth:Wizard:Form:Input:Scope:Label' => 'Scope~~', - 'UI:OAuth:Wizard:Form:Input:Additional:Label' => 'Additional parameters~~', - 'UI:OAuth:Wizard:Form:Input:RedirectUri:Label' => 'Redirect Uri~~', - 'UI:OAuth:Wizard:Form:Button:Submit:Label' => 'Authentication~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Title' => 'Configuration for SMTP~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Description' => 'Paste this content into your configuration file to use this OAuth connection for your outgoing emails~~', -)); \ No newline at end of file diff --git a/dictionaries/ja.dictionary.itop.ui.php b/dictionaries/ja.dictionary.itop.ui.php index ec58e1697..8f3ad8e22 100644 --- a/dictionaries/ja.dictionary.itop.ui.php +++ b/dictionaries/ja.dictionary.itop.ui.php @@ -1582,20 +1582,3 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'UI:Newsroom:DisplayMessagesFor_Provider' => 'Display messages from %1$s~~', 'UI:Newsroom:DisplayAtMost_X_Messages' => 'Display up to %1$s messages in the %2$s menu.~~', )); - - -// OAuth -Dict::Add('JA JP', 'Japanese', '日本語', array( - 'Menu:OAuthWizardMenu' => 'OAuth 2.0~~', - 'core/Operation:Wizard/Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Page:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Panel:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Input:ClientId:Label' => 'Client Id~~', - 'UI:OAuth:Wizard:Form:Input:ClientSecret:Label' => 'Client Secret~~', - 'UI:OAuth:Wizard:Form:Input:Scope:Label' => 'Scope~~', - 'UI:OAuth:Wizard:Form:Input:Additional:Label' => 'Additional parameters~~', - 'UI:OAuth:Wizard:Form:Input:RedirectUri:Label' => 'Redirect Uri~~', - 'UI:OAuth:Wizard:Form:Button:Submit:Label' => 'Authentication~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Title' => 'Configuration for SMTP~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Description' => 'Paste this content into your configuration file to use this OAuth connection for your outgoing emails~~', -)); \ No newline at end of file diff --git a/dictionaries/nl.dictionary.itop.ui.php b/dictionaries/nl.dictionary.itop.ui.php index 011056ed1..94840979a 100644 --- a/dictionaries/nl.dictionary.itop.ui.php +++ b/dictionaries/nl.dictionary.itop.ui.php @@ -1604,20 +1604,3 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', array( 'UI:Newsroom:DisplayMessagesFor_Provider' => 'Bekijk berichten van %1$s', 'UI:Newsroom:DisplayAtMost_X_Messages' => 'Toon maximaal %1$s berichten in het %2$s menu.', )); - - -// OAuth -Dict::Add('NL NL', 'Dutch', 'Nederlands', array( - 'Menu:OAuthWizardMenu' => 'OAuth 2.0~~', - 'core/Operation:Wizard/Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Page:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Panel:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Input:ClientId:Label' => 'Client Id~~', - 'UI:OAuth:Wizard:Form:Input:ClientSecret:Label' => 'Client Secret~~', - 'UI:OAuth:Wizard:Form:Input:Scope:Label' => 'Scope~~', - 'UI:OAuth:Wizard:Form:Input:Additional:Label' => 'Additional parameters~~', - 'UI:OAuth:Wizard:Form:Input:RedirectUri:Label' => 'Redirect Uri~~', - 'UI:OAuth:Wizard:Form:Button:Submit:Label' => 'Authentication~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Title' => 'Configuration for SMTP~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Description' => 'Paste this content into your configuration file to use this OAuth connection for your outgoing emails~~', -)); \ No newline at end of file diff --git a/dictionaries/pt_br.dictionary.itop.ui.php b/dictionaries/pt_br.dictionary.itop.ui.php index 6a51d4410..600ca2752 100644 --- a/dictionaries/pt_br.dictionary.itop.ui.php +++ b/dictionaries/pt_br.dictionary.itop.ui.php @@ -1595,20 +1595,3 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', array( 'UI:Newsroom:DisplayMessagesFor_Provider' => 'Mostrar mensagens de %1$s', 'UI:Newsroom:DisplayAtMost_X_Messages' => 'Exibir até %1$s mensagens no menu %2$s.', )); - - -// OAuth -Dict::Add('PT BR', 'Brazilian', 'Brazilian', array( - 'Menu:OAuthWizardMenu' => 'OAuth 2.0~~', - 'core/Operation:Wizard/Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Page:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Panel:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Input:ClientId:Label' => 'Client Id~~', - 'UI:OAuth:Wizard:Form:Input:ClientSecret:Label' => 'Client Secret~~', - 'UI:OAuth:Wizard:Form:Input:Scope:Label' => 'Scope~~', - 'UI:OAuth:Wizard:Form:Input:Additional:Label' => 'Additional parameters~~', - 'UI:OAuth:Wizard:Form:Input:RedirectUri:Label' => 'Redirect Uri~~', - 'UI:OAuth:Wizard:Form:Button:Submit:Label' => 'Authentication~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Title' => 'Configuration for SMTP~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Description' => 'Paste this content into your configuration file to use this OAuth connection for your outgoing emails~~', -)); \ No newline at end of file diff --git a/dictionaries/ru.dictionary.itop.ui.php b/dictionaries/ru.dictionary.itop.ui.php index c2b968113..235232902 100644 --- a/dictionaries/ru.dictionary.itop.ui.php +++ b/dictionaries/ru.dictionary.itop.ui.php @@ -1573,20 +1573,3 @@ Dict::Add('RU RU', 'Russian', 'Русский', array( 'UI:Newsroom:DisplayMessagesFor_Provider' => 'Показать сообщения от %1$s', 'UI:Newsroom:DisplayAtMost_X_Messages' => 'Отобразите не более %1$s сообщений в меню %2$s.', )); - - -// OAuth -Dict::Add('RU RU', 'Russian', 'Русский', array( - 'Menu:OAuthWizardMenu' => 'OAuth 2.0~~', - 'core/Operation:Wizard/Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Page:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Panel:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Input:ClientId:Label' => 'Client Id~~', - 'UI:OAuth:Wizard:Form:Input:ClientSecret:Label' => 'Client Secret~~', - 'UI:OAuth:Wizard:Form:Input:Scope:Label' => 'Scope~~', - 'UI:OAuth:Wizard:Form:Input:Additional:Label' => 'Additional parameters~~', - 'UI:OAuth:Wizard:Form:Input:RedirectUri:Label' => 'Redirect Uri~~', - 'UI:OAuth:Wizard:Form:Button:Submit:Label' => 'Authentication~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Title' => 'Configuration for SMTP~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Description' => 'Paste this content into your configuration file to use this OAuth connection for your outgoing emails~~', -)); \ No newline at end of file diff --git a/dictionaries/sk.dictionary.itop.ui.php b/dictionaries/sk.dictionary.itop.ui.php index 854232778..3574a85d4 100644 --- a/dictionaries/sk.dictionary.itop.ui.php +++ b/dictionaries/sk.dictionary.itop.ui.php @@ -1584,20 +1584,3 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'UI:Newsroom:DisplayMessagesFor_Provider' => 'Display messages from %1$s~~', 'UI:Newsroom:DisplayAtMost_X_Messages' => 'Display up to %1$s messages in the %2$s menu.~~', )); - - -// OAuth -Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( - 'Menu:OAuthWizardMenu' => 'OAuth 2.0~~', - 'core/Operation:Wizard/Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Page:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Panel:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Input:ClientId:Label' => 'Client Id~~', - 'UI:OAuth:Wizard:Form:Input:ClientSecret:Label' => 'Client Secret~~', - 'UI:OAuth:Wizard:Form:Input:Scope:Label' => 'Scope~~', - 'UI:OAuth:Wizard:Form:Input:Additional:Label' => 'Additional parameters~~', - 'UI:OAuth:Wizard:Form:Input:RedirectUri:Label' => 'Redirect Uri~~', - 'UI:OAuth:Wizard:Form:Button:Submit:Label' => 'Authentication~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Title' => 'Configuration for SMTP~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Description' => 'Paste this content into your configuration file to use this OAuth connection for your outgoing emails~~', -)); \ No newline at end of file diff --git a/dictionaries/tr.dictionary.itop.ui.php b/dictionaries/tr.dictionary.itop.ui.php index 32a7015d3..74e9180fa 100644 --- a/dictionaries/tr.dictionary.itop.ui.php +++ b/dictionaries/tr.dictionary.itop.ui.php @@ -1596,20 +1596,3 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array( 'UI:Newsroom:DisplayMessagesFor_Provider' => 'Display messages from %1$s~~', 'UI:Newsroom:DisplayAtMost_X_Messages' => 'Display up to %1$s messages in the %2$s menu.~~', )); - - -// OAuth -Dict::Add('TR TR', 'Turkish', 'Türkçe', array( - 'Menu:OAuthWizardMenu' => 'OAuth 2.0~~', - 'core/Operation:Wizard/Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Page:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Panel:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Input:ClientId:Label' => 'Client Id~~', - 'UI:OAuth:Wizard:Form:Input:ClientSecret:Label' => 'Client Secret~~', - 'UI:OAuth:Wizard:Form:Input:Scope:Label' => 'Scope~~', - 'UI:OAuth:Wizard:Form:Input:Additional:Label' => 'Additional parameters~~', - 'UI:OAuth:Wizard:Form:Input:RedirectUri:Label' => 'Redirect Uri~~', - 'UI:OAuth:Wizard:Form:Button:Submit:Label' => 'Authentication~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Title' => 'Configuration for SMTP~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Description' => 'Paste this content into your configuration file to use this OAuth connection for your outgoing emails~~', -)); \ No newline at end of file diff --git a/dictionaries/zh_cn.dictionary.itop.ui.php b/dictionaries/zh_cn.dictionary.itop.ui.php index fc2cbd798..075197f89 100644 --- a/dictionaries/zh_cn.dictionary.itop.ui.php +++ b/dictionaries/zh_cn.dictionary.itop.ui.php @@ -1595,20 +1595,3 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array( 'UI:Newsroom:DisplayMessagesFor_Provider' => '显示来自 %1$s 的消息', 'UI:Newsroom:DisplayAtMost_X_Messages' => '在 %2$s 菜单中最多显示 %1$s 条消息.', )); - - -// OAuth -Dict::Add('ZH CN', 'Chinese', '简体中文', array( - 'Menu:OAuthWizardMenu' => 'OAuth 2.0~~', - 'core/Operation:Wizard/Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Page:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Panel:Title' => 'OAuth 2.0 Configuration~~', - 'UI:OAuth:Wizard:Form:Input:ClientId:Label' => 'Client Id~~', - 'UI:OAuth:Wizard:Form:Input:ClientSecret:Label' => 'Client Secret~~', - 'UI:OAuth:Wizard:Form:Input:Scope:Label' => 'Scope~~', - 'UI:OAuth:Wizard:Form:Input:Additional:Label' => 'Additional parameters~~', - 'UI:OAuth:Wizard:Form:Input:RedirectUri:Label' => 'Redirect Uri~~', - 'UI:OAuth:Wizard:Form:Button:Submit:Label' => 'Authentication~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Title' => 'Configuration for SMTP~~', - 'UI:OAuth:Wizard:ResultConf:Panel:Description' => 'Paste this content into your configuration file to use this OAuth connection for your outgoing emails~~', -)); \ No newline at end of file diff --git a/lib/autoload.php b/lib/autoload.php index 64168f99a..79c1600b5 100644 --- a/lib/autoload.php +++ b/lib/autoload.php @@ -2,11 +2,6 @@ // autoload.php @generated by Composer -if (PHP_VERSION_ID < 50600) { - echo 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL; - exit(1); -} - require_once __DIR__ . '/composer/autoload_real.php'; return ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b::getLoader(); diff --git a/lib/composer/ClassLoader.php b/lib/composer/ClassLoader.php index afef3fa2a..0cd6055d1 100644 --- a/lib/composer/ClassLoader.php +++ b/lib/composer/ClassLoader.php @@ -149,7 +149,7 @@ class ClassLoader /** * @return string[] Array of classname => path - * @psalm-return array + * @psalm-var array */ public function getClassMap() { diff --git a/lib/composer/autoload_classmap.php b/lib/composer/autoload_classmap.php index 704d9f730..c63cfe237 100644 --- a/lib/composer/autoload_classmap.php +++ b/lib/composer/autoload_classmap.php @@ -2,7 +2,7 @@ // autoload_classmap.php @generated by Composer -$vendorDir = dirname(__DIR__); +$vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( diff --git a/lib/composer/autoload_files.php b/lib/composer/autoload_files.php index ae02e5199..7be757bea 100644 --- a/lib/composer/autoload_files.php +++ b/lib/composer/autoload_files.php @@ -2,25 +2,25 @@ // autoload_files.php @generated by Composer -$vendorDir = dirname(__DIR__); +$vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', '5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php', '023d27dca8066ef29e6739335ea73bad' => $vendorDir . '/symfony/polyfill-php70/bootstrap.php', - '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', + '32dcc8afd4335739640db7d200c1971d' => $vendorDir . '/symfony/polyfill-apcu/bootstrap.php', + '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', + 'bd9634f2d41831496de0d3dfe4c94881' => $vendorDir . '/symfony/polyfill-php56/bootstrap.php', '7e9bd612cc444b3eed788ebbe46263a0' => $vendorDir . '/laminas/laminas-zendframework-bridge/src/autoload.php', 'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php', '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php', 'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php', '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', - 'bd9634f2d41831496de0d3dfe4c94881' => $vendorDir . '/symfony/polyfill-php56/bootstrap.php', 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', - '32dcc8afd4335739640db7d200c1971d' => $vendorDir . '/symfony/polyfill-apcu/bootstrap.php', 'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php', - '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', '2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php', ); diff --git a/lib/composer/autoload_namespaces.php b/lib/composer/autoload_namespaces.php index e6117c750..d12922d08 100644 --- a/lib/composer/autoload_namespaces.php +++ b/lib/composer/autoload_namespaces.php @@ -2,7 +2,7 @@ // autoload_namespaces.php @generated by Composer -$vendorDir = dirname(__DIR__); +$vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( diff --git a/lib/composer/autoload_psr4.php b/lib/composer/autoload_psr4.php index 651c9f0c1..ca8b4b9f6 100644 --- a/lib/composer/autoload_psr4.php +++ b/lib/composer/autoload_psr4.php @@ -2,7 +2,7 @@ // autoload_psr4.php @generated by Composer -$vendorDir = dirname(__DIR__); +$vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( diff --git a/lib/composer/autoload_real.php b/lib/composer/autoload_real.php index 752e35fbd..661cd2543 100644 --- a/lib/composer/autoload_real.php +++ b/lib/composer/autoload_real.php @@ -25,20 +25,33 @@ class ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b require __DIR__ . '/platform_check.php'; spl_autoload_register(array('ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b', 'loadClassLoader'), true, true); - self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__))); spl_autoload_unregister(array('ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b', 'loadClassLoader')); $includePaths = require __DIR__ . '/include_paths.php'; $includePaths[] = get_include_path(); set_include_path(implode(PATH_SEPARATOR, $includePaths)); - require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit0018331147de7601e7552f7da8e3bb8b::getInitializer($loader)); + $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit0018331147de7601e7552f7da8e3bb8b::getInitializer($loader)); + } else { + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } $loader->setClassMapAuthoritative(true); $loader->register(true); - $includeFiles = \Composer\Autoload\ComposerStaticInit0018331147de7601e7552f7da8e3bb8b::$files; + if ($useStaticLoader) { + $includeFiles = Composer\Autoload\ComposerStaticInit0018331147de7601e7552f7da8e3bb8b::$files; + } else { + $includeFiles = require __DIR__ . '/autoload_files.php'; + } foreach ($includeFiles as $fileIdentifier => $file) { composerRequire0018331147de7601e7552f7da8e3bb8b($fileIdentifier, $file); } @@ -47,16 +60,11 @@ class ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b } } -/** - * @param string $fileIdentifier - * @param string $file - * @return void - */ function composerRequire0018331147de7601e7552f7da8e3bb8b($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - require $file; + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; } } diff --git a/lib/composer/autoload_static.php b/lib/composer/autoload_static.php index 021b67052..2b50f81a9 100644 --- a/lib/composer/autoload_static.php +++ b/lib/composer/autoload_static.php @@ -8,21 +8,21 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b { public static $files = array ( '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', '5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php', '023d27dca8066ef29e6739335ea73bad' => __DIR__ . '/..' . '/symfony/polyfill-php70/bootstrap.php', - '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', + '32dcc8afd4335739640db7d200c1971d' => __DIR__ . '/..' . '/symfony/polyfill-apcu/bootstrap.php', + '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php', + 'bd9634f2d41831496de0d3dfe4c94881' => __DIR__ . '/..' . '/symfony/polyfill-php56/bootstrap.php', '7e9bd612cc444b3eed788ebbe46263a0' => __DIR__ . '/..' . '/laminas/laminas-zendframework-bridge/src/autoload.php', 'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php', '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', 'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php', '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', - 'bd9634f2d41831496de0d3dfe4c94881' => __DIR__ . '/..' . '/symfony/polyfill-php56/bootstrap.php', 'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', - '32dcc8afd4335739640db7d200c1971d' => __DIR__ . '/..' . '/symfony/polyfill-apcu/bootstrap.php', 'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php', - '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php', '2c102faa651ef8ea5874edb585946bce' => __DIR__ . '/..' . '/swiftmailer/swiftmailer/lib/swift_required.php', ); diff --git a/lib/composer/include_paths.php b/lib/composer/include_paths.php index af33c1491..d4fb96718 100644 --- a/lib/composer/include_paths.php +++ b/lib/composer/include_paths.php @@ -2,7 +2,7 @@ // include_paths.php @generated by Composer -$vendorDir = dirname(__DIR__); +$vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( diff --git a/pages/ajax.oauth.wizard.php b/pages/ajax.oauth.wizard.php deleted file mode 100644 index 7a753a320..000000000 --- a/pages/ajax.oauth.wizard.php +++ /dev/null @@ -1,13 +0,0 @@ -AllowOnlyAdmin(); -$oUpdateController->SetDefaultOperation('Default'); -$oUpdateController->HandleOperation(); diff --git a/pages/oauth.wizard.php b/pages/oauth.wizard.php deleted file mode 100644 index 507e6a401..000000000 --- a/pages/oauth.wizard.php +++ /dev/null @@ -1,14 +0,0 @@ -AllowOnlyAdmin(); -$oUpdateController->SetDefaultOperation('Wizard'); -$oUpdateController->HandleOperation(); - diff --git a/setup/email.test.php b/setup/email.test.php index d435fccea..b6e31eec1 100644 --- a/setup/email.test.php +++ b/setup/email.test.php @@ -20,6 +20,9 @@ /** * Wizard to configure and initialize the iTop application */ + +use Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory; + require_once('../approot.inc.php'); require_once(APPROOT.'/application/utils.inc.php'); require_once(APPROOT.'/core/email.class.inc.php'); @@ -133,13 +136,19 @@ function CheckEmailSetting($oP) $sDisplayEncryption = empty($sEncryption) ? 'no encryption ' : $sEncryption; $sUserName = MetaModel::GetConfig()->Get('email_transport_smtp.username'); $sDisplayUserName = empty($sUserName) ? 'no user ' : $sUserName; - $sProvider = MetaModel::GetConfig()->Get('email_transport_smtp.oauth.provider'); - $sDisplayProvider = empty($sProvider) ? 'no Provider ' : $sProvider; - $sClientID = MetaModel::GetConfig()->Get('email_transport_smtp.oauth.client_id'); - $sDisplayClientID = empty($sClientID) ? 'no password ' : $sClientID; - $oP->info("SMTP configuration (from config-itop.php): host: $sHost, port: $sPort, provider: $sDisplayProvider, user: $sDisplayUserName, client id: $sDisplayClientID, encryption: $sDisplayEncryption."); - if (($sHost == 'localhost') && ($sPort == '25') && ($sUserName == '') && ($sClientID == '') && ($sProvider == '')) { - $oP->warning("The default settings may not be suitable for your environment. You may want to adjust these values by editing iTop's configuration file (".utils::GetConfigFilePathRelative().').'); + try { + $oRemoteAuthentOAuth = OAuthClientProviderFactory::GetRemoteAuthentOAuthForSMTP(); + $sProvider = $oRemoteAuthentOAuth->Get('provider'); + $sDisplayProvider = empty($sProvider) ? 'no Provider ' : $sProvider; + $sClientID = $oRemoteAuthentOAuth->Get('client_id'); + $sDisplayClientID = empty($sClientID) ? 'no password ' : $sClientID; + $oP->info("SMTP configuration (from config-itop.php): host: $sHost, port: $sPort, provider: $sDisplayProvider, user: $sDisplayUserName, client id: $sDisplayClientID, encryption: $sDisplayEncryption."); + if (($sHost == 'localhost') && ($sPort == '25') && ($sUserName == '') && ($sClientID == '') && ($sProvider == '')) { + $oP->warning("The default settings may not be suitable for your environment. You may want to adjust these values by editing iTop's configuration file (".utils::GetConfigFilePathRelative().').'); + } + } catch (CoreException $e) { + $bRet = false; + $oP->error($e->getMessage()); } break; @@ -194,9 +203,10 @@ function DisplayStep1(SetupPage $oP) 'input' => "", 'help' => ' email address (e.g. john.foo@worldcompany.com)', ); + $sDefaultFrom = MetaModel::GetConfig()->Get('email_transport_smtp.username'); $aForm[] = array( 'label' => "From:", - 'input' => "", + 'input' => "", 'help' => ' defaults to the configuration param "email_default_sender_address" or "To" field.', ); $oP->form($aForm); @@ -298,4 +308,4 @@ catch(CoreException $e) $oP->error("Error: '".$e->getHtmlDesc()."'"); } $oP->output(); -?> + diff --git a/sources/Controller/OAuth/OAuthAjaxController.php b/sources/Controller/OAuth/OAuthAjaxController.php deleted file mode 100644 index 155cdd9bc..000000000 --- a/sources/Controller/OAuth/OAuthAjaxController.php +++ /dev/null @@ -1,62 +0,0 @@ - 'success', 'data' => []]; - $sProvider = utils::ReadParam('provider', '', false, 'raw'); - $sClientId = utils::ReadParam('client_id', '', false, 'raw'); - $sClientSecret = utils::ReadParam('client_secret', '', false, 'raw'); - $sScope = utils::ReadParam('scope', '', false, 'raw'); - $sAdditional = utils::ReadParam('additional', '', false, 'raw'); - $aAdditional = []; - parse_str($sAdditional, $aAdditional); - $sAuthorizationUrl = OAuthClientProviderFactory::getVendorProviderForAccessUrl($sProvider, $sClientId, $sClientSecret, $sScope, $aAdditional); - $aResult['data']['authorization_url'] = $sAuthorizationUrl; - - $this->DisplayJSONPage($aResult); - } - - public function OperationGetDisplayAuthenticationResults() - { - $aResult = ['status' => 'success', 'data' => []]; - $sProvider = utils::ReadParam('provider', '', false, 'raw'); - $sRedirectUrl = utils::ReadParam('redirect_url', '', false, 'raw'); - $sClientId = utils::ReadParam('client_id', '', false, 'raw'); - $sClientSecret = utils::ReadParam('client_secret', '', false, 'raw'); - $sScope = utils::ReadParam('scope', '', false, 'raw'); - $sAdditional = utils::ReadParam('additional', '', false, 'raw'); - - $sRedirectUrlQuery = parse_url($sRedirectUrl)['query']; - - $aOAuthResultDisplayClasses[] = '\Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientResultDisplayConf'; - if (class_exists('Combodo\iTop\Extension\Service\OAuthClientResultDisplayMailbox')) { - $aOAuthResultDisplayClasses[] = 'Combodo\iTop\Extension\Service\OAuthClientResultDisplayMailbox'; - } - - $aAdditional = []; - parse_str($sAdditional, $aAdditional); - - // $sProviderClass = "\Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProvider".$sProvider; - // $sRedirectUrl = OAuthClientProviderAbstract::GetRedirectUri(); - - $aQuery = []; - parse_str($sRedirectUrlQuery, $aQuery); - $sCode = $aQuery['code']; - $oProvider = OAuthClientProviderFactory::getVendorProvider($sProvider, $sClientId, $sClientSecret, $sScope, $aAdditional); - $oAccessToken = OAuthClientProviderFactory::getAccessTokenFromCode($oProvider, $sCode); - - foreach ($aOAuthResultDisplayClasses as $sOAuthClass) { - $aResult['data'][] = $sOAuthClass::GetResultDisplayScript($sClientId, $sClientSecret, $sProvider, $oAccessToken); - } - - $this->DisplayJSONPage($aResult); - } -} \ No newline at end of file diff --git a/sources/Controller/OAuth/OAuthWizardController.php b/sources/Controller/OAuth/OAuthWizardController.php deleted file mode 100644 index 25265ea6b..000000000 --- a/sources/Controller/OAuth/OAuthWizardController.php +++ /dev/null @@ -1,68 +0,0 @@ -AddLinkedScript(utils::GetAbsoluteUrlAppRoot().'/js/pages/backoffice/oauth.wizard.js'); - - $aOAuthClasses = [ - 'Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderAzure', - 'Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderGoogle', - ]; - - foreach ($aOAuthClasses as $sOAuthClass) { - $aParams['aProviders'][] = [ - 'name' => $sOAuthClass::GetVendorName(), - 'icon' => $sOAuthClass::GetVendorIcon(), - 'colors' => $sOAuthClass::GetVendorColors(), - ]; - } - - $aParams['aInputs'] = [ - 'client_id' => ['type' => 'text', 'label' => Dict::S('UI:OAuth:Wizard:Form:Input:ClientId:Label'), 'read_only' => false, 'value' => ''], - 'client_secret' => ['type' => 'text', 'label' => Dict::S('UI:OAuth:Wizard:Form:Input:ClientSecret:Label'), 'read_only' => false, 'value' => ''], - 'scope' => ['type' => 'text', 'label' => Dict::S('UI:OAuth:Wizard:Form:Input:Scope:Label'), 'read_only' => false, 'value' => ''], - 'additional' => ['type' => 'text', 'label' => Dict::S('UI:OAuth:Wizard:Form:Input:Additional:Label'), 'read_only' => false, 'value' => ''], - 'redirect_uri' => ['type' => 'text', 'label' => Dict::S('UI:OAuth:Wizard:Form:Input:RedirectUri:Label'), 'read_only' => true, 'value' => OAuthClientProviderAbstract::GetRedirectUri()], - ]; - - // TODO: Needs to handle mail to ticket part too - $aParams['aAdditionalBlocks'][] = OAuthClientResultDisplayConf::GetResultDisplayTemplate(); - if (class_exists('Combodo\iTop\Extension\Service\OAuthClientResultDisplayMailbox')) { - $aParams['aAdditionalBlocks'][] = OAuthClientResultDisplayMailbox::GetResultDisplayTemplate(); - } - - $this->DisplayPage($aParams); - } -} \ No newline at end of file diff --git a/sources/Core/Authentication/Client/OAuth/OAuthClientProviderAzure.php b/sources/Core/Authentication/Client/OAuth/OAuthClientProviderAzure.php index cbf298377..6ba981917 100644 --- a/sources/Core/Authentication/Client/OAuth/OAuthClientProviderAzure.php +++ b/sources/Core/Authentication/Client/OAuth/OAuthClientProviderAzure.php @@ -16,8 +16,7 @@ class OAuthClientProviderAzure extends OAuthClientProviderAbstract static protected $sRequiredSMTPScope = 'https://outlook.office.com/SMTP.Send offline_access'; static protected $sRequiredIMAPScope = 'https://outlook.office.com/IMAP.AccessAsUser.All offline_access'; static protected $sRequiredPOPScope = 'https://outlook.office.com/POP.AccessAsUser.All offline access'; - /** @var \League\OAuth2\Client\Provider\GenericProvider */ - protected $oVendorProvider; + /** @var \League\OAuth2\Client\Token\AccessToken */ protected $oAccessToken; diff --git a/sources/Core/Authentication/Client/OAuth/OAuthClientProviderFactory.php b/sources/Core/Authentication/Client/OAuth/OAuthClientProviderFactory.php index d484b26ba..e42d8c31e 100644 --- a/sources/Core/Authentication/Client/OAuth/OAuthClientProviderFactory.php +++ b/sources/Core/Authentication/Client/OAuth/OAuthClientProviderFactory.php @@ -3,6 +3,8 @@ namespace Combodo\iTop\Core\Authentication\Client\OAuth; use CoreException; +use DBObjectSet; +use DBSearch; use Dict; use GuzzleHttp\Client; use League\OAuth2\Client\Token\AccessTokenInterface; @@ -16,17 +18,19 @@ class OAuthClientProviderFactory */ public static function getProviderForSMTP() { - $sProviderVendor = MetaModel::GetConfig()->Get('email_transport_smtp.oauth.provider'); // email_transport_smtp.oauth.provider + $oRemoteAuthentOAuth = self::GetRemoteAuthentOAuthForSMTP(); + + $sProviderVendor = $oRemoteAuthentOAuth->Get('provider'); $sProviderClass = self::getProviderClass($sProviderVendor); $aProviderVendorParams = [ - 'clientId' => MetaModel::GetConfig()->Get('email_transport_smtp.oauth.client_id'), // email_transport_smtp.oauth.client_id - 'clientSecret' => MetaModel::GetConfig()->Get('email_transport_smtp.oauth.client_secret'),// email_transport_smtp.oauth.client_secret + 'clientId' => $oRemoteAuthentOAuth->Get('client_id'), + 'clientSecret' => $oRemoteAuthentOAuth->Get('client_secret'), 'redirectUri' => $sProviderClass::GetRedirectUri(), 'scope' => $sProviderClass::GetRequiredSMTPScope(), ]; $aAccessTokenParams = [ - "access_token" => MetaModel::GetConfig()->Get('email_transport_smtp.oauth.access_token'), // email_transport_smtp.oauth.access_token - "refresh_token" => MetaModel::GetConfig()->Get('email_transport_smtp.oauth.refresh_token'), // email_transport_smtp.oauth.refresh_token + "access_token" => $oRemoteAuthentOAuth->Get('token'), + "refresh_token" => $oRemoteAuthentOAuth->Get('refresh_token'), 'scope' => $sProviderClass::GetRequiredSMTPScope(), ]; $aCollaborators = [ @@ -36,6 +40,25 @@ class OAuthClientProviderFactory return new $sProviderClass($aProviderVendorParams, $aCollaborators, $aAccessTokenParams); } + /** + * @return \DBObject|null + * @throws \CoreException + * @throws \CoreUnexpectedValue + * @throws \MissingQueryArgument + * @throws \MySQLException + * @throws \MySQLHasGoneAwayException + * @throws \OQLException + */ + public static function GetRemoteAuthentOAuthForSMTP() + { + $sUsername = MetaModel::GetConfig()->Get('email_transport_smtp.username'); + $oSet = new DBObjectSet(DBSearch::FromOQL('SELECT RemoteAuthentOAuth WHERE name=:username', ['username' => $sUsername])); + if ($oSet->Count() != 1) { + throw new CoreException(Dict::Format('itop-remote-authent-oauth:MissingRemoteAuthentOAuth', $sUsername)); + } + return $oSet->Fetch(); + } + /** * @param $sProviderVendor * @param $sClientId diff --git a/sources/Core/Authentication/Client/OAuth/OAuthClientProviderGoogle.php b/sources/Core/Authentication/Client/OAuth/OAuthClientProviderGoogle.php index bd2a1e3b6..a8afe837c 100644 --- a/sources/Core/Authentication/Client/OAuth/OAuthClientProviderGoogle.php +++ b/sources/Core/Authentication/Client/OAuth/OAuthClientProviderGoogle.php @@ -13,8 +13,7 @@ class OAuthClientProviderGoogle extends OAuthClientProviderAbstract static protected $sVendorColors = ['#DB4437', '#F4B400', '#0F9D58', '#4285F4']; /** @var string */ static protected $sVendorIcon = '../images/icons/icons8-google.svg'; - /** @var \League\OAuth2\Client\Provider\GenericProvider */ - protected $oVendorProvider; + /** @var \League\OAuth2\Client\Token\AccessToken */ protected $oAccessToken; static protected $sRequiredSMTPScope = 'https://mail.google.com/'; diff --git a/sources/Core/Authentication/Client/Smtp/SmtpOAuthLogin.php b/sources/Core/Authentication/Client/Smtp/SmtpOAuthLogin.php index 1c261a5e7..d9e185e34 100644 --- a/sources/Core/Authentication/Client/Smtp/SmtpOAuthLogin.php +++ b/sources/Core/Authentication/Client/Smtp/SmtpOAuthLogin.php @@ -51,7 +51,7 @@ class Oauth extends Login * * @return void */ - public static function setProvider(OAuthClientProviderAbstract $oProvider): void + public static function setProvider(OAuthClientProviderAbstract $oProvider) { self::$oProvider = $oProvider; } @@ -73,7 +73,7 @@ class Oauth extends Login } } catch (IdentityProviderException $e) { - IssueLog::Error('Failed to get oAuth credentials for outgoing mails for provider '.self::$oProvider::GetVendorName(), static::LOG_CHANNEL); + IssueLog::Error('Failed to get oAuth credentials for outgoing mails for provider '.self::$oProvider::GetVendorName().' '.$e->getMessage(), static::LOG_CHANNEL); return false; } diff --git a/templates/pages/backoffice/oauth/DisplayConfig.html.twig b/templates/pages/backoffice/oauth/DisplayConfig.html.twig deleted file mode 100644 index 1fcf8b8b3..000000000 --- a/templates/pages/backoffice/oauth/DisplayConfig.html.twig +++ /dev/null @@ -1,8 +0,0 @@ -{# @copyright Copyright (C) 2010-2022 Combodo SARL #} -{# @license http://opensource.org/licenses/AGPL-3.0 #} - -
- {{ 'UI:OAuth:Wizard:ResultConf:Panel:Title'|dict_s }} -

{{ 'UI:OAuth:Wizard:ResultConf:Panel:Description'|dict_s }}

-
-
\ No newline at end of file diff --git a/templates/pages/backoffice/oauth/Wizard.html.twig b/templates/pages/backoffice/oauth/Wizard.html.twig deleted file mode 100644 index 0aee723b3..000000000 --- a/templates/pages/backoffice/oauth/Wizard.html.twig +++ /dev/null @@ -1,53 +0,0 @@ -{# @copyright Copyright (C) 2010-2022 Combodo SARL #} -{# @license http://opensource.org/licenses/AGPL-3.0 #} - -
-

{{ 'UI:OAuth:Wizard:Page:Title'|dict_s }}

- -
- -
-
- {% set sIsChecked = 'checked' %} - {% for aSelect in aProviders %} - - - - {% set sIsChecked = '' %} - {% endfor %} -
-
- -
- {{ 'UI:OAuth:Wizard:Form:Panel:Title'|dict_s }} -
- - {% for sName, aInput in aInputs %} -
-
-
-
- -
-
-
- {% endfor %} - -
-
-
- - {% for sTemplate in aAdditionalBlocks %} - {% include sTemplate %} - {% endfor %} - -
\ No newline at end of file diff --git a/templates/pages/backoffice/oauth/Wizard.ready.js.twig b/templates/pages/backoffice/oauth/Wizard.ready.js.twig deleted file mode 100644 index 8cc297840..000000000 --- a/templates/pages/backoffice/oauth/Wizard.ready.js.twig +++ /dev/null @@ -1,131 +0,0 @@ -// Function used to open OAuth popup -var oWindowObjectReference = null; -var sPreviousUrl = null; -var oListener = null - -const oOnOauthSuccess = function (event){ - clearInterval(oListener); - $.post( - '{{ sAjaxUri }}', - { - operation: 'GetDisplayAuthenticationResults', - provider: $('[name="provider"]:checked').val(), - client_id: $('[name="client_id"]').val(), - client_secret: $('[name="client_secret"]').val(), - scope: $(this).find('[name="scope"]').val(), - additional: $(this).find('[name="additional"]').val(), - redirect_url: event.data - }, - function(oData){ - if(oData.status == 'success') - { - oData.data.forEach(function(item, index){ - new Function(item)(); - }); - } - $('.ibo-oauth-wizard--form--submit').prop('disabled', false); - } - ); -} -const oOpenSignInWindow = function (url, name){ - // Remove any existing event listener - window.removeEventListener('message', oOnOauthSuccess); - if(oListener !== null){ - clearInterval(oListener); - } - - // Window features - const sWindowFeatures = 'toolbar=no, menubar=no, width=600, height=700, top=100, left=100'; - - if (oWindowObjectReference === null || oWindowObjectReference.closed) { - /* If the pointer to the window object in memory does not exist - or if such pointer exists but the window was closed */ - oWindowObjectReference = window.open(url, name, sWindowFeatures); - } else if (sPreviousUrl !== url) { - /* If the resource to load is different, - then we load it in the already opened secondary window, and then - we bring such window back on top/in front of its parent window. */ - oWindowObjectReference = window.open(url, name, sWindowFeatures); - oWindowObjectReference.focus(); - } else { - /* Else the window reference must exist and the window - is not closed; therefore, we can bring it back on top of any other - window with the focus() method. There would be no need to re-create - the window or to reload the referenced resource. */ - oWindowObjectReference.focus(); - } - /* Let know every second our child window that we're waiting for it to complete, - once we reach our landing page, it'll send us a reply - */ - oListener = window.setInterval(function(){ - if (oWindowObjectReference.closed) { - $('.ibo-oauth-wizard--form--submit').prop('disabled', false); - clearInterval(oListener); - } - oWindowObjectReference.postMessage('anyone', '{{ sReturnUri }}'); - }, 1000); - /* Once we receive a response, transmit it to the server to get authenticate and display - results - */ - window.addEventListener('message', oOnOauthSuccess, false); - // Assign the previous URL - sPreviousUrl = url; -}; - -// Function used when the form is submitted - -const oOnFormSubmit = function(){ - $('.ibo-oauth-wizard--form--submit').prop('disabled', true); - $.post( - '{{ sAjaxUri }}', - { - operation: 'GetAuthorizationUrl', - provider: $('[name="provider"]:checked').val(), - client_id: $(this).find('[name="client_id"]').val(), - client_secret: $(this).find('[name="client_secret"]').val(), - scope: $(this).find('[name="scope"]').val(), - additional: $(this).find('[name="additional"]').val() - }, - function(oData){ - if(oData.status == 'success') - { - oOpenSignInWindow(oData.data.authorization_url, 'OAuth authorization') - } - else{ - $('.ibo-oauth-wizard--form--submit').prop('disabled', false); - } - } - ); - return false; -} - -// Function used to update provider image - -function oUpdateProviderImage(elem){ - - var oColor1 = $(elem).prev('[name="provider"]').attr('data-color1'); - var oColor2 = $(elem).prev('[name="provider"]').attr('data-color2'); - var oColor4 = $(elem).prev('[name="provider"]').attr('data-color3'); - var oColor3 = $(elem).prev('[name="provider"]').attr('data-color4'); - - $('#fcef55fc-4968-45b2-93bb-1a1080c85fc7').attr('fill', oColor1); - $('#e8fa0310-b872-4adf-aedd-0c6eda09f3b8').attr('fill', oColor1); - $('#a4813fcf-056e-4514-bb8b-e6506f49341f').attr('fill', oColor1); - $('#e73810fe-4cf4-40cc-8c7c-ca544ce30bd4-108').attr('fill', oColor2); - $('#e12ee00d-aa4a-4413-a013-11d20b7f97f7').attr('fill', oColor2); - $('#b4d4939a-c6e6-4f4d-ba6c-e8b05485017d').attr('fill', oColor2); - $('#b06d66ec-6c84-45dd-8c27-1263a6253192-107').attr('fill', oColor3); - $('#f58f497e-6949-45c8-be5f-eee2aa0f6586').attr('fill', oColor3); - $('#aff120b1-519b-4e96-ac87-836aa55663de').attr('fill', oColor3); - $('#ae7af94f-88d7-4204-9f07-e3651de85c05-111').attr('fill', oColor4); - $('#a6768b0e-63d0-4b31-8462-9b2e0b00f0fd-112').attr('fill', oColor4); -} -$('body').on('click', '.ui-checkboxradio-radio-label', function(){ - oUpdateProviderImage(this) -}) -oUpdateProviderImage($('[name="provider"]:checked').next()); - -// Initialize provider buttons -$('#select_layout').buttonset(); - -$('.ibo-oauth-wizard--form').on('submit', oOnFormSubmit);