xref: /plugin/oauth/auth.php (revision d9be1cb5d4b89892fd7351309c9c9722836436f4)
180852c15SAndreas Gohr<?php
23e7ac5b1SAndreas Gohr
3b8ca6a42SAnna Dabrowskause dokuwiki\plugin\oauth\SessionManager;
4b8ca6a42SAnna Dabrowska
580852c15SAndreas Gohr/**
680852c15SAndreas Gohr * DokuWiki Plugin oauth (Auth Component)
780852c15SAndreas Gohr *
880852c15SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
980852c15SAndreas Gohr * @author  Andreas Gohr <andi@splitbrain.org>
1080852c15SAndreas Gohr */
113e7ac5b1SAndreas Gohrclass auth_plugin_oauth extends auth_plugin_authplain
123e7ac5b1SAndreas Gohr{
1380852c15SAndreas Gohr
14*d9be1cb5SAnna Dabrowska    /**
15*d9be1cb5SAnna Dabrowska     * @var SessionManager
16*d9be1cb5SAnna Dabrowska     */
17*d9be1cb5SAnna Dabrowska    protected static $sessionManager;
18*d9be1cb5SAnna Dabrowska
193e7ac5b1SAndreas Gohr    /** @inheritDoc */
203e7ac5b1SAndreas Gohr    public function __construct()
213e7ac5b1SAndreas Gohr    {
22f10e09e2SAndreas Gohr        parent::__construct();
2380852c15SAndreas Gohr
24f10e09e2SAndreas Gohr        $this->cando['external'] = true;
25*d9be1cb5SAnna Dabrowska        self::$sessionManager = SessionManager::getInstance();
2680852c15SAndreas Gohr    }
2780852c15SAndreas Gohr
283e7ac5b1SAndreas Gohr    /** @inheritDoc */
29311a6606SAnna Dabrowska    public function trustExternal($user, $pass, $sticky = false)
303e7ac5b1SAndreas Gohr    {
31a02a5d81SAnna Dabrowska        global $INPUT;
32438dcc52SMichael Grosse
33b8ca6a42SAnna Dabrowska        // handle redirects from farmer to animal wiki instances
34438dcc52SMichael Grosse        if ($INPUT->has('state') && plugin_load('helper', 'farmer', false, true)) {
35*d9be1cb5SAnna Dabrowska            $this->handleFarmState($INPUT->str('state'));
36438dcc52SMichael Grosse        }
3780852c15SAndreas Gohr
38b8ca6a42SAnna Dabrowska        // first check in auth setup: is auth data present and still valid?
39a02a5d81SAnna Dabrowska        if ($this->sessionLogin()) return true;
4080852c15SAndreas Gohr
41b8ca6a42SAnna Dabrowska        // if we have a service in session, either we're in oauth login or a previous login needs to be revalidated
42*d9be1cb5SAnna Dabrowska        $servicename = self::$sessionManager->getServiceName();
43*d9be1cb5SAnna Dabrowska
44b8ca6a42SAnna Dabrowska        if ($servicename) {
45*d9be1cb5SAnna Dabrowska            $pid = self::$sessionManager->getPid();
46*d9be1cb5SAnna Dabrowska            $params = self::$sessionManager->getParams();
47*d9be1cb5SAnna Dabrowska            $inProgress = self::$sessionManager->isInProgress();
48*d9be1cb5SAnna Dabrowska            self::$sessionManager->setInProgress(false);
49*d9be1cb5SAnna Dabrowska            self::$sessionManager->saveState();
50b8ca6a42SAnna Dabrowska            return $this->serviceLogin($servicename,
51b8ca6a42SAnna Dabrowska                $sticky,
524a95c35bSAnna Dabrowska                $pid,
534a95c35bSAnna Dabrowska                $params,
544a95c35bSAnna Dabrowska                $inProgress
55b8ca6a42SAnna Dabrowska            );
56a7a8f46aSAndreas Gohr        }
57a7a8f46aSAndreas Gohr
58a02a5d81SAnna Dabrowska        // otherwise try cookie
59a02a5d81SAnna Dabrowska        $this->cookieLogin();
6080852c15SAndreas Gohr
61a7a8f46aSAndreas Gohr        // do the "normal" plain auth login via form
62a7a8f46aSAndreas Gohr        return auth_login($user, $pass, $sticky);
63a7a8f46aSAndreas Gohr    }
6480852c15SAndreas Gohr
65f2e164b0SMichael Große    /**
66311a6606SAnna Dabrowska     * Enhance function to check against duplicate emails
67311a6606SAnna Dabrowska     *
68311a6606SAnna Dabrowska     * @param string $user
69311a6606SAnna Dabrowska     * @param string $pwd
70311a6606SAnna Dabrowska     * @param string $name
71311a6606SAnna Dabrowska     * @param string $mail
72311a6606SAnna Dabrowska     * @param null $grps
73311a6606SAnna Dabrowska     * @return bool|null|string
74311a6606SAnna Dabrowska     */
75311a6606SAnna Dabrowska    public function createUser($user, $pwd, $name, $mail, $grps = null)
76311a6606SAnna Dabrowska    {
77311a6606SAnna Dabrowska        if ($this->getUserByEmail($mail)) {
78311a6606SAnna Dabrowska            msg($this->getLang('emailduplicate'), -1);
79311a6606SAnna Dabrowska            return false;
80311a6606SAnna Dabrowska        }
81311a6606SAnna Dabrowska
82311a6606SAnna Dabrowska        return parent::createUser($user, $pwd, $name, $mail, $grps);
83311a6606SAnna Dabrowska    }
84311a6606SAnna Dabrowska
85311a6606SAnna Dabrowska    /**
86311a6606SAnna Dabrowska     * Enhance function to check against duplicate emails
87311a6606SAnna Dabrowska     *
88311a6606SAnna Dabrowska     * @param string $user
89311a6606SAnna Dabrowska     * @param array $changes
90311a6606SAnna Dabrowska     * @return bool
91311a6606SAnna Dabrowska     */
92311a6606SAnna Dabrowska    public function modifyUser($user, $changes)
93311a6606SAnna Dabrowska    {
94311a6606SAnna Dabrowska        global $conf;
95311a6606SAnna Dabrowska
96311a6606SAnna Dabrowska        if (isset($changes['mail'])) {
97311a6606SAnna Dabrowska            $found = $this->getUserByEmail($changes['mail']);
98311a6606SAnna Dabrowska            if ($found && $found != $user) {
99311a6606SAnna Dabrowska                msg($this->getLang('emailduplicate'), -1);
100311a6606SAnna Dabrowska                return false;
101311a6606SAnna Dabrowska            }
102311a6606SAnna Dabrowska        }
103311a6606SAnna Dabrowska
104311a6606SAnna Dabrowska        $ok = parent::modifyUser($user, $changes);
105311a6606SAnna Dabrowska
106311a6606SAnna Dabrowska        // refresh session cache
107311a6606SAnna Dabrowska        touch($conf['cachedir'] . '/sessionpurge');
108311a6606SAnna Dabrowska
109311a6606SAnna Dabrowska        return $ok;
110311a6606SAnna Dabrowska    }
111311a6606SAnna Dabrowska
112311a6606SAnna Dabrowska    /**
113311a6606SAnna Dabrowska     * Unset additional stuff in session on logout
114311a6606SAnna Dabrowska     */
115311a6606SAnna Dabrowska    public function logOff()
116311a6606SAnna Dabrowska    {
117311a6606SAnna Dabrowska        parent::logOff();
118311a6606SAnna Dabrowska
119311a6606SAnna Dabrowska        $this->cleanLogout();
120311a6606SAnna Dabrowska    }
121311a6606SAnna Dabrowska
122311a6606SAnna Dabrowska    /**
123a02a5d81SAnna Dabrowska     * check if auth data is present in session and is still considered valid
124f2e164b0SMichael Große     *
125f2e164b0SMichael Große     * @return bool
126f2e164b0SMichael Große     */
127a02a5d81SAnna Dabrowska    protected function sessionLogin()
1283e7ac5b1SAndreas Gohr    {
129a02a5d81SAnna Dabrowska        global $USERINFO;
130a02a5d81SAnna Dabrowska        $session = $_SESSION[DOKU_COOKIE]['auth'];
131b8ca6a42SAnna Dabrowska        // FIXME session can be null at this point (e.g. coming from sprintdoc svg.php)
132b8ca6a42SAnna Dabrowska        // FIXME and so the subsequent check for non-GET non-doku.php requests is not performed
133a02a5d81SAnna Dabrowska        if (isset($session['oauth']) && $this->isSessionValid($session)) {
134a02a5d81SAnna Dabrowska            $_SERVER['REMOTE_USER'] = $session['user'];
135a02a5d81SAnna Dabrowska            $USERINFO = $session['info'];
136f2e164b0SMichael Große            return true;
137f2e164b0SMichael Große        }
138f2e164b0SMichael Große        return false;
139f2e164b0SMichael Große    }
140f2e164b0SMichael Große
141a02a5d81SAnna Dabrowska    /**
142a02a5d81SAnna Dabrowska     * Use cookie data to log in
143a02a5d81SAnna Dabrowska     */
144a02a5d81SAnna Dabrowska    protected function cookieLogin()
145a02a5d81SAnna Dabrowska    {
146*d9be1cb5SAnna Dabrowska        // FIXME SessionManager access?
147a02a5d81SAnna Dabrowska        if (isset($_COOKIE[DOKU_COOKIE])) {
148a02a5d81SAnna Dabrowska            list($cookieuser, $cookiesticky, $auth, $servicename) = explode('|', $_COOKIE[DOKU_COOKIE]);
149a02a5d81SAnna Dabrowska            $auth = base64_decode($auth, true);
150a02a5d81SAnna Dabrowska            $servicename = base64_decode($servicename, true);
151a02a5d81SAnna Dabrowska            if ($auth === 'oauth') {
152b8ca6a42SAnna Dabrowska                $this->relogin($servicename);
153a02a5d81SAnna Dabrowska            }
154a02a5d81SAnna Dabrowska        }
155a02a5d81SAnna Dabrowska    }
156a02a5d81SAnna Dabrowska
157a02a5d81SAnna Dabrowska    /**
158a02a5d81SAnna Dabrowska     * Use the OAuth service
159a02a5d81SAnna Dabrowska     *
160a02a5d81SAnna Dabrowska     * @param $servicename
161b2b9fbc7SMichael Große     * @param $sticky
162a02a5d81SAnna Dabrowska     * @param $page
163a02a5d81SAnna Dabrowska     * @param $params
164a02a5d81SAnna Dabrowska     * @param $existingLoginProcess
165a02a5d81SAnna Dabrowska     * @return bool
166a02a5d81SAnna Dabrowska     * @throws \OAuth\Common\Exception\Exception
167a02a5d81SAnna Dabrowska     * @throws \OAuth\Common\Http\Exception\TokenResponseException
168a02a5d81SAnna Dabrowska     * @throws \OAuth\Common\Storage\Exception\TokenNotFoundException
169a02a5d81SAnna Dabrowska     */
170a02a5d81SAnna Dabrowska    protected function serviceLogin($servicename, $sticky, $page, $params, $existingLoginProcess)
171a02a5d81SAnna Dabrowska    {
172a02a5d81SAnna Dabrowska        $service = $this->getService($servicename);
173a02a5d81SAnna Dabrowska        if (is_null($service)) {
174a02a5d81SAnna Dabrowska            $this->cleanLogout();
175a02a5d81SAnna Dabrowska            return false;
176a02a5d81SAnna Dabrowska        }
177a02a5d81SAnna Dabrowska
178a02a5d81SAnna Dabrowska        if ($service->checkToken()) {
179a02a5d81SAnna Dabrowska            if (!$this->processLogin($sticky, $service, $servicename, $page, $params)) {
180a02a5d81SAnna Dabrowska                $this->cleanLogout();
181a02a5d81SAnna Dabrowska                return false;
182a02a5d81SAnna Dabrowska            }
183a02a5d81SAnna Dabrowska            return true;
184a02a5d81SAnna Dabrowska        } else {
185a02a5d81SAnna Dabrowska            if ($existingLoginProcess) {
186a02a5d81SAnna Dabrowska                msg($this->getLang('oauth login failed'), 0);
187a02a5d81SAnna Dabrowska                $this->cleanLogout();
188a02a5d81SAnna Dabrowska                return false;
189a02a5d81SAnna Dabrowska            } else {
190a02a5d81SAnna Dabrowska                // first time here
191b8ca6a42SAnna Dabrowska                $this->relogin($servicename);
192a02a5d81SAnna Dabrowska            }
193a02a5d81SAnna Dabrowska        }
194a02a5d81SAnna Dabrowska
195a02a5d81SAnna Dabrowska        $this->cleanLogout();
196a02a5d81SAnna Dabrowska        return false; // something went wrong during oAuth login
197a02a5d81SAnna Dabrowska    }
198a02a5d81SAnna Dabrowska
199a02a5d81SAnna Dabrowska    /**
200b8ca6a42SAnna Dabrowska     * Relogin using auth info read from session / cookie
201b8ca6a42SAnna Dabrowska     *
202a02a5d81SAnna Dabrowska     * @param string $servicename
203a02a5d81SAnna Dabrowska     * @return void|false
204a02a5d81SAnna Dabrowska     * @throws \OAuth\Common\Http\Exception\TokenResponseException
205a02a5d81SAnna Dabrowska     */
206b8ca6a42SAnna Dabrowska    protected function relogin($servicename)
207a02a5d81SAnna Dabrowska    {
208a02a5d81SAnna Dabrowska        $service = $this->getService($servicename);
209a02a5d81SAnna Dabrowska        if (is_null($service)) return false;
210a02a5d81SAnna Dabrowska
211a02a5d81SAnna Dabrowska        $this->writeSession($servicename);
212a02a5d81SAnna Dabrowska        $service->login();
213a02a5d81SAnna Dabrowska    }
214a02a5d81SAnna Dabrowska
215a02a5d81SAnna Dabrowska
216a02a5d81SAnna Dabrowska    /**
217a02a5d81SAnna Dabrowska     * @param bool $sticky
218a02a5d81SAnna Dabrowska     * @param \dokuwiki\plugin\oauth\Service $service
2199928f5efSMichael Große     * @param string $servicename
220b2b9fbc7SMichael Große     * @param string $page
221188ba446SMichael Große     * @param array $params
222f07c7607SMichael Große     *
223f07c7607SMichael Große     * @return bool
224a02a5d81SAnna Dabrowska     * @throws \OAuth\Common\Exception\Exception
225f07c7607SMichael Große     */
226a02a5d81SAnna Dabrowska    protected function processLogin($sticky, $service, $servicename, $page, $params = [])
2273e7ac5b1SAndreas Gohr    {
228a02a5d81SAnna Dabrowska        $userinfo = $service->getUser();
229a02a5d81SAnna Dabrowska        $ok = $this->processUserinfo($userinfo, $servicename);
230f07c7607SMichael Große        if (!$ok) {
231f07c7607SMichael Große            return false;
232f07c7607SMichael Große        }
233a02a5d81SAnna Dabrowska        $this->setUserSession($userinfo, $servicename);
234a02a5d81SAnna Dabrowska        $this->setUserCookie($userinfo['user'], $sticky, $servicename);
235b2b9fbc7SMichael Große        if (isset($page)) {
236188ba446SMichael Große            if (!empty($params['id'])) unset($params['id']);
237188ba446SMichael Große            send_redirect(wl($page, $params, false, '&'));
238b2b9fbc7SMichael Große        }
239f07c7607SMichael Große        return true;
240f07c7607SMichael Große    }
241f07c7607SMichael Große
2429928f5efSMichael Große    /**
243a02a5d81SAnna Dabrowska     * process the user and update the user info array
2449928f5efSMichael Große     *
245a02a5d81SAnna Dabrowska     * @param array $userinfo User info received from authentication
246a02a5d81SAnna Dabrowska     * @param string $servicename Auth service
2479928f5efSMichael Große     *
2489928f5efSMichael Große     * @return bool
2499928f5efSMichael Große     */
250a02a5d81SAnna Dabrowska    protected function processUserinfo(&$userinfo, $servicename)
2513e7ac5b1SAndreas Gohr    {
252a02a5d81SAnna Dabrowska        $userinfo['user'] = $this->cleanUser((string)$userinfo['user']);
253a02a5d81SAnna Dabrowska        if (!$userinfo['name']) $userinfo['name'] = $userinfo['user'];
2549928f5efSMichael Große
255a02a5d81SAnna Dabrowska        if (!$userinfo['user'] || !$userinfo['mail']) {
2569928f5efSMichael Große            msg("$servicename did not provide the needed user info. Can't log you in", -1);
2579928f5efSMichael Große            return false;
2589928f5efSMichael Große        }
2599928f5efSMichael Große
2609928f5efSMichael Große        // see if the user is known already
261a02a5d81SAnna Dabrowska        $localUser = $this->getUserByEmail($userinfo['mail']);
262a02a5d81SAnna Dabrowska        if ($localUser) {
263a02a5d81SAnna Dabrowska            $localUserInfo = $this->getUserData($localUser);
2649928f5efSMichael Große            // check if the user allowed access via this service
265a02a5d81SAnna Dabrowska            if (!in_array($this->cleanGroup($servicename), $localUserInfo['grps'])) {
2669928f5efSMichael Große                msg(sprintf($this->getLang('authnotenabled'), $servicename), -1);
2679928f5efSMichael Große                return false;
2689928f5efSMichael Große            }
269a02a5d81SAnna Dabrowska            $userinfo['user'] = $localUser;
270a02a5d81SAnna Dabrowska            $userinfo['name'] = $localUserInfo['name'];
271a02a5d81SAnna Dabrowska            $userinfo['grps'] = array_merge((array)$userinfo['grps'], $localUserInfo['grps']);
272d313403cSAnna Dabrowska        } elseif (actionOK('register') || $this->getConf('register-on-auth')) {
273a02a5d81SAnna Dabrowska            $ok = $this->addUser($userinfo, $servicename);
2749928f5efSMichael Große            if (!$ok) {
2759928f5efSMichael Große                msg('something went wrong creating your user account. please try again later.', -1);
2769928f5efSMichael Große                return false;
2779928f5efSMichael Große            }
2789928f5efSMichael Große        } else {
2799928f5efSMichael Große            msg($this->getLang('addUser not possible'), -1);
2809928f5efSMichael Große            return false;
2819928f5efSMichael Große        }
2829928f5efSMichael Große        return true;
2839928f5efSMichael Große    }
2849928f5efSMichael Große
2859928f5efSMichael Große    /**
286b2b9fbc7SMichael Große     * new user, create him - making sure the login is unique by adding a number if needed
287b2b9fbc7SMichael Große     *
288a02a5d81SAnna Dabrowska     * @param array $userinfo user info received from the oAuth service
289b2b9fbc7SMichael Große     * @param string $servicename
290b2b9fbc7SMichael Große     *
291b2b9fbc7SMichael Große     * @return bool
292b2b9fbc7SMichael Große     */
293a02a5d81SAnna Dabrowska    protected function addUser(&$userinfo, $servicename)
2943e7ac5b1SAndreas Gohr    {
295b2b9fbc7SMichael Große        global $conf;
296a02a5d81SAnna Dabrowska        $user = $userinfo['user'];
297b2b9fbc7SMichael Große        $count = '';
298b2b9fbc7SMichael Große        while ($this->getUserData($user . $count)) {
299b2b9fbc7SMichael Große            if ($count) {
300b2b9fbc7SMichael Große                $count++;
301b2b9fbc7SMichael Große            } else {
302b2b9fbc7SMichael Große                $count = 1;
303b2b9fbc7SMichael Große            }
304b2b9fbc7SMichael Große        }
305b2b9fbc7SMichael Große        $user = $user . $count;
306a02a5d81SAnna Dabrowska        $userinfo['user'] = $user;
307b2b9fbc7SMichael Große        $groups_on_creation = array();
308b2b9fbc7SMichael Große        $groups_on_creation[] = $conf['defaultgroup'];
309b2b9fbc7SMichael Große        $groups_on_creation[] = $this->cleanGroup($servicename); // add service as group
310a02a5d81SAnna Dabrowska        $userinfo['grps'] = array_merge((array)$userinfo['grps'], $groups_on_creation);
311b2b9fbc7SMichael Große
312b2b9fbc7SMichael Große        $ok = $this->triggerUserMod(
313b2b9fbc7SMichael Große            'create',
314a02a5d81SAnna Dabrowska            array($user, auth_pwgen($user), $userinfo['name'], $userinfo['mail'], $groups_on_creation,)
315b2b9fbc7SMichael Große        );
316b2b9fbc7SMichael Große        if (!$ok) {
317b2b9fbc7SMichael Große            return false;
318b2b9fbc7SMichael Große        }
319b2b9fbc7SMichael Große
320b2b9fbc7SMichael Große        // send notification about the new user
321b2b9fbc7SMichael Große        $subscription = new Subscription();
322a02a5d81SAnna Dabrowska        $subscription->send_register($user, $userinfo['name'], $userinfo['mail']);
323b2b9fbc7SMichael Große        return true;
324b2b9fbc7SMichael Große    }
325b2b9fbc7SMichael Große
326b2b9fbc7SMichael Große    /**
327a02a5d81SAnna Dabrowska     * Find a user by email address
328b2b9fbc7SMichael Große     *
329b2b9fbc7SMichael Große     * @param $mail
330b2b9fbc7SMichael Große     * @return bool|string
331b2b9fbc7SMichael Große     */
3323e7ac5b1SAndreas Gohr    protected function getUserByEmail($mail)
3333e7ac5b1SAndreas Gohr    {
3348b214edcSAndreas Gohr        if ($this->users === null) {
3358b214edcSAndreas Gohr            if (is_callable([$this, '_loadUserData'])) {
3368b214edcSAndreas Gohr                $this->_loadUserData();
3378b214edcSAndreas Gohr            } else {
3388b214edcSAndreas Gohr                $this->loadUserData();
3398b214edcSAndreas Gohr            }
3408b214edcSAndreas Gohr        }
341b2b9fbc7SMichael Große        $mail = strtolower($mail);
342b2b9fbc7SMichael Große
343a02a5d81SAnna Dabrowska        foreach ($this->users as $user => $userinfo) {
344a02a5d81SAnna Dabrowska            if (strtolower($userinfo['mail']) == $mail) return $user;
345b2b9fbc7SMichael Große        }
346b2b9fbc7SMichael Große
347b2b9fbc7SMichael Große        return false;
348b2b9fbc7SMichael Große    }
349b2b9fbc7SMichael Große
350b2b9fbc7SMichael Große    /**
351a02a5d81SAnna Dabrowska     * unset auth cookies and session information
352a02a5d81SAnna Dabrowska     */
353a02a5d81SAnna Dabrowska    private function cleanLogout()
354a02a5d81SAnna Dabrowska    {
355a02a5d81SAnna Dabrowska        if (isset($_SESSION[DOKU_COOKIE]['oauth-done'])) {
356a02a5d81SAnna Dabrowska            unset($_SESSION[DOKU_COOKIE]['oauth-done']);
357a02a5d81SAnna Dabrowska        }
358a02a5d81SAnna Dabrowska        if (isset($_SESSION[DOKU_COOKIE]['auth'])) {
359a02a5d81SAnna Dabrowska            unset($_SESSION[DOKU_COOKIE]['auth']);
360a02a5d81SAnna Dabrowska        }
361a02a5d81SAnna Dabrowska        $this->setUserCookie('', true, '', -60);
362a02a5d81SAnna Dabrowska    }
363a02a5d81SAnna Dabrowska
364a02a5d81SAnna Dabrowska    /**
365a02a5d81SAnna Dabrowska     * @param string $servicename
366a02a5d81SAnna Dabrowska     * @return \dokuwiki\plugin\oauth\Service
367a02a5d81SAnna Dabrowska     */
368a02a5d81SAnna Dabrowska    protected function getService($servicename)
369a02a5d81SAnna Dabrowska    {
370a02a5d81SAnna Dabrowska        /** @var helper_plugin_oauth $hlp */
371a02a5d81SAnna Dabrowska        $hlp = plugin_load('helper', 'oauth');
372a02a5d81SAnna Dabrowska
373a02a5d81SAnna Dabrowska        return $hlp->loadService($servicename);
374a02a5d81SAnna Dabrowska    }
375a02a5d81SAnna Dabrowska
376a02a5d81SAnna Dabrowska
377a02a5d81SAnna Dabrowska    /**
378a02a5d81SAnna Dabrowska     * Save user and auth data
379a02a5d81SAnna Dabrowska     *
380b2b9fbc7SMichael Große     * @param array $data
381b2b9fbc7SMichael Große     * @param string $service
382b2b9fbc7SMichael Große     */
3833e7ac5b1SAndreas Gohr    protected function setUserSession($data, $service)
3843e7ac5b1SAndreas Gohr    {
385b2b9fbc7SMichael Große        global $USERINFO;
386b2b9fbc7SMichael Große
387b2b9fbc7SMichael Große        // set up groups
388b2b9fbc7SMichael Große        if (!is_array($data['grps'])) {
389b2b9fbc7SMichael Große            $data['grps'] = array();
390b2b9fbc7SMichael Große        }
391b2b9fbc7SMichael Große        $data['grps'][] = $this->cleanGroup($service);
392b2b9fbc7SMichael Große        $data['grps'] = array_unique($data['grps']);
393b2b9fbc7SMichael Große
394b2b9fbc7SMichael Große        $USERINFO = $data;
395b2b9fbc7SMichael Große        $_SERVER['REMOTE_USER'] = $data['user'];
396*d9be1cb5SAnna Dabrowska
397*d9be1cb5SAnna Dabrowska
398*d9be1cb5SAnna Dabrowska        // FIXME this is not handled by SessionManager because auth.php accesses the data directly
399b2b9fbc7SMichael Große        $_SESSION[DOKU_COOKIE]['auth']['user'] = $data['user'];
400b2b9fbc7SMichael Große        $_SESSION[DOKU_COOKIE]['auth']['pass'] = $data['pass'];
401b2b9fbc7SMichael Große        $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
402b2b9fbc7SMichael Große        $_SESSION[DOKU_COOKIE]['auth']['buid'] = auth_browseruid();
403b2b9fbc7SMichael Große        $_SESSION[DOKU_COOKIE]['auth']['time'] = time();
404b2b9fbc7SMichael Große        $_SESSION[DOKU_COOKIE]['auth']['oauth'] = $service;
405b2b9fbc7SMichael Große    }
406b2b9fbc7SMichael Große
407b2b9fbc7SMichael Große    /**
4089928f5efSMichael Große     * @param string $user
409523e6571SMichael Große     * @param bool $sticky
4109928f5efSMichael Große     * @param string $servicename
411523e6571SMichael Große     * @param int $validityPeriodInSeconds optional, per default 1 Year
4129928f5efSMichael Große     */
4133e7ac5b1SAndreas Gohr    private function setUserCookie($user, $sticky, $servicename, $validityPeriodInSeconds = 31536000)
4143e7ac5b1SAndreas Gohr    {
4159928f5efSMichael Große        $cookie = base64_encode($user) . '|' . ((int)$sticky) . '|' . base64_encode('oauth') . '|' . base64_encode($servicename);
4169928f5efSMichael Große        $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'];
417523e6571SMichael Große        $time = $sticky ? (time() + $validityPeriodInSeconds) : 0;
4189928f5efSMichael Große        setcookie(DOKU_COOKIE, $cookie, $time, $cookieDir, '', ($conf['securecookie'] && is_ssl()), true);
4199928f5efSMichael Große    }
4209928f5efSMichael Große
421827232fcSMichael Große    /**
422a02a5d81SAnna Dabrowska     * @param array $session cookie auth session
423a02a5d81SAnna Dabrowska     *
424a02a5d81SAnna Dabrowska     * @return bool
425b2b9fbc7SMichael Große     */
426a02a5d81SAnna Dabrowska    protected function isSessionValid($session)
4273e7ac5b1SAndreas Gohr    {
428a02a5d81SAnna Dabrowska        /** @var helper_plugin_oauth $hlp */
429a02a5d81SAnna Dabrowska        $hlp = plugin_load('helper', 'oauth');
430a02a5d81SAnna Dabrowska        if ($hlp->validBrowserID($session)) {
431a02a5d81SAnna Dabrowska            if (!$hlp->isSessionTimedOut($session)) {
432a02a5d81SAnna Dabrowska                return true;
433a02a5d81SAnna Dabrowska            } elseif (!($hlp->isGETRequest() && $hlp->isDokuPHP())) {
434a02a5d81SAnna Dabrowska                // only force a recheck on a timed-out session during a GET request on the main script doku.php
435a02a5d81SAnna Dabrowska                return true;
436af2a4e8fSMichael Große            }
437af2a4e8fSMichael Große        }
438a02a5d81SAnna Dabrowska        return false;
439a02a5d81SAnna Dabrowska    }
440a02a5d81SAnna Dabrowska
441a02a5d81SAnna Dabrowska    /**
442a02a5d81SAnna Dabrowska     * Save login info in session
443a02a5d81SAnna Dabrowska     *
444a02a5d81SAnna Dabrowska     * @param string $servicename
445a02a5d81SAnna Dabrowska     */
446a02a5d81SAnna Dabrowska    protected function writeSession($servicename)
447a02a5d81SAnna Dabrowska    {
448a02a5d81SAnna Dabrowska        global $INPUT;
449a02a5d81SAnna Dabrowska
450*d9be1cb5SAnna Dabrowska        // used to be in 'oauth-inprogress'
451*d9be1cb5SAnna Dabrowska        self::$sessionManager->setServiceName($servicename);
452*d9be1cb5SAnna Dabrowska        self::$sessionManager->setPid($INPUT->str('id'));
453*d9be1cb5SAnna Dabrowska        self::$sessionManager->setParams($_GET);
454b8ca6a42SAnna Dabrowska
455*d9be1cb5SAnna Dabrowska        // used to be in 'oauth-done'
456*d9be1cb5SAnna Dabrowska        self::$sessionManager->setRequest($_REQUEST);
457a02a5d81SAnna Dabrowska
458a02a5d81SAnna Dabrowska        if (is_array($INPUT->post->param('do'))) {
459a02a5d81SAnna Dabrowska            $doPost = key($INPUT->post->arr('do'));
460a02a5d81SAnna Dabrowska        } else {
461a02a5d81SAnna Dabrowska            $doPost = $INPUT->post->str('do');
462a02a5d81SAnna Dabrowska        }
463a02a5d81SAnna Dabrowska        $doGet = $INPUT->get->str('do');
464a02a5d81SAnna Dabrowska        if (!empty($doPost)) {
465*d9be1cb5SAnna Dabrowska            self::$sessionManager->setDo($doPost);
466a02a5d81SAnna Dabrowska        } elseif (!empty($doGet)) {
467*d9be1cb5SAnna Dabrowska            self::$sessionManager->setDo($doGet);
468a02a5d81SAnna Dabrowska        }
469*d9be1cb5SAnna Dabrowska        self::$sessionManager->saveState();
470b2b9fbc7SMichael Große    }
471b2b9fbc7SMichael Große
472b2b9fbc7SMichael Große    /**
473b8ca6a42SAnna Dabrowska     * Farmer plugin support
474b8ca6a42SAnna Dabrowska     *
475b8ca6a42SAnna Dabrowska     * When coming back to farmer instance via OAUTH redirectURI, we need to redirect again
476b8ca6a42SAnna Dabrowska     * to a proper animal instance detected from $state
477b2b9fbc7SMichael Große     *
478311a6606SAnna Dabrowska     * @param $state
479b2b9fbc7SMichael Große     */
480*d9be1cb5SAnna Dabrowska    private function handleFarmState($state)
4813e7ac5b1SAndreas Gohr    {
482311a6606SAnna Dabrowska        /** @var \helper_plugin_farmer $farmer */
483311a6606SAnna Dabrowska        $farmer = plugin_load('helper', 'farmer', false, true);
484311a6606SAnna Dabrowska        $data = json_decode(base64_decode(urldecode($state)));
485311a6606SAnna Dabrowska        if (empty($data->animal) || $farmer->getAnimal() == $data->animal) {
486311a6606SAnna Dabrowska            return;
487827232fcSMichael Große        }
488311a6606SAnna Dabrowska        $animal = $data->animal;
489311a6606SAnna Dabrowska        $allAnimals = $farmer->getAllAnimals();
490311a6606SAnna Dabrowska        if (!in_array($animal, $allAnimals)) {
491311a6606SAnna Dabrowska            msg('Animal ' . $animal . ' does not exist!');
492311a6606SAnna Dabrowska            return;
493827232fcSMichael Große        }
494311a6606SAnna Dabrowska        global $INPUT;
495311a6606SAnna Dabrowska        $url = $farmer->getAnimalURL($animal) . '/doku.php?' . $INPUT->server->str('QUERY_STRING');
496311a6606SAnna Dabrowska        send_redirect($url);
497b2b9fbc7SMichael Große    }
498b2b9fbc7SMichael Große}
499b2b9fbc7SMichael Große
50080852c15SAndreas Gohr// vim:ts=4:sw=4:et:
501