Merge pull request #1457 from splitbrain/authpdo

AuthPDO Plugin implements #1029, replaces #1143
This commit is contained in:
Andreas Gohr 2016-06-24 14:53:56 +02:00 committed by GitHub
commit ce5bade5fe
43 changed files with 3682 additions and 6 deletions

1
.gitignore vendored
View File

@ -40,6 +40,7 @@
!/lib/plugins/authldap
!/lib/plugins/authmysql
!/lib/plugins/authpgsql
!/lib/plugins/authpdo
!/lib/plugins/authplain
!/lib/plugins/config
!/lib/plugins/extension

View File

@ -19,5 +19,11 @@ notifications:
- "chat.freenode.net#dokuwiki"
on_success: change
on_failure: change
before_script: echo "disable_functions=$DISABLE_FUNCTIONS" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
services:
- "mysql"
- "postgresql"
before_script:
- echo "disable_functions=$DISABLE_FUNCTIONS" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
- cp _test/mysql.conf.php.dist _test/mysql.conf.php
- cp _test/pgsql.conf.php.dist _test/pgsql.conf.php
script: cd _test && phpunit --verbose --stderr

View File

@ -0,0 +1,9 @@
<?php
/**
* This configures the access to a mysql database. The user needs to have permissions
* to create and drop databases.
*/
$conf['host'] = 'localhost';
$conf['port'] = 3306;
$conf['user'] = 'root';
$conf['pass'] = '';

View File

@ -0,0 +1,9 @@
<?php
/**
* This configures the access to a postgres database. The user needs to have permissions
* to create and drop databases.
*/
$conf['host'] = 'localhost';
$conf['port'] = 5432;
$conf['user'] = 'postgres';
$conf['pass'] = '';

View File

@ -2,6 +2,6 @@ base authmysql
author Andreas Gohr
email andi@splitbrain.org
date 2015-07-13
name MYSQL Auth Plugin
desc Provides user authentication against a MySQL database
name [DEPRECATED] MYSQL Auth Plugin
desc ▶This plugin will be removed from DokuWiki in a future release! Use authpdo instead.◀ Provides user authentication against a MySQL database
url http://www.dokuwiki.org/plugin:authmysql

View File

@ -0,0 +1,27 @@
authpdo Plugin for DokuWiki
Authenticate against a database via PDO
All documentation for this plugin can be found at
https://www.dokuwiki.org/plugin:authpdo
If you install this plugin manually, make sure it is installed in
lib/plugins/authpdo/ - if the folder is called different it
will not work!
Please refer to http://www.dokuwiki.org/plugins for additional info
on how to install plugins in DokuWiki.
----
Copyright (C) Andreas Gohr <andi@splitbrain.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License
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 General Public License for more details.
See the COPYING file in your DokuWiki folder for details

View File

@ -0,0 +1,315 @@
<?php
/**
* mysql tests for the authpdo plugin
*
* @group plugin_authpdo
* @group plugins
*/
class mysql_plugin_authpdo_test extends DokuWikiTest {
protected $driver = 'mysql';
protected $host = '';
protected $database = 'authpdo_testing';
protected $user = '';
protected $pass = '';
protected $port = '';
public function setUp() {
parent::setUp();
$configuration = DOKU_UNITTEST . "{$this->driver}.conf.php";
if(!file_exists($configuration)) {
return;
}
/** @var $conf array */
include $configuration;
$this->host = $conf['host'];
$this->user = $conf['user'];
$this->pass = $conf['pass'];
$this->port = $conf['port'];
}
/**
* try to remove the last set up database
*
* it might still be there if something went wrong
*/
public function tearDown() {
parent::tearDown();
$this->dropDatabase();
}
/**
* Check if database credentials and extensions exist
*/
public function test_requirements() {
if(!$this->host || !$this->user) {
$this->markTestSkipped("Skipped {$this->driver} tests. Missing configuration");
}
if(!class_exists('PDO')) {
$this->markTestSkipped("Skipped {$this->driver} tests. Missing PDO extension");
}
if(!in_array($this->driver, pdo_drivers())) {
$this->markTestSkipped("Skipped {$this->driver} tests. Missing pdo_{$this->driver} extension");
}
}
/**
* create the database for testing
*/
protected function createDatabase() {
$pdo = new PDO(
"{$this->driver}:host={$this->host};port={$this->port}", $this->user, $this->pass,
array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // we want exceptions, not error codes
)
);
$pdo->exec("DROP DATABASE IF EXISTS {$this->database}");
$pdo->exec("CREATE DATABASE {$this->database}");
$pdo = null;
}
/**
* remove the database
*/
protected function dropDatabase() {
$pdo = new PDO(
"{$this->driver}:host={$this->host};port={$this->port}", $this->user, $this->pass,
array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // we want exceptions, not error codes
)
);
try {
$pdo->exec("DROP DATABASE IF EXISTS {$this->database}");
} catch (PDOException $e) {
// ignore - sometimes this fails even though the database was deleted
}
$pdo = null;
}
/**
* imports a database dump
*
* @param $file
*/
protected function importDatabase($file) {
// connect to database and import dump
$pdo = null;
$pdo = new PDO(
"{$this->driver}:dbname={$this->database};host={$this->host};port={$this->port}", $this->user, $this->pass,
array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // we want exceptions, not error codes
)
);
$sql = file_get_contents($file);
$pdo->exec($sql);
$pdo = null;
}
/**
* Run general tests on all users
*
* @param auth_plugin_authpdo $auth
* @param array $users
*/
protected function runGeneralTests(auth_plugin_authpdo $auth, $users) {
global $conf;
$info = 'DSN: ' . $auth->getConf('dsn');
$this->assertTrue($auth->success, $info);
if($auth->canDo('getUsers')) {
$list = $auth->retrieveUsers();
$this->assertGreaterThanOrEqual(count($users), count($list), $info);
}
if($auth->canDo('getGroups')) {
$list = $auth->retrieveGroups();
$this->assertGreaterThanOrEqual(1, $list, $info);
}
if($auth->canDo('getUserCount')) {
$count = $auth->getUserCount();
$this->assertGreaterThanOrEqual(count($users), $count);
}
if($auth->canDo('addUser')) {
$newuser = array(
'user' => 'newuserfoobar',
'name' => 'First LastFoobar',
'pass' => 'password',
'mail' => 'newuserfoobar@example.com',
'grps' => array('acompletelynewgroup')
);
$ok = $auth->createUser(
$newuser['user'],
$newuser['pass'],
$newuser['name'],
$newuser['mail'],
$newuser['grps']
);
$this->assertTrue($ok, $info);
$check = $auth->getUserData($newuser['user']);
$this->assertEquals($newuser['user'], $check['user'], $info);
$this->assertEquals($newuser['mail'], $check['mail'], $info);
$groups = array_merge($newuser['grps'], array($conf['defaultgroup']));
$this->assertEquals($groups, $check['grps'], $info);
}
}
/**
* run all the tests with the given user, depending on the capabilities
*
* @param auth_plugin_authpdo $auth
* @param $user
*/
protected function runUserTests(auth_plugin_authpdo $auth, $user) {
global $conf;
$info = 'DSN: ' . $auth->getConf('dsn') . ' User:' . $user['user'];
// minimal setup
$this->assertTrue($auth->checkPass($user['user'], $user['pass']), $info);
$check = $auth->getUserData($user['user']);
$this->assertEquals($user['user'], $check['user'], $info);
$this->assertEquals($user['name'], $check['name'], $info);
$this->assertEquals($user['mail'], $check['mail'], $info);
$groups = array_merge($user['grps'], array($conf['defaultgroup']));
$this->assertEquals($groups, $check['grps'], $info);
// getUsers
if($auth->canDo('getUsers')) {
$list = $auth->retrieveUsers(0, -1, array('user' => $user['user']));
$this->assertGreaterThanOrEqual(1, count($list));
$list = $auth->retrieveUsers(0, -1, array('name' => $user['name']));
$this->assertGreaterThanOrEqual(1, count($list));
$list = $auth->retrieveUsers(0, -1, array('mail' => $user['mail']));
$this->assertGreaterThanOrEqual(1, count($list));
}
// getUserCount
if($auth->canDo('getUserCount')) {
$count = $auth->getUserCount(array('user' => $user['user']));
$this->assertGreaterThanOrEqual(1, $count);
$count = $auth->getUserCount(array('name' => $user['name']));
$this->assertGreaterThanOrEqual(1, $count);
$count = $auth->getUserCount(array('mail' => $user['mail']));
$this->assertGreaterThanOrEqual(1, $count);
}
// modGroups
if($auth->canDo('modGroups')) {
$newgroup = 'foobar';
$ok = $auth->modifyUser($user['user'], array('grps' => array($newgroup)));
$this->assertTrue($ok, $info);
$check = $auth->getUserData($user['user']);
$this->assertTrue(in_array($newgroup, $check['grps']), $info);
}
// modPass
if($auth->canDo('modPass')) {
$newpass = 'foobar';
$ok = $auth->modifyUser($user['user'], array('pass' => $newpass));
$this->assertTrue($ok, $info);
$this->assertTrue($auth->checkPass($user['user'], $newpass), $info);
}
// modMail
if($auth->canDo('modMail')) {
$newmail = 'foobar@example.com';
$ok = $auth->modifyUser($user['user'], array('mail' => $newmail));
$this->assertTrue($ok, $info);
$check = $auth->getUserData($user['user']);
$this->assertEquals($newmail, $check['mail'], $info);
}
// modName
if($auth->canDo('modName')) {
$newname = 'FirstName Foobar';
$ok = $auth->modifyUser($user['user'], array('name' => $newname));
$this->assertTrue($ok, $info);
$check = $auth->getUserData($user['user']);
$this->assertEquals($newname, $check['name'], $info);
}
// modLogin
if($auth->canDo('modLogin')) {
$newuser = 'foobar' . $user['user'];
$ok = $auth->modifyUser($user['user'], array('user' => $newuser));
$this->assertTrue($ok, $info);
$check = $auth->getUserData($newuser);
$this->assertEquals($newuser, $check['user'], $info);
// rename back
$ok = $auth->modifyUser($newuser, array('user' => $user['user']));
$this->assertTrue($ok, $info);
}
// delUser
if($auth->canDo('delUser')) {
$num = $auth->deleteUsers(array($user['user']));
$this->assertEquals(1, $num, $info);
$this->assertFalse($auth->getUserData($user['user']), $info);
}
}
/**
* prepares the individual configurations for testing
*
* @return array
*/
public function data_provider() {
$testdata = array();
$files = glob(__DIR__ . "/{$this->driver}/*.php");
foreach($files as $file) {
$dump = preg_replace('/\.php$/', '.sql', $file);
$dbname = 'authpdo_testing_' . basename($file, '.php');
/** @var $data array */
include $file;
$testdata[] = array($dbname, $dump, $data);
}
return $testdata;
}
/**
* This triggers all the tests based on the dumps and configurations
*
* @dataProvider data_provider
* @depends test_requirements
* @param string $dbname Name of the database to use
* @param string $dump The path to the dump file to import
* @param array|string $data config and test user setup. When a string is passed, test is skipped with that msg
*/
public function test_database($dbname, $dump, $data){
global $conf;
if(!is_array($data)) {
$this->markTestSkipped($data);
return;
}
$this->database = $dbname;
$this->createDatabase();
$this->importDatabase($dump);
// Setup the configuration and initialize a new auth object
$conf['plugin']['authpdo'] = array();
$conf['plugin']['authpdo'] = $data['conf'];
$conf['plugin']['authpdo']['dsn'] = "{$this->driver}:dbname={$this->database};host={$this->host};port={$this->port}";
$conf['plugin']['authpdo']['user'] = $this->user;
$conf['plugin']['authpdo']['pass'] = $this->pass;
$conf['plugin']['authpdo']['debug'] = 1;
if($data['passcrypt']) $conf['passcrypt'] = $data['passcrypt'];
$auth = new auth_plugin_authpdo();
$this->runGeneralTests($auth, $data['users']);
foreach($data['users'] as $user) {
$this->runUserTests($auth, $user);
}
$this->dropDatabase();
}
}

