envole/docker/volume/nextcloud/envole/app/user_cas/lib/Hooks/UserHooks.php

448 lines
14 KiB
PHP

<?php
/**
* ownCloud - user_cas
*
* @author Felix Rupp <kontakt@felixrupp.com>
* @copyright Felix Rupp <kontakt@felixrupp.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library 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 AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\UserCAS\Hooks;
use OCA\UserCAS\Exception\PhpCas\PhpUserCasLibraryNotFoundException;
use OCA\UserCAS\User\UserCasBackendInterface;
use \OCP\IUserManager;
use \OCP\IUserSession;
use \OCP\IConfig;
use OCA\UserCAS\Service\LoggingService;
use OCA\UserCAS\Service\UserService;
use OCA\UserCAS\Service\AppService;
/**
* Class UserCAS_Hooks
*
* @package OCA\UserCAS\Hooks
*
* @author Felix Rupp <kontakt@felixrupp.com>
* @copyright Felix Rupp <kontakt@felixrupp.com>
*
* @since 1.4.0
*/
class UserHooks
{
/**
* @var string
*/
private $appName;
/**
* @var \OCP\IUserManager $userManager
*/
private $userManager;
/**
* @var \OCP\IUserSession $userSession
*/
private $userSession;
/**
* @var \OCP\IConfig
*/
private $config;
/**
* @var \OCA\UserCAS\Service\UserService $userService
*/
private $userService;
/**
* @var \OCA\UserCAS\Service\AppService $appService
*/
private $appService;
/**
* @var \OCA\UserCAS\Service\LoggingService
*/
private $loggingService;
/**
* @var UserCasBackendInterface
*/
private $backend;
/**
* UserHooks constructor.
*
* @param string $appName
* @param \OCP\IUserManager $userManager
* @param \OCP\IUserSession $userSession
* @param \OCP\IConfig $config
* @param \OCA\UserCAS\Service\UserService $userService
* @param \OCA\UserCAS\Service\AppService $appService
* @param \OCA\UserCAS\Service\LoggingService $loggingService
* @param UserCasBackendInterface $backend
*/
public function __construct($appName, IUserManager $userManager, IUserSession $userSession, IConfig $config, UserService $userService, AppService $appService, LoggingService $loggingService, UserCasBackendInterface $backend)
{
$this->appName = $appName;
$this->userManager = $userManager;
$this->userSession = $userSession;
$this->config = $config;
$this->userService = $userService;
$this->appService = $appService;
$this->loggingService = $loggingService;
$this->backend = $backend;
}
/**
* Register method.
*/
public function register()
{
#$this->userSession->listen('\OC\User', 'preLogin', array($this, 'preLogin'));
$this->userSession->listen('\OC\User', 'postLogin', array($this, 'postLogin'));
$this->userSession->listen('\OC\User', 'postLogout', array($this, 'postLogout'));
}
/**
* postLogin method to update user data.
*
* @param mixed $uid
* @param string $password
* @return bool
* @throws \Exception
*
* @deprecated
* @since 1.8.0
*/
public function preLogin($uid, $password)
{
if (!$this->appService->isCasInitialized()) {
try {
$this->appService->init();
} catch (PhpUserCasLibraryNotFoundException $e) {
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::FATAL, 'Fatal error with code: ' . $e->getCode() . ' and message: ' . $e->getMessage());
return FALSE;
}
};
if ($uid instanceof \OCP\IUser) {
$user = $uid;
$uid = $user->getUID();
}
else {
$user = $this->userManager->get($uid);
}
if (\phpCAS::isAuthenticated() && !$this->userSession->isLoggedIn()) {
#$casUid = \phpCAS::getUser();
$casUid = $this->userService->getUserId();
if ($casUid === $uid) {
if (boolval($this->config->getAppValue($this->appName, 'cas_autocreate'))) {
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCas pre login hook triggered. User: ' . $uid);
// Autocreate user if needed or create a new account in CAS Backend
if (is_null($user)) {
// create users if they do not exist
if (preg_match('/[^a-zA-Z0-9 _\.@\-]/', $uid)) {
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'Invalid username "' . $uid . '", allowed chars "a-zA-Z0-9" and "_.@-" ');
return FALSE;
} else {
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCAS creating a new user with UID: ' . $uid);
/** @var bool|\OCP\IUser the created user or false $uid */
$user = $this->userService->create($uid, $this->backend);
if ($user instanceof \OCP\IUser) {
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCAS created new user with UID: ' . $uid);
}
}
} else {
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCAS no new user has been created.');
}
}
# Update the Backend of the user if necessary
#$this->userService->updateBackend($user);
}
} else {
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCas pre login hook NOT triggered. User: ' . $uid);
}
return TRUE;
}
/**
* postLogin method to update user data.
*
* @param mixed $uid
* @param string $password
* @return bool
*/
public function postLogin($uid, $password)
{
if (!$this->appService->isCasInitialized()) {
try {
$this->appService->init();
} catch (PhpUserCasLibraryNotFoundException $e) {
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::FATAL, 'Fatal error with code: ' . $e->getCode() . ' and message: ' . $e->getMessage());
return FALSE;
}
};
if ($uid instanceof \OCP\IUser) {
$user = $uid;
$uid = $user->getUID();
} else {
$user = $this->userManager->get($uid);
}
if (\phpCAS::isAuthenticated() && $this->userSession->isLoggedIn()) {
if (boolval($this->config->getAppValue($this->appName, 'cas_update_user_data'))) {
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCas post login hook triggered. User: ' . $uid);
// $cas_attributes may vary in name, therefore attributes are fetched to $attributes
#$casUid = \phpCAS::getUser();
$casUid = $this->userService->getUserId();
if ($casUid === $uid) {
# Update the Backend of the user if necessary
#$this->userService->updateBackend($user);
$casAttributes = \phpCAS::getAttributes();
# Test if an attribute parser added a new dimension to our attributes array
if (array_key_exists('attributes', $casAttributes)) {
$newAttributes = $casAttributes['attributes'];
unset($casAttributes['attributes']);
$casAttributes = array_merge($casAttributes, $newAttributes);
}
$casAttributesString = '';
foreach ($casAttributes as $key => $attribute) {
$attributeString = $this->convertArrayAttributeValuesForDebug($attribute);
$casAttributesString .= $key . ': ' . $attributeString . '; ';
}
// parameters
$attributes = array();
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'Attributes for the user: ' . $uid . ' => ' . $casAttributesString);
// DisplayName
$displayNameMapping = $this->config->getAppValue($this->appName, 'cas_displayName_mapping');
$displayNameMappingArray = explode("+", $displayNameMapping);
$attributes['cas_name'] = '';
foreach ($displayNameMappingArray as $displayNameMapping) {
if (array_key_exists($displayNameMapping, $casAttributes)) {
$attributes['cas_name'] .= $casAttributes[$displayNameMapping] . " ";
}
}
$attributes['cas_name'] = trim($attributes['cas_name']);
if ($attributes['cas_name'] === '' && array_key_exists('displayName', $casAttributes)) {
$attributes['cas_name'] = $casAttributes['displayName'];
}
// E-Mail
$mailMapping = $this->config->getAppValue($this->appName, 'cas_email_mapping');
if (array_key_exists($mailMapping, $casAttributes)) {
$attributes['cas_email'] = $casAttributes[$mailMapping];
} else if (array_key_exists('mail', $casAttributes)) {
$attributes['cas_email'] = $casAttributes['mail'];
}
// Group handling
$groupMapping = $this->config->getAppValue($this->appName, 'cas_group_mapping');
$defaultGroup = $this->config->getAppValue($this->appName, 'cas_default_group');
# Test for mapped attribute from settings
if (array_key_exists($groupMapping, $casAttributes)) {
$attributes['cas_groups'] = $casAttributes[$groupMapping];
} # Test for standard 'groups' attribute
else if (array_key_exists('groups', $casAttributes)) {
$attributes['cas_groups'] = $casAttributes['groups'];
} else if (is_string($defaultGroup) && strlen($defaultGroup) > 0) {
$attributes['cas_groups'] = array($defaultGroup);
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'Using default group "' . $defaultGroup . '" for the user: ' . $uid);
}
// Group Quota handling
$groupQuotas = $this->config->getAppValue($this->appName, 'cas_access_group_quotas');
$groupQuotas = explode(",", $groupQuotas);
foreach ($groupQuotas as $groupQuota) {
$groupQuota = explode(":", $groupQuota);
if (is_array($groupQuota) && count($groupQuota) === 2) {
$attributes['cas_group_quota'][$groupQuota[0]] = $groupQuota[1];
}
}
// User Quota handling
// Overwrites group quota
$userQuotaMapping = $this->config->getAppValue($this->appName, 'cas_quota_mapping');
#$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCas quota-mapping-contents: '.$userQuotaMapping);
if (array_key_exists($userQuotaMapping, $casAttributes)) {
$attributes['cas_quota'] = $casAttributes[$userQuotaMapping];
} else if (array_key_exists('quota', $casAttributes)) {
$attributes['cas_quota'] = $casAttributes['quota'];
}
// Try to update user attributes
$this->userService->updateUser($user, $attributes);
}
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCas post login hook finished.');
}
} else {
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCas post login hook NOT triggered. User: ' . $uid);
}
return TRUE;
}
/**
* Logout hook method.
*
* @return boolean
*/
public function postLogout()
{
if (!$this->appService->isCasInitialized()) {
try {
$this->appService->init();
} catch (PhpUserCasLibraryNotFoundException $e) {
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::FATAL, 'Fatal error with code: ' . $e->getCode() . ' and message: ' . $e->getMessage());
return FALSE;
}
};
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'Logout hook triggered.');
if (!boolval($this->config->getAppValue($this->appName, 'cas_disable_logout'))) {
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCAS logging out.');
# Reset cookie
setcookie("user_cas_redirect_url", '/', 0, '/');
\phpCAS::logout(array("service" => $this->appService->getAbsoluteURL('/')));
} else {
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCAS not logging out, because CAS logout was disabled.');
}
return TRUE;
}
/**
* Convert CAS Attribute values for debug reasons
*
* @param $attributes
* @return string
*/
private function convertArrayAttributeValuesForDebug($attributes)
{
if (is_array($attributes)) {
$stringValue = '';
foreach ($attributes as $attribute) {
if (is_array($attribute)) {
$stringValue .= $this->convertArrayAttributeValuesForDebug($attribute);
} else {
$stringValue .= $attribute . ", ";
}
}
return $stringValue;
}
return $attributes;
}
}