Gestione login tramite Microsoft
This commit is contained in:
parent
9c1d3a0ed7
commit
9e2b76ffdf
15
index.php
15
index.php
|
@ -161,6 +161,9 @@ echo '
|
||||||
if (isset($username)) {
|
if (isset($username)) {
|
||||||
echo ' value="'.$username.'"';
|
echo ' value="'.$username.'"';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$microsoft = $dbo->selectOne('zz_oauth2', '*', ['nome' => 'Microsoft', 'enabled' => 1, 'is_login' => 1]);
|
||||||
|
|
||||||
echo ' required>
|
echo ' required>
|
||||||
<span class="form-control-feedback"><i class="fa fa-user"></i> </span>
|
<span class="form-control-feedback"><i class="fa fa-user"></i> </span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -171,7 +174,17 @@ echo ' required>
|
||||||
|
|
||||||
<button type="submit" class="btn btn-danger btn-block btn-flat">'.tr('Accedi').'</button>
|
<button type="submit" class="btn btn-danger btn-block btn-flat">'.tr('Accedi').'</button>
|
||||||
<br>
|
<br>
|
||||||
<p><a href="'.base_path().'/reset.php">'.tr('Password dimenticata?').'</a></p>
|
<p><a href="'.base_path().'/reset.php">'.tr('Password dimenticata?').'</a></p>';
|
||||||
|
if ($microsoft) {
|
||||||
|
echo '
|
||||||
|
<div class="social-auth-links text-center">
|
||||||
|
<p>- oppure -</p>
|
||||||
|
|
||||||
|
<a href="'.base_path().'/oauth2_login.php?id='.$microsoft['id'].'" class="btn btn-block btn-social btn-primary btn-flat"><i class="fa fa-windows"></i>'.tr('Accedi con Microsoft').'</a>
|
||||||
|
</div>';
|
||||||
|
}
|
||||||
|
echo '
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<!-- /.box -->
|
<!-- /.box -->
|
||||||
|
|
|
@ -11,6 +11,16 @@ class Google extends OriginalProvider implements ProviderInterface
|
||||||
'accessType' => 'offline',
|
'accessType' => 'offline',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function __construct(array $options = [], array $collaborators = [])
|
||||||
|
{
|
||||||
|
// Configurazioni specifiche per il provider di Microsoft Azure
|
||||||
|
$config = array_merge($options, [
|
||||||
|
'redirectUri' => base_url().'/oauth2.php',
|
||||||
|
]);
|
||||||
|
|
||||||
|
parent::__construct($config, $collaborators);
|
||||||
|
}
|
||||||
|
|
||||||
public function getOptions()
|
public function getOptions()
|
||||||
{
|
{
|
||||||
return self::$options;
|
return self::$options;
|
||||||
|
|
|
@ -21,6 +21,7 @@ class Microsoft extends Azure implements ProviderInterface
|
||||||
'https://outlook.office.com/SMTP.Send',
|
'https://outlook.office.com/SMTP.Send',
|
||||||
// 'https://outlook.office.com/IMAP.AccessAsUser.All'
|
// 'https://outlook.office.com/IMAP.AccessAsUser.All'
|
||||||
],
|
],
|
||||||
|
'accessType' => 'offline'
|
||||||
];
|
];
|
||||||
|
|
||||||
public function __construct(array $options = [], array $collaborators = [])
|
public function __construct(array $options = [], array $collaborators = [])
|
||||||
|
@ -29,6 +30,7 @@ class Microsoft extends Azure implements ProviderInterface
|
||||||
$config = array_merge($options, [
|
$config = array_merge($options, [
|
||||||
'defaultEndPointVersion' => parent::ENDPOINT_VERSION_2_0,
|
'defaultEndPointVersion' => parent::ENDPOINT_VERSION_2_0,
|
||||||
'tenant' => $options['tenant_id'],
|
'tenant' => $options['tenant_id'],
|
||||||
|
'redirectUri' => base_url().'/oauth2.php',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
parent::__construct($config, $collaborators);
|
parent::__construct($config, $collaborators);
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Emails\OAuth2;
|
||||||
|
|
||||||
|
use TheNetworg\OAuth2\Client\Provider\Azure;
|
||||||
|
|
||||||
|
class MicrosoftLogin extends Azure implements ProviderInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Impostazioni native per la connessione.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @var \string[][]
|
||||||
|
*/
|
||||||
|
protected static $options = [
|
||||||
|
'scope' => [
|
||||||
|
'https://graph.microsoft.com/User.Read',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
public function __construct(array $options = [], array $collaborators = [])
|
||||||
|
{
|
||||||
|
// Configurazioni specifiche per il provider di Microsoft Azure
|
||||||
|
$config = array_merge($options, [
|
||||||
|
'defaultEndPointVersion' => parent::ENDPOINT_VERSION_2_0,
|
||||||
|
'tenant' => $options['tenant_id'],
|
||||||
|
'redirectUri' => base_url().'/oauth2_login.php',
|
||||||
|
]);
|
||||||
|
|
||||||
|
parent::__construct($config, $collaborators);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOptions()
|
||||||
|
{
|
||||||
|
return self::$options;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getConfigInputs()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'tenant_id' => [
|
||||||
|
'label' => 'Tenant ID',
|
||||||
|
'type' => 'text',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUser($access_token)
|
||||||
|
{
|
||||||
|
$me = $this->get('https://graph.microsoft.com/v1.0/me', $access_token);
|
||||||
|
|
||||||
|
return $me['mail'];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
|
||||||
|
* Copyright (C) DevCode s.r.l.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
include_once __DIR__.'/../../core.php';
|
||||||
|
|
||||||
|
switch (filter('op')) {
|
||||||
|
case 'update':
|
||||||
|
$dbo->update('zz_oauth2', [
|
||||||
|
'client_id' => post('client_id'),
|
||||||
|
'client_secret' => post('client_secret'),
|
||||||
|
'config' => post('config'),
|
||||||
|
'enabled' => post('enabled'),
|
||||||
|
], ['id' => $id_record]);
|
||||||
|
|
||||||
|
flash()->info(tr('Salvataggio completato!'));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
|
||||||
|
* Copyright (C) DevCode s.r.l.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
include_once __DIR__.'/../../core.php';
|
||||||
|
|
||||||
|
?><form action="" method="post" id="edit-form">
|
||||||
|
<input type="hidden" name="backto" value="record-edit">
|
||||||
|
<input type="hidden" name="op" value="update">
|
||||||
|
|
||||||
|
<!-- DATI -->
|
||||||
|
<div class="panel panel-primary">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title"><?php echo tr('OAuth2'); ?></h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
{[ "type": "text", "label": "<?php echo tr('Nome'); ?>", "name": "nome", "value": "$nome$", "disabled": "1" ]}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
{[ "type": "checkbox", "label": "<?php echo tr('Abilita'); ?>", "name": "enabled", "value": "$enabled$" ]}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
{[ "type": "text", "label": "<?php echo tr('Client ID'); ?>", "name": "client_id", "value": "$client_id$" ]}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-4">
|
||||||
|
{[ "type": "text", "label": "<?php echo tr('Client Secret'); ?>", "name": "client_secret", "value": "$client_secret$" ]}
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
$config = $record['class']::getConfigInputs();
|
||||||
|
foreach ($config as $name => $field) {
|
||||||
|
$field['name'] = 'config['.$name.']';
|
||||||
|
$field['value'] = $oauth2->config[$name];
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<div class="col-md-4">
|
||||||
|
'.input($field).'
|
||||||
|
</div>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
|
||||||
|
* Copyright (C) DevCode s.r.l.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Models\OAuth2;
|
||||||
|
|
||||||
|
include_once __DIR__.'/../../core.php';
|
||||||
|
|
||||||
|
|
||||||
|
if (isset($id_record)) {
|
||||||
|
$record = $dbo->fetchOne('SELECT * FROM `zz_oauth2` WHERE id='.prepare($id_record));
|
||||||
|
$oauth2 = OAuth2::find($id_record);
|
||||||
|
$a=0;
|
||||||
|
}
|
|
@ -47,11 +47,13 @@ if (empty($account)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redirect all'URL di autorizzazione del servizio esterno
|
// Redirect all'URL di autorizzazione del servizio esterno
|
||||||
$redirect = $account->configure($code, $state);
|
$response = $account->configure($code, $state);
|
||||||
|
|
||||||
// Redirect automatico al record
|
// Redirect automatico al record
|
||||||
if (empty($redirect)) {
|
if (empty($response['authorization_url'])) {
|
||||||
$redirect = $account->after_configuration;
|
$redirect = $account->after_configuration;
|
||||||
|
} else {
|
||||||
|
$redirect = $response['authorization_url'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($_GET['error'])) {
|
if (empty($_GET['error'])) {
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
|
||||||
|
* Copyright (C) DevCode s.r.l.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Models\OAuth2;
|
||||||
|
|
||||||
|
$skip_permissions = true;
|
||||||
|
include_once __DIR__.'/core.php';
|
||||||
|
|
||||||
|
// Authorization information
|
||||||
|
$state = $_GET['state'];
|
||||||
|
$code = $_GET['code'];
|
||||||
|
|
||||||
|
// Account individuato via state
|
||||||
|
if (!empty($state)) {
|
||||||
|
$account = OAuth2::where('state', '=', $state)
|
||||||
|
->first();
|
||||||
|
} else {
|
||||||
|
$account = OAuth2::find(get('id'));
|
||||||
|
|
||||||
|
// Impostazione access token a null per reimpostare la configurazione
|
||||||
|
$account->access_token = null;
|
||||||
|
$account->refresh_token = null;
|
||||||
|
$account->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($account)) {
|
||||||
|
echo tr('Errore durante il completamento della configurazione: account non trovato');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redirect all'URL di autorizzazione del servizio esterno
|
||||||
|
$response = $account->configure($code, $state);
|
||||||
|
|
||||||
|
// Redirect automatico al record
|
||||||
|
if (empty($response['authorization_url'])) {
|
||||||
|
$redirect = $account->after_configuration;
|
||||||
|
} else {
|
||||||
|
$redirect = $response['authorization_url'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($_GET['error'])) {
|
||||||
|
if ($response['access_token']) {
|
||||||
|
$username = $account->getProvider()->getUser($response['access_token']);
|
||||||
|
|
||||||
|
if (!auth()->attempt($username, null, true)) {
|
||||||
|
flash()->error(tr('Autenticazione fallita!'));
|
||||||
|
}
|
||||||
|
redirect(base_path());
|
||||||
|
} else {
|
||||||
|
redirect($redirect);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
exit;
|
||||||
|
} else {
|
||||||
|
echo strip_tags($_GET['error']).'<br>'.strip_tags($_GET['error_description']).'
|
||||||
|
<br><br>
|
||||||
|
<a href="'.$redirect.'">'.tr('Riprova').'</a>';
|
||||||
|
}
|
12
src/Auth.php
12
src/Auth.php
|
@ -101,10 +101,11 @@ class Auth extends Util\Singleton
|
||||||
*
|
*
|
||||||
* @param string $username
|
* @param string $username
|
||||||
* @param string $password
|
* @param string $password
|
||||||
|
* @param bool $force Forza il login solo tramite username (serve per l'autenticazione con Oauth2)
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function attempt($username, $password)
|
public function attempt($username, $password, $force = false)
|
||||||
{
|
{
|
||||||
session_regenerate_id();
|
session_regenerate_id();
|
||||||
|
|
||||||
|
@ -134,7 +135,14 @@ class Auth extends Util\Singleton
|
||||||
$module = $gruppo['id_module_start'];
|
$module = $gruppo['id_module_start'];
|
||||||
$module = $this->getFirstModule($module);
|
$module = $this->getFirstModule($module);
|
||||||
|
|
||||||
if (
|
if ($force) {
|
||||||
|
// Accesso completato
|
||||||
|
$log['id_utente'] = $this->user->id;
|
||||||
|
$status = 'success';
|
||||||
|
|
||||||
|
// Salvataggio nella sessione
|
||||||
|
$this->saveToSession();
|
||||||
|
} elseif (
|
||||||
$this->isAuthenticated()
|
$this->isAuthenticated()
|
||||||
&& $this->password_check($password, $user['password'], $user['id'])
|
&& $this->password_check($password, $user['password'], $user['id'])
|
||||||
&& !empty($module)
|
&& !empty($module)
|
||||||
|
|
|
@ -47,9 +47,7 @@ class OAuth2 extends Model
|
||||||
$config = $this->config ?? [];
|
$config = $this->config ?? [];
|
||||||
$config = array_merge($config, [
|
$config = array_merge($config, [
|
||||||
'clientId' => $this->client_id,
|
'clientId' => $this->client_id,
|
||||||
'clientSecret' => $this->client_secret,
|
'clientSecret' => $this->client_secret
|
||||||
'redirectUri' => base_url().'/oauth2.php',
|
|
||||||
'accessType' => 'offline',
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$class = $this->class;
|
$class = $this->class;
|
||||||
|
@ -106,7 +104,7 @@ class OAuth2 extends Model
|
||||||
$this->save();
|
$this->save();
|
||||||
|
|
||||||
// Redirect the user to the authorization URL.
|
// Redirect the user to the authorization URL.
|
||||||
return $authorization_url;
|
return ['authorization_url' => $authorization_url];
|
||||||
} elseif (!empty($this->state) && $this->state !== $state) {
|
} elseif (!empty($this->state) && $this->state !== $state) {
|
||||||
$this->state = null;
|
$this->state = null;
|
||||||
$this->save();
|
$this->save();
|
||||||
|
@ -123,6 +121,8 @@ class OAuth2 extends Model
|
||||||
$refresh_token = $access_token->getRefreshToken();
|
$refresh_token = $access_token->getRefreshToken();
|
||||||
|
|
||||||
$this->updateTokens($access_token, $refresh_token);
|
$this->updateTokens($access_token, $refresh_token);
|
||||||
|
|
||||||
|
return ['access_token' => $access_token];
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -11,3 +11,17 @@ INSERT INTO `zz_views` (`id_module`, `name`, `query`, `order`, `search`, `slow`,
|
||||||
|
|
||||||
INSERT INTO `zz_views` (`id`, `id_module`, `name`, `query`, `order`, `search`, `slow`, `format`, `html_format`, `search_inside`, `order_by`, `visible`, `summable`, `default`) VALUES (NULL, (SELECT `id` FROM `zz_modules` WHERE `name` = 'Utenti e permessi'), 'Tema', '`zz_groups`.`theme`', '4', '1', '0', '0', '0', '', '', '1', '0', '0');
|
INSERT INTO `zz_views` (`id`, `id_module`, `name`, `query`, `order`, `search`, `slow`, `format`, `html_format`, `search_inside`, `order_by`, `visible`, `summable`, `default`) VALUES (NULL, (SELECT `id` FROM `zz_modules` WHERE `name` = 'Utenti e permessi'), 'Tema', '`zz_groups`.`theme`', '4', '1', '0', '0', '0', '', '', '1', '0', '0');
|
||||||
|
|
||||||
|
-- Creazione modulo Login
|
||||||
|
INSERT INTO `zz_modules` (`id`, `name`, `title`, `directory`, `options`, `options2`, `icon`, `version`, `compatibility`, `order`, `parent`, `default`, `enabled`, `use_notes`, `use_checklists`) VALUES (NULL, 'Accesso con OAuth', 'Accesso con OAuth', 'oauth', 'SELECT |select| FROM zz_oauth2 WHERE 1=1 AND is_login=1 HAVING 2=2', '', 'fa fa-angle-right', '1.0', '2.4.54', '100', (SELECT `t`.`id` FROM `zz_modules` AS `t` WHERE `t`.`name` = 'Tabelle'), '1', '1', '0', '0');
|
||||||
|
|
||||||
|
ALTER TABLE `zz_oauth2` ADD `nome` VARCHAR(255) NOT NULL AFTER `id`;
|
||||||
|
ALTER TABLE `zz_oauth2` ADD `is_login` BOOLEAN NOT NULL AFTER `after_configuration`;
|
||||||
|
ALTER TABLE `zz_oauth2` ADD `enabled` BOOLEAN NOT NULL DEFAULT TRUE AFTER `is_login`;
|
||||||
|
|
||||||
|
-- Viste modulo Oauth
|
||||||
|
INSERT INTO `zz_views` (`id_module`, `name`, `query`, `order`, `search`, `slow`, `format`, `search_inside`, `order_by`, `visible`, `summable`, `default`) VALUES
|
||||||
|
((SELECT `id` FROM `zz_modules` WHERE name='Accesso con OAuth'), 'id', 'id', 0, 1, 0, 0, '', '', 0, 0, 0),
|
||||||
|
((SELECT `id` FROM `zz_modules` WHERE name='Accesso con OAuth'), 'Nome', 'nome', 1, 1, 0, 0, '', '', 1, 0, 0);
|
||||||
|
|
||||||
|
INSERT INTO `zz_oauth2` (`nome`, `class`, `client_id`, `client_secret`, `config`, `state`, `access_token`, `refresh_token`, `after_configuration`, `is_login`, `enabled`) VALUES
|
||||||
|
('Microsoft', 'Modules\\Emails\\OAuth2\\MicrosoftLogin', '', '', '{\"tenant_id\":\"consumers\"}', '', NULL, NULL, '', 1, 0);
|
Loading…
Reference in New Issue