View File

@ -0,0 +1,104 @@
<?php
/**
* Confiuration for fluxbb. They have a very simplistic model. There is no separate display name and a user can
* only be in a single group.
*/
/** @noinspection SqlResolve */
$data = array(
'passcrypt' => 'sha1',
'conf' => array(
'select-user' => '
SELECT id AS uid,
username AS user,
username AS name,
password AS hash,
email AS mail
FROM fluy_users
WHERE username = :user
',
'select-user-groups' => '
SELECT g_title AS `group`
FROM fluy_groups G, fluy_users U
WHERE U.id = :uid
AND U.group_id = G.g_id
',
'select-groups' => '
SELECT g_id AS gid, g_title AS `group`
FROM fluy_groups
',
'insert-user' => '
INSERT INTO fluy_users
(group_id, username, password, email)
VALUES (0, :user, :hash, :mail)
',
'delete-user' => '
DELETE FROM fluy_users
WHERE id = :uid
',
'list-users' => '
SELECT DISTINCT username AS user
FROM fluy_users U, fluy_groups G
WHERE U.id = G.g_id
AND G.g_title LIKE :group
AND U.username LIKE :user
AND U.username LIKE :name
AND U.email LIKE :mail
ORDER BY username
LIMIT :limit
OFFSET :start
',
'count-users' => '
SELECT COUNT(DISTINCT username) AS `count`
FROM fluy_users U, fluy_groups G
WHERE U.id = G.g_id
AND G.g_title LIKE :group
AND U.username LIKE :user
AND U.username LIKE :name
AND U.email LIKE :mail
',
'update-user-info' => '', // we can't do this because username = displayname
'update-user-login' => '
UPDATE fluy_users
SET username = :newlogin
WHERE id = :uid
',
'update-user-pass' => '
UPDATE fluy_users
SET password = :hash
WHERE id = :uid
',
'insert-group' => '
INSERT INTO fluy_groups (g_title) VALUES (:group)
',
'join-group' => '
UPDATE fluy_users
SET group_id = :gid
WHERE id = :uid
',
'leave-group' => '
SELECT 1
', // we do a no-op for this
),
'users' => array(
array(
'user' => 'admin',
'pass' => 'pass',
'name' => 'admin',
'mail' => 'admin@example.com',
'grps' =>
array(
0 => 'Administrators',
),
),
array(
'user' => 'test1',
'pass' => 'password',
'name' => 'test1',
'mail' => 'test1@example.com',
'grps' =>
array(
0 => 'test',
),
),
),
);

View File

