xref: /plugin/pureldap/auth.php (revision 8bb750c24eaadcd46be7c46102066046f2973e3b)
1<?php
2
3use dokuwiki\plugin\pureldap\classes\ADClient;
4use dokuwiki\plugin\pureldap\classes\Client;
5
6/**
7 * DokuWiki Plugin pureldap (Auth Component)
8 *
9 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
10 * @author  Andreas Gohr <andi@splitbrain.org>
11 */
12class auth_plugin_pureldap extends DokuWiki_Auth_Plugin
13{
14    /** @var Client */
15    protected $client;
16
17    /**
18     * Constructor.
19     */
20    public function __construct()
21    {
22        global $conf;
23        parent::__construct(); // for compatibility
24
25        $this->cando['getUsers'] = true;
26        $this->cando['getGroups'] = true;
27
28        // prepare the base client
29        $this->loadConfig();
30        $this->conf['admin_password'] = conf_decodeString($this->conf['admin_password']);
31        $this->conf['defaultgroup'] = $conf['defaultgroup'];
32
33        $this->client = new ADClient($this->conf); // FIXME decide class on config
34        $this->success = true;
35    }
36
37
38    /**
39     * Log off the current user [ OPTIONAL ]
40     */
41    // public function logOff()
42    // {
43    // }
44
45    /**
46     * Do all authentication [ OPTIONAL ]
47     *
48     * @param string $user Username
49     * @param string $pass Cleartext Password
50     * @param bool $sticky Cookie should not expire
51     *
52     * @return  bool             true on successful auth
53     */
54    //public function trustExternal($user, $pass, $sticky = false)
55    //{
56    /* some example:
57
58    global $USERINFO;
59    global $conf;
60    $sticky ? $sticky = true : $sticky = false; //sanity check
61
62    // do the checking here
63
64    // set the globals if authed
65    $USERINFO['name'] = 'FIXME';
66    $USERINFO['mail'] = 'FIXME';
67    $USERINFO['grps'] = array('FIXME');
68    $_SERVER['REMOTE_USER'] = $user;
69    $_SESSION[DOKU_COOKIE]['auth']['user'] = $user;
70    $_SESSION[DOKU_COOKIE]['auth']['pass'] = $pass;
71    $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
72    return true;
73
74    */
75    //}
76
77    /** @inheritDoc */
78    public function checkPass($user, $pass)
79    {
80        // use a separate client from the default one, because this is not a superuser bind
81        $client = new ADClient($this->conf); // FIXME decide class on config
82        return $client->authenticate($user, $pass);
83    }
84
85    /** @inheritDoc */
86    public function getUserData($user, $requireGroups = true)
87    {
88        $info = $this->client->getCachedUser($user, $requireGroups);
89        return $info ?: false;
90    }
91
92    /**
93     * Create a new User [implement only where required/possible]
94     *
95     * Returns false if the user already exists, null when an error
96     * occurred and true if everything went well.
97     *
98     * The new user HAS TO be added to the default group by this
99     * function!
100     *
101     * Set addUser capability when implemented
102     *
103     * @param string $user
104     * @param string $pass
105     * @param string $name
106     * @param string $mail
107     * @param null|array $grps
108     *
109     * @return bool|null
110     */
111    //public function createUser($user, $pass, $name, $mail, $grps = null)
112    //{
113    // FIXME implement
114    //    return null;
115    //}
116
117    /**
118     * Modify user data [implement only where required/possible]
119     *
120     * Set the mod* capabilities according to the implemented features
121     *
122     * @param string $user nick of the user to be changed
123     * @param array $changes array of field/value pairs to be changed (password will be clear text)
124     *
125     * @return  bool
126     */
127    //public function modifyUser($user, $changes)
128    //{
129    // FIXME implement
130    //    return false;
131    //}
132
133    /**
134     * Delete one or more users [implement only where required/possible]
135     *
136     * Set delUser capability when implemented
137     *
138     * @param array $users
139     *
140     * @return  int    number of users deleted
141     */
142    //public function deleteUsers($users)
143    //{
144    // FIXME implement
145    //    return false;
146    //}
147
148    /** @inheritDoc */
149    public function retrieveUsers($start = 0, $limit = 0, $filter = null)
150    {
151        return array_slice(
152            $this->client->getFilteredUsers(
153                $filter,
154                $this->filterType2FilterMethod('contains')
155            ),
156            $start,
157            $limit);
158    }
159
160    /**
161     * Define a group [implement only where required/possible]
162     *
163     * Set addGroup capability when implemented
164     *
165     * @param string $group
166     *
167     * @return  bool
168     */
169    //public function addGroup($group)
170    //{
171    // FIXME implement
172    //    return false;
173    //}
174
175    /** @inheritDoc */
176    public function retrieveGroups($start = 0, $limit = 0)
177    {
178        return array_slice($this->client->getCachedGroups(), $start, $limit);
179    }
180
181    /**
182     * Return case sensitivity of the backend
183     *
184     * When your backend is caseinsensitive (eg. you can login with USER and
185     * user) then you need to overwrite this method and return false
186     *
187     * @return bool
188     */
189    public function isCaseSensitive()
190    {
191        return true;
192    }
193
194    /**
195     * Sanitize a given username
196     *
197     * This function is applied to any user name that is given to
198     * the backend and should also be applied to any user name within
199     * the backend before returning it somewhere.
200     *
201     * This should be used to enforce username restrictions.
202     *
203     * @param string $user username
204     * @return string the cleaned username
205     */
206    public function cleanUser($user)
207    {
208        return $user;
209    }
210
211    /**
212     * Sanitize a given groupname
213     *
214     * This function is applied to any groupname that is given to
215     * the backend and should also be applied to any groupname within
216     * the backend before returning it somewhere.
217     *
218     * This should be used to enforce groupname restrictions.
219     *
220     * Groupnames are to be passed without a leading '@' here.
221     *
222     * @param string $group groupname
223     *
224     * @return string the cleaned groupname
225     */
226    public function cleanGroup($group)
227    {
228        return $group;
229    }
230
231    /**
232     * Check Session Cache validity [implement only where required/possible]
233     *
234     * DokuWiki caches user info in the user's session for the timespan defined
235     * in $conf['auth_security_timeout'].
236     *
237     * This makes sure slow authentication backends do not slow down DokuWiki.
238     * This also means that changes to the user database will not be reflected
239     * on currently logged in users.
240     *
241     * To accommodate for this, the user manager plugin will touch a reference
242     * file whenever a change is submitted. This function compares the filetime
243     * of this reference file with the time stored in the session.
244     *
245     * This reference file mechanism does not reflect changes done directly in
246     * the backend's database through other means than the user manager plugin.
247     *
248     * Fast backends might want to return always false, to force rechecks on
249     * each page load. Others might want to use their own checking here. If
250     * unsure, do not override.
251     *
252     * @param string $user - The username
253     *
254     * @return bool
255     */
256    public function useSessionCache($user)
257    {
258        return false;
259    }
260
261    /**
262     * Convert DokuWiki filter type to method in the library
263     *
264     * @todo implement with proper constants once #3028 has been implemented
265     * @param string $type
266     * @return string
267     */
268    protected function filterType2FilterMethod($type)
269    {
270        $filtermethods = [
271            'contains' => 'contains',
272            'startswith' => 'startsWith',
273            'endswith' => 'endsWith',
274            'equals' => 'equals',
275        ];
276
277        if (isset($filtermethods[$type])) {
278            return $filtermethods[$type];
279        }
280
281        return 'equals';
282    }
283}
284
285