Skip to content
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
12 changes: 6 additions & 6 deletions action.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ function handle_login_form (&$event, $param) {
$href = $form->addTagOpen('a');
$href->attr('href', $this->_selfdo('caslogin'));
$form->addHTML($caslogo);
// Add remember me checkbox using addCheckbox
$form->addCheckbox('remember', $lang['remember_me']);
$form->addHTML($lang['btn_login']);
$form->addTagClose('a');
$form->addFieldsetClose();
Expand All @@ -91,8 +93,9 @@ function handle_login_form (&$event, $param) {
$event->data->_content = array(); // remove the login form

$event->data->insertElement(0,'<fieldset><legend>'.$this->getConf('name').'</legend>');
$event->data->insertElement(1,'<p style="text-align: center;"><a href="'.$this->_selfdo('caslogin').'"><div>'.$caslogo.'</div>'.$lang['btn_login'].'</a></p>');
$event->data->insertElement(2,'</fieldset>');
$event->data>insertElement(1, form_makeCheckboxField('remember', '1', $lang['remember_me'], 'remember', 'remember__me'));
$event->data->insertElement(2,'<p style="text-align: center;"><a href="'.$this->_selfdo('caslogin').'"><div>'.$caslogo.'</div>'.$lang['btn_login'].'</a></p>');
$event->data->insertElement(3,'</fieldset>');

//instead of removing, one could implement a local login here...
// if ($this->getConf('jshidelocal')) {
Expand All @@ -102,14 +105,11 @@ function handle_login_form (&$event, $param) {
// $event->data->replaceElement(3,'<fieldset><legend>'.$this->getConf('localname').'</legend>');
// }

$insertElement = 3;
if ($auth && $auth->canDo('modPass') && actionOK('resendpwd')) {
$event->data->insertElement($insertElement,'<p>'.$lang['pwdforget'].': <a href="'.wl($ID,'do=resendpwd').'" rel="nofollow" class="wikilink1">'.$lang['btn_resendpwd'].'</a></p>');
$event->data->insertElement(4,'<p>'.$lang['pwdforget'].': <a href="'.wl($ID,'do=resendpwd').'" rel="nofollow" class="wikilink1">'.$lang['btn_resendpwd'].'</a></p>');
}
}

}

}

