mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
Merge remote-tracking branch 'origin/support/3.0' into develop
# Conflicts: # composer.lock # datamodels/2.x/itop-oauth-client/datamodel.itop-oauth-client.xml # lib/composer/autoload_files.php # lib/composer/autoload_real.php # lib/composer/autoload_static.php # lib/composer/installed.json # lib/composer/installed.php
This commit is contained in:
@@ -114,9 +114,9 @@ Our tests are located in the `test/` directory, containing a PHPUnit config file
|
|||||||
* Use the present tense ("Add feature" not "Added feature")
|
* Use the present tense ("Add feature" not "Added feature")
|
||||||
* Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
|
* Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
|
||||||
* Limit the first line to 72 characters or less
|
* Limit the first line to 72 characters or less
|
||||||
* Please start the commit message with an applicable emoji code (following the [Gitmoji guide](https://gitmoji.carloscuesta.me/)).
|
* Please start the commit message with an applicable emoji code (following the [Gitmoji guide](https://gitmoji.dev/)).
|
||||||
Beware to use the code (for example `:bug:`) and not the character (🐛) as Unicode support in git clients is very poor for now...
|
Beware to use the code (for example `:bug:`) and not the character (🐛) as Unicode support in git clients is very poor for now...
|
||||||
Emoji examples :
|
Emoji examples :
|
||||||
* 🌐 `:globe_with_meridians:` for translations
|
* 🌐 `:globe_with_meridians:` for translations
|
||||||
* 🎨 `:art:` when improving the format/structure of the code
|
* 🎨 `:art:` when improving the format/structure of the code
|
||||||
* ⚡️ `:zap:` when improving performance
|
* ⚡️ `:zap:` when improving performance
|
||||||
|
|||||||
@@ -5,8 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use Combodo\iTop\Application\Helper\WebResourcesHelper;
|
use Combodo\iTop\Application\Helper\WebResourcesHelper;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Title\Title;
|
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Title\TitleUIBlockFactory;
|
|
||||||
|
|
||||||
require_once(APPROOT.'/application/utils.inc.php');
|
require_once(APPROOT.'/application/utils.inc.php');
|
||||||
require_once(APPROOT.'/application/template.class.inc.php');
|
require_once(APPROOT.'/application/template.class.inc.php');
|
||||||
@@ -655,8 +653,7 @@ abstract class MenuNode
|
|||||||
$this->sMenuId = $sMenuId;
|
$this->sMenuId = $sMenuId;
|
||||||
$this->iParentIndex = $iParentIndex;
|
$this->iParentIndex = $iParentIndex;
|
||||||
$this->aReflectionProperties = array();
|
$this->aReflectionProperties = array();
|
||||||
if (utils::StrLen($sEnableClass) > 0)
|
if (utils::IsNotNullOrEmptyString($sEnableClass)) {
|
||||||
{
|
|
||||||
$this->aReflectionProperties['enable_class'] = $sEnableClass;
|
$this->aReflectionProperties['enable_class'] = $sEnableClass;
|
||||||
$this->aReflectionProperties['enable_action'] = $iActionCode;
|
$this->aReflectionProperties['enable_action'] = $iActionCode;
|
||||||
$this->aReflectionProperties['enable_permission'] = $iAllowedResults;
|
$this->aReflectionProperties['enable_permission'] = $iAllowedResults;
|
||||||
|
|||||||
@@ -973,7 +973,7 @@ HTML
|
|||||||
);
|
);
|
||||||
|
|
||||||
$oPage->add_ready_script(<<<JS
|
$oPage->add_ready_script(<<<JS
|
||||||
$('#ac_create_{$this->iId}').dialog({ width: 'auto', height: 'auto', maxHeight: $(window).height() - 50, autoOpen: false, modal: true});
|
$('#ac_create_{$this->iId}').dialog({ width: $(window).width() * 0.6, height: 'auto', maxHeight: $(window).height() - 50, autoOpen: false, modal: true});
|
||||||
$('#dcr_{$this->iId} form').removeAttr('onsubmit');
|
$('#dcr_{$this->iId} form').removeAttr('onsubmit');
|
||||||
$('#dcr_{$this->iId} form').find('button[type="submit"]').on('click', oACWidget_{$this->iId}.DoCreateObject);
|
$('#dcr_{$this->iId} form').find('button[type="submit"]').on('click', oACWidget_{$this->iId}.DoCreateObject);
|
||||||
JS
|
JS
|
||||||
|
|||||||
@@ -1942,7 +1942,7 @@ class utils
|
|||||||
*/
|
*/
|
||||||
public static function CompileCSSFromSASS($sSassContent, $aImportPaths = array(), $aVariables = array())
|
public static function CompileCSSFromSASS($sSassContent, $aImportPaths = array(), $aVariables = array())
|
||||||
{
|
{
|
||||||
$oSass = new Compiler();//['checkImportResolutions'=>true]);
|
$oSass = new Compiler();
|
||||||
$oSass->setOutputStyle(OutputStyle::COMPRESSED);
|
$oSass->setOutputStyle(OutputStyle::COMPRESSED);
|
||||||
// Setting our variables
|
// Setting our variables
|
||||||
$aCssVariable = [];
|
$aCssVariable = [];
|
||||||
@@ -2845,6 +2845,36 @@ HTML;
|
|||||||
return strlen($sString ?? '');
|
return strlen($sString ?? '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper around the native strlen() PHP method to test a string for null or empty value
|
||||||
|
*
|
||||||
|
* @link https://www.php.net/releases/8.1/en.php#deprecations_and_bc_breaks "Passing null to non-nullable internal function parameters is deprecated"
|
||||||
|
*
|
||||||
|
* @param string|null $sString
|
||||||
|
*
|
||||||
|
* @return bool if string null or empty
|
||||||
|
* @since 3.0.2 N°5302
|
||||||
|
*/
|
||||||
|
public static function IsNullOrEmptyString(?string $sString): bool
|
||||||
|
{
|
||||||
|
return $sString == null || strlen($sString) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper around the native strlen() PHP method to test a string not null or empty value
|
||||||
|
*
|
||||||
|
* @link https://www.php.net/releases/8.1/en.php#deprecations_and_bc_breaks "Passing null to non-nullable internal function parameters is deprecated"
|
||||||
|
*
|
||||||
|
* @param string|null $sString
|
||||||
|
*
|
||||||
|
* @return bool if string is not null and not empty
|
||||||
|
* @since 3.0.2 N°5302
|
||||||
|
*/
|
||||||
|
public static function IsNotNullOrEmptyString(?string $sString): bool
|
||||||
|
{
|
||||||
|
return !static::IsNullOrEmptyString($sString);
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------
|
//----------------------------------------------
|
||||||
// Environment helpers
|
// Environment helpers
|
||||||
//----------------------------------------------
|
//----------------------------------------------
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
{
|
{
|
||||||
|
"name": "combodo/itop",
|
||||||
|
"description": "IT Operations Portal",
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"license": "AGPLv3",
|
"license": "AGPL-3.0-or-later",
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=7.2.5 <8.0.0",
|
"php": ">=7.2.5 <8.0.0",
|
||||||
"ext-ctype": "*",
|
"ext-ctype": "*",
|
||||||
|
|||||||
@@ -293,7 +293,7 @@ abstract class AsyncTask extends DBObject
|
|||||||
$this->Set('remaining_retries', $this->GetMaxRetries($iErrorCode));
|
$this->Set('remaining_retries', $this->GetMaxRetries($iErrorCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->Set('last_error', $sErrorMessage);
|
$this->SetTrim('last_error', $sErrorMessage);
|
||||||
$this->Set('last_error_code', $iErrorCode); // Note: can be ZERO !!!
|
$this->Set('last_error_code', $iErrorCode); // Note: can be ZERO !!!
|
||||||
$this->Set('last_attempt', time());
|
$this->Set('last_attempt', time());
|
||||||
|
|
||||||
|
|||||||
@@ -530,7 +530,7 @@ class Config
|
|||||||
],
|
],
|
||||||
'email_transport' => [
|
'email_transport' => [
|
||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
'description' => 'Mean to send emails: PHPMail (uses the function mail()) or SMTP (implements the client protocol)',
|
'description' => 'Mean to send emails: PHPMail (uses the function mail()), SMTP (implements the client protocol) or SMTP_OAuth (connect to the server using OAuth 2.0)',
|
||||||
'default' => "PHPMail",
|
'default' => "PHPMail",
|
||||||
'value' => "PHPMail",
|
'value' => "PHPMail",
|
||||||
'source_of_value' => '',
|
'source_of_value' => '',
|
||||||
|
|||||||
@@ -26,8 +26,10 @@
|
|||||||
|
|
||||||
namespace Combodo\iTop;
|
namespace Combodo\iTop;
|
||||||
|
|
||||||
use \DOMDocument;
|
use DOMDocument;
|
||||||
use \DOMFormatException;
|
use DOMFormatException;
|
||||||
|
use IssueLog;
|
||||||
|
use LogAPI;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class \Combodo\iTop\DesignDocument
|
* Class \Combodo\iTop\DesignDocument
|
||||||
@@ -64,9 +66,13 @@ class DesignDocument extends DOMDocument
|
|||||||
* @param $filename
|
* @param $filename
|
||||||
* @param int $options
|
* @param int $options
|
||||||
*/
|
*/
|
||||||
public function load($filename, $options = 0)
|
public function load($filename, $options = null)
|
||||||
{
|
{
|
||||||
parent::load($filename, LIBXML_NOBLANKS);
|
libxml_clear_errors();
|
||||||
|
if (parent::load($filename, LIBXML_NOBLANKS) === false) {
|
||||||
|
$aErrors = libxml_get_errors();
|
||||||
|
IssueLog::Error("Error loading $filename", LogAPI::CHANNEL_DEFAULT, $aErrors);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -77,10 +83,10 @@ class DesignDocument extends DOMDocument
|
|||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function save($filename, $options = 0)
|
public function save($filename, $options = null)
|
||||||
{
|
{
|
||||||
$this->documentElement->setAttribute('xmlns:xsi', "http://www.w3.org/2001/XMLSchema-instance");
|
$this->documentElement->setAttribute('xmlns:xsi', "http://www.w3.org/2001/XMLSchema-instance");
|
||||||
return parent::save($filename, LIBXML_NOBLANKS);
|
return parent::save($filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -461,7 +461,7 @@ abstract class MetaModel
|
|||||||
$oStyle = self::$m_aClassParams[$sClass]['style'];
|
$oStyle = self::$m_aClassParams[$sClass]['style'];
|
||||||
$sIcon = $oStyle->GetIconAsAbsUrl();
|
$sIcon = $oStyle->GetIconAsAbsUrl();
|
||||||
}
|
}
|
||||||
if (utils::StrLen($sIcon) == 0) {
|
if (utils::IsNullOrEmptyString($sIcon)) {
|
||||||
$sParentClass = self::GetParentPersistentClass($sClass);
|
$sParentClass = self::GetParentPersistentClass($sClass);
|
||||||
if (strlen($sParentClass) > 0) {
|
if (strlen($sParentClass) > 0) {
|
||||||
return self::GetClassIcon($sParentClass, $bImgTag, $sMoreStyles);
|
return self::GetClassIcon($sParentClass, $bImgTag, $sMoreStyles);
|
||||||
@@ -494,7 +494,7 @@ abstract class MetaModel
|
|||||||
$oStyle = new ormStyle("ibo-class-style--$sClass", "ibo-class-style-alt--$sClass");
|
$oStyle = new ormStyle("ibo-class-style--$sClass", "ibo-class-style-alt--$sClass");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((utils::StrLen($oStyle->GetMainColor()) > 0) && (utils::StrLen($oStyle->GetComplementaryColor()) > 0) && (utils::StrLen($oStyle->GetIconAsRelPath()) > 0)) {
|
if (utils::IsNotNullOrEmptyString($oStyle->GetMainColor()) && utils::IsNotNullOrEmptyString($oStyle->GetComplementaryColor()) && utils::IsNotNullOrEmptyString($oStyle->GetIconAsRelPath())) {
|
||||||
// all the parameters are set, no need to search in the parent classes
|
// all the parameters are set, no need to search in the parent classes
|
||||||
return $oStyle;
|
return $oStyle;
|
||||||
}
|
}
|
||||||
@@ -504,18 +504,18 @@ abstract class MetaModel
|
|||||||
while (strlen($sParentClass) > 0) {
|
while (strlen($sParentClass) > 0) {
|
||||||
$oParentStyle = self::GetClassStyle($sParentClass);
|
$oParentStyle = self::GetClassStyle($sParentClass);
|
||||||
if (!is_null($oParentStyle)) {
|
if (!is_null($oParentStyle)) {
|
||||||
if (utils::StrLen($oStyle->GetMainColor()) == 0) {
|
if (utils::IsNullOrEmptyString($oStyle->GetMainColor())) {
|
||||||
$oStyle->SetMainColor($oParentStyle->GetMainColor());
|
$oStyle->SetMainColor($oParentStyle->GetMainColor());
|
||||||
$oStyle->SetStyleClass($oParentStyle->GetStyleClass());
|
$oStyle->SetStyleClass($oParentStyle->GetStyleClass());
|
||||||
}
|
}
|
||||||
if (utils::StrLen($oStyle->GetComplementaryColor()) == 0) {
|
if (utils::IsNullOrEmptyString($oStyle->GetComplementaryColor())) {
|
||||||
$oStyle->SetComplementaryColor($oParentStyle->GetComplementaryColor());
|
$oStyle->SetComplementaryColor($oParentStyle->GetComplementaryColor());
|
||||||
$oStyle->SetAltStyleClass($oParentStyle->GetAltStyleClass());
|
$oStyle->SetAltStyleClass($oParentStyle->GetAltStyleClass());
|
||||||
}
|
}
|
||||||
if (utils::StrLen($oStyle->GetIconAsRelPath()) == 0) {
|
if (utils::IsNullOrEmptyString($oStyle->GetIconAsRelPath())) {
|
||||||
$oStyle->SetIcon($oParentStyle->GetIconAsRelPath());
|
$oStyle->SetIcon($oParentStyle->GetIconAsRelPath());
|
||||||
}
|
}
|
||||||
if ((utils::StrLen($oStyle->GetMainColor()) > 0) && (utils::StrLen($oStyle->GetComplementaryColor()) > 0) && (utils::StrLen($oStyle->GetIconAsRelPath()) > 0)) {
|
if (utils::IsNotNullOrEmptyString($oStyle->GetMainColor()) && utils::IsNotNullOrEmptyString($oStyle->GetComplementaryColor()) && utils::IsNotNullOrEmptyString($oStyle->GetIconAsRelPath())) {
|
||||||
// all the parameters are set, no need to search in the parent classes
|
// all the parameters are set, no need to search in the parent classes
|
||||||
return $oStyle;
|
return $oStyle;
|
||||||
}
|
}
|
||||||
@@ -523,7 +523,7 @@ abstract class MetaModel
|
|||||||
$sParentClass = self::GetParentPersistentClass($sParentClass);
|
$sParentClass = self::GetParentPersistentClass($sParentClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((utils::StrLen($oStyle->GetMainColor()) == 0) && (utils::StrLen($oStyle->GetComplementaryColor()) == 0) && (utils::StrLen($oStyle->GetIconAsRelPath()) == 0)) {
|
if (utils::IsNullOrEmptyString($oStyle->GetMainColor()) && utils::IsNullOrEmptyString($oStyle->GetComplementaryColor()) && utils::IsNullOrEmptyString($oStyle->GetIconAsRelPath())) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class ormStyle
|
|||||||
*/
|
*/
|
||||||
public function HasMainColor(): bool
|
public function HasMainColor(): bool
|
||||||
{
|
{
|
||||||
return utils::StrLen($this->sMainColor) > 0;
|
return utils::IsNotNullOrEmptyString($this->sMainColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -68,7 +68,7 @@ class ormStyle
|
|||||||
*/
|
*/
|
||||||
public function SetMainColor(?string $sMainColor)
|
public function SetMainColor(?string $sMainColor)
|
||||||
{
|
{
|
||||||
$this->sMainColor = (utils::StrLen($sMainColor) === 0) ? null : $sMainColor;
|
$this->sMainColor = utils::IsNullOrEmptyString($sMainColor) ? null : $sMainColor;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ class ormStyle
|
|||||||
*/
|
*/
|
||||||
public function HasComplementaryColor(): bool
|
public function HasComplementaryColor(): bool
|
||||||
{
|
{
|
||||||
return utils::StrLen($this->sComplementaryColor) > 0;
|
return utils::IsNotNullOrEmptyString($this->sComplementaryColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -96,7 +96,7 @@ class ormStyle
|
|||||||
*/
|
*/
|
||||||
public function SetComplementaryColor(?string $sComplementaryColor)
|
public function SetComplementaryColor(?string $sComplementaryColor)
|
||||||
{
|
{
|
||||||
$this->sComplementaryColor = (utils::StrLen($sComplementaryColor) === 0) ? null : $sComplementaryColor;
|
$this->sComplementaryColor = utils::IsNullOrEmptyString($sComplementaryColor) ? null : $sComplementaryColor;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ class ormStyle
|
|||||||
*/
|
*/
|
||||||
public function HasStyleClass(): bool
|
public function HasStyleClass(): bool
|
||||||
{
|
{
|
||||||
return utils::StrLen($this->sStyleClass) > 0;
|
return utils::IsNotNullOrEmptyString($this->sStyleClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -134,7 +134,7 @@ class ormStyle
|
|||||||
*/
|
*/
|
||||||
public function SetStyleClass(?string $sStyleClass)
|
public function SetStyleClass(?string $sStyleClass)
|
||||||
{
|
{
|
||||||
$this->sStyleClass = (utils::StrLen($sStyleClass) === 0) ? null : $sStyleClass;
|
$this->sStyleClass = utils::IsNullOrEmptyString($sStyleClass) ? null : $sStyleClass;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ class ormStyle
|
|||||||
*/
|
*/
|
||||||
public function HasAltStyleClass(): bool
|
public function HasAltStyleClass(): bool
|
||||||
{
|
{
|
||||||
return utils::StrLen($this->sAltStyleClass) > 0;
|
return utils::IsNotNullOrEmptyString($this->sAltStyleClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -162,7 +162,7 @@ class ormStyle
|
|||||||
*/
|
*/
|
||||||
public function SetAltStyleClass(?string $sAltStyleClass)
|
public function SetAltStyleClass(?string $sAltStyleClass)
|
||||||
{
|
{
|
||||||
$this->sAltStyleClass = (utils::StrLen($sAltStyleClass) === 0) ? null : $sAltStyleClass;
|
$this->sAltStyleClass = utils::IsNullOrEmptyString($sAltStyleClass) ? null : $sAltStyleClass;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,7 +172,7 @@ class ormStyle
|
|||||||
*/
|
*/
|
||||||
public function HasDecorationClasses(): bool
|
public function HasDecorationClasses(): bool
|
||||||
{
|
{
|
||||||
return utils::StrLen($this->sDecorationClasses) > 0;
|
return utils::IsNotNullOrEmptyString($this->sDecorationClasses);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -190,7 +190,7 @@ class ormStyle
|
|||||||
*/
|
*/
|
||||||
public function SetDecorationClasses(?string $sDecorationClasses)
|
public function SetDecorationClasses(?string $sDecorationClasses)
|
||||||
{
|
{
|
||||||
$this->sDecorationClasses = (utils::StrLen($sDecorationClasses) === 0) ? null : $sDecorationClasses;
|
$this->sDecorationClasses = utils::IsNullOrEmptyString($sDecorationClasses) ? null : $sDecorationClasses;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,7 +200,7 @@ class ormStyle
|
|||||||
*/
|
*/
|
||||||
public function HasIcon(): bool
|
public function HasIcon(): bool
|
||||||
{
|
{
|
||||||
return utils::StrLen($this->sIcon) > 0;
|
return utils::IsNotNullOrEmptyString($this->sIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -210,7 +210,7 @@ class ormStyle
|
|||||||
*/
|
*/
|
||||||
public function SetIcon(?string $sIcon)
|
public function SetIcon(?string $sIcon)
|
||||||
{
|
{
|
||||||
$this->sIcon = (utils::StrLen($sIcon) === 0) ? null : $sIcon;
|
$this->sIcon = utils::IsNullOrEmptyString($sIcon) ? null : $sIcon;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/*!
|
/*
|
||||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|||||||
2
css/backoffice/vendors/_selectize.scss
vendored
2
css/backoffice/vendors/_selectize.scss
vendored
@@ -1,4 +1,4 @@
|
|||||||
/*!
|
/*
|
||||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
# Extension OAuth 2.0 client
|
# Extension OAuth 2.0 client
|
||||||
|
|
||||||
|
## GMail
|
||||||
|
|
||||||
|
If the account is in test, after 7 days the tokens are no longer valid, you have to renew the tokens manually.
|
||||||
|
|||||||
@@ -17,8 +17,7 @@ if (version_compare(ITOP_DESIGN_LATEST_VERSION , '3.0') >= 0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$oUpdateController = new AjaxOauthClientController($sTemplates, 'itop-oauth-client');
|
$oUpdateController = new AjaxOauthClientController($sTemplates, 'itop-oauth-client');
|
||||||
$oUpdateController->AllowOnlyAdmin();
|
$oUpdateController->SetMenuId('OAuthClient');
|
||||||
$oUpdateController->SetDefaultOperation('CreateMailbox');
|
|
||||||
$oUpdateController->HandleOperation();
|
$oUpdateController->HandleOperation();
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<class id="OAuthClient" _delta="define">
|
<class id="OAuthClient" _delta="define">
|
||||||
<parent>cmdbAbstractObject</parent>
|
<parent>cmdbAbstractObject</parent>
|
||||||
<properties>
|
<properties>
|
||||||
<category>cloud,searchable</category>
|
<category>grant_by_profile,application</category>
|
||||||
<abstract>true</abstract>
|
<abstract>true</abstract>
|
||||||
<key_type>autoincrement</key_type>
|
<key_type>autoincrement</key_type>
|
||||||
<db_table>priv_oauth_client</db_table>
|
<db_table>priv_oauth_client</db_table>
|
||||||
@@ -17,14 +17,15 @@
|
|||||||
<attribute id="name"/>
|
<attribute id="name"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</naming>
|
</naming>
|
||||||
<display_template/>
|
|
||||||
<icon/>
|
|
||||||
<reconciliation>
|
<reconciliation>
|
||||||
<attributes>
|
<attributes>
|
||||||
<attribute id="provider"/>
|
<attribute id="provider"/>
|
||||||
<attribute id="name"/>
|
<attribute id="name"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</reconciliation>
|
</reconciliation>
|
||||||
|
<style>
|
||||||
|
<icon/>
|
||||||
|
</style>
|
||||||
</properties>
|
</properties>
|
||||||
<fields>
|
<fields>
|
||||||
<field id="provider" xsi:type="AttributeString">
|
<field id="provider" xsi:type="AttributeString">
|
||||||
@@ -119,22 +120,35 @@
|
|||||||
<access>public</access>
|
<access>public</access>
|
||||||
<type>Overload-DBObject</type>
|
<type>Overload-DBObject</type>
|
||||||
<code><![CDATA[
|
<code><![CDATA[
|
||||||
public function DisplayBareHeader(WebPage $oPage, $bEditMode = false)
|
public function DisplayBareHeader(WebPage $oPage, $bEditMode = false)
|
||||||
{
|
{
|
||||||
parent::DisplayBareHeader($oPage, $bEditMode);
|
$aHeaderBlocks = parent::DisplayBareHeader($oPage, $bEditMode);
|
||||||
if (!$bEditMode) {
|
$aTags = [];
|
||||||
$oConfig = utils::GetConfig();
|
if (!$bEditMode) {
|
||||||
$sScope = $this->Get('scope');
|
$oConfig = utils::GetConfig();
|
||||||
if ($this->Get('status') == 'inactive') {
|
if ($this->Get('status') == 'inactive') {
|
||||||
$oPage->p('<b>'.Dict::S('itop-oauth-client:Message:MissingToken').'</b>');
|
$sLabel = Dict::S('itop-oauth-client:Message:MissingToken');
|
||||||
} elseif (($sScope == 'SMTP' || $sScope == 'EMail') && $oConfig->Get('email_transport_smtp.username') == $this->Get('name')) {
|
$sTitle = '';
|
||||||
$sLabel = Dict::S('itop-oauth-client:UsedForSMTP');
|
$aTags['oauth-message'] = ['title' => $sTitle, 'css_classes' => 'ibo-object-details--tag--oauth-message', 'decoration_classes' => 'fas fa-exclamation-triangle', 'label' => $sLabel];
|
||||||
$sTestLabel = Dict::S('itop-oauth-client:TestSMTP');
|
} elseif ($this->Get('used_for_smtp') == 'yes' && $oConfig->Get('email_transport_smtp.username') == $this->Get('name')) {
|
||||||
$sTestURL = utils::GetAbsoluteUrlAppRoot().'setup/email.test.php';
|
$sLabel = Dict::S('itop-oauth-client:UsedForSMTP');
|
||||||
$oPage->p("<b>$sLabel</b> <a href='$sTestURL' target='_blank'>$sTestLabel</a>");
|
$sTestLabel = Dict::S('itop-oauth-client:TestSMTP');
|
||||||
}
|
$sTestURL = utils::GetAbsoluteUrlAppRoot().'setup/email.test.php';
|
||||||
}
|
$sLabel = Dict::S('itop-oauth-client:UsedForSMTP')." <a href='$sTestURL' target='_blank'>$sTestLabel</a>";
|
||||||
}
|
$sTitle = '';
|
||||||
|
$aTags['oauth-message'] = ['title' => $sTitle, 'css_classes' => 'ibo-object-details--tag--oauth-message', 'decoration_classes' => 'far fa-envelope', 'label' => $sLabel];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($aTags as $sIconId => $aIconData) {
|
||||||
|
$sTagTooltipContent = utils::EscapeHtml($aIconData['title']);
|
||||||
|
$aHeaderBlocks['subtitle'][static::HEADER_BLOCKS_SUBTITLE_TAG_PREFIX.$sIconId] = new Combodo\iTop\Application\UI\Base\Component\Html\Html(<<<HTML
|
||||||
|
<span id="{$sIconId}" class="ibo-object-details--tag {$aIconData['css_classes']}" data-tooltip-content="{$sTagTooltipContent}" data-tooltip-html-enabled="true"><span class="ibo-object-details--tag-icon"><span class="{$aIconData['decoration_classes']}"></span></span>{$aIconData['label']}</span>
|
||||||
|
HTML
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aHeaderBlocks;
|
||||||
|
}
|
||||||
]]></code>
|
]]></code>
|
||||||
</method>
|
</method>
|
||||||
<method id="GetAttributeFlags">
|
<method id="GetAttributeFlags">
|
||||||
@@ -142,14 +156,14 @@
|
|||||||
<access>public</access>
|
<access>public</access>
|
||||||
<type>Overload-DBObject</type>
|
<type>Overload-DBObject</type>
|
||||||
<code><![CDATA[
|
<code><![CDATA[
|
||||||
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
||||||
{
|
{
|
||||||
if ($sAttCode == 'status') {
|
if ($sAttCode == 'status') {
|
||||||
return OPT_ATT_READONLY;
|
return OPT_ATT_READONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
||||||
}
|
}
|
||||||
]]></code>
|
]]></code>
|
||||||
</method>
|
</method>
|
||||||
<method id="GetInitialStateAttributeFlags">
|
<method id="GetInitialStateAttributeFlags">
|
||||||
@@ -157,68 +171,68 @@
|
|||||||
<access>public</access>
|
<access>public</access>
|
||||||
<type>Overload-DBObject</type>
|
<type>Overload-DBObject</type>
|
||||||
<code><![CDATA[
|
<code><![CDATA[
|
||||||
public function GetInitialStateAttributeFlags($sAttCode, &$aReasons = array())
|
public function GetInitialStateAttributeFlags($sAttCode, &$aReasons = array())
|
||||||
{
|
{
|
||||||
if ($sAttCode == 'status') {
|
if ($sAttCode == 'status') {
|
||||||
return OPT_ATT_READONLY;
|
return OPT_ATT_READONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::GetInitialStateAttributeFlags($sAttCode, $aReasons);
|
return parent::GetInitialStateAttributeFlags($sAttCode, $aReasons);
|
||||||
}
|
}
|
||||||
]]></code>
|
]]></code>
|
||||||
</method>
|
</method>
|
||||||
<method id="GetDefaultMailServer">
|
<method id="GetDefaultMailServer">
|
||||||
<static>false</static>
|
<static>false</static>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<code><![CDATA[
|
<code><![CDATA[
|
||||||
public function GetDefaultMailServer()
|
public function GetDefaultMailServer()
|
||||||
{
|
{
|
||||||
return 'imap.'.$this->Get('provider').'.com';
|
return 'imap.'.$this->Get('provider').'.com';
|
||||||
}
|
}
|
||||||
]]></code>
|
]]></code>
|
||||||
</method>
|
</method>
|
||||||
<method id="GetDefaultMailServerPort">
|
<method id="GetDefaultMailServerPort">
|
||||||
<static>false</static>
|
<static>false</static>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<code><![CDATA[
|
<code><![CDATA[
|
||||||
public function GetDefaultMailServerPort()
|
public function GetDefaultMailServerPort()
|
||||||
{
|
{
|
||||||
return 993;
|
return 993;
|
||||||
}
|
}
|
||||||
]]></code>
|
]]></code>
|
||||||
</method>
|
</method>
|
||||||
<method id="GetAccessToken">
|
<method id="GetAccessToken">
|
||||||
<static>false</static>
|
<static>false</static>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<code><![CDATA[
|
<code><![CDATA[
|
||||||
public function GetAccessToken()
|
public function GetAccessToken()
|
||||||
{
|
{
|
||||||
if ($this->Get('status') == 'active') {
|
if ($this->Get('status') == 'active') {
|
||||||
return new \League\OAuth2\Client\Token\AccessToken([
|
return new \League\OAuth2\Client\Token\AccessToken([
|
||||||
'access_token' => $this->Get('token'),
|
'access_token' => $this->Get('token'),
|
||||||
'expires_in' => date_format(new DateTime($this->Get('token_expiration')), 'U') - time(),
|
'expires_in' => date_format(new DateTime($this->Get('token_expiration')), 'U') - time(),
|
||||||
'refresh_token' => $this->Get('refresh_token'),
|
'refresh_token' => $this->Get('refresh_token'),
|
||||||
'token_type' => 'Bearer',
|
'token_type' => 'Bearer',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
]]></code>
|
]]></code>
|
||||||
</method>
|
</method>
|
||||||
<method id="SetAccessToken">
|
<method id="SetAccessToken">
|
||||||
<static>false</static>
|
<static>false</static>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<code><![CDATA[
|
<code><![CDATA[
|
||||||
public function SetAccessToken(\League\OAuth2\Client\Token\AccessTokenInterface $oAccessToken)
|
public function SetAccessToken(\League\OAuth2\Client\Token\AccessTokenInterface $oAccessToken)
|
||||||
{
|
{
|
||||||
$this->Set('token', $oAccessToken->getToken());
|
$this->Set('token', $oAccessToken->getToken());
|
||||||
$this->Set('token_expiration', date(AttributeDateTime::GetSQLFormat(), $oAccessToken->getExpires()));
|
$this->Set('token_expiration', date(AttributeDateTime::GetSQLFormat(), $oAccessToken->getExpires()));
|
||||||
if (!empty($oAccessToken->getRefreshToken())) {
|
if (!empty($oAccessToken->getRefreshToken())) {
|
||||||
$this->Set('refresh_token', $oAccessToken->getRefreshToken());
|
$this->Set('refresh_token', $oAccessToken->getRefreshToken());
|
||||||
}
|
}
|
||||||
$this->Set('status', 'active');
|
$this->Set('status', 'active');
|
||||||
$this->DBUpdate();
|
$this->DBUpdate();
|
||||||
}
|
}
|
||||||
]]></code>
|
]]></code>
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
@@ -280,6 +294,632 @@
|
|||||||
</default_search>
|
</default_search>
|
||||||
</presentation>
|
</presentation>
|
||||||
</class>
|
</class>
|
||||||
|
<class id="OAuthClientAzure" _delta="define">
|
||||||
|
<parent>OAuthClient</parent>
|
||||||
|
<properties>
|
||||||
|
<category>grant_by_profile,application</category>
|
||||||
|
<abstract>false</abstract>
|
||||||
|
<key_type>autoincrement</key_type>
|
||||||
|
<db_table>priv_oauth_client_azure</db_table>
|
||||||
|
<db_key_field>id</db_key_field>
|
||||||
|
<db_final_class_field/>
|
||||||
|
<naming>
|
||||||
|
<attributes>
|
||||||
|
<attribute id="provider"/>
|
||||||
|
<attribute id="name"/>
|
||||||
|
</attributes>
|
||||||
|
</naming>
|
||||||
|
<reconciliation>
|
||||||
|
<attributes>
|
||||||
|
<attribute id="provider"/>
|
||||||
|
<attribute id="name"/>
|
||||||
|
</attributes>
|
||||||
|
</reconciliation>
|
||||||
|
<uniqueness_rules>
|
||||||
|
<rule id="server">
|
||||||
|
<attributes>
|
||||||
|
<attribute id="provider"/>
|
||||||
|
<attribute id="client_id"/>
|
||||||
|
<attribute id="client_secret"/>
|
||||||
|
</attributes>
|
||||||
|
<is_blocking>true</is_blocking>
|
||||||
|
</rule>
|
||||||
|
</uniqueness_rules>
|
||||||
|
<style>
|
||||||
|
<icon/>
|
||||||
|
</style>
|
||||||
|
</properties>
|
||||||
|
<fields>
|
||||||
|
<field id="scope" xsi:type="AttributeEnumSet">
|
||||||
|
<always_load_in_tables>true</always_load_in_tables>
|
||||||
|
<values>
|
||||||
|
<value id="SMTP">
|
||||||
|
<code>SMTP</code>
|
||||||
|
</value>
|
||||||
|
<value id="IMAP">
|
||||||
|
<code>IMAP</code>
|
||||||
|
</value>
|
||||||
|
</values>
|
||||||
|
<sql>scope</sql>
|
||||||
|
<default_value>SMTP,IMAP</default_value>
|
||||||
|
<is_null_allowed>true</is_null_allowed>
|
||||||
|
</field>
|
||||||
|
<field id="advanced_scope" xsi:type="AttributeString">
|
||||||
|
<sql>advanced_scope</sql>
|
||||||
|
<default_value/>
|
||||||
|
<is_null_allowed>true</is_null_allowed>
|
||||||
|
</field>
|
||||||
|
<field id="used_scope" xsi:type="AttributeEnum">
|
||||||
|
<always_load_in_tables>true</always_load_in_tables>
|
||||||
|
<values>
|
||||||
|
<value id="simple">
|
||||||
|
<code>simple</code>
|
||||||
|
</value>
|
||||||
|
<value id="advanced">
|
||||||
|
<code>advanced</code>
|
||||||
|
</value>
|
||||||
|
</values>
|
||||||
|
<sql>used_scope</sql>
|
||||||
|
<default_value>simple</default_value>
|
||||||
|
<is_null_allowed>false</is_null_allowed>
|
||||||
|
<dependencies>
|
||||||
|
<attribute id="scope"/>
|
||||||
|
<attribute id="advanced_scope"/>
|
||||||
|
</dependencies>
|
||||||
|
</field>
|
||||||
|
<field id="used_for_smtp" xsi:type="AttributeEnum">
|
||||||
|
<always_load_in_tables>true</always_load_in_tables>
|
||||||
|
<values>
|
||||||
|
<value id="yes">
|
||||||
|
<code>yes</code>
|
||||||
|
</value>
|
||||||
|
<value id="no">
|
||||||
|
<code>no</code>
|
||||||
|
</value>
|
||||||
|
</values>
|
||||||
|
<sql>used_for_smtp</sql>
|
||||||
|
<default_value>no</default_value>
|
||||||
|
<is_null_allowed>true</is_null_allowed>
|
||||||
|
</field>
|
||||||
|
</fields>
|
||||||
|
<presentation>
|
||||||
|
<details>
|
||||||
|
<items>
|
||||||
|
<item id="col:col1">
|
||||||
|
<rank>10</rank>
|
||||||
|
<items>
|
||||||
|
<item id="fieldset:OAuthClient:baseinfo">
|
||||||
|
<rank>10</rank>
|
||||||
|
<items>
|
||||||
|
<item id="name">
|
||||||
|
<rank>10</rank>
|
||||||
|
</item>
|
||||||
|
<item id="status">
|
||||||
|
<rank>20</rank>
|
||||||
|
</item>
|
||||||
|
<item id="description">
|
||||||
|
<rank>30</rank>
|
||||||
|
</item>
|
||||||
|
<item id="provider">
|
||||||
|
<rank>40</rank>
|
||||||
|
</item>
|
||||||
|
<item id="redirect_url">
|
||||||
|
<rank>50</rank>
|
||||||
|
</item>
|
||||||
|
<item id="client_id">
|
||||||
|
<rank>60</rank>
|
||||||
|
</item>
|
||||||
|
<item id="client_secret">
|
||||||
|
<rank>70</rank>
|
||||||
|
</item>
|
||||||
|
<item id="mailbox_list">
|
||||||
|
<rank>80</rank>
|
||||||
|
</item>
|
||||||
|
</items>
|
||||||
|
</item>
|
||||||
|
</items>
|
||||||
|
</item>
|
||||||
|
<item id="col:col2">
|
||||||
|
<rank>20</rank>
|
||||||
|
<items>
|
||||||
|
<item id="fieldset:OAuthClient:scope">
|
||||||
|
<rank>10</rank>
|
||||||
|
<items>
|
||||||
|
<item id="used_scope">
|
||||||
|
<rank>10</rank>
|
||||||
|
</item>
|
||||||
|
<item id="scope">
|
||||||
|
<rank>20</rank>
|
||||||
|
</item>
|
||||||
|
<item id="advanced_scope">
|
||||||
|
<rank>30</rank>
|
||||||
|
</item>
|
||||||
|
<item id="used_for_smtp">
|
||||||
|
<rank>40</rank>
|
||||||
|
</item>
|
||||||
|
</items>
|
||||||
|
</item>
|
||||||
|
</items>
|
||||||
|
</item>
|
||||||
|
</items>
|
||||||
|
</details>
|
||||||
|
<list>
|
||||||
|
<items>
|
||||||
|
<item id="provider">
|
||||||
|
<rank>10</rank>
|
||||||
|
</item>
|
||||||
|
<item id="status">
|
||||||
|
<rank>10</rank>
|
||||||
|
</item>
|
||||||
|
</items>
|
||||||
|
</list>
|
||||||
|
<standard_search>
|
||||||
|
<items>
|
||||||
|
<item id="name">
|
||||||
|
<rank>10</rank>
|
||||||
|
</item>
|
||||||
|
<item id="provider">
|
||||||
|
<rank>10</rank>
|
||||||
|
</item>
|
||||||
|
<item id="status">
|
||||||
|
<rank>10</rank>
|
||||||
|
</item>
|
||||||
|
</items>
|
||||||
|
</standard_search>
|
||||||
|
</presentation>
|
||||||
|
<methods>
|
||||||
|
<method id="PrefillCreationForm">
|
||||||
|
<static>false</static>
|
||||||
|
<access>public</access>
|
||||||
|
<type>Overload-DBObject</type>
|
||||||
|
<code><![CDATA[
|
||||||
|
public function PrefillCreationForm(&$aContextParam)
|
||||||
|
{
|
||||||
|
$this->Set('provider', 'Azure');
|
||||||
|
$this->Set('redirect_url', Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory::GetRedirectUri());
|
||||||
|
$this->Set('scope', 'SMTP, IMAP');
|
||||||
|
|
||||||
|
parent::PrefillCreationForm($aContextParam);
|
||||||
|
}
|
||||||
|
]]></code>
|
||||||
|
</method>
|
||||||
|
<method id="DoCheckToWrite">
|
||||||
|
<static>false</static>
|
||||||
|
<access>public</access>
|
||||||
|
<type>Overload-DBObject</type>
|
||||||
|
<code><![CDATA[ public function DoCheckToWrite()
|
||||||
|
{
|
||||||
|
parent::DoCheckToWrite();
|
||||||
|
|
||||||
|
$aChanges = $this->ListChanges();
|
||||||
|
if (array_key_exists('name', $aChanges) || array_key_exists('used_for_smtp', $aChanges))
|
||||||
|
{
|
||||||
|
$sNewName = $this->Get('name');
|
||||||
|
$sNewUseForSMTP = $this->Get('used_for_smtp');
|
||||||
|
if ($sNewUseForSMTP == 'yes') {
|
||||||
|
$oSearch = DBObjectSearch::FromOQL_AllData("SELECT OAuthClientGoogle WHERE name = :newname AND used_for_smtp = :newuseforsmtp AND id != :id UNION SELECT OAuthClientAzure WHERE name = :newname AND used_for_smtp = :newuseforsmtp AND id != :id");
|
||||||
|
$oSet = new DBObjectSet($oSearch, array(), ['id' => $this->GetKey(), 'newname' => $sNewName, 'newuseforsmtp' => $sNewUseForSMTP]);
|
||||||
|
if ($oSet->Count() > 0)
|
||||||
|
{
|
||||||
|
$this->m_aCheckIssues[] = Dict::Format('OAuthClient:Name/UseForSMTPMustBeUnique', $sNewName, $sNewUseForSMTP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} ]]></code>
|
||||||
|
</method>
|
||||||
|
<method id="ComputeValues">
|
||||||
|
<static>false</static>
|
||||||
|
<access>public</access>
|
||||||
|
<type>Overload-DBObject</type>
|
||||||
|
<code><![CDATA[
|
||||||
|
public function ComputeValues()
|
||||||
|
{
|
||||||
|
parent::ComputeValues();
|
||||||
|
if (empty($this->Get('provider'))) {
|
||||||
|
$this->Set('provider', 'Azure');
|
||||||
|
}
|
||||||
|
if (empty($this->Get('redirect_url'))) {
|
||||||
|
$this->Set('redirect_url', Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory::GetRedirectUri());
|
||||||
|
}
|
||||||
|
if (empty($this->Get('advanced_scope'))) {
|
||||||
|
$this->Set('used_scope', 'simple');
|
||||||
|
if (count($this->Get('scope')->GetValues()) == 0) {
|
||||||
|
$this->Set('scope', 'SMTP, IMAP');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->Set('used_scope', 'advanced');
|
||||||
|
$this->Set('scope', '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]]></code>
|
||||||
|
</method>
|
||||||
|
<method id="GetAttributeFlags">
|
||||||
|
<static>false</static>
|
||||||
|
<access>public</access>
|
||||||
|
<type>Overload-DBObject</type>
|
||||||
|
<code><![CDATA[
|
||||||
|
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
||||||
|
{
|
||||||
|
switch ($sAttCode) {
|
||||||
|
case 'provider':
|
||||||
|
case 'redirect_url':
|
||||||
|
case 'used_scope':
|
||||||
|
return OPT_ATT_READONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
||||||
|
}
|
||||||
|
]]></code>
|
||||||
|
</method>
|
||||||
|
<method id="GetInitialStateAttributeFlags">
|
||||||
|
<static>false</static>
|
||||||
|
<access>public</access>
|
||||||
|
<type>Overload-DBObject</type>
|
||||||
|
<code><![CDATA[
|
||||||
|
public function GetInitialStateAttributeFlags($sAttCode, &$aReasons = array())
|
||||||
|
{
|
||||||
|
switch ($sAttCode) {
|
||||||
|
case 'provider':
|
||||||
|
case 'redirect_url':
|
||||||
|
case 'used_scope':
|
||||||
|
return OPT_ATT_READONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::GetInitialStateAttributeFlags($sAttCode, $aReasons);
|
||||||
|
}
|
||||||
|
]]></code>
|
||||||
|
</method>
|
||||||
|
<method id="GetDefaultMailServer">
|
||||||
|
<static>false</static>
|
||||||
|
<access>public</access>
|
||||||
|
<code><![CDATA[
|
||||||
|
public function GetDefaultMailServer()
|
||||||
|
{
|
||||||
|
return 'outlook.office365.com';
|
||||||
|
}
|
||||||
|
]]></code>
|
||||||
|
</method>
|
||||||
|
<method id="GetScope">
|
||||||
|
<static>false</static>
|
||||||
|
<access>public</access>
|
||||||
|
<code><![CDATA[
|
||||||
|
public function GetScope()
|
||||||
|
{
|
||||||
|
if (!empty($this->Get('advanced_scope'))) {
|
||||||
|
return $this->Get('advanced_scope');
|
||||||
|
}
|
||||||
|
$aScopes = $this->Get('scope')->GetValues();
|
||||||
|
$aRawScopes = ['offline_access'];
|
||||||
|
foreach ($aScopes as $sScope) {
|
||||||
|
switch ($sScope) {
|
||||||
|
case 'SMTP':
|
||||||
|
$aRawScopes[] = 'https://outlook.office.com/SMTP.Send';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'IMAP':
|
||||||
|
$aRawScopes[] = 'https://outlook.office.com/IMAP.AccessAsUser.All';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return implode(' ', $aRawScopes);
|
||||||
|
}
|
||||||
|
]]></code>
|
||||||
|
</method>
|
||||||
|
</methods>
|
||||||
|
</class>
|
||||||
|
<class id="OAuthClientGoogle" _delta="define">
|
||||||
|
<parent>OAuthClient</parent>
|
||||||
|
<properties>
|
||||||
|
<category>grant_by_profile,application</category>
|
||||||
|
<abstract>false</abstract>
|
||||||
|
<key_type>autoincrement</key_type>
|
||||||
|
<db_table>priv_oauth_client_google</db_table>
|
||||||
|
<db_key_field>id</db_key_field>
|
||||||
|
<db_final_class_field/>
|
||||||
|
<naming>
|
||||||
|
<attributes>
|
||||||
|
<attribute id="provider"/>
|
||||||
|
<attribute id="name"/>
|
||||||
|
</attributes>
|
||||||
|
</naming>
|
||||||
|
<reconciliation>
|
||||||
|
<attributes>
|
||||||
|
<attribute id="provider"/>
|
||||||
|
<attribute id="name"/>
|
||||||
|
</attributes>
|
||||||
|
</reconciliation>
|
||||||
|
<uniqueness_rules>
|
||||||
|
<rule id="server">
|
||||||
|
<attributes>
|
||||||
|
<attribute id="provider"/>
|
||||||
|
<attribute id="client_id"/>
|
||||||
|
<attribute id="client_secret"/>
|
||||||
|
</attributes>
|
||||||
|
<is_blocking>true</is_blocking>
|
||||||
|
</rule>
|
||||||
|
</uniqueness_rules>
|
||||||
|
<style>
|
||||||
|
<icon/>
|
||||||
|
</style>
|
||||||
|
</properties>
|
||||||
|
<fields>
|
||||||
|
<field id="scope" xsi:type="AttributeEnumSet">
|
||||||
|
<always_load_in_tables>true</always_load_in_tables>
|
||||||
|
<values>
|
||||||
|
<value id="SMTP">
|
||||||
|
<code>SMTP</code>
|
||||||
|
</value>
|
||||||
|
<value id="IMAP">
|
||||||
|
<code>IMAP</code>
|
||||||
|
</value>
|
||||||
|
</values>
|
||||||
|
<sql>scope</sql>
|
||||||
|
<default_value>SMTP,IMAP</default_value>
|
||||||
|
<is_null_allowed>true</is_null_allowed>
|
||||||
|
</field>
|
||||||
|
<field id="advanced_scope" xsi:type="AttributeString">
|
||||||
|
<sql>advanced_scope</sql>
|
||||||
|
<default_value/>
|
||||||
|
<is_null_allowed>true</is_null_allowed>
|
||||||
|
</field>
|
||||||
|
<field id="used_scope" xsi:type="AttributeEnum">
|
||||||
|
<always_load_in_tables>true</always_load_in_tables>
|
||||||
|
<values>
|
||||||
|
<value id="simple">
|
||||||
|
<code>simple</code>
|
||||||
|
</value>
|
||||||
|
<value id="advanced">
|
||||||
|
<code>advanced</code>
|
||||||
|
</value>
|
||||||
|
</values>
|
||||||
|
<sql>used_scope</sql>
|
||||||
|
<default_value>simple</default_value>
|
||||||
|
<is_null_allowed>false</is_null_allowed>
|
||||||
|
<dependencies>
|
||||||
|
<attribute id="scope"/>
|
||||||
|
<attribute id="advanced_scope"/>
|
||||||
|
</dependencies>
|
||||||
|
</field>
|
||||||
|
<field id="used_for_smtp" xsi:type="AttributeEnum">
|
||||||
|
<always_load_in_tables>true</always_load_in_tables>
|
||||||
|
<values>
|
||||||
|
<value id="yes">
|
||||||
|
<code>yes</code>
|
||||||
|
</value>
|
||||||
|
<value id="no">
|
||||||
|
<code>no</code>
|
||||||
|
</value>
|
||||||
|
</values>
|
||||||
|
<sql>used_for_smtp</sql>
|
||||||
|
<default_value>no</default_value>
|
||||||
|
<is_null_allowed>true</is_null_allowed>
|
||||||
|
</field>
|
||||||
|
</fields>
|
||||||
|
<presentation>
|
||||||
|
<details>
|
||||||
|
<items>
|
||||||
|
<item id="col:col1">
|
||||||
|
<rank>10</rank>
|
||||||
|
<items>
|
||||||
|
<item id="fieldset:OAuthClient:baseinfo">
|
||||||
|
<rank>10</rank>
|
||||||
|
<items>
|
||||||
|
<item id="name">
|
||||||
|
<rank>10</rank>
|
||||||
|
</item>
|
||||||
|
<item id="status">
|
||||||
|
<rank>20</rank>
|
||||||
|
</item>
|
||||||
|
<item id="description">
|
||||||
|
<rank>30</rank>
|
||||||
|
</item>
|
||||||
|
<item id="provider">
|
||||||
|
<rank>40</rank>
|
||||||
|
</item>
|
||||||
|
<item id="redirect_url">
|
||||||
|
<rank>50</rank>
|
||||||
|
</item>
|
||||||
|
<item id="client_id">
|
||||||
|
<rank>60</rank>
|
||||||
|
</item>
|
||||||
|
<item id="client_secret">
|
||||||
|
<rank>70</rank>
|
||||||
|
</item>
|
||||||
|
<item id="mailbox_list">
|
||||||
|
<rank>80</rank>
|
||||||
|
</item>
|
||||||
|
</items>
|
||||||
|
</item>
|
||||||
|
</items>
|
||||||
|
</item>
|
||||||
|
<item id="col:col2">
|
||||||
|
<rank>20</rank>
|
||||||
|
<items>
|
||||||
|
<item id="fieldset:OAuthClient:scope">
|
||||||
|
<rank>10</rank>
|
||||||
|
<items>
|
||||||
|
<item id="used_scope">
|
||||||
|
<rank>10</rank>
|
||||||
|
</item>
|
||||||
|
<item id="scope">
|
||||||
|
<rank>20</rank>
|
||||||
|
</item>
|
||||||
|
<item id="advanced_scope">
|
||||||
|
<rank>30</rank>
|
||||||
|
</item>
|
||||||
|
<item id="used_for_smtp">
|
||||||
|
<rank>40</rank>
|
||||||
|
</item>
|
||||||
|
</items>
|
||||||
|
</item>
|
||||||
|
</items>
|
||||||
|
</item>
|
||||||
|
</items>
|
||||||
|
</details>
|
||||||
|
<list>
|
||||||
|
<items>
|
||||||
|
<item id="provider">
|
||||||
|
<rank>10</rank>
|
||||||
|
</item>
|
||||||
|
<item id="status">
|
||||||
|
<rank>10</rank>
|
||||||
|
</item>
|
||||||
|
</items>
|
||||||
|
</list>
|
||||||
|
<standard_search>
|
||||||
|
<items>
|
||||||
|
<item id="name">
|
||||||
|
<rank>10</rank>
|
||||||
|
</item>
|
||||||
|
<item id="provider">
|
||||||
|
<rank>10</rank>
|
||||||
|
</item>
|
||||||
|
<item id="status">
|
||||||
|
<rank>10</rank>
|
||||||
|
</item>
|
||||||
|
</items>
|
||||||
|
</standard_search>
|
||||||
|
</presentation>
|
||||||
|
<methods>
|
||||||
|
<method id="PrefillCreationForm">
|
||||||
|
<static>false</static>
|
||||||
|
<access>public</access>
|
||||||
|
<type>Overload-DBObject</type>
|
||||||
|
<code><![CDATA[
|
||||||
|
public function PrefillCreationForm(&$aContextParam)
|
||||||
|
{
|
||||||
|
$this->Set('provider', 'Google');
|
||||||
|
$this->Set('redirect_url', Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory::GetRedirectUri());
|
||||||
|
$this->Set('scope', 'SMTP, IMAP');
|
||||||
|
|
||||||
|
parent::PrefillCreationForm($aContextParam);
|
||||||
|
}
|
||||||
|
]]></code>
|
||||||
|
</method>
|
||||||
|
<method id="DoCheckToWrite">
|
||||||
|
<static>false</static>
|
||||||
|
<access>public</access>
|
||||||
|
<type>Overload-DBObject</type>
|
||||||
|
<code><![CDATA[ public function DoCheckToWrite()
|
||||||
|
{
|
||||||
|
parent::DoCheckToWrite();
|
||||||
|
|
||||||
|
$aChanges = $this->ListChanges();
|
||||||
|
if (array_key_exists('name', $aChanges) || array_key_exists('used_for_smtp', $aChanges))
|
||||||
|
{
|
||||||
|
$sNewName = $this->Get('name');
|
||||||
|
$sNewUseForSMTP = $this->Get('used_for_smtp');
|
||||||
|
if ($sNewUseForSMTP == 'yes') {
|
||||||
|
$oSearch = DBObjectSearch::FromOQL_AllData("SELECT OAuthClientGoogle WHERE name = :newname AND used_for_smtp = :newuseforsmtp AND id != :id UNION SELECT OAuthClientAzure WHERE name = :newname AND used_for_smtp = :newuseforsmtp AND id != :id");
|
||||||
|
$oSet = new DBObjectSet($oSearch, array(), ['id' => $this->GetKey(), 'newname' => $sNewName, 'newuseforsmtp' => $sNewUseForSMTP]);
|
||||||
|
if ($oSet->Count() > 0)
|
||||||
|
{
|
||||||
|
$this->m_aCheckIssues[] = Dict::Format('OAuthClient:Name/UseForSMTPMustBeUnique', $sNewName, $sNewUseForSMTP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} ]]></code>
|
||||||
|
</method>
|
||||||
|
<method id="ComputeValues">
|
||||||
|
<static>false</static>
|
||||||
|
<access>public</access>
|
||||||
|
<type>Overload-DBObject</type>
|
||||||
|
<code><![CDATA[
|
||||||
|
public function ComputeValues()
|
||||||
|
{
|
||||||
|
parent::ComputeValues();
|
||||||
|
if (empty($this->Get('provider'))) {
|
||||||
|
$this->Set('provider', 'Google');
|
||||||
|
}
|
||||||
|
if (empty($this->Get('redirect_url'))) {
|
||||||
|
$this->Set('redirect_url', Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory::GetRedirectUri());
|
||||||
|
}
|
||||||
|
if (empty($this->Get('advanced_scope'))) {
|
||||||
|
$this->Set('used_scope', 'simple');
|
||||||
|
if (count($this->Get('scope')->GetValues()) == 0) {
|
||||||
|
$this->Set('scope', 'SMTP, IMAP');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->Set('used_scope', 'advanced');
|
||||||
|
$this->Set('scope', '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]]></code>
|
||||||
|
</method>
|
||||||
|
<method id="GetAttributeFlags">
|
||||||
|
<static>false</static>
|
||||||
|
<access>public</access>
|
||||||
|
<type>Overload-DBObject</type>
|
||||||
|
<code><![CDATA[
|
||||||
|
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
||||||
|
{
|
||||||
|
switch ($sAttCode) {
|
||||||
|
case 'provider':
|
||||||
|
case 'redirect_url':
|
||||||
|
case 'used_scope':
|
||||||
|
return OPT_ATT_READONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
||||||
|
}
|
||||||
|
]]></code>
|
||||||
|
</method>
|
||||||
|
<method id="GetInitialStateAttributeFlags">
|
||||||
|
<static>false</static>
|
||||||
|
<access>public</access>
|
||||||
|
<type>Overload-DBObject</type>
|
||||||
|
<code><![CDATA[
|
||||||
|
public function GetInitialStateAttributeFlags($sAttCode, &$aReasons = array())
|
||||||
|
{
|
||||||
|
switch ($sAttCode) {
|
||||||
|
case 'provider':
|
||||||
|
case 'redirect_url':
|
||||||
|
case 'used_scope':
|
||||||
|
return OPT_ATT_READONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::GetInitialStateAttributeFlags($sAttCode, $aReasons);
|
||||||
|
}
|
||||||
|
]]></code>
|
||||||
|
</method>
|
||||||
|
<method id="GetDefaultMailServer">
|
||||||
|
<static>false</static>
|
||||||
|
<access>public</access>
|
||||||
|
<code><![CDATA[
|
||||||
|
public function GetDefaultMailServer()
|
||||||
|
{
|
||||||
|
return 'imap.gmail.com';
|
||||||
|
}
|
||||||
|
]]></code>
|
||||||
|
</method>
|
||||||
|
<method id="GetScope">
|
||||||
|
<static>false</static>
|
||||||
|
<access>public</access>
|
||||||
|
<code><![CDATA[
|
||||||
|
public function GetScope()
|
||||||
|
{
|
||||||
|
if (!empty($this->Get('advanced_scope'))) {
|
||||||
|
return $this->Get('advanced_scope');
|
||||||
|
}
|
||||||
|
$aScopes = $this->Get('scope')->GetValues();
|
||||||
|
$aRawScopes = [];
|
||||||
|
foreach ($aScopes as $sScope) {
|
||||||
|
switch ($sScope) {
|
||||||
|
case 'SMTP':
|
||||||
|
$aRawScopes['https://mail.google.com/'] = 'https://mail.google.com/';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'IMAP':
|
||||||
|
$aRawScopes['https://mail.google.com/'] = 'https://mail.google.com/';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return implode(' ', $aRawScopes);
|
||||||
|
}
|
||||||
|
]]></code>
|
||||||
|
</method>
|
||||||
|
</methods>
|
||||||
|
</class>
|
||||||
</classes>
|
</classes>
|
||||||
<menus>
|
<menus>
|
||||||
<menu id="OAuthClient" xsi:type="OQLMenuNode" _delta="define">
|
<menu id="OAuthClient" xsi:type="OQLMenuNode" _delta="define">
|
||||||
@@ -289,13 +929,16 @@
|
|||||||
<do_search>1</do_search>
|
<do_search>1</do_search>
|
||||||
<enable_admin_only>0</enable_admin_only>
|
<enable_admin_only>0</enable_admin_only>
|
||||||
<enable_class>OAuthClient</enable_class>
|
<enable_class>OAuthClient</enable_class>
|
||||||
<enable_action>UR_ACTION_READ</enable_action>
|
<enable_action>UR_ACTION_MODIFY</enable_action>
|
||||||
</menu>
|
</menu>
|
||||||
</menus>
|
</menus>
|
||||||
<user_rights>
|
<user_rights>
|
||||||
<groups>
|
<groups>
|
||||||
|
<group id="OauthConnection" _delta="define">
|
||||||
|
<classes>
|
||||||
|
<class id="OAuthClient"/>
|
||||||
|
</classes>
|
||||||
|
</group>
|
||||||
</groups>
|
</groups>
|
||||||
<profiles>
|
|
||||||
</profiles>
|
|
||||||
</user_rights>
|
</user_rights>
|
||||||
</itop_design>
|
</itop_design>
|
||||||
|
|||||||
@@ -21,6 +21,11 @@ Dict::Add('EN US', 'English', 'English', [
|
|||||||
'itop-oauth-client:Message:MissingToken' => 'Generate access token before using this OAuth client',
|
'itop-oauth-client:Message:MissingToken' => 'Generate access token before using this OAuth client',
|
||||||
'itop-oauth-client:Message:TokenCreated' => 'Access token created',
|
'itop-oauth-client:Message:TokenCreated' => 'Access token created',
|
||||||
'itop-oauth-client:Message:TokenRecreated' => 'Access token regenerated',
|
'itop-oauth-client:Message:TokenRecreated' => 'Access token regenerated',
|
||||||
|
|
||||||
|
'OAuthClient:Name/UseForSMTPMustBeUnique' => 'The combination Login (%1$s) and Use for SMTP (%2$s) has already be used for OAuth Client',
|
||||||
|
|
||||||
|
'OAuthClient:baseinfo' => 'Base Information',
|
||||||
|
'OAuthClient:scope' => 'Scope',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -32,19 +37,17 @@ Dict::Add('EN US', 'English', 'English', [
|
|||||||
'Class:OAuthClient/Attribute:provider' => 'Provider',
|
'Class:OAuthClient/Attribute:provider' => 'Provider',
|
||||||
'Class:OAuthClient/Attribute:provider+' => '',
|
'Class:OAuthClient/Attribute:provider+' => '',
|
||||||
'Class:OAuthClient/Attribute:name' => 'Login',
|
'Class:OAuthClient/Attribute:name' => 'Login',
|
||||||
'Class:OAuthClient/Attribute:name+' => '',
|
'Class:OAuthClient/Attribute:name+' => 'In general, this is your email address',
|
||||||
'Class:OAuthClient/Attribute:scope' => 'Scope',
|
|
||||||
'Class:OAuthClient/Attribute:scope+' => '',
|
|
||||||
'Class:OAuthClient/Attribute:status' => 'Status',
|
'Class:OAuthClient/Attribute:status' => 'Status',
|
||||||
'Class:OAuthClient/Attribute:status+' => '',
|
'Class:OAuthClient/Attribute:status+' => 'After creation, use the action “Generate access token” to be able to use this OAuth client',
|
||||||
'Class:OAuthClient/Attribute:status/Value:active' => 'Access token generated',
|
'Class:OAuthClient/Attribute:status/Value:active' => 'Access token generated',
|
||||||
'Class:OAuthClient/Attribute:status/Value:inactive' => 'No Access token',
|
'Class:OAuthClient/Attribute:status/Value:inactive' => 'No Access token',
|
||||||
'Class:OAuthClient/Attribute:description' => 'Description',
|
'Class:OAuthClient/Attribute:description' => 'Description',
|
||||||
'Class:OAuthClient/Attribute:description+' => '',
|
'Class:OAuthClient/Attribute:description+' => '',
|
||||||
'Class:OAuthClient/Attribute:client_id' => 'Client id',
|
'Class:OAuthClient/Attribute:client_id' => 'Client id',
|
||||||
'Class:OAuthClient/Attribute:client_id+' => '',
|
'Class:OAuthClient/Attribute:client_id+' => 'A long string of characters provided by your OAuth2 provider',
|
||||||
'Class:OAuthClient/Attribute:client_secret' => 'Client secret',
|
'Class:OAuthClient/Attribute:client_secret' => 'Client secret',
|
||||||
'Class:OAuthClient/Attribute:client_secret+' => '',
|
'Class:OAuthClient/Attribute:client_secret+' => 'Another long string of characters provided by your OAuth2 provider',
|
||||||
'Class:OAuthClient/Attribute:refresh_token' => 'Refresh token',
|
'Class:OAuthClient/Attribute:refresh_token' => 'Refresh token',
|
||||||
'Class:OAuthClient/Attribute:refresh_token+' => '',
|
'Class:OAuthClient/Attribute:refresh_token+' => '',
|
||||||
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Refresh token expiration',
|
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Refresh token expiration',
|
||||||
@@ -54,7 +57,7 @@ Dict::Add('EN US', 'English', 'English', [
|
|||||||
'Class:OAuthClient/Attribute:token_expiration' => 'Access token expiration',
|
'Class:OAuthClient/Attribute:token_expiration' => 'Access token expiration',
|
||||||
'Class:OAuthClient/Attribute:token_expiration+' => '',
|
'Class:OAuthClient/Attribute:token_expiration+' => '',
|
||||||
'Class:OAuthClient/Attribute:redirect_url' => 'Redirect url',
|
'Class:OAuthClient/Attribute:redirect_url' => 'Redirect url',
|
||||||
'Class:OAuthClient/Attribute:redirect_url+' => '',
|
'Class:OAuthClient/Attribute:redirect_url+' => 'This url must be copied in the OAuth2 configuration of the provider',
|
||||||
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list',
|
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list',
|
||||||
'Class:OAuthClient/Attribute:mailbox_list+' => '',
|
'Class:OAuthClient/Attribute:mailbox_list+' => '',
|
||||||
]);
|
]);
|
||||||
@@ -62,17 +65,53 @@ Dict::Add('EN US', 'English', 'English', [
|
|||||||
//
|
//
|
||||||
// Class: OAuthClientAzure
|
// Class: OAuthClientAzure
|
||||||
//
|
//
|
||||||
Dict::Add('EN US', 'English', 'English', [
|
|
||||||
|
Dict::Add('EN US', 'English', 'English', array(
|
||||||
'Class:OAuthClientAzure' => 'OAuth client for Microsoft Azure',
|
'Class:OAuthClientAzure' => 'OAuth client for Microsoft Azure',
|
||||||
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)',
|
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)',
|
||||||
|
'Class:OAuthClientAzure/Attribute:scope' => 'Scope',
|
||||||
]);
|
'Class:OAuthClientAzure/Attribute:scope+' => 'Usually default selection is appropriate',
|
||||||
|
'Class:OAuthClientAzure/Attribute:scope/Value:SMTP' => 'SMTP',
|
||||||
|
'Class:OAuthClientAzure/Attribute:scope/Value:SMTP+' => '',
|
||||||
|
'Class:OAuthClientAzure/Attribute:scope/Value:IMAP' => 'IMAP',
|
||||||
|
'Class:OAuthClientAzure/Attribute:scope/Value:IMAP+' => '',
|
||||||
|
'Class:OAuthClientAzure/Attribute:advanced_scope' => 'Advanced scope',
|
||||||
|
'Class:OAuthClientAzure/Attribute:advanced_scope+' => 'As soon as you enter something here it takes precedence on the “Scope” selection which is then ignored',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_scope' => 'Used scope',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_scope+' => '',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_scope/Value:simple' => 'Simple',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_scope/Value:simple+' => '',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_scope/Value:advanced' => 'Advanced',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_scope/Value:advanced+' => '',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_for_smtp' => 'Used for SMTP',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_for_smtp+' => 'At least one OAuth client must have this flag to “Yes”, if you want iTop to use it for sending mails',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_for_smtp/Value:yes' => 'Yes',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_for_smtp/Value:no' => 'No',
|
||||||
|
));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Class: OAuthClientGoogle
|
// Class: OAuthClientGoogle
|
||||||
//
|
//
|
||||||
Dict::Add('EN US', 'English', 'English', [
|
|
||||||
|
Dict::Add('EN US', 'English', 'English', array(
|
||||||
'Class:OAuthClientGoogle' => 'OAuth client for Google',
|
'Class:OAuthClientGoogle' => 'OAuth client for Google',
|
||||||
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)',
|
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)',
|
||||||
]);
|
'Class:OAuthClientGoogle/Attribute:scope' => 'Scope',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:scope+' => 'Usually default selection is appropriate',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:scope/Value:SMTP' => 'SMTP',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:scope/Value:SMTP+' => '',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:scope/Value:IMAP' => 'IMAP',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:scope/Value:IMAP+' => '',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:advanced_scope' => 'Advanced scope',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:advanced_scope+' => 'As soon as you enter something here it takes precedence on the “Scope” selection which is then ignored',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:used_scope' => 'Used scope',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:used_scope+' => '',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:used_scope/Value:simple' => 'Simple',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:used_scope/Value:simple+' => '',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:used_scope/Value:advanced' => 'Advanced',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:used_scope/Value:advanced+' => '',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:used_for_smtp' => 'Used for SMTP',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:used_for_smtp+' => 'At least one OAuth client must have this flag to “Yes”, if you want iTop to use it for sending mails',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:used_for_smtp/Value:yes' => 'Yes',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:used_for_smtp/Value:no' => 'No',
|
||||||
|
));
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
* @copyright Copyright (C) 2013 XXXXX
|
* @copyright Copyright (C) 2013 XXXXX
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Dict::Add('FR FR', 'French', 'Français', [
|
Dict::Add('FR FR', 'French', 'Français', [
|
||||||
'Menu:CreateMailbox' => 'Créer une boite mail...',
|
'Menu:CreateMailbox' => 'Créer une boite mail...',
|
||||||
'Menu:OAuthClient' => 'Client OAuth',
|
'Menu:OAuthClient' => 'Client OAuth',
|
||||||
@@ -20,6 +21,11 @@ Dict::Add('FR FR', 'French', 'Français', [
|
|||||||
'itop-oauth-client:Message:MissingToken' => 'Générez le jeton d\'accès avant d\'utiliser ce client OAuth',
|
'itop-oauth-client:Message:MissingToken' => 'Générez le jeton d\'accès avant d\'utiliser ce client OAuth',
|
||||||
'itop-oauth-client:Message:TokenCreated' => 'Le jeton d\'accès à été créé',
|
'itop-oauth-client:Message:TokenCreated' => 'Le jeton d\'accès à été créé',
|
||||||
'itop-oauth-client:Message:TokenRecreated' => 'Le jeton d\'accès à été renouvelé',
|
'itop-oauth-client:Message:TokenRecreated' => 'Le jeton d\'accès à été renouvelé',
|
||||||
|
|
||||||
|
'OAuthClient:Name/UseForSMTPMustBeUnique' => 'La combinaison Login (%1$s) and Utilisé pour SMTP (%2$s) a déjà été utilisée pour OAuth Client',
|
||||||
|
|
||||||
|
'OAuthClient:baseinfo' => 'Information',
|
||||||
|
'OAuthClient:scope' => 'Scope',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -31,15 +37,17 @@ Dict::Add('FR FR', 'French', 'Français', [
|
|||||||
'Class:OAuthClient/Attribute:provider' => 'Fournisseur',
|
'Class:OAuthClient/Attribute:provider' => 'Fournisseur',
|
||||||
'Class:OAuthClient/Attribute:provider+' => '',
|
'Class:OAuthClient/Attribute:provider+' => '',
|
||||||
'Class:OAuthClient/Attribute:name' => 'Login',
|
'Class:OAuthClient/Attribute:name' => 'Login',
|
||||||
'Class:OAuthClient/Attribute:name+' => '',
|
'Class:OAuthClient/Attribute:name+' => 'L\'adresse email à utiliser chez ce fournisseur',
|
||||||
'Class:OAuthClient/Attribute:scope' => 'Niveaux d\'accès',
|
'Class:OAuthClient/Attribute:status' => 'Statut',
|
||||||
'Class:OAuthClient/Attribute:scope+' => '',
|
'Class:OAuthClient/Attribute:status+' => 'Après la création, effectuer l\'action \'Créer un jeton d\'accès...\' pour activer ce client OAuth',
|
||||||
|
'Class:OAuthClient/Attribute:status/Value:active' => 'Jeton d\'accès créé',
|
||||||
|
'Class:OAuthClient/Attribute:status/Value:inactive' => 'Pas de jeton d\'accès',
|
||||||
'Class:OAuthClient/Attribute:description' => 'Description',
|
'Class:OAuthClient/Attribute:description' => 'Description',
|
||||||
'Class:OAuthClient/Attribute:description+' => '',
|
'Class:OAuthClient/Attribute:description+' => '',
|
||||||
'Class:OAuthClient/Attribute:client_id' => 'ID Client',
|
'Class:OAuthClient/Attribute:client_id' => 'ID Client',
|
||||||
'Class:OAuthClient/Attribute:client_id+' => '',
|
'Class:OAuthClient/Attribute:client_id+' => 'Recopier la chaine fournie par votre fournisseur OAuth2',
|
||||||
'Class:OAuthClient/Attribute:client_secret' => 'Code secret du client',
|
'Class:OAuthClient/Attribute:client_secret' => 'Code secret du client',
|
||||||
'Class:OAuthClient/Attribute:client_secret+' => '',
|
'Class:OAuthClient/Attribute:client_secret+' => 'Recopier l\'information fournie par votre fournisseur OAuth2',
|
||||||
'Class:OAuthClient/Attribute:refresh_token' => 'Jeton de renouvellement',
|
'Class:OAuthClient/Attribute:refresh_token' => 'Jeton de renouvellement',
|
||||||
'Class:OAuthClient/Attribute:refresh_token+' => '',
|
'Class:OAuthClient/Attribute:refresh_token+' => '',
|
||||||
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Date d\'expiration du jeton de renouvellement',
|
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Date d\'expiration du jeton de renouvellement',
|
||||||
@@ -49,7 +57,7 @@ Dict::Add('FR FR', 'French', 'Français', [
|
|||||||
'Class:OAuthClient/Attribute:token_expiration' => 'Date d\'expiration du jeton d\'accès',
|
'Class:OAuthClient/Attribute:token_expiration' => 'Date d\'expiration du jeton d\'accès',
|
||||||
'Class:OAuthClient/Attribute:token_expiration+' => '',
|
'Class:OAuthClient/Attribute:token_expiration+' => '',
|
||||||
'Class:OAuthClient/Attribute:redirect_url' => 'URL de redirection',
|
'Class:OAuthClient/Attribute:redirect_url' => 'URL de redirection',
|
||||||
'Class:OAuthClient/Attribute:redirect_url+' => '',
|
'Class:OAuthClient/Attribute:redirect_url+' => 'Cet URL doit être recopié dans la configuration OAuth2 de votre fournisseur',
|
||||||
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list',
|
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailbox list',
|
||||||
'Class:OAuthClient/Attribute:mailbox_list+' => '',
|
'Class:OAuthClient/Attribute:mailbox_list+' => '',
|
||||||
]);
|
]);
|
||||||
@@ -57,22 +65,52 @@ Dict::Add('FR FR', 'French', 'Français', [
|
|||||||
//
|
//
|
||||||
// Class: OAuthClientAzure
|
// Class: OAuthClientAzure
|
||||||
//
|
//
|
||||||
Dict::Add('FR FR', 'French', 'Français', [
|
|
||||||
|
Dict::Add('FR FR', 'French', 'Français', array(
|
||||||
'Class:OAuthClientAzure' => 'Client OAuth pour Microsoft Azure',
|
'Class:OAuthClientAzure' => 'Client OAuth pour Microsoft Azure',
|
||||||
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)',
|
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)',
|
||||||
|
'Class:OAuthClientAzure/Attribute:scope' => 'Niveaux d\'accès',
|
||||||
]);
|
'Class:OAuthClientAzure/Attribute:scope+' => 'Les niveaux par défaut sont les plus souvent suffisants',
|
||||||
|
'Class:OAuthClientAzure/Attribute:scope/Value:SMTP' => 'SMTP',
|
||||||
|
'Class:OAuthClientAzure/Attribute:scope/Value:SMTP+' => '',
|
||||||
|
'Class:OAuthClientAzure/Attribute:scope/Value:IMAP' => 'IMAP',
|
||||||
|
'Class:OAuthClientAzure/Attribute:scope/Value:IMAP+' => '',
|
||||||
|
'Class:OAuthClientAzure/Attribute:advanced_scope' => 'Niveaux d\'accès avancé',
|
||||||
|
'Class:OAuthClientAzure/Attribute:advanced_scope+' => 'A saisir, lorsque les niveaux prédéfinis ne suffisent pas',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_scope' => 'Niveaux d\'accès utilisés',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_scope+' => '',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_scope/Value:simple' => 'Simple',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_scope/Value:simple+' => '',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_scope/Value:advanced' => 'Avancé',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_scope/Value:advanced+' => '',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_for_smtp' => 'Utilisé pour SMTP',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_for_smtp+' => 'Le Client OAuth utilisé pour l\'envoi d\'emails doit être à \'Oui\'',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_for_smtp/Value:yes' => 'Oui',
|
||||||
|
'Class:OAuthClientAzure/Attribute:used_for_smtp/Value:no' => 'Non',
|
||||||
|
));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Class: OAuthClientGoogle
|
// Class: OAuthClientGoogle
|
||||||
//
|
//
|
||||||
Dict::Add('FR FR', 'French', 'Français', [
|
|
||||||
|
Dict::Add('FR FR', 'French', 'Français', array(
|
||||||
'Class:OAuthClientGoogle' => 'Client OAuth pour Google',
|
'Class:OAuthClientGoogle' => 'Client OAuth pour Google',
|
||||||
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)',
|
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)',
|
||||||
]);
|
'Class:OAuthClientGoogle/Attribute:scope' => 'Niveaux d\'accès',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:scope+' => 'Les niveaux par défaut sont les plus souvent suffisants',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:scope/Value:SMTP' => 'SMTP',
|
||||||
// Additional language entries not present in English dict
|
'Class:OAuthClientGoogle/Attribute:scope/Value:SMTP+' => '',
|
||||||
Dict::Add('FR FR', 'French', 'Français', array(
|
'Class:OAuthClientGoogle/Attribute:scope/Value:IMAP' => 'IMAP',
|
||||||
'Class:OAuthClient/Name' => '%1$s-%%2$~',
|
'Class:OAuthClientGoogle/Attribute:scope/Value:IMAP+' => '',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:advanced_scope' => 'Niveaux d\'accès avancé',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:advanced_scope+' => 'A saisir, lorsque les niveaux prédéfinis ne suffisent pas',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:used_scope' => 'Niveaux d\'accès utilisés',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:used_scope+' => '',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:used_scope/Value:simple' => 'Simple',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:used_scope/Value:advanced' => 'Avancé',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:used_scope/Value:advanced+' => '',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:used_for_smtp' => 'Utilisé pour SMTP',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:used_for_smtp+' => 'Le Client OAuth utilisé pour l\'envoi d\'emails doit être à \'Oui\'',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:used_for_smtp/Value:yes' => 'Oui',
|
||||||
|
'Class:OAuthClientGoogle/Attribute:used_for_smtp/Value:no' => 'Non',
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -25,9 +25,8 @@ SetupWebPage::AddModule(
|
|||||||
'datamodel' => array(
|
'datamodel' => array(
|
||||||
'vendor/autoload.php',
|
'vendor/autoload.php',
|
||||||
'model.itop-oauth-client.php', // Contains the PHP code generated by the "compilation" of datamodel.remote-authent-oauth.xml
|
'model.itop-oauth-client.php', // Contains the PHP code generated by the "compilation" of datamodel.remote-authent-oauth.xml
|
||||||
'src/Model/OAuthClientGoogle.php',
|
|
||||||
'src/Model/OAuthClientAzure.php',
|
|
||||||
'src/Service/PopupMenuExtension.php',
|
'src/Service/PopupMenuExtension.php',
|
||||||
|
'src/Service/ApplicationUIExtension.php',
|
||||||
),
|
),
|
||||||
'webservice' => array(
|
'webservice' => array(
|
||||||
|
|
||||||
|
|||||||
@@ -1,128 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
use Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory;
|
|
||||||
|
|
||||||
class OAuthClientAzure extends OAuthClient
|
|
||||||
{
|
|
||||||
public static function Init()
|
|
||||||
{
|
|
||||||
$aParams = [
|
|
||||||
'category' => 'cloud',
|
|
||||||
'key_type' => 'autoincrement',
|
|
||||||
'name_attcode' => ['name', 'scope'],
|
|
||||||
'state_attcode' => '',
|
|
||||||
'reconc_keys' => ['provider', 'name'],
|
|
||||||
'db_table' => 'priv_oauth_client_azure',
|
|
||||||
'db_key_field' => 'id',
|
|
||||||
'icon' => utils::GetAbsoluteUrlModulesRoot().'itop-oauth-client/assets/img/icons8-azure.svg',
|
|
||||||
'db_finalclass_field' => '',
|
|
||||||
'uniqueness_rules' => [
|
|
||||||
'Username for scope' =>
|
|
||||||
[
|
|
||||||
'attributes' => ['name', 'scope'],
|
|
||||||
'filter' => null,
|
|
||||||
'disabled' => false,
|
|
||||||
'is_blocking' => true,
|
|
||||||
],
|
|
||||||
'OAuth Server' =>
|
|
||||||
[
|
|
||||||
'attributes' => ['provider', 'scope', 'client_id', 'client_secret'],
|
|
||||||
'filter' => null,
|
|
||||||
'disabled' => false,
|
|
||||||
'is_blocking' => true,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
MetaModel::Init_Params($aParams);
|
|
||||||
MetaModel::Init_InheritAttributes();
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum('scope', [
|
|
||||||
'allowed_values' => new ValueSetEnum('EMail'),
|
|
||||||
'display_style' => 'list',
|
|
||||||
'sql' => 'scope',
|
|
||||||
'default_value' => 'EMail',
|
|
||||||
'is_null_allowed' => false,
|
|
||||||
'depends_on' => [],
|
|
||||||
'always_load_in_tables' => true,
|
|
||||||
]));
|
|
||||||
|
|
||||||
MetaModel::Init_SetZListItems('details', [
|
|
||||||
'name',
|
|
||||||
'status',
|
|
||||||
'description',
|
|
||||||
'provider',
|
|
||||||
'scope',
|
|
||||||
'redirect_url',
|
|
||||||
'client_id',
|
|
||||||
'client_secret',
|
|
||||||
'mailbox_list',
|
|
||||||
]);
|
|
||||||
MetaModel::Init_SetZListItems('standard_search', [
|
|
||||||
'name',
|
|
||||||
'provider',
|
|
||||||
'status',
|
|
||||||
]);
|
|
||||||
MetaModel::Init_SetZListItems('list', [
|
|
||||||
'status',
|
|
||||||
'provider',
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function PrefillCreationForm(&$aContextParam)
|
|
||||||
{
|
|
||||||
$this->Set('provider', 'Azure');
|
|
||||||
$this->Set('redirect_url', OAuthClientProviderFactory::GetRedirectUri());
|
|
||||||
|
|
||||||
parent::PrefillCreationForm($aContextParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compute read-only values
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
* @throws \ArchivedObjectException
|
|
||||||
* @throws \CoreException
|
|
||||||
* @throws \CoreUnexpectedValue
|
|
||||||
*/
|
|
||||||
public function ComputeValues()
|
|
||||||
{
|
|
||||||
parent::ComputeValues();
|
|
||||||
if (empty($this->Get('provider'))) {
|
|
||||||
$this->Set('provider', 'Azure');
|
|
||||||
}
|
|
||||||
if (empty($this->Get('redirect_url'))) {
|
|
||||||
$this->Set('redirect_url', OAuthClientProviderFactory::GetRedirectUri());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
|
||||||
{
|
|
||||||
if ($sAttCode == 'provider' || $sAttCode == 'redirect_url') {
|
|
||||||
return OPT_ATT_READONLY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetInitialStateAttributeFlags($sAttCode, &$aReasons = array())
|
|
||||||
{
|
|
||||||
if ($sAttCode == 'provider' || $sAttCode == 'redirect_url') {
|
|
||||||
return OPT_ATT_READONLY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return parent::GetInitialStateAttributeFlags($sAttCode, $aReasons);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetDefaultMailServer()
|
|
||||||
{
|
|
||||||
return 'outlook.office365.com';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetScope()
|
|
||||||
{
|
|
||||||
return 'https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/SMTP.Send offline_access';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
use Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory;
|
|
||||||
|
|
||||||
class OAuthClientGoogle extends OAuthClient
|
|
||||||
{
|
|
||||||
public static function Init()
|
|
||||||
{
|
|
||||||
$aParams = array
|
|
||||||
(
|
|
||||||
'category' => 'cloud',
|
|
||||||
'key_type' => 'autoincrement',
|
|
||||||
'name_attcode' => ['name', 'scope'],
|
|
||||||
'state_attcode' => '',
|
|
||||||
'reconc_keys' => ['provider', 'name'],
|
|
||||||
'db_table' => 'priv_oauth_client_google',
|
|
||||||
'db_key_field' => 'id',
|
|
||||||
'icon' => utils::GetAbsoluteUrlModulesRoot().'itop-oauth-client/assets/img/icons8-google.svg',
|
|
||||||
'db_finalclass_field' => '',
|
|
||||||
'uniqueness_rules' => [
|
|
||||||
'Username for scope' =>
|
|
||||||
[
|
|
||||||
'attributes' => ['name', 'scope'],
|
|
||||||
'filter' => null,
|
|
||||||
'disabled' => false,
|
|
||||||
'is_blocking' => true,
|
|
||||||
],
|
|
||||||
'OAuth Server' =>
|
|
||||||
[
|
|
||||||
'attributes' => ['provider', 'scope', 'client_id', 'client_secret'],
|
|
||||||
'filter' => null,
|
|
||||||
'disabled' => false,
|
|
||||||
'is_blocking' => true,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
);
|
|
||||||
MetaModel::Init_Params($aParams);
|
|
||||||
MetaModel::Init_InheritAttributes();
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum('scope', [
|
|
||||||
'allowed_values' => new ValueSetEnum('EMail'),
|
|
||||||
'display_style' => 'list',
|
|
||||||
'sql' => 'scope',
|
|
||||||
'default_value' => 'EMail',
|
|
||||||
'is_null_allowed' => false,
|
|
||||||
'depends_on' => [],
|
|
||||||
'always_load_in_tables' => true,
|
|
||||||
]));
|
|
||||||
|
|
||||||
MetaModel::Init_SetZListItems('details', [
|
|
||||||
'name',
|
|
||||||
'status',
|
|
||||||
'description',
|
|
||||||
'provider',
|
|
||||||
'scope',
|
|
||||||
'redirect_url',
|
|
||||||
'client_id',
|
|
||||||
'client_secret',
|
|
||||||
'mailbox_list',
|
|
||||||
]);
|
|
||||||
MetaModel::Init_SetZListItems('standard_search', [
|
|
||||||
'name',
|
|
||||||
'provider',
|
|
||||||
'status',
|
|
||||||
]);
|
|
||||||
MetaModel::Init_SetZListItems('list', [
|
|
||||||
'status',
|
|
||||||
'provider',
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function PrefillCreationForm(&$aContextParam)
|
|
||||||
{
|
|
||||||
$this->Set('provider', 'Google');
|
|
||||||
$this->Set('scope', 'EMail');
|
|
||||||
$this->Set('redirect_url', OAuthClientProviderFactory::GetRedirectUri());
|
|
||||||
|
|
||||||
parent::PrefillCreationForm($aContextParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
|
||||||
{
|
|
||||||
if ($sAttCode == 'provider' || $sAttCode == 'scope' || $sAttCode == 'redirect_url') {
|
|
||||||
return OPT_ATT_READONLY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetInitialStateAttributeFlags($sAttCode, &$aReasons = array())
|
|
||||||
{
|
|
||||||
if ($sAttCode == 'provider' || $sAttCode == 'scope' || $sAttCode == 'redirect_url') {
|
|
||||||
return OPT_ATT_READONLY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return parent::GetInitialStateAttributeFlags($sAttCode, $aReasons);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compute read-only values
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
* @throws \ArchivedObjectException
|
|
||||||
* @throws \CoreException
|
|
||||||
* @throws \CoreUnexpectedValue
|
|
||||||
*/
|
|
||||||
public function ComputeValues()
|
|
||||||
{
|
|
||||||
parent::ComputeValues();
|
|
||||||
if (empty($this->Get('provider'))) {
|
|
||||||
$this->Set('provider', 'Google');
|
|
||||||
}
|
|
||||||
if (empty($this->Get('redirect_url'))) {
|
|
||||||
$this->Set('redirect_url', OAuthClientProviderFactory::GetRedirectUri());
|
|
||||||
}
|
|
||||||
if (empty($this->Get('scope'))) {
|
|
||||||
$this->Set('scope', 'EMail');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function GetDefaultMailServer()
|
|
||||||
{
|
|
||||||
return 'imap.gmail.com';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetScope()
|
|
||||||
{
|
|
||||||
return 'https://mail.google.com/';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Combodo\iTop\OAuthClient\Service;
|
||||||
|
|
||||||
|
use AbstractApplicationUIExtension;
|
||||||
|
use OAuthClient;
|
||||||
|
use utils;
|
||||||
|
|
||||||
|
class ApplicationUIExtension extends AbstractApplicationUIExtension
|
||||||
|
{
|
||||||
|
|
||||||
|
public function GetHilightClass($oObject)
|
||||||
|
{
|
||||||
|
if ($oObject instanceof OAuthClient) {
|
||||||
|
// Possible return values are:
|
||||||
|
// HILIGHT_CLASS_CRITICAL, HILIGHT_CLASS_WARNING, HILIGHT_CLASS_OK, HILIGHT_CLASS_NONE
|
||||||
|
$oConfig = utils::GetConfig();
|
||||||
|
if ($oObject->Get('status') == 'inactive') {
|
||||||
|
return HILIGHT_CLASS_WARNING;
|
||||||
|
} elseif ($oObject->Get('used_for_smtp') == 'yes' && $oConfig->Get('email_transport_smtp.username') == $oObject->Get('name')) {
|
||||||
|
return HILIGHT_CLASS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return HILIGHT_CLASS_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -41,7 +41,7 @@ class PopupMenuExtension implements \iPopupMenuExtension
|
|||||||
$sId = $oObj->GetKey();
|
$sId = $oObj->GetKey();
|
||||||
$sAjaxUri = utils::GetAbsoluteUrlModulePage(static::MODULE_CODE, 'ajax.php');
|
$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
|
// 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';
|
$sJSFileUrl = 'env-'.utils::GetCurrentEnvironment().'/'.static::MODULE_CODE.'/assets/js/oauth_connect.js';
|
||||||
$sRedirectUri = OAuthClientProviderFactory::GetRedirectUri();
|
$sRedirectUri = OAuthClientProviderFactory::GetRedirectUri();
|
||||||
$aResult[] = new JSPopupMenuItem(
|
$aResult[] = new JSPopupMenuItem(
|
||||||
$sMenu.' from '.$sObjClass,
|
$sMenu.' from '.$sObjClass,
|
||||||
@@ -51,8 +51,8 @@ class PopupMenuExtension implements \iPopupMenuExtension
|
|||||||
);
|
);
|
||||||
|
|
||||||
if ($bHasToken) {
|
if ($bHasToken) {
|
||||||
$sScope = $oObj->Get('scope');
|
$aScopes = $oObj->Get('scope')->GetValues();
|
||||||
if ($sScope == 'EMail') {
|
if (in_array('IMAP', $aScopes)) {
|
||||||
$aParams = $oAppContext->GetAsHash();
|
$aParams = $oAppContext->GetAsHash();
|
||||||
$sMenu = 'Menu:CreateMailbox';
|
$sMenu = 'Menu:CreateMailbox';
|
||||||
$sObjClass = get_class($oObj);
|
$sObjClass = get_class($oObj);
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{# @copyright Copyright (C) 2010-2022 Combodo SARL #}
|
||||||
|
{# @license http://opensource.org/licenses/AGPL-3.0 #}
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{# @copyright Copyright (C) 2010-2022 Combodo SARL #}
|
||||||
|
{# @license http://opensource.org/licenses/AGPL-3.0 #}
|
||||||
|
|
||||||
|
window.location.href = '{{ sURL|raw }}'
|
||||||
@@ -93,7 +93,7 @@ class ObjectFormManager extends FormManager
|
|||||||
* @since 2.7.6 3.0.0 N°4384 method creation : factorize as this is used twice now
|
* @since 2.7.6 3.0.0 N°4384 method creation : factorize as this is used twice now
|
||||||
* @since 2.7.7 3.0.1 N°4867 now only used once, but we decided to keep this method anyway
|
* @since 2.7.7 3.0.1 N°4867 now only used once, but we decided to keep this method anyway
|
||||||
*/
|
*/
|
||||||
protected static function DecodeFormManagerData($formManagerData)
|
public static function DecodeFormManagerData($formManagerData)
|
||||||
{
|
{
|
||||||
if (is_array($formManagerData)) {
|
if (is_array($formManagerData)) {
|
||||||
return $formManagerData;
|
return $formManagerData;
|
||||||
|
|||||||
@@ -453,7 +453,7 @@ class ObjectFormHandlerHelper
|
|||||||
* @throws \OQLException
|
* @throws \OQLException
|
||||||
*/
|
*/
|
||||||
public function CheckReadFormDataAllowed($sFormManagerData){
|
public function CheckReadFormDataAllowed($sFormManagerData){
|
||||||
$aJsonFromData = json_decode($sFormManagerData, true);
|
$aJsonFromData = ObjectFormManager::DecodeFormManagerData($sFormManagerData);
|
||||||
if(isset($aJsonFromData['formobject_class'])
|
if(isset($aJsonFromData['formobject_class'])
|
||||||
&& isset($aJsonFromData['formobject_id'])
|
&& isset($aJsonFromData['formobject_id'])
|
||||||
&& !$this->oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $aJsonFromData['formobject_class'], $aJsonFromData['formobject_id'])){
|
&& !$this->oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $aJsonFromData['formobject_class'], $aJsonFromData['formobject_id'])){
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ $(function()
|
|||||||
});
|
});
|
||||||
me._updateExtraTabsList();
|
me._updateExtraTabsList();
|
||||||
}, {
|
}, {
|
||||||
root: $('.ibo-tab-container--tabs-list')[0],
|
root: this.element.find(this.js_selectors.tabs_list)[0],
|
||||||
threshold: [0.9] // N°4783 Should be completely visible, but lowering the threshold prevents a bug in the JS Observer API when the window is zoomed in/out, in which case all items respond as being hidden even when they are not.
|
threshold: [0.9] // N°4783 Should be completely visible, but lowering the threshold prevents a bug in the JS Observer API when the window is zoomed in/out, in which case all items respond as being hidden even when they are not.
|
||||||
});
|
});
|
||||||
this.element.find(this.js_selectors.tab_header).each(function(){
|
this.element.find(this.js_selectors.tab_header).each(function(){
|
||||||
|
|||||||
@@ -2,11 +2,6 @@
|
|||||||
|
|
||||||
// autoload.php @generated by Composer
|
// 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';
|
require_once __DIR__ . '/composer/autoload_real.php';
|
||||||
|
|
||||||
return ComposerAutoloaderInit7f81b4a2a468a061c306af5e447a9a9f::getLoader();
|
return ComposerAutoloaderInit7f81b4a2a468a061c306af5e447a9a9f::getLoader();
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ class ClassLoader
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string[] Array of classname => path
|
* @return string[] Array of classname => path
|
||||||
* @psalm-return array<string, string>
|
* @psalm-var array<string, string>
|
||||||
*/
|
*/
|
||||||
public function getClassMap()
|
public function getClassMap()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,26 +21,11 @@ use Composer\Semver\VersionParser;
|
|||||||
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
|
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
|
||||||
*
|
*
|
||||||
* To require its presence, you can require `composer-runtime-api ^2.0`
|
* To require its presence, you can require `composer-runtime-api ^2.0`
|
||||||
*
|
|
||||||
* @final
|
|
||||||
*/
|
*/
|
||||||
class InstalledVersions
|
class InstalledVersions
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var mixed[]|null
|
|
||||||
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
|
||||||
*/
|
|
||||||
private static $installed;
|
private static $installed;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var bool|null
|
|
||||||
*/
|
|
||||||
private static $canGetVendors;
|
private static $canGetVendors;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array[]
|
|
||||||
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
|
||||||
*/
|
|
||||||
private static $installedByVendor = array();
|
private static $installedByVendor = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -243,7 +228,7 @@ class InstalledVersions
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
|
* @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}
|
||||||
*/
|
*/
|
||||||
public static function getRootPackage()
|
public static function getRootPackage()
|
||||||
{
|
{
|
||||||
@@ -257,7 +242,7 @@ class InstalledVersions
|
|||||||
*
|
*
|
||||||
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
||||||
* @return array[]
|
* @return array[]
|
||||||
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
|
* @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}
|
||||||
*/
|
*/
|
||||||
public static function getRawData()
|
public static function getRawData()
|
||||||
{
|
{
|
||||||
@@ -280,7 +265,7 @@ class InstalledVersions
|
|||||||
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
||||||
*
|
*
|
||||||
* @return array[]
|
* @return array[]
|
||||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
|
||||||
*/
|
*/
|
||||||
public static function getAllRawData()
|
public static function getAllRawData()
|
||||||
{
|
{
|
||||||
@@ -303,7 +288,7 @@ class InstalledVersions
|
|||||||
* @param array[] $data A vendor/composer/installed.php data set
|
* @param array[] $data A vendor/composer/installed.php data set
|
||||||
* @return void
|
* @return void
|
||||||
*
|
*
|
||||||
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
|
* @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data
|
||||||
*/
|
*/
|
||||||
public static function reload($data)
|
public static function reload($data)
|
||||||
{
|
{
|
||||||
@@ -313,7 +298,7 @@ class InstalledVersions
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array[]
|
* @return array[]
|
||||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
|
||||||
*/
|
*/
|
||||||
private static function getInstalled()
|
private static function getInstalled()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// autoload_classmap.php @generated by Composer
|
// autoload_classmap.php @generated by Composer
|
||||||
|
|
||||||
$vendorDir = dirname(__DIR__);
|
$vendorDir = dirname(dirname(__FILE__));
|
||||||
$baseDir = dirname($vendorDir);
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// autoload_namespaces.php @generated by Composer
|
// autoload_namespaces.php @generated by Composer
|
||||||
|
|
||||||
$vendorDir = dirname(__DIR__);
|
$vendorDir = dirname(dirname(__FILE__));
|
||||||
$baseDir = dirname($vendorDir);
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// autoload_psr4.php @generated by Composer
|
// autoload_psr4.php @generated by Composer
|
||||||
|
|
||||||
$vendorDir = dirname(__DIR__);
|
$vendorDir = dirname(dirname(__FILE__));
|
||||||
$baseDir = dirname($vendorDir);
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// include_paths.php @generated by Composer
|
// include_paths.php @generated by Composer
|
||||||
|
|
||||||
$vendorDir = dirname(__DIR__);
|
$vendorDir = dirname(dirname(__FILE__));
|
||||||
$baseDir = dirname($vendorDir);
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ if (!(PHP_VERSION_ID >= 70205)) {
|
|||||||
$missingExtensions = array();
|
$missingExtensions = array();
|
||||||
extension_loaded('dom') || $missingExtensions[] = 'dom';
|
extension_loaded('dom') || $missingExtensions[] = 'dom';
|
||||||
extension_loaded('gd') || $missingExtensions[] = 'gd';
|
extension_loaded('gd') || $missingExtensions[] = 'gd';
|
||||||
extension_loaded('iconv') || $missingExtensions[] = 'iconv';
|
|
||||||
extension_loaded('json') || $missingExtensions[] = 'json';
|
extension_loaded('json') || $missingExtensions[] = 'json';
|
||||||
extension_loaded('libxml') || $missingExtensions[] = 'libxml';
|
extension_loaded('libxml') || $missingExtensions[] = 'libxml';
|
||||||
extension_loaded('mysqli') || $missingExtensions[] = 'mysqli';
|
extension_loaded('mysqli') || $missingExtensions[] = 'mysqli';
|
||||||
|
extension_loaded('openssl') || $missingExtensions[] = 'openssl';
|
||||||
extension_loaded('soap') || $missingExtensions[] = 'soap';
|
extension_loaded('soap') || $missingExtensions[] = 'soap';
|
||||||
extension_loaded('tokenizer') || $missingExtensions[] = 'tokenizer';
|
extension_loaded('tokenizer') || $missingExtensions[] = 'tokenizer';
|
||||||
extension_loaded('xml') || $missingExtensions[] = 'xml';
|
extension_loaded('xml') || $missingExtensions[] = 'xml';
|
||||||
|
|||||||
4
lib/thenetworg/oauth2-azure/.gitignore
vendored
4
lib/thenetworg/oauth2-azure/.gitignore
vendored
@@ -3,3 +3,7 @@
|
|||||||
composer.phar
|
composer.phar
|
||||||
composer.lock
|
composer.lock
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
/.idea
|
||||||
|
/.vscode
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ $provider = new TheNetworg\OAuth2\Client\Provider\Azure([
|
|||||||
'clientSecret' => '{azure-client-secret}',
|
'clientSecret' => '{azure-client-secret}',
|
||||||
'redirectUri' => 'https://example.com/callback-url',
|
'redirectUri' => 'https://example.com/callback-url',
|
||||||
//Optional
|
//Optional
|
||||||
'scopes' => 'openid',
|
'scopes' => ['openid'],
|
||||||
//Optional
|
//Optional
|
||||||
'defaultEndPointVersion' => '2.0'
|
'defaultEndPointVersion' => '2.0'
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -22,9 +22,11 @@
|
|||||||
"sso"
|
"sso"
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^5.6|^7.0|^8.0",
|
"ext-json": "*",
|
||||||
|
"ext-openssl": "*",
|
||||||
|
"php": "^7.1|^8.0",
|
||||||
"league/oauth2-client": "~2.0",
|
"league/oauth2-client": "~2.0",
|
||||||
"firebase/php-jwt": "~3.0||~4.0||~5.0"
|
"firebase/php-jwt": "~3.0||~4.0||~5.0||~6.0"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
|||||||
@@ -3,9 +3,13 @@
|
|||||||
namespace TheNetworg\OAuth2\Client\Provider;
|
namespace TheNetworg\OAuth2\Client\Provider;
|
||||||
|
|
||||||
use Firebase\JWT\JWT;
|
use Firebase\JWT\JWT;
|
||||||
|
use Firebase\JWT\JWK;
|
||||||
|
use Firebase\JWT\Key;
|
||||||
use League\OAuth2\Client\Grant\AbstractGrant;
|
use League\OAuth2\Client\Grant\AbstractGrant;
|
||||||
use League\OAuth2\Client\Provider\AbstractProvider;
|
use League\OAuth2\Client\Provider\AbstractProvider;
|
||||||
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
|
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
|
||||||
|
use League\OAuth2\Client\Provider\ResourceOwnerInterface;
|
||||||
|
use League\OAuth2\Client\Token\AccessTokenInterface;
|
||||||
use League\OAuth2\Client\Tool\BearerAuthorizationTrait;
|
use League\OAuth2\Client\Tool\BearerAuthorizationTrait;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use TheNetworg\OAuth2\Client\Grant\JwtBearer;
|
use TheNetworg\OAuth2\Client\Grant\JwtBearer;
|
||||||
@@ -66,7 +70,8 @@ class Azure extends AbstractProvider
|
|||||||
}
|
}
|
||||||
if (!array_key_exists($version, $this->openIdConfiguration[$tenant])) {
|
if (!array_key_exists($version, $this->openIdConfiguration[$tenant])) {
|
||||||
$versionInfix = $this->getVersionUriInfix($version);
|
$versionInfix = $this->getVersionUriInfix($version);
|
||||||
$openIdConfigurationUri = 'https://login.microsoftonline.com/' . $tenant . $versionInfix . '/.well-known/openid-configuration';
|
$openIdConfigurationUri = $this->urlLogin . $tenant . $versionInfix . '/.well-known/openid-configuration?appid=' . $this->clientId;
|
||||||
|
|
||||||
$factory = $this->getRequestFactory();
|
$factory = $this->getRequestFactory();
|
||||||
$request = $factory->getRequestWithOptions(
|
$request = $factory->getRequestWithOptions(
|
||||||
'get',
|
'get',
|
||||||
@@ -80,19 +85,28 @@ class Azure extends AbstractProvider
|
|||||||
return $this->openIdConfiguration[$tenant][$version];
|
return $this->openIdConfiguration[$tenant][$version];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBaseAuthorizationUrl()
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getBaseAuthorizationUrl(): string
|
||||||
{
|
{
|
||||||
$openIdConfiguration = $this->getOpenIdConfiguration($this->tenant, $this->defaultEndPointVersion);
|
$openIdConfiguration = $this->getOpenIdConfiguration($this->tenant, $this->defaultEndPointVersion);
|
||||||
return $openIdConfiguration['authorization_endpoint'];
|
return $openIdConfiguration['authorization_endpoint'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBaseAccessTokenUrl(array $params)
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getBaseAccessTokenUrl(array $params): string
|
||||||
{
|
{
|
||||||
$openIdConfiguration = $this->getOpenIdConfiguration($this->tenant, $this->defaultEndPointVersion);
|
$openIdConfiguration = $this->getOpenIdConfiguration($this->tenant, $this->defaultEndPointVersion);
|
||||||
return $openIdConfiguration['token_endpoint'];
|
return $openIdConfiguration['token_endpoint'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAccessToken($grant, array $options = [])
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getAccessToken($grant, array $options = []): AccessTokenInterface
|
||||||
{
|
{
|
||||||
if ($this->defaultEndPointVersion != self::ENDPOINT_VERSION_2_0) {
|
if ($this->defaultEndPointVersion != self::ENDPOINT_VERSION_2_0) {
|
||||||
// Version 2.0 does not support the resources parameter
|
// Version 2.0 does not support the resources parameter
|
||||||
@@ -106,14 +120,21 @@ class Azure extends AbstractProvider
|
|||||||
return parent::getAccessToken($grant, $options);
|
return parent::getAccessToken($grant, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getResourceOwner(\League\OAuth2\Client\Token\AccessToken $token)
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getResourceOwner(\League\OAuth2\Client\Token\AccessToken $token): ResourceOwnerInterface
|
||||||
{
|
{
|
||||||
$data = $token->getIdTokenClaims();
|
$data = $token->getIdTokenClaims();
|
||||||
return $this->createResourceOwner($data, $token);
|
return $this->createResourceOwner($data, $token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getResourceOwnerDetailsUrl(\League\OAuth2\Client\Token\AccessToken $token)
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getResourceOwnerDetailsUrl(\League\OAuth2\Client\Token\AccessToken $token): string
|
||||||
{
|
{
|
||||||
|
return ''; // shouldn't that return such a URL?
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getObjects($tenant, $ref, &$accessToken, $headers = [])
|
public function getObjects($tenant, $ref, &$accessToken, $headers = [])
|
||||||
@@ -164,11 +185,11 @@ class Azure extends AbstractProvider
|
|||||||
return 'https://' . $openIdConfiguration['msgraph_host'];
|
return 'https://' . $openIdConfiguration['msgraph_host'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get($ref, &$accessToken, $headers = [])
|
public function get($ref, &$accessToken, $headers = [], $doNotWrap = false)
|
||||||
{
|
{
|
||||||
$response = $this->request('get', $ref, $accessToken, ['headers' => $headers]);
|
$response = $this->request('get', $ref, $accessToken, ['headers' => $headers]);
|
||||||
|
|
||||||
return $this->wrapResponse($response);
|
return $doNotWrap ? $response : $this->wrapResponse($response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function post($ref, $body, &$accessToken, $headers = [])
|
public function post($ref, $body, &$accessToken, $headers = [])
|
||||||
@@ -352,8 +373,24 @@ class Azure extends AbstractProvider
|
|||||||
|
|
||||||
$publicKey = $pkey_array ['key'];
|
$publicKey = $pkey_array ['key'];
|
||||||
|
|
||||||
$keys[$keyinfo['kid']] = $publicKey;
|
$keys[$keyinfo['kid']] = new Key($publicKey, 'RS256');
|
||||||
}
|
}
|
||||||
|
} else if (isset($keyinfo['n']) && isset($keyinfo['e'])) {
|
||||||
|
$pkey_object = JWK::parseKey($keyinfo);
|
||||||
|
|
||||||
|
if ($pkey_object === false) {
|
||||||
|
throw new \RuntimeException('An attempt to read a public key from a ' . $keyinfo['n'] . ' certificate failed.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$pkey_array = openssl_pkey_get_details($pkey_object);
|
||||||
|
|
||||||
|
if ($pkey_array === false) {
|
||||||
|
throw new \RuntimeException('An attempt to get a public key as an array from a ' . $keyinfo['n'] . ' certificate failed.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$publicKey = $pkey_array ['key'];
|
||||||
|
|
||||||
|
$keys[$keyinfo['kid']] = new Key($publicKey, 'RS256');;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,7 +419,10 @@ class Azure extends AbstractProvider
|
|||||||
return $this->getOpenIdConfiguration($this->tenant, $this->defaultEndPointVersion);
|
return $this->getOpenIdConfiguration($this->tenant, $this->defaultEndPointVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function checkResponse(ResponseInterface $response, $data)
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
protected function checkResponse(ResponseInterface $response, $data): void
|
||||||
{
|
{
|
||||||
if (isset($data['odata.error']) || isset($data['error'])) {
|
if (isset($data['odata.error']) || isset($data['error'])) {
|
||||||
if (isset($data['odata.error']['message']['value'])) {
|
if (isset($data['odata.error']['message']['value'])) {
|
||||||
@@ -402,27 +442,39 @@ class Azure extends AbstractProvider
|
|||||||
throw new IdentityProviderException(
|
throw new IdentityProviderException(
|
||||||
$message,
|
$message,
|
||||||
$response->getStatusCode(),
|
$response->getStatusCode(),
|
||||||
$response
|
$response->getBody()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getDefaultScopes()
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
protected function getDefaultScopes(): array
|
||||||
{
|
{
|
||||||
return $this->scope;
|
return $this->scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getScopeSeparator()
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
protected function getScopeSeparator(): string
|
||||||
{
|
{
|
||||||
return $this->scopeSeparator;
|
return $this->scopeSeparator;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function createAccessToken(array $response, AbstractGrant $grant)
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
protected function createAccessToken(array $response, AbstractGrant $grant): AccessToken
|
||||||
{
|
{
|
||||||
return new AccessToken($response, $this);
|
return new AccessToken($response, $this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function createResourceOwner(array $response, \League\OAuth2\Client\Token\AccessToken $token)
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
protected function createResourceOwner(array $response, \League\OAuth2\Client\Token\AccessToken $token): AzureResourceOwner
|
||||||
{
|
{
|
||||||
return new AzureResourceOwner($response);
|
return new AzureResourceOwner($response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ class AccessToken extends \League\OAuth2\Client\Token\AccessToken
|
|||||||
if (!empty($options['id_token'])) {
|
if (!empty($options['id_token'])) {
|
||||||
$this->idToken = $options['id_token'];
|
$this->idToken = $options['id_token'];
|
||||||
|
|
||||||
|
unset($this->values['id_token']);
|
||||||
|
|
||||||
$keys = $provider->getJwtVerificationKeys();
|
$keys = $provider->getJwtVerificationKeys();
|
||||||
$idTokenClaims = null;
|
$idTokenClaims = null;
|
||||||
try {
|
try {
|
||||||
@@ -45,8 +47,27 @@ class AccessToken extends \League\OAuth2\Client\Token\AccessToken
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getIdToken()
|
||||||
|
{
|
||||||
|
return $this->idToken;
|
||||||
|
}
|
||||||
|
|
||||||
public function getIdTokenClaims()
|
public function getIdTokenClaims()
|
||||||
{
|
{
|
||||||
return $this->idTokenClaims;
|
return $this->idTokenClaims;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function jsonSerialize()
|
||||||
|
{
|
||||||
|
$parameters = parent::jsonSerialize();
|
||||||
|
|
||||||
|
if ($this->idToken) {
|
||||||
|
$parameters['id_token'] = $this->idToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $parameters;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1672,214 +1672,6 @@ Awesome, nor vice versa. **Please do not use brand logos for any purpose except
|
|||||||
to represent the company, product, or service to which they refer.**
|
to represent the company, product, or service to which they refer.**
|
||||||
]]></text>
|
]]></text>
|
||||||
</license>
|
</license>
|
||||||
<license>
|
|
||||||
<product scope="datamodels">apereo/phpcas</product>
|
|
||||||
<author>Joachim Fritschi - Adam Franco</author>
|
|
||||||
<license_type>Apache-2.0</license_type>
|
|
||||||
<text><![CDATA[
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
]]></text>
|
|
||||||
</license>
|
|
||||||
<license>
|
<license>
|
||||||
<product scope="js">C3 js</product>
|
<product scope="js">C3 js</product>
|
||||||
<author>Masayuki Tanaka</author>
|
<author>Masayuki Tanaka</author>
|
||||||
|
|||||||
@@ -684,6 +684,7 @@ class SetupUtils
|
|||||||
* Emulates sys_get_temp_dir if needed (PHP < 5.2.1)
|
* Emulates sys_get_temp_dir if needed (PHP < 5.2.1)
|
||||||
*
|
*
|
||||||
* @return string Path to the system's temp directory
|
* @return string Path to the system's temp directory
|
||||||
|
* @uses \sys_get_temp_dir()
|
||||||
*/
|
*/
|
||||||
public static function GetTmpDir() {
|
public static function GetTmpDir() {
|
||||||
return realpath(sys_get_temp_dir());
|
return realpath(sys_get_temp_dir());
|
||||||
|
|||||||
@@ -424,11 +424,11 @@ class ButtonUIBlockFactory extends AbstractUIBlockFactory
|
|||||||
$oButton->SetActionType($sActionType)
|
$oButton->SetActionType($sActionType)
|
||||||
->SetColor($sColor);
|
->SetColor($sColor);
|
||||||
|
|
||||||
if (utils::StrLen($sValue) > 0) {
|
if (utils::IsNotNullOrEmptyString($sValue)) {
|
||||||
$oButton->SetValue($sValue);
|
$oButton->SetValue($sValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (utils::StrLen($sName) > 0) {
|
if (utils::IsNotNullOrEmptyString($sName)) {
|
||||||
$oButton->SetName($sName);
|
$oButton->SetName($sName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ class InputWithLabel extends UIBlock
|
|||||||
*/
|
*/
|
||||||
public function HasDescription(): bool
|
public function HasDescription(): bool
|
||||||
{
|
{
|
||||||
return utils::StrLen($this->sDescription) > 0;
|
return utils::IsNotNullOrEmptyString($this->sDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -8,15 +8,8 @@ use OAuthClient;
|
|||||||
|
|
||||||
abstract class OAuthClientProviderAbstract implements IOAuthClientProvider
|
abstract class OAuthClientProviderAbstract implements IOAuthClientProvider
|
||||||
{
|
{
|
||||||
// /** @var string */
|
/** @var string */
|
||||||
// static protected $sVendorName = '';
|
static protected $sVendorName = '';
|
||||||
// /** @var array */
|
|
||||||
// static protected $sVendorColors = ['', '', '', ''];
|
|
||||||
// /** @var string */
|
|
||||||
// static protected $sVendorIcon = '';
|
|
||||||
// static protected $sRequiredSMTPScope = '';
|
|
||||||
// static protected $sRequiredIMAPScope = '';
|
|
||||||
// static protected $sRequiredPOPScope = '';
|
|
||||||
|
|
||||||
/** @var \League\OAuth2\Client\Provider\GenericProvider */
|
/** @var \League\OAuth2\Client\Provider\GenericProvider */
|
||||||
protected $oVendorProvider;
|
protected $oVendorProvider;
|
||||||
@@ -69,4 +62,12 @@ abstract class OAuthClientProviderAbstract implements IOAuthClientProvider
|
|||||||
return $this->oOauthClient->GetScope();
|
return $this->oOauthClient->GetScope();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function GetVendorName()
|
||||||
|
{
|
||||||
|
return self::$sVendorName;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -6,16 +6,8 @@ use TheNetworg\OAuth2\Client\Provider\Azure;
|
|||||||
|
|
||||||
class OAuthClientProviderAzure extends OAuthClientProviderAbstract
|
class OAuthClientProviderAzure extends OAuthClientProviderAbstract
|
||||||
{
|
{
|
||||||
// /** @var string */
|
/** @var string */
|
||||||
// static protected $sVendorName = 'Azure';
|
static protected $sVendorName = 'Azure';
|
||||||
// /** @var array */
|
|
||||||
// static protected $sVendorColors = ['#0766b7', '#0d396b', '#2893df', '#3ccbf4'];
|
|
||||||
// /** @var string */
|
|
||||||
// static protected $sVendorIcon = '../images/icons/icons8-azure.svg';
|
|
||||||
// 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';
|
|
||||||
|
|
||||||
|
|
||||||
public function __construct($oOAuthClient, array $collaborators = [])
|
public function __construct($oOAuthClient, array $collaborators = [])
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -43,8 +43,7 @@ class OAuthClientProviderFactory
|
|||||||
throw new CoreException(Dict::Format('itop-oauth-client:MissingOAuthClient', $sUsername));
|
throw new CoreException(Dict::Format('itop-oauth-client:MissingOAuthClient', $sUsername));
|
||||||
}
|
}
|
||||||
while ($oOAuthClient = $oSet->Fetch()) {
|
while ($oOAuthClient = $oSet->Fetch()) {
|
||||||
$sScope = $oOAuthClient->Get('scope');
|
if ($oOAuthClient->Get('used_for_smtp') == 'yes') {
|
||||||
if ($sScope == 'EMail') {
|
|
||||||
return $oOAuthClient;
|
return $oOAuthClient;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,16 +6,8 @@ use League\OAuth2\Client\Provider\Google;
|
|||||||
|
|
||||||
class OAuthClientProviderGoogle extends OAuthClientProviderAbstract
|
class OAuthClientProviderGoogle extends OAuthClientProviderAbstract
|
||||||
{
|
{
|
||||||
// /** @var string */
|
/** @var string */
|
||||||
// static protected $sVendorName = 'Google';
|
static protected $sVendorName = 'Google';
|
||||||
// /** @var array */
|
|
||||||
// static protected $sVendorColors = ['#DB4437', '#F4B400', '#0F9D58', '#4285F4'];
|
|
||||||
// /** @var string */
|
|
||||||
// static protected $sVendorIcon = '../images/icons/icons8-google.svg';
|
|
||||||
//
|
|
||||||
// static protected $sRequiredSMTPScope = 'https://mail.google.com/';
|
|
||||||
// static protected $sRequiredIMAPScope = 'https://mail.google.com/';
|
|
||||||
// static protected $sRequiredPOPScope = 'https://mail.google.com/';
|
|
||||||
|
|
||||||
public function __construct($oOAuthClient, array $collaborators = [])
|
public function __construct($oOAuthClient, array $collaborators = [])
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user