mirror of
https://github.com/netzbegruenung/user_saml.git
synced 2024-05-11 05:06:06 +02:00
Allow authentication for specific implementations of PKI #223
This commit is contained in:
parent
37b89e4c32
commit
c3caa02a6e
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,3 +1,6 @@
|
|||
.buildpath
|
||||
.project
|
||||
.settings/
|
||||
3rdparty/vendor/onelogin/php-saml/certs/
|
||||
3rdparty/vendor/onelogin/php-saml/demo1/
|
||||
3rdparty/vendor/onelogin/php-saml/demo2/
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
use OCA\User_SAML\Strategies\UserBackend\StrategyManager;
|
||||
/**
|
||||
* @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch>
|
||||
*
|
||||
|
@ -39,7 +40,10 @@ $samlSettings = new \OCA\User_SAML\SAMLSettings(
|
|||
$request
|
||||
);
|
||||
|
||||
$userBackend = new \OCA\User_SAML\UserBackend(
|
||||
$userBackendStrategy = StrategyManager::getStrategy(true);
|
||||
$userBackend = (is_null($userBackendStrategy) ? '\OCA\User_SAML\UserBackend' : $userBackendStrategy);
|
||||
|
||||
$userBackend = new $userBackend(
|
||||
$config,
|
||||
$urlGenerator,
|
||||
\OC::$server->getSession(),
|
||||
|
|
|
@ -35,6 +35,8 @@ use OCP\IURLGenerator;
|
|||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use OCP\IUserSession;
|
||||
use OCA\User_SAML\Strategies\Authentication\StrategyManager;
|
||||
use OCA\User_SAML\AppInfo\Application;
|
||||
|
||||
class SAMLController extends Controller {
|
||||
/** @var ISession */
|
||||
|
@ -148,6 +150,10 @@ class SAMLController extends Controller {
|
|||
* @throws \Exception
|
||||
*/
|
||||
public function login() {
|
||||
if (($strategy = StrategyManager::getStrategy()) != null)
|
||||
{
|
||||
return $strategy->login($this->config, $this->urlGenerator, $this->logger, $this->userManager, $this->userBackend, $this->session);
|
||||
}
|
||||
$type = $this->config->getAppValue($this->appName, 'type');
|
||||
switch($type) {
|
||||
case 'saml':
|
||||
|
@ -388,5 +394,4 @@ class SAMLController extends Controller {
|
|||
$directUrl = $this->urlGenerator->linkToRouteAbsolute('core.login.tryLogin', ['direct' => '1']);
|
||||
return $directUrl;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
55
lib/Strategies/AbstractStrategyManager.php
Normal file
55
lib/Strategies/AbstractStrategyManager.php
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Flávio Gomes da Silva Lisboa <flavio.lisboa@fgsl.eti.br>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\User_SAML\Strategies;
|
||||
|
||||
abstract class AbstractStrategyManager {
|
||||
/**
|
||||
* @param string $dir
|
||||
* @param string $onlyClassName
|
||||
* @return object|NULL
|
||||
*/
|
||||
public static function getStrategy($onlyClassName = false)
|
||||
{
|
||||
$dir = static::getStrategyDir();
|
||||
$files = array_diff(scandir($dir), ['..', '.']);
|
||||
foreach($files as $file){
|
||||
// Only one strategy is expected, then first matched is returned
|
||||
if (substr($file,-12) === 'Strategy.php' && substr($file,0,8) !== 'Abstract'){
|
||||
$namespace = get_called_class();
|
||||
$tokens = explode('\\', $namespace);
|
||||
unset($tokens[count($tokens)-1]);
|
||||
$namespace = implode('\\', $tokens);
|
||||
$strategy = $namespace . '\\' . substr($file,0,strlen($file)-4);
|
||||
return ($onlyClassName ? $strategy : new $strategy());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getStrategyDir()
|
||||
{
|
||||
throw new \NotFoundException(get_called_class() . ' must implement ' . __METHOD__);
|
||||
}
|
||||
}
|
178
lib/Strategies/Authentication/AbstractPKIStrategy.php
Normal file
178
lib/Strategies/Authentication/AbstractPKIStrategy.php
Normal file
|
@ -0,0 +1,178 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Flávio Gomes da Silva Lisboa <flavio.lisboa@fgsl.eti.br>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
namespace OCA\User_SAML\Strategies\Authentication;
|
||||
|
||||
use OCA\User_SAML\Exceptions\NoUserFoundException;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\IConfig;
|
||||
use OCP\ILogger;
|
||||
use OCP\ISession;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IUserManager;
|
||||
use OCP\IUserBackend;
|
||||
|
||||
/**
|
||||
* @link http://iti.gov.br/images/repositorio/legislacao/documentos-principais/DOC-ICP-04.01_-_versao_3.2_ATRIBUICAO_DE_OID_NA_ICP-BRASIL.pdf
|
||||
*/
|
||||
abstract class AbstractPKIStrategy implements StrategyInterface {
|
||||
/**
|
||||
* OID for required attributes
|
||||
* @var string
|
||||
*/
|
||||
protected $OIDRequiredAttribute;
|
||||
/**
|
||||
* name of uid attribute
|
||||
* @var string
|
||||
*/
|
||||
protected $certUidAttribute;
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
*
|
||||
* @see \OCA\User_SAML\Strategies\Authentication\StrategyInterface::login()
|
||||
*/
|
||||
public function login(IConfig $config, IURLGenerator $urlGenerator, ILogger $logger, IUserManager $userManager, IUserBackend $userBackend, ISession $session) {
|
||||
$ssoUrl = $urlGenerator->getAbsoluteURL ( '/' );
|
||||
$uidMapping = $config->getAppValue ( 'user_saml', 'general-uid_mapping', 'SSL_CLIENT_CERT');
|
||||
|
||||
// receives certificate
|
||||
$cert = "";
|
||||
if (is_array ( $_SERVER [$uidMapping] )) {
|
||||
$cert = $_SERVER [$uidMapping] [0];
|
||||
} else {
|
||||
$cert = $_SERVER [$uidMapping];
|
||||
}
|
||||
if (empty ( $cert )) {
|
||||
$logger->error ( 'Cert "' . $cert . '" is not a valid certificate', [
|
||||
'app' => $this->appName
|
||||
] );
|
||||
throw new \InvalidArgumentException ( 'No valid cert given, please check your configuration' . $cert );
|
||||
}
|
||||
try {
|
||||
// extracts attribute from certificate mapping
|
||||
$PKIData = $this->parsePKIData ( $cert );
|
||||
$certUid = $PKIData [$this->OIDRequiredAttribute] [$this->certUidAttribute];
|
||||
|
||||
// provide user from a search. Certificate attribute must exist in user search filters
|
||||
$users = $userManager->search ( $certUid );
|
||||
|
||||
// recover nextcloud name of user
|
||||
$listKeys = array_keys ( $users );
|
||||
$nextcloud_uid = '';
|
||||
if (isset ( $listKeys [0] )) {
|
||||
$nextcloud_uid = $listKeys [0];
|
||||
}
|
||||
|
||||
if (!isset ( $nextcloud_uid )) {
|
||||
throw new NoUserFoundException ('Nextcloud uid not found');
|
||||
}
|
||||
// create user session
|
||||
$_SERVER [$uidMapping] = $nextcloud_uid;
|
||||
$session->set ( 'user_saml.samlUserData', $_SERVER );
|
||||
$user = $userManager->get ( $userBackend->getCurrentUserId () );
|
||||
if (! ($user instanceof IUser)) {
|
||||
throw new NoUserFoundException();
|
||||
}
|
||||
$user->updateLastLoginTimestamp ();
|
||||
} catch ( NoUserFoundException $e ) {
|
||||
$ssoUrl = $urlGenerator->linkToRouteAbsolute ( 'user_saml.SAML.notProvisioned' );
|
||||
}
|
||||
|
||||
return new Http\RedirectResponse ( $ssoUrl );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $certificate
|
||||
* @return boolean|Ambigous <multitype:, string>
|
||||
*/
|
||||
abstract protected function parsePKIData($certificate);
|
||||
|
||||
/**
|
||||
* @param string $oid
|
||||
* @return string
|
||||
*/
|
||||
protected function oid2Hex($oid) {
|
||||
$abBinary = array ();
|
||||
$parts = explode ( '.', $oid );
|
||||
$n = 0;
|
||||
$b = 0;
|
||||
|
||||
for($n = 0; $n < count ( $parts ); $n ++) {
|
||||
if ($n == 0) {
|
||||
$b = 40 * $parts [$n];
|
||||
} elseif ($n == 1) {
|
||||
$b += $parts [$n];
|
||||
$abBinary [] = $b;
|
||||
} else {
|
||||
$abBinary = $this->xBase128 ( $abBinary, $parts [$n], 1 );
|
||||
}
|
||||
}
|
||||
|
||||
$value = chr ( 0x06 ) . chr ( count ( $abBinary ) );
|
||||
foreach ( $abBinary as $item ) {
|
||||
$value .= chr ( $item );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $ab
|
||||
* @param integer $q
|
||||
* @param boolean $flag
|
||||
* @return Ambigous <boolean, unknown>
|
||||
*/
|
||||
protected function xBase128(array $ab, $q, $flag) {
|
||||
$abc = $ab;
|
||||
if ($q > 127) {
|
||||
$abc = $this->xBase128 ( $abc, floor ( $q / 128 ), 0 );
|
||||
}
|
||||
|
||||
$q = $q % 128;
|
||||
if ($flag) {
|
||||
$abc [] = $q;
|
||||
} else {
|
||||
$abc [] = 0x80 | $q;
|
||||
}
|
||||
|
||||
return $abc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $pemCertificate
|
||||
* @return string
|
||||
*/
|
||||
protected function pem2Der($pemCertificate) {
|
||||
$aux = explode ( chr ( 0x0A ), $pemCertificate );
|
||||
$derCertificate = '';
|
||||
foreach ( $aux as $i ) {
|
||||
if ($i != '') {
|
||||
if (substr ( $i, 0, 5 ) !== '-----') {
|
||||
$derCertificate .= $i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return base64_decode ( $derCertificate );
|
||||
}
|
||||
}
|
43
lib/Strategies/Authentication/StrategyInterface.php
Normal file
43
lib/Strategies/Authentication/StrategyInterface.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Flávio Gomes da Silva Lisboa <flavio.lisboa@fgsl.eti.br>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\User_SAML\Strategies\Authentication;
|
||||
|
||||
use OCP\IConfig;
|
||||
use OCP\ILogger;
|
||||
use OCP\ISession;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IUserManager;
|
||||
use OCP\IUserBackend;
|
||||
|
||||
interface StrategyInterface {
|
||||
/**
|
||||
* @param IConfig $config
|
||||
* @param IURLGenerator $urlGenerator
|
||||
* @param ILogger $logger
|
||||
* @param IUserManager $userManager
|
||||
* @param UserBackend $userBackend
|
||||
* @param ISession $session
|
||||
* @return Http\RedirectResponse
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function login(IConfig $config, IURLGenerator $urlGenerator, ILogger $logger, IUserManager $userManager, IUserBackend $userBackend, ISession $session);
|
||||
}
|
34
lib/Strategies/Authentication/StrategyManager.php
Normal file
34
lib/Strategies/Authentication/StrategyManager.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Flávio Gomes da Silva Lisboa <flavio.lisboa@fgsl.eti.br>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\User_SAML\Strategies\Authentication;
|
||||
|
||||
use OCA\User_SAML\Strategies\AbstractStrategyManager;
|
||||
|
||||
class StrategyManager extends AbstractStrategyManager {
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getStrategyDir()
|
||||
{
|
||||
return __DIR__;
|
||||
}
|
||||
}
|
82
lib/Strategies/UserBackend/StrategyInterface.php
Normal file
82
lib/Strategies/UserBackend/StrategyInterface.php
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Flávio Gomes da Silva Lisboa <flavio.lisboa@fgsl.eti.br>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\User_SAML\Strategies\UserBackend;
|
||||
|
||||
interface StrategyInterface {
|
||||
|
||||
/**
|
||||
* delete a user
|
||||
* @param string $uid The username of the user to delete
|
||||
* @return bool
|
||||
* @since 4.5.0
|
||||
*/
|
||||
public function deleteUser($uid);
|
||||
|
||||
/**
|
||||
* Get a list of all users
|
||||
*
|
||||
* @param string $search
|
||||
* @param null|int $limit
|
||||
* @param null|int $offset
|
||||
* @return string[] an array of all uids
|
||||
* @since 4.5.0
|
||||
*/
|
||||
public function getUsers($search = '', $limit = null, $offset = null);
|
||||
|
||||
/**
|
||||
* check if a user exists
|
||||
* @param string $uid the username
|
||||
* @return boolean
|
||||
* @since 4.5.0
|
||||
*/
|
||||
public function userExists($uid);
|
||||
|
||||
public function setDisplayName($uid, $displayName);
|
||||
|
||||
/**
|
||||
* Get display name of the user
|
||||
*
|
||||
* @param string $uid user ID of the user
|
||||
* @return string display name
|
||||
* @since 4.5.0
|
||||
*/
|
||||
public function getDisplayName($uid);
|
||||
|
||||
/**
|
||||
* Get a list of all display names and user ids.
|
||||
*
|
||||
* @param string $search
|
||||
* @param string|null $limit
|
||||
* @param string|null $offset
|
||||
* @return array an array of all displayNames (value) and the corresponding uids (key)
|
||||
* @since 4.5.0
|
||||
*/
|
||||
public function getDisplayNames($search = '', $limit = null, $offset = null);
|
||||
|
||||
/**
|
||||
* In case the user has been authenticated by Apache true is returned.
|
||||
*
|
||||
* @return boolean whether Apache reports a user as currently logged in.
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function isSessionActive();
|
||||
}
|
34
lib/Strategies/UserBackend/StrategyManager.php
Normal file
34
lib/Strategies/UserBackend/StrategyManager.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Flávio Gomes da Silva Lisboa <flavio.lisboa@fgsl.eti.br>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\User_SAML\Strategies\UserBackend;
|
||||
|
||||
use OCA\User_SAML\Strategies\AbstractStrategyManager;
|
||||
|
||||
class StrategyManager extends AbstractStrategyManager {
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getStrategyDir()
|
||||
{
|
||||
return __DIR__;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,10 @@
|
|||
<?php
|
||||
script('user_saml', 'admin');
|
||||
style('user_saml', 'admin');
|
||||
|
||||
$customTemplate = __DIR__ . DIRECTORY_SEPARATOR . 'custom' . DIRECTORY_SEPARATOR . basename(__FILE__);
|
||||
if (file_exists($customTemplate)):
|
||||
include $customTemplate;
|
||||
else:
|
||||
script('user_saml', 'admin');
|
||||
style('user_saml', 'admin');
|
||||
/** @var array $_ */
|
||||
?>
|
||||
<form id="user-saml" class="section" action="#" method="post" data-type="<?php p($_['type']) ?>">
|
||||
|
@ -136,3 +139,6 @@ style('user_saml', 'admin');
|
|||
<span class="success hidden" id="user-saml-settings-complete"><?php p($l->t('Metadata valid')) ?></span>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
10
templates/custom/README.md
Normal file
10
templates/custom/README.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
Customized templates
|
||||
====================
|
||||
|
||||
Here you can custom content of templates.
|
||||
|
||||
It's enough to create a file with the same name of template, and it will be used instead of former file.
|
||||
|
||||
For instance, you want to customize notProvisioned.php. Create a notProvisioned.php inside folder custom and fill it with content that you need.
|
||||
|
||||
|
15
templates/error.php
Normal file
15
templates/error.php
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
$customTemplate = __DIR__ . DIRECTORY_SEPARATOR . 'custom' . DIRECTORY_SEPARATOR . basename(__FILE__);
|
||||
if (file_exists($customTemplate)):
|
||||
include $customTemplate;
|
||||
else:
|
||||
?>
|
||||
<ul>
|
||||
<li class="error">
|
||||
<?php p($l->t('Authentication Error')) ?><br>
|
||||
<p class="hint"><?php p($_['message']) ?></p>
|
||||
</li>
|
||||
</ul>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
|
@ -1,6 +1,15 @@
|
|||
<?php
|
||||
$customTemplate = __DIR__ . DIRECTORY_SEPARATOR . 'custom' . DIRECTORY_SEPARATOR . basename(__FILE__);
|
||||
if (file_exists($customTemplate)):
|
||||
include $customTemplate;
|
||||
else:
|
||||
?>
|
||||
<ul>
|
||||
<li class="error">
|
||||
<?php p($l->t('Account not provisioned.')) ?><br>
|
||||
<p class="hint"><?php p($l->t('Your account is not provisioned, access to this service is thus not possible.')) ?></p>
|
||||
</li>
|
||||
</ul>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
|
@ -1,10 +1,13 @@
|
|||
<?php
|
||||
style('user_saml', 'selectUserBackEnd');
|
||||
$customTemplate = __DIR__ . DIRECTORY_SEPARATOR . 'custom' . DIRECTORY_SEPARATOR . basename(__FILE__);
|
||||
if (file_exists($customTemplate)):
|
||||
include $customTemplate;
|
||||
else:
|
||||
style('user_saml', 'selectUserBackEnd');
|
||||
|
||||
/** @var array $_ */
|
||||
/** @var $l \OCP\IL10N */
|
||||
?>
|
||||
|
||||
<div id="saml-select-user-back-end">
|
||||
|
||||
<h1>Choose login option:</h1>
|
||||
|
@ -18,3 +21,6 @@ style('user_saml', 'selectUserBackEnd');
|
|||
</div>
|
||||
|
||||
</div>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
Loading…
Reference in a new issue