1<?php
2/**
3 * DokuWiki HTTP authentication plugin
4 * https://www.dokuwiki.org/plugin:authhttp
5 *
6 * This plugin basically replaces DokuWiki's own authentication features
7 * with the HTTP authentication configured in the Webserver. As only login name and
8 * password are known:
9 * - the user's real name is set to his login name
10 * - a possibly non-working email address is constructed with the "emaildomain"
11 *   config setting
12 * - all users are part of the DokuWiki group configured with DokuWiki's
13 *   "defaultgroup" config setting
14 * - users that are specified in the list configured with "specialusers" will
15 *   also be member of the group configured with "specialgroup" (default: "admin")
16 *
17 * These restrictions may not suit your setup, in which case you should check out
18 * the "authsplit" plugin at https://www.dokuwiki.org/plugin:authhttp.
19 *
20 * This plugin in based on the ideas in the "ggauth" auth backend by Grant Gardner
21 * <grant@lastweekend.com.au>, https://www.dokuwiki.org/auth:ggauth.
22 *
23 * @license GPL 3 http://www.gnu.org/licenses/gpl-3.0.html
24 * @author  Pieter Hollants <pieter@hollants.com>
25 */
26
27// must be run within Dokuwiki
28if (!defined('DOKU_INC'))
29    die();
30
31use dokuwiki\Extension\AuthPlugin;
32
33class auth_plugin_authhttp extends AuthPlugin {
34    protected $usernameregex;
35    protected $emaildomain;
36    protected $specialusers;
37    protected $specialgroup;
38
39    /**
40     * Constructor.
41     */
42    public function __construct() {
43        global $conf;
44
45        parent::__construct();
46
47        /* Make sure that HTTP authentication has been enabled in the Web
48           server. Note that does not seem to work with PHP >= 4.3.0 and safe
49           mode enabled! */
50        if (!array_key_exists('PHP_AUTH_USER', $_SERVER) || $_SERVER['PHP_AUTH_USER'] == "") {
51            msg($this->getLang('nocreds'), -1);
52            $this->success = false;
53            return;
54        }
55
56        /* We have to distinguish between the plugin being loaded and the plugin
57           actually being used for authentication. */
58        $this->active = (
59            $conf['authtype'] == 'authhttp' ||
60            (
61                $conf['authtype'] == 'authsplit' &&
62                $conf['plugin']['authsplit']['primary_authplugin'] == 'authhttp'
63            )
64        );
65
66        /* Load the config */
67        $this->loadConfig();
68
69        /* Set the config values */
70        foreach (array("usernameregex", "emaildomain", "specialusers", "specialgroup") as $cfgvar) {
71            $this->$cfgvar = $this->getConf("$cfgvar");
72            if (!$this->$cfgvar) {
73                 msg("Config error: \"$cfgvar\" not set!", -1);
74                 $this->success = false;
75                 return;
76            }
77        }
78        if (preg_match('/^\/.*\/$/m', $this->usernameregex) == 0) {
79            $this->usernameregex = '/'.$this->usernameregex.'/';
80        }
81        $this->specialusers = explode(" ", $this->specialusers);
82
83        if ($this->active) {
84            /* No support for logout in this auth plugin. */
85            $this->cando['logout'] = false;
86        }
87
88        $this->success = true;
89    }
90
91    /**
92     * Check user+password
93     *
94     * @param   string $user the user name
95     * @param   string $pass the clear text password
96     * @return  bool
97     */
98    public function checkPass($user, $pass) {
99        return ($user == $this->cleanUser($_SERVER['PHP_AUTH_USER']) && $pass == $_SERVER['PHP_AUTH_PW']);
100    }
101
102    /**
103     * Return user info
104     *
105     * Returned info about the given user needs to contain
106     * at least these fields:
107     *
108     * name string  full name of the user
109     * mail string  email address of the user
110     * grps array   list of groups the user is in
111     *
112     * @param   string $user the user name
113     * @param   bool $requireGroups ignored, this plugin always returns groups
114     * @return  array containing user data or false
115     */
116    public function getUserData($user, $requireGroups = true) {
117        global $conf;
118
119        $info['name'] = $user;
120        $info['mail'] = $user."@".$this->emaildomain;
121        $info['grps'] = array($conf['defaultgroup']);
122        if (in_array($user, $this->specialusers)) {
123            $info['grps'][] = $this->specialgroup;
124        }
125
126        return $info;
127    }
128
129    /**
130     * Sanitize a given user name
131     *
132     * This function is applied to any user name that is given to
133     * the backend.
134     *
135     * @param  string $user user name
136     * @return string the cleaned user name
137     */
138    public function cleanUser($user) {
139        if (preg_match($this->usernameregex, $user, $results)) {
140            return $results[0];
141        } else {
142            return $user;
143        }
144    }
145}
146
147// vim:ts=4:sw=4:et:
148