xref: /plugin/authwordpress/auth.php (revision 5a63294461eefe7c94611e764d3fe8d571b03e90)
1<?php
2/**
3 * DokuWiki Plugin authwordpress (Auth Component)
4 *
5 * Provides authentication against a WordPress MySQL database backend
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * See the COPYING file in your DokuWiki folder for details
17 *
18 * @author     Damien Regad <dregad@mantisbt.org>
19 * @copyright  2015 Damien Regad
20 * @license    GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
21 * @version    1.1
22 * @link       https://github.com/dregad/dokuwiki-authwordpress
23 */
24
25
26// must be run within Dokuwiki
27if(!defined('DOKU_INC')) die();
28
29/**
30 * WordPress password hashing framework
31 */
32require_once('class-phpass.php');
33
34/**
35 * Authentication class
36 */
37class auth_plugin_authwordpress extends DokuWiki_Auth_Plugin {
38
39	/**
40	 * SQL statement to retrieve User data from WordPress DB
41	 * (including group memberships)
42	 * '%prefix%' will be replaced by the actual prefix (from plugin config)
43	 */
44	private $sql_wp_user_data = "SELECT
45			id, user_login, user_pass, user_email, display_name,
46			meta_value AS groups
47		FROM %prefix%users u
48		JOIN %prefix%usermeta m ON u.id = m.user_id
49		WHERE meta_key = '%prefix%capabilities'
50		AND user_login = :user";
51
52	/**
53	 * Constructor.
54	 */
55	public function __construct() {
56		parent::__construct();
57
58		// Try to establish a connection to the WordPress DB
59		// abort in case of failure
60		try {
61			$wp_db = $this->wp_connect();
62		}
63		catch (Exception $e) {
64			msg(sprintf($this->getLang('error_connect_failed'), $e->getMessage()));
65			$this->success = false;
66			return;
67		}
68
69		// Initialize SQL query with configured prefix
70		$this->sql_wp_user_data = str_replace(
71			'%prefix%',
72			$this->getConf('prefix'),
73			$this->sql_wp_user_data
74		);
75
76		$this->success = true;
77	}
78
79
80	/**
81	 * Check user+password
82	 *
83	 * @param   string $user the user name
84	 * @param   string $pass the clear text password
85	 * @return  bool
86	 *
87	 * @uses PasswordHash::CheckPassword WordPress password hasher
88	 */
89	public function checkPass($user, $pass) {
90		$data = $this->getUserData($user);
91		if ($data === false) {
92			return false;
93		}
94
95		$hasher = new PasswordHash(8, true);
96		return $hasher->CheckPassword($pass, $data['pass']);
97	}
98
99
100	/**
101	 * Returns info about the given user
102	 *
103	 * @param   string $user the user name
104	 * @return  array containing user data or false
105	 */
106	function getUserData($user, $requireGroups=true) {
107		global $conf;
108
109		$wp_db = $this->wp_connect();
110		$stmt = $wp_db->prepare($this->sql_wp_user_data);
111		$stmt->bindParam(':user', $user);
112
113		if (!$stmt->execute()) {
114			// Query execution failed
115			return false;
116		}
117
118		$user = $stmt->fetch(PDO::FETCH_ASSOC);
119		if ($user === false) {
120			// Unknown user
121			return false;
122		}
123
124		// Group membership - add DokuWiki's default group
125		$groups = array_keys(unserialize($user['groups']));
126		$groups[] = $conf['defaultgroup'];
127
128		$info = array(
129			'user' => $user['user_login'],
130			'name' => $user['display_name'],
131			'pass' => $user['user_pass'],
132			'mail' => $user['user_email'],
133			'grps' => $groups,
134		);
135		return $info;
136	}
137
138
139	/**
140	 * Connect to Wordpress database
141	 *
142	 * @return PDO object
143	 */
144	private function wp_connect() {
145		$dsn = array(
146			'host=' . $this->getConf('hostname'),
147			'dbname=' . $this->getConf('database'),
148		);
149		$port = $this->getConf('port');
150		if ($port) {
151			$dsn[] = 'port=' . $port;
152		}
153		$dsn = 'mysql:' . implode(';', $dsn);
154
155		return new PDO($dsn, $this->getConf('username'), $this->getConf('password'));
156	}
157
158}
159
160// vim:ts=4:sw=4:noet:
161