svg
This commit is contained in:
@ -0,0 +1,197 @@
|
||||
<?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\AppInfo;
|
||||
|
||||
use \OCP\AppFramework\App;
|
||||
use \OCP\IContainer;
|
||||
|
||||
use OCA\UserCAS\Service\UserService;
|
||||
use OCA\UserCAS\Service\AppService;
|
||||
use OCA\UserCAS\Hooks\UserHooks;
|
||||
use OCA\UserCAS\Controller\SettingsController;
|
||||
use OCA\UserCAS\Controller\AuthenticationController;
|
||||
use OCA\UserCAS\User\Backend;
|
||||
use OCA\UserCAS\User\NextBackend;
|
||||
use OCA\UserCAS\Service\LoggingService;
|
||||
|
||||
/**
|
||||
* Class Application
|
||||
*
|
||||
* @package OCA\UserCAS\AppInfo
|
||||
*
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
* @copyright Felix Rupp <kontakt@felixrupp.com>
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
class Application extends App
|
||||
{
|
||||
|
||||
/**
|
||||
* Application constructor.
|
||||
*
|
||||
* @param array $urlParams
|
||||
*/
|
||||
public function __construct(array $urlParams = array())
|
||||
{
|
||||
|
||||
parent::__construct('user_cas', $urlParams);
|
||||
|
||||
$container = $this->getContainer();
|
||||
|
||||
$container->registerService('User', function (IContainer $c) {
|
||||
return $c->query('UserSession')->getUser();
|
||||
});
|
||||
|
||||
$container->registerService('Config', function (IContainer $c) {
|
||||
return $c->query('ServerContainer')->getConfig();
|
||||
});
|
||||
|
||||
$container->registerService('L10N', function (IContainer $c) {
|
||||
return $c->query('ServerContainer')->getL10N($c->query('AppName'));
|
||||
});
|
||||
|
||||
$container->registerService('Logger', function (IContainer $c) {
|
||||
return $c->query('ServerContainer')->getLogger();
|
||||
});
|
||||
|
||||
/**
|
||||
* Register LoggingService
|
||||
*/
|
||||
$container->registerService('LoggingService', function (IContainer $c) {
|
||||
return new LoggingService(
|
||||
$c->query('AppName'),
|
||||
$c->query('Config'),
|
||||
$c->query('Logger')
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Register AppService with config
|
||||
*/
|
||||
$container->registerService('AppService', function (IContainer $c) {
|
||||
return new AppService(
|
||||
$c->query('AppName'),
|
||||
$c->query('Config'),
|
||||
$c->query('LoggingService'),
|
||||
$c->query('ServerContainer')->getUserManager(),
|
||||
$c->query('ServerContainer')->getUserSession(),
|
||||
$c->query('ServerContainer')->getURLGenerator(),
|
||||
$c->query('ServerContainer')->getAppManager()
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
// Workaround for Nextcloud >= 14.0.0
|
||||
if ($container->query('AppService')->isNotNextcloud()) {
|
||||
|
||||
/**
|
||||
* Register regular Backend
|
||||
*/
|
||||
$container->registerService('Backend', function (IContainer $c) {
|
||||
return new Backend(
|
||||
$c->query('AppName'),
|
||||
$c->query('Config'),
|
||||
$c->query('LoggingService'),
|
||||
$c->query('AppService'),
|
||||
$c->query('ServerContainer')->getUserManager(),
|
||||
$c->query('UserService')
|
||||
);
|
||||
});
|
||||
} else {
|
||||
|
||||
/**
|
||||
* Register Nextcloud Backend
|
||||
*/
|
||||
$container->registerService('Backend', function (IContainer $c) {
|
||||
return new NextBackend(
|
||||
$c->query('AppName'),
|
||||
$c->query('Config'),
|
||||
$c->query('LoggingService'),
|
||||
$c->query('AppService'),
|
||||
$c->query('ServerContainer')->getUserManager(),
|
||||
$c->query('UserService')
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register UserService with UserSession for login/logout and UserManager for create
|
||||
*/
|
||||
$container->registerService('UserService', function (IContainer $c) {
|
||||
return new UserService(
|
||||
$c->query('AppName'),
|
||||
$c->query('Config'),
|
||||
$c->query('ServerContainer')->getUserManager(),
|
||||
$c->query('ServerContainer')->getUserSession(),
|
||||
$c->query('ServerContainer')->getGroupManager(),
|
||||
$c->query('AppService'),
|
||||
$c->query('LoggingService')
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Register SettingsController
|
||||
*/
|
||||
$container->registerService('SettingsController', function (IContainer $c) {
|
||||
return new SettingsController(
|
||||
$c->query('AppName'),
|
||||
$c->query('Request'),
|
||||
$c->query('Config'),
|
||||
$c->query('L10N')
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Register AuthenticationController
|
||||
*/
|
||||
$container->registerService('AuthenticationController', function (IContainer $c) {
|
||||
return new AuthenticationController(
|
||||
$c->query('AppName'),
|
||||
$c->query('Request'),
|
||||
$c->query('Config'),
|
||||
$c->query('UserService'),
|
||||
$c->query('AppService'),
|
||||
$c->query('ServerContainer')->getUserSession(),
|
||||
$c->query('LoggingService')
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Register UserHooks
|
||||
*/
|
||||
$container->registerService('UserHooks', function (IContainer $c) {
|
||||
return new UserHooks(
|
||||
$c->query('AppName'),
|
||||
$c->query('ServerContainer')->getUserManager(),
|
||||
$c->query('ServerContainer')->getUserSession(),
|
||||
$c->query('Config'),
|
||||
$c->query('UserService'),
|
||||
$c->query('AppService'),
|
||||
$c->query('LoggingService'),
|
||||
$c->query('Backend')
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,304 @@
|
||||
<?php
|
||||
|
||||
namespace OCA\UserCAS\Command;
|
||||
|
||||
use OCA\UserCAS\Service\AppService;
|
||||
use OCA\UserCAS\Service\LoggingService;
|
||||
use OCA\UserCAS\Service\UserService;
|
||||
|
||||
use OCA\UserCAS\User\Backend;
|
||||
use OCA\UserCAS\User\NextBackend;
|
||||
use OCA\UserCAS\User\UserCasBackendInterface;
|
||||
use OCP\IConfig;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Mail\IMailer;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
||||
|
||||
/**
|
||||
* Class CreateUser
|
||||
*
|
||||
* @package OCA\UserCAS\Command
|
||||
*
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
* @copyright Felix Rupp <kontakt@felixrupp.com>
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
class CreateUser extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* @var UserService
|
||||
*/
|
||||
protected $userService;
|
||||
|
||||
/**
|
||||
* @var AppService
|
||||
*/
|
||||
protected $appService;
|
||||
|
||||
/**
|
||||
* @var IUserManager
|
||||
*/
|
||||
protected $userManager;
|
||||
|
||||
/**
|
||||
* @var IGroupManager
|
||||
*/
|
||||
protected $groupManager;
|
||||
|
||||
/**
|
||||
* @var IMailer
|
||||
*/
|
||||
protected $mailer;
|
||||
|
||||
/**
|
||||
* @var LoggingService
|
||||
*/
|
||||
protected $loggingService;
|
||||
|
||||
/**
|
||||
* @var IConfig
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var Backend|UserCasBackendInterface
|
||||
*/
|
||||
protected $backend;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$userManager = \OC::$server->getUserManager();
|
||||
$groupManager = \OC::$server->getGroupManager();
|
||||
$mailer = \OC::$server->getMailer();
|
||||
$config = \OC::$server->getConfig();
|
||||
$userSession = \OC::$server->getUserSession();
|
||||
$logger = \OC::$server->getLogger();
|
||||
$urlGenerator = \OC::$server->getURLGenerator();
|
||||
$appManager = \OC::$server->getAppManager();
|
||||
|
||||
$loggingService = new LoggingService('user_cas', $config, $logger);
|
||||
$this->appService = new AppService('user_cas', $config, $loggingService, $userManager, $userSession, $urlGenerator, $appManager);
|
||||
|
||||
$userService = new UserService(
|
||||
'user_cas',
|
||||
$config,
|
||||
$userManager,
|
||||
$userSession,
|
||||
$groupManager,
|
||||
$this->appService,
|
||||
$loggingService
|
||||
);
|
||||
|
||||
if ($this->appService->isNotNextcloud()) {
|
||||
|
||||
$backend = new Backend(
|
||||
'user_cas',
|
||||
$config,
|
||||
$loggingService,
|
||||
$this->appService,
|
||||
$userManager,
|
||||
$userService
|
||||
);
|
||||
} else {
|
||||
|
||||
$backend = new NextBackend(
|
||||
'user_cas',
|
||||
$config,
|
||||
$loggingService,
|
||||
$this->appService,
|
||||
$userManager,
|
||||
$userService
|
||||
);
|
||||
}
|
||||
|
||||
$this->userService = $userService;
|
||||
$this->userManager = $userManager;
|
||||
$this->groupManager = $groupManager;
|
||||
$this->mailer = $mailer;
|
||||
$this->loggingService = $loggingService;
|
||||
$this->config = $config;
|
||||
$this->backend = $backend;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('cas:create-user')
|
||||
->setDescription('Adds a user_cas user to the database.')
|
||||
->addArgument(
|
||||
'uid',
|
||||
InputArgument::REQUIRED,
|
||||
'User ID used to login (must only contain a-z, A-Z, 0-9, -, _ and @).'
|
||||
)
|
||||
->addOption(
|
||||
'display-name',
|
||||
null,
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'User name used in the web UI (can contain any characters).'
|
||||
)
|
||||
->addOption(
|
||||
'email',
|
||||
null,
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'Email address for the user.'
|
||||
)
|
||||
->addOption(
|
||||
'group',
|
||||
'g',
|
||||
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
|
||||
'The groups the user should be added to (The group will be created if it does not exist).'
|
||||
)
|
||||
->addOption(
|
||||
'quota',
|
||||
'o',
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'The quota the user should get either as numeric value in bytes or as a human readable string (e.g. 1GB for 1 Gigabyte)'
|
||||
)
|
||||
->addOption(
|
||||
'enabled',
|
||||
'e',
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'Set user enabled'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return int|null
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
|
||||
$uid = $input->getArgument('uid');
|
||||
if ($this->userManager->userExists($uid)) {
|
||||
$output->writeln('<error>The user "' . $uid . '" already exists.</error>');
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Validate email before we create the user
|
||||
if ($input->getOption('email')) {
|
||||
// Validate first
|
||||
if (!$this->mailer->validateMailAddress($input->getOption('email'))) {
|
||||
// Invalid! Error
|
||||
$output->writeln('<error>Invalid email address supplied</error>');
|
||||
return 1;
|
||||
} else {
|
||||
$email = $input->getOption('email');
|
||||
}
|
||||
} else {
|
||||
$email = null;
|
||||
}
|
||||
|
||||
# Register Backend
|
||||
$this->userService->registerBackend($this->backend);
|
||||
|
||||
/**
|
||||
* @var IUser
|
||||
*/
|
||||
$user = $this->userService->create($uid, $this->backend);
|
||||
|
||||
if ($user instanceof IUser) {
|
||||
|
||||
$output->writeln('<info>The user "' . $user->getUID() . '" was created successfully</info>');
|
||||
} else {
|
||||
|
||||
$output->writeln('<error>An error occurred while creating the user</error>');
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Set displayName
|
||||
if ($input->getOption('display-name')) {
|
||||
|
||||
$user->setDisplayName($input->getOption('display-name'));
|
||||
$output->writeln('Display name set to "' . $user->getDisplayName() . '"');
|
||||
}
|
||||
|
||||
# Set email if supplied & valid
|
||||
if ($email !== null) {
|
||||
|
||||
$user->setEMailAddress($email);
|
||||
$output->writeln('Email address set to "' . $user->getEMailAddress() . '"');
|
||||
}
|
||||
|
||||
# Set Groups
|
||||
$groups = (array)$input->getOption('group');
|
||||
|
||||
if (count($groups) > 0) {
|
||||
|
||||
$this->userService->updateGroups($user, $groups, $this->config->getAppValue('user_cas', 'cas_protected_groups'), TRUE);
|
||||
$output->writeln('Groups have been set.');
|
||||
}
|
||||
|
||||
# Set Quota
|
||||
$quota = $input->getOption('quota');
|
||||
|
||||
if (!empty($quota)) {
|
||||
|
||||
if (is_numeric($quota)) {
|
||||
|
||||
$newQuota = $quota;
|
||||
} elseif ($quota === 'default') {
|
||||
|
||||
$newQuota = 'default';
|
||||
} elseif ($quota === 'none') {
|
||||
|
||||
$newQuota = 'none';
|
||||
} else {
|
||||
|
||||
$newQuota = \OCP\Util::computerFileSize($quota);
|
||||
}
|
||||
|
||||
$user->setQuota($newQuota);
|
||||
$output->writeln('Quota set to "' . $user->getQuota() . '"');
|
||||
}
|
||||
|
||||
# Set enabled
|
||||
$enabled = $input->getOption('enabled');
|
||||
|
||||
if (is_numeric($enabled) || is_bool($enabled)) {
|
||||
|
||||
$user->setEnabled(boolval($enabled));
|
||||
|
||||
$enabledString = ($user->isEnabled()) ? 'enabled' : 'not enabled';
|
||||
$output->writeln('Enabled set to "' . $enabledString . '"');
|
||||
}
|
||||
|
||||
# Set Backend
|
||||
if ($this->appService->isNotNextcloud()) {
|
||||
|
||||
if (!is_null($user) && ($user->getBackendClassName() === 'OC\User\Database' || $user->getBackendClassName() === "Database")) {
|
||||
|
||||
$query = \OC_DB::prepare('UPDATE `*PREFIX*accounts` SET `backend` = ? WHERE LOWER(`user_id`) = LOWER(?)');
|
||||
$result = $query->execute([get_class($this->backend), $uid]);
|
||||
|
||||
$output->writeln('New user added to CAS backend.');
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$output->writeln('This is a Nextcloud instance, no backend update needed.');
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,187 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace OCA\UserCAS\Command;
|
||||
|
||||
use OC\User\Manager;
|
||||
use OCA\UserCAS\Service\Import\AdImporter;
|
||||
use OCA\UserCAS\Service\Import\ImporterInterface;
|
||||
use OCP\IConfig;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Helper\ProgressBar;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Logger\ConsoleLogger;
|
||||
use Symfony\Component\Console\Output\NullOutput;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Class ImportUsersAd
|
||||
* @package OCA\UserCAS\Command
|
||||
*
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
* @copyright Felix Rupp
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class ImportUsersAd extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Manager $userManager
|
||||
*/
|
||||
private $userManager;
|
||||
|
||||
/**
|
||||
* @var IConfig
|
||||
*/
|
||||
private $config;
|
||||
|
||||
|
||||
/**
|
||||
* ImportUsersAd constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->userManager = \OC::$server->getUserManager();
|
||||
$this->config = \OC::$server->getConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure method
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('cas:import-users-ad')
|
||||
->setDescription('Imports users from an ActiveDirectory LDAP.')
|
||||
->addOption(
|
||||
'delta-update',
|
||||
'd',
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'Activate updates on existing accounts'
|
||||
)
|
||||
->addOption(
|
||||
'convert-backend',
|
||||
'c',
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'Convert the backend to CAS (on update only)'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute method
|
||||
*
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
|
||||
|
||||
try {
|
||||
/**
|
||||
* @var LoggerInterface $logger
|
||||
*/
|
||||
$logger = new ConsoleLogger($output);
|
||||
|
||||
# Check for ldap extension
|
||||
if (extension_loaded("ldap")) {
|
||||
|
||||
$output->writeln('Start account import from ActiveDirectory.');
|
||||
|
||||
/**
|
||||
* @var ImporterInterface $importer
|
||||
*/
|
||||
$importer = new AdImporter($this->config);
|
||||
|
||||
$importer->init($logger);
|
||||
|
||||
$allUsers = $importer->getUsers();
|
||||
|
||||
$importer->close();
|
||||
|
||||
$output->writeln('Account import from ActiveDirectory finished.');
|
||||
|
||||
#$importer->exportAsCsv($allUsers);
|
||||
#$importer->exportAsText($allUsers);
|
||||
#exit;
|
||||
|
||||
$output->writeln('Start account import to database.');
|
||||
|
||||
$progressBar = new ProgressBar($output, count($allUsers));
|
||||
|
||||
# Convert backend
|
||||
$convertBackend = $input->getOption('convert-backend');
|
||||
|
||||
if ($convertBackend) {
|
||||
|
||||
$logger->info("Backend conversion: Backends will be converted to CAS-Backend.");
|
||||
}
|
||||
|
||||
# Delta Update
|
||||
$deltaUpdate = $input->getOption('delta-update');
|
||||
|
||||
if ($deltaUpdate) {
|
||||
|
||||
$logger->info("Delta updates: Existing users will be updated.");
|
||||
}
|
||||
|
||||
$createCommand = $this->getApplication()->find('cas:create-user');
|
||||
$updateCommand = $this->getApplication()->find('cas:update-user');
|
||||
|
||||
foreach ($allUsers as $user) {
|
||||
|
||||
$arguments = [
|
||||
'command' => 'cas:create-user',
|
||||
'uid' => $user["uid"],
|
||||
'--display-name' => $user["displayName"],
|
||||
'--email' => $user["email"],
|
||||
'--quota' => $user["quota"],
|
||||
'--enabled' => $user["enable"],
|
||||
'--group' => $user["groups"]
|
||||
];
|
||||
|
||||
# Create user if he does not exist
|
||||
if (!$this->userManager->userExists($user["uid"])) {
|
||||
|
||||
$input = new ArrayInput($arguments);
|
||||
|
||||
$createCommand->run($input, new NullOutput());
|
||||
} # Update user if he already exists and delta update is true
|
||||
else if ($this->userManager->userExists($user["uid"]) && $deltaUpdate) {
|
||||
|
||||
$arguments['command'] = 'cas:update-user';
|
||||
|
||||
if ($convertBackend) {
|
||||
|
||||
$arguments["--convert-backend"] = 1;
|
||||
}
|
||||
$input = new ArrayInput($arguments);
|
||||
|
||||
$updateCommand->run($input, new NullOutput());
|
||||
}
|
||||
|
||||
$progressBar->advance();
|
||||
}
|
||||
|
||||
$progressBar->finish();
|
||||
$progressBar->clear();
|
||||
|
||||
$output->writeln('Account import to database finished.');
|
||||
|
||||
} else {
|
||||
|
||||
throw new \Exception("User import failed. PHP extension 'ldap' is not loaded.");
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
|
||||
$logger->critical("Fatal Error: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,313 @@
|
||||
<?php
|
||||
|
||||
namespace OCA\UserCAS\Command;
|
||||
|
||||
use OCA\UserCAS\Service\AppService;
|
||||
use OCA\UserCAS\Service\LoggingService;
|
||||
use OCA\UserCAS\Service\UserService;
|
||||
|
||||
use OCA\UserCAS\User\Backend;
|
||||
use OCA\UserCAS\User\NextBackend;
|
||||
use OCA\UserCAS\User\UserCasBackendInterface;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Mail\IMailer;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
||||
|
||||
/**
|
||||
* Class UpdateUser
|
||||
*
|
||||
* @package OCA\UserCAS\Command
|
||||
*
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
* @copyright Felix Rupp <kontakt@felixrupp.com>
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
class UpdateUser extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* @var UserService
|
||||
*/
|
||||
protected $userService;
|
||||
|
||||
/**
|
||||
* @var AppService
|
||||
*/
|
||||
protected $appService;
|
||||
|
||||
/**
|
||||
* @var IUserManager
|
||||
*/
|
||||
protected $userManager;
|
||||
|
||||
/**
|
||||
* @var IGroupManager
|
||||
*/
|
||||
protected $groupManager;
|
||||
|
||||
/**
|
||||
* @var IMailer
|
||||
*/
|
||||
protected $mailer;
|
||||
|
||||
/**
|
||||
* @var LoggingService
|
||||
*/
|
||||
protected $loggingService;
|
||||
|
||||
/**
|
||||
* @var \OCP\IConfig
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var Backend|UserCasBackendInterface
|
||||
*/
|
||||
protected $backend;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$userManager = \OC::$server->getUserManager();
|
||||
$groupManager = \OC::$server->getGroupManager();
|
||||
$mailer = \OC::$server->getMailer();
|
||||
$config = \OC::$server->getConfig();
|
||||
$userSession = \OC::$server->getUserSession();
|
||||
$logger = \OC::$server->getLogger();
|
||||
$urlGenerator = \OC::$server->getURLGenerator();
|
||||
$appManager = \OC::$server->getAppManager();
|
||||
|
||||
$loggingService = new LoggingService('user_cas', $config, $logger);
|
||||
$this->appService = new AppService('user_cas', $config, $loggingService, $userManager, $userSession, $urlGenerator, $appManager);
|
||||
|
||||
$userService = new UserService(
|
||||
'user_cas',
|
||||
$config,
|
||||
$userManager,
|
||||
$userSession,
|
||||
$groupManager,
|
||||
$this->appService,
|
||||
$loggingService
|
||||
);
|
||||
|
||||
if ($this->appService->isNotNextcloud()) {
|
||||
|
||||
$backend = new Backend(
|
||||
'user_cas',
|
||||
$config,
|
||||
$loggingService,
|
||||
$this->appService,
|
||||
$userManager,
|
||||
$userService
|
||||
);
|
||||
} else {
|
||||
|
||||
$backend = new NextBackend(
|
||||
'user_cas',
|
||||
$config,
|
||||
$loggingService,
|
||||
$this->appService,
|
||||
$userManager,
|
||||
$userService
|
||||
);
|
||||
}
|
||||
|
||||
$this->userService = $userService;
|
||||
$this->userManager = $userManager;
|
||||
$this->groupManager = $groupManager;
|
||||
$this->mailer = $mailer;
|
||||
$this->loggingService = $loggingService;
|
||||
$this->config = $config;
|
||||
$this->backend = $backend;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('cas:update-user')
|
||||
->setDescription('Updates an existing user and, if not yet a CAS user, converts the record to CAS backend.')
|
||||
->addArgument(
|
||||
'uid',
|
||||
InputArgument::REQUIRED,
|
||||
'User ID used to login (must only contain a-z, A-Z, 0-9, -, _ and @).'
|
||||
)
|
||||
->addOption(
|
||||
'display-name',
|
||||
null,
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'User name used in the web UI (can contain any characters).'
|
||||
)
|
||||
->addOption(
|
||||
'email',
|
||||
null,
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'Email address for the user.'
|
||||
)
|
||||
->addOption(
|
||||
'group',
|
||||
'g',
|
||||
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
|
||||
'The groups the user should be added to (The group will be created if it does not exist).'
|
||||
)
|
||||
->addOption(
|
||||
'quota',
|
||||
'o',
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'The quota the user should get, either as numeric value in bytes or as a human readable string (e.g. 1GB for 1 Gigabyte)'
|
||||
)
|
||||
->addOption(
|
||||
'enabled',
|
||||
'e',
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'Set user enabled'
|
||||
)
|
||||
->addOption(
|
||||
'convert-backend',
|
||||
'c',
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'Convert the backend to CAS'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return int|null
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
|
||||
$uid = $input->getArgument('uid');
|
||||
if (!$this->userManager->userExists($uid)) {
|
||||
$output->writeln('<error>The user "' . $uid . '" does not exist.</error>');
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Validate email before we create the user
|
||||
if ($input->getOption('email')) {
|
||||
// Validate first
|
||||
if (!$this->mailer->validateMailAddress($input->getOption('email'))) {
|
||||
// Invalid! Error
|
||||
$output->writeln('<error>Invalid email address supplied</error>');
|
||||
return 1;
|
||||
} else {
|
||||
$email = $input->getOption('email');
|
||||
}
|
||||
} else {
|
||||
$email = null;
|
||||
}
|
||||
|
||||
# Register Backend
|
||||
$this->userService->registerBackend($this->backend);
|
||||
|
||||
/**
|
||||
* @var IUser
|
||||
*/
|
||||
$user = $this->userManager->get($uid);
|
||||
|
||||
if ($user instanceof IUser) {
|
||||
|
||||
$output->writeln('<info>The user "' . $user->getUID() . '" has been found</info>');
|
||||
} else {
|
||||
|
||||
$output->writeln('<error>An error occurred while finding the user</error>');
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Set displayName
|
||||
if ($input->getOption('display-name')) {
|
||||
|
||||
$user->setDisplayName($input->getOption('display-name'));
|
||||
$output->writeln('Display name set to "' . $user->getDisplayName() . '"');
|
||||
}
|
||||
|
||||
# Set email if supplied & valid
|
||||
if ($email !== null) {
|
||||
|
||||
$user->setEMailAddress($email);
|
||||
$output->writeln('Email address set to "' . $user->getEMailAddress() . '"');
|
||||
}
|
||||
|
||||
# Set Groups
|
||||
$groups = (array)$input->getOption('group');
|
||||
|
||||
if (count($groups) > 0) {
|
||||
|
||||
$this->userService->updateGroups($user, $groups, $this->config->getAppValue('user_cas', 'cas_protected_groups'));
|
||||
$output->writeln('Groups have been updated.');
|
||||
}
|
||||
|
||||
# Set Quota
|
||||
$quota = $input->getOption('quota');
|
||||
|
||||
if (!empty($quota)) {
|
||||
|
||||
if (is_numeric($quota)) {
|
||||
|
||||
$newQuota = $quota;
|
||||
} elseif ($quota === 'default') {
|
||||
|
||||
$newQuota = 'default';
|
||||
} elseif ($quota === 'none') {
|
||||
|
||||
$newQuota = 'none';
|
||||
} else {
|
||||
|
||||
$newQuota = \OCP\Util::computerFileSize($quota);
|
||||
}
|
||||
|
||||
$user->setQuota($newQuota);
|
||||
$output->writeln('Quota set to "' . $user->getQuota() . '"');
|
||||
}
|
||||
|
||||
# Set enabled
|
||||
$enabled = $input->getOption('enabled');
|
||||
|
||||
if (is_numeric($enabled) || is_bool($enabled)) {
|
||||
|
||||
$user->setEnabled(boolval($enabled));
|
||||
|
||||
$enabledString = ($user->isEnabled()) ? 'enabled' : 'not enabled';
|
||||
$output->writeln('Enabled set to "' . $enabledString . '"');
|
||||
}
|
||||
|
||||
# Convert backend
|
||||
$convertBackend = $input->getOption('convert-backend');
|
||||
|
||||
if ($convertBackend) {
|
||||
|
||||
# Set Backend
|
||||
if ($this->appService->isNotNextcloud()) {
|
||||
|
||||
$query = \OC_DB::prepare('UPDATE `*PREFIX*accounts` SET `backend` = ? WHERE LOWER(`user_id`) = LOWER(?)');
|
||||
$result = $query->execute([get_class($this->backend), $uid]);
|
||||
|
||||
$output->writeln('New user added to CAS backend.');
|
||||
|
||||
} else {
|
||||
|
||||
$output->writeln('This is a Nextcloud instance, no backend update needed.');
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,296 @@
|
||||
<?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\Controller;
|
||||
|
||||
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use \OCP\IRequest;
|
||||
use \OCP\AppFramework\Http\RedirectResponse;
|
||||
use \OCP\AppFramework\Controller;
|
||||
use \OCP\IConfig;
|
||||
use \OCP\IUserSession;
|
||||
|
||||
use OCA\UserCAS\Service\AppService;
|
||||
use OCA\UserCAS\Service\UserService;
|
||||
use OCA\UserCAS\Service\LoggingService;
|
||||
use OCA\UserCAS\Exception\PhpCas\PhpUserCasLibraryNotFoundException;
|
||||
|
||||
|
||||
/**
|
||||
* Class AuthenticationController
|
||||
*
|
||||
* @package OCA\UserCAS\Controller
|
||||
*
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
* @copyright Felix Rupp <kontakt@felixrupp.com>
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
class AuthenticationController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string $appName
|
||||
*/
|
||||
protected $appName;
|
||||
|
||||
/**
|
||||
* @var \OCP\IConfig $config
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @var \OCA\UserCAS\Service\UserService $userService
|
||||
*/
|
||||
private $userService;
|
||||
|
||||
/**
|
||||
* @var \OCA\UserCAS\Service\AppService $appService
|
||||
*/
|
||||
private $appService;
|
||||
|
||||
/**
|
||||
* @var IUserSession $userSession
|
||||
*/
|
||||
private $userSession;
|
||||
|
||||
/**
|
||||
* @var \OCA\UserCAS\Service\LoggingService $loggingService
|
||||
*/
|
||||
private $loggingService;
|
||||
|
||||
/**
|
||||
* AuthenticationController constructor.
|
||||
* @param $appName
|
||||
* @param IRequest $request
|
||||
* @param IConfig $config
|
||||
* @param UserService $userService
|
||||
* @param AppService $appService
|
||||
* @param IUserSession $userSession
|
||||
* @param LoggingService $loggingService
|
||||
*/
|
||||
public function __construct($appName, IRequest $request, IConfig $config, UserService $userService, AppService $appService, IUserSession $userSession, LoggingService $loggingService)
|
||||
{
|
||||
$this->appName = $appName;
|
||||
$this->config = $config;
|
||||
$this->userService = $userService;
|
||||
$this->appService = $appService;
|
||||
$this->userSession = $userSession;
|
||||
$this->loggingService = $loggingService;
|
||||
parent::__construct($appName, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Login method.
|
||||
*
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
* @PublicPage
|
||||
* @UseSession
|
||||
* @OnlyUnauthenticatedUsers
|
||||
*
|
||||
* @return RedirectResponse|TemplateResponse
|
||||
*/
|
||||
public function casLogin()
|
||||
{
|
||||
|
||||
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());
|
||||
|
||||
header("Location: " . $this->appService->getAbsoluteURL('/'));
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
# Handle redirect based on cookie value
|
||||
if (isset($_COOKIE['user_cas_redirect_url'])) {
|
||||
|
||||
$url = urldecode($_COOKIE['user_cas_redirect_url']);
|
||||
|
||||
if (strpos($url, 'http') !== FALSE || strpos($url, 'https') !== FALSE) {
|
||||
|
||||
$location = $url;
|
||||
} else {
|
||||
|
||||
$location = $this->appService->getAbsoluteURL($url);
|
||||
}
|
||||
} else {
|
||||
|
||||
$location = $this->appService->getAbsoluteURL("/");
|
||||
}
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'The Redirect URL Parameter in Login Action was: ' . $location);
|
||||
|
||||
if (!$this->userService->isLoggedIn()) {
|
||||
|
||||
try {
|
||||
|
||||
if (\phpCAS::isAuthenticated()) {
|
||||
|
||||
#$userName = \phpCAS::getUser();
|
||||
$userName = $this->userService->getUserId();
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS user " . $userName . " has been authenticated.");
|
||||
|
||||
$isLoggedIn = $this->userService->login($this->request, $userName);
|
||||
|
||||
if ($isLoggedIn) {
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS user has been authenticated against owncloud.");
|
||||
|
||||
# Reset cookie
|
||||
setcookie("user_cas_redirect_url", '/', 0, '/');
|
||||
|
||||
return new RedirectResponse($location);
|
||||
} else { # Not authenticated against owncloud
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS user has not been authenticated against owncloud.");
|
||||
|
||||
return $this->casError(null, \OCP\AppFramework\Http::STATUS_FORBIDDEN);
|
||||
}
|
||||
} else { # Not authenticated against CAS
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS user is not authenticated, redirect to CAS server.");
|
||||
|
||||
\phpCAS::forceAuthentication();
|
||||
}
|
||||
} catch (\CAS_Exception $e) {
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::ERROR, "phpCAS has thrown an exception with code: " . $e->getCode() . " and message: " . $e->getMessage() . ".");
|
||||
|
||||
return $this->casError(null, \OCP\AppFramework\Http::STATUS_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
} else {
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS user is already authenticated against owncloud.");
|
||||
|
||||
# Reset cookie
|
||||
setcookie("user_cas_redirect_url", '/', 0, '/');
|
||||
|
||||
return new RedirectResponse($location);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Logout method for CAS Single-Logout-Feature.
|
||||
*
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
* @PublicPage
|
||||
* @UseSession
|
||||
*/
|
||||
public function casLogout()
|
||||
{
|
||||
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());
|
||||
|
||||
header("Location: " . $this->appService->getAbsoluteURL('/'));
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
// Logout oC/NC user
|
||||
if ($this->userService->isLoggedIn()) {
|
||||
|
||||
$this->userService->logout();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render error view
|
||||
*
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
* @PublicPage
|
||||
* @UseSession
|
||||
* @OnlyUnauthenticatedUsers
|
||||
*
|
||||
* @param \Exception|null $exception
|
||||
* @param int $additionalErrorCode
|
||||
*
|
||||
* @return TemplateResponse
|
||||
*/
|
||||
private function casError(\Exception $exception = NULL, $additionalErrorCode = 0)
|
||||
{
|
||||
$params = [];
|
||||
|
||||
if ($additionalErrorCode !== 0) {
|
||||
|
||||
if ($additionalErrorCode === \OCP\AppFramework\Http::STATUS_FORBIDDEN) {
|
||||
|
||||
if (boolval($this->config->getAppValue('user_cas', 'cas_ecas_attributeparserenabled', false))) {
|
||||
|
||||
$params['errorCode'] = '';
|
||||
$params['errorMessage'] = "You do not have access to the JRCbox application. Please contact the JRCbox administrator if something feels wrong to you.";
|
||||
} else {
|
||||
|
||||
$params['errorCode'] = $additionalErrorCode;
|
||||
$params['errorMessage'] = "Forbidden. You do not have access to this application. Please refer to your administrator if something feels wrong to you.";
|
||||
}
|
||||
}
|
||||
|
||||
if ($additionalErrorCode === \OCP\AppFramework\Http::STATUS_INTERNAL_SERVER_ERROR) {
|
||||
|
||||
$params['errorCode'] = $additionalErrorCode;
|
||||
$params['errorMessage'] = "Internal Server Error. The server encountered an error. Please try again.";
|
||||
}
|
||||
} else if ($exception instanceof \Exception) {
|
||||
|
||||
$params['errorCode'] = $exception->getCode();
|
||||
$params['errorMessage'] = $exception->getMessage();
|
||||
}
|
||||
|
||||
/*if ($this->config->getAppValue($this->appName, 'cas_force_login') === '1') {
|
||||
|
||||
$newProtocol = 'http://';
|
||||
|
||||
if (intval($this->config->getAppValue($this->appName, 'cas_server_port')) === 443) {
|
||||
|
||||
$newProtocol = 'https://';
|
||||
}
|
||||
|
||||
$params['backUrl'] = $newProtocol . $this->config->getAppValue($this->appName, 'cas_server_hostname') . $this->config->getAppValue($this->appName, 'cas_server_path');
|
||||
} else {*/
|
||||
|
||||
$params['backUrl'] = $this->appService->getAbsoluteURL('/');
|
||||
//}
|
||||
|
||||
$response = new TemplateResponse($this->appName, 'cas-error', $params, 'guest');
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
@ -0,0 +1,246 @@
|
||||
<?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\Controller;
|
||||
|
||||
use OCP\IRequest;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\IL10N;
|
||||
use OCP\IConfig;
|
||||
|
||||
|
||||
/**
|
||||
* Class SettingsController
|
||||
*
|
||||
* @package OCA\UserCAS\Controller
|
||||
*
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
* @copyright Felix Rupp <kontakt@felixrupp.com>
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
class SettingsController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var IL10N
|
||||
*/
|
||||
private $l10n;
|
||||
|
||||
/**
|
||||
* @var IConfig
|
||||
*/
|
||||
private $config;
|
||||
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $appName;
|
||||
|
||||
/**
|
||||
* SettingsController constructor.
|
||||
* @param $appName
|
||||
* @param IRequest $request
|
||||
* @param IConfig $config
|
||||
* @param IL10N $l10n
|
||||
*/
|
||||
public function __construct($appName, IRequest $request, IConfig $config, IL10N $l10n)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->appName = $appName;
|
||||
$this->l10n = $l10n;
|
||||
parent::__construct($appName, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @AdminRequired
|
||||
*
|
||||
* @param string $cas_server_version
|
||||
* @param string $cas_server_hostname
|
||||
* @param string $cas_server_port
|
||||
* @param string $cas_server_path
|
||||
* @param string $cas_protected_groups
|
||||
* @param string $cas_default_group
|
||||
* @param string $cas_groups_letter_filter
|
||||
* @param string $cas_groups_create_default_for_user_prefix
|
||||
* @param string $cas_userid_mapping
|
||||
* @param string $cas_email_mapping
|
||||
* @param string $cas_displayName_mapping
|
||||
* @param string $cas_group_mapping
|
||||
* @param string $cas_quota_mapping
|
||||
* @param string $cas_cert_path
|
||||
* @param string $cas_debug_file
|
||||
* @param string $cas_php_cas_path
|
||||
* @param string $cas_service_url
|
||||
* @param string $cas_handlelogout_servers
|
||||
* @param string $cas_login_button_label
|
||||
* @param string $cas_access_allow_groups
|
||||
* @param string $cas_ecas_accepted_strengths
|
||||
* @param string $cas_ecas_retrieve_groups
|
||||
* @param string $cas_ecas_assurance_level
|
||||
* @param string $cas_access_group_quotas
|
||||
* @param string $cas_force_login_exceptions
|
||||
* @param string $cas_ecas_internal_ip_range
|
||||
* @param string $cas_import_ad_protocol
|
||||
* @param string $cas_import_ad_host
|
||||
* @param string $cas_import_ad_port
|
||||
* @param string $cas_import_ad_user
|
||||
* @param string $cas_import_ad_domain
|
||||
* @param string $cas_import_ad_password
|
||||
* @param string $cas_import_ad_base_dn
|
||||
* @param string $cas_import_ad_sync_filter
|
||||
* @param string $cas_import_ad_sync_pagesize
|
||||
* @param string $cas_import_map_uid
|
||||
* @param string $cas_import_map_displayname
|
||||
* @param string $cas_import_map_email
|
||||
* @param string $cas_import_map_groups
|
||||
* @param string $cas_import_map_groups_description
|
||||
* @param string $cas_import_map_quota
|
||||
* @param string $cas_import_map_enabled
|
||||
* @param string $cas_import_map_enabled_and_bitwise
|
||||
* @param string $cas_import_map_dn
|
||||
* @param string $cas_import_map_dn_filter
|
||||
* @param string|null $cas_ecas_attributeparserenabled
|
||||
* @param string|null $cas_ecas_request_full_userdetails
|
||||
* @param string|null $cas_force_login
|
||||
* @param string|null $cas_autocreate
|
||||
* @param string|null $cas_update_user_data
|
||||
* @param string|null $cas_link_to_ldap_backend
|
||||
* @param string|null $cas_disable_logout
|
||||
* @param string|null $cas_disable_singlesignout
|
||||
* @param string|null $cas_use_proxy
|
||||
* @param string|null $cas_import_merge
|
||||
* @param string|null $cas_import_merge_enabled
|
||||
* @param string|null $cas_groups_letter_umlauts
|
||||
* @param string|null $cas_keep_ticket_ids
|
||||
* @param string|null $cas_groups_json_decode
|
||||
* @param string|null $cas_groups_create_default_for_user
|
||||
* @param string|null $cas_shares_protected
|
||||
* @return mixed
|
||||
*/
|
||||
public function saveSettings($cas_server_version, $cas_server_hostname, $cas_server_port, $cas_server_path, $cas_protected_groups, $cas_default_group, $cas_groups_letter_filter, $cas_groups_create_default_for_user_prefix,
|
||||
$cas_userid_mapping, $cas_email_mapping, $cas_displayName_mapping, $cas_group_mapping, $cas_quota_mapping, $cas_cert_path, $cas_debug_file, $cas_php_cas_path, $cas_service_url, $cas_handlelogout_servers, $cas_login_button_label,
|
||||
$cas_access_allow_groups, $cas_ecas_accepted_strengths, $cas_ecas_retrieve_groups, $cas_ecas_assurance_level, $cas_access_group_quotas, $cas_force_login_exceptions, $cas_ecas_internal_ip_range,
|
||||
$cas_import_ad_protocol, $cas_import_ad_host, $cas_import_ad_port, $cas_import_ad_user, $cas_import_ad_domain, $cas_import_ad_password, $cas_import_ad_base_dn, $cas_import_ad_sync_filter, $cas_import_ad_sync_pagesize,
|
||||
$cas_import_map_uid, $cas_import_map_displayname, $cas_import_map_email, $cas_import_map_groups, $cas_import_map_groups_description, $cas_import_map_quota, $cas_import_map_enabled, $cas_import_map_enabled_and_bitwise, $cas_import_map_dn, $cas_import_map_dn_filter,
|
||||
$cas_ecas_attributeparserenabled = NULL, $cas_ecas_request_full_userdetails = NULL, $cas_force_login = NULL, $cas_autocreate = NULL, $cas_update_user_data = NULL, $cas_link_to_ldap_backend = NULL,
|
||||
$cas_disable_logout = NULL, $cas_disable_singlesignout = NULL, $cas_use_proxy = NULL, $cas_import_merge = NULL, $cas_import_merge_enabled = NULL, $cas_groups_letter_umlauts = NULL, $cas_keep_ticket_ids = NULL, $cas_groups_json_decode = NULL,
|
||||
$cas_groups_create_default_for_user = NULL, $cas_shares_protected = NULL)
|
||||
{
|
||||
|
||||
try {
|
||||
|
||||
# CAS Server
|
||||
$this->config->setAppValue($this->appName, 'cas_server_version', $cas_server_version);
|
||||
$this->config->setAppValue($this->appName, 'cas_server_hostname', $cas_server_hostname);
|
||||
$this->config->setAppValue($this->appName, 'cas_server_port', $cas_server_port);
|
||||
$this->config->setAppValue($this->appName, 'cas_server_path', $cas_server_path);
|
||||
|
||||
# Basic
|
||||
$this->config->setAppValue($this->appName, 'cas_force_login_exceptions', $cas_force_login_exceptions);
|
||||
$this->config->setAppValue($this->appName, 'cas_protected_groups', $cas_protected_groups);
|
||||
$this->config->setAppValue($this->appName, 'cas_default_group', $cas_default_group);
|
||||
$this->config->setAppValue($this->appName, 'cas_access_allow_groups', $cas_access_allow_groups);
|
||||
$this->config->setAppValue($this->appName, 'cas_access_group_quotas', $cas_access_group_quotas);
|
||||
$this->config->setAppValue($this->appName, 'cas_cert_path', $cas_cert_path);
|
||||
$this->config->setAppValue($this->appName, 'cas_service_url', $cas_service_url);
|
||||
$this->config->setAppValue($this->appName, 'cas_handlelogout_servers', $cas_handlelogout_servers);
|
||||
$this->config->setAppValue($this->appName, 'cas_login_button_label', $cas_login_button_label);
|
||||
|
||||
# Mapping
|
||||
$this->config->setAppValue($this->appName, 'cas_userid_mapping', $cas_userid_mapping);
|
||||
$this->config->setAppValue($this->appName, 'cas_email_mapping', $cas_email_mapping);
|
||||
$this->config->setAppValue($this->appName, 'cas_displayName_mapping', $cas_displayName_mapping);
|
||||
$this->config->setAppValue($this->appName, 'cas_group_mapping', $cas_group_mapping);
|
||||
$this->config->setAppValue($this->appName, 'cas_quota_mapping', $cas_quota_mapping);
|
||||
$this->config->setAppValue($this->appName, 'cas_groups_letter_filter', $cas_groups_letter_filter);
|
||||
$this->config->setAppValue($this->appName, 'cas_groups_create_default_for_user_prefix', $cas_groups_create_default_for_user_prefix);
|
||||
|
||||
# phpCas
|
||||
$this->config->setAppValue($this->appName, 'cas_debug_file', $cas_debug_file);
|
||||
$this->config->setAppValue($this->appName, 'cas_php_cas_path', $cas_php_cas_path);
|
||||
|
||||
# ECAS settings
|
||||
$this->config->setAppValue($this->appName, 'cas_ecas_accepted_strengths', $cas_ecas_accepted_strengths);
|
||||
$this->config->setAppValue($this->appName, 'cas_ecas_retrieve_groups', $cas_ecas_retrieve_groups);
|
||||
$this->config->setAppValue($this->appName, 'cas_ecas_assurance_level', $cas_ecas_assurance_level);
|
||||
$this->config->setAppValue($this->appName, 'cas_ecas_internal_ip_range', $cas_ecas_internal_ip_range);
|
||||
|
||||
# Import module AD
|
||||
$this->config->setAppValue($this->appName, 'cas_import_ad_protocol', $cas_import_ad_protocol);
|
||||
$this->config->setAppValue($this->appName, 'cas_import_ad_host', $cas_import_ad_host);
|
||||
$this->config->setAppValue($this->appName, 'cas_import_ad_port', intval($cas_import_ad_port));
|
||||
$this->config->setAppValue($this->appName, 'cas_import_ad_user', $cas_import_ad_user);
|
||||
$this->config->setAppValue($this->appName, 'cas_import_ad_domain', $cas_import_ad_domain);
|
||||
|
||||
if(strlen($cas_import_ad_password) > 0) { # Only save if a new password is given
|
||||
$this->config->setAppValue($this->appName, 'cas_import_ad_password', $cas_import_ad_password);
|
||||
}
|
||||
|
||||
$this->config->setAppValue($this->appName, 'cas_import_ad_base_dn', $cas_import_ad_base_dn);
|
||||
$this->config->setAppValue($this->appName, 'cas_import_ad_sync_filter', htmlspecialchars_decode($cas_import_ad_sync_filter));
|
||||
$this->config->setAppValue($this->appName, 'cas_import_ad_sync_pagesize', intval($cas_import_ad_sync_pagesize));
|
||||
|
||||
# Import module cli mapping
|
||||
$this->config->setAppValue($this->appName, 'cas_import_map_uid', $cas_import_map_uid);
|
||||
$this->config->setAppValue($this->appName, 'cas_import_map_displayname', $cas_import_map_displayname);
|
||||
$this->config->setAppValue($this->appName, 'cas_import_map_email', $cas_import_map_email);
|
||||
$this->config->setAppValue($this->appName, 'cas_import_map_groups', $cas_import_map_groups);
|
||||
$this->config->setAppValue($this->appName, 'cas_import_map_groups_description', $cas_import_map_groups_description);
|
||||
$this->config->setAppValue($this->appName, 'cas_import_map_quota', $cas_import_map_quota);
|
||||
$this->config->setAppValue($this->appName, 'cas_import_map_enabled', $cas_import_map_enabled);
|
||||
$this->config->setAppValue($this->appName, 'cas_import_map_enabled_and_bitwise', $cas_import_map_enabled_and_bitwise);
|
||||
$this->config->setAppValue($this->appName, 'cas_import_map_dn', $cas_import_map_dn);
|
||||
$this->config->setAppValue($this->appName, 'cas_import_map_dn_filter', $cas_import_map_dn_filter);
|
||||
|
||||
# Checkbox settings
|
||||
$this->config->setAppValue($this->appName, 'cas_force_login', ($cas_force_login !== NULL) ? '1' : '0');
|
||||
$this->config->setAppValue($this->appName, 'cas_autocreate', ($cas_autocreate !== NULL) ? '1' : '0');
|
||||
$this->config->setAppValue($this->appName, 'cas_update_user_data', ($cas_update_user_data !== NULL) ? '1' : '0');
|
||||
$this->config->setAppValue($this->appName, 'cas_link_to_ldap_backend', ($cas_link_to_ldap_backend !== NULL) ? '1' : '0');
|
||||
$this->config->setAppValue($this->appName, 'cas_disable_logout', ($cas_disable_logout !== NULL) ? '1' : '0');
|
||||
$this->config->setAppValue($this->appName, 'cas_disable_singlesignout', ($cas_disable_singlesignout !== NULL) ? '1' : '0');
|
||||
$this->config->setAppValue($this->appName, 'cas_ecas_attributeparserenabled', ($cas_ecas_attributeparserenabled !== NULL) ? '1' : '0');
|
||||
$this->config->setAppValue($this->appName, 'cas_ecas_request_full_userdetails', ($cas_ecas_request_full_userdetails !== NULL) ? '1' : '0');
|
||||
$this->config->setAppValue($this->appName, 'cas_use_proxy', ($cas_use_proxy !== NULL) ? '1' : '0');
|
||||
$this->config->setAppValue($this->appName, 'cas_import_merge', ($cas_import_merge !== NULL) ? '1' : '0');
|
||||
$this->config->setAppValue($this->appName, 'cas_import_merge_enabled', ($cas_import_merge_enabled !== NULL) ? '1' : '0');
|
||||
$this->config->setAppValue($this->appName, 'cas_groups_letter_umlauts', ($cas_groups_letter_umlauts !== NULL) ? '1' : '0');
|
||||
$this->config->setAppValue($this->appName, 'cas_keep_ticket_ids', ($cas_keep_ticket_ids !== NULL) ? '1' : '0');
|
||||
$this->config->setAppValue($this->appName, 'cas_groups_json_decode', ($cas_groups_json_decode !== NULL) ? '1' : '0');
|
||||
$this->config->setAppValue($this->appName, 'cas_groups_create_default_for_user', ($cas_groups_create_default_for_user !== NULL) ? '1' : '0');
|
||||
$this->config->setAppValue($this->appName, 'cas_shares_protected', ($cas_shares_protected !== NULL) ? '1' : '0');
|
||||
|
||||
|
||||
return array(
|
||||
'code' => 200,
|
||||
'message' => $this->l10n->t('Your CAS settings have been updated.')
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
|
||||
return array(
|
||||
'code' => 500,
|
||||
'message' => $this->l10n->t('Your CAS settings could not be updated. Please try again.')
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
<?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\Exception\PhpCas;
|
||||
|
||||
|
||||
use OCA\UserCAS\Exception\UserCasException;
|
||||
|
||||
/**
|
||||
* Class PhpUserCasLibraryNotFoundException
|
||||
*
|
||||
* @package OCA\UserCAS\Exception\PhpCas
|
||||
*
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
* @copyright Felix Rupp <kontakt@felixrupp.com>
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
class PhpUserCasLibraryNotFoundException extends UserCasException
|
||||
{
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
<?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\Exception;
|
||||
|
||||
|
||||
/**
|
||||
* Class UserCasException
|
||||
*
|
||||
* @package OCA\UserCAS\Exception
|
||||
*
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
* @copyright Felix Rupp <kontakt@felixrupp.com>
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
class UserCasException extends \Exception
|
||||
{
|
||||
}
|
@ -0,0 +1,448 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
@ -0,0 +1,136 @@
|
||||
<?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\Panels;
|
||||
|
||||
use OCP\Settings\ISettings;
|
||||
use OCP\Template;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\IConfig;
|
||||
|
||||
/**
|
||||
* Class Admin
|
||||
*
|
||||
* @package OCA\UserCAS\Panels
|
||||
*
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
* @copyright Felix Rupp <kontakt@felixrupp.com>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
class Admin implements ISettings
|
||||
{
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $params = array('cas_server_version', 'cas_server_hostname', 'cas_server_port', 'cas_server_path', 'cas_force_login', 'cas_force_login_exceptions','cas_autocreate',
|
||||
'cas_update_user_data', 'cas_keep_ticket_ids', 'cas_login_button_label', 'cas_protected_groups', 'cas_default_group', 'cas_ecas_attributeparserenabled', 'cas_userid_mapping', 'cas_email_mapping', 'cas_displayName_mapping', 'cas_group_mapping', 'cas_quota_mapping',
|
||||
'cas_cert_path', 'cas_debug_file', 'cas_php_cas_path', 'cas_link_to_ldap_backend', 'cas_disable_logout', 'cas_disable_singlesignout', 'cas_handlelogout_servers', 'cas_service_url', 'cas_access_allow_groups',
|
||||
'cas_access_group_quotas', 'cas_groups_letter_filter', 'cas_groups_letter_umlauts', 'cas_groups_json_decode', 'cas_groups_create_default_for_user', 'cas_groups_create_default_for_user_prefix',
|
||||
'cas_import_ad_protocol', 'cas_import_ad_host', 'cas_import_ad_port', 'cas_import_ad_user', 'cas_import_ad_domain', 'cas_import_ad_password', 'cas_import_ad_base_dn', 'cas_import_ad_sync_filter', 'cas_import_ad_sync_pagesize',
|
||||
'cas_import_map_uid', 'cas_import_map_displayname', 'cas_import_map_email', 'cas_import_map_groups', 'cas_import_map_groups_description', 'cas_import_map_quota', 'cas_import_map_enabled', 'cas_import_map_enabled_and_bitwise', 'cas_import_map_dn_filter', 'cas_import_map_dn', 'cas_import_merge', 'cas_import_merge_enabled',
|
||||
'cas_ecas_accepted_strengths', 'cas_ecas_retrieve_groups','cas_ecas_request_full_userdetails', 'cas_ecas_assurance_level','cas_use_proxy', 'cas_ecas_internal_ip_range', 'cas_shares_protected');
|
||||
|
||||
/**
|
||||
* @var IConfig
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* Admin constructor.
|
||||
*
|
||||
* @param IConfig $config
|
||||
*/
|
||||
public function __construct(IConfig $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSectionID()
|
||||
{
|
||||
return 'authentication';
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Nextcloud 13 support
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public function getSection()
|
||||
{
|
||||
return 'security';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPriority()
|
||||
{
|
||||
return 50;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Panel
|
||||
*
|
||||
* @return Template
|
||||
*/
|
||||
public function getPanel()
|
||||
{
|
||||
|
||||
$tmpl = new Template('user_cas', 'admin');
|
||||
|
||||
foreach ($this->params as $param) {
|
||||
|
||||
$value = htmlentities($this->config->getAppValue('user_cas', $param));
|
||||
|
||||
$tmpl->assign($param, $value);
|
||||
}
|
||||
|
||||
return $tmpl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Nextcloud 13 support
|
||||
*
|
||||
* @return TemplateResponse
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public function getForm()
|
||||
{
|
||||
|
||||
$parameters = array();
|
||||
|
||||
foreach ($this->params as $param) {
|
||||
|
||||
$parameters[$param] = htmlentities($this->config->getAppValue('user_cas', $param));
|
||||
}
|
||||
|
||||
return new TemplateResponse('user_cas', 'admin', $parameters);
|
||||
}
|
||||
}
|
@ -0,0 +1,1025 @@
|
||||
<?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\Service;
|
||||
|
||||
use OC\Authentication\Token\IToken;
|
||||
use OCA\UserCAS\Exception\PhpCas\PhpUserCasLibraryNotFoundException;
|
||||
use OCP\App\IAppManager;
|
||||
use \OCP\IConfig;
|
||||
use \OCP\IUserSession;
|
||||
use \OCP\IUserManager;
|
||||
use \OCP\IURLGenerator;
|
||||
|
||||
/**
|
||||
* Class UserService
|
||||
*
|
||||
* @package OCA\UserCAS\Service
|
||||
*
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
* @copyright Felix Rupp <kontakt@felixrupp.com>
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
class AppService
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string $appName
|
||||
*/
|
||||
private $appName;
|
||||
|
||||
/**
|
||||
* @var \OCP\IConfig $appConfig
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @var \OCA\UserCAS\Service\LoggingService
|
||||
*/
|
||||
private $loggingService;
|
||||
|
||||
/**
|
||||
* @var \OCP\IUserManager $userManager
|
||||
*/
|
||||
private $userManager;
|
||||
|
||||
/**
|
||||
* @var \OCP\IUserSession $userSession
|
||||
*/
|
||||
private $userSession;
|
||||
|
||||
/**
|
||||
* @var \OCP\IURLGenerator $urlGenerator
|
||||
*/
|
||||
private $urlGenerator;
|
||||
|
||||
/**
|
||||
* @var IAppManager $appManager
|
||||
*/
|
||||
private $appManager;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $casVersion;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $casHostname;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $casPort;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $casPath;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $casDebugFile;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $casCertPath;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $casPhpFile;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $casServiceUrl;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
private $casDisableLogout;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
private $casDisableSinglesignout;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $casHandleLogoutServers;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
private $casKeepTicketIds;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $cas_ecas_accepted_strengths;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $cas_ecas_retrieve_groups;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $cas_ecas_assurance_level;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
private $cas_ecas_request_full_userdetails;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $cas_ecas_internal_ip_range;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
private $casInitialized;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
private $ecasAttributeParserEnabled;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
private $casUseProxy;
|
||||
|
||||
/**
|
||||
* UserService constructor.
|
||||
* @param $appName
|
||||
* @param \OCP\IConfig $config
|
||||
* @param \OCA\UserCAS\Service\LoggingService $loggingService
|
||||
* @param \OCP\IUserManager $userManager
|
||||
* @param \OCP\IUserSession $userSession
|
||||
* @param \OCP\IURLGenerator $urlGenerator
|
||||
* @param IAppManager $appManager
|
||||
*/
|
||||
public function __construct($appName, IConfig $config, LoggingService $loggingService, IUserManager $userManager, IUserSession $userSession, IURLGenerator $urlGenerator, IAppManager $appManager)
|
||||
{
|
||||
|
||||
$this->appName = $appName;
|
||||
$this->config = $config;
|
||||
$this->loggingService = $loggingService;
|
||||
$this->userManager = $userManager;
|
||||
$this->userSession = $userSession;
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
$this->appManager = $appManager;
|
||||
$this->casInitialized = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* init method.
|
||||
* @throws PhpUserCasLibraryNotFoundException
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
|
||||
$serverHostName = (isset($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : '';
|
||||
|
||||
// Gather all app config values
|
||||
$this->casVersion = $this->config->getAppValue($this->appName, 'cas_server_version', '3.0');
|
||||
$this->casHostname = $this->config->getAppValue($this->appName, 'cas_server_hostname', $serverHostName);
|
||||
$this->casPort = intval($this->config->getAppValue($this->appName, 'cas_server_port', 443));
|
||||
$this->casPath = $this->config->getAppValue($this->appName, 'cas_server_path', '/cas');
|
||||
$this->casServiceUrl = $this->config->getAppValue($this->appName, 'cas_service_url', '');
|
||||
$this->casCertPath = $this->config->getAppValue($this->appName, 'cas_cert_path', '');
|
||||
|
||||
|
||||
// Correctly handle cas server path for document root
|
||||
if ($this->casPath === '/') {
|
||||
$this->casPath = '';
|
||||
}
|
||||
|
||||
$this->casUseProxy = boolval($this->config->getAppValue($this->appName, 'cas_use_proxy', false));
|
||||
$this->casDisableLogout = boolval($this->config->getAppValue($this->appName, 'cas_disable_logout', false));
|
||||
$this->casDisableSinglesignout = boolval($this->config->getAppValue($this->appName, 'cas_disable_singlesignout', false));
|
||||
$logoutServersArray = explode(",", $this->config->getAppValue($this->appName, 'cas_handlelogout_servers', ''));
|
||||
$this->casHandleLogoutServers = array();
|
||||
$this->casKeepTicketIds = boolval($this->config->getAppValue($this->appName, 'cas_keep_ticket_ids', false));
|
||||
|
||||
# ECAS
|
||||
$this->ecasAttributeParserEnabled = boolval($this->config->getAppValue($this->appName, 'cas_ecas_attributeparserenabled', false));
|
||||
$this->cas_ecas_request_full_userdetails = boolval($this->config->getAppValue($this->appName, 'cas_ecas_request_full_userdetails', false));
|
||||
$this->cas_ecas_accepted_strengths = $this->config->getAppValue($this->appName, 'cas_ecas_accepted_strengths');
|
||||
$this->cas_ecas_retrieve_groups = $this->config->getAppValue($this->appName, 'cas_ecas_retrieve_groups');
|
||||
$this->cas_ecas_assurance_level = $this->config->getAppValue($this->appName, 'cas_ecas_assurance_level');
|
||||
$this->cas_ecas_internal_ip_range = $this->config->getAppValue($this->appName, 'cas_ecas_internal_ip_range');
|
||||
|
||||
|
||||
foreach ($logoutServersArray as $casHandleLogoutServer) {
|
||||
|
||||
$casHandleLogoutServer = ltrim(trim($casHandleLogoutServer));
|
||||
|
||||
if (strlen($casHandleLogoutServer) > 4) {
|
||||
|
||||
$this->casHandleLogoutServers[] = $casHandleLogoutServer;
|
||||
}
|
||||
}
|
||||
|
||||
$this->casDebugFile = $this->config->getAppValue($this->appName, 'cas_debug_file', '');
|
||||
$this->casPhpFile = $this->config->getAppValue($this->appName, 'cas_php_cas_path', '');
|
||||
|
||||
if (is_string($this->casPhpFile) && strlen($this->casPhpFile) > 0) {
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'Use custom phpCAS file:: ' . $this->casPhpFile);
|
||||
#\OCP\Util::writeLog('cas', 'Use custom phpCAS file:: ' . $this->casPhpFile, \OCA\UserCas\Service\LoggingService::DEBUG);
|
||||
|
||||
if (is_file($this->casPhpFile)) {
|
||||
|
||||
require_once("$this->casPhpFile");
|
||||
} else {
|
||||
|
||||
throw new PhpUserCasLibraryNotFoundException('Your custom phpCAS library could not be loaded. The class was not found. Please disable the app with ./occ command or in Database and adjust the path to your library (or remove it to use the shipped library).', 500);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (is_file(__DIR__ . '/../../vendor/jasig/phpcas/CAS.php')) {
|
||||
|
||||
require_once(__DIR__ . '/../../vendor/jasig/phpcas/CAS.php');
|
||||
} else {
|
||||
|
||||
throw new PhpUserCasLibraryNotFoundException('phpCAS library could not be loaded. The class was not found.', 500);
|
||||
}
|
||||
}
|
||||
|
||||
if (!class_exists('\\phpCAS')) {
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::ERROR, 'phpCAS library could not be loaded. The class was not found.');
|
||||
|
||||
throw new PhpUserCasLibraryNotFoundException('phpCAS library could not be loaded. The class was not found.', 500);
|
||||
}
|
||||
|
||||
if (!\phpCAS::isInitialized()) {
|
||||
|
||||
try {
|
||||
|
||||
\phpCAS::setVerbose(FALSE);
|
||||
|
||||
if (!empty($this->casDebugFile)) {
|
||||
|
||||
\phpCAS::setDebug($this->casDebugFile);
|
||||
\phpCAS::setVerbose(TRUE);
|
||||
}
|
||||
|
||||
$serviceBasedUrl = $this->getServiceBasedUrl();
|
||||
|
||||
# Initialize client
|
||||
if ($this->casUseProxy) {
|
||||
|
||||
\phpCAS::proxy($this->casVersion, $this->casHostname, (int)($this->casPort), $this->casPath, $serviceBasedUrl);
|
||||
} else {
|
||||
|
||||
\phpCAS::client($this->casVersion, $this->casHostname, (int)($this->casPort), $this->casPath, $serviceBasedUrl);
|
||||
}
|
||||
|
||||
# Handle SingleSignout requests
|
||||
if (!$this->casDisableSinglesignout) {
|
||||
|
||||
\phpCAS::setSingleSignoutCallback([$this, 'casSingleSignOut']);
|
||||
\phpCAS::handleLogoutRequests(true, $this->casHandleLogoutServers);
|
||||
}
|
||||
|
||||
# Handle fixed service URL
|
||||
if (!empty($this->casServiceUrl)) {
|
||||
|
||||
\phpCAS::setFixedServiceURL($this->casServiceUrl);
|
||||
}
|
||||
|
||||
# Handle certificate
|
||||
if (!empty($this->casCertPath)) {
|
||||
|
||||
\phpCAS::setCasServerCACert($this->casCertPath);
|
||||
} else {
|
||||
|
||||
\phpCAS::setNoCasServerValidation();
|
||||
}
|
||||
|
||||
# Handle keeping of cas-ticket-ids
|
||||
if ($this->casKeepTicketIds) {
|
||||
|
||||
\phpCAS::setNoClearTicketsFromUrl();
|
||||
}
|
||||
|
||||
# Handle ECAS Attributes if enabled
|
||||
if ($this->ecasAttributeParserEnabled) {
|
||||
|
||||
if (is_file(__DIR__ . '/../../vendor/ec-europa/ecas-phpcas-parser/src/EcasPhpCASParser.php')) {
|
||||
|
||||
require_once(__DIR__ . '/../../vendor/ec-europa/ecas-phpcas-parser/src/EcasPhpCASParser.php');
|
||||
} else {
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::ERROR, 'phpCAS EcasPhpCASParser library could not be loaded. The class was not found.');
|
||||
|
||||
throw new PhpUserCasLibraryNotFoundException('phpCAS EcasPhpCASParser could not be loaded. The class was not found.', 500);
|
||||
}
|
||||
|
||||
# Register the parser
|
||||
\phpCAS::setCasAttributeParserCallback(array(new \EcasPhpCASParser\EcasPhpCASParser(), 'parse'));
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS EcasPhpCASParser has been successfully set.");
|
||||
}
|
||||
|
||||
#### Register the new ticket validation url
|
||||
if ((is_string($this->cas_ecas_retrieve_groups) && strlen($this->cas_ecas_retrieve_groups) > 0)
|
||||
|| ($this->cas_ecas_request_full_userdetails)
|
||||
|| (is_string($this->cas_ecas_assurance_level) && strlen($this->cas_ecas_assurance_level) > 0)
|
||||
|| (is_string($this->cas_ecas_accepted_strengths) && strlen($this->cas_ecas_accepted_strengths) > 0)) {
|
||||
|
||||
|
||||
## Check for external IP Ranges to en-/disable the Two-Factor-Authentication (AcceptedStrength at least MEDIUM)
|
||||
if ($this->isIpInLocalRange($this->cas_ecas_internal_ip_range) && $this->cas_ecas_accepted_strengths !== '') {
|
||||
|
||||
$this->cas_ecas_accepted_strengths = 'BASIC';
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS ECAS AcceptedStrength Level is forced to BASIC, because the user is in the internal network. Test Address: " . $endIp . " | Users Remote Address: " . $remoteAddress);
|
||||
}
|
||||
|
||||
# Add acceptedStrength Querystring Parameters
|
||||
if (is_string($this->cas_ecas_accepted_strengths) && strlen($this->cas_ecas_accepted_strengths) > 0) {
|
||||
|
||||
# Register the new login url
|
||||
$serverLoginUrl = \phpCAS::getServerLoginURL();
|
||||
|
||||
$serverLoginUrl = $this->buildQueryUrl($serverLoginUrl, 'acceptStrengths=' . urlencode($this->cas_ecas_accepted_strengths));
|
||||
|
||||
\phpCAS::setServerLoginURL($serverLoginUrl);
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS ECAS strength attribute has been successfully set. New service login URL: " . $serverLoginUrl);
|
||||
}
|
||||
|
||||
## Change validation URL based on ECAS assuranceLevel
|
||||
$newProtocol = 'http://';
|
||||
$newUrl = '';
|
||||
$newSamlUrl = '';
|
||||
|
||||
if ($this->getCasPort() === 443) {
|
||||
|
||||
$newProtocol = 'https://';
|
||||
}
|
||||
|
||||
if ($this->getCasVersion() === "1.0") {
|
||||
|
||||
$newUrl = $newProtocol . $this->getCasHostname() . $this->getCasPath() . '/validate';
|
||||
} else if ($this->getCasVersion() === "2.0") {
|
||||
|
||||
$newUrl = $newProtocol . $this->getCasHostname() . $this->getCasPath() . '/serviceValidate';
|
||||
} else if ($this->getCasVersion() === "3.0") {
|
||||
|
||||
$newUrl = $newProtocol . $this->getCasHostname() . $this->getCasPath() . '/p3/serviceValidate';
|
||||
} else if ($this->getCasVersion() === "S1") {
|
||||
|
||||
$newSamlUrl = $newProtocol . $this->getCasHostname() . $this->getCasPath() . '/samlValidate';
|
||||
}
|
||||
|
||||
if (is_string($this->cas_ecas_assurance_level) && $this->cas_ecas_assurance_level === 'LOW') {
|
||||
|
||||
$newUrl = $newProtocol . $this->getCasHostname() . $this->getCasPath() . '/laxValidate';
|
||||
} else if (is_string($this->cas_ecas_assurance_level) && $this->cas_ecas_assurance_level === 'MEDIUM') {
|
||||
|
||||
$newUrl = $newProtocol . $this->getCasHostname() . $this->getCasPath() . '/sponsorValidate';
|
||||
} else if (is_string($this->cas_ecas_assurance_level) && $this->cas_ecas_assurance_level === 'HIGH') {
|
||||
|
||||
$newUrl = $newProtocol . $this->getCasHostname() . $this->getCasPath() . '/interinstitutionalValidate';
|
||||
} else if (is_string($this->cas_ecas_assurance_level) && $this->cas_ecas_assurance_level === 'TOP') {
|
||||
|
||||
$newUrl = $newProtocol . $this->getCasHostname() . $this->getCasPath() . '/strictValidate';
|
||||
}
|
||||
|
||||
if (!empty($this->casServiceUrl)) {
|
||||
|
||||
$newUrl = $this->buildQueryUrl($newUrl, 'service=' . urlencode($this->casServiceUrl));
|
||||
$newSamlUrl = $this->buildQueryUrl($newSamlUrl, 'TARGET=' . urlencode($this->casServiceUrl));
|
||||
} else {
|
||||
|
||||
$newUrl = $this->buildQueryUrl($newUrl, 'service=' . urlencode(\phpCAS::getServiceURL()));
|
||||
$newSamlUrl = $this->buildQueryUrl($newSamlUrl, 'TARGET=' . urlencode(\phpCAS::getServiceURL()));
|
||||
}
|
||||
|
||||
# Add the groups to retrieve
|
||||
if (is_string($this->cas_ecas_retrieve_groups) && strlen($this->cas_ecas_retrieve_groups) > 0) {
|
||||
|
||||
$newUrl = $this->buildQueryUrl($newUrl, 'groups=' . urlencode($this->cas_ecas_retrieve_groups));
|
||||
$newSamlUrl = $this->buildQueryUrl($newSamlUrl, 'groups=' . urlencode($this->cas_ecas_retrieve_groups));
|
||||
}
|
||||
|
||||
# Add the requestFullUserDetails flag
|
||||
if ($this->cas_ecas_request_full_userdetails) {
|
||||
|
||||
$newUrl = $this->buildQueryUrl($newUrl, 'userDetails=' . urlencode('true'));
|
||||
$newSamlUrl = $this->buildQueryUrl($newSamlUrl, 'userDetails=' . urlencode('true'));
|
||||
}
|
||||
|
||||
# Set the user agent to mimic an ecas client
|
||||
$userAgent = sprintf("ECAS PHP Client (%s, %s)",
|
||||
'2.1.3',
|
||||
$_SERVER['SERVER_SOFTWARE']);
|
||||
\phpCAS::setExtraCurlOption(CURLOPT_USERAGENT, $userAgent);
|
||||
|
||||
# Set the new URLs
|
||||
if ($this->getCasVersion() !== "S1" && !empty($newUrl)) {
|
||||
|
||||
\phpCAS::setServerServiceValidateURL($newUrl);
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS ECAS additional attributes have been successfully set. New CAS " . $this->getCasVersion() . " service validate URL: " . $newUrl);
|
||||
|
||||
} elseif ($this->getCasVersion() === "S1" && !empty($newSamlUrl)) {
|
||||
|
||||
\phpCAS::setServerSamlValidateURL($newSamlUrl);
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS ECAS additional attributes have been successfully set. New SAML 1.0 service validate URL: " . $newSamlUrl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->casInitialized = TRUE;
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS has been successfully initialized.");
|
||||
|
||||
} catch (\CAS_Exception $e) {
|
||||
|
||||
\phpCAS::setVerbose(TRUE);
|
||||
|
||||
$this->casInitialized = FALSE;
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::ERROR, "phpCAS has thrown an exception with code: " . $e->getCode() . " and message: " . $e->getMessage() . ".");
|
||||
}
|
||||
} else {
|
||||
|
||||
$this->casInitialized = TRUE;
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS has already been initialized.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the instance is not a Nextcloud instance
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isNotNextcloud()
|
||||
{
|
||||
|
||||
require __DIR__ . '/../../../../version.php';
|
||||
|
||||
/**
|
||||
* @var string $vendor The vendor of this instance
|
||||
*/
|
||||
|
||||
#$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS vendor: ".$vendor);
|
||||
|
||||
if (strpos(strtolower($vendor), 'next') === FALSE) {
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if login should be enforced using user_cas.
|
||||
*
|
||||
* @param $remoteAddress
|
||||
* @param string $requestUri
|
||||
* @return bool TRUE|FALSE
|
||||
*/
|
||||
public function isEnforceAuthentication($remoteAddress, $requestUri)
|
||||
{
|
||||
|
||||
$isEnforced = TRUE;
|
||||
|
||||
$forceLoginExceptions = $this->config->getAppValue($this->appName, 'cas_force_login_exceptions', '');
|
||||
$forceLoginExceptionsArray = explode(',', $forceLoginExceptions);
|
||||
|
||||
# Enforce off
|
||||
if ($this->config->getAppValue($this->appName, 'cas_force_login') !== '1') {
|
||||
|
||||
$isEnforced = FALSE;
|
||||
} else {
|
||||
|
||||
# Check enforce IP ranges
|
||||
foreach ($forceLoginExceptionsArray as $forceLoginException) {
|
||||
|
||||
$forceLoginExceptionRanges = explode('-', $forceLoginException);
|
||||
|
||||
if (isset($forceLoginExceptionRanges[0])) {
|
||||
|
||||
if (isset($forceLoginExceptionRanges[1])) {
|
||||
|
||||
$baseIpComponents = explode('.', $forceLoginExceptionRanges[0]);
|
||||
|
||||
$baseIp = $baseIpComponents[0] . '.' . $baseIpComponents[1] . '.';
|
||||
|
||||
$additionalIpComponents = explode('.', $forceLoginExceptionRanges[1]);
|
||||
|
||||
if (isset($additionalIpComponents[1]) && $additionalIpComponents[0]) {
|
||||
|
||||
# We have a two part range here (eg. 127.0.0.1-1.19) which means, we have to cover 127.0.0.1-127.0.0.254 and 127.0.1.1-127.0.1.19
|
||||
|
||||
for ($ipThirdPart = intval($baseIpComponents[2]); $ipThirdPart <= intval($additionalIpComponents[0]); $ipThirdPart++) {
|
||||
|
||||
if ($ipThirdPart !== intval($additionalIpComponents[0])) {
|
||||
|
||||
$ipFourthPartMax = 254;
|
||||
} else {
|
||||
|
||||
$ipFourthPartMax = intval($additionalIpComponents[1]);
|
||||
}
|
||||
|
||||
for ($ipFourthPart = intval($baseIpComponents[3]); $ipFourthPart <= $ipFourthPartMax; $ipFourthPart++) {
|
||||
|
||||
$endIp = $baseIp . $ipThirdPart . '.' . $ipFourthPart;
|
||||
|
||||
#$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS Enforce Login IP checked: " . $endIp);
|
||||
|
||||
if ($remoteAddress === $endIp) {
|
||||
|
||||
$isEnforced = FALSE;
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS Enforce Login NOT triggered. Test Address: " . $endIp . " | Users Remote Address: " . $remoteAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ($additionalIpComponents[0]) {
|
||||
|
||||
# We have a one part range here (eg. 127.0.0.1-19)
|
||||
|
||||
$newIp = $baseIp . $baseIpComponents[2] . '.';
|
||||
|
||||
for ($ipFourthPart = intval($baseIpComponents[3]); $ipFourthPart <= intval($additionalIpComponents[0]); $ipFourthPart++) {
|
||||
|
||||
$endIp = $newIp . $ipFourthPart;
|
||||
|
||||
if ($remoteAddress === $endIp) {
|
||||
|
||||
$isEnforced = FALSE;
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS Enforce Login NOT triggered. Test Address: " . $endIp . " | Users Remote Address: " . $remoteAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
# Single IP-Adress given
|
||||
if ($remoteAddress === $forceLoginExceptionRanges[0]) {
|
||||
|
||||
$isEnforced = FALSE;
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS Enforce Login NOT triggered. Test Address: " . $forceLoginExceptionRanges[0] . " | Users Remote Address: " . $remoteAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# User already logged in
|
||||
if ($this->userSession->isLoggedIn()) {
|
||||
|
||||
$isEnforced = FALSE;
|
||||
}
|
||||
|
||||
# Disable on Nextcloud login-flow use
|
||||
if (!$this->isNotNextcloud() && strpos($requestUri, "/login/flow") !== FALSE) {
|
||||
|
||||
$isEnforced = FALSE;
|
||||
}
|
||||
|
||||
return $isEnforced;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if public shares should be protected
|
||||
*
|
||||
* @return bool TRUE|FALSE
|
||||
*/
|
||||
public function arePublicSharesProtected()
|
||||
{
|
||||
$protected = (bool)$this->config->getAppValue($this->appName, 'cas_shares_protected', FALSE);
|
||||
$loggedIn = $this->userSession->isLoggedIn();
|
||||
|
||||
if($loggedIn && $protected) {
|
||||
$protected = FALSE;
|
||||
}
|
||||
|
||||
return $protected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Login
|
||||
*
|
||||
*/
|
||||
public function registerLogIn()
|
||||
{
|
||||
|
||||
$loginButtonLabel = $this->config->getAppValue($this->appName, 'cas_login_button_label', 'CAS Login');
|
||||
|
||||
// Login Button handling
|
||||
if (strlen($loginButtonLabel) <= 0) {
|
||||
|
||||
$loginButtonLabel = 'CAS Login';
|
||||
}
|
||||
|
||||
$this->unregisterLogin();
|
||||
|
||||
if ($this->isNotNextcloud()) {
|
||||
|
||||
/** @var array $loginAlternatives */
|
||||
/*$loginAlternatives = $this->config->getSystemValue('login.alternatives', []);
|
||||
|
||||
$loginAlreadyRegistered = FALSE;
|
||||
|
||||
foreach ($loginAlternatives as $key => $loginAlternative) {
|
||||
|
||||
if (isset($loginAlternative['name']) && $loginAlternative['name'] === $loginButtonLabel) {
|
||||
|
||||
$loginAlternatives[$key]['href'] = $this->linkToRoute($this->appName . '.authentication.casLogin');
|
||||
$this->config->setSystemValue('login.alternatives', $loginAlternatives);
|
||||
$loginAlreadyRegistered = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$loginAlreadyRegistered) {*/
|
||||
|
||||
$loginAlternatives[] = ['href' => $this->linkToRoute($this->appName . '.authentication.casLogin'), 'name' => $loginButtonLabel, 'img' => $this->appManager->getAppWebPath($this->appName).'/img/cas-logo.png'];
|
||||
|
||||
$this->config->setSystemValue('login.alternatives', $loginAlternatives);
|
||||
#}
|
||||
} else {
|
||||
|
||||
#$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS Nextcloud " . $version[0] . "." . $version[1] . "." . $version[2] . "." . " detected.");
|
||||
\OC_App::registerLogIn(array('href' => $this->linkToRoute($this->appName . '.authentication.casLogin'), 'name' => $loginButtonLabel));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* UnregisterLogin
|
||||
*/
|
||||
public function unregisterLogin()
|
||||
{
|
||||
|
||||
$loginButtonLabel = $this->config->getAppValue($this->appName, 'cas_login_button_label', 'CAS Login');
|
||||
|
||||
// Login Button handling
|
||||
if (strlen($loginButtonLabel) <= 0) {
|
||||
|
||||
$loginButtonLabel = 'CAS Login';
|
||||
}
|
||||
|
||||
if ($this->isNotNextcloud()) {
|
||||
|
||||
$loginAlternatives = $this->config->getSystemValue('login.alternatives', []);
|
||||
|
||||
foreach ($loginAlternatives as $key => $loginAlternative) {
|
||||
|
||||
if (isset($loginAlternative['name']) && ($loginAlternative['name'] === $loginButtonLabel || $loginAlternative['name'] === 'CAS Login')) {
|
||||
|
||||
unset($loginAlternatives[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->config->setSystemValue('login.alternatives', $loginAlternatives);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isSetupValid()
|
||||
{
|
||||
|
||||
$casHostname = $this->config->getAppValue($this->appName, 'cas_server_hostname');
|
||||
$casPort = intval($this->config->getAppValue($this->appName, 'cas_server_port'));
|
||||
$casPath = $this->config->getAppValue($this->appName, 'cas_server_path');
|
||||
|
||||
if (is_string($casHostname) && strlen($casHostname) > 1 && is_int($casPort) && $casPort > 1 && is_string($casPath) && strpos($casPath, "/") === 0) {
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a link to $route with URLGenerator.
|
||||
*
|
||||
* @param string $route
|
||||
* @param array $arguments
|
||||
* @return string
|
||||
*/
|
||||
public function linkToRoute($route, $arguments = array())
|
||||
{
|
||||
|
||||
return $this->urlGenerator->linkToRoute($route, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an absolute link to $route with URLGenerator.
|
||||
*
|
||||
* @param string $route
|
||||
* @param array $arguments
|
||||
* @return string
|
||||
*/
|
||||
public function linkToRouteAbsolute($route, $arguments = array())
|
||||
{
|
||||
|
||||
return $this->urlGenerator->linkToRouteAbsolute($route, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an url relative to owncloud host
|
||||
*
|
||||
* @param string $url
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAbsoluteURL($url)
|
||||
{
|
||||
|
||||
return $this->urlGenerator->getAbsoluteURL($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function isCasInitialized()
|
||||
{
|
||||
return $this->casInitialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to append query parameters to an url. Since the url
|
||||
* might already contain parameter it has to be detected and to build a proper
|
||||
* URL
|
||||
*
|
||||
* @param string $url base url to add the query params to
|
||||
* @param string $query params in query form with & separated
|
||||
*
|
||||
* @return string url with query params
|
||||
*/
|
||||
private function buildQueryUrl($url, $query)
|
||||
{
|
||||
$url .= (strstr($url, '?') === false) ? '?' : '&';
|
||||
$url .= $query;
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test if the client’s IP adress is in our local range
|
||||
*
|
||||
* @param string|array $internalIps
|
||||
* @return bool TRUE|FALSE
|
||||
*/
|
||||
private function isIpInLocalRange($internalIps)
|
||||
{
|
||||
|
||||
if (is_string($internalIps)) {
|
||||
|
||||
$internalIps = explode(',', $internalIps);
|
||||
}
|
||||
|
||||
$remoteAddress = $_SERVER['REMOTE_ADDR'];
|
||||
|
||||
$proxyHeader = "HTTP_X_FORWARDED_FOR";
|
||||
|
||||
# Header can contain multiple IP-s of proxies that are passed through.
|
||||
# Only the IP added by the last proxy (last IP in the list) can be trusted.
|
||||
if (array_key_exists($proxyHeader, $_SERVER)) {
|
||||
|
||||
$explodedProxyHeader = explode(",", $_SERVER[$proxyHeader]);
|
||||
$proxyIp = trim(end($explodedProxyHeader));
|
||||
|
||||
if (filter_var($proxyIp, FILTER_VALIDATE_IP)) {
|
||||
|
||||
$remoteAddress = $proxyIp;
|
||||
}
|
||||
}
|
||||
|
||||
# Check enforce IP ranges for acceptedStrength attribute
|
||||
foreach ($internalIps as $internalIp) {
|
||||
|
||||
$internalIpRanges = explode('-', $internalIp);
|
||||
|
||||
if (isset($internalIpRanges[0])) {
|
||||
|
||||
if (isset($internalIpRanges[1])) {
|
||||
|
||||
$baseIpComponents = explode('.', $internalIpRanges[0]);
|
||||
|
||||
$baseIp = $baseIpComponents[0] . '.' . $baseIpComponents[1] . '.';
|
||||
|
||||
$additionalIpComponents = explode('.', $internalIpRanges[1]);
|
||||
|
||||
if (isset($additionalIpComponents[1]) && $additionalIpComponents[0]) {
|
||||
|
||||
# We have a two part range here (eg. 127.0.0.1-1.19) which means, we have to cover 127.0.0.1-127.0.0.254 and 127.0.1.1-127.0.1.19
|
||||
|
||||
for ($ipThirdPart = intval($baseIpComponents[2]); $ipThirdPart <= intval($additionalIpComponents[0]); $ipThirdPart++) {
|
||||
|
||||
if ($ipThirdPart !== intval($additionalIpComponents[0])) {
|
||||
|
||||
$ipFourthPartMax = 254;
|
||||
} else {
|
||||
|
||||
$ipFourthPartMax = intval($additionalIpComponents[1]);
|
||||
}
|
||||
|
||||
for ($ipFourthPart = intval($baseIpComponents[3]); $ipFourthPart <= $ipFourthPartMax; $ipFourthPart++) {
|
||||
|
||||
$endIp = $baseIp . $ipThirdPart . '.' . $ipFourthPart;
|
||||
|
||||
#$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS Enforce Login IP checked: " . $endIp);
|
||||
|
||||
if ($remoteAddress === $endIp) {
|
||||
|
||||
return TRUE;
|
||||
|
||||
/*if ($this->cas_ecas_accepted_strengths !== '') {
|
||||
|
||||
$this->cas_ecas_accepted_strengths = 'BASIC';
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS ECAS AcceptedStrength Level is forced to BASIC, because the user is in the internal network. Test Address: " . $endIp . " | Users Remote Address: " . $remoteAddress);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ($additionalIpComponents[0]) {
|
||||
|
||||
# We have a one part range here (eg. 127.0.0.1-19)
|
||||
|
||||
$newIp = $baseIp . $baseIpComponents[2] . '.';
|
||||
|
||||
for ($ipFourthPart = intval($baseIpComponents[3]); $ipFourthPart <= intval($additionalIpComponents[0]); $ipFourthPart++) {
|
||||
|
||||
$endIp = $newIp . $ipFourthPart;
|
||||
|
||||
if ($remoteAddress === $endIp) {
|
||||
|
||||
return TRUE;
|
||||
|
||||
/*if ($this->cas_ecas_accepted_strengths !== '') {
|
||||
|
||||
$this->cas_ecas_accepted_strengths = 'BASIC';
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS ECAS AcceptedStrength is forced to BASIC, because the user is in the internal network. Test Address: " . $endIp . " | Users Remote Address: " . $remoteAddress);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
# Single IP-Adress given
|
||||
if ($remoteAddress === $internalIpRanges[0]) {
|
||||
|
||||
return TRUE;
|
||||
|
||||
/*if ($this->cas_ecas_accepted_strengths !== '') {
|
||||
|
||||
$this->cas_ecas_accepted_strengths = 'BASIC';
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, "phpCAS ECAS AcceptedStrength is forced to BASIC, because the user is in the internal network. Test Address: " . $internalIpRanges[0] . " | Users Remote Address: " . $remoteAddress);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function for CAS singleSignOut call
|
||||
*
|
||||
* @author Vincent <https://github.com/pingou2712>
|
||||
*
|
||||
* @param string $ticket Ticket Object
|
||||
*/
|
||||
public function casSingleSignOut($ticket)
|
||||
{
|
||||
// Extract the userID from the SAML Request
|
||||
$decodedLogoutRequest = urldecode($_POST['logoutRequest']);
|
||||
preg_match(
|
||||
"|<saml:NameID[^>]*>(.*)</saml:NameID>|",
|
||||
$decodedLogoutRequest, $tick, PREG_OFFSET_CAPTURE, 3
|
||||
);
|
||||
$wrappedSamlNameId = preg_replace(
|
||||
'|<saml:NameID[^>]*>|', '', $tick[0][0]
|
||||
);
|
||||
$nameId = preg_replace(
|
||||
'|</saml:NameID>|', '', $wrappedSamlNameId
|
||||
);
|
||||
|
||||
//Kill Session Of UserID:
|
||||
$this->killSessionUserName($nameId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Kill the username's session.
|
||||
*
|
||||
* @author Vincent <https://github.com/pingou2712>
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
*
|
||||
* @param string $username The username of the user.
|
||||
* @return NULL
|
||||
*/
|
||||
private function killSessionUserName($username)
|
||||
{
|
||||
|
||||
if ($this->userManager->userExists($username)) {
|
||||
|
||||
$tokenType = IToken::TEMPORARY_TOKEN;
|
||||
|
||||
$sql = "DELETE FROM oc_authtoken WHERE uid = ? AND type = ? AND password IS NULL;";
|
||||
$stmt = \OC::$server->getDatabaseConnection()->prepare($sql);
|
||||
$stmt->bindParam(1, $username, \PDO::PARAM_STR);
|
||||
$stmt->bindParam(2, $tokenType, \PDO::PARAM_INT);
|
||||
|
||||
$stmt->execute();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
## Setters/Getters
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAppName()
|
||||
{
|
||||
return $this->appName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCasVersion()
|
||||
{
|
||||
return $this->casVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCasHostname()
|
||||
{
|
||||
return $this->casHostname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getCasPort()
|
||||
{
|
||||
return $this->casPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCasPath()
|
||||
{
|
||||
return $this->casPath;
|
||||
}
|
||||
|
||||
private function getServiceBasedUrl(): string {
|
||||
$overwrite = \OC::$server->getConfig()->getSystemValue('overwrite.cli.url');
|
||||
if($overwrite) return $overwrite;
|
||||
|
||||
$httpProtocol = \OC::$server->getConfig()->getSystemValue('protocol');
|
||||
$currentUrl = $_SERVER['SERVER_NAME'];
|
||||
|
||||
return $httpProtocol . $currentUrl;
|
||||
}
|
||||
}
|
@ -0,0 +1,477 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace OCA\UserCAS\Service\Import;
|
||||
|
||||
use OCA\UserCAS\Service\Merge\AdUserMerger;
|
||||
use OCA\UserCAS\Service\Merge\MergerInterface;
|
||||
use OCP\IConfig;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Class AdImporter
|
||||
* @package OCA\UserCAS\Service\Import
|
||||
*
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
* @copyright Felix Rupp
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class AdImporter implements ImporterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var boolean|resource
|
||||
*/
|
||||
private $ldapConnection;
|
||||
|
||||
/**
|
||||
* @var MergerInterface $merger
|
||||
*/
|
||||
private $merger;
|
||||
|
||||
/**
|
||||
* @var LoggerInterface $logger
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* @var IConfig
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @var string $appName
|
||||
*/
|
||||
private $appName = 'user_cas';
|
||||
|
||||
|
||||
/**
|
||||
* AdImporter constructor.
|
||||
* @param IConfig $config
|
||||
*/
|
||||
public function __construct(IConfig $config)
|
||||
{
|
||||
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param LoggerInterface $logger
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function init(LoggerInterface $logger)
|
||||
{
|
||||
|
||||
$this->merger = new AdUserMerger($logger);
|
||||
$this->logger = $logger;
|
||||
|
||||
$this->ldapConnect();
|
||||
$this->ldapBind();
|
||||
|
||||
$this->logger->info("Init complete.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
|
||||
$this->ldapClose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get User data
|
||||
*
|
||||
* @return array User data
|
||||
*/
|
||||
public function getUsers()
|
||||
{
|
||||
|
||||
$uidAttribute = $this->config->getAppValue($this->appName, 'cas_import_map_uid');
|
||||
|
||||
$displayNameAttribute1 = $this->config->getAppValue($this->appName, 'cas_import_map_displayname');
|
||||
$displayNameAttribute2 = '';
|
||||
|
||||
if (strpos($displayNameAttribute1, "+") !== FALSE) {
|
||||
$displayNameAttributes = explode("+", $displayNameAttribute1);
|
||||
$displayNameAttribute1 = $displayNameAttributes[0];
|
||||
$displayNameAttribute2 = $displayNameAttributes[1];
|
||||
}
|
||||
|
||||
|
||||
$emailAttribute = $this->config->getAppValue($this->appName, 'cas_import_map_email');
|
||||
$groupsAttribute = $this->config->getAppValue($this->appName, 'cas_import_map_groups');
|
||||
$quotaAttribute = $this->config->getAppValue($this->appName, 'cas_import_map_quota');
|
||||
$enableAttribute = $this->config->getAppValue($this->appName, 'cas_import_map_enabled');
|
||||
$dnAttribute = $this->config->getAppValue($this->appName, 'cas_import_map_dn');
|
||||
$mergeAttribute = boolval($this->config->getAppValue($this->appName, 'cas_import_merge'));
|
||||
$primaryAccountDnStartswWith = $this->config->getAppValue($this->appName, 'cas_import_map_dn_filter');
|
||||
$preferEnabledAccountsOverDisabled = boolval($this->config->getAppValue($this->appName, 'cas_import_merge_enabled'));
|
||||
$andEnableAttributeBitwise = $this->config->getAppValue($this->appName, 'cas_import_map_enabled_and_bitwise');
|
||||
|
||||
$keep = [$uidAttribute, $displayNameAttribute1, $displayNameAttribute2, $emailAttribute, $groupsAttribute, $quotaAttribute, $enableAttribute, $dnAttribute];
|
||||
|
||||
$groupAttrField = $this->config->getAppValue($this->appName, 'cas_import_map_groups_description');
|
||||
$groupsKeep = [$groupAttrField];
|
||||
|
||||
$pageSize = $this->config->getAppValue($this->appName, 'cas_import_ad_sync_pagesize');
|
||||
|
||||
$users = [];
|
||||
|
||||
$this->logger->info("Getting all users from the AD …");
|
||||
|
||||
# Get all members of the sync group
|
||||
$memberPages = $this->getLdapList($this->config->getAppValue($this->appName, 'cas_import_ad_base_dn'), $this->config->getAppValue($this->appName, 'cas_import_ad_sync_filter'), $keep, $pageSize);
|
||||
|
||||
foreach ($memberPages as $memberPage) {
|
||||
|
||||
#var_dump($memberPage["count"]);
|
||||
|
||||
for ($key = 0; $key < $memberPage["count"]; $key++) {
|
||||
|
||||
$m = $memberPage[$key];
|
||||
|
||||
# Each attribute is returned as an array, the first key is [count], [0]+ will contain the actual value(s)
|
||||
$employeeID = isset($m[$uidAttribute][0]) ? $m[$uidAttribute][0] : "";
|
||||
$mail = isset($m[$emailAttribute][0]) ? $m[$emailAttribute][0] : "";
|
||||
$dn = isset($m[$dnAttribute]) ? $m[$dnAttribute] : "";
|
||||
|
||||
$displayName = $employeeID;
|
||||
|
||||
if (isset($m[$displayNameAttribute1][0])) {
|
||||
|
||||
$displayName = $m[$displayNameAttribute1][0];
|
||||
|
||||
if (strlen($displayNameAttribute2) > 0 && isset($m[$displayNameAttribute2][0])) {
|
||||
|
||||
$displayName .= " " . $m[$displayNameAttribute2][0];
|
||||
}
|
||||
} else {
|
||||
|
||||
if (strlen($displayNameAttribute2) > 0 && isset($m[$displayNameAttribute2][0])) {
|
||||
|
||||
$displayName = $m[$displayNameAttribute2][0];
|
||||
}
|
||||
}
|
||||
|
||||
$quota = isset($m[$quotaAttribute][0]) ? intval($m[$quotaAttribute][0]) : 0;
|
||||
|
||||
|
||||
$enable = 1;
|
||||
|
||||
# Shift enable attribute bytewise?
|
||||
if (isset($m[$enableAttribute][0])) {
|
||||
|
||||
if (strlen($andEnableAttributeBitwise) > 0) {
|
||||
|
||||
if (is_numeric($andEnableAttributeBitwise)) {
|
||||
|
||||
$andEnableAttributeBitwise = intval($andEnableAttributeBitwise);
|
||||
}
|
||||
|
||||
$enable = intval((intval($m[$enableAttribute][0]) & $andEnableAttributeBitwise) == 0);
|
||||
} else {
|
||||
|
||||
$enable = intval($m[$enableAttribute][0]);
|
||||
}
|
||||
}
|
||||
|
||||
$groupsArray = [];
|
||||
|
||||
$addUser = FALSE;
|
||||
|
||||
if (isset($m[$groupsAttribute][0])) {
|
||||
|
||||
# Cycle all groups of the user
|
||||
for ($j = 0; $j < $m[$groupsAttribute]["count"]; $j++) {
|
||||
|
||||
# Check if user has MAP_GROUPS attribute
|
||||
if (isset($m[$groupsAttribute][$j])) {
|
||||
|
||||
$addUser = TRUE; # Only add user if the group has a MAP_GROUPS attribute
|
||||
|
||||
$groupCn = $m[$groupsAttribute][$j];
|
||||
|
||||
# Retrieve the MAP_GROUPS_FIELD attribute of the group
|
||||
$groupAttr = $this->getLdapAttributes($groupCn, $groupsKeep);
|
||||
$groupName = '';
|
||||
|
||||
if (isset($groupAttr[$groupAttrField][0])) {
|
||||
|
||||
$groupName = $groupAttr[$groupAttrField][0];
|
||||
|
||||
/*# Replace umlauts
|
||||
if (boolval($this->config->getAppValue($this->appName, 'cas_import_map_groups_letter_umlauts'))) {
|
||||
|
||||
$groupName = str_replace("Ä", "Ae", $groupName);
|
||||
$groupName = str_replace("Ö", "Oe", $groupName);
|
||||
$groupName = str_replace("Ü", "Ue", $groupName);
|
||||
$groupName = str_replace("ä", "ae", $groupName);
|
||||
$groupName = str_replace("ö", "oe", $groupName);
|
||||
$groupName = str_replace("ü", "ue", $groupName);
|
||||
$groupName = str_replace("ß", "ss", $groupName);
|
||||
}
|
||||
|
||||
# Filter unwanted characters
|
||||
$nameFilter = $this->config->getAppValue($this->appName, 'cas_import_map_groups_letter_filter');
|
||||
|
||||
if (strlen($nameFilter) > 0) {
|
||||
|
||||
$groupName = preg_replace("/[^" . $nameFilter . "]+/", "", $groupName);
|
||||
}
|
||||
|
||||
# Filter length to max 64 chars
|
||||
$groupName = substr($groupName, 0, 64);*/
|
||||
}
|
||||
else {
|
||||
|
||||
$groupCnArray = explode(",", $groupCn);
|
||||
$groupName = substr($groupCnArray[0], 3, strlen($groupCnArray[0]));
|
||||
}
|
||||
|
||||
if (strlen($groupName) > 0) {
|
||||
|
||||
$groupsArray[] = $groupName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Fill the users array only if we have an employeeId and addUser is true
|
||||
if (isset($employeeID) && $addUser) {
|
||||
|
||||
$this->merger->mergeUsers($users, ['uid' => $employeeID, 'displayName' => $displayName, 'email' => $mail, 'quota' => $quota, 'groups' => $groupsArray, 'enable' => $enable, 'dn' => $dn], $mergeAttribute, $preferEnabledAccountsOverDisabled, $primaryAccountDnStartswWith);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->logger->info("Users have been retrieved.");
|
||||
|
||||
return $users;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* List ldap entries in the base dn
|
||||
*
|
||||
* @param string $object_dn
|
||||
* @param $filter
|
||||
* @param array $keepAtributes
|
||||
* @param $pageSize
|
||||
* @return array
|
||||
*/
|
||||
protected function getLdapList($object_dn, $filter, $keepAtributes, $pageSize)
|
||||
{
|
||||
|
||||
$cookie = '';
|
||||
$members = [];
|
||||
|
||||
do {
|
||||
|
||||
// Query Group members
|
||||
ldap_control_paged_result($this->ldapConnection, $pageSize, false, $cookie);
|
||||
|
||||
$results = ldap_search($this->ldapConnection, $object_dn, $filter, $keepAtributes/*, array("member;range=$range_start-$range_end")*/) or die('Error searching LDAP: ' . ldap_error($this->ldapConnection));
|
||||
$members[] = ldap_get_entries($this->ldapConnection, $results);
|
||||
|
||||
ldap_control_paged_result_response($this->ldapConnection, $results, $cookie);
|
||||
|
||||
} while ($cookie !== null && $cookie != '');
|
||||
|
||||
// Return sorted member list
|
||||
sort($members);
|
||||
|
||||
return $members;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $user_dn
|
||||
* @param bool $keep
|
||||
* @return array Attribute list
|
||||
*/
|
||||
protected function getLdapAttributes($user_dn, $keep = false)
|
||||
{
|
||||
|
||||
if (!isset($this->ldapConnection)) die('Error, no LDAP connection established');
|
||||
if (empty($user_dn)) die('Error, no LDAP user specified');
|
||||
|
||||
// Disable pagination setting, not needed for individual attribute queries
|
||||
ldap_control_paged_result($this->ldapConnection, 1);
|
||||
|
||||
// Query user attributes
|
||||
$results = (($keep) ? ldap_search($this->ldapConnection, $user_dn, 'cn=*', $keep) : ldap_search($this->ldapConnection, $user_dn, 'cn=*'))
|
||||
or die('Error searching LDAP: ' . ldap_error($this->ldapConnection));
|
||||
|
||||
$attributes = ldap_get_entries($this->ldapConnection, $results);
|
||||
|
||||
$this->logger->debug("AD attributes successfully retrieved.");
|
||||
|
||||
// Return attributes list
|
||||
if (isset($attributes[0])) return $attributes[0];
|
||||
else return array();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Connect ldap
|
||||
*
|
||||
* @return bool|resource
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function ldapConnect()
|
||||
{
|
||||
try {
|
||||
|
||||
$host = $this->config->getAppValue($this->appName, 'cas_import_ad_host');
|
||||
|
||||
$this->ldapConnection = ldap_connect($this->config->getAppValue($this->appName, 'cas_import_ad_protocol') . $host . ":" . $this->config->getAppValue($this->appName, 'cas_import_ad_port')) or die("Could not connect to " . $host);
|
||||
|
||||
ldap_set_option($this->ldapConnection, LDAP_OPT_PROTOCOL_VERSION, 3);
|
||||
ldap_set_option($this->ldapConnection, LDAP_OPT_REFERRALS, 0);
|
||||
ldap_set_option($this->ldapConnection, LDAP_OPT_NETWORK_TIMEOUT, 10);
|
||||
|
||||
$this->logger->info("AD connected successfully.");
|
||||
|
||||
return $this->ldapConnection;
|
||||
} catch (\Exception $e) {
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind ldap
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function ldapBind()
|
||||
{
|
||||
|
||||
try {
|
||||
|
||||
if ($this->ldapConnection) {
|
||||
|
||||
$ldapIsBound = ldap_bind($this->ldapConnection, $this->config->getAppValue($this->appName, 'cas_import_ad_user') . "@" . $this->config->getAppValue($this->appName, 'cas_import_ad_domain'), $this->config->getAppValue($this->appName, 'cas_import_ad_password'));
|
||||
|
||||
if (!$ldapIsBound) {
|
||||
|
||||
throw new \Exception("LDAP bind failed. Error: " . ldap_error($this->ldapConnection));
|
||||
} else {
|
||||
|
||||
$this->logger->info("AD bound successfully.");
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unbind ldap
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function ldapUnbind()
|
||||
{
|
||||
|
||||
try {
|
||||
|
||||
ldap_unbind($this->ldapConnection);
|
||||
|
||||
$this->logger->info("AD unbound successfully.");
|
||||
} catch (\Exception $e) {
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close ldap connection
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function ldapClose()
|
||||
{
|
||||
try {
|
||||
|
||||
ldap_close($this->ldapConnection);
|
||||
|
||||
$this->logger->info("AD connection closed successfully.");
|
||||
} catch (\Exception $e) {
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $exportData
|
||||
*/
|
||||
public function exportAsCsv(array $exportData)
|
||||
{
|
||||
|
||||
$this->logger->info("Exporting users to .csv …");
|
||||
|
||||
$fp = fopen('accounts.csv', 'wa+');
|
||||
|
||||
fputcsv($fp, ["UID", "displayName", "email", "quota", "groups", "enabled"]);
|
||||
|
||||
foreach ($exportData as $fields) {
|
||||
|
||||
for ($i = 0; $i < count($fields); $i++) {
|
||||
|
||||
if (is_array($fields[$i])) {
|
||||
|
||||
$fields[$i] = $this->multiImplode($fields[$i], " ");
|
||||
}
|
||||
}
|
||||
|
||||
fputcsv($fp, $fields);
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
|
||||
$this->logger->info("CSV export finished.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $exportData
|
||||
*/
|
||||
public function exportAsText(array $exportData)
|
||||
{
|
||||
|
||||
$this->logger->info("Exporting users to .txt …");
|
||||
|
||||
file_put_contents('accounts.txt', serialize($exportData));
|
||||
|
||||
$this->logger->info("TXT export finished.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $array
|
||||
* @param string $glue
|
||||
* @return bool|string
|
||||
*/
|
||||
private function multiImplode($array, $glue)
|
||||
{
|
||||
$ret = '';
|
||||
|
||||
foreach ($array as $item) {
|
||||
if (is_array($item)) {
|
||||
$ret .= $this->multiImplode($item, $glue) . $glue;
|
||||
} else {
|
||||
$ret .= $item . $glue;
|
||||
}
|
||||
}
|
||||
|
||||
$ret = substr($ret, 0, 0 - strlen($glue));
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace OCA\UserCAS\Service\Import;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Interface ImporterInterface
|
||||
* @package OCA\UserCAS\Service\Import
|
||||
*
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
* @copyright Felix Rupp
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
interface ImporterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param LoggerInterface $logger
|
||||
*/
|
||||
public function init(LoggerInterface $logger);
|
||||
|
||||
public function close();
|
||||
|
||||
public function getUsers();
|
||||
|
||||
/**
|
||||
* @param array $userData
|
||||
*/
|
||||
public function exportAsCsv(array $userData);
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
<?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\Service;
|
||||
|
||||
use \OCP\IConfig;
|
||||
use \OCP\ILogger;
|
||||
|
||||
/**
|
||||
* Class LoggingService
|
||||
*
|
||||
* @package OCA\UserCAS\Service
|
||||
*
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
* @copyright Felix Rupp <kontakt@felixrupp.com>
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
class LoggingService
|
||||
{
|
||||
|
||||
/**
|
||||
* @since 1.6.1
|
||||
*/
|
||||
const DEBUG = 0;
|
||||
/**
|
||||
* @since 1.6.1
|
||||
*/
|
||||
const INFO = 1;
|
||||
/**
|
||||
* @since 1.6.1
|
||||
*/
|
||||
const WARN = 2;
|
||||
/**
|
||||
* @since 1.6.1
|
||||
*/
|
||||
const ERROR = 3;
|
||||
/**
|
||||
* @since 1.6.1
|
||||
*/
|
||||
const FATAL = 4;
|
||||
|
||||
/**
|
||||
* @var string $appName
|
||||
*/
|
||||
private $appName;
|
||||
|
||||
/**
|
||||
* @var \OCP\IConfig $appConfig
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @var \OCP\ILogger $logger
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* LoggingService constructor.
|
||||
* @param string $appName
|
||||
* @param \OCP\IConfig $config
|
||||
* @param \OCP\ILogger $logger
|
||||
*/
|
||||
public function __construct($appName, IConfig $config, ILogger $logger)
|
||||
{
|
||||
|
||||
$this->appName = $appName;
|
||||
$this->config = $config;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $level
|
||||
* @param string $message
|
||||
*/
|
||||
public function write($level, $message)
|
||||
{
|
||||
|
||||
$this->logger->log($level, $message, ['app' => $this->appName]);
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace OCA\UserCAS\Service\Merge;
|
||||
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Class AdUserMerger
|
||||
* @package OCA\UserCAS\Service\Merge
|
||||
*
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
* @copyright Felix Rupp
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class AdUserMerger implements MergerInterface
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
|
||||
/**
|
||||
* AdUserMerger constructor.
|
||||
* @param LoggerInterface $logger
|
||||
*/
|
||||
public function __construct(LoggerInterface $logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge users method
|
||||
*
|
||||
* @param array $userStack
|
||||
* @param array $userToMerge
|
||||
* @param bool $merge
|
||||
* @param bool $preferEnabledAccountsOverDisabled
|
||||
* @param string $primaryAccountDnStartswWith
|
||||
*/
|
||||
public function mergeUsers(array &$userStack, array $userToMerge, $merge, $preferEnabledAccountsOverDisabled, $primaryAccountDnStartswWith)
|
||||
{
|
||||
# User already in stack
|
||||
if ($merge && isset($userStack[$userToMerge["uid"]])) {
|
||||
|
||||
$this->logger->debug("User " . $userToMerge["uid"] . " has to be merged …");
|
||||
|
||||
// Check if accounts are enabled or disabled
|
||||
// if both disabled, first account stays
|
||||
// if one is enabled, use this account
|
||||
// if both enabled, use information of $primaryAccountDnStartswWith
|
||||
|
||||
if ($preferEnabledAccountsOverDisabled && $userStack[$userToMerge["uid"]]['enable'] == 0 && $userToMerge['enable'] == 1) { # First disabled, second enabled and $preferEnabledAccountsOverDisabled is true
|
||||
|
||||
$this->logger->info("User " . $userToMerge["uid"] . " is merged because first account was disabled.");
|
||||
|
||||
$userStack[$userToMerge["uid"]] = $userToMerge;
|
||||
}
|
||||
elseif(!$preferEnabledAccountsOverDisabled && $userStack[$userToMerge["uid"]]['enable'] == 0 && $userToMerge['enable'] == 1) { # First disabled, second enabled and $preferEnabledAccountsOverDisabled is false
|
||||
|
||||
$this->logger->info("User " . $userToMerge["uid"] . " has not been merged, second enabled account was not preferred, because of preferEnabledAccountsOverDisabled option.");
|
||||
}
|
||||
elseif ($userStack[$userToMerge["uid"]]['enable'] == 1 && $userToMerge['enable'] == 1) { # Both enabled
|
||||
|
||||
if (strpos(strtolower($userToMerge['dn']), strtolower($primaryAccountDnStartswWith) !== FALSE)) {
|
||||
|
||||
$this->logger->info("User " . $userToMerge["uid"] . " is merged because second account is primary, based on merge filter.");
|
||||
|
||||
$userStack[$userToMerge["uid"]] = $userToMerge;
|
||||
}
|
||||
else {
|
||||
|
||||
$this->logger->info("User " . $userToMerge["uid"] . " has not been merged, second account was not primary, based on merge filter.");
|
||||
}
|
||||
} else {
|
||||
|
||||
$this->logger->info("User " . $userToMerge["uid"] . " has not been merged, second account was disabled, first account was enabled.");
|
||||
}
|
||||
} else { # User not in stack
|
||||
|
||||
$userStack[$userToMerge["uid"]] = $userToMerge;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace OCA\UserCAS\Service\Merge;
|
||||
|
||||
|
||||
/**
|
||||
* Interface MergerInterface
|
||||
* @package OCA\UserCAS\Service\Merge
|
||||
*
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
* @copyright Felix Rupp
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
interface MergerInterface
|
||||
{
|
||||
|
||||
public function mergeUsers(array &$userStack, array $userToMerge, $merge, $preferEnabledAccountsOverDisabled, $primaryAccountDnStartswWith);
|
||||
}
|
@ -0,0 +1,680 @@
|
||||
<?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\Service;
|
||||
|
||||
use OCA\UserCAS\Exception\PhpCas\PhpUserCasLibraryNotFoundException;
|
||||
use OCA\UserCas\Service\LoggingService;
|
||||
use OCA\UserCAS\User\UserCasBackendInterface;
|
||||
use \OCP\IConfig;
|
||||
use \OCP\IUserManager;
|
||||
use \OCP\IGroupManager;
|
||||
use \OCP\IUserSession;
|
||||
|
||||
use OCA\UserCAS\User\Backend;
|
||||
|
||||
/**
|
||||
* Class UserService
|
||||
*
|
||||
* @package OCA\UserCAS\Service
|
||||
*
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
* @copyright Felix Rupp <kontakt@felixrupp.com>
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
class UserService
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string $appName
|
||||
*/
|
||||
private $appName;
|
||||
|
||||
/**
|
||||
* @var \OCP\IConfig $appConfig
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @var \OCP\IUserSession $userSession
|
||||
*/
|
||||
private $userSession;
|
||||
|
||||
/**
|
||||
* @var \OCP\IUserManager $userManager
|
||||
*/
|
||||
private $userManager;
|
||||
|
||||
/**
|
||||
* @var \OCP\IGroupManager
|
||||
*/
|
||||
private $groupManager;
|
||||
|
||||
/**
|
||||
* @var AppService $appService
|
||||
*/
|
||||
private $appService;
|
||||
|
||||
/**
|
||||
* @var LoggingService $loggingService
|
||||
*/
|
||||
private $loggingService;
|
||||
|
||||
|
||||
/**
|
||||
* UserService constructor.
|
||||
*
|
||||
* @param $appName
|
||||
* @param IConfig $config
|
||||
* @param IUserManager $userManager
|
||||
* @param IUserSession $userSession
|
||||
* @param IGroupManager $groupManager
|
||||
* @param AppService $appService
|
||||
* @param LoggingService $loggingService
|
||||
*/
|
||||
public function __construct($appName, IConfig $config, IUserManager $userManager, IUserSession $userSession, IGroupManager $groupManager, AppService $appService, LoggingService $loggingService)
|
||||
{
|
||||
|
||||
$this->appName = $appName;
|
||||
$this->config = $config;
|
||||
$this->userManager = $userManager;
|
||||
$this->userSession = $userSession;
|
||||
$this->groupManager = $groupManager;
|
||||
$this->appService = $appService;
|
||||
$this->loggingService = $loggingService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Login hook method.
|
||||
*
|
||||
* @param $request
|
||||
* @param string $uid
|
||||
* @param string $password
|
||||
* @return bool
|
||||
*/
|
||||
public function login($request, $uid, $password = '')
|
||||
{
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, 'phpCAS login function step 1.');
|
||||
#\OCP\Util::writeLog('cas', 'phpCAS login function step 1.', \OCA\UserCas\Service\LoggingService::DEBUG);
|
||||
|
||||
try {
|
||||
|
||||
if (!boolval($this->config->getAppValue($this->appName, 'cas_autocreate')) && !$this->userExists($uid)) {
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, 'phpCas autocreate disabled, and OC User does not exist, phpCas based login not possible. Bye.');
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
# Check if user may be authorized based on groups or not
|
||||
$cas_access_allow_groups = $this->config->getAppValue($this->appName, 'cas_access_allow_groups');
|
||||
if (is_string($cas_access_allow_groups) && strlen($cas_access_allow_groups) > 0) {
|
||||
|
||||
$cas_access_allow_groups = explode(',', $cas_access_allow_groups);
|
||||
$casAttributes = \phpCAS::getAttributes();
|
||||
$casGroups = array();
|
||||
$isAuthorized = FALSE;
|
||||
|
||||
$groupMapping = $this->config->getAppValue($this->appName, 'cas_group_mapping');
|
||||
|
||||
# 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);
|
||||
}
|
||||
|
||||
# Test for mapped attribute from settings
|
||||
if (array_key_exists($groupMapping, $casAttributes)) {
|
||||
|
||||
$casGroups = (array)$casAttributes[$groupMapping];
|
||||
} # Test for standard 'groups' attribute
|
||||
else if (array_key_exists('groups', $casAttributes)) {
|
||||
|
||||
if($this->config->getAppValue($this->appName, 'cas_groups_json_decode')) {
|
||||
|
||||
$casGroups = json_decode($casAttributes['groups']);
|
||||
}
|
||||
else {
|
||||
|
||||
$casGroups = (array)$casAttributes['groups'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($casGroups as $casGroup) {
|
||||
|
||||
if (in_array($casGroup, $cas_access_allow_groups)) {
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, 'phpCas CAS users login has been authorized with group: ' . $casGroup);
|
||||
|
||||
$isAuthorized = TRUE;
|
||||
} else {
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, 'phpCas CAS users login has not been authorized with group: ' . $casGroup . ', because the group was not in allowedGroups: ' . implode(", ", $cas_access_allow_groups));
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->groupManager->isInGroup($uid, 'admin')) {
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, 'phpCas CAS users login has been authorized with group: admin');
|
||||
|
||||
$isAuthorized = TRUE;
|
||||
}
|
||||
|
||||
if (!$isAuthorized) {
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, 'phpCas CAS user is not authorized to log into ownCloud. Bye.');
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
$loginSuccessful = $this->userSession->login($uid, $password);
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, 'phpCAS login function result: ' . $loginSuccessful);
|
||||
#\OCP\Util::writeLog('cas', 'phpCAS login function result: ' . $loginSuccessful, \OCA\UserCas\Service\LoggingService::DEBUG);
|
||||
|
||||
if ($loginSuccessful) {
|
||||
|
||||
return $this->userSession->createSessionToken($request, $this->userSession->getUser()->getUID(), $uid, NULL);
|
||||
}
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, 'phpCAS login function not successful.');
|
||||
#\OCP\Util::writeLog('cas', 'phpCAS login function not successful.', \OCA\UserCas\Service\LoggingService::DEBUG);
|
||||
|
||||
return FALSE;
|
||||
} catch (\OC\User\LoginException $e) {
|
||||
|
||||
$this->loggingService->write(LoggingService::ERROR, 'Owncloud could not log in the user with UID: ' . $uid . '. Exception thrown with code: ' . $e->getCode() . ' and message: ' . $e->getMessage() . '.');
|
||||
#\OCP\Util::writeLog('cas', 'Owncloud could not log in the user with UID: ' . $uid . '. Exception thrown with code: ' . $e->getCode() . ' and message: ' . $e->getMessage() . '.', \OCA\UserCas\Service\LoggingService::ERROR);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Logout function
|
||||
*
|
||||
* @return bool|void
|
||||
*/
|
||||
public function logout()
|
||||
{
|
||||
|
||||
return $this->userSession->logout();
|
||||
}
|
||||
|
||||
/**
|
||||
* IsLoggedIn method.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isLoggedIn()
|
||||
{
|
||||
|
||||
return $this->userSession->isLoggedIn();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $userId
|
||||
* @param UserCasBackendInterface $backend
|
||||
* @return boolean|\OCP\IUser the created user or false
|
||||
*/
|
||||
public function create($userId, UserCasBackendInterface $backend)
|
||||
{
|
||||
|
||||
$randomPassword = $this->getNewPassword();
|
||||
|
||||
if ($backend->implementsActions(\OC\User\Backend::CREATE_USER)) {
|
||||
|
||||
return $this->userManager->createUserFromBackend($userId, $randomPassword, $backend);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $userId
|
||||
* @return mixed
|
||||
*/
|
||||
public function userExists($userId)
|
||||
{
|
||||
|
||||
return $this->userManager->userExists($userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUserId()
|
||||
{
|
||||
$uid = \phpCAS::getUser();
|
||||
|
||||
$casAttributes = \phpCAS::getAttributes();
|
||||
|
||||
if($this->config->getAppValue($this->appName, 'cas_userid_mapping') && strlen($this->config->getAppValue($this->appName, 'cas_userid_mapping')) > 0) {
|
||||
|
||||
$userIdAttribute = $this->config->getAppValue($this->appName, 'cas_userid_mapping');
|
||||
if(isset($casAttributes[$userIdAttribute])) {
|
||||
|
||||
$uid = $casAttributes[$userIdAttribute];
|
||||
}
|
||||
}
|
||||
|
||||
return $uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the user
|
||||
*
|
||||
* @param \OCP\IUser $user
|
||||
* @param array $attributes
|
||||
*/
|
||||
public function updateUser($user, $attributes)
|
||||
{
|
||||
|
||||
$userId = $user->getUID();
|
||||
|
||||
/*$attributesString = '';
|
||||
foreach ($attributes as $key => $attribute) {
|
||||
|
||||
$attributesString .= $key . ': ' . $attribute . '; ';
|
||||
}*/
|
||||
|
||||
$newGroupQuota = NULL;
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, 'Updating data of the user: ' . $userId);
|
||||
#\OCP\Util::writeLog('cas', 'Updating data of the user: ' . $userId, \OCA\UserCas\Service\LoggingService::DEBUG);
|
||||
#\OCP\Util::writeLog('cas', 'Attributes: ' . $attributesString, \OCA\UserCas\Service\LoggingService::DEBUG);
|
||||
|
||||
if (isset($attributes['cas_email']) && is_object($user)) {
|
||||
|
||||
$this->updateMail($user, $attributes['cas_email']);
|
||||
}
|
||||
if (isset($attributes['cas_name']) && is_object($user)) {
|
||||
|
||||
$this->updateName($user, $attributes['cas_name']);
|
||||
}
|
||||
if (isset($attributes['cas_groups']) && is_object($user)) {
|
||||
|
||||
$this->updateGroups($user, $attributes['cas_groups'], $this->config->getAppValue($this->appName, 'cas_protected_groups'));
|
||||
}
|
||||
if (isset($attributes['cas_group_quota']) && is_object($user)) {
|
||||
|
||||
$newGroupQuota = $this->updateGroupQuota($user, $attributes['cas_group_quota']);
|
||||
}
|
||||
if (isset($attributes['cas_quota']) && is_object($user)) {
|
||||
|
||||
$this->updateQuota($user, $newGroupQuota, $attributes['cas_quota']);
|
||||
}
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, 'Updating data finished.');
|
||||
#\OCP\Util::writeLog('cas', 'Updating data finished.', \OCA\UserCas\Service\LoggingService::DEBUG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the eMail address
|
||||
*
|
||||
* @param \OCP\IUser $user
|
||||
* @param string|array $email
|
||||
*/
|
||||
private function updateMail($user, $email)
|
||||
{
|
||||
|
||||
if (is_array($email)) {
|
||||
|
||||
$email = $email[0];
|
||||
}
|
||||
|
||||
if ($email !== $user->getEMailAddress()) {
|
||||
|
||||
$user->setEMailAddress($email);
|
||||
$this->loggingService->write(LoggingService::DEBUG, 'Set email "' . $email . '" for the user: ' . $user->getUID());
|
||||
#\OCP\Util::writeLog('cas', 'Set email "' . $email . '" for the user: ' . $user->getUID(), \OCA\UserCas\Service\LoggingService::DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the display name
|
||||
*
|
||||
* @param \OCP\IUser $user
|
||||
* @param string| $name
|
||||
*/
|
||||
private function updateName($user, $name)
|
||||
{
|
||||
|
||||
if (is_array($name)) {
|
||||
|
||||
$name = $name[0];
|
||||
}
|
||||
|
||||
if ($name !== $user->getDisplayName() && strlen($name) > 0) {
|
||||
|
||||
$user->setDisplayName($name);
|
||||
$this->loggingService->write(LoggingService::DEBUG, 'Set Name: ' . $name . ' for the user: ' . $user->getUID());
|
||||
#\OCP\Util::writeLog('cas', 'Set Name: ' . $name . ' for the user: ' . $user->getUID(), \OCA\UserCas\Service\LoggingService::DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of groups and will try to add the group to OC and then add the user to the groups.
|
||||
*
|
||||
* @param \OCP\IUser $user
|
||||
* @param string|array $groups
|
||||
* @param string|array $protectedGroups
|
||||
* @param bool $justCreated
|
||||
*/
|
||||
public function updateGroups($user, $groups, $protectedGroups = '', $justCreated = false)
|
||||
{
|
||||
|
||||
if (is_string($groups)) $groups = explode(",", $groups);
|
||||
if (is_string($protectedGroups)) $protectedGroups = explode(",", $protectedGroups);
|
||||
|
||||
$uid = $user->getUID();
|
||||
|
||||
# Add default user group to groups and protectedGroups
|
||||
if($this->config->getAppValue($this->appName, 'cas_groups_create_default_for_user')) {
|
||||
|
||||
$userGroupPrefix = $this->config->getAppValue($this->appName, 'cas_groups_create_default_for_user_prefix', '');
|
||||
|
||||
if(strpos($userGroupPrefix, '/') !== strlen($userGroupPrefix)) {
|
||||
|
||||
$userGroupPrefix .= '/';
|
||||
}
|
||||
|
||||
$userGroupName = $userGroupPrefix.$uid;
|
||||
|
||||
$groups[] = $userGroupName;
|
||||
$protectedGroups[] = $userGroupName;
|
||||
}
|
||||
|
||||
if (!$justCreated) {
|
||||
|
||||
$oldGroups = $this->groupManager->getUserGroups($user);
|
||||
|
||||
foreach ($oldGroups as $group) {
|
||||
|
||||
if ($group instanceof \OCP\IGroup) {
|
||||
|
||||
$groupId = $group->getGID();
|
||||
|
||||
if (!in_array($groupId, $protectedGroups) && !in_array($groupId, $groups)) {
|
||||
|
||||
$group->removeUser($user);
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, "Removed '" . $uid . "' from the group '" . $groupId . "'");
|
||||
#\OCP\Util::writeLog('cas', 'Removed "' . $uid . '" from the group "' . $groupId . '"', \OCA\UserCas\Service\LoggingService::DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($groups as $group) {
|
||||
|
||||
$groupObject = NULL;
|
||||
|
||||
# Replace umlauts
|
||||
if (boolval($this->config->getAppValue($this->appName, 'cas_groups_letter_umlauts'))) {
|
||||
|
||||
$group = str_replace("Ä", "Ae", $group);
|
||||
$group = str_replace("Ö", "Oe", $group);
|
||||
$group = str_replace("Ü", "Ue", $group);
|
||||
$group = str_replace("ä", "ae", $group);
|
||||
$group = str_replace("ö", "oe", $group);
|
||||
$group = str_replace("ü", "ue", $group);
|
||||
$group = str_replace("ß", "ss", $group);
|
||||
}
|
||||
|
||||
# Filter unwanted characters
|
||||
$nameFilter = $this->config->getAppValue($this->appName, 'cas_groups_letter_filter');
|
||||
|
||||
if (strlen($nameFilter) > 0) {
|
||||
|
||||
$group = preg_replace("/[^" . $nameFilter . "]+/", "", $group);
|
||||
} else { # Use default filter
|
||||
|
||||
$group = preg_replace("/[^a-zA-Z0-9\.\-_ @\/]+/", "", $group);
|
||||
}
|
||||
|
||||
# Filter length to max 64 chars
|
||||
if (strlen($group) > 64) {
|
||||
|
||||
$group = substr($group, 0, 63) . "…";
|
||||
}
|
||||
|
||||
if (!$this->groupManager->isInGroup($uid, $group)) {
|
||||
|
||||
if (!$this->groupManager->groupExists($group)) {
|
||||
|
||||
$groupObject = $this->groupManager->createGroup($group);
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, 'New group created: ' . $group);
|
||||
#\OCP\Util::writeLog('cas', 'New group created: ' . $group, \OCA\UserCas\Service\LoggingService::DEBUG);
|
||||
} else {
|
||||
|
||||
$groupObject = $this->groupManager->get($group);
|
||||
}
|
||||
|
||||
$groupObject->addUser($user);
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, "Added '" . $uid . "' to the group '" . $group . "'");
|
||||
#\OCP\Util::writeLog('cas', 'Added "' . $uid . '" to the group "' . $group . '"', \OCA\UserCas\Service\LoggingService::DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param \OCP\IUser $user
|
||||
* @param int|boolean $newGroupQuota
|
||||
* @param string $quota
|
||||
*/
|
||||
public function updateQuota($user, $newGroupQuota, $quota = 'default')
|
||||
{
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCas new UserQuota contents: ' . $quota . ' | New GroupQuota was: ' . $newGroupQuota);
|
||||
|
||||
$defaultQuota = $this->config->getAppValue('files', 'default_quota');
|
||||
|
||||
if ($defaultQuota === '') {
|
||||
|
||||
$defaultQuota = 'none';
|
||||
}
|
||||
|
||||
$uid = $user->getUID();
|
||||
|
||||
if ($quota === 'none') {
|
||||
|
||||
$newQuota = PHP_INT_MAX;
|
||||
} elseif ($quota === 'default') {
|
||||
|
||||
$newQuota = \OCP\Util::computerFileSize($defaultQuota);
|
||||
} else {
|
||||
|
||||
$newQuota = \OCP\Util::computerFileSize($quota);
|
||||
}
|
||||
|
||||
$usersOldQuota = $user->getQuota();
|
||||
|
||||
if ($usersOldQuota === 'none') {
|
||||
|
||||
$usersOldQuota = PHP_INT_MAX;
|
||||
} elseif ($usersOldQuota === 'default') {
|
||||
|
||||
$usersOldQuota = \OCP\Util::computerFileSize($defaultQuota);
|
||||
} else {
|
||||
|
||||
$usersOldQuota = \OCP\Util::computerFileSize($usersOldQuota);
|
||||
}
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, "Default System Quota is: '" . $defaultQuota . "'");
|
||||
$this->loggingService->write(LoggingService::DEBUG, "User '" . $uid . "' old computerized Quota is: '" . $usersOldQuota . "'");
|
||||
$this->loggingService->write(LoggingService::DEBUG, "User '" . $uid . "' new computerized User Quota would be: '" . $newQuota . "'");
|
||||
|
||||
if ($usersOldQuota < $newQuota || ($usersOldQuota > $newQuota && $newGroupQuota != NULL)) {
|
||||
|
||||
$user->setQuota($newQuota);
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, "User '" . $uid . "' has new Quota: '" . $newQuota . "'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \OCP\IUser $user
|
||||
* @param array $groupQuotas
|
||||
* @return int New Quota
|
||||
*/
|
||||
private function updateGroupQuota($user, $groupQuotas)
|
||||
{
|
||||
|
||||
$defaultQuota = $this->config->getAppValue('files', 'default_quota');
|
||||
|
||||
if ($defaultQuota === '') {
|
||||
|
||||
$defaultQuota = 'none';
|
||||
}
|
||||
|
||||
$uid = $user->getUID();
|
||||
$collectedQuotas = array();
|
||||
|
||||
foreach ($groupQuotas as $groupName => $groupQuota) {
|
||||
|
||||
if ($this->groupManager->isInGroup($uid, $groupName)) {
|
||||
|
||||
if ($groupQuota === 'none') {
|
||||
|
||||
$collectedQuotas[PHP_INT_MAX] = $groupQuota;
|
||||
} elseif ($groupQuota === 'default') {
|
||||
|
||||
$defaultQuotaFilesize = \OCP\Util::computerFileSize($defaultQuota);
|
||||
|
||||
$collectedQuotas[$defaultQuotaFilesize] = $groupQuota;
|
||||
} else {
|
||||
|
||||
$groupQuotaComputerFilesize = \OCP\Util::computerFileSize($groupQuota);
|
||||
$collectedQuotas[$groupQuotaComputerFilesize] = $groupQuota;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Sort descending by key
|
||||
krsort($collectedQuotas);
|
||||
|
||||
$newQuota = \OCP\Util::computerFileSize(array_shift($collectedQuotas));
|
||||
|
||||
$usersOldQuota = $user->getQuota();
|
||||
|
||||
if ($usersOldQuota === 'none') {
|
||||
|
||||
$usersOldQuota = PHP_INT_MAX;
|
||||
} elseif ($usersOldQuota === 'default') {
|
||||
|
||||
$usersOldQuota = \OCP\Util::computerFileSize($defaultQuota);
|
||||
} else {
|
||||
|
||||
$usersOldQuota = \OCP\Util::computerFileSize($usersOldQuota);
|
||||
}
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, "Default System Quota is: '" . $defaultQuota . "'");
|
||||
$this->loggingService->write(LoggingService::DEBUG, "User '" . $uid . "' old computerized Quota is: '" . $usersOldQuota . "'");
|
||||
$this->loggingService->write(LoggingService::DEBUG, "User '" . $uid . "' new computerized Group Quota would be: '" . $newQuota . "'");
|
||||
|
||||
if ($usersOldQuota < $newQuota) {
|
||||
|
||||
$user->setQuota($newQuota);
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, "User '" . $uid . "' has new Quota: '" . $newQuota . "'");
|
||||
|
||||
return $newQuota;
|
||||
}
|
||||
|
||||
return $usersOldQuota;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register User Backend.
|
||||
*
|
||||
* @param UserCasBackendInterface $backend
|
||||
*/
|
||||
public function registerBackend(UserCasBackendInterface $backend)
|
||||
{
|
||||
|
||||
$this->userManager->registerBackend($backend);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the backend of the user on ownCloud
|
||||
*
|
||||
* @param \OCP\IUser $user
|
||||
* @return bool|int|\OC_DB_StatementWrapper
|
||||
*
|
||||
* @deprecated
|
||||
**/
|
||||
public function updateBackend(\OCP\IUser $user)
|
||||
{
|
||||
|
||||
try {
|
||||
|
||||
$uid = $user->getUID();
|
||||
$result = false;
|
||||
|
||||
if ($this->appService->isNotNextcloud()) {
|
||||
|
||||
if (!is_null($user) && ($user->getBackendClassName() === 'OC\User\Database' || $user->getBackendClassName() === "Database")) {
|
||||
|
||||
$query = \OC_DB::prepare('UPDATE `*PREFIX*accounts` SET `backend` = ? WHERE LOWER(`user_id`) = LOWER(?)');
|
||||
$result = $query->execute([get_class($this->getBackend()), $uid]);
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCAS user existing in database backend, move to CAS-Backend with result: ' . $result);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
} catch (\Exception $e) {
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random PW with special char symbol characters
|
||||
*
|
||||
* @return string New Password
|
||||
*/
|
||||
protected function getNewPassword()
|
||||
{
|
||||
|
||||
$newPasswordCharsLower = \OC::$server->getSecureRandom()->generate(8, \OCP\Security\ISecureRandom::CHAR_LOWER);
|
||||
$newPasswordCharsUpper = \OC::$server->getSecureRandom()->generate(4, \OCP\Security\ISecureRandom::CHAR_UPPER);
|
||||
$newPasswordNumbers = \OC::$server->getSecureRandom()->generate(4, \OCP\Security\ISecureRandom::CHAR_DIGITS);
|
||||
$newPasswordSymbols = \OC::$server->getSecureRandom()->generate(4, \OCP\Security\ISecureRandom::CHAR_SYMBOLS);
|
||||
|
||||
return str_shuffle($newPasswordCharsLower . $newPasswordCharsUpper . $newPasswordNumbers . $newPasswordSymbols);
|
||||
}
|
||||
}
|
@ -0,0 +1,301 @@
|
||||
<?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\User;
|
||||
|
||||
use OC\User\Database;
|
||||
use OCA\UserCAS\Exception\PhpCas\PhpUserCasLibraryNotFoundException;
|
||||
use OCA\UserCAS\Service\AppService;
|
||||
use OCA\UserCAS\Service\LoggingService;
|
||||
use OCA\UserCAS\Service\UserService;
|
||||
use OCP\IConfig;
|
||||
use OCP\IUserBackend;
|
||||
use OCP\IUserManager;
|
||||
use OCP\User\IProvidesDisplayNameBackend;
|
||||
use OCP\User\IProvidesHomeBackend;
|
||||
use OCP\UserInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Class Backend
|
||||
*
|
||||
* @package OCA\UserCAS\User
|
||||
*
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
* @copyright Felix Rupp <kontakt@felixrupp.com>
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
class Backend extends Database implements UserInterface, IUserBackend, IProvidesHomeBackend, IProvidesDisplayNameBackend, UserCasBackendInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $appName;
|
||||
|
||||
/**
|
||||
* @var IConfig
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var \OCA\UserCAS\Service\LoggingService $loggingService
|
||||
*/
|
||||
protected $loggingService;
|
||||
|
||||
/**
|
||||
* @var \OCA\UserCAS\Service\AppService $appService
|
||||
*/
|
||||
protected $appService;
|
||||
|
||||
/**
|
||||
* @var \OCA\UserCAS\Service\UserService $userService
|
||||
*/
|
||||
protected $userService;
|
||||
|
||||
|
||||
/**
|
||||
* @var \OCP\IUserManager $userManager
|
||||
*/
|
||||
protected $userManager;
|
||||
|
||||
|
||||
/**
|
||||
* Backend constructor.
|
||||
* @param string $appName
|
||||
* @param IConfig $config
|
||||
* @param LoggingService $loggingService
|
||||
* @param AppService $appService
|
||||
* @param IUserManager $userManager
|
||||
* @param UserService $userService
|
||||
*/
|
||||
public function __construct($appName, IConfig $config, LoggingService $loggingService, AppService $appService, IUserManager $userManager, UserService $userService)
|
||||
{
|
||||
|
||||
parent::__construct();
|
||||
$this->appName = $appName;
|
||||
$this->loggingService = $loggingService;
|
||||
$this->appService = $appService;
|
||||
$this->userService = $userService;
|
||||
$this->config = $config;
|
||||
$this->userManager = $userManager;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Backend name to be shown in user management
|
||||
* @return string the name of the backend to be shown
|
||||
*/
|
||||
public function getBackendName()
|
||||
{
|
||||
|
||||
return "CAS";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $uid
|
||||
* @param string $password
|
||||
* @return string|bool The users UID or false
|
||||
*/
|
||||
public function checkPassword($uid, $password)
|
||||
{
|
||||
|
||||
if (!$this->appService->isCasInitialized()) {
|
||||
|
||||
try {
|
||||
|
||||
$this->appService->init();
|
||||
} catch (PhpUserCasLibraryNotFoundException $e) {
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::ERROR, 'Fatal error with code: ' . $e->getCode() . ' and message: ' . $e->getMessage());
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (\phpCAS::isInitialized()) {
|
||||
|
||||
if ($uid === FALSE) {
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::ERROR, 'phpCAS returned no user.');
|
||||
}
|
||||
|
||||
if (\phpCAS::isAuthenticated()) {
|
||||
|
||||
#$casUid = \phpCAS::getUser();
|
||||
$casUid = $this->userService->getUserId();
|
||||
|
||||
$isAuthorized = TRUE;
|
||||
$createUser = TRUE;
|
||||
|
||||
|
||||
# Check if user may be authorized based on groups or not
|
||||
$cas_access_allow_groups = $this->config->getAppValue($this->appName, 'cas_access_allow_groups');
|
||||
if (is_string($cas_access_allow_groups) && strlen($cas_access_allow_groups) > 0) {
|
||||
|
||||
$cas_access_allow_groups = explode(',', $cas_access_allow_groups);
|
||||
$casAttributes = \phpCAS::getAttributes();
|
||||
$casGroups = array();
|
||||
$groupMapping = $this->config->getAppValue($this->appName, 'cas_group_mapping');
|
||||
|
||||
# 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);
|
||||
}
|
||||
|
||||
# Test for mapped attribute from settings
|
||||
if (array_key_exists($groupMapping, $casAttributes)) {
|
||||
|
||||
$casGroups = (array)$casAttributes[$groupMapping];
|
||||
} # Test for standard 'groups' attribute
|
||||
else if (array_key_exists('groups', $casAttributes)) {
|
||||
|
||||
if ($this->config->getAppValue($this->appName, 'cas_groups_json_decode')) {
|
||||
|
||||
$casGroups = json_decode($casAttributes['groups']);
|
||||
} else {
|
||||
|
||||
$casGroups = (array)$casAttributes['groups'];
|
||||
}
|
||||
}
|
||||
|
||||
$isAuthorized = FALSE;
|
||||
|
||||
foreach ($casGroups as $casGroup) {
|
||||
|
||||
if (in_array($casGroup, $cas_access_allow_groups)) {
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, 'phpCas CAS users login has been authorized with group: ' . $casGroup);
|
||||
|
||||
$isAuthorized = TRUE;
|
||||
} else {
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, 'phpCas CAS users login has not been authorized with group: ' . $casGroup . ', because the group was not in allowedGroups: ' . implode(", ", $cas_access_allow_groups));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Autocreate user if needed or create a new account in CAS Backend
|
||||
if (!$this->userManager->userExists($uid) && boolval($this->config->getAppValue($this->appName, 'cas_autocreate'))) {
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCAS creating a new user with UID: ' . $uid);
|
||||
} elseif (!$this->userManager->userExists($uid) && !boolval($this->config->getAppValue($this->appName, 'cas_autocreate'))) {
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCAS no new user has been created.');
|
||||
|
||||
$createUser = FALSE;
|
||||
}
|
||||
|
||||
// Finalize check
|
||||
if ($casUid === $uid && $isAuthorized && $createUser) {
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCAS user password has been checked.');
|
||||
|
||||
return $uid;
|
||||
}
|
||||
}
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCAS user password has been checked, user not logged in.');
|
||||
|
||||
return FALSE;
|
||||
} else {
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::ERROR, 'phpCAS has not been initialized.');
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $uid
|
||||
* @return bool|string
|
||||
*/
|
||||
public function getDisplayName($uid)
|
||||
{
|
||||
|
||||
$displayName = $uid;
|
||||
|
||||
if (!$this->appService->isCasInitialized()) {
|
||||
|
||||
try {
|
||||
|
||||
$this->appService->init();
|
||||
} catch (PhpUserCasLibraryNotFoundException $e) {
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::ERROR, 'Fatal error with code: ' . $e->getCode() . ' and message: ' . $e->getMessage());
|
||||
|
||||
return $displayName;
|
||||
}
|
||||
}
|
||||
|
||||
if (\phpCAS::isInitialized()) {
|
||||
|
||||
if (\phpCAS::isAuthenticated()) {
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
// DisplayName
|
||||
$displayNameMapping = $this->config->getAppValue($this->appName, 'cas_displayName_mapping');
|
||||
|
||||
$displayNameMappingArray = explode("+", $displayNameMapping);
|
||||
|
||||
$displayName = '';
|
||||
|
||||
foreach ($displayNameMappingArray as $displayNameMapping) {
|
||||
|
||||
if (array_key_exists($displayNameMapping, $casAttributes)) {
|
||||
|
||||
$displayName .= $casAttributes[$displayNameMapping] . " ";
|
||||
}
|
||||
}
|
||||
|
||||
$displayName = trim($displayName);
|
||||
|
||||
if ($displayName === '' && array_key_exists('displayName', $casAttributes)) {
|
||||
|
||||
$displayName = $casAttributes['displayName'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $displayName;
|
||||
}
|
||||
}
|
@ -0,0 +1,263 @@
|
||||
<?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\User;
|
||||
|
||||
use OC\User\Database;
|
||||
use OCA\UserCAS\Exception\PhpCas\PhpUserCasLibraryNotFoundException;
|
||||
use OCA\UserCAS\Service\AppService;
|
||||
use OCA\UserCAS\Service\LoggingService;
|
||||
use OCA\UserCAS\Service\UserService;
|
||||
use OCP\IConfig;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserBackend;
|
||||
use OCP\IUserManager;
|
||||
use \OCP\User\Backend\ICheckPasswordBackend;
|
||||
use OCP\UserInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Class Backend
|
||||
*
|
||||
* @package OCA\UserCAS\User
|
||||
*
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
* @copyright Felix Rupp <kontakt@felixrupp.com>
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
class NextBackend extends Database implements UserInterface, IUserBackend, ICheckPasswordBackend, UserCasBackendInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $appName;
|
||||
|
||||
/**
|
||||
* @var IConfig
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var \OCA\UserCAS\Service\LoggingService $loggingService
|
||||
*/
|
||||
protected $loggingService;
|
||||
|
||||
/**
|
||||
* @var \OCA\UserCAS\Service\AppService $appService
|
||||
*/
|
||||
protected $appService;
|
||||
|
||||
/**
|
||||
* @var \OCP\IUserManager;
|
||||
*/
|
||||
protected $userManager;
|
||||
|
||||
/**
|
||||
* @var \OCA\UserCAS\Service\UserService $userService
|
||||
*/
|
||||
protected $userService;
|
||||
|
||||
|
||||
/**
|
||||
* Backend constructor.
|
||||
*
|
||||
* @param string $appName
|
||||
* @param IConfig $config
|
||||
* @param LoggingService $loggingService
|
||||
* @param AppService $appService
|
||||
* @param IUserManager $userManager
|
||||
* @param UserService $userService
|
||||
*/
|
||||
public function __construct($appName, IConfig $config, LoggingService $loggingService, AppService $appService, IUserManager $userManager, UserService $userService)
|
||||
{
|
||||
|
||||
parent::__construct();
|
||||
$this->appName = $appName;
|
||||
$this->loggingService = $loggingService;
|
||||
$this->appService = $appService;
|
||||
$this->config = $config;
|
||||
$this->userManager = $userManager;
|
||||
$this->userService = $userService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Backend name to be shown in user management
|
||||
*
|
||||
* @return string the name of the backend to be shown
|
||||
*/
|
||||
public function getBackendName()
|
||||
{
|
||||
|
||||
return "CAS";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check the password
|
||||
*
|
||||
* @param string $loginName
|
||||
* @param string $password
|
||||
* @return string|bool The users UID or false
|
||||
*/
|
||||
public function checkPassword(string $loginName, string $password)
|
||||
{
|
||||
|
||||
if (!$this->appService->isCasInitialized()) {
|
||||
|
||||
try {
|
||||
|
||||
$this->appService->init();
|
||||
} catch (PhpUserCasLibraryNotFoundException $e) {
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::ERROR, 'Fatal error with code: ' . $e->getCode() . ' and message: ' . $e->getMessage());
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (\phpCAS::isInitialized()) {
|
||||
|
||||
if ($loginName === FALSE) {
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::ERROR, 'phpCAS returned no user.');
|
||||
}
|
||||
|
||||
if (\phpCAS::isAuthenticated()) {
|
||||
|
||||
#$casUid = \phpCAS::getUser();
|
||||
$casUid = $this->userService->getUserId();
|
||||
|
||||
$isAuthorized = TRUE;
|
||||
$createUser = TRUE;
|
||||
|
||||
|
||||
# Check if user may be authorized based on groups or not
|
||||
$cas_access_allow_groups = $this->config->getAppValue($this->appName, 'cas_access_allow_groups');
|
||||
if (is_string($cas_access_allow_groups) && strlen($cas_access_allow_groups) > 0) {
|
||||
|
||||
$cas_access_allow_groups = explode(',', $cas_access_allow_groups);
|
||||
$casAttributes = \phpCAS::getAttributes();
|
||||
$casGroups = array();
|
||||
$groupMapping = $this->config->getAppValue($this->appName, 'cas_group_mapping');
|
||||
|
||||
# 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);
|
||||
}
|
||||
|
||||
# Test for mapped attribute from settings
|
||||
if (array_key_exists($groupMapping, $casAttributes)) {
|
||||
|
||||
$casGroups = (array)$casAttributes[$groupMapping];
|
||||
} # Test for standard 'groups' attribute
|
||||
else if (array_key_exists('groups', $casAttributes)) {
|
||||
|
||||
if ($this->config->getAppValue($this->appName, 'cas_groups_json_decode')) {
|
||||
|
||||
$casGroups = json_decode($casAttributes['groups']);
|
||||
} else {
|
||||
|
||||
$casGroups = (array)$casAttributes['groups'];
|
||||
}
|
||||
}
|
||||
|
||||
$isAuthorized = FALSE;
|
||||
|
||||
foreach ($casGroups as $casGroup) {
|
||||
|
||||
if (in_array($casGroup, $cas_access_allow_groups)) {
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, 'phpCas CAS users login has been authorized with group: ' . $casGroup);
|
||||
|
||||
$isAuthorized = TRUE;
|
||||
} else {
|
||||
|
||||
$this->loggingService->write(LoggingService::DEBUG, 'phpCas CAS users login has not been authorized with group: ' . $casGroup . ', because the group was not in allowedGroups: ' . implode(", ", $cas_access_allow_groups));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Autocreate user if needed or create a new account in CAS Backend
|
||||
if (!$this->userManager->userExists($loginName) && boolval($this->config->getAppValue($this->appName, 'cas_autocreate'))) {
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCAS creating a new user with UID: ' . $loginName);
|
||||
|
||||
try {
|
||||
|
||||
$createUser = $this->userService->create($loginName, $this);
|
||||
|
||||
if (!$createUser instanceof IUser) {
|
||||
|
||||
$createUser = FALSE;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
|
||||
$createUser = FALSE;
|
||||
}
|
||||
} elseif (!$this->userManager->userExists($loginName) && !boolval($this->config->getAppValue($this->appName, 'cas_autocreate'))) {
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCAS no new user has been created.');
|
||||
|
||||
$createUser = FALSE;
|
||||
}
|
||||
|
||||
// Finalize check
|
||||
if ($casUid === $loginName && $isAuthorized && $createUser) {
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::DEBUG, 'phpCAS user password has been checked.');
|
||||
|
||||
return $loginName;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
} else {
|
||||
|
||||
$this->loggingService->write(\OCA\UserCas\Service\LoggingService::ERROR, 'phpCAS has not been initialized.');
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the real UID
|
||||
*
|
||||
* @param string $uid
|
||||
* @return string
|
||||
*
|
||||
* @since 1.8.0
|
||||
*/
|
||||
public function getRealUID(string $uid): string
|
||||
{
|
||||
|
||||
return $uid;
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: felixrupp
|
||||
* Date: 17.09.18
|
||||
* Time: 01:51
|
||||
*/
|
||||
|
||||
namespace OCA\UserCAS\User;
|
||||
|
||||
use OCP\UserInterface;
|
||||
|
||||
/**
|
||||
* Interface UserCasBackendInterface
|
||||
*
|
||||
* @package OCA\UserCAS\User
|
||||
*
|
||||
* @author Felix Rupp <kontakt@felixrupp.com>
|
||||
* @copyright Felix Rupp <kontakt@felixrupp.com>
|
||||
*/
|
||||
interface UserCasBackendInterface extends UserInterface
|
||||
{
|
||||
}
|
Reference in New Issue
Block a user