Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvement support SingleSignout #88

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
<nextcloud min-version="14" max-version="18"/>
</dependencies>

<background-jobs>
<job>OCA\UserCAS\BackgroundJob\TicketCleanupJob</job>
</background-jobs>

<commands>
<command>OCA\UserCAS\Command\CreateUser</command>
<command>OCA\UserCAS\Command\UpdateUser</command>
Expand Down
46 changes: 46 additions & 0 deletions lib/BackgroundJob/TicketCleanupJob.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php
/**
* ownCloud - user_cas
*
* @author Vincent Laffargue <[email protected]>
* @copyright Vincent Laffargue <[email protected]>
*
* 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\BackgroundJob;

use \OC;
use \OCA\UserCAS\Service\PhpCasTicketManager\PhpCasTicketManager;
use \OCP\BackgroundJob\Job;

/**
* Class TicketCleanupJob
*
* @package OCA\UserCAS\BackgroundJob
*
* @author Vincent Laffargue <[email protected]>
* @copyright Vincent Laffargue <[email protected]>
*
* @since 1.8.4
*/
class TicketCleanupJob extends Job {

protected function run($argument) {
/* @var $provider IProvider */
$phpCasTicketManager = new PhpCasTicketManager();
$phpCasTicketManager->deleteTicketWithoutValideToken();
}
}
3 changes: 1 addition & 2 deletions lib/Hooks/UserHooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -375,13 +375,12 @@ public function postLogin($uid, $password)
}

/**
* Logout hook method.
* postLogout hook method.
*
* @return boolean
*/
public function postLogout()
{

if (!$this->appService->isCasInitialized()) {

try {
Expand Down
62 changes: 62 additions & 0 deletions lib/Migration/Version104000Date20200401000002.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

/**
* ownCloud - user_cas
*
* @author Vincent Laffargue <[email protected]>
* @copyright Vincent Laffargue <[email protected]>
*
* 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/>.
*
*/

declare(strict_types=1);

namespace OCA\UserCAS\Migration;

use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\SimpleMigrationStep;
use OCP\Migration\IOutput;

class Version104000Date20200401000002 extends SimpleMigrationStep {
public function name(): string {
return 'Add user_cas_ticket table';
}

public function description(): string {
return 'Adds table to store relation ticket <=> token';
}

public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();

if (!$schema->hasTable('user_cas_ticket')) {
$table = $schema->createTable('user_cas_ticket');
$table->addColumn('ticket', 'string', [
'notnull' => true,
'length' => 200,
]);
$table->addColumn('token', 'string', [
'notnull' => true,
'length' => 200,
]);
$table->setPrimaryKey(['ticket']);
$table->addUniqueIndex(['token'], 'index_token');
}

return $schema;
}
}
77 changes: 22 additions & 55 deletions lib/Service/AppService.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

use OC\Authentication\Token\IToken;
use OCA\UserCAS\Exception\PhpCas\PhpUserCasLibraryNotFoundException;
use OCA\UserCAS\Service\PhpCasTicketManager\PhpCasTicketManager;
use \OCP\IConfig;
use \OCP\IUserSession;
use \OCP\IUserManager;
Expand Down Expand Up @@ -58,6 +59,11 @@ class AppService
*/
private $loggingService;

/**
* @var \OCA\UserCAS\Service\PhpCasTicketManager\PhpCasTicketManager $phpCasTicketManager
*/
private $phpCasTicketManager;

/**
* @var \OCP\IUserManager $userManager
*/
Expand Down Expand Up @@ -191,6 +197,7 @@ public function __construct($appName, IConfig $config, LoggingService $loggingSe
$this->userManager = $userManager;
$this->userSession = $userSession;
$this->urlGenerator = $urlGenerator;
$this->phpCasTicketManager = new PhpCasTicketManager($config, $userSession->getSession());;
$this->casInitialized = FALSE;
}

Expand Down Expand Up @@ -290,6 +297,12 @@ public function init()
\phpCAS::setVerbose(TRUE);
}

//Ticket not register in phpCAS but needed in order to know what ticket for what user...
//For SingleSignOut
//Warning : function saveTicket must be before \phpCAS::proxy or \phpCAS::client because these functions unset ticket
if (!$this->casDisableSinglesignout) {
$this->phpCasTicketManager->saveTicket();
}

# Initialize client
if ($this->casUseProxy) {
Expand All @@ -303,7 +316,7 @@ public function init()
# Handle SingleSignout requests
if (!$this->casDisableSinglesignout) {

\phpCAS::setSingleSignoutCallback([$this, 'casSingleSignOut']);
\phpCAS::setSingleSignoutCallback([$this->phpCasTicketManager, 'invalidateTokenByTicket']);
\phpCAS::handleLogoutRequests(true, $this->casHandleLogoutServers);
}

Expand Down Expand Up @@ -893,60 +906,6 @@ private function isIpInLocalRange($internalIps)
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 <[email protected]>
*
* @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

/**
Expand Down Expand Up @@ -988,4 +947,12 @@ public function getCasPath()
{
return $this->casPath;
}

/**
* @return boolean
*/
public function getCasDisableSinglesignout()
{
return $this->casDisableSinglesignout;
}
}
Loading