xref: /plugin/authwordpress/auth.php (revision 9520968d05e52faf3e72d9e3b841ce0680bdf644)
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.0
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	 */
43	const SQL_WP_USER_DATA = "SELECT
44			id, user_login, user_pass, user_email, display_name,
45			meta_value AS groups
46		FROM wp_users u
47		JOIN wp_usermeta m ON u.id = m.user_id
48		WHERE meta_key = 'wp_capabilities'
49		AND user_login = :user";
50
51	/**
52	 * Constructor.
53	 */
54	public function __construct() {
55		parent::__construct();
56
57		// Try to establish a connection to the WordPress DB
58		// abort in case of failure
59		try {
60			$wp_db = $this->wp_connect();
61		}
62		catch (Exception $e) {
63			msg(sprintf($this->getLang('error_connect_failed'), $e->getMessage()));
64			$this->success = false;
65			return;
66		}
67
68		$this->success = true;
69	}
70
71
72	/**
73	 * Check user+password
74	 *
75	 * @param   string $user the user name
76	 * @param   string $pass the clear text password
77	 * @return  bool
78	 *
79	 * @uses PasswordHash::CheckPassword WordPress password hasher
80	 */
81	public function checkPass($user, $pass) {
82		$data = $this->getUserData($user);
83		if ($data === false) {
84			return false;
85		}
86
87		$hasher = new PasswordHash(8, true);
88		return $hasher->CheckPassword($pass, $data['pass']);
89	}
90
91
92	/**
93	 * Returns info about the given user
94	 *
95	 * @param   string $user the user name
96	 * @return  array containing user data or false
97	 */
98	function getUserData($user, $requireGroups=true) {
99		global $conf;
100
101		$wp_db = $this->wp_connect();
102		$stmt = $wp_db->prepare(self::SQL_WP_USER_DATA);
103		$stmt->bindParam(':user', $user);
104
105		if (!$stmt->execute()) {
106			// Query execution failed
107			return false;
108		}
109
110		$user = $stmt->fetch(PDO::FETCH_ASSOC);
111		if ($user === false) {
112			// Unknown user
113			return false;
114		}
115
116		// Group membership - add DokuWiki's default group
117		$groups = array_keys(unserialize($user['groups']));
118		$groups[] = $conf['defaultgroup'];
119
120		$info = array(
121			'user' => $user['user_login'],
122			'name' => $user['display_name'],
123			'pass' => $user['user_pass'],
124			'mail' => $user['user_email'],
125			'grps' => $groups,
126		);
127		return $info;
128	}
129
130
131	/**
132	 * Connect to Wordpress database
133	 *
134	 * @return PDO object
135	 */
136	private function wp_connect() {
137		$dsn = array(
138			'host=' . $this->getConf('hostname'),
139			'dbname=' . $this->getConf('database'),
140		);
141		$port = $this->getConf('port');
142		if ($port) {
143			$dsn[] = 'port=' . $port;
144		}
145		$dsn = 'mysql:' . implode(';', $dsn);
146
147		return new PDO($dsn, $this->getConf('username'), $this->getConf('password'));
148	}
149
150}
151
152// vim:ts=4:sw=4:noet:
153