middlewares to import sch user and school in database on first sso login

parent af6ef85a
......@@ -73,11 +73,6 @@ return function (Slim\App $app) {
);
};
$container[SchSSO\Listener\User::class] = function ($c) {
return new SchSSO\Listener\User($c['logger']);
};
$container[SchSSO\Action\Login::class] = function ($c) {
$authService = $c['authentication_service'];
$authService->setAdapter($c[SchSSO\Adapter\Cas::class]);
......@@ -119,13 +114,6 @@ return function (Slim\App $app) {
}
});
$events('on', 'authenticate.success', function ($stop, $identity) use ($container) {
$listener = $container[SchSSO\Listener\User::class];
return $listener($stop, $identity);
}, 10);
$app->get('/user/login/sso', SchSSO\Action\Login::class)->setName('user.login.sso');
$app->get('/user/logout/sso', SchSSO\Action\Logout::class)->setName('user.logout.sso');
};
<?php
/**
* gredu_labs.
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
*
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
namespace SchSSO\Listener;
use Psr\Log\LoggerInterface;
use RedBeanPHP\R;
class User
{
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function __invoke(callable $stop, $identity)
{
$user = R::findOne('user', 'mail = ?', [$identity->mail]);
if (!$user) {
$user = R::dispense('user');
$user->uid = $identity->uid;
$user->mail = $identity->mail;
$user->display_name = $identity->displayName;
$user->office_name = $identity->officeName;
$user->authentication_source = $identity->authenticationSource;
$user->password = '';
$user->created = time();
$user->role = 'school';
$this->logger->info(sprintf('User %s imported from sso.sch.gr to database', $identity->mail));
}
$user->last_login = time();
R::store($user);
}
}
......@@ -14,14 +14,33 @@ return function (Slim\App $app) {
$container['autoloader']->addPsr4('SchSync\\', __DIR__ . '/src');
$container[SchSync\Listener\CreateSchool::class] = function ($c) {
return new SchSync\Listener\CreateSchool($c['ldap'], $c[SchMM\FetchUnit::class]);
};
$events = $container['events'];
$events('on', 'authenticate.success', function ($stop, $identity) use ($container) {
$listener = $container[SchSync\Listener\CreateSchool::class];
$listener($stop, $identity);
}, 20);
$events('on', 'bootstrap', function () use ($app, $container) {
$container[SchSync\Middleware\CreateUser::class] = function ($c) {
return new SchSync\Middleware\CreateUser(
$c['authentication_service'],
$c['router']->pathFor('user.login'),
$c['router']->pathFor('user.logout.sso'),
$c['flash'],
$c['logger']
);
};
$container[SchSync\Middleware\CreateSchool::class] = function ($c) {
return new SchSync\Middleware\CreateSchool(
$c['ldap'],
$c[SchMM\FetchUnit::class],
$c['authentication_service'],
$c['router']->pathFor('user.login'),
$c['router']->pathFor('user.logout.sso'),
$c['flash'],
$c['logger']
);
};
$container['router']->getNamedRoute('user.login.sso')
->add(SchSync\Middleware\CreateSchool::class)
->add(SchSync\Middleware\CreateUser::class);
});
};
<?php
/**
* gredu_labs.
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
*
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
namespace SchSync\Listener;
use GrEduLabs\Authentication\Identity;
use RedBeanPHP\R;
use Zend\Ldap\Dn;
use Zend\Ldap\Filter;
use Zend\Ldap\Ldap;
class CreateSchool
{
/**
* @var Ldap
*/
private $ldap;
/**
* @var callable
*/
private $fetchUnit;
public function __construct(Ldap $ldap, callable $fetchUnitFromMM)
{
$this->ldap = $ldap;
$this->fetchUnit = $fetchUnitFromMM;
}
public function __invoke(callable $stop, Identity $identity)
{
$registryNo = $this->findUnitRegitryNo($identity);
if (null === $registryNo) {
$stop();
}
$registryNo = ($registryNo === '1111111') ? '0601010' : $registryNo;
$unit = call_user_func($this->fetchUnit, $registryNo);
if (null === $unit) {
$stop();
}
$school = R::findOne('school', 'registryNo = ?', [$registryNo]);
try {
if (!$school) {
$school = R::dispense('school');
$school->name = $unit['name'];
$school->streetAddress = $unit['street_address'];
$school->postalCode = $unit['postal_code'];
$school->phoneNumber = $unit['phone_number'];
$school->faxNumber = $unit['fax_number'];
$school->email = $unit['email'];
$school->municipality = $unit['municipality'];
$school->schooltype_id = $unit['unit_type_id'];
$school->prefecture_id = $unit['prefecture_id'];
$school->educationlevel_id = $unit['education_level_id'];
$school->eduadmin_id = $unit['edu_admin_id'];
$school->created = time();
$school->creator = $identity->mail;
R::store($school);
}
} catch (\Exception $e) {
// todo handle exceptions
die('ERROR');
}
}
private function findUnitRegitryNo(Identity $identity)
{
$filter = Filter::equals('mail', $identity->mail);
$baseDn = Dn::factory($this->ldap->getBaseDn())->prepend(['ou' => 'people']);
$result = $this->ldap->search($filter, $baseDn, Ldap::SEARCH_SCOPE_ONE, ['l']);
if (1 !== $result->count()) {
return;
}
$result = $result->current();
$unitDn = $result['l'][0];
$unit = $this->ldap->getNode($unitDn);
return $unit->getAttribute('gsnunitcode', 0);
}
}
<?php
/**
* gredu_labs.
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
*
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
namespace SchSync\Middleware;
use GrEduLabs\Authentication\Identity;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Log\LoggerInterface;
use RedBeanPHP\R;
use Slim\Flash\Messages;
use Zend\Authentication\AuthenticationServiceInterface;
use Zend\Ldap\Dn;
use Zend\Ldap\Filter;
use Zend\Ldap\Ldap;
class CreateSchool
{
/**
* @var Ldap
*/
private $ldap;
/**
* @var callable
*/
private $fetchUnit;
/**
* @var AuthenticationServiceInterface
*/
private $authService;
/**
* @var string
*/
private $unitNotFoundRedirectUrl;
/**
* @var string
*/
private $ssoLogoutUrl;
/**
* @var Messages
*/
private $flash;
/**
* @var LoggerInterface
*/
private $logger;
public function __construct(
Ldap $ldap,
callable $fetchUnitFromMM,
AuthenticationServiceInterface $authService,
$unitNotFoundRedirectUrl,
$ssoLogoutUrl,
Messages $flash,
LoggerInterface $logger
) {
$this->ldap = $ldap;
$this->fetchUnit = $fetchUnitFromMM;
$this->authService = $authService;
$this->unitNotFoundRedirectUrl = (string) $unitNotFoundRedirectUrl;
$this->ssoLogoutUrl = (string) $ssoLogoutUrl;
$this->flash = $flash;
$this->logger = $logger;
}
public function __invoke(Request $req, Response $res, callable $next)
{
$res = $next($req, $res);
$identity = $this->authService->getIdentity();
if (!$identity) {
return $res;
}
$registryNo = $this->findUnitRegitryNo($identity);
if (null === $registryNo) {
$this->logger->error(sprintf('Unit for user %s not found in LDAP', $identity->mail), $identity->toArray());
return $this->logoutAndRediret($res, sprintf(
'School not found. <a href="%s" title="SSO logout">SSO Logout</a>',
$this->ssoLogoutUrl
));
}
$unit = call_user_func($this->fetchUnit, $registryNo);
if (null === $unit) {
$this->logger->error(sprintf(
'Unit with %s for user %s not found in MM',
$identity->mail,
$registryNo
));
$this->logger->debug('Trace', ['registryNo'=> $registryNo, 'identity' => $identity->toArray()]);
return $this->logoutAndRediret($res, sprintf(
'School not found. <a href="%s" title="SSO logout">SSO Logout</a>',
$this->ssoLogoutUrl
));
}
$school = R::findOne('school', 'registry_no = ?', [$registryNo]);
try {
if (!$school) {
$school = R::dispense('school');
$school->registry_no = $unit['registry_no'];
$school->name = $unit['name'];
$school->street_address = $unit['street_address'];
$school->postal_code = $unit['postal_code'];
$school->phone_number = $unit['phone_number'];
$school->fax_number = $unit['fax_number'];
$school->email = $unit['email'];
$school->municipality = $unit['municipality'];
$school->schooltype_id = $unit['unit_type_id'];
$school->prefecture_id = $unit['prefecture_id'];
$school->educationlevel_id = $unit['education_level_id'];
$school->eduadmin_id = $unit['edu_admin_id'];
$school->created = time();
$school->creator = $identity->mail;
R::store($school);
$this->logger->info(sprintf('School %s imported from MM to database', $registryNo), ['creator' => $identity->mail]);
}
} catch (\Exception $e) {
$this->logger->error(sprintf('Problem inserting school %s form MM in database', $registryNo));
$this->logger->debug('Exception', [$e->getMessage(), $e->getTraceAsString()]);
return $this->logoutAndRediret($res, sprintf(
'A problem occured fetching school data. <a href="%s" title="SSO logout">SSO Logout</a>',
$this->ssoLogoutUrl
));
}
return $res;
}
private function findUnitRegitryNo(Identity $identity)
{
$filter = Filter::equals('mail', $identity->mail);
$baseDn = Dn::factory($this->ldap->getBaseDn())->prepend(['ou' => 'people']);
$result = $this->ldap->search($filter, $baseDn, Ldap::SEARCH_SCOPE_ONE, ['l']);
if (1 !== $result->count()) {
return;
}
$result = $result->current();
$unitDn = $result['l'][0];
$unit = $this->ldap->getNode($unitDn);
return $unit->getAttribute('gsnunitcode', 0);
}
private function logoutAndRediret(Response $res, $message)
{
$this->authService->clearIdentity();
$this->flash->addMessage('danger', $message);
return $res->withRedirect($this->unitNotFoundRedirectUrl);
}
}
<?php
/**
* gredu_labs.
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
*
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
namespace SchSync\Middleware;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Log\LoggerInterface;
use RedBeanPHP\R;
use Slim\Flash\Messages;
use Zend\Authentication\AuthenticationServiceInterface;
class CreateUser
{
/**
* @var AuthenticationServiceInterface
*/
private $authService;
/**
* @var string
*/
private $userErrorRedirectUrl;
/**
* @var string
*/
private $ssoLogoutUrl;
/**
* @var Messages
*/
private $flash;
/**
* @var LoggerInterface
*/
private $logger;
public function __construct(
AuthenticationServiceInterface $authService,
$userErrorRedirectUrl,
$ssoLogoutUrl,
Messages $flash,
LoggerInterface $logger
) {
$this->authService = $authService;
$this->userErrorRedirectUrl = (string) $userErrorRedirectUrl;
$this->ssoLogoutUrl = (string) $ssoLogoutUrl;
$this->flash = $flash;
$this->logger = $logger;
}
public function __invoke(Request $req, Response $res, callable $next)
{
$res = $next($req, $res);
$identity = $this->authService->getIdentity();
if (!$identity) {
return $res;
}
try {
$user = R::findOne('user', 'mail = ?', [$identity->mail]);
if (!$user) {
$user = R::dispense('user');
$user->uid = $identity->uid;
$user->mail = $identity->mail;
$user->display_name = $identity->displayName;
$user->office_name = $identity->officeName;
$user->authentication_source = $identity->authenticationSource;
$user->password = '';
$user->created = time();
$user->role = 'school';
$this->logger->info(sprintf(
'User %s imported from sso.sch.gr to database',
$identity->mail
));
}
$user->last_login = time();
R::store($user);
} catch (\Exception $e) {
$this->authService->clearIdentity();
$this->flash->addMessage(
'danger',
'A problem occured storing user in database. <a href="%s" title="SSO logout">SSO Logout</a>'
);
$this->logger->error('Problem inserting user form CAS in database', $identity->toArray());
$this->logger->debug('Exception', [$e->getMessage(), $e->getTraceAsString()]);
return $res->withRedirect($this->userErrorRedirectUrl);
}
return $res;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment