Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
This commit is contained in:
John Molakvoæ 2021-12-10 09:28:16 +01:00
parent 6ed78c3c02
commit 4510f70ff7
No known key found for this signature in database
GPG key ID: 60C25B8C072916CF
25 changed files with 207 additions and 232 deletions

View file

@ -24,7 +24,7 @@ require_once __DIR__ . '/../3rdparty/vendor/autoload.php';
// If we run in CLI mode do not setup the app as it can fail the OCC execution // If we run in CLI mode do not setup the app as it can fail the OCC execution
// since the URLGenerator isn't accessible. // since the URLGenerator isn't accessible.
$cli = false; $cli = false;
if(OC::$CLI) { if (OC::$CLI) {
$cli = true; $cli = true;
} }
try { try {
@ -70,7 +70,7 @@ $params = [];
// Setting up the one login config may fail, if so, do not catch the requests later. // Setting up the one login config may fail, if so, do not catch the requests later.
$returnScript = false; $returnScript = false;
$type = ''; $type = '';
switch($config->getAppValue('user_saml', 'type')) { switch ($config->getAppValue('user_saml', 'type')) {
case 'saml': case 'saml':
try { try {
$oneLoginSettings = new \OneLogin\Saml2\Settings($samlSettings->getOneLoginSettingsArray(1)); $oneLoginSettings = new \OneLogin\Saml2\Settings($samlSettings->getOneLoginSettingsArray(1));
@ -96,7 +96,7 @@ if ($type === 'environment-variable') {
OC_User::handleApacheAuth(); OC_User::handleApacheAuth();
} }
if($returnScript === true) { if ($returnScript === true) {
return; return;
} }
@ -122,7 +122,7 @@ if ($user !== null) {
// All requests that are not authenticated and match against the "/login" route are // All requests that are not authenticated and match against the "/login" route are
// redirected to the SAML login endpoint // redirected to the SAML login endpoint
if(!$cli && if (!$cli &&
!$userSession->isLoggedIn() && !$userSession->isLoggedIn() &&
\OC::$server->getRequest()->getPathInfo() === '/login' && \OC::$server->getRequest()->getPathInfo() === '/login' &&
$type !== '') { $type !== '') {
@ -145,10 +145,10 @@ if(!$cli &&
// UX (users don't have to reauthenticate) we default to disallow the access via // UX (users don't have to reauthenticate) we default to disallow the access via
// SAML at the moment. // SAML at the moment.
$useSamlForDesktopClients = $config->getAppValue('user_saml', 'general-use_saml_auth_for_desktop', '0'); $useSamlForDesktopClients = $config->getAppValue('user_saml', 'general-use_saml_auth_for_desktop', '0');
if($useSamlForDesktopClients === '1') { if ($useSamlForDesktopClients === '1') {
$currentUrl = substr(explode('?',$request->getRequestUri(), 2)[0], strlen(\OC::$WEBROOT)); $currentUrl = substr(explode('?',$request->getRequestUri(), 2)[0], strlen(\OC::$WEBROOT));
if(substr($currentUrl, 0, 12) === '/remote.php/' || substr($currentUrl, 0, 5) === '/ocs/') { if (substr($currentUrl, 0, 12) === '/remote.php/' || substr($currentUrl, 0, 5) === '/ocs/') {
if(!$userSession->isLoggedIn() && $request->isUserAgent([\OCP\IRequest::USER_AGENT_CLIENT_DESKTOP])) { if (!$userSession->isLoggedIn() && $request->isUserAgent([\OCP\IRequest::USER_AGENT_CLIENT_DESKTOP])) {
$redirectSituation = true; $redirectSituation = true;
if (preg_match('/^.*\/(\d+\.\d+\.\d+).*$/', $request->getHeader('USER_AGENT'), $matches) === 1) { if (preg_match('/^.*\/(\d+\.\d+\.\d+).*$/', $request->getHeader('USER_AGENT'), $matches) === 1) {
@ -173,7 +173,7 @@ if ($redirectSituation === true && $showLoginOptions) {
// ignore exception when PUT is called since getParams cannot parse parameters in that case // ignore exception when PUT is called since getParams cannot parse parameters in that case
} }
$redirectUrl = ''; $redirectUrl = '';
if(isset($params['redirect_url'])) { if (isset($params['redirect_url'])) {
$redirectUrl = $params['redirect_url']; $redirectUrl = $params['redirect_url'];
} }
@ -185,17 +185,16 @@ if ($redirectSituation === true && $showLoginOptions) {
); );
header('Location: '.$targetUrl); header('Location: '.$targetUrl);
exit(); exit();
} }
if($redirectSituation === true) { if ($redirectSituation === true) {
try { try {
$params = $request->getParams(); $params = $request->getParams();
} catch (\LogicException $e) { } catch (\LogicException $e) {
// ignore exception when PUT is called since getParams cannot parse parameters in that case // ignore exception when PUT is called since getParams cannot parse parameters in that case
} }
$originalUrl = ''; $originalUrl = '';
if(isset($params['redirect_url'])) { if (isset($params['redirect_url'])) {
$originalUrl = $urlGenerator->getAbsoluteURL($params['redirect_url']); $originalUrl = $urlGenerator->getAbsoluteURL($params['redirect_url']);
} }

View file

@ -28,7 +28,7 @@ use OCP\AppFramework\IAppContainer;
use OCP\SabrePluginEvent; use OCP\SabrePluginEvent;
class Application extends App { class Application extends App {
public function __construct(array $urlParams = array()) { public function __construct(array $urlParams = []) {
parent::__construct('user_saml', $urlParams); parent::__construct('user_saml', $urlParams);
$container = $this->getContainer(); $container = $this->getContainer();
@ -57,7 +57,6 @@ class Application extends App {
} }
public function registerDavAuth() { public function registerDavAuth() {
$container = $this->getContainer(); $container = $this->getContainer();
$dispatcher = $container->getServer()->getEventDispatcher(); $dispatcher = $container->getServer()->getEventDispatcher();
@ -74,7 +73,7 @@ class Application extends App {
$config = $container->getServer()->getConfig(); $config = $container->getServer()->getConfig();
$dispatcher = $container->getServer()->getEventDispatcher(); $dispatcher = $container->getServer()->getEventDispatcher();
$dispatcher->addListener('OCA\Files::loadAdditionalScripts', function() use ($session, $config, $userSession) { $dispatcher->addListener('OCA\Files::loadAdditionalScripts', function () use ($session, $config, $userSession) {
if (!$userSession->isLoggedIn()) { if (!$userSession->isLoggedIn()) {
return; return;
} }

View file

@ -38,8 +38,6 @@ use OCP\ILogger;
use OCP\IRequest; use OCP\IRequest;
use OCP\ISession; use OCP\ISession;
use OCP\IURLGenerator; use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserManager;
use OCP\IUserSession; use OCP\IUserSession;
use OCP\Security\ICrypto; use OCP\Security\ICrypto;
use OneLogin\Saml2\Auth; use OneLogin\Saml2\Auth;
@ -120,7 +118,7 @@ class SAMLController extends Controller {
private function autoprovisionIfPossible() { private function autoprovisionIfPossible() {
$auth = $this->userData->getAttributes(); $auth = $this->userData->getAttributes();
if(!$this->userData->hasUidMappingAttribute()) { if (!$this->userData->hasUidMappingAttribute()) {
throw new NoUserFoundException('IDP parameter for the UID not found. Possible parameters are: ' . json_encode(array_keys($auth))); throw new NoUserFoundException('IDP parameter for the UID not found. Possible parameters are: ' . json_encode(array_keys($auth)));
} }
@ -142,17 +140,17 @@ class SAMLController extends Controller {
return; return;
} }
$autoProvisioningAllowed = $this->userBackend->autoprovisionAllowed(); $autoProvisioningAllowed = $this->userBackend->autoprovisionAllowed();
if($userExists) { if ($userExists) {
if($autoProvisioningAllowed) { if ($autoProvisioningAllowed) {
$this->userBackend->updateAttributes($uid, $auth); $this->userBackend->updateAttributes($uid, $auth);
} }
return; return;
} }
$uid = $this->userData->getOriginalUid(); $uid = $this->userData->getOriginalUid();
$uid = $this->userData->testEncodedObjectGUID($uid); $uid = $this->userData->testEncodedObjectGUID($uid);
if(!$userExists && !$autoProvisioningAllowed) { if (!$userExists && !$autoProvisioningAllowed) {
throw new NoUserFoundException('Auto provisioning not allowed and user ' . $uid . ' does not exist'); throw new NoUserFoundException('Auto provisioning not allowed and user ' . $uid . ' does not exist');
} elseif(!$userExists && $autoProvisioningAllowed) { } elseif (!$userExists && $autoProvisioningAllowed) {
$this->userBackend->createUserIfNotExists($uid, $auth); $this->userBackend->createUserIfNotExists($uid, $auth);
$this->userBackend->updateAttributes($uid, $auth); $this->userBackend->updateAttributes($uid, $auth);
return; return;
@ -171,7 +169,7 @@ class SAMLController extends Controller {
*/ */
public function login($idp) { public function login($idp) {
$type = $this->config->getAppValue($this->appName, 'type'); $type = $this->config->getAppValue($this->appName, 'type');
switch($type) { switch ($type) {
case 'saml': case 'saml':
$auth = new Auth($this->SAMLSettings->getOneLoginSettingsArray($idp)); $auth = new Auth($this->SAMLSettings->getOneLoginSettingsArray($idp));
$ssoUrl = $auth->login(null, [], false, false, true); $ssoUrl = $auth->login(null, [], false, false, true);
@ -182,7 +180,7 @@ class SAMLController extends Controller {
if ($this->session->get(ClientFlowLoginController::STATE_NAME) !== null) { if ($this->session->get(ClientFlowLoginController::STATE_NAME) !== null) {
$flowData['cf1'] = $this->session->get(ClientFlowLoginController::STATE_NAME); $flowData['cf1'] = $this->session->get(ClientFlowLoginController::STATE_NAME);
} else if ($this->session->get(ClientFlowLoginV2Controller::TOKEN_NAME) !== null) { } elseif ($this->session->get(ClientFlowLoginV2Controller::TOKEN_NAME) !== null) {
$flowData['cf2'] = [ $flowData['cf2'] = [
'token' => $this->session->get(ClientFlowLoginV2Controller::TOKEN_NAME), 'token' => $this->session->get(ClientFlowLoginV2Controller::TOKEN_NAME),
'state' => $this->session->get(ClientFlowLoginV2Controller::STATE_NAME), 'state' => $this->session->get(ClientFlowLoginV2Controller::STATE_NAME),
@ -291,18 +289,17 @@ class SAMLController extends Controller {
if (isset($data['flow'])) { if (isset($data['flow'])) {
if (isset($data['flow']['cf1'])) { if (isset($data['flow']['cf1'])) {
$this->session->set(ClientFlowLoginController::STATE_NAME, $data['flow']['cf1']); $this->session->set(ClientFlowLoginController::STATE_NAME, $data['flow']['cf1']);
} else if (isset($data['flow']['cf2'])) { } elseif (isset($data['flow']['cf2'])) {
$this->session->set(ClientFlowLoginV2Controller::TOKEN_NAME, $data['flow']['cf2']['token']); $this->session->set(ClientFlowLoginV2Controller::TOKEN_NAME, $data['flow']['cf2']['token']);
$this->session->set(ClientFlowLoginV2Controller::STATE_NAME, $data['flow']['cf2']['state']); $this->session->set(ClientFlowLoginV2Controller::STATE_NAME, $data['flow']['cf2']['state']);
} }
} }
$AuthNRequestID = $data['AuthNRequestID']; $AuthNRequestID = $data['AuthNRequestID'];
$idp = $data['Idp']; $idp = $data['Idp'];
// need to keep the IdP config ID during session lifetime (SAMLSettings::getPrefix) // need to keep the IdP config ID during session lifetime (SAMLSettings::getPrefix)
$this->session->set('user_saml.Idp', $idp); $this->session->set('user_saml.Idp', $idp);
if(is_null($AuthNRequestID) || $AuthNRequestID === '' || is_null($idp)) { if (is_null($AuthNRequestID) || $AuthNRequestID === '' || is_null($idp)) {
$this->logger->debug('Invalid auth payload', ['app' => 'user_saml']); $this->logger->debug('Invalid auth payload', ['app' => 'user_saml']);
return new Http\RedirectResponse($this->urlGenerator->getAbsoluteURL('/')); return new Http\RedirectResponse($this->urlGenerator->getAbsoluteURL('/'));
} }
@ -315,7 +312,7 @@ class SAMLController extends Controller {
$errors = $auth->getErrors(); $errors = $auth->getErrors();
if (!empty($errors)) { if (!empty($errors)) {
foreach($errors as $error) { foreach ($errors as $error) {
$this->logger->error($error, ['app' => $this->appName]); $this->logger->error($error, ['app' => $this->appName]);
} }
$this->logger->error($auth->getLastErrorReason(), ['app' => $this->appName]); $this->logger->error($auth->getLastErrorReason(), ['app' => $this->appName]);
@ -363,14 +360,14 @@ class SAMLController extends Controller {
} }
$originalUrl = $data['OriginalUrl']; $originalUrl = $data['OriginalUrl'];
if($originalUrl !== null && $originalUrl !== '') { if ($originalUrl !== null && $originalUrl !== '') {
$response = new Http\RedirectResponse($originalUrl); $response = new Http\RedirectResponse($originalUrl);
} else { } else {
$response = new Http\RedirectResponse(\OC::$server->getURLGenerator()->getAbsoluteURL('/')); $response = new Http\RedirectResponse(\OC::$server->getURLGenerator()->getAbsoluteURL('/'));
} }
// The Nextcloud desktop client expects a cookie with the key of "_shibsession" // The Nextcloud desktop client expects a cookie with the key of "_shibsession"
// to be there. // to be there.
if($this->request->isUserAgent(['/^.*(mirall|csyncoC)\/.*$/'])) { if ($this->request->isUserAgent(['/^.*(mirall|csyncoC)\/.*$/'])) {
$response->addCookie('_shibsession_', 'authenticated'); $response->addCookie('_shibsession_', 'authenticated');
} }
@ -392,17 +389,17 @@ class SAMLController extends Controller {
// Some IDPs send the SLO request via POST, but OneLogin php-saml only handles GET. // Some IDPs send the SLO request via POST, but OneLogin php-saml only handles GET.
// To hack around this issue we copy the request from _POST to _GET. // To hack around this issue we copy the request from _POST to _GET.
if(!empty($_POST['SAMLRequest'])) { if (!empty($_POST['SAMLRequest'])) {
$_GET['SAMLRequest'] = $_POST['SAMLRequest']; $_GET['SAMLRequest'] = $_POST['SAMLRequest'];
} }
$isFromIDP = !$isFromGS && !empty($_GET['SAMLRequest']); $isFromIDP = !$isFromGS && !empty($_GET['SAMLRequest']);
if($isFromIDP) { if ($isFromIDP) {
// requests comes from the IDP so let it manage the logout // requests comes from the IDP so let it manage the logout
// (or raise Error if request is invalid) // (or raise Error if request is invalid)
$pass = True ; $pass = true ;
} elseif($isFromGS) { } elseif ($isFromGS) {
// Request is from master GlobalScale // Request is from master GlobalScale
// Request validity is check via a JSON Web Token // Request validity is check via a JSON Web Token
$jwt = $this->request->getParam('jwt', ''); $jwt = $this->request->getParam('jwt', '');
@ -412,7 +409,7 @@ class SAMLController extends Controller {
$pass = $this->request->passesCSRFCheck(); $pass = $this->request->passesCSRFCheck();
} }
if($pass) { if ($pass) {
$idp = $this->session->get('user_saml.Idp'); $idp = $this->session->get('user_saml.Idp');
$auth = new Auth($this->SAMLSettings->getOneLoginSettingsArray($idp)); $auth = new Auth($this->SAMLSettings->getOneLoginSettingsArray($idp));
$stay = true ; // $auth will return the redirect URL but won't perform the redirect himself $stay = true ; // $auth will return the redirect URL but won't perform the redirect himself
@ -428,14 +425,14 @@ class SAMLController extends Controller {
$errors = $auth->getErrors(); $errors = $auth->getErrors();
if (!empty($errors)) { if (!empty($errors)) {
foreach($errors as $error) { foreach ($errors as $error) {
$this->logger->error($error, ['app' => $this->appName]); $this->logger->error($error, ['app' => $this->appName]);
} }
$this->logger->error($auth->getLastErrorReason(), ['app' => $this->appName]); $this->logger->error($auth->getLastErrorReason(), ['app' => $this->appName]);
} }
} else { } else {
// If request is not from IDP, we send the logout request to the IDP // If request is not from IDP, we send the logout request to the IDP
$parameters = array(); $parameters = [];
$nameId = $this->session->get('user_saml.samlNameId'); $nameId = $this->session->get('user_saml.samlNameId');
$nameIdFormat = $this->session->get('user_saml.samlNameIdFormat'); $nameIdFormat = $this->session->get('user_saml.samlNameIdFormat');
$nameIdNameQualifier = $this->session->get('user_saml.samlNameIdNameQualifier'); $nameIdNameQualifier = $this->session->get('user_saml.samlNameIdNameQualifier');
@ -448,11 +445,11 @@ class SAMLController extends Controller {
$this->userSession->logout(); $this->userSession->logout();
} }
} }
if(!empty($targetUrl) && !$auth->getLastErrorReason()){ if (!empty($targetUrl) && !$auth->getLastErrorReason()) {
$this->userSession->logout(); $this->userSession->logout();
} }
} }
if(empty($targetUrl)){ if (empty($targetUrl)) {
$targetUrl = $this->urlGenerator->getAbsoluteURL('/'); $targetUrl = $this->urlGenerator->getAbsoluteURL('/');
} }
@ -491,7 +488,6 @@ class SAMLController extends Controller {
* @return Http\TemplateResponse * @return Http\TemplateResponse
*/ */
public function selectUserBackEnd($redirectUrl) { public function selectUserBackEnd($redirectUrl) {
$attributes = ['loginUrls' => []]; $attributes = ['loginUrls' => []];
if ($this->SAMLSettings->allowMultipleUserBackEnds()) { if ($this->SAMLSettings->allowMultipleUserBackEnds()) {
@ -543,9 +539,8 @@ class SAMLController extends Controller {
* @return string * @return string
*/ */
private function getSSOUrl($redirectUrl, $idp) { private function getSSOUrl($redirectUrl, $idp) {
$originalUrl = ''; $originalUrl = '';
if(!empty($redirectUrl)) { if (!empty($redirectUrl)) {
$originalUrl = $this->urlGenerator->getAbsoluteURL($redirectUrl); $originalUrl = $this->urlGenerator->getAbsoluteURL($redirectUrl);
} }
@ -561,7 +556,6 @@ class SAMLController extends Controller {
); );
return $ssoUrl; return $ssoUrl;
} }
/** /**
@ -612,5 +606,4 @@ class SAMLController extends Controller {
$message = $this->l->t('This page should not be visited directly.'); $message = $this->l->t('This page should not be visited directly.');
return new Http\TemplateResponse($this->appName, 'error', ['message' => $message], 'guest'); return new Http\TemplateResponse($this->appName, 'error', ['message' => $message], 'guest');
} }
} }

View file

@ -116,5 +116,4 @@ class SettingsController extends Controller {
} }
return new Response(); return new Response();
} }
} }

View file

@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
/** /**
* @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl> * @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>

View file

@ -24,11 +24,8 @@ namespace OCA\User_SAML;
use OCA\DAV\Connector\Sabre\Auth; use OCA\DAV\Connector\Sabre\Auth;
use OCP\IConfig; use OCP\IConfig;
use OCP\ISession; use OCP\ISession;
use Sabre\DAV\CorePlugin;
use Sabre\DAV\FS\Directory;
use Sabre\DAV\Server; use Sabre\DAV\Server;
use Sabre\DAV\ServerPlugin; use Sabre\DAV\ServerPlugin;
use Sabre\DAV\Tree;
use Sabre\HTTP\RequestInterface; use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface; use Sabre\HTTP\ResponseInterface;

View file

@ -21,7 +21,6 @@
namespace OCA\User_SAML\Middleware; namespace OCA\User_SAML\Middleware;
use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Http\RedirectResponse;
use OCP\AppFramework\Middleware; use OCP\AppFramework\Middleware;
use OCP\AppFramework\Utility\IControllerMethodReflector; use OCP\AppFramework\Utility\IControllerMethodReflector;
@ -61,8 +60,8 @@ class OnlyLoggedInMiddleware extends Middleware {
* @param string $methodName * @param string $methodName
* @throws \Exception * @throws \Exception
*/ */
public function beforeController($controller, $methodName){ public function beforeController($controller, $methodName) {
if($this->reflector->hasAnnotation('OnlyUnauthenticatedUsers') && $this->userSession->isLoggedIn()) { if ($this->reflector->hasAnnotation('OnlyUnauthenticatedUsers') && $this->userSession->isLoggedIn()) {
throw new \Exception('User is already logged-in'); throw new \Exception('User is already logged-in');
} }
} }
@ -75,7 +74,7 @@ class OnlyLoggedInMiddleware extends Middleware {
* @throws \Exception * @throws \Exception
*/ */
public function afterException($controller, $methodName, \Exception $exception) { public function afterException($controller, $methodName, \Exception $exception) {
if($exception->getMessage() === 'User is already logged-in') { if ($exception->getMessage() === 'User is already logged-in') {
return new RedirectResponse($this->urlGenerator->getAbsoluteURL('/')); return new RedirectResponse($this->urlGenerator->getAbsoluteURL('/'));
} }

View file

@ -21,7 +21,6 @@
namespace OCA\User_SAML; namespace OCA\User_SAML;
use OCP\AppFramework\Http;
use OCP\IConfig; use OCP\IConfig;
use OCP\IRequest; use OCP\IRequest;
use OCP\ISession; use OCP\ISession;
@ -99,7 +98,6 @@ class SAMLSettings {
* @return array * @return array
*/ */
public function getOneLoginSettingsArray($idp) { public function getOneLoginSettingsArray($idp) {
$prefix = ''; $prefix = '';
if ($idp > 1) { if ($idp > 1) {
$prefix = $idp . '-'; $prefix = $idp . '-';
@ -142,20 +140,20 @@ class SAMLSettings {
$spx509cert = $this->config->getAppValue('user_saml', $prefix . 'sp-x509cert', ''); $spx509cert = $this->config->getAppValue('user_saml', $prefix . 'sp-x509cert', '');
$spxprivateKey = $this->config->getAppValue('user_saml', $prefix . 'sp-privateKey', ''); $spxprivateKey = $this->config->getAppValue('user_saml', $prefix . 'sp-privateKey', '');
if($spx509cert !== '') { if ($spx509cert !== '') {
$settings['sp']['x509cert'] = $spx509cert; $settings['sp']['x509cert'] = $spx509cert;
} }
if($spxprivateKey !== '') { if ($spxprivateKey !== '') {
$settings['sp']['privateKey'] = $spxprivateKey; $settings['sp']['privateKey'] = $spxprivateKey;
} }
$idpx509cert = $this->config->getAppValue('user_saml', $prefix . 'idp-x509cert', ''); $idpx509cert = $this->config->getAppValue('user_saml', $prefix . 'idp-x509cert', '');
if($idpx509cert !== '') { if ($idpx509cert !== '') {
$settings['idp']['x509cert'] = $idpx509cert; $settings['idp']['x509cert'] = $idpx509cert;
} }
$slo = $this->config->getAppValue('user_saml', $prefix . 'idp-singleLogoutService.url', ''); $slo = $this->config->getAppValue('user_saml', $prefix . 'idp-singleLogoutService.url', '');
if($slo !== '') { if ($slo !== '') {
$settings['idp']['singleLogoutService'] = [ $settings['idp']['singleLogoutService'] = [
'url' => $this->config->getAppValue('user_saml', $prefix . 'idp-singleLogoutService.url', ''), 'url' => $this->config->getAppValue('user_saml', $prefix . 'idp-singleLogoutService.url', ''),
]; ];
@ -164,7 +162,7 @@ class SAMLSettings {
]; ];
$sloResponseUrl = $this->config->getAppValue('user_saml', $prefix . 'idp-singleLogoutService.responseUrl', ''); $sloResponseUrl = $this->config->getAppValue('user_saml', $prefix . 'idp-singleLogoutService.responseUrl', '');
if($sloResponseUrl !== '') { if ($sloResponseUrl !== '') {
$settings['idp']['singleLogoutService']['responseUrl'] = $sloResponseUrl; $settings['idp']['singleLogoutService']['responseUrl'] = $sloResponseUrl;
} }
} }
@ -179,7 +177,6 @@ class SAMLSettings {
* @return string * @return string
*/ */
public function getPrefix($setting = '') { public function getPrefix($setting = '') {
$prefix = ''; $prefix = '';
if (!empty($setting) && in_array($setting, $this->globalSettings)) { if (!empty($setting) && in_array($setting, $this->globalSettings)) {
return $prefix; return $prefix;
@ -192,5 +189,4 @@ class SAMLSettings {
return $prefix; return $prefix;
} }
} }

View file

@ -64,7 +64,7 @@ class Admin implements ISettings {
$providers[] = [ $providers[] = [
'id' => $id, 'id' => $id,
'name' => $name === '' ? $this->l10n->t('Provider ') . $id : $name 'name' => $name === '' ? $this->l10n->t('Provider ') . $id : $name
]; ];
} }
$serviceProviderFields = [ $serviceProviderFields = [
'x509cert' => $this->l10n->t('X.509 certificate of the Service Provider'), 'x509cert' => $this->l10n->t('X.509 certificate of the Service Provider'),
@ -86,7 +86,7 @@ class Admin implements ISettings {
'wantXMLValidation' => $this->l10n->t('Indicates if the SP will validate all received XML.'), 'wantXMLValidation' => $this->l10n->t('Indicates if the SP will validate all received XML.'),
]; ];
$securityGeneral = [ $securityGeneral = [
'lowercaseUrlencoding' => $this->l10n->t('ADFS URL-Encodes SAML data as lowercase, and the toolkit by default uses uppercase. Enable for ADFS compatibility on signature verification.'), 'lowercaseUrlencoding' => $this->l10n->t('ADFS URL-Encodes SAML data as lowercase, and the toolkit by default uses uppercase. Enable for ADFS compatibility on signature verification.'),
'signatureAlgorithm' => [ 'signatureAlgorithm' => [
'type' => 'line', 'type' => 'line',
'text' => $this->l10n->t('Algorithm that the toolkit will use on signing process.') 'text' => $this->l10n->t('Algorithm that the toolkit will use on signing process.')
@ -175,7 +175,7 @@ class Admin implements ISettings {
]; ];
$type = $this->config->getAppValue('user_saml', 'type'); $type = $this->config->getAppValue('user_saml', 'type');
if($type === 'saml') { if ($type === 'saml') {
$generalSettings['use_saml_auth_for_desktop'] = [ $generalSettings['use_saml_auth_for_desktop'] = [
'text' => $this->l10n->t('Use SAML auth for the %s desktop clients (requires user re-authentication)', [$this->defaults->getName()]), 'text' => $this->l10n->t('Use SAML auth for the %s desktop clients (requires user re-authentication)', [$this->defaults->getName()]),
'type' => 'checkbox', 'type' => 'checkbox',
@ -226,5 +226,4 @@ class Admin implements ISettings {
public function getPriority() { public function getPriority() {
return 0; return 0;
} }
} }

View file

@ -35,7 +35,6 @@ use OCP\IConfig;
use OCP\IURLGenerator; use OCP\IURLGenerator;
use OCP\ISession; use OCP\ISession;
use Symfony\Component\EventDispatcher\GenericEvent; use Symfony\Component\EventDispatcher\GenericEvent;
use function base64_decode;
class UserBackend implements IApacheBackend, UserInterface, IUserBackend { class UserBackend implements IApacheBackend, UserInterface, IUserBackend {
/** @var IConfig */ /** @var IConfig */
@ -108,8 +107,8 @@ class UserBackend implements IApacheBackend, UserInterface, IUserBackend {
* @param string $uid * @param string $uid
* @param array $attributes * @param array $attributes
*/ */
public function createUserIfNotExists($uid, array $attributes = array()) { public function createUserIfNotExists($uid, array $attributes = []) {
if(!$this->userExistsInDatabase($uid)) { if (!$this->userExistsInDatabase($uid)) {
$values = [ $values = [
'uid' => $uid, 'uid' => $uid,
]; ];
@ -124,12 +123,12 @@ class UserBackend implements IApacheBackend, UserInterface, IUserBackend {
if ($home !== '') { if ($home !== '') {
//if attribute's value is an absolute path take this, otherwise append it to data dir //if attribute's value is an absolute path take this, otherwise append it to data dir
//check for / at the beginning or pattern c:\ resp. c:/ //check for / at the beginning or pattern c:\ resp. c:/
if( '/' !== $home[0] if ('/' !== $home[0]
&& !(3 < strlen($home) && ctype_alpha($home[0]) && !(3 < strlen($home) && ctype_alpha($home[0])
&& $home[1] === ':' && ('\\' === $home[2] || '/' === $home[2])) && $home[1] === ':' && ('\\' === $home[2] || '/' === $home[2]))
) { ) {
$home = $this->config->getSystemValue('datadirectory', $home = $this->config->getSystemValue('datadirectory',
\OC::$SERVERROOT.'/data' ) . '/' . $home; \OC::$SERVERROOT.'/data') . '/' . $home;
} }
$values['home'] = $home; $values['home'] = $home;
@ -138,13 +137,12 @@ class UserBackend implements IApacheBackend, UserInterface, IUserBackend {
/* @var $qb IQueryBuilder */ /* @var $qb IQueryBuilder */
$qb = $this->db->getQueryBuilder(); $qb = $this->db->getQueryBuilder();
$qb->insert('user_saml_users'); $qb->insert('user_saml_users');
foreach($values as $column => $value) { foreach ($values as $column => $value) {
$qb->setValue($column, $qb->createNamedParameter($value)); $qb->setValue($column, $qb->createNamedParameter($value));
} }
$qb->execute(); $qb->execute();
$this->initializeHomeDir($uid); $this->initializeHomeDir($uid);
} }
} }
@ -204,8 +202,8 @@ class UserBackend implements IApacheBackend, UserInterface, IUserBackend {
$data = $result->fetchAll(); $data = $result->fetchAll();
$result->closeCursor(); $result->closeCursor();
foreach($data as $passwords) { foreach ($data as $passwords) {
if(password_verify($password, $passwords['token'])) { if (password_verify($password, $passwords['token'])) {
return $uid; return $uid;
} }
} }
@ -220,7 +218,7 @@ class UserBackend implements IApacheBackend, UserInterface, IUserBackend {
* @since 4.5.0 * @since 4.5.0
*/ */
public function deleteUser($uid) { public function deleteUser($uid) {
if($this->userExistsInDatabase($uid)) { if ($this->userExistsInDatabase($uid)) {
/* @var $qb IQueryBuilder */ /* @var $qb IQueryBuilder */
$qb = $this->db->getQueryBuilder(); $qb = $this->db->getQueryBuilder();
$qb->delete('user_saml_users') $qb->delete('user_saml_users')
@ -238,7 +236,7 @@ class UserBackend implements IApacheBackend, UserInterface, IUserBackend {
* @return string * @return string
*/ */
public function getHome($uid) { public function getHome($uid) {
if($this->userExistsInDatabase($uid)) { if ($this->userExistsInDatabase($uid)) {
$qb = $this->db->getQueryBuilder(); $qb = $this->db->getQueryBuilder();
$qb->select('home') $qb->select('home')
->from('user_saml_users') ->from('user_saml_users')
@ -278,7 +276,7 @@ class UserBackend implements IApacheBackend, UserInterface, IUserBackend {
* @since 4.5.0 * @since 4.5.0
*/ */
public function userExists($uid) { public function userExists($uid) {
if($backend = $this->getActualUserBackend($uid)) { if ($backend = $this->getActualUserBackend($uid)) {
return $backend->userExists($uid); return $backend->userExists($uid);
} else { } else {
return $this->userExistsInDatabase($uid); return $this->userExistsInDatabase($uid);
@ -286,7 +284,7 @@ class UserBackend implements IApacheBackend, UserInterface, IUserBackend {
} }
public function setDisplayName($uid, $displayName) { public function setDisplayName($uid, $displayName) {
if($backend = $this->getActualUserBackend($uid)) { if ($backend = $this->getActualUserBackend($uid)) {
return $backend->setDisplayName($uid, $displayName); return $backend->setDisplayName($uid, $displayName);
} }
@ -310,10 +308,10 @@ class UserBackend implements IApacheBackend, UserInterface, IUserBackend {
* @since 4.5.0 * @since 4.5.0
*/ */
public function getDisplayName($uid) { public function getDisplayName($uid) {
if($backend = $this->getActualUserBackend($uid)) { if ($backend = $this->getActualUserBackend($uid)) {
return $backend->getDisplayName($uid); return $backend->getDisplayName($uid);
} else { } else {
if($this->userExistsInDatabase($uid)) { if ($this->userExistsInDatabase($uid)) {
$qb = $this->db->getQueryBuilder(); $qb = $this->db->getQueryBuilder();
$qb->select('displayname') $qb->select('displayname')
->from('user_saml_users') ->from('user_saml_users')
@ -375,7 +373,7 @@ class UserBackend implements IApacheBackend, UserInterface, IUserBackend {
* @since 4.5.0 * @since 4.5.0
*/ */
public function hasUserListings() { public function hasUserListings() {
if($this->autoprovisionAllowed()) { if ($this->autoprovisionAllowed()) {
return true; return true;
} }
@ -398,7 +396,7 @@ class UserBackend implements IApacheBackend, UserInterface, IUserBackend {
public function getLogoutUrl() { public function getLogoutUrl() {
$prefix = $this->settings->getPrefix(); $prefix = $this->settings->getPrefix();
$slo = $this->config->getAppValue('user_saml', $prefix . 'idp-singleLogoutService.url', ''); $slo = $this->config->getAppValue('user_saml', $prefix . 'idp-singleLogoutService.url', '');
if($slo === '') { if ($slo === '') {
return ''; return '';
} }
@ -486,14 +484,14 @@ class UserBackend implements IApacheBackend, UserInterface, IUserBackend {
public function getCurrentUserId() { public function getCurrentUserId() {
$user = \OC::$server->getUserSession()->getUser(); $user = \OC::$server->getUserSession()->getUser();
if($user instanceof IUser && $this->session->get('user_saml.samlUserData')) { if ($user instanceof IUser && $this->session->get('user_saml.samlUserData')) {
$uid = $user->getUID(); $uid = $user->getUID();
} else { } else {
$this->userData->setAttributes($this->session->get('user_saml.samlUserData') ?? []); $this->userData->setAttributes($this->session->get('user_saml.samlUserData') ?? []);
$uid = $this->userData->getEffectiveUid(); $uid = $this->userData->getEffectiveUid();
} }
if($uid !== '' && $this->userExists($uid)) { if ($uid !== '' && $this->userExists($uid)) {
$this->session->set('last-password-confirm', strtotime('+4 year', time())); $this->session->set('last-password-confirm', strtotime('+4 year', time()));
return $uid; return $uid;
} }
@ -526,8 +524,8 @@ class UserBackend implements IApacheBackend, UserInterface, IUserBackend {
* @return null|UserInterface * @return null|UserInterface
*/ */
public function getActualUserBackend($uid) { public function getActualUserBackend($uid) {
foreach(self::$backends as $backend) { foreach (self::$backends as $backend) {
if($backend->userExists($uid)) { if ($backend->userExists($uid)) {
return $backend; return $backend;
} }
} }
@ -545,8 +543,7 @@ class UserBackend implements IApacheBackend, UserInterface, IUserBackend {
self::$backends = $backends; self::$backends = $backends;
} }
private function getAttributeKeys($name) private function getAttributeKeys($name) {
{
$prefix = $this->settings->getPrefix($name); $prefix = $this->settings->getPrefix($name);
$keys = explode(' ', $this->config->getAppValue('user_saml', $prefix . $name, '')); $keys = explode(' ', $this->config->getAppValue('user_saml', $prefix . $name, ''));
@ -560,17 +557,17 @@ class UserBackend implements IApacheBackend, UserInterface, IUserBackend {
$keys = $this->getAttributeKeys($name); $keys = $this->getAttributeKeys($name);
$value = ''; $value = '';
foreach($keys as $key) { foreach ($keys as $key) {
if (isset($attributes[$key])) { if (isset($attributes[$key])) {
if (is_array($attributes[$key])) { if (is_array($attributes[$key])) {
foreach ($attributes[$key] as $attribute_part_value) { foreach ($attributes[$key] as $attribute_part_value) {
if($value !== '') { if ($value !== '') {
$value .= ' '; $value .= ' ';
} }
$value .= $attribute_part_value; $value .= $attribute_part_value;
} }
} else { } else {
if($value !== '') { if ($value !== '') {
$value .= ' '; $value .= ' ';
} }
$value .= $attributes[$key]; $value .= $attributes[$key];
@ -584,8 +581,8 @@ class UserBackend implements IApacheBackend, UserInterface, IUserBackend {
private function getAttributeArrayValue($name, array $attributes) { private function getAttributeArrayValue($name, array $attributes) {
$keys = $this->getAttributeKeys($name); $keys = $this->getAttributeKeys($name);
$value = array(); $value = [];
foreach($keys as $key) { foreach ($keys as $key) {
if (isset($attributes[$key])) { if (isset($attributes[$key])) {
if (is_array($attributes[$key])) { if (is_array($attributes[$key])) {
$value = array_merge($value, array_values($attributes[$key])); $value = array_merge($value, array_values($attributes[$key]));

View file

@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
/** /**
* @copyright Copyright (c) 2020 Arthur Schiwon <blizzz@arthur-schiwon.de> * @copyright Copyright (c) 2020 Arthur Schiwon <blizzz@arthur-schiwon.de>
@ -67,7 +68,7 @@ class UserData {
} }
public function getEffectiveUid(): string { public function getEffectiveUid(): string {
if($this->uid !== null) { if ($this->uid !== null) {
return $this->uid; return $this->uid;
} }
$this->assertIsInitialized(); $this->assertIsInitialized();
@ -85,7 +86,7 @@ class UserData {
protected function extractSamlUserId(): string { protected function extractSamlUserId(): string {
$prefix = $this->samlSettings->getPrefix(); $prefix = $this->samlSettings->getPrefix();
$uidMapping = $this->config->getAppValue('user_saml', $prefix . 'general-uid_mapping'); $uidMapping = $this->config->getAppValue('user_saml', $prefix . 'general-uid_mapping');
if(isset($this->attributes[$uidMapping])) { if (isset($this->attributes[$uidMapping])) {
if (is_array($this->attributes[$uidMapping])) { if (is_array($this->attributes[$uidMapping])) {
return trim($this->attributes[$uidMapping][0]); return trim($this->attributes[$uidMapping][0]);
} else { } else {
@ -107,13 +108,13 @@ class UserData {
} }
$candidate = base64_decode($uid, true); $candidate = base64_decode($uid, true);
if($candidate === false) { if ($candidate === false) {
return $uid; return $uid;
} }
$candidate = $this->convertObjectGUID2Str($candidate); $candidate = $this->convertObjectGUID2Str($candidate);
// the regex only matches the structure of the UUID, not its semantic // the regex only matches the structure of the UUID, not its semantic
// (i.e. version or variant) simply to be future compatible // (i.e. version or variant) simply to be future compatible
if(preg_match('/^[a-f0-9]{8}(-[a-f0-9]{4}){4}[a-f0-9]{8}$/i', $candidate) === 1) { if (preg_match('/^[a-f0-9]{8}(-[a-f0-9]{4}){4}[a-f0-9]{8}$/i', $candidate) === 1) {
$uid = $candidate; $uid = $candidate;
} }
return $uid; return $uid;
@ -125,15 +126,15 @@ class UserData {
protected function convertObjectGUID2Str($oguid): string { protected function convertObjectGUID2Str($oguid): string {
$hex_guid = bin2hex($oguid); $hex_guid = bin2hex($oguid);
$hex_guid_to_guid_str = ''; $hex_guid_to_guid_str = '';
for($k = 1; $k <= 4; ++$k) { for ($k = 1; $k <= 4; ++$k) {
$hex_guid_to_guid_str .= substr($hex_guid, 8 - 2 * $k, 2); $hex_guid_to_guid_str .= substr($hex_guid, 8 - 2 * $k, 2);
} }
$hex_guid_to_guid_str .= '-'; $hex_guid_to_guid_str .= '-';
for($k = 1; $k <= 2; ++$k) { for ($k = 1; $k <= 2; ++$k) {
$hex_guid_to_guid_str .= substr($hex_guid, 12 - 2 * $k, 2); $hex_guid_to_guid_str .= substr($hex_guid, 12 - 2 * $k, 2);
} }
$hex_guid_to_guid_str .= '-'; $hex_guid_to_guid_str .= '-';
for($k = 1; $k <= 2; ++$k) { for ($k = 1; $k <= 2; ++$k) {
$hex_guid_to_guid_str .= substr($hex_guid, 16 - 2 * $k, 2); $hex_guid_to_guid_str .= substr($hex_guid, 16 - 2 * $k, 2);
} }
$hex_guid_to_guid_str .= '-' . substr($hex_guid, 16, 4); $hex_guid_to_guid_str .= '-' . substr($hex_guid, 16, 4);
@ -143,7 +144,7 @@ class UserData {
} }
protected function assertIsInitialized() { protected function assertIsInitialized() {
if($this->attributes === null) { if ($this->attributes === null) {
throw new \LogicException('UserData have to be initialized with setAttributes first'); throw new \LogicException('UserData have to be initialized with setAttributes first');
} }
} }

View file

@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
/** /**
* @copyright Copyright (c) 2020 Arthur Schiwon <blizzz@arthur-schiwon.de> * @copyright Copyright (c) 2020 Arthur Schiwon <blizzz@arthur-schiwon.de>
@ -40,18 +41,18 @@ class UserResolver {
* @throws NoUserFoundException * @throws NoUserFoundException
*/ */
public function findExistingUserId(string $rawUidCandidate, bool $force = false): string { public function findExistingUserId(string $rawUidCandidate, bool $force = false): string {
if($force) { if ($force) {
$this->ensureUser($rawUidCandidate); $this->ensureUser($rawUidCandidate);
} }
if($this->userManager->userExists($rawUidCandidate)) { if ($this->userManager->userExists($rawUidCandidate)) {
return $rawUidCandidate; return $rawUidCandidate;
} }
try { try {
$sanitized = $this->sanitizeUserIdCandidate($rawUidCandidate); $sanitized = $this->sanitizeUserIdCandidate($rawUidCandidate);
} catch(\InvalidArgumentException $e) { } catch (\InvalidArgumentException $e) {
$sanitized = ''; $sanitized = '';
} }
if($this->userManager->userExists($sanitized)) { if ($this->userManager->userExists($sanitized)) {
return $sanitized; return $sanitized;
} }
throw new NoUserFoundException('User' . $rawUidCandidate . ' not valid or not found'); throw new NoUserFoundException('User' . $rawUidCandidate . ' not valid or not found');
@ -63,7 +64,7 @@ class UserResolver {
public function findExistingUser(string $rawUidCandidate): IUser { public function findExistingUser(string $rawUidCandidate): IUser {
$uid = $this->findExistingUserId($rawUidCandidate); $uid = $this->findExistingUserId($rawUidCandidate);
$user = $this->userManager->get($uid); $user = $this->userManager->get($uid);
if($user === null) { if ($user === null) {
throw new NoUserFoundException('User' . $rawUidCandidate . ' not valid or not found'); throw new NoUserFoundException('User' . $rawUidCandidate . ' not valid or not found');
} }
return $user; return $user;
@ -73,7 +74,7 @@ class UserResolver {
try { try {
$this->findExistingUserId($uid, $force); $this->findExistingUserId($uid, $force);
return true; return true;
} catch(NoUserFoundException $e) { } catch (NoUserFoundException $e) {
return false; return false;
} }
} }
@ -91,7 +92,7 @@ class UserResolver {
// Transliteration to ASCII // Transliteration to ASCII
$transliterated = @iconv('UTF-8', 'ASCII//TRANSLIT', $sanitized); $transliterated = @iconv('UTF-8', 'ASCII//TRANSLIT', $sanitized);
if($transliterated !== false) { if ($transliterated !== false) {
// depending on system config iconv can work or not // depending on system config iconv can work or not
$sanitized = $transliterated; $sanitized = $transliterated;
} }
@ -102,7 +103,7 @@ class UserResolver {
// Every remaining disallowed characters will be removed // Every remaining disallowed characters will be removed
$sanitized = preg_replace('/[^a-zA-Z0-9_.@-]/u', '', $sanitized); $sanitized = preg_replace('/[^a-zA-Z0-9_.@-]/u', '', $sanitized);
if($sanitized === '') { if ($sanitized === '') {
throw new \InvalidArgumentException('provided name template for username does not contain any allowed characters'); throw new \InvalidArgumentException('provided name template for username does not contain any allowed characters');
} }

View file

@ -52,15 +52,15 @@ style('user_saml', 'admin');
<div id="user-saml-global" class="hidden"> <div id="user-saml-global" class="hidden">
<h3><?php p($l->t('Global settings')) ?></h3> <h3><?php p($l->t('Global settings')) ?></h3>
<?php foreach($_['general'] as $key => $attribute): ?> <?php foreach ($_['general'] as $key => $attribute): ?>
<?php if($attribute['type'] === 'checkbox' && $attribute['global']): ?> <?php if ($attribute['type'] === 'checkbox' && $attribute['global']): ?>
<p> <p>
<input type="checkbox" data-key="<?php p($key)?>" id="user-saml-general-<?php p($key)?>" name="<?php p($key)?>" value="<?php p(\OC::$server->getConfig()->getAppValue('user_saml', 'general-'.$key, '0')) ?>"> <input type="checkbox" data-key="<?php p($key)?>" id="user-saml-general-<?php p($key)?>" name="<?php p($key)?>" value="<?php p(\OC::$server->getConfig()->getAppValue('user_saml', 'general-'.$key, '0')) ?>">
<label for="user-saml-general-<?php p($key)?>"><?php p($attribute['text']) ?></label><br/> <label for="user-saml-general-<?php p($key)?>"><?php p($attribute['text']) ?></label><br/>
</p> </p>
<?php elseif($attribute['type'] === 'line' && isset($attribute['global'])): ?> <?php elseif ($attribute['type'] === 'line' && isset($attribute['global'])): ?>
<p> <p>
<input data-key="<?php p($key)?>" name="<?php p($key) ?>" value="<?php p(\OC::$server->getConfig()->getAppValue('user_saml', 'general-'.$key, '')) ?>" type="text" <?php if(isset($attribute['required']) && $attribute['required'] === true): ?>class="required"<?php endif;?> placeholder="<?php p($attribute['text']) ?>"/> <input data-key="<?php p($key)?>" name="<?php p($key) ?>" value="<?php p(\OC::$server->getConfig()->getAppValue('user_saml', 'general-'.$key, '')) ?>" type="text" <?php if (isset($attribute['required']) && $attribute['required'] === true): ?>class="required"<?php endif;?> placeholder="<?php p($attribute['text']) ?>"/>
</p> </p>
<?php endif; ?> <?php endif; ?>
<?php endforeach; ?> <?php endforeach; ?>
@ -82,15 +82,15 @@ style('user_saml', 'admin');
<h3> <h3>
<?php p($l->t('General')) ?> <?php p($l->t('General')) ?>
</h3> </h3>
<?php foreach($_['general'] as $key => $attribute): ?> <?php foreach ($_['general'] as $key => $attribute): ?>
<?php if($attribute['type'] === 'checkbox' && !$attribute['global']): ?> <?php if ($attribute['type'] === 'checkbox' && !$attribute['global']): ?>
<p> <p>
<input type="checkbox" data-key="<?php p($key)?>" id="user-saml-general-<?php p($key)?>" name="<?php p($key)?>" value="<?php p(\OC::$server->getConfig()->getAppValue('user_saml', 'general-'.$key, '0')) ?>"> <input type="checkbox" data-key="<?php p($key)?>" id="user-saml-general-<?php p($key)?>" name="<?php p($key)?>" value="<?php p(\OC::$server->getConfig()->getAppValue('user_saml', 'general-'.$key, '0')) ?>">
<label for="user-saml-general-<?php p($key)?>"><?php p($attribute['text']) ?></label><br/> <label for="user-saml-general-<?php p($key)?>"><?php p($attribute['text']) ?></label><br/>
</p> </p>
<?php elseif($attribute['type'] === 'line' && !isset($attribute['global'])): ?> <?php elseif ($attribute['type'] === 'line' && !isset($attribute['global'])): ?>
<p> <p>
<input data-key="<?php p($key)?>" name="<?php p($key) ?>" value="<?php p(\OC::$server->getConfig()->getAppValue('user_saml', 'general-'.$key, '')) ?>" type="text" <?php if(isset($attribute['required']) && $attribute['required'] === true): ?>class="required"<?php endif;?> placeholder="<?php p($attribute['text']) ?>"/> <input data-key="<?php p($key)?>" name="<?php p($key) ?>" value="<?php p(\OC::$server->getConfig()->getAppValue('user_saml', 'general-'.$key, '')) ?>" type="text" <?php if (isset($attribute['required']) && $attribute['required'] === true): ?>class="required"<?php endif;?> placeholder="<?php p($attribute['text']) ?>"/>
</p> </p>
<?php endif; ?> <?php endif; ?>
<?php endforeach; ?> <?php endforeach; ?>
@ -109,12 +109,14 @@ style('user_saml', 'admin');
<label for="user-saml-nameidformat"><?php p($l->t('Name ID format')) ?></label><br/> <label for="user-saml-nameidformat"><?php p($l->t('Name ID format')) ?></label><br/>
<select id="user-saml-nameidformat" <select id="user-saml-nameidformat"
name="name-id-format"> name="name-id-format">
<?php foreach($_['name-id-formats'] as $key => $value): ?> <?php foreach ($_['name-id-formats'] as $key => $value): ?>
<option value="<?php p($key) ?>" <option value="<?php p($key) ?>"
<?php if ($value['selected'] ?? false) { p("selected"); } ?> ><?php p($value['label']) ?></option> <?php if ($value['selected'] ?? false) {
p("selected");
} ?> ><?php p($value['label']) ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
<?php foreach($_['sp'] as $key => $text): ?> <?php foreach ($_['sp'] as $key => $text): ?>
<p> <p>
<textarea name="<?php p($key) ?>" placeholder="<?php p($text) ?>"><?php p(\OC::$server->getConfig()->getAppValue('user_saml', 'sp-'.$key, '')) ?></textarea> <textarea name="<?php p($key) ?>" placeholder="<?php p($text) ?>"><?php p(\OC::$server->getConfig()->getAppValue('user_saml', 'sp-'.$key, '')) ?></textarea>
</p> </p>
@ -145,11 +147,11 @@ style('user_saml', 'admin');
</p> </p>
<div class="hidden"> <div class="hidden">
<?php foreach($_['attribute-mapping'] as $key => $attribute): ?> <?php foreach ($_['attribute-mapping'] as $key => $attribute): ?>
<?php <?php
if($attribute['type'] === 'line'): ?> if ($attribute['type'] === 'line'): ?>
<p> <p>
<input name="<?php p($key) ?>" value="<?php p(\OC::$server->getConfig()->getAppValue('user_saml', 'saml-attribute-mapping-'.$key, '')) ?>" type="text" <?php if(isset($attribute['required']) && $attribute['required'] === true): ?>class="required"<?php endif;?> placeholder="<?php p($attribute['text']) ?>"/> <input name="<?php p($key) ?>" value="<?php p(\OC::$server->getConfig()->getAppValue('user_saml', 'saml-attribute-mapping-'.$key, '')) ?>" type="text" <?php if (isset($attribute['required']) && $attribute['required'] === true): ?>class="required"<?php endif;?> placeholder="<?php p($attribute['text']) ?>"/>
</p> </p>
<?php endif; ?> <?php endif; ?>
<?php endforeach; ?> <?php endforeach; ?>
@ -164,26 +166,26 @@ style('user_saml', 'admin');
</p> </p>
<div class="indent hidden"> <div class="indent hidden">
<h4><?php p($l->t('Signatures and encryption offered')) ?></h4> <h4><?php p($l->t('Signatures and encryption offered')) ?></h4>
<?php foreach($_['security-offer'] as $key => $text): ?> <?php foreach ($_['security-offer'] as $key => $text): ?>
<p> <p>
<input type="checkbox" id="user-saml-<?php p($key)?>" name="<?php p($key)?>" value="<?php p(\OC::$server->getConfig()->getAppValue('user_saml', 'security-'.$key, '0')) ?>" class="checkbox"> <input type="checkbox" id="user-saml-<?php p($key)?>" name="<?php p($key)?>" value="<?php p(\OC::$server->getConfig()->getAppValue('user_saml', 'security-'.$key, '0')) ?>" class="checkbox">
<label for="user-saml-<?php p($key)?>"><?php p($text) ?></label><br/> <label for="user-saml-<?php p($key)?>"><?php p($text) ?></label><br/>
</p> </p>
<?php endforeach; ?> <?php endforeach; ?>
<h4><?php p($l->t('Signatures and encryption required')) ?></h4> <h4><?php p($l->t('Signatures and encryption required')) ?></h4>
<?php foreach($_['security-required'] as $key => $text): ?> <?php foreach ($_['security-required'] as $key => $text): ?>
<p> <p>
<input type="checkbox" id="user-saml-<?php p($key)?>" name="<?php p($key)?>" value="<?php p(\OC::$server->getConfig()->getAppValue('user_saml', 'security-'.$key, '0')) ?>" class="checkbox"> <input type="checkbox" id="user-saml-<?php p($key)?>" name="<?php p($key)?>" value="<?php p(\OC::$server->getConfig()->getAppValue('user_saml', 'security-'.$key, '0')) ?>" class="checkbox">
<label for="user-saml-<?php p($key)?>"><?php p($text) ?></label> <label for="user-saml-<?php p($key)?>"><?php p($text) ?></label>
</p> </p>
<?php endforeach; ?> <?php endforeach; ?>
<h4><?php p($l->t('General')) ?></h4> <h4><?php p($l->t('General')) ?></h4>
<?php foreach($_['security-general'] as $key => $attribute): ?> <?php foreach ($_['security-general'] as $key => $attribute): ?>
<?php if (is_array($attribute) && $attribute['type'] === 'line') { ?> <?php if (is_array($attribute) && $attribute['type'] === 'line') { ?>
<?php $text = $attribute['text'] ?> <?php $text = $attribute['text'] ?>
<p> <p>
<label><?php p($attribute['text']) ?></label><br /> <label><?php p($attribute['text']) ?></label><br />
<input data-key="<?php p($key)?>" name="<?php p($key) ?>" value="<?php p(\OC::$server->getConfig()->getAppValue('user_saml', 'security-'.$key, '')) ?>" type="text" <?php if(isset($attribute['required']) && $attribute['required'] === true): ?>class="required"<?php endif;?> placeholder="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/> <input data-key="<?php p($key)?>" name="<?php p($key) ?>" value="<?php p(\OC::$server->getConfig()->getAppValue('user_saml', 'security-'.$key, '')) ?>" type="text" <?php if (isset($attribute['required']) && $attribute['required'] === true): ?>class="required"<?php endif;?> placeholder="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
</p> </p>
<?php } else { ?> <?php } else { ?>
<?php $text = $attribute ?> <?php $text = $attribute ?>

View file

@ -10,21 +10,21 @@ script('user_saml', 'selectUserBackEnd');
<h1><?php p($l->t('Login options:')); ?></h1> <h1><?php p($l->t('Login options:')); ?></h1>
<?php if($_['useCombobox']) { ?> <?php if ($_['useCombobox']) { ?>
<select class="login-chose-saml-idp" id="av_mode" name="avMode"> <select class="login-chose-saml-idp" id="av_mode" name="avMode">
<option value=""><?php p($l->t('Choose a authentication provider')); ?></option> <option value=""><?php p($l->t('Choose a authentication provider')); ?></option>
<?php foreach ($_['loginUrls']['ssoLogin'] as $idp) { ?> <?php foreach ($_['loginUrls']['ssoLogin'] as $idp) { ?>
<option value="<?php p($idp['url']); ?>"><?php p($idp['display-name']); ?></option> <option value="<?php p($idp['url']); ?>"><?php p($idp['display-name']); ?></option>
<?php } ?> <?php } ?>
<?php if(isset($_['loginUrls']['directLogin'])) : ?> <?php if (isset($_['loginUrls']['directLogin'])) : ?>
<option value="<?php p($_['loginUrls']['directLogin']['url']); ?>"><?php p($_['loginUrls']['directLogin']['display-name']); ?></option> <option value="<?php p($_['loginUrls']['directLogin']['url']); ?>"><?php p($_['loginUrls']['directLogin']['display-name']); ?></option>
<?php endif; ?> <?php endif; ?>
</select> </select>
<?php } else { ?> <?php } else { ?>
<?php if(isset($_['loginUrls']['directLogin'])) : ?> <?php if (isset($_['loginUrls']['directLogin'])) : ?>
<div class="login-option"> <div class="login-option">
<a href="<?php p($_['loginUrls']['directLogin']['url']); ?>"><?php p($_['loginUrls']['directLogin']['display-name']); ?></a> <a href="<?php p($_['loginUrls']['directLogin']['url']); ?>"><?php p($_['loginUrls']['directLogin']['display-name']); ?></a>
</div> </div>

View file

@ -41,12 +41,10 @@ class FeatureContext implements Context {
'cookies' => $jar, 'cookies' => $jar,
'verify' => false, 'verify' => false,
'allow_redirects' => [ 'allow_redirects' => [
'referer' => true, 'referer' => true,
'track_redirects' => true, 'track_redirects' => true,
], ],
]); ]);
} }
/** @AfterScenario */ /** @AfterScenario */
@ -55,7 +53,7 @@ class FeatureContext implements Context {
'student1', 'student1',
]; ];
foreach($users as $user) { foreach ($users as $user) {
shell_exec( shell_exec(
sprintf( sprintf(
'sudo -u apache %s %s user:delete %s', 'sudo -u apache %s %s user:delete %s',
@ -66,7 +64,7 @@ class FeatureContext implements Context {
); );
} }
foreach($this->changedSettings as $setting) { foreach ($this->changedSettings as $setting) {
shell_exec( shell_exec(
sprintf( sprintf(
'sudo -u apache %s %s config:app:delete user_saml %s', 'sudo -u apache %s %s config:app:delete user_saml %s',
@ -135,10 +133,10 @@ class FeatureContext implements Context {
]; ];
// Remove everything after a comma in the URL since cookies are passed there // Remove everything after a comma in the URL since cookies are passed there
list($url['path'])=explode(';', $url['path']); [$url['path']] = explode(';', $url['path']);
foreach($paramsToCheck as $param) { foreach ($paramsToCheck as $param) {
if($targetUrl[$param] !== $url[$param]) { if ($targetUrl[$param] !== $url[$param]) {
throw new InvalidArgumentException( throw new InvalidArgumentException(
sprintf( sprintf(
'Expected %s for parameter %s, got %s', 'Expected %s for parameter %s, got %s',
@ -181,10 +179,9 @@ class FeatureContext implements Context {
$inputElements = $xpath->query('//input'); $inputElements = $xpath->query('//input');
if (is_object($inputElements)) { if (is_object($inputElements)) {
/** @var DOMElement $node */ /** @var DOMElement $node */
foreach($inputElements as $node) { foreach ($inputElements as $node) {
$postData[$node->getAttribute('name')] = $node->getAttribute('value'); $postData[$node->getAttribute('name')] = $node->getAttribute('value');
} }
} }
$this->response = $this->client->request( $this->response = $this->client->request(
@ -203,7 +200,7 @@ class FeatureContext implements Context {
* @param string $value * @param string $value
* @throws UnexpectedValueException * @throws UnexpectedValueException
*/ */
public function thUserValueShouldBe($key, $value) { public function thUserValueShouldBe($key, $value) {
$this->response = $this->client->request( $this->response = $this->client->request(
'GET', 'GET',
'http://localhost/ocs/v1.php/cloud/user', 'http://localhost/ocs/v1.php/cloud/user',
@ -223,7 +220,7 @@ class FeatureContext implements Context {
} }
$actualValue = $responseArray['data'][$key]; $actualValue = $responseArray['data'][$key];
if($actualValue !== $value) { if ($actualValue !== $value) {
throw new UnexpectedValueException( throw new UnexpectedValueException(
sprintf( sprintf(
'Expected %s as value but got %s', 'Expected %s as value but got %s',
@ -267,7 +264,7 @@ class FeatureContext implements Context {
$response = trim($response); $response = trim($response);
$expectedStringStart = "$uid`s last login: "; $expectedStringStart = "$uid`s last login: ";
if(substr($response, 0, strlen($expectedStringStart)) !== $expectedStringStart) { if (substr($response, 0, strlen($expectedStringStart)) !== $expectedStringStart) {
throw new UnexpectedValueException("Expected last login message, found instead '$response'"); throw new UnexpectedValueException("Expected last login message, found instead '$response'");
} }
} }
@ -275,7 +272,7 @@ class FeatureContext implements Context {
/** /**
* @Given The environment variable :key is set to :value * @Given The environment variable :key is set to :value
*/ */
public function theEnvironmentVariableIsSetTo($key, $value) { public function theEnvironmentVariableIsSetTo($key, $value) {
file_put_contents(__DIR__ . '/../../../../../../.htaccess', "\nSetEnv $key $value\n", FILE_APPEND); file_put_contents(__DIR__ . '/../../../../../../.htaccess', "\nSetEnv $key $value\n", FILE_APPEND);
} }
} }

View file

@ -25,10 +25,9 @@
namespace OCA\User_SAML\Tests\AppInfo; namespace OCA\User_SAML\Tests\AppInfo;
use OCA\User_SAML\AppInfo\Application; use OCA\User_SAML\AppInfo\Application;
use OCA\User_SAML\Controller\SAMLController;
use OCA\User_SAML\Middleware\OnlyLoggedInMiddleware; use OCA\User_SAML\Middleware\OnlyLoggedInMiddleware;
class ApplicationTest extends \Test\TestCase { class ApplicationTest extends \Test\TestCase {
/** @var Application */ /** @var Application */
protected $app; protected $app;
/** @var \OCP\AppFramework\IAppContainer */ /** @var \OCP\AppFramework\IAppContainer */
@ -49,7 +48,6 @@ class ApplicationTest extends \Test\TestCase {
return [ return [
['OnlyLoggedInMiddleware', OnlyLoggedInMiddleware::class], ['OnlyLoggedInMiddleware', OnlyLoggedInMiddleware::class],
]; ];
} }
/** /**

View file

@ -23,9 +23,9 @@ namespace OCA\User_SAML\Tests\AppInfo;
use Test\TestCase; use Test\TestCase;
class Test extends TestCase { class Test extends TestCase {
public function testFile() { public function testFile() {
$dir =__DIR__; $dir = __DIR__;
$routes = require_once __DIR__ . '/../../../appinfo/routes.php'; $routes = require_once __DIR__ . '/../../../appinfo/routes.php';
$expected = [ $expected = [

View file

@ -30,73 +30,72 @@ use OCP\IRequest;
use OCP\ISession; use OCP\ISession;
use OCP\IURLGenerator; use OCP\IURLGenerator;
class GetMetadataTest extends \Test\TestCase { class GetMetadataTest extends \Test\TestCase {
/** @var GetMetadata|\PHPUnit_Framework_MockObject_MockObject*/ /** @var GetMetadata|\PHPUnit_Framework_MockObject_MockObject*/
protected $GetMetadata; protected $GetMetadata;
/** @var IRequest|\PHPUnit_Framework_MockObject_MockObject */ /** @var IRequest|\PHPUnit_Framework_MockObject_MockObject */
private $request; private $request;
/** @var ISession|\PHPUnit_Framework_MockObject_MockObject */ /** @var ISession|\PHPUnit_Framework_MockObject_MockObject */
private $session; private $session;
/** @var SAMLSettings|\PHPUnit_Framework_MockObject_MockObject*/ /** @var SAMLSettings|\PHPUnit_Framework_MockObject_MockObject*/
private $samlSettings; private $samlSettings;
/** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
private $config; private $config;
/** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */ /** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */
private $urlGenerator; private $urlGenerator;
protected function setUp(): void { protected function setUp(): void {
$this->urlGenerator = $this->createMock(IURLGenerator::class); $this->urlGenerator = $this->createMock(IURLGenerator::class);
$this->config = $this->createMock(IConfig::class); $this->config = $this->createMock(IConfig::class);
$this->request = $this->createMock(IRequest::class); $this->request = $this->createMock(IRequest::class);
$this->session = $this->createMock(ISession::class); $this->session = $this->createMock(ISession::class);
$this->samlSettings = new SAMLSettings($this->urlGenerator, $this->samlSettings = new SAMLSettings($this->urlGenerator,
$this->config, $this->config,
$this->request, $this->request,
$this->session); $this->session);
$this->GetMetadata = new GetMetadata($this->samlSettings); $this->GetMetadata = new GetMetadata($this->samlSettings);
parent::setUp(); parent::setUp();
} }
public function testGetMetadata(){ public function testGetMetadata() {
$inputInterface = $this->createMock(InputInterface::class); $inputInterface = $this->createMock(InputInterface::class);
$outputInterface = $this->createMock(OutputInterface::class); $outputInterface = $this->createMock(OutputInterface::class);
$this->urlGenerator $this->urlGenerator
->expects($this->at(0)) ->expects($this->at(0))
->method('linkToRouteAbsolute') ->method('linkToRouteAbsolute')
->with('user_saml.SAML.base') ->with('user_saml.SAML.base')
->willReturn('https://nextcloud.com/base/'); ->willReturn('https://nextcloud.com/base/');
$this->urlGenerator $this->urlGenerator
->expects($this->at(1)) ->expects($this->at(1))
->method('linkToRouteAbsolute') ->method('linkToRouteAbsolute')
->with('user_saml.SAML.getMetadata') ->with('user_saml.SAML.getMetadata')
->willReturn('https://nextcloud.com/metadata/'); ->willReturn('https://nextcloud.com/metadata/');
$this->urlGenerator $this->urlGenerator
->expects($this->at(2)) ->expects($this->at(2))
->method('linkToRouteAbsolute') ->method('linkToRouteAbsolute')
->with('user_saml.SAML.assertionConsumerService') ->with('user_saml.SAML.assertionConsumerService')
->willReturn('https://nextcloud.com/acs/'); ->willReturn('https://nextcloud.com/acs/');
$this->config->expects($this->any())->method('getAppValue') $this->config->expects($this->any())->method('getAppValue')
->willReturnCallback(function($app, $key, $default) { ->willReturnCallback(function ($app, $key, $default) {
if ($key == 'idp-entityId') { if ($key == 'idp-entityId') {
return "dummy"; return "dummy";
} }
if ($key == 'idp-singleSignOnService.url') { if ($key == 'idp-singleSignOnService.url') {
return "https://example.com/sso"; return "https://example.com/sso";
} }
if ($key == 'idp-x509cert') { if ($key == 'idp-x509cert') {
return "DUMMY CERTIFICATE"; return "DUMMY CERTIFICATE";
} }
return $default; return $default;
}); });
$outputInterface->expects($this->once())->method('writeln') $outputInterface->expects($this->once())->method('writeln')
->with($this->stringContains('md:EntityDescriptor')); ->with($this->stringContains('md:EntityDescriptor'));
$this->invokePrivate($this->GetMetadata, 'execute', [$inputInterface, $outputInterface]); $this->invokePrivate($this->GetMetadata, 'execute', [$inputInterface, $outputInterface]);
} }
} }

View file

@ -42,7 +42,7 @@ use PHPUnit\Framework\MockObject\MockObject;
use OCP\Security\ICrypto; use OCP\Security\ICrypto;
use Test\TestCase; use Test\TestCase;
class SAMLControllerTest extends TestCase { class SAMLControllerTest extends TestCase {
/** @var UserResolver|\PHPUnit\Framework\MockObject\MockObject */ /** @var UserResolver|\PHPUnit\Framework\MockObject\MockObject */
protected $userResolver; protected $userResolver;
/** @var UserData|\PHPUnit\Framework\MockObject\MockObject */ /** @var UserData|\PHPUnit\Framework\MockObject\MockObject */
@ -87,15 +87,15 @@ class SAMLControllerTest extends TestCase {
$this->crypto = $this->createMock(ICrypto::class); $this->crypto = $this->createMock(ICrypto::class);
$this->l->expects($this->any())->method('t')->willReturnCallback( $this->l->expects($this->any())->method('t')->willReturnCallback(
function($param) { function ($param) {
return $param; return $param;
} }
); );
$this->config->expects($this->any())->method('getSystemValue') $this->config->expects($this->any())->method('getSystemValue')
->willReturnCallback(function($key, $default) { ->willReturnCallback(function ($key, $default) {
return $default; return $default;
}); });
$this->samlController = new SAMLController( $this->samlController = new SAMLController(
'user_saml', 'user_saml',
@ -112,7 +112,6 @@ class SAMLControllerTest extends TestCase {
$this->userData, $this->userData,
$this->crypto $this->crypto
); );
} }
public function testLoginWithInvalidAppValue() { public function testLoginWithInvalidAppValue() {
@ -217,11 +216,11 @@ class SAMLControllerTest extends TestCase {
$this->config->expects($this->any()) $this->config->expects($this->any())
->method('getAppValue') ->method('getAppValue')
->willReturnCallback(function (string $app, string $key) { ->willReturnCallback(function (string $app, string $key) {
if($app === 'user_saml') { if ($app === 'user_saml') {
if($key === 'type') { if ($key === 'type') {
return 'environment-variable'; return 'environment-variable';
} }
if($key === 'general-uid_mapping') { if ($key === 'general-uid_mapping') {
return 'uid'; return 'uid';
} }
} }
@ -261,7 +260,7 @@ class SAMLControllerTest extends TestCase {
->method('getEffectiveUid') ->method('getEffectiveUid')
->willReturn($userState > 0 ? 'MyUid' : ''); ->willReturn($userState > 0 ? 'MyUid' : '');
if(strpos($redirect, 'notProvisioned') !== false) { if (strpos($redirect, 'notProvisioned') !== false) {
$this->urlGenerator $this->urlGenerator
->expects($this->once()) ->expects($this->once())
->method('linkToRouteAbsolute') ->method('linkToRouteAbsolute')
@ -280,14 +279,14 @@ class SAMLControllerTest extends TestCase {
->with('MyUid') ->with('MyUid')
->willReturn($userState === 1); ->willReturn($userState === 1);
if(isset($samlUserData['uid']) && !($userState === 0 && $autoProvision === 0)) { if (isset($samlUserData['uid']) && !($userState === 0 && $autoProvision === 0)) {
/** @var IUser|MockObject $user */ /** @var IUser|MockObject $user */
$user = $this->createMock(IUser::class); $user = $this->createMock(IUser::class);
$im = $this->userResolver $im = $this->userResolver
->expects($this->once()) ->expects($this->once())
->method('findExistingUser') ->method('findExistingUser')
->with('MyUid'); ->with('MyUid');
if($autoProvision < 2) { if ($autoProvision < 2) {
$im->willReturn($user); $im->willReturn($user);
} else { } else {
$im->willThrowException(new NoUserFoundException()); $im->willThrowException(new NoUserFoundException());
@ -297,13 +296,13 @@ class SAMLControllerTest extends TestCase {
->expects($this->exactly((int)($autoProvision < 2))) ->expects($this->exactly((int)($autoProvision < 2)))
->method('updateLastLoginTimestamp'); ->method('updateLastLoginTimestamp');
if($userState === 0) { if ($userState === 0) {
$this->userResolver $this->userResolver
->expects($this->any()) ->expects($this->any())
->method('findExistingUserId') ->method('findExistingUserId')
->with('MyUid', true) ->with('MyUid', true)
->willThrowException(new NoUserFoundException()); ->willThrowException(new NoUserFoundException());
} else if($userState === 2) { } elseif ($userState === 2) {
$this->userResolver $this->userResolver
->expects($this->any()) ->expects($this->any())
->method('findExistingUserId') ->method('findExistingUserId')

View file

@ -24,13 +24,12 @@ namespace OCA\User_SAML\Tests\Middleware;
use Exception; use Exception;
use OCA\User_SAML\Middleware\OnlyLoggedInMiddleware; use OCA\User_SAML\Middleware\OnlyLoggedInMiddleware;
use OCP\AppFramework\Controller; use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Http\RedirectResponse;
use OCP\AppFramework\Utility\IControllerMethodReflector; use OCP\AppFramework\Utility\IControllerMethodReflector;
use OCP\IURLGenerator; use OCP\IURLGenerator;
use OCP\IUserSession; use OCP\IUserSession;
class OnlyLoggedInMiddlewareTest extends \Test\TestCase { class OnlyLoggedInMiddlewareTest extends \Test\TestCase {
/** @var IURLGenerator|\PHPUnit\Framework\MockObject\MockObject */ /** @var IURLGenerator|\PHPUnit\Framework\MockObject\MockObject */
protected $urlGenerator; protected $urlGenerator;
/** @var IControllerMethodReflector|\PHPUnit_Framework_MockObject_MockObject */ /** @var IControllerMethodReflector|\PHPUnit_Framework_MockObject_MockObject */

View file

@ -27,7 +27,7 @@ use OCP\IConfig;
use OCP\IL10N; use OCP\IL10N;
use OneLogin\Saml2\Constants; use OneLogin\Saml2\Constants;
class AdminTest extends \Test\TestCase { class AdminTest extends \Test\TestCase {
/** @var \OCA\User_SAML\Settings\Admin */ /** @var \OCA\User_SAML\Settings\Admin */
private $admin; private $admin;
/** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */ /** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */
@ -55,7 +55,7 @@ class AdminTest extends \Test\TestCase {
$this->l10n $this->l10n
->expects($this->any()) ->expects($this->any())
->method('t') ->method('t')
->will($this->returnCallback(function($text, $parameters = array()) { ->will($this->returnCallback(function ($text, $parameters = []) {
return vsprintf($text, $parameters); return vsprintf($text, $parameters);
})); }));

View file

@ -24,7 +24,7 @@ namespace OCA\User_SAML\Tests\Settings;
use OCP\IL10N; use OCP\IL10N;
use OCP\IURLGenerator; use OCP\IURLGenerator;
class SectionTest extends \Test\TestCase { class SectionTest extends \Test\TestCase {
/** @var \OCA\User_SAML\Settings\Section */ /** @var \OCA\User_SAML\Settings\Section */
private $section; private $section;
/** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */ /** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */

View file

@ -35,7 +35,7 @@ use OCP\IUser;
use OCP\IUserManager; use OCP\IUserManager;
use Test\TestCase; use Test\TestCase;
class UserBackendTest extends TestCase { class UserBackendTest extends TestCase {
/** @var UserData|\PHPUnit\Framework\MockObject\MockObject */ /** @var UserData|\PHPUnit\Framework\MockObject\MockObject */
private $userData; private $userData;
/** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
@ -72,7 +72,7 @@ class UserBackendTest extends TestCase {
} }
public function getMockedBuilder(array $mockedFunctions = []) { public function getMockedBuilder(array $mockedFunctions = []) {
if($mockedFunctions !== []) { if ($mockedFunctions !== []) {
$this->userBackend = $this->getMockBuilder(UserBackend::class) $this->userBackend = $this->getMockBuilder(UserBackend::class)
->setConstructorArgs([ ->setConstructorArgs([
$this->config, $this->config,
@ -307,5 +307,4 @@ class UserBackendTest extends TestCase {
->with('ExistingUser', 'New Displayname'); ->with('ExistingUser', 'New Displayname');
$this->userBackend->updateAttributes('ExistingUser', ['email' => 'new@example.com', 'displayname' => 'New Displayname', 'quota' => '']); $this->userBackend->updateAttributes('ExistingUser', ['email' => 'new@example.com', 'displayname' => 'New Displayname', 'quota' => '']);
} }
} }

View file

@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
/** /**
* @copyright Copyright (c) 2020 Arthur Schiwon <blizzz@arthur-schiwon.de> * @copyright Copyright (c) 2020 Arthur Schiwon <blizzz@arthur-schiwon.de>

View file

@ -25,7 +25,7 @@ if (!defined('PHPUNIT_RUN')) {
require_once __DIR__.'/../../../../lib/base.php'; require_once __DIR__.'/../../../../lib/base.php';
\OC::$loader->addValidRoot(\OC::$SERVERROOT . '/tests'); \OC::$loader->addValidRoot(\OC::$SERVERROOT . '/tests');
\OC_App::loadApp('user_saml'); \OC_App::loadApp('user_saml');
if(!class_exists('\PHPUnit\Framework\TestCase')) { if (!class_exists('\PHPUnit\Framework\TestCase')) {
require_once('PHPUnit/Autoload.php'); require_once('PHPUnit/Autoload.php');
} }
OC_Hook::clear(); OC_Hook::clear();