function handle_caslogin () {
Expand Down
188 changes: 146 additions & 42 deletions auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ class auth_plugin_authplaincas extends DokuWiki_Auth_Plugin {
var $casuserfile = null;
var $localuserfile = NULL;

protected $rememberMeCookieName = 'DOKU_PLAINCAS_AUTH';
protected $rememberMeFileName = '/_plaincas_tokens.php';

/**
* Constructor
*
Expand Down Expand Up @@ -106,7 +109,7 @@ public function __construct() {
$this->cando['logout'] = true;
$this->cando['logoff'] = true;

// The default options which need to be set in the settins file.
// The default options which need to be set in the settings file.
$defaults = array(
// 'server' => 'galaxy.esn.org',
// 'rootcas' => '/cas',
Expand Down Expand Up @@ -269,78 +272,179 @@ public function logOff() {
session_destroy();
unset($_SESSION['phpCAS']);
}

// Clear RememberMe data
setcookie($this->rememberMeCookieName, '', time() - 3600, DOKU_BASE);
$this->clearPersistentToken($_SERVER['REMOTE_USER']);
}

protected function clearPersistentToken($user) {
global $conf;
$tokenFile = $conf['metadir'].$this->rememberMeFileName;

if (file_exists($tokenFile)) {
$tokens = include($tokenFile);
if (isset($tokens[$user])) {
unset($tokens[$user]);
$content = "<?php return " . var_export($tokens, true) . ";";
io_saveFile($tokenFile, $content);
}
}
}

function trustExternal ($user,$pass,$sticky=false)
{
global $USERINFO;
$sticky ? $sticky = true : $sticky = false; //sanity check

if (phpCAS::isAuthenticated() || ( $this->_getOption('autologin') && phpCAS::checkAuthentication() )) {
$remoteUser = $this->checkRememberedLogin();
if ($remoteUser == null) { // RememberMe cookie not available
if (phpCAS::isAuthenticated() || ( $this->_getOption('autologin') && phpCAS::checkAuthentication() )) {
$remoteUser = phpCAS::getUser(); // User logged in
} else {
return false; // Not logged in
}
$this->setAuthCookie($remoteUser);

}

$this->_userInfo = $this->getUserData($remoteUser);
// msg(print_r($this->_userInfo,true) . __LINE__);

// Create the user if he doesn't exist
if ($this->_userInfo === false) {
$attributes = plaincas_user_attributes(phpCAS::getAttributes());
$this->_userInfo = array(
'uid' => $remoteUser,
'name' => $attributes['name'],
'mail' => $attributes['mail']
);

$this->_assembleGroups($remoteUser);
$this->_saveUserGroup();
$this->_saveUserInfo();

$remoteUser = phpCAS::getUser();
$this->_userInfo = $this->getUserData($remoteUser);
// msg(print_r($this->_userInfo,true) . __LINE__);

// Create the user if he doesn't exist
if ($this->_userInfo === false) {
$attributes = plaincas_user_attributes(phpCAS::getAttributes());
$USERINFO = $this->_userInfo;
$_SESSION[DOKU_COOKIE]['auth']['user'] = $USERINFO['uid'];
$_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
$_SERVER['REMOTE_USER'] = $USERINFO['uid'];
} else { // User exists, check for updates
$this->_userInfo['uid'] = $remoteUser;
$this->_assembleGroups($remoteUser);

$attributes = plaincas_user_attributes(phpCAS::getAttributes());

if ($this->_userInfo['grps'] != $this->_userInfo['tmp_grps'] ||
$attributes['name'] !== $this->_userInfo['name'] ||
$attributes['mail'] !== $this->_userInfo['mail']
) {
//msg("new roles, email, or name");
$this->deleteUsers(array($remoteUser));
$this->_userInfo = array(
'uid' => $remoteUser,
'name' => $attributes['name'],
'mail' => $attributes['mail']
);

$this->_assembleGroups($remoteUser);
$this->_saveUserGroup();
$this->_saveUserInfo();
}

// msg(print_r($this->_userInfo,true) . __LINE__);

$USERINFO = $this->_userInfo;
$_SESSION[DOKU_COOKIE]['auth']['user'] = $USERINFO['uid'];
$_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
$_SERVER['REMOTE_USER'] = $USERINFO['uid'];
return true;
$USERINFO = $this->_userInfo;
$_SESSION[DOKU_COOKIE]['auth']['user'] = $USERINFO['uid'];
$_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
$_SERVER['REMOTE_USER'] = $USERINFO['uid'];
}

// User exists, check for updates
} else {
$this->_userInfo['uid'] = $remoteUser;
$this->_assembleGroups($remoteUser);
return true;
}

$attributes = plaincas_user_attributes(phpCAS::getAttributes());

if ($this->_userInfo['grps'] != $this->_userInfo['tmp_grps'] ||
$attributes['name'] !== $this->_userInfo['name'] ||
$attributes['mail'] !== $this->_userInfo['mail']
) {
//msg("new roles, email, or name");
$this->deleteUsers(array($remoteUser));
$this->_userInfo = array(
'uid' => $remoteUser,
'name' => $attributes['name'],
'mail' => $attributes['mail']
);
$this->_assembleGroups($remoteUser);
$this->_saveUserGroup();
$this->_saveUserInfo();
protected function checkRememberedLogin() {
if (isset($_COOKIE[$this->rememberMeCookieName])) {
try {
$data = json_decode(base64_decode($_COOKIE[$this->rememberMeCookieName]), true);
if ($data &&
isset($data['user']) &&
isset($data['token']) &&
isset($data['expires']) &&
$data['expires'] > time()) {
if ($this->verifyPersistentToken($data['user'], $data['token'])) {
return $data['user'];
}
}
} catch (Exception $e) {
msg($e->getMessage(), -1);
}

$USERINFO = $this->_userInfo;
$_SESSION[DOKU_COOKIE]['auth']['user'] = $USERINFO['uid'];
$_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
$_SERVER['REMOTE_USER'] = $USERINFO['uid'];
// Clear invalid cookie
setcookie($this->rememberMeCookieName, '', time() - 3600, DOKU_BASE);
}
return null;
}

protected function verifyPersistentToken($user, $token) {
global $conf;
$tokenFile = $conf['metadir'].$this->rememberMeFileName;

if (file_exists($tokenFile)) {
$tokens = include($tokenFile);
if (isset($tokens[$user]) &&
$tokens[$user]['token'] === $token &&
$tokens[$user]['expires'] > time()) {
return true;
}

}
// else{
// }

return false;
}

protected function setAuthCookie($user) {
$cookie_lifetime = time() + 30 * 24 * 60 * 60; // 30 days

$token = bin2hex(random_bytes(32));

$cookie_data = base64_encode(json_encode([
'user' => $user,
'token' => $token,
'expires' => $cookie_lifetime
]));

setcookie(
$this->rememberMeCookieName,
$cookie_data,
[
'expires' => $cookie_lifetime,
'path' => DOKU_BASE,
'secure' => (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'),
'httponly' => true,
'samesite' => 'Strict',
]
);

// Store token in metadata
$this->storePersistentToken($user, $token, $cookie_lifetime);
}

protected function storePersistentToken($user, $token, $cookie_lifetime) {
global $conf;
$tokenFile = $conf['metadir'].$this->rememberMeFileName;

$tokens = array();
if (file_exists($tokenFile)) {
$tokens = include($tokenFile);
}

$tokens[$user] = [
'token' => $token,
'expires' => $cookie_lifetime
];

$content = "<?php return " . var_export($tokens, true) . ";";
io_saveFile($tokenFile, $content);
}


function _assembleGroups($remoteUser) {

Expand Down
3 changes: 3 additions & 0 deletions lang/en/lang.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php

$lang['remember_me'] = 'Remember me';