@ -0,0 +1,136 @@
-- phpMyAdmin SQL Dump
-- version 4.0.10.7
-- http://www.phpmyadmin.net
--
-- Host: localhost:3306
-- Generation Time: Feb 12, 2016 at 03:06 PM
-- Server version: 10.0.23-MariaDB
-- PHP Version: 5.4.31
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
--
-- Database: `dokuwiki_flux570`
--
-- --------------------------------------------------------
--
-- Table structure for table `fluy_groups`
--
CREATE TABLE IF NOT EXISTS `fluy_groups` (
`g_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`g_title` varchar(50) NOT NULL DEFAULT '',
`g_user_title` varchar(50) DEFAULT NULL,
`g_promote_min_posts` int(10) unsigned NOT NULL DEFAULT '0',
`g_promote_next_group` int(10) unsigned NOT NULL DEFAULT '0',
`g_moderator` tinyint(1) NOT NULL DEFAULT '0',
`g_mod_edit_users` tinyint(1) NOT NULL DEFAULT '0',
`g_mod_rename_users` tinyint(1) NOT NULL DEFAULT '0',
`g_mod_change_passwords` tinyint(1) NOT NULL DEFAULT '0',
`g_mod_ban_users` tinyint(1) NOT NULL DEFAULT '0',
`g_mod_promote_users` tinyint(1) NOT NULL DEFAULT '0',
`g_read_board` tinyint(1) NOT NULL DEFAULT '1',
`g_view_users` tinyint(1) NOT NULL DEFAULT '1',
`g_post_replies` tinyint(1) NOT NULL DEFAULT '1',
`g_post_topics` tinyint(1) NOT NULL DEFAULT '1',
`g_edit_posts` tinyint(1) NOT NULL DEFAULT '1',
`g_delete_posts` tinyint(1) NOT NULL DEFAULT '1',
`g_delete_topics` tinyint(1) NOT NULL DEFAULT '1',
`g_post_links` tinyint(1) NOT NULL DEFAULT '1',
`g_set_title` tinyint(1) NOT NULL DEFAULT '1',
`g_search` tinyint(1) NOT NULL DEFAULT '1',
`g_search_users` tinyint(1) NOT NULL DEFAULT '1',
`g_send_email` tinyint(1) NOT NULL DEFAULT '1',
`g_post_flood` smallint(6) NOT NULL DEFAULT '30',
`g_search_flood` smallint(6) NOT NULL DEFAULT '30',
`g_email_flood` smallint(6) NOT NULL DEFAULT '60',
`g_report_flood` smallint(6) NOT NULL DEFAULT '60',
PRIMARY KEY (`g_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;
--
-- Dumping data for table `fluy_groups`
--
INSERT INTO `fluy_groups` (`g_id`, `g_title`, `g_user_title`, `g_promote_min_posts`, `g_promote_next_group`, `g_moderator`, `g_mod_edit_users`, `g_mod_rename_users`, `g_mod_change_passwords`, `g_mod_ban_users`, `g_mod_promote_users`, `g_read_board`, `g_view_users`, `g_post_replies`, `g_post_topics`, `g_edit_posts`, `g_delete_posts`, `g_delete_topics`, `g_post_links`, `g_set_title`, `g_search`, `g_search_users`, `g_send_email`, `g_post_flood`, `g_search_flood`, `g_email_flood`, `g_report_flood`) VALUES
(1, 'Administrators', 'Administrator', 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0),
(2, 'Moderators', 'Moderator', 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0),
(3, 'Guests', NULL, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 60, 30, 0, 0),
(4, 'Members', NULL, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 60, 30, 60, 60),
(5, 'test', NULL, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 60, 30, 60, 60);
-- --------------------------------------------------------
--
-- Table structure for table `fluy_users`
--
CREATE TABLE IF NOT EXISTS `fluy_users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`group_id` int(10) unsigned NOT NULL DEFAULT '3',
`username` varchar(200) NOT NULL DEFAULT '',
`password` varchar(40) NOT NULL DEFAULT '',
`email` varchar(80) NOT NULL DEFAULT '',
`title` varchar(50) DEFAULT NULL,
`realname` varchar(40) DEFAULT NULL,
`url` varchar(100) DEFAULT NULL,
`jabber` varchar(80) DEFAULT NULL,
`icq` varchar(12) DEFAULT NULL,
`msn` varchar(80) DEFAULT NULL,
`aim` varchar(30) DEFAULT NULL,
`yahoo` varchar(30) DEFAULT NULL,
`location` varchar(30) DEFAULT NULL,
`signature` text,
`disp_topics` tinyint(3) unsigned DEFAULT NULL,
`disp_posts` tinyint(3) unsigned DEFAULT NULL,
`email_setting` tinyint(1) NOT NULL DEFAULT '1',
`notify_with_post` tinyint(1) NOT NULL DEFAULT '0',
`auto_notify` tinyint(1) NOT NULL DEFAULT '0',
`show_smilies` tinyint(1) NOT NULL DEFAULT '1',
`show_img` tinyint(1) NOT NULL DEFAULT '1',
`show_img_sig` tinyint(1) NOT NULL DEFAULT '1',
`show_avatars` tinyint(1) NOT NULL DEFAULT '1',
`show_sig` tinyint(1) NOT NULL DEFAULT '1',
`timezone` float NOT NULL DEFAULT '0',
`dst` tinyint(1) NOT NULL DEFAULT '0',
`time_format` tinyint(1) NOT NULL DEFAULT '0',
`date_format` tinyint(1) NOT NULL DEFAULT '0',
`language` varchar(25) NOT NULL DEFAULT 'English',
`style` varchar(25) NOT NULL DEFAULT 'Air',
`num_posts` int(10) unsigned NOT NULL DEFAULT '0',
`last_post` int(10) unsigned DEFAULT NULL,
`last_search` int(10) unsigned DEFAULT NULL,
`last_email_sent` int(10) unsigned DEFAULT NULL,
`last_report_sent` int(10) unsigned DEFAULT NULL,
`registered` int(10) unsigned NOT NULL DEFAULT '0',
`registration_ip` varchar(39) NOT NULL DEFAULT '0.0.0.0',
`last_visit` int(10) unsigned NOT NULL DEFAULT '0',
`admin_note` varchar(30) DEFAULT NULL,
`activate_string` varchar(80) DEFAULT NULL,
`activate_key` varchar(8) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `fluy_users_username_idx` (`username`(25)),
KEY `fluy_users_registered_idx` (`registered`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
--
-- Dumping data for table `fluy_users`
--
INSERT INTO `fluy_users` (`id`, `group_id`, `username`, `password`, `email`, `title`, `realname`, `url`, `jabber`, `icq`, `msn`, `aim`, `yahoo`, `location`, `signature`, `disp_topics`, `disp_posts`, `email_setting`, `notify_with_post`, `auto_notify`, `show_smilies`, `show_img`, `show_img_sig`, `show_avatars`, `show_sig`, `timezone`, `dst`, `time_format`, `date_format`, `language`, `style`, `num_posts`, `last_post`, `last_search`, `last_email_sent`, `last_report_sent`, `registered`, `registration_ip`, `last_visit`, `admin_note`, `activate_string`, `activate_key`) VALUES
(1, 3, 'Guest', 'Guest', 'Guest', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 'English', 'Air', 0, NULL, NULL, NULL, NULL, 0, '0.0.0.0', 0, NULL, NULL, NULL),
(2, 1, 'admin', '9d4e1e23bd5b727046a9e3b4b7db57bd8d6ee684', 'admin@example.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 'English', 'Air', 1, 1455307304, NULL, NULL, NULL, 1455307304, '86.56.56.211', 1455307448, NULL, NULL, NULL),
(3, 5, 'test1', '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8', 'test1@example.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 'English', 'Air', 0, NULL, NULL, NULL, NULL, 1455307527, '86.56.56.217', 1455307529, NULL, NULL, NULL);
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

View File

@ -0,0 +1,115 @@
<?php
/**
* Basic Wordpress config
*
* Wordpress has no proper groups. This configures the default access permissions as groups. Better group
* support is available through a Wrdpress plugin
*/
/** @noinspection SqlResolve */
$data = array(
'passcrypt' => 'pmd5',
'conf' => array(
'select-user' => '
SELECT ID AS uid,
user_login AS user,
display_name AS name,
user_pass AS hash,
user_email AS mail
FROM wpvk_users
WHERE user_login = :user
',
'select-user-groups' => '
SELECT CONCAT("group",meta_value) AS `group`
FROM wpvk_usermeta
WHERE user_id = :uid
AND meta_key = "wpvk_user_level"
',
'select-groups' => '',
'insert-user' => '',
'delete-user' => '',
'list-users' => '
SELECT DISTINCT user_login AS user
FROM wpvk_users U, wpvk_usermeta M
WHERE U.ID = M.user_id
AND M.meta_key = "wpvk_user_level"
AND CONCAT("group", M.meta_value) LIKE :group
AND U.user_login LIKE :user
AND U.display_name LIKE :name
AND U.user_email LIKE :mail
ORDER BY user_login
LIMIT :limit
OFFSET :start
',
'count-users' => '
SELECT COUNT(DISTINCT user_login) as `count`
FROM wpvk_users U, wpvk_usermeta M
WHERE U.ID = M.user_id
AND M.meta_key = "wpvk_user_level"
AND CONCAT("group", M.meta_value) LIKE :group
AND U.user_login LIKE :user
AND U.display_name LIKE :name
AND U.user_email LIKE :mail
',
'update-user-info' => '
UPDATE wpvk_users
SET display_name = :name,
user_email = :mail
WHERE ID = :uid
',
'update-user-login' => '
UPDATE wpvk_users
SET user_login = :newlogin
WHERE ID = :uid
',
'update-user-pass' => '
UPDATE wpvk_users
SET user_pass = :hash
WHERE ID = :uid
',
'insert-group' => '',
'join-group' => '',
'leave-group' => '',
),
'users' => array(
array(
'user' => 'admin',
'pass' => 'pass',
'name' => 'admin',
'mail' => 'admin@example.com',
'grps' =>
array(
0 => 'group10',
),
),
array(
'user' => 'test1',
'pass' => 'pass',
'name' => 'Test1 Subscriber',
'mail' => 'test1@example.com',
'grps' =>
array(
0 => 'group0',
),
),
array(
'user' => 'test2',
'pass' => 'pass',
'name' => 'Test2 Contributor',
'mail' => 'test2@example.com',
'grps' =>
array(
0 => 'group1',
),
),
array(
'user' => 'test3',
'pass' => 'pass',
'name' => 'Test3 Author',
'mail' => 'test3@example.com',
'grps' =>
array(
0 => 'group2',
),
),
),
);

View File

@ -0,0 +1,130 @@
-- phpMyAdmin SQL Dump
-- version 4.0.10.7
-- http://www.phpmyadmin.net
--
-- Host: localhost:3306
-- Generation Time: Feb 10, 2016 at 02:02 PM
-- Server version: 10.0.23-MariaDB
-- PHP Version: 5.4.31
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
--
-- Database: `dokuwiki_wp240`
--
-- --------------------------------------------------------
--
-- Table structure for table `wpvk_usermeta`
--
CREATE TABLE IF NOT EXISTS `wpvk_usermeta` (
`umeta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) unsigned NOT NULL DEFAULT '0',
`meta_key` varchar(255) DEFAULT NULL,
`meta_value` longtext,
PRIMARY KEY (`umeta_id`),
KEY `user_id` (`user_id`),
KEY `meta_key` (`meta_key`(191))
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=52 ;
--
-- Dumping data for table `wpvk_usermeta`
--
INSERT INTO `wpvk_usermeta` (`umeta_id`, `user_id`, `meta_key`, `meta_value`) VALUES
(1, 1, 'nickname', 'admin'),
(2, 1, 'first_name', 'First'),
(3, 1, 'last_name', 'Last'),
(4, 1, 'description', ''),
(5, 1, 'rich_editing', 'true'),
(6, 1, 'comment_shortcuts', 'false'),
(7, 1, 'admin_color', 'fresh'),
(8, 1, 'use_ssl', '0'),
(9, 1, 'show_admin_bar_front', 'true'),
(10, 1, 'wpvk_capabilities', 'a:1:{s:13:"administrator";b:1;}'),
(11, 1, 'wpvk_user_level', '10'),
(12, 1, 'dismissed_wp_pointers', ''),
(13, 1, 'show_welcome_panel', '1'),
(14, 1, 'session_tokens', 'a:1:{s:64:"3e9f99a7068bf3fb79f50e111b6ef10f599beb466c27152205d4b89360c5004d";a:4:{s:10:"expiration";i:1456340157;s:2:"ip";s:12:"86.56.56.217";s:2:"ua";s:104:"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36";s:5:"login";i:1455130557;}}'),
(15, 1, 'wpvk_dashboard_quick_press_last_post_id', '3'),
(16, 2, 'nickname', 'test1'),
(17, 2, 'first_name', 'Test1'),
(18, 2, 'last_name', 'Subscriber'),
(19, 2, 'description', ''),
(20, 2, 'rich_editing', 'true'),
(21, 2, 'comment_shortcuts', 'false'),
(22, 2, 'admin_color', 'fresh'),
(23, 2, 'use_ssl', '0'),
(24, 2, 'show_admin_bar_front', 'true'),
(25, 2, 'wpvk_capabilities', 'a:1:{s:10:"subscriber";b:1;}'),
(26, 2, 'wpvk_user_level', '0'),
(27, 2, 'dismissed_wp_pointers', ''),
(28, 3, 'nickname', 'test2'),
(29, 3, 'first_name', 'Test2'),
(30, 3, 'last_name', 'Contributor'),
(31, 3, 'description', ''),
(32, 3, 'rich_editing', 'true'),
(33, 3, 'comment_shortcuts', 'false'),
(34, 3, 'admin_color', 'fresh'),
(35, 3, 'use_ssl', '0'),
(36, 3, 'show_admin_bar_front', 'true'),
(37, 3, 'wpvk_capabilities', 'a:1:{s:11:"contributor";b:1;}'),
(38, 3, 'wpvk_user_level', '1'),
(39, 3, 'dismissed_wp_pointers', ''),
(40, 4, 'nickname', 'test3'),
(41, 4, 'first_name', 'Test3'),
(42, 4, 'last_name', 'Author'),
(43, 4, 'description', ''),
(44, 4, 'rich_editing', 'true'),
(45, 4, 'comment_shortcuts', 'false'),
(46, 4, 'admin_color', 'fresh'),
(47, 4, 'use_ssl', '0'),
(48, 4, 'show_admin_bar_front', 'true'),
(49, 4, 'wpvk_capabilities', 'a:1:{s:6:"author";b:1;}'),
(50, 4, 'wpvk_user_level', '2'),
(51, 4, 'dismissed_wp_pointers', '');
-- --------------------------------------------------------
--
-- Table structure for table `wpvk_users`
--
CREATE TABLE IF NOT EXISTS `wpvk_users` (
`ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_login` varchar(60) NOT NULL DEFAULT '',
`user_pass` varchar(255) NOT NULL DEFAULT '',
`user_nicename` varchar(50) NOT NULL DEFAULT '',
`user_email` varchar(100) NOT NULL DEFAULT '',
`user_url` varchar(100) NOT NULL DEFAULT '',
`user_registered` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`user_activation_key` varchar(255) NOT NULL DEFAULT '',
`user_status` int(11) NOT NULL DEFAULT '0',
`display_name` varchar(250) NOT NULL DEFAULT '',
PRIMARY KEY (`ID`),
KEY `user_login_key` (`user_login`),
KEY `user_nicename` (`user_nicename`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
--
-- Dumping data for table `wpvk_users`
--
INSERT INTO `wpvk_users` (`ID`, `user_login`, `user_pass`, `user_nicename`, `user_email`, `user_url`, `user_registered`, `user_activation_key`, `user_status`, `display_name`) VALUES
(1, 'admin', '$P$BlO2X5nM.djjfsPjOBHz97GHZmpBRr.', 'admin', 'admin@example.com', '', '2016-02-10 18:55:26', '', 0, 'admin'),
(2, 'test1', '$P$B3BfWySh.ymDeURK0OXMFo4vh4JprO0', 'test1', 'test1@example.com', '', '2016-02-10 18:57:47', '', 0, 'Test1 Subscriber'),
(3, 'test2', '$P$BMNEUEo5nalKEswryuP69KXEfz8Y.z.', 'test2', 'test2@example.com', '', '2016-02-10 18:58:32', '', 0, 'Test2 Contributor'),
(4, 'test3', '$P$B2PP3AP6NF/jLO0HYu3xf577rBnp2j.', 'test3', 'test3@example.com', '', '2016-02-10 18:59:19', '', 0, 'Test3 Author');
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

View File

@ -0,0 +1,13 @@
<?php
/**
* pgsql tests for the authpdo plugin
*
* @group plugin_authpdo
* @group plugins
*/
class pgsql_plugin_authpdo_test extends mysql_plugin_authpdo_test {
protected $driver = 'pgsql';
}

View File

@ -0,0 +1,140 @@
<?php
/**
* Django application config
*
*/
/** @noinspection SqlResolve */
$data = array(
'passcrypt' => 'djangopbkdf2_sha256',
'conf' => array(
'select-user' => '
SELECT id AS uid,
username AS "user",
CONCAT_WS(\' \', first_name, last_name) AS name,
password AS hash,
email AS mail
FROM auth_user
WHERE username = :user
',
'select-user-groups' => '
SELECT G.name AS "group"
FROM auth_group G, auth_user_groups UG
WHERE UG.user_id = :uid
AND UG.group_id = G.id
',
'select-groups' => '
SELECT id AS gid, name AS "group"
FROM auth_group
',
'insert-user' => '
INSERT INTO auth_user
(password, is_superuser, username, first_name, last_name, email, is_staff, is_active, date_joined)
VALUES (:hash, false, :user, SPLIT_PART(:name,\' \',1), SPLIT_PART(:name,\' \',2), :mail, false, true, NOW())
',
'delete-user' => '
DELETE FROM auth_user_user_permissions
WHERE user_id = :uid
;
DELETE FROM auth_user
WHERE id = :uid
',
'list-users' => '
SELECT DISTINCT U.username AS "user"
FROM auth_user U, auth_user_groups UG, auth_group G
WHERE U.id = UG.user_id
AND G.id = UG.group_id
AND G.name LIKE :group
AND U.username LIKE :user
AND CONCAT_WS(\' \', U.first_name, U.last_name) LIKE :name
AND U.email LIKE :mail
ORDER BY username
LIMIT :limit
OFFSET :start
',
'count-users' => '
SELECT COUNT(DISTINCT U.username) AS count
FROM auth_user U, auth_user_groups UG, auth_group G
WHERE U.id = UG.user_id
AND G.id = UG.group_id
AND G.name LIKE :group
AND U.username LIKE :user
AND CONCAT_WS(\' \', U.first_name, U.last_name) LIKE :name
AND U.email LIKE :mail
',
'update-user-info' => '
UPDATE auth_user
SET first_name = SPLIT_PART(:name,\' \',1),
last_name = SPLIT_PART(:name,\' \',2),
email = :mail
WHERE id = :uid
',
'update-user-login' => '
UPDATE auth_user
SET username = :newlogin
WHERE id = :uid
',
'update-user-pass' => '
UPDATE auth_user
SET password = :hash
WHERE id = :uid
',
'insert-group' => '
INSERT INTO auth_group (name) VALUES (:group)
',
'join-group' => '
INSERT INTO auth_user_groups (user_id, group_id) VALUES (:uid, :gid)
',
'leave-group' => '
DELETE FROM auth_user_groups
WHERE user_id = :uid
AND group_id = :gid
',
),
'users' => array(
array(
'user' => 'test-billing',
'pass' => 'P4zzW0rd!',
'name' => 'Joana Gröschel',
'mail' => 'jg@billing.com',
'grps' =>
array(
0 => 'Billing',
),
),
array(
'user' => 'test-kunde',
'pass' => 'P4zzW0rd!',
'name' => 'Niels Buchberger',
'mail' => 'ng@kunde.com',
'grps' =>
array(
0 => 'Kunden',
),
),
array(
'user' => 'test-mitarbeiter',
'pass' => 'P4zzW0rd!',
'name' => 'Claus Wernke',
'mail' => 'cw@mitarbeiter.com',
'grps' =>
array(
0 => 'Mitarbeiter',
),
),
array(
'user' => 'test-projektleiter',
'pass' => 'P4zzW0rd!',
'name' => 'Sascha Weiher',
'mail' => 'sw@projektleiter.com',
'grps' =>
array(
0 => 'Projektleiter',
),
),
),
);
// passwords in the dump use the newest format, we need PHP support for that
if(!function_exists('hash_pbkdf2') || !in_array('sha256', hash_algos())){
$data = 'missing pbkdf2 hash support to check passwords - django test has to be skipped';
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,192 @@
<?php
/**
* Class testable_auth_plugin_authpdo
*
* makes protected methods public for testing
*/
class testable_auth_plugin_authpdo extends auth_plugin_authpdo {
public function getPluginName() {
return 'authpdo';
}
public function _selectGroups() {
return parent::_selectGroups();
}
public function addGroup($group) {
return parent::addGroup($group);
}
}
/**
* General tests for the authpdo plugin
*
* @group plugin_authpdo
* @group plugins
*/
class sqlite_plugin_authpdo_test extends DokuWikiTest {
protected $dbfile;
public function test_pdo_sqlite_support() {
if(!class_exists('PDO') || !in_array('sqlite',PDO::getAvailableDrivers())) {
$this->markTestSkipped('skipping all authpdo tests for sqlite. Need PDO_sqlite extension');
}
}
public function setUp() {
parent::setUp();
$this->dbfile = tempnam('/tmp/', 'pluginpdo_test_');
copy(__DIR__ . '/test.sqlite3', $this->dbfile);
global $conf;
$conf['plugin']['authpdo']['debug'] = 1;
$conf['plugin']['authpdo']['dsn'] = 'sqlite:' . $this->dbfile;
$conf['plugin']['authpdo']['user'] = '';
$conf['plugin']['authpdo']['pass'] = '';
$conf['plugin']['authpdo']['select-user'] = 'SELECT id AS uid, login AS user, name, pass AS clear, mail FROM user WHERE login = :user';
$conf['plugin']['authpdo']['select-user-groups'] = 'SELECT * FROM member AS m, "group" AS g WHERE m.gid = g.id AND m.uid = :uid';
$conf['plugin']['authpdo']['select-groups'] = 'SELECT id AS gid, "group" FROM "group"';
$conf['plugin']['authpdo']['insert-user'] = 'INSERT INTO user (login, pass, name, mail) VALUES (:user, :hash, :name, :mail)';
$conf['plugin']['authpdo']['delete-user'] = 'DELETE FROM user WHERE id = :uid';
$conf['plugin']['authpdo']['list-users'] = 'SELECT DISTINCT login as user
FROM user U, member M, "group" G
WHERE U.id = M.uid
AND M.gid = G.id
AND G."group" LIKE :group
AND U.login LIKE :user
AND U.name LIKE :name
AND U.mail LIKE :mail
ORDER BY login
LIMIT :start,:limit';
$conf['plugin']['authpdo']['count-users'] = 'SELECT COUNT(DISTINCT login) as count
FROM user U, member M, "group" G
WHERE U.id = M.uid
AND M.gid = G.id
AND G."group" LIKE :group
AND U.login LIKE :user
AND U.name LIKE :name
AND U.mail LIKE :mail';
$conf['plugin']['authpdo']['update-user-login'] = 'UPDATE user SET login = :newlogin WHERE id = :uid';
$conf['plugin']['authpdo']['update-user-info'] = 'UPDATE user SET name = :name, mail = :mail WHERE id = :uid';
$conf['plugin']['authpdo']['update-user-pass'] = 'UPDATE user SET pass = :hash WHERE id = :uid';
$conf['plugin']['authpdo']['insert-group'] = 'INSERT INTO "group" ("group") VALUES (:group)';
$conf['plugin']['authpdo']['join-group'] = 'INSERT INTO member (uid, gid) VALUES (:uid, :gid)';
$conf['plugin']['authpdo']['leave-group'] = 'DELETE FROM member WHERE uid = :uid AND gid = :gid';
}
public function tearDown() {
parent::tearDown();
unlink($this->dbfile);
}
/**
* @depends test_pdo_sqlite_support
*/
public function test_internals() {
$auth = new testable_auth_plugin_authpdo();
$groups = $auth->_selectGroups();
$this->assertArrayHasKey('user', $groups);
$this->assertEquals(1, $groups['user']['gid']);
$this->assertArrayHasKey('admin', $groups);
$this->assertEquals(2, $groups['admin']['gid']);
$ok = $auth->addGroup('test');
$this->assertTrue($ok);
$groups = $auth->_selectGroups();
$this->assertArrayHasKey('test', $groups);
$this->assertEquals(3, $groups['test']['gid']);
}
/**
* @depends test_pdo_sqlite_support
*/
public function test_userinfo() {
global $conf;
$auth = new auth_plugin_authpdo();
// clear text pasword (with default config above
$this->assertFalse($auth->checkPass('nobody', 'nope'));
$this->assertFalse($auth->checkPass('admin', 'nope'));
$this->assertTrue($auth->checkPass('admin', 'password'));
// now with a hashed password
$conf['plugin']['authpdo']['select-user'] = 'SELECT id AS uid, login AS user, name, pass AS hash, mail FROM user WHERE login = :user';
$this->assertFalse($auth->checkPass('admin', 'password'));
$this->assertFalse($auth->checkPass('user', md5('password')));
// access user data
$info = $auth->getUserData('admin');
$this->assertEquals('admin', $info['user']);
$this->assertEquals('The Admin', $info['name']);
$this->assertEquals('admin@example.com', $info['mail']);
$this->assertEquals(array('admin', 'user'), $info['grps']);
// group retrieval
$this->assertEquals(array('admin', 'user'), $auth->retrieveGroups());
$this->assertEquals(array('user'), $auth->retrieveGroups(1));
$this->assertEquals(array('admin'), $auth->retrieveGroups(0, 1));
// user creation
$auth->createUser('test', 'password', 'A Test user', 'test@example.com', array('newgroup'));
$info = $auth->getUserData('test');
$this->assertEquals('test', $info['user']);
$this->assertEquals('A Test user', $info['name']);
$this->assertEquals('test@example.com', $info['mail']);
$this->assertEquals(array('newgroup', 'user'), $info['grps']);
$this->assertEquals(array('admin', 'newgroup', 'user'), $auth->retrieveGroups());
// user modification
$auth->modifyUser('test', array('user' => 'tester', 'name' => 'The Test User', 'pass' => 'secret'));
$info = $auth->getUserData('tester');
$this->assertEquals('tester', $info['user']);
$this->assertEquals('The Test User', $info['name']);
$this->assertTrue($auth->checkPass('tester','secret'));
// move user to different groups
$auth->modifyUser('tester', array('grps' => array('user', 'admin', 'another')));
$info = $auth->getUserData('tester');
$this->assertEquals(array('admin', 'another', 'user'), $info['grps']);
// list users
$users = $auth->retrieveUsers();
$this->assertEquals(array('admin', 'tester', 'user'), $users);
$users = $auth->retrieveUsers(1); // offset
$this->assertEquals(array('tester', 'user'), $users);
$users = $auth->retrieveUsers(1, 1); // offset + limit
$this->assertEquals(array('tester'), $users);
$users = $auth->retrieveUsers(0, -1, array('group' => 'admin')); // full group
$this->assertEquals(array('admin', 'tester'), $users);
$count = $auth->getUserCount(array('group' => 'admin'));
$this->assertEquals(2, $count);
$users = $auth->retrieveUsers(0, -1, array('group' => 'dmi')); // substring
$this->assertEquals(array('admin', 'tester'), $users);
$count = $auth->getUserCount(array('group' => 'dmi'));
$this->assertEquals(2, $count);
$users = $auth->retrieveUsers(0, -1, array('user' => 'dmi')); // substring
$this->assertEquals(array('admin'), $users);
$count = $auth->getUserCount(array('user' => 'dmi'));
$this->assertEquals(1, $count);
// delete user
$num = $auth->deleteUsers(array('tester', 'foobar'));
$this->assertEquals(1, $num);
}
}

Binary file not shown.

View File

@ -0,0 +1,751 @@
<?php
/**
* DokuWiki Plugin authpdo (Auth Component)
*
* @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
* @author Andreas Gohr <andi@splitbrain.org>
*/
// must be run within Dokuwiki
if(!defined('DOKU_INC')) die();
/**
* Class auth_plugin_authpdo
*/
class auth_plugin_authpdo extends DokuWiki_Auth_Plugin {
/** @var PDO */
protected $pdo;
/** @var null|array The list of all groups */
protected $groupcache = null;
/**
* Constructor.
*/
public function __construct() {
parent::__construct(); // for compatibility
if(!class_exists('PDO')) {
$this->_debug('PDO extension for PHP not found.', -1, __LINE__);
$this->success = false;
return;
}
if(!$this->getConf('dsn')) {
$this->_debug('No DSN specified', -1, __LINE__);
$this->success = false;
return;
}
try {
$this->pdo = new PDO(
$this->getConf('dsn'),
$this->getConf('user'),
conf_decodeString($this->getConf('pass')),
array(
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // always fetch as array
PDO::ATTR_EMULATE_PREPARES => true, // emulating prepares allows us to reuse param names
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // we want exceptions, not error codes
)
);
} catch(PDOException $e) {
$this->_debug($e);
msg($this->getLang('connectfail'), -1);
$this->success = false;
return;
}
// can Users be created?
$this->cando['addUser'] = $this->_chkcnf(
array(
'select-user',
'select-user-groups',
'select-groups',
'insert-user',
'insert-group',
'join-group'
)
);
// can Users be deleted?
$this->cando['delUser'] = $this->_chkcnf(
array(
'select-user',
'select-user-groups',
'select-groups',
'leave-group',
'delete-user'
)
);
// can login names be changed?
$this->cando['modLogin'] = $this->_chkcnf(
array(
'select-user',
'select-user-groups',
'update-user-login'
)
);
// can passwords be changed?
$this->cando['modPass'] = $this->_chkcnf(
array(
'select-user',
'select-user-groups',
'update-user-pass'
)
);
// can real names and emails be changed?
$this->cando['modName'] = $this->cando['modMail'] = $this->_chkcnf(
array(
'select-user',
'select-user-groups',
'update-user-info'
)
);
// can groups be changed?
$this->cando['modGroups'] = $this->_chkcnf(
array(
'select-user',
'select-user-groups',
'select-groups',
'leave-group',
'join-group',
'insert-group'
)
);
// can a filtered list of users be retrieved?
$this->cando['getUsers'] = $this->_chkcnf(
array(
'list-users'
)
);
// can the number of users be retrieved?
$this->cando['getUserCount'] = $this->_chkcnf(
array(
'count-users'
)
);
// can a list of available groups be retrieved?
$this->cando['getGroups'] = $this->_chkcnf(
array(
'select-groups'
)
);
$this->success = true;
}
/**
* Check user+password
*
* @param string $user the user name
* @param string $pass the clear text password
* @return bool
*/
public function checkPass($user, $pass) {
$data = $this->_selectUser($user);
if($data == false) return false;
if(isset($data['hash'])) {
// hashed password
$passhash = new PassHash();
return $passhash->verify_hash($pass, $data['hash']);
} else {
// clear text password in the database O_o
return ($pass == $data['clear']);
}
}
/**
* Return user info
*
* Returns info about the given user needs to contain
* at least these fields:
*
* name string full name of the user
* mail string email addres of the user
* grps array list of groups the user is in
*
* @param string $user the user name
* @param bool $requireGroups whether or not the returned data must include groups
* @return array|bool containing user data or false
*/
public function getUserData($user, $requireGroups = true) {
$data = $this->_selectUser($user);
if($data == false) return false;
if(isset($data['hash'])) unset($data['hash']);
if(isset($data['clean'])) unset($data['clean']);
if($requireGroups) {
$data['grps'] = $this->_selectUserGroups($data);
if($data['grps'] === false) return false;
}
return $data;
}
/**
* Create a new User [implement only where required/possible]
*
* Returns false if the user already exists, null when an error
* occurred and true if everything went well.
*
* The new user HAS TO be added to the default group by this
* function!
*
* Set addUser capability when implemented
*
* @param string $user
* @param string $clear
* @param string $name
* @param string $mail
* @param null|array $grps
* @return bool|null
*/
public function createUser($user, $clear, $name, $mail, $grps = null) {
global $conf;
if(($info = $this->getUserData($user, false)) !== false) {
msg($this->getLang('userexists'), -1);
return false; // user already exists
}
// prepare data
if($grps == null) $grps = array();
array_unshift($grps, $conf['defaultgroup']);
$grps = array_unique($grps);
$hash = auth_cryptPassword($clear);
$userdata = compact('user', 'clear', 'hash', 'name', 'mail');
// action protected by transaction
$this->pdo->beginTransaction();
{
// insert the user
$ok = $this->_query($this->getConf('insert-user'), $userdata);
if($ok === false) goto FAIL;
$userdata = $this->getUserData($user, false);
if($userdata === false) goto FAIL;
// create all groups that do not exist, the refetch the groups
$allgroups = $this->_selectGroups();
foreach($grps as $group) {
if(!isset($allgroups[$group])) {
$ok = $this->addGroup($group);
if($ok === false) goto FAIL;
}
}
$allgroups = $this->_selectGroups();
// add user to the groups
foreach($grps as $group) {
$ok = $this->_joinGroup($userdata, $allgroups[$group]);
if($ok === false) goto FAIL;
}
}
$this->pdo->commit();
return true;
// something went wrong, rollback
FAIL:
$this->pdo->rollBack();
$this->_debug('Transaction rolled back', 0, __LINE__);
msg($this->getLang('writefail'), -1);
return null; // return error
}
/**
* Modify user data
*
* @param string $user nick of the user to be changed
* @param array $changes array of field/value pairs to be changed (password will be clear text)
* @return bool
*/
public function modifyUser($user, $changes) {
// secure everything in transaction
$this->pdo->beginTransaction();
{
$olddata = $this->getUserData($user);
$oldgroups = $olddata['grps'];
unset($olddata['grps']);
// changing the user name?
if(isset($changes['user'])) {
if($this->getUserData($changes['user'], false)) goto FAIL;
$params = $olddata;
$params['newlogin'] = $changes['user'];
$ok = $this->_query($this->getConf('update-user-login'), $params);
if($ok === false) goto FAIL;
}
// changing the password?
if(isset($changes['pass'])) {
$params = $olddata;
$params['clear'] = $changes['pass'];
$params['hash'] = auth_cryptPassword($changes['pass']);
$ok = $this->_query($this->getConf('update-user-pass'), $params);
if($ok === false) goto FAIL;
}
// changing info?
if(isset($changes['mail']) || isset($changes['name'])) {
$params = $olddata;
if(isset($changes['mail'])) $params['mail'] = $changes['mail'];
if(isset($changes['name'])) $params['name'] = $changes['name'];
$ok = $this->_query($this->getConf('update-user-info'), $params);
if($ok === false) goto FAIL;
}
// changing groups?
if(isset($changes['grps'])) {
$allgroups = $this->_selectGroups();
// remove membership for previous groups
foreach($oldgroups as $group) {
if(!in_array($group, $changes['grps']) && isset($allgroups[$group])) {
$ok = $this->_leaveGroup($olddata, $allgroups[$group]);
if($ok === false) goto FAIL;
}
}
// create all new groups that are missing
$added = 0;
foreach($changes['grps'] as $group) {
if(!isset($allgroups[$group])) {
$ok = $this->addGroup($group);
if($ok === false) goto FAIL;
$added++;
}
}
// reload group info
if($added > 0) $allgroups = $this->_selectGroups();
// add membership for new groups
foreach($changes['grps'] as $group) {
if(!in_array($group, $oldgroups)) {
$ok = $this->_joinGroup($olddata, $allgroups[$group]);
if($ok === false) goto FAIL;
}
}
}
}
$this->pdo->commit();
return true;
// something went wrong, rollback
FAIL:
$this->pdo->rollBack();
$this->_debug('Transaction rolled back', 0, __LINE__);
msg($this->getLang('writefail'), -1);
return false; // return error
}
/**
* Delete one or more users
*
* Set delUser capability when implemented
*
* @param array $users
* @return int number of users deleted
*/
public function deleteUsers($users) {
$count = 0;
foreach($users as $user) {
if($this->_deleteUser($user)) $count++;
}
return $count;
}
/**
* Bulk retrieval of user data [implement only where required/possible]
*
* Set getUsers capability when implemented
*
* @param int $start index of first user to be returned
* @param int $limit max number of users to be returned
* @param array $filter array of field/pattern pairs, null for no filter
* @return array list of userinfo (refer getUserData for internal userinfo details)
*/
public function retrieveUsers($start = 0, $limit = -1, $filter = null) {
if($limit < 0) $limit = 10000; // we don't support no limit
if(is_null($filter)) $filter = array();
foreach(array('user', 'name', 'mail', 'group') as $key) {
if(!isset($filter[$key])) {
$filter[$key] = '%';
} else {
$filter[$key] = '%' . $filter[$key] . '%';
}
}
$filter['start'] = (int) $start;
$filter['end'] = (int) $start + $limit;
$filter['limit'] = (int) $limit;
$result = $this->_query($this->getConf('list-users'), $filter);
if(!$result) return array();
$users = array();
foreach($result as $row) {
if(!isset($row['user'])) {
$this->_debug("Statement did not return 'user' attribute", -1, __LINE__);
return array();
}
$users[] = $row['user'];
}
return $users;
}
/**
* Return a count of the number of user which meet $filter criteria
*
* @param array $filter array of field/pattern pairs, empty array for no filter
* @return int
*/
public function getUserCount($filter = array()) {
if(is_null($filter)) $filter = array();
foreach(array('user', 'name', 'mail', 'group') as $key) {
if(!isset($filter[$key])) {
$filter[$key] = '%';
} else {
$filter[$key] = '%' . $filter[$key] . '%';
}
}
$result = $this->_query($this->getConf('count-users'), $filter);
if(!$result || !isset($result[0]['count'])) {
$this->_debug("Statement did not return 'count' attribute", -1, __LINE__);
}
return isset($result[0]['count']);
}
/**
* Create a new group with the given name
*
* @param string $group
* @return bool
*/
public function addGroup($group) {
$sql = $this->getConf('insert-group');
$result = $this->_query($sql, array(':group' => $group));
$this->_clearGroupCache();
if($result === false) return false;
return true;
}
/**
* Retrieve groups
*
* Set getGroups capability when implemented
*
* @param int $start
* @param int $limit
* @return array
*/
public function retrieveGroups($start = 0, $limit = 0) {
$groups = array_keys($this->_selectGroups());
if($groups === false) return array();
if(!$limit) {
return array_splice($groups, $start);
} else {
return array_splice($groups, $start, $limit);
}
}
/**
* Select data of a specified user
*
* @param string $user the user name
* @return bool|array user data, false on error
*/
protected function _selectUser($user) {
$sql = $this->getConf('select-user');
$result = $this->_query($sql, array(':user' => $user));
if(!$result) return false;
if(count($result) > 1) {
$this->_debug('Found more than one matching user', -1, __LINE__);
return false;
}
$data = array_shift($result);
$dataok = true;
if(!isset($data['user'])) {
$this->_debug("Statement did not return 'user' attribute", -1, __LINE__);
$dataok = false;
}
if(!isset($data['hash']) && !isset($data['clear'])) {
$this->_debug("Statement did not return 'clear' or 'hash' attribute", -1, __LINE__);
$dataok = false;
}
if(!isset($data['name'])) {
$this->_debug("Statement did not return 'name' attribute", -1, __LINE__);
$dataok = false;
}
if(!isset($data['mail'])) {
$this->_debug("Statement did not return 'mail' attribute", -1, __LINE__);
$dataok = false;
}
if(!$dataok) return false;
return $data;
}
/**
* Delete a user after removing all their group memberships
*
* @param string $user
* @return bool true when the user was deleted
*/
protected function _deleteUser($user) {
$this->pdo->beginTransaction();
{
$userdata = $this->getUserData($user);
if($userdata === false) goto FAIL;
$allgroups = $this->_selectGroups();
// remove group memberships (ignore errors)
foreach($userdata['grps'] as $group) {
if(isset($allgroups[$group])) {
$this->_leaveGroup($userdata, $allgroups[$group]);
}
}
$ok = $this->_query($this->getConf('delete-user'), $userdata);
if($ok === false) goto FAIL;
}
$this->pdo->commit();
return true;
FAIL:
$this->pdo->rollBack();
return false;
}
/**
* Select all groups of a user
*
* @param array $userdata The userdata as returned by _selectUser()
* @return array|bool list of group names, false on error
*/
protected function _selectUserGroups($userdata) {
global $conf;
$sql = $this->getConf('select-user-groups');
$result = $this->_query($sql, $userdata);
if($result === false) return false;
$groups = array($conf['defaultgroup']); // always add default config
foreach($result as $row) {
if(!isset($row['group'])) {
$this->_debug("No 'group' field returned in select-user-groups statement");
return false;
}
$groups[] = $row['group'];
}
$groups = array_unique($groups);
sort($groups);
return $groups;
}
/**
* Select all available groups
*
* @return array|bool list of all available groups and their properties
*/
protected function _selectGroups() {
if($this->groupcache) return $this->groupcache;
$sql = $this->getConf('select-groups');
$result = $this->_query($sql);
if($result === false) return false;
$groups = array();
foreach($result as $row) {
if(!isset($row['group'])) {
$this->_debug("No 'group' field returned from select-groups statement", -1, __LINE__);
return false;
}
// relayout result with group name as key
$group = $row['group'];
$groups[$group] = $row;
}
ksort($groups);
return $groups;
}
/**
* Remove all entries from the group cache
*/
protected function _clearGroupCache() {
$this->groupcache = null;
}
/**
* Adds the user to the group
*
* @param array $userdata all the user data
* @param array $groupdata all the group data
* @return bool
*/
protected function _joinGroup($userdata, $groupdata) {
$data = array_merge($userdata, $groupdata);
$sql = $this->getConf('join-group');
$result = $this->_query($sql, $data);
if($result === false) return false;
return true;
}
/**
* Removes the user from the group
*
* @param array $userdata all the user data
* @param array $groupdata all the group data
* @return bool
*/
protected function _leaveGroup($userdata, $groupdata) {
$data = array_merge($userdata, $groupdata);
$sql = $this->getConf('leave-group');
$result = $this->_query($sql, $data);
if($result === false) return false;
return true;
}
/**
* Executes a query
*
* @param string $sql The SQL statement to execute
* @param array $arguments Named parameters to be used in the statement
* @return array|int|bool The result as associative array for SELECTs, affected rows for others, false on error
*/
protected function _query($sql, $arguments = array()) {
$sql = trim($sql);
if(empty($sql)) {
$this->_debug('No SQL query given', -1, __LINE__);
return false;
}
// execute
$params = array();
$sth = $this->pdo->prepare($sql);
try {
// prepare parameters - we only use those that exist in the SQL
foreach($arguments as $key => $value) {
if(is_array($value)) continue;
if(is_object($value)) continue;
if($key[0] != ':') $key = ":$key"; // prefix with colon if needed
if(strpos($sql, $key) === false) continue; // skip if parameter is missing
if(is_int($value)) {
$sth->bindValue($key, $value, PDO::PARAM_INT);
} else {
$sth->bindValue($key, $value);
}
$params[$key] = $value; //remember for debugging
}
$sth->execute();
if(strtolower(substr($sql, 0, 6)) == 'select') {
$result = $sth->fetchAll();
} else {
$result = $sth->rowCount();
}
} catch(Exception $e) {
// report the caller's line
$trace = debug_backtrace();
$line = $trace[0]['line'];
$dsql = $this->_debugSQL($sql, $params, !defined('DOKU_UNITTEST'));
$this->_debug($e, -1, $line);
$this->_debug("SQL: <pre>$dsql</pre>", -1, $line);
$result = false;
}
$sth->closeCursor();
$sth = null;
return $result;
}
/**
* Wrapper around msg() but outputs only when debug is enabled
*
* @param string|Exception $message
* @param int $err
* @param int $line
*/
protected function _debug($message, $err = 0, $line = 0) {
if(!$this->getConf('debug')) return;
if(is_a($message, 'Exception')) {
$err = -1;
$msg = $message->getMessage();
if(!$line) $line = $message->getLine();
} else {
$msg = $message;
}
if(defined('DOKU_UNITTEST')) {
printf("\n%s, %s:%d\n", $msg, __FILE__, $line);
} else {
msg('authpdo: ' . $msg, $err, $line, __FILE__);
}
}
/**
* Check if the given config strings are set
*
* @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
*
* @param string[] $keys
* @return bool
*/
protected function _chkcnf($keys) {
foreach($keys as $key) {
if(!trim($this->getConf($key))) return false;
}
return true;
}
/**
* create an approximation of the SQL string with parameters replaced
*
* @param string $sql
* @param array $params
* @param bool $htmlescape Should the result be escaped for output in HTML?
* @return string
*/
protected function _debugSQL($sql, $params, $htmlescape = true) {
foreach($params as $key => $val) {
if(is_int($val)) {
$val = $this->pdo->quote($val, PDO::PARAM_INT);
} elseif(is_bool($val)) {
$val = $this->pdo->quote($val, PDO::PARAM_BOOL);
} elseif(is_null($val)) {
$val = 'NULL';
} else {
$val = $this->pdo->quote($val);
}
$sql = str_replace($key, $val, $sql);
}
if($htmlescape) $sql = hsc($sql);
return $sql;
}
}
// vim:ts=4:sw=4:et:

View File

@ -0,0 +1,110 @@
<?php
/**
* Default settings for the authpdo plugin
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
$conf['debug'] = 0;
$conf['dsn'] = '';
$conf['user'] = '';
$conf['pass'] = '';
/**
* statement to select a single user identified by its login name
*
* input: :user
* return: user, name, mail, (clear|hash), [uid], [*]
*/
$conf['select-user'] = '';
/**
* statement to select a single user identified by its login name
*
* input: :user, [uid]
* return: group
*/
$conf['select-user-groups'] = '';
/**
* Select all the existing group names
*
* return: group, [gid], [*]
*/
$conf['select-groups'] = '';
/**
* Create a new user
*
* input: :user, :name, :mail, (:clear|:hash)
*/
$conf['insert-user'] = '';
/**
* Remove a user
*
* input: :user, [:uid], [*]
*/
$conf['delete-user'] = '';
/**
* list user names matching the given criteria
*
* Make sure the list is distinct and sorted by user name. Apply the given limit and offset
*
* input: :user, :name, :mail, :group, :start, :end, :limit
* out: user
*/
$conf['list-users'] = '';
/**
* count user names matching the given criteria
*
* Make sure the counted list is distinct
*
* input: :user, :name, :mail, :group
* out: count
*/
$conf['count-users'] = '';
/**
* Update user data (except password and user name)
*
* input: :user, :name, :mail, [:uid], [*]
*/
$conf['update-user-info'] = '';
/**
* Update user name aka login
*
* input: :user, :newlogin, [:uid], [*]
*/
$conf['update-user-login'] = '';
/**
* Update user password
*
* input: :user, :clear, :hash, [:uid], [*]
*/
$conf['update-user-pass'] = '';
/**
* Create a new group
*
* input: :group
*/
$conf['insert-group'] = '';
/**
* Make user join group
*
* input: :user, [:uid], group, [:gid], [*]
*/
$conf['join-group'] = '';
/**
* Make user leave group
*
* input: :user, [:uid], group, [:gid], [*]
*/
$conf['leave-group'] = '';

View File

@ -0,0 +1,26 @@
<?php
/**
* Options for the authpdo plugin
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
$meta['debug'] = array('onoff', '_caution' => 'security');
$meta['dsn'] = array('string', '_caution' => 'danger');
$meta['user'] = array('string', '_caution' => 'danger');
$meta['pass'] = array('password', '_caution' => 'danger', '_code' => 'base64');
$meta['select-user'] = array('', '_caution' => 'danger');
$meta['select-user-groups'] = array('', '_caution' => 'danger');
$meta['select-groups'] = array('', '_caution' => 'danger');
$meta['insert-user'] = array('', '_caution' => 'danger');
$meta['delete-user'] = array('', '_caution' => 'danger');
$meta['list-users'] = array('', '_caution' => 'danger');
$meta['count-users'] = array('', '_caution' => 'danger');
$meta['update-user-info'] = array('', '_caution' => 'danger');
$meta['update-user-login'] = array('', '_caution' => 'danger');
$meta['update-user-pass'] = array('', '_caution' => 'danger');
$meta['insert-group'] = array('', '_caution' => 'danger');
$meta['join-group'] = array('', '_caution' => 'danger');
$meta['leave-group'] = array('', '_caution' => 'danger');

View File

@ -0,0 +1,9 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Kiril <neohidra@gmail.com>
*/
$lang['connectfail'] = 'Свързването с базата данни се провали.';
$lang['userexists'] = 'За съжаление вече съществува потребител с това име.';

View File

@ -0,0 +1,10 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Jaroslav Lichtblau <jlichtblau@seznam.cz>
*/
$lang['connectfail'] = 'Selhalo připojení k databázi.';
$lang['userexists'] = 'Omlouváme se, ale uživatel s tímto jménem již existuje.';
$lang['writefail'] = 'Nelze změnit údaje uživatele. Informujte prosím správce wiki';

View File

@ -0,0 +1,12 @@
<?php
/**
* Welsh language file for authmysql plugin
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
*/
$lang['connectfail'] = 'Method y cysylltiad i\'r databas.';
$lang['userexists'] = 'Sori, mae defnyddiwr gyda\'r enw mewngofnodi hwn eisoes yn bodoli.';
$lang['writefail'] = 'Methu â newid data defnyddiwr. Rhowch wybod i Weinyddwr y Wici';
//Setup VIM: ex: et ts=4 :

View File

@ -0,0 +1,12 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Noel Tilliot <noeltilliot@byom.de>
* @author Hendrik Diel <diel.hendrik@gmail.com>
* @author Philip Knack <p.knack@stollfuss.de>
*/
$lang['connectfail'] = 'Verbindung zur Datenbank fehlgeschlagen.';
$lang['userexists'] = 'Entschuldigung, aber dieser Benutzername ist bereits vergeben.';
$lang['writefail'] = 'Die Benutzerdaten konnten nicht geändert werden. Bitte wenden Sie sich an den Wiki-Admin.';

View File

@ -0,0 +1,12 @@
<?php
/**
* English language file for authpdo plugin
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
*/
$lang['connectfail'] = 'Failed to connect to database.';
$lang['userexists'] = 'Sorry, a user with this login already exists.';
$lang['writefail'] = 'Unable to modify user data. Please inform the Wiki-Admin';
//Setup VIM: ex: et ts=4 :

View File

@ -0,0 +1,24 @@
<?php
/**
* english language file for authpdo plugin
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
$lang['debug'] = 'Print out detailed error messages. Should be disabled after setup.';
$lang['dsn'] = 'The DSN to connect to the database.';
$lang['user'] = 'The user for the above database connection (empty for sqlite)';
$lang['pass'] = 'The password for the above database connection (empty for sqlite)';
$lang['select-user'] = 'SQL Statement to select the data of a single user';
$lang['select-user-groups'] = 'SQL Statement to select all groups of a single user';
$lang['select-groups'] = 'SQL Statement to select all available groups';
$lang['insert-user'] = 'SQL Statement to insert a new user into the database';
$lang['delete-user'] = 'SQL Statement to remove a single user from the database';
$lang['list-users'] = 'SQL Statement to list users matching a filter';
$lang['count-users'] = 'SQL Statement to count users matching a filter';
$lang['update-user-info'] = 'SQL Statement to update the full name and email address of a single user';
$lang['update-user-login'] = 'SQL Statement to update the login name of a single user';
$lang['update-user-pass'] = 'SQL Statement to update the password of a single user';
$lang['insert-group'] = 'SQL Statement to insert a new group into the database';
$lang['join-group'] = 'SQL Statement to add a user to an exisitng group';
$lang['leave-group'] = 'SQL Statement to remove a user from a group';

View File

@ -0,0 +1,10 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Domingo Redal <docxml@gmail.com>
*/
$lang['connectfail'] = 'Error al conectar con la base de datos.';
$lang['userexists'] = 'Lo sentimos, ya existe un usuario con ese inicio de sesión.';
$lang['writefail'] = 'No es posible modificar los datos del usuario. Por favor, informa al Administrador del Wiki';

View File

@ -0,0 +1,11 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Mohmmad Razavi <sepent@gmail.com>
* @author Masoud Sadrnezhaad <masoud@sadrnezhaad.ir>
*/
$lang['connectfail'] = 'خطا در اتصال به دیتابیس';
$lang['userexists'] = 'با عرض پوزش، یک کاربر با این نام از قبل وجود دارد.';
$lang['writefail'] = 'امکان تغییر داده کاربر وجود نداشت. لطفا مسئول Wiki را آگاه کنید.';

View File

@ -0,0 +1,10 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Pietroni <pietroni@informatique.univ-paris-diderot.fr>
*/
$lang['connectfail'] = 'Impossible de se connecter à la base de données.';
$lang['userexists'] = 'Désolé, un utilisateur avec cet identifiant existe déjà.';
$lang['writefail'] = 'Impossible de modifier les données utilisateur. Veuillez en informer l\'administrateur du Wiki.';

View File

@ -0,0 +1,10 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Davor Turkalj <turki.bsc@gmail.com>
*/
$lang['connectfail'] = 'Ne mogu se spojiti na bazu.';
$lang['userexists'] = 'Oprostite ali korisnik s ovom prijavom već postoji.';
$lang['writefail'] = 'Ne mogu izmijeniti podatke. Molim obavijestite Wiki administratora';

View File

@ -0,0 +1,10 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Marton Sebok <sebokmarton@gmail.com>
*/
$lang['connectfail'] = 'Az adatbázishoz való csatlakozás sikertelen.';
$lang['userexists'] = 'Sajnos már létezik ilyen azonosítójú felhasználó.';
$lang['writefail'] = 'A felhasználói adatok módosítása sikertelen. Kérlek, fordulj a wiki rendszergazdájához!';

View File

@ -0,0 +1,10 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Torpedo <dgtorpedo@gmail.com>
*/
$lang['connectfail'] = 'Connessione fallita al database.';
$lang['userexists'] = 'Spiacente, esiste già un utente con queste credenziali.';
$lang['writefail'] = 'Non è possibile cambiare le informazioni utente. Si prega di informare l\'Amministratore del wiki';

View File

@ -0,0 +1,10 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Hideaki SAWADA <chuno@live.jp>
*/
$lang['connectfail'] = 'データベースへの接続に失敗しました。';
$lang['userexists'] = 'このログイン名のユーザーが既に存在しています。';
$lang['writefail'] = 'ユーザーデータを変更できません。Wiki の管理者に連絡してください。';

View File

@ -0,0 +1,11 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author hyeonsoft <hyeonsoft@live.co.kr>
* @author Myeongjin <aranet100@gmail.com>
*/
$lang['connectfail'] = '데이터베이스에 연결하는 데 실패했습니다.';
$lang['userexists'] = '죄송하지만 이 계정으로 이미 로그인한 사용자가 있습니다.';
$lang['writefail'] = '사용자 데이터를 수정할 수 없습니다. 위키 관리자에게 문의하시기 바랍니다';

View File

@ -0,0 +1,10 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Hugo Smet <hugo.smet@scarlet.be>
*/
$lang['connectfail'] = 'Connectie met de database mislukt.';
$lang['userexists'] = 'Sorry, een gebruiker met deze login bestaat reeds.';
$lang['writefail'] = 'Onmogelijk om de gebruikers data te wijzigen. Gelieve de Wiki-Admin te informeren.';

View File

@ -0,0 +1,10 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Frederico Gonçalves Guimarães <frederico@teia.bio.br>
*/
$lang['connectfail'] = 'Não foi possível conectar ao banco de dados.';
$lang['userexists'] = 'Desculpe, mas já existe esse nome de usuário.';
$lang['writefail'] = 'Não foi possível modificar os dados do usuário. Por favor, informe ao administrador do Wiki.';

View File

@ -0,0 +1,9 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Paulo Carmino <contato@paulocarmino.com>
*/
$lang['connectfail'] = 'Falha ao conectar com o banco de dados.';
$lang['userexists'] = 'Desculpe, esse login já está sendo usado.';

View File

@ -0,0 +1,11 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Takumo <9206984@mail.ru>
* @author Aleksandr Selivanov <alexgearbox@yandex.ru>
*/
$lang['connectfail'] = 'Ошибка соединения с базой данных.';
$lang['userexists'] = 'Извините, пользователь с таким логином уже существует.';
$lang['writefail'] = 'Невозможно изменить данные пользователя. Сообщите об этом администратору вики.';

View File

@ -0,0 +1,10 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Martin Michalek <michalek.dev@gmail.com>
*/
$lang['connectfail'] = 'Nepodarilo sa pripojiť k databáze.';
$lang['userexists'] = 'Ľutujem, ale používateľ s týmto prihlasovacím menom už existuje.';
$lang['writefail'] = 'Nie je možné zmeniť údaje používateľa, informujte prosím administrátora Wiki.';

View File

@ -0,0 +1,8 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Mete Cuma <mcumax@gmail.com>
*/
$lang['connectfail'] = 'Veritabanına bağlantı kurulamadı.';

View File

@ -0,0 +1,10 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Errol <errol@hotmail.com>
*/
$lang['connectfail'] = '连接数据库失败';
$lang['userexists'] = '抱歉,用户名已被使用。';
$lang['writefail'] = '无法修改用户数据。请通知管理员';

View File

@ -0,0 +1,7 @@
base authpdo
author Andreas Gohr
email andi@splitbrain.org
date 2016-01-29
name authpdo plugin
desc Authenticate against a database via PDO
url https://www.dokuwiki.org/plugin:authpdo

View File

@ -2,6 +2,6 @@ base authpgsql
author Andreas Gohr
email andi@splitbrain.org
date 2015-07-13
name PostgreSQL Auth Plugin
desc Provides user authentication against a PostgreSQL database
name [DEPRECATED] PostgreSQL Auth Plugin
desc ▶This plugin will be removed from DokuWiki in a future release! Use authpdo instead.◀ Provides user authentication against a PostgreSQL database
url http://www.dokuwiki.org/plugin:authpgsql

View File

@ -107,7 +107,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin {
if (!empty($this->remoteInfo['bundled'])) return $this->remoteInfo['bundled'];
return in_array($this->id,
array(
'authad', 'authldap', 'authmysql', 'authpgsql', 'authplain', 'acl', 'info', 'extension',
'authad', 'authldap', 'authmysql', 'authpdo', 'authpgsql', 'authplain', 'acl', 'info', 'extension',
'revert', 'popularity', 'config', 'safefnrecode', 'styling', 'testing', 'template:dokuwiki'
)
);