aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/inc/auth.php
diff options
context:
space:
mode:
Diffstat (limited to 'inc/auth.php')
-rw-r--r--inc/auth.php537
1 files changed, 289 insertions, 248 deletions
diff --git a/inc/auth.php b/inc/auth.php
index 1dd2b2bdd..a18eab1e3 100644
--- a/inc/auth.php
+++ b/inc/auth.php
@@ -1,4 +1,5 @@
<?php
+
/**
* Authentication library
*
@@ -9,6 +10,8 @@
* @author Andreas Gohr <andi@splitbrain.org>
*/
+use phpseclib\Crypt\AES;
+use dokuwiki\Utf8\PhpString;
use dokuwiki\Extension\AuthPlugin;
use dokuwiki\Extension\Event;
use dokuwiki\Extension\PluginController;
@@ -27,7 +30,8 @@ use dokuwiki\Subscriptions\RegistrationSubscriptionSender;
* @triggers AUTH_LOGIN_CHECK
* @return bool
*/
-function auth_setup() {
+function auth_setup()
+{
global $conf;
/* @var AuthPlugin $auth */
global $auth;
@@ -37,9 +41,9 @@ function auth_setup() {
global $lang;
/* @var PluginController $plugin_controller */
global $plugin_controller;
- $AUTH_ACL = array();
+ $AUTH_ACL = [];
- if(!$conf['useacl']) return false;
+ if (!$conf['useacl']) return false;
// try to load auth backend from plugins
foreach ($plugin_controller->getList('auth') as $plugin) {
@@ -49,7 +53,7 @@ function auth_setup() {
}
}
- if(!isset($auth) || !$auth){
+ if (!$auth instanceof AuthPlugin) {
msg($lang['authtempfail'], -1);
return false;
}
@@ -64,14 +68,14 @@ function auth_setup() {
// do the login either by cookie or provided credentials XXX
$INPUT->set('http_credentials', false);
- if(!$conf['rememberme']) $INPUT->set('r', false);
+ if (!$conf['rememberme']) $INPUT->set('r', false);
// Populate Basic Auth user/password from Authorization header
// Note: with FastCGI, data is in REDIRECT_HTTP_AUTHORIZATION instead of HTTP_AUTHORIZATION
$header = $INPUT->server->str('HTTP_AUTHORIZATION') ?: $INPUT->server->str('REDIRECT_HTTP_AUTHORIZATION');
- if(preg_match( '~^Basic ([a-z\d/+]*={0,2})$~i', $header, $matches )) {
+ if (preg_match('~^Basic ([a-z\d/+]*={0,2})$~i', $header, $matches)) {
$userpass = explode(':', base64_decode($matches[1]));
- list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = $userpass;
+ [$_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']] = $userpass;
}
// if no credentials were given try to use HTTP auth (for SSO)
@@ -88,19 +92,19 @@ function auth_setup() {
}
$ok = null;
- if (!is_null($auth) && $auth->canDo('external')) {
+ if ($auth instanceof AuthPlugin && $auth->canDo('external')) {
$ok = $auth->trustExternal($INPUT->str('u'), $INPUT->str('p'), $INPUT->bool('r'));
}
if ($ok === null) {
// external trust mechanism not in place, or returns no result,
// then attempt auth_login
- $evdata = array(
+ $evdata = [
'user' => $INPUT->str('u'),
'password' => $INPUT->str('p'),
'sticky' => $INPUT->bool('r'),
'silent' => $INPUT->bool('http_credentials')
- );
+ ];
Event::createAndTrigger('AUTH_LOGIN_CHECK', $evdata, 'auth_login_wrapper');
}
@@ -117,38 +121,39 @@ function auth_setup() {
*
* @return array
*/
-function auth_loadACL() {
+function auth_loadACL()
+{
global $config_cascade;
global $USERINFO;
/* @var Input $INPUT */
global $INPUT;
- if(!is_readable($config_cascade['acl']['default'])) return array();
+ if (!is_readable($config_cascade['acl']['default'])) return [];
$acl = file($config_cascade['acl']['default']);
- $out = array();
- foreach($acl as $line) {
+ $out = [];
+ foreach ($acl as $line) {
$line = trim($line);
- if(empty($line) || ($line[0] == '#')) continue; // skip blank lines & comments
- list($id,$rest) = preg_split('/[ \t]+/',$line,2);
+ if (empty($line) || ($line[0] == '#')) continue; // skip blank lines & comments
+ [$id, $rest] = preg_split('/[ \t]+/', $line, 2);
// substitute user wildcard first (its 1:1)
- if(strstr($line, '%USER%')){
+ if (strstr($line, '%USER%')) {
// if user is not logged in, this ACL line is meaningless - skip it
if (!$INPUT->server->has('REMOTE_USER')) continue;
- $id = str_replace('%USER%',cleanID($INPUT->server->str('REMOTE_USER')),$id);
- $rest = str_replace('%USER%',auth_nameencode($INPUT->server->str('REMOTE_USER')),$rest);
+ $id = str_replace('%USER%', cleanID($INPUT->server->str('REMOTE_USER')), $id);
+ $rest = str_replace('%USER%', auth_nameencode($INPUT->server->str('REMOTE_USER')), $rest);
}
// substitute group wildcard (its 1:m)
- if(strstr($line, '%GROUP%')){
+ if (strstr($line, '%GROUP%')) {
// if user is not logged in, grps is empty, no output will be added (i.e. skipped)
- if(isset($USERINFO['grps'])){
- foreach((array) $USERINFO['grps'] as $grp){
- $nid = str_replace('%GROUP%',cleanID($grp),$id);
- $nrest = str_replace('%GROUP%','@'.auth_nameencode($grp),$rest);
+ if (isset($USERINFO['grps'])) {
+ foreach ((array) $USERINFO['grps'] as $grp) {
+ $nid = str_replace('%GROUP%', cleanID($grp), $id);
+ $nrest = str_replace('%GROUP%', '@' . auth_nameencode($grp), $rest);
$out[] = "$nid\t$nrest";
}
}
@@ -165,8 +170,10 @@ function auth_loadACL() {
*
* @param array $evdata
* @return bool
+ * @throws Exception
*/
-function auth_login_wrapper($evdata) {
+function auth_login_wrapper($evdata)
+{
return auth_login(
$evdata['user'],
$evdata['password'],
@@ -196,15 +203,17 @@ function auth_login_wrapper($evdata) {
* On a successful login $_SERVER[REMOTE_USER] and $USERINFO
* are set.
*
- * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $user Username
+ * @param string $pass Cleartext Password
+ * @param bool $sticky Cookie should not expire
+ * @param bool $silent Don't show error on bad auth
+ * @return bool true on successful auth
+ * @throws Exception
*
- * @param string $user Username
- * @param string $pass Cleartext Password
- * @param bool $sticky Cookie should not expire
- * @param bool $silent Don't show error on bad auth
- * @return bool true on successful auth
+ * @author Andreas Gohr <andi@splitbrain.org>
*/
-function auth_login($user, $pass, $sticky = false, $silent = false) {
+function auth_login($user, $pass, $sticky = false, $silent = false)
+{
global $USERINFO;
global $conf;
global $lang;
@@ -213,13 +222,11 @@ function auth_login($user, $pass, $sticky = false, $silent = false) {
/* @var Input $INPUT */
global $INPUT;
- $sticky ? $sticky = true : $sticky = false; //sanity check
-
- if(!$auth) return false;
+ if (!$auth instanceof AuthPlugin) return false;
- if(!empty($user)) {
+ if (!empty($user)) {
//usual login
- if(!empty($pass) && $auth->checkPass($user, $pass)) {
+ if (!empty($pass) && $auth->checkPass($user, $pass)) {
// make logininfo globally available
$INPUT->server->set('REMOTE_USER', $user);
$secret = auth_cookiesalt(!$sticky, true); //bind non-sticky to session
@@ -227,7 +234,7 @@ function auth_login($user, $pass, $sticky = false, $silent = false) {
return true;
} else {
//invalid credentials - log off
- if(!$silent) {
+ if (!$silent) {
http_status(403, 'Login failed');
msg($lang['badlogin'], -1);
}
@@ -236,21 +243,21 @@ function auth_login($user, $pass, $sticky = false, $silent = false) {
}
} else {
// read cookie information
- list($user, $sticky, $pass) = auth_getCookie();
- if($user && $pass) {
+ [$user, $sticky, $pass] = auth_getCookie();
+ if ($user && $pass) {
// we got a cookie - see if we can trust it
// get session info
if (isset($_SESSION[DOKU_COOKIE])) {
$session = $_SESSION[DOKU_COOKIE]['auth'];
- if (isset($session) &&
+ if (
+ isset($session) &&
$auth->useSessionCache($user) &&
($session['time'] >= time() - $conf['auth_security_timeout']) &&
($session['user'] == $user) &&
($session['pass'] == sha1($pass)) && //still crypted
($session['buid'] == auth_browseruid())
) {
-
// he has session, cookie and browser right - let him in
$INPUT->server->set('REMOTE_USER', $user);
$USERINFO = $session['info']; //FIXME move all references to session
@@ -279,7 +286,8 @@ function auth_login($user, $pass, $sticky = false, $silent = false) {
*
* @return string a SHA256 sum of various browser headers
*/
-function auth_browseruid() {
+function auth_browseruid()
+{
/* @var Input $INPUT */
global $INPUT;
@@ -303,27 +311,29 @@ function auth_browseruid() {
* if no such file is found a random key is created and
* and stored in this file.
*
- * @author Andreas Gohr <andi@splitbrain.org>
- *
- * @param bool $addsession if true, the sessionid is added to the salt
- * @param bool $secure if security is more important than keeping the old value
+ * @param bool $addsession if true, the sessionid is added to the salt
+ * @param bool $secure if security is more important than keeping the old value
* @return string
+ * @throws Exception
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
*/
-function auth_cookiesalt($addsession = false, $secure = false) {
+function auth_cookiesalt($addsession = false, $secure = false)
+{
if (defined('SIMPLE_TEST')) {
return 'test';
}
global $conf;
- $file = $conf['metadir'].'/_htcookiesalt';
+ $file = $conf['metadir'] . '/_htcookiesalt';
if ($secure || !file_exists($file)) {
- $file = $conf['metadir'].'/_htcookiesalt2';
+ $file = $conf['metadir'] . '/_htcookiesalt2';
}
$salt = io_readFile($file);
- if(empty($salt)) {
+ if (empty($salt)) {
$salt = bin2hex(auth_randombytes(64));
io_saveFile($file, $salt);
}
- if($addsession) {
+ if ($addsession) {
$salt .= session_id();
}
return $salt;
@@ -332,25 +342,29 @@ function auth_cookiesalt($addsession = false, $secure = false) {
/**
* Return cryptographically secure random bytes.
*
- * @author Niklas Keller <me@kelunik.com>
- *
* @param int $length number of bytes
* @return string cryptographically secure random bytes
+ * @throws Exception
+ *
+ * @author Niklas Keller <me@kelunik.com>
*/
-function auth_randombytes($length) {
+function auth_randombytes($length)
+{
return random_bytes($length);
}
/**
* Cryptographically secure random number generator.
*
- * @author Niklas Keller <me@kelunik.com>
- *
* @param int $min
* @param int $max
* @return int
+ * @throws Exception
+ *
+ * @author Niklas Keller <me@kelunik.com>
*/
-function auth_random($min, $max) {
+function auth_random($min, $max)
+{
return random_int($min, $max);
}
@@ -360,13 +374,15 @@ function auth_random($min, $max) {
* The mode is CBC with a random initialization vector, the key is derived
* using pbkdf2.
*
- * @param string $data The data that shall be encrypted
+ * @param string $data The data that shall be encrypted
* @param string $secret The secret/password that shall be used
* @return string The ciphertext
+ * @throws Exception
*/
-function auth_encrypt($data, $secret) {
+function auth_encrypt($data, $secret)
+{
$iv = auth_randombytes(16);
- $cipher = new \phpseclib\Crypt\AES();
+ $cipher = new AES();
$cipher->setPassword($secret);
/*
@@ -375,7 +391,7 @@ function auth_encrypt($data, $secret) {
for unique but necessarily random IVs. The resulting ciphertext is
compatible to ciphertext that was created using a "normal" IV.
*/
- return $cipher->encrypt($iv.$data);
+ return $cipher->encrypt($iv . $data);
}
/**
@@ -387,9 +403,10 @@ function auth_encrypt($data, $secret) {
* @param string $secret The secret/password that shall be used
* @return string The decrypted data
*/
-function auth_decrypt($ciphertext, $secret) {
+function auth_decrypt($ciphertext, $secret)
+{
$iv = substr($ciphertext, 0, 16);
- $cipher = new \phpseclib\Crypt\AES();
+ $cipher = new AES();
$cipher->setPassword($secret);
$cipher->setIV($iv);
@@ -406,7 +423,8 @@ function auth_decrypt($ciphertext, $secret) {
*
* @param bool $keepbc - when true, the breadcrumb data is not cleared
*/
-function auth_logoff($keepbc = false) {
+function auth_logoff($keepbc = false)
+{
global $conf;
global $USERINFO;
/* @var AuthPlugin $auth */
@@ -417,13 +435,13 @@ function auth_logoff($keepbc = false) {
// make sure the session is writable (it usually is)
@session_start();
- if(isset($_SESSION[DOKU_COOKIE]['auth']['user']))
+ if (isset($_SESSION[DOKU_COOKIE]['auth']['user']))
unset($_SESSION[DOKU_COOKIE]['auth']['user']);
- if(isset($_SESSION[DOKU_COOKIE]['auth']['pass']))
+ if (isset($_SESSION[DOKU_COOKIE]['auth']['pass']))
unset($_SESSION[DOKU_COOKIE]['auth']['pass']);
- if(isset($_SESSION[DOKU_COOKIE]['auth']['info']))
+ if (isset($_SESSION[DOKU_COOKIE]['auth']['info']))
unset($_SESSION[DOKU_COOKIE]['auth']['info']);
- if(!$keepbc && isset($_SESSION[DOKU_COOKIE]['bc']))
+ if (!$keepbc && isset($_SESSION[DOKU_COOKIE]['bc']))
unset($_SESSION[DOKU_COOKIE]['bc']);
$INPUT->server->remove('REMOTE_USER');
$USERINFO = null; //FIXME
@@ -437,7 +455,9 @@ function auth_logoff($keepbc = false) {
'samesite' => $conf['samesitecookie'] ?: null, // null means browser default
]);
- if($auth) $auth->logOff();
+ if ($auth instanceof AuthPlugin) {
+ $auth->logOff();
+ }
}
/**
@@ -457,7 +477,8 @@ function auth_logoff($keepbc = false) {
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function auth_ismanager($user = null, $groups = null, $adminonly = false, $recache=false) {
+function auth_ismanager($user = null, $groups = null, $adminonly = false, $recache = false)
+{
global $conf;
global $USERINFO;
/* @var AuthPlugin $auth */
@@ -466,9 +487,9 @@ function auth_ismanager($user = null, $groups = null, $adminonly = false, $recac
global $INPUT;
- if(!$auth) return false;
- if(is_null($user)) {
- if(!$INPUT->server->has('REMOTE_USER')) {
+ if (!$auth instanceof AuthPlugin) return false;
+ if (is_null($user)) {
+ if (!$INPUT->server->has('REMOTE_USER')) {
return false;
} else {
$user = $INPUT->server->str('REMOTE_USER');
@@ -517,7 +538,8 @@ function auth_ismanager($user = null, $groups = null, $adminonly = false, $recac
* @see auth_ismanager()
*
*/
-function auth_isadmin($user = null, $groups = null, $recache=false) {
+function auth_isadmin($user = null, $groups = null, $recache = false)
+{
return auth_ismanager($user, $groups, true, $recache);
}
@@ -532,18 +554,19 @@ function auth_isadmin($user = null, $groups = null, $recache=false) {
* @param array $groups groups the user is member of
* @return bool true for membership acknowledged
*/
-function auth_isMember($memberlist, $user, array $groups) {
+function auth_isMember($memberlist, $user, array $groups)
+{
/* @var AuthPlugin $auth */
global $auth;
- if(!$auth) return false;
+ if (!$auth instanceof AuthPlugin) return false;
// clean user and groups
- if(!$auth->isCaseSensitive()) {
- $user = \dokuwiki\Utf8\PhpString::strtolower($user);
- $groups = array_map([\dokuwiki\Utf8\PhpString::class, 'strtolower'], $groups);
+ if (!$auth->isCaseSensitive()) {
+ $user = PhpString::strtolower($user);
+ $groups = array_map([PhpString::class, 'strtolower'], $groups);
}
$user = $auth->cleanUser($user);
- $groups = array_map(array($auth, 'cleanGroup'), $groups);
+ $groups = array_map([$auth, 'cleanGroup'], $groups);
// extract the memberlist
$members = explode(',', $memberlist);
@@ -552,15 +575,15 @@ function auth_isMember($memberlist, $user, array $groups) {
$members = array_filter($members);
// compare cleaned values
- foreach($members as $member) {
- if($member == '@ALL' ) return true;
- if(!$auth->isCaseSensitive()) $member = \dokuwiki\Utf8\PhpString::strtolower($member);
- if($member[0] == '@') {
+ foreach ($members as $member) {
+ if ($member == '@ALL') return true;
+ if (!$auth->isCaseSensitive()) $member = PhpString::strtolower($member);
+ if ($member[0] == '@') {
$member = $auth->cleanGroup(substr($member, 1));
- if(in_array($member, $groups)) return true;
+ if (in_array($member, $groups)) return true;
} else {
$member = $auth->cleanUser($member);
- if($member == $user) return true;
+ if ($member == $user) return true;
}
}
@@ -578,14 +601,15 @@ function auth_isMember($memberlist, $user, array $groups) {
* @param string $id page ID (needs to be resolved and cleaned)
* @return int permission level
*/
-function auth_quickaclcheck($id) {
+function auth_quickaclcheck($id)
+{
global $conf;
global $USERINFO;
/* @var Input $INPUT */
global $INPUT;
# if no ACL is used always return upload rights
- if(!$conf['useacl']) return AUTH_UPLOAD;
- return auth_aclcheck($id, $INPUT->server->str('REMOTE_USER'), is_array($USERINFO) ? $USERINFO['grps'] : array());
+ if (!$conf['useacl']) return AUTH_UPLOAD;
+ return auth_aclcheck($id, $INPUT->server->str('REMOTE_USER'), is_array($USERINFO) ? $USERINFO['grps'] : []);
}
/**
@@ -599,12 +623,13 @@ function auth_quickaclcheck($id) {
* @param array|null $groups Array of groups the user is in
* @return int permission level
*/
-function auth_aclcheck($id, $user, $groups) {
- $data = array(
+function auth_aclcheck($id, $user, $groups)
+{
+ $data = [
'id' => $id ?? '',
'user' => $user,
'groups' => $groups
- );
+ ];
return Event::createAndTrigger('AUTH_ACL_CHECK', $data, 'auth_aclcheck_cb');
}
@@ -619,7 +644,8 @@ function auth_aclcheck($id, $user, $groups) {
* @param array $data event data
* @return int permission level
*/
-function auth_aclcheck_cb($data) {
+function auth_aclcheck_cb($data)
+{
$id =& $data['id'];
$user =& $data['user'];
$groups =& $data['groups'];
@@ -630,28 +656,28 @@ function auth_aclcheck_cb($data) {
global $auth;
// if no ACL is used always return upload rights
- if(!$conf['useacl']) return AUTH_UPLOAD;
- if(!$auth) return AUTH_NONE;
- if(!is_array($AUTH_ACL)) return AUTH_NONE;
+ if (!$conf['useacl']) return AUTH_UPLOAD;
+ if (!$auth instanceof AuthPlugin) return AUTH_NONE;
+ if (!is_array($AUTH_ACL)) return AUTH_NONE;
//make sure groups is an array
- if(!is_array($groups)) $groups = array();
+ if (!is_array($groups)) $groups = [];
//if user is superuser or in superusergroup return 255 (acl_admin)
- if(auth_isadmin($user, $groups)) {
+ if (auth_isadmin($user, $groups)) {
return AUTH_ADMIN;
}
- if(!$auth->isCaseSensitive()) {
- $user = \dokuwiki\Utf8\PhpString::strtolower($user);
- $groups = array_map([\dokuwiki\Utf8\PhpString::class, 'strtolower'], $groups);
+ if (!$auth->isCaseSensitive()) {
+ $user = PhpString::strtolower($user);
+ $groups = array_map([PhpString::class, 'strtolower'], $groups);
}
$user = auth_nameencode($auth->cleanUser($user));
- $groups = array_map(array($auth, 'cleanGroup'), (array) $groups);
+ $groups = array_map([$auth, 'cleanGroup'], $groups);
//prepend groups with @ and nameencode
- foreach($groups as &$group) {
- $group = '@'.auth_nameencode($group);
+ foreach ($groups as &$group) {
+ $group = '@' . auth_nameencode($group);
}
$ns = getNS($id);
@@ -661,66 +687,66 @@ function auth_aclcheck_cb($data) {
$groups[] = '@ALL';
//add User
- if($user) $groups[] = $user;
+ if ($user) $groups[] = $user;
//check exact match first
- $matches = preg_grep('/^'.preg_quote($id, '/').'[ \t]+([^ \t]+)[ \t]+/', $AUTH_ACL);
- if(count($matches)) {
- foreach($matches as $match) {
+ $matches = preg_grep('/^' . preg_quote($id, '/') . '[ \t]+([^ \t]+)[ \t]+/', $AUTH_ACL);
+ if (count($matches)) {
+ foreach ($matches as $match) {
$match = preg_replace('/#.*$/', '', $match); //ignore comments
$acl = preg_split('/[ \t]+/', $match);
- if(!$auth->isCaseSensitive() && $acl[1] !== '@ALL') {
- $acl[1] = \dokuwiki\Utf8\PhpString::strtolower($acl[1]);
+ if (!$auth->isCaseSensitive() && $acl[1] !== '@ALL') {
+ $acl[1] = PhpString::strtolower($acl[1]);
}
- if(!in_array($acl[1], $groups)) {
+ if (!in_array($acl[1], $groups)) {
continue;
}
- if($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL!
- if($acl[2] > $perm) {
+ if ($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL!
+ if ($acl[2] > $perm) {
$perm = $acl[2];
}
}
- if($perm > -1) {
+ if ($perm > -1) {
//we had a match - return it
return (int) $perm;
}
}
//still here? do the namespace checks
- if($ns) {
- $path = $ns.':*';
+ if ($ns) {
+ $path = $ns . ':*';
} else {
$path = '*'; //root document
}
do {
- $matches = preg_grep('/^'.preg_quote($path, '/').'[ \t]+([^ \t]+)[ \t]+/', $AUTH_ACL);
- if(count($matches)) {
- foreach($matches as $match) {
+ $matches = preg_grep('/^' . preg_quote($path, '/') . '[ \t]+([^ \t]+)[ \t]+/', $AUTH_ACL);
+ if (count($matches)) {
+ foreach ($matches as $match) {
$match = preg_replace('/#.*$/', '', $match); //ignore comments
$acl = preg_split('/[ \t]+/', $match);
- if(!$auth->isCaseSensitive() && $acl[1] !== '@ALL') {
- $acl[1] = \dokuwiki\Utf8\PhpString::strtolower($acl[1]);
+ if (!$auth->isCaseSensitive() && $acl[1] !== '@ALL') {
+ $acl[1] = PhpString::strtolower($acl[1]);
}
- if(!in_array($acl[1], $groups)) {
+ if (!in_array($acl[1], $groups)) {
continue;
}
- if($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL!
- if($acl[2] > $perm) {
+ if ($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL!
+ if ($acl[2] > $perm) {
$perm = $acl[2];
}
}
//we had a match - return it
- if($perm != -1) {
+ if ($perm != -1) {
return (int) $perm;
}
}
//get next higher namespace
$ns = getNS($ns);
- if($path != '*') {
- $path = $ns.':*';
- if($path == ':*') $path = '*';
+ if ($path != '*') {
+ $path = $ns . ':*';
+ if ($path == ':*') $path = '*';
} else {
//we did this already
//looks like there is something wrong with the ACL
@@ -728,7 +754,7 @@ function auth_aclcheck_cb($data) {
msg('No ACL setup yet! Denying access to everyone.');
return AUTH_NONE;
}
- } while(1); //this should never loop endless
+ } while (1); //this should never loop endless
return AUTH_NONE;
}
@@ -749,25 +775,28 @@ function auth_aclcheck_cb($data) {
* @param bool $skip_group
* @return string
*/
-function auth_nameencode($name, $skip_group = false) {
+function auth_nameencode($name, $skip_group = false)
+{
global $cache_authname;
$cache =& $cache_authname;
$name = (string) $name;
// never encode wildcard FS#1955
- if($name == '%USER%') return $name;
- if($name == '%GROUP%') return $name;
+ if ($name == '%USER%') return $name;
+ if ($name == '%GROUP%') return $name;
- if(!isset($cache[$name][$skip_group])) {
- if($skip_group && $name[0] == '@') {
- $cache[$name][$skip_group] = '@'.preg_replace_callback(
+ if (!isset($cache[$name][$skip_group])) {
+ if ($skip_group && $name[0] == '@') {
+ $cache[$name][$skip_group] = '@' . preg_replace_callback(
'/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f])/',
- 'auth_nameencode_callback', substr($name, 1)
+ 'auth_nameencode_callback',
+ substr($name, 1)
);
} else {
$cache[$name][$skip_group] = preg_replace_callback(
'/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f])/',
- 'auth_nameencode_callback', $name
+ 'auth_nameencode_callback',
+ $name
);
}
}
@@ -781,8 +810,9 @@ function auth_nameencode($name, $skip_group = false) {
* @param array $matches first complete match, next matching subpatterms
* @return string
*/
-function auth_nameencode_callback($matches) {
- return '%'.dechex(ord(substr($matches[1],-1)));
+function auth_nameencode_callback($matches)
+{
+ return '%' . dechex(ord(substr($matches[1], -1)));
}
/**
@@ -791,34 +821,37 @@ function auth_nameencode_callback($matches) {
* The $foruser variable might be used by plugins to run additional password
* policy checks, but is not used by the default implementation
*
- * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $foruser username for which the password is generated
+ * @return string pronouncable password
+ * @throws Exception
+ *
* @link http://www.phpbuilder.com/annotate/message.php3?id=1014451
* @triggers AUTH_PASSWORD_GENERATE
*
- * @param string $foruser username for which the password is generated
- * @return string pronouncable password
+ * @author Andreas Gohr <andi@splitbrain.org>
*/
-function auth_pwgen($foruser = '') {
- $data = array(
+function auth_pwgen($foruser = '')
+{
+ $data = [
'password' => '',
'foruser' => $foruser
- );
+ ];
$evt = new Event('AUTH_PASSWORD_GENERATE', $data);
- if($evt->advise_before(true)) {
+ if ($evt->advise_before(true)) {
$c = 'bcdfghjklmnprstvwz'; //consonants except hard to speak ones
$v = 'aeiou'; //vowels
- $a = $c.$v; //both
+ $a = $c . $v; //both
$s = '!$%&?+*~#-_:.;,'; // specials
//use thre syllables...
- for($i = 0; $i < 3; $i++) {
+ for ($i = 0; $i < 3; $i++) {
$data['password'] .= $c[auth_random(0, strlen($c) - 1)];
$data['password'] .= $v[auth_random(0, strlen($v) - 1)];
$data['password'] .= $a[auth_random(0, strlen($a) - 1)];
}
//... and add a nice number and special
- $data['password'] .= $s[auth_random(0, strlen($s) - 1)].auth_random(10, 99);
+ $data['password'] .= $s[auth_random(0, strlen($s) - 1)] . auth_random(10, 99);
}
$evt->advise_after();
@@ -834,26 +867,27 @@ function auth_pwgen($foruser = '') {
* @param string $password The new password in clear text
* @return bool true on success
*/
-function auth_sendPassword($user, $password) {
+function auth_sendPassword($user, $password)
+{
global $lang;
/* @var AuthPlugin $auth */
global $auth;
- if(!$auth) return false;
+ if (!$auth instanceof AuthPlugin) return false;
$user = $auth->cleanUser($user);
- $userinfo = $auth->getUserData($user, $requireGroups = false);
+ $userinfo = $auth->getUserData($user, false);
- if(!$userinfo['mail']) return false;
+ if (!$userinfo['mail']) return false;
$text = rawLocale('password');
- $trep = array(
+ $trep = [
'FULLNAME' => $userinfo['name'],
'LOGIN' => $user,
'PASSWORD' => $password
- );
+ ];
$mail = new Mailer();
- $mail->to($mail->getCleanName($userinfo['name']).' <'.$userinfo['mail'].'>');
+ $mail->to($mail->getCleanName($userinfo['name']) . ' <' . $userinfo['mail'] . '>');
$mail->subject($lang['regpwmail']);
$mail->setBody($text, $trep);
return $mail->send();
@@ -864,19 +898,21 @@ function auth_sendPassword($user, $password) {
*
* This registers a new user - Data is read directly from $_POST
*
- * @author Andreas Gohr <andi@splitbrain.org>
- *
* @return bool true on success, false on any error
+ * @throws Exception
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
*/
-function register() {
+function register()
+{
global $lang;
global $conf;
- /* @var \dokuwiki\Extension\AuthPlugin $auth */
+ /* @var AuthPlugin $auth */
global $auth;
global $INPUT;
- if(!$INPUT->post->bool('save')) return false;
- if(!actionOK('register')) return false;
+ if (!$INPUT->post->bool('save')) return false;
+ if (!actionOK('register')) return false;
// gather input
$login = trim($auth->cleanUser($INPUT->post->str('login')));
@@ -885,29 +921,29 @@ function register() {
$pass = $INPUT->post->str('pass');
$passchk = $INPUT->post->str('passchk');
- if(empty($login) || empty($fullname) || empty($email)) {
+ if (empty($login) || empty($fullname) || empty($email)) {
msg($lang['regmissing'], -1);
return false;
}
- if($conf['autopasswd']) {
+ if ($conf['autopasswd']) {
$pass = auth_pwgen($login); // automatically generate password
- } elseif(empty($pass) || empty($passchk)) {
+ } elseif (empty($pass) || empty($passchk)) {
msg($lang['regmissing'], -1); // complain about missing passwords
return false;
- } elseif($pass != $passchk) {
+ } elseif ($pass != $passchk) {
msg($lang['regbadpass'], -1); // complain about misspelled passwords
return false;
}
//check mail
- if(!mail_isvalid($email)) {
+ if (!mail_isvalid($email)) {
msg($lang['regbadmail'], -1);
return false;
}
//okay try to create the user
- if(!$auth->triggerUserMod('create', array($login, $pass, $fullname, $email))) {
+ if (!$auth->triggerUserMod('create', [$login, $pass, $fullname, $email])) {
msg($lang['regfail'], -1);
return false;
}
@@ -917,13 +953,13 @@ function register() {
$subscription->sendRegister($login, $fullname, $email);
// are we done?
- if(!$conf['autopasswd']) {
+ if (!$conf['autopasswd']) {
msg($lang['regsuccess2'], 1);
return true;
}
// autogenerated password? then send password to user
- if(auth_sendPassword($login, $pass)) {
+ if (auth_sendPassword($login, $pass)) {
msg($lang['regsuccess'], 1);
return true;
} else {
@@ -935,9 +971,12 @@ function register() {
/**
* Update user profile
*
+ * @throws Exception
+ *
* @author Christopher Smith <chris@jalakai.co.uk>
*/
-function updateprofile() {
+function updateprofile()
+{
global $conf;
global $lang;
/* @var AuthPlugin $auth */
@@ -945,21 +984,21 @@ function updateprofile() {
/* @var Input $INPUT */
global $INPUT;
- if(!$INPUT->post->bool('save')) return false;
- if(!checkSecurityToken()) return false;
+ if (!$INPUT->post->bool('save')) return false;
+ if (!checkSecurityToken()) return false;
- if(!actionOK('profile')) {
+ if (!actionOK('profile')) {
msg($lang['profna'], -1);
return false;
}
- $changes = array();
+ $changes = [];
$changes['pass'] = $INPUT->post->str('newpass');
$changes['name'] = $INPUT->post->str('fullname');
$changes['mail'] = $INPUT->post->str('email');
// check misspelled passwords
- if($changes['pass'] != $INPUT->post->str('passchk')) {
+ if ($changes['pass'] != $INPUT->post->str('passchk')) {
msg($lang['regbadpass'], -1);
return false;
}
@@ -969,13 +1008,14 @@ function updateprofile() {
$changes['mail'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/', '', $changes['mail']));
// no empty name and email (except the backend doesn't support them)
- if((empty($changes['name']) && $auth->canDo('modName')) ||
+ if (
+ (empty($changes['name']) && $auth->canDo('modName')) ||
(empty($changes['mail']) && $auth->canDo('modMail'))
) {
msg($lang['profnoempty'], -1);
return false;
}
- if(!mail_isvalid($changes['mail']) && $auth->canDo('modMail')) {
+ if (!mail_isvalid($changes['mail']) && $auth->canDo('modMail')) {
msg($lang['regbadmail'], -1);
return false;
}
@@ -983,31 +1023,31 @@ function updateprofile() {
$changes = array_filter($changes);
// check for unavailable capabilities
- if(!$auth->canDo('modName')) unset($changes['name']);
- if(!$auth->canDo('modMail')) unset($changes['mail']);
- if(!$auth->canDo('modPass')) unset($changes['pass']);
+ if (!$auth->canDo('modName')) unset($changes['name']);
+ if (!$auth->canDo('modMail')) unset($changes['mail']);
+ if (!$auth->canDo('modPass')) unset($changes['pass']);
// anything to do?
- if(!count($changes)) {
+ if ($changes === []) {
msg($lang['profnochange'], -1);
return false;
}
- if($conf['profileconfirm']) {
- if(!$auth->checkPass($INPUT->server->str('REMOTE_USER'), $INPUT->post->str('oldpass'))) {
+ if ($conf['profileconfirm']) {
+ if (!$auth->checkPass($INPUT->server->str('REMOTE_USER'), $INPUT->post->str('oldpass'))) {
msg($lang['badpassconfirm'], -1);
return false;
}
}
- if(!$auth->triggerUserMod('modify', array($INPUT->server->str('REMOTE_USER'), &$changes))) {
+ if (!$auth->triggerUserMod('modify', [$INPUT->server->str('REMOTE_USER'), &$changes])) {
msg($lang['proffail'], -1);
return false;
}
- if($changes['pass']) {
+ if ($changes['pass']) {
// update cookie and session with the changed data
- list( /*user*/, $sticky, /*pass*/) = auth_getCookie();
+ [/* user */, $sticky, /* pass */] = auth_getCookie();
$pass = auth_encrypt($changes['pass'], auth_cookiesalt(!$sticky, true));
auth_setCookie($INPUT->server->str('REMOTE_USER'), $pass, (bool) $sticky);
} else {
@@ -1026,38 +1066,39 @@ function updateprofile() {
*
* @return bool true on success, false on any error
*/
-function auth_deleteprofile(){
+function auth_deleteprofile()
+{
global $conf;
global $lang;
- /* @var \dokuwiki\Extension\AuthPlugin $auth */
+ /* @var AuthPlugin $auth */
global $auth;
/* @var Input $INPUT */
global $INPUT;
- if(!$INPUT->post->bool('delete')) return false;
- if(!checkSecurityToken()) return false;
+ if (!$INPUT->post->bool('delete')) return false;
+ if (!checkSecurityToken()) return false;
// action prevented or auth module disallows
- if(!actionOK('profile_delete') || !$auth->canDo('delUser')) {
+ if (!actionOK('profile_delete') || !$auth->canDo('delUser')) {
msg($lang['profnodelete'], -1);
return false;
}
- if(!$INPUT->post->bool('confirm_delete')){
+ if (!$INPUT->post->bool('confirm_delete')) {
msg($lang['profconfdeletemissing'], -1);
return false;
}
- if($conf['profileconfirm']) {
- if(!$auth->checkPass($INPUT->server->str('REMOTE_USER'), $INPUT->post->str('oldpass'))) {
+ if ($conf['profileconfirm']) {
+ if (!$auth->checkPass($INPUT->server->str('REMOTE_USER'), $INPUT->post->str('oldpass'))) {
msg($lang['badpassconfirm'], -1);
return false;
}
}
- $deleted = array();
+ $deleted = [];
$deleted[] = $INPUT->server->str('REMOTE_USER');
- if($auth->triggerUserMod('delete', array($deleted))) {
+ if ($auth->triggerUserMod('delete', [$deleted])) {
// force and immediate logout including removing the sticky cookie
auth_logoff();
return true;
@@ -1074,13 +1115,15 @@ function auth_deleteprofile(){
* - handling the first request of password reset
* - validating the password reset auth token
*
+ * @return bool true on success, false on any error
+ * @throws Exception
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
* @author Benoit Chesneau <benoit@bchesneau.info>
* @author Chris Smith <chris@jalakai.co.uk>
- * @author Andreas Gohr <andi@splitbrain.org>
- *
- * @return bool true on success, false on any error
*/
-function act_resendpwd() {
+function act_resendpwd()
+{
global $lang;
global $conf;
/* @var AuthPlugin $auth */
@@ -1088,24 +1131,24 @@ function act_resendpwd() {
/* @var Input $INPUT */
global $INPUT;
- if(!actionOK('resendpwd')) {
+ if (!actionOK('resendpwd')) {
msg($lang['resendna'], -1);
return false;
}
$token = preg_replace('/[^a-f0-9]+/', '', $INPUT->str('pwauth'));
- if($token) {
+ if ($token) {
// we're in token phase - get user info from token
- $tfile = $conf['cachedir'].'/'.$token[0].'/'.$token.'.pwauth';
- if(!file_exists($tfile)) {
+ $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth';
+ if (!file_exists($tfile)) {
msg($lang['resendpwdbadauth'], -1);
$INPUT->remove('pwauth');
return false;
}
// token is only valid for 3 days
- if((time() - filemtime($tfile)) > (3 * 60 * 60 * 24)) {
+ if ((time() - filemtime($tfile)) > (3 * 60 * 60 * 24)) {
msg($lang['resendpwdbadauth'], -1);
$INPUT->remove('pwauth');
@unlink($tfile);
@@ -1113,37 +1156,35 @@ function act_resendpwd() {
}
$user = io_readfile($tfile);
- $userinfo = $auth->getUserData($user, $requireGroups = false);
- if(!$userinfo['mail']) {
+ $userinfo = $auth->getUserData($user, false);
+ if (!$userinfo['mail']) {
msg($lang['resendpwdnouser'], -1);
return false;
}
- if(!$conf['autopasswd']) { // we let the user choose a password
+ if (!$conf['autopasswd']) { // we let the user choose a password
$pass = $INPUT->str('pass');
// password given correctly?
- if(!$pass) return false;
- if($pass != $INPUT->str('passchk')) {
+ if (!$pass) return false;
+ if ($pass != $INPUT->str('passchk')) {
msg($lang['regbadpass'], -1);
return false;
}
// change it
- if(!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) {
+ if (!$auth->triggerUserMod('modify', [$user, ['pass' => $pass]])) {
msg($lang['proffail'], -1);
return false;
}
-
} else { // autogenerate the password and send by mail
-
$pass = auth_pwgen($user);
- if(!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) {
+ if (!$auth->triggerUserMod('modify', [$user, ['pass' => $pass]])) {
msg($lang['proffail'], -1);
return false;
}
- if(auth_sendPassword($user, $pass)) {
+ if (auth_sendPassword($user, $pass)) {
msg($lang['resendpwdsuccess'], 1);
} else {
msg($lang['regmailfail'], -1);
@@ -1152,44 +1193,39 @@ function act_resendpwd() {
@unlink($tfile);
return true;
-
} else {
// we're in request phase
- if(!$INPUT->post->bool('save')) return false;
+ if (!$INPUT->post->bool('save')) return false;
- if(!$INPUT->post->str('login')) {
+ if (!$INPUT->post->str('login')) {
msg($lang['resendpwdmissing'], -1);
return false;
} else {
$user = trim($auth->cleanUser($INPUT->post->str('login')));
}
- $userinfo = $auth->getUserData($user, $requireGroups = false);
- if(!$userinfo['mail']) {
+ $userinfo = $auth->getUserData($user, false);
+ if (!$userinfo['mail']) {
msg($lang['resendpwdnouser'], -1);
return false;
}
// generate auth token
$token = md5(auth_randombytes(16)); // random secret
- $tfile = $conf['cachedir'].'/'.$token[0].'/'.$token.'.pwauth';
- $url = wl('', array('do'=> 'resendpwd', 'pwauth'=> $token), true, '&');
+ $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth';
+ $url = wl('', ['do' => 'resendpwd', 'pwauth' => $token], true, '&');
io_saveFile($tfile, $user);
$text = rawLocale('pwconfirm');
- $trep = array(
- 'FULLNAME' => $userinfo['name'],
- 'LOGIN' => $user,
- 'CONFIRM' => $url
- );
+ $trep = ['FULLNAME' => $userinfo['name'], 'LOGIN' => $user, 'CONFIRM' => $url];
$mail = new Mailer();
- $mail->to($userinfo['name'].' <'.$userinfo['mail'].'>');
+ $mail->to($userinfo['name'] . ' <' . $userinfo['mail'] . '>');
$mail->subject($lang['regpwmail']);
$mail->setBody($text, $trep);
- if($mail->send()) {
+ if ($mail->send()) {
msg($lang['resendpwdconfirm'], 1);
} else {
msg($lang['regmailfail'], -1);
@@ -1212,14 +1248,15 @@ function act_resendpwd() {
* @param string $salt A salt, null for random
* @return string The crypted password
*/
-function auth_cryptPassword($clear, $method = '', $salt = null) {
+function auth_cryptPassword($clear, $method = '', $salt = null)
+{
global $conf;
- if(empty($method)) $method = $conf['passcrypt'];
+ if (empty($method)) $method = $conf['passcrypt'];
$pass = new PassHash();
- $call = 'hash_'.$method;
+ $call = 'hash_' . $method;
- if(!method_exists($pass, $call)) {
+ if (!method_exists($pass, $call)) {
msg("Unsupported crypt method $method", -1);
return false;
}
@@ -1230,13 +1267,15 @@ function auth_cryptPassword($clear, $method = '', $salt = null) {
/**
* Verifies a cleartext password against a crypted hash
*
- * @author Andreas Gohr <andi@splitbrain.org>
- *
- * @param string $clear The clear text password
- * @param string $crypt The hash to compare with
+ * @param string $clear The clear text password
+ * @param string $crypt The hash to compare with
* @return bool true if both match
+ * @throws Exception
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
*/
-function auth_verifyPassword($clear, $crypt) {
+function auth_verifyPassword($clear, $crypt)
+{
$pass = new PassHash();
return $pass->verify_hash($clear, $crypt);
}
@@ -1249,17 +1288,18 @@ function auth_verifyPassword($clear, $crypt) {
* @param bool $sticky whether or not the cookie will last beyond the session
* @return bool
*/
-function auth_setCookie($user, $pass, $sticky) {
+function auth_setCookie($user, $pass, $sticky)
+{
global $conf;
/* @var AuthPlugin $auth */
global $auth;
global $USERINFO;
- if(!$auth) return false;
+ if (!$auth instanceof AuthPlugin) return false;
$USERINFO = $auth->getUserData($user);
// set cookie
- $cookie = base64_encode($user).'|'.((int) $sticky).'|'.base64_encode($pass);
+ $cookie = base64_encode($user) . '|' . ((int) $sticky) . '|' . base64_encode($pass);
$cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'];
$time = $sticky ? (time() + 60 * 60 * 24 * 365) : 0; //one year
setcookie(DOKU_COOKIE, $cookie, [
@@ -1285,15 +1325,16 @@ function auth_setCookie($user, $pass, $sticky) {
*
* @returns array
*/
-function auth_getCookie() {
- if(!isset($_COOKIE[DOKU_COOKIE])) {
- return array(null, null, null);
+function auth_getCookie()
+{
+ if (!isset($_COOKIE[DOKU_COOKIE])) {
+ return [null, null, null];
}
- list($user, $sticky, $pass) = sexplode('|', $_COOKIE[DOKU_COOKIE], 3, '');
+ [$user, $sticky, $pass] = sexplode('|', $_COOKIE[DOKU_COOKIE], 3, '');
$sticky = (bool) $sticky;
$pass = base64_decode($pass);
$user = base64_decode($user);
- return array($user, $sticky, $pass);
+ return [$user, $sticky, $pass];
}
//Setup VIM: ex: et ts=2 :