xref: /plugin/oauth/auth.php (revision b8ca6a42fba4b00664bb9c14ccfeda17e50ca209)
180852c15SAndreas Gohr<?php
23e7ac5b1SAndreas Gohr
3*b8ca6a42SAnna Dabrowskause dokuwiki\plugin\oauth\SessionManager;
4*b8ca6a42SAnna 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
143e7ac5b1SAndreas Gohr    /** @inheritDoc */
153e7ac5b1SAndreas Gohr    public function __construct()
163e7ac5b1SAndreas Gohr    {
17f10e09e2SAndreas Gohr        parent::__construct();
1880852c15SAndreas Gohr
19f10e09e2SAndreas Gohr        $this->cando['external'] = true;
2080852c15SAndreas Gohr    }
2180852c15SAndreas Gohr
223e7ac5b1SAndreas Gohr    /** @inheritDoc */
23311a6606SAnna Dabrowska    public function trustExternal($user, $pass, $sticky = false)
243e7ac5b1SAndreas Gohr    {
25a02a5d81SAnna Dabrowska        global $INPUT;
26438dcc52SMichael Grosse
27*b8ca6a42SAnna Dabrowska        // handle redirects from farmer to animal wiki instances
28438dcc52SMichael Grosse        if ($INPUT->has('state') && plugin_load('helper', 'farmer', false, true)) {
29438dcc52SMichael Grosse            $this->handleState($INPUT->str('state'));
30438dcc52SMichael Grosse        }
3180852c15SAndreas Gohr
32*b8ca6a42SAnna Dabrowska        // first check in auth setup: is auth data present and still valid?
33a02a5d81SAnna Dabrowska        if ($this->sessionLogin()) return true;
3480852c15SAndreas Gohr
35*b8ca6a42SAnna Dabrowska        // if we have a service in session, either we're in oauth login or a previous login needs to be revalidated
36*b8ca6a42SAnna Dabrowska        $servicename = SessionManager::getServiceName();
37*b8ca6a42SAnna Dabrowska        if ($servicename) {
38*b8ca6a42SAnna Dabrowska            return $this->serviceLogin($servicename,
39*b8ca6a42SAnna Dabrowska                $sticky,
40*b8ca6a42SAnna Dabrowska                SessionManager::getPid(),
41*b8ca6a42SAnna Dabrowska                SessionManager::getParams(),
42*b8ca6a42SAnna Dabrowska                SessionManager::hasState()
43*b8ca6a42SAnna Dabrowska            );
44a7a8f46aSAndreas Gohr        }
45a7a8f46aSAndreas Gohr
46a02a5d81SAnna Dabrowska        // otherwise try cookie
47a02a5d81SAnna Dabrowska        $this->cookieLogin();
4880852c15SAndreas Gohr
49a7a8f46aSAndreas Gohr        // do the "normal" plain auth login via form
50a7a8f46aSAndreas Gohr        return auth_login($user, $pass, $sticky);
51a7a8f46aSAndreas Gohr    }
5280852c15SAndreas Gohr
53f2e164b0SMichael Große    /**
54311a6606SAnna Dabrowska     * Enhance function to check against duplicate emails
55311a6606SAnna Dabrowska     *
56311a6606SAnna Dabrowska     * @param string $user
57311a6606SAnna Dabrowska     * @param string $pwd
58311a6606SAnna Dabrowska     * @param string $name
59311a6606SAnna Dabrowska     * @param string $mail
60311a6606SAnna Dabrowska     * @param null $grps
61311a6606SAnna Dabrowska     * @return bool|null|string
62311a6606SAnna Dabrowska     */
63311a6606SAnna Dabrowska    public function createUser($user, $pwd, $name, $mail, $grps = null)
64311a6606SAnna Dabrowska    {
65311a6606SAnna Dabrowska        if ($this->getUserByEmail($mail)) {
66311a6606SAnna Dabrowska            msg($this->getLang('emailduplicate'), -1);
67311a6606SAnna Dabrowska            return false;
68311a6606SAnna Dabrowska        }
69311a6606SAnna Dabrowska
70311a6606SAnna Dabrowska        return parent::createUser($user, $pwd, $name, $mail, $grps);
71311a6606SAnna Dabrowska    }
72311a6606SAnna Dabrowska
73311a6606SAnna Dabrowska    /**
74311a6606SAnna Dabrowska     * Enhance function to check against duplicate emails
75311a6606SAnna Dabrowska     *
76311a6606SAnna Dabrowska     * @param string $user
77311a6606SAnna Dabrowska     * @param array $changes
78311a6606SAnna Dabrowska     * @return bool
79311a6606SAnna Dabrowska     */
80311a6606SAnna Dabrowska    public function modifyUser($user, $changes)
81311a6606SAnna Dabrowska    {
82311a6606SAnna Dabrowska        global $conf;
83311a6606SAnna Dabrowska
84311a6606SAnna Dabrowska        if (isset($changes['mail'])) {
85311a6606SAnna Dabrowska            $found = $this->getUserByEmail($changes['mail']);
86311a6606SAnna Dabrowska            if ($found && $found != $user) {
87311a6606SAnna Dabrowska                msg($this->getLang('emailduplicate'), -1);
88311a6606SAnna Dabrowska                return false;
89311a6606SAnna Dabrowska            }
90311a6606SAnna Dabrowska        }
91311a6606SAnna Dabrowska
92311a6606SAnna Dabrowska        $ok = parent::modifyUser($user, $changes);
93311a6606SAnna Dabrowska
94311a6606SAnna Dabrowska        // refresh session cache
95311a6606SAnna Dabrowska        touch($conf['cachedir'] . '/sessionpurge');
96311a6606SAnna Dabrowska
97311a6606SAnna Dabrowska        return $ok;
98311a6606SAnna Dabrowska    }
99311a6606SAnna Dabrowska
100311a6606SAnna Dabrowska    /**
101311a6606SAnna Dabrowska     * Unset additional stuff in session on logout
102311a6606SAnna Dabrowska     */
103311a6606SAnna Dabrowska    public function logOff()
104311a6606SAnna Dabrowska    {
105311a6606SAnna Dabrowska        parent::logOff();
106311a6606SAnna Dabrowska
107311a6606SAnna Dabrowska        $this->cleanLogout();
108311a6606SAnna Dabrowska    }
109311a6606SAnna Dabrowska
110311a6606SAnna Dabrowska    /**
111a02a5d81SAnna Dabrowska     * check if auth data is present in session and is still considered valid
112f2e164b0SMichael Große     *
113f2e164b0SMichael Große     * @return bool
114f2e164b0SMichael Große     */
115a02a5d81SAnna Dabrowska    protected function sessionLogin()
1163e7ac5b1SAndreas Gohr    {
117a02a5d81SAnna Dabrowska        global $USERINFO;
118a02a5d81SAnna Dabrowska        $session = $_SESSION[DOKU_COOKIE]['auth'];
119*b8ca6a42SAnna Dabrowska        // FIXME session can be null at this point (e.g. coming from sprintdoc svg.php)
120*b8ca6a42SAnna Dabrowska        // FIXME and so the subsequent check for non-GET non-doku.php requests is not performed
121a02a5d81SAnna Dabrowska        if (isset($session['oauth']) && $this->isSessionValid($session)) {
122a02a5d81SAnna Dabrowska            $_SERVER['REMOTE_USER'] = $session['user'];
123a02a5d81SAnna Dabrowska            $USERINFO = $session['info'];
124f2e164b0SMichael Große            return true;
125f2e164b0SMichael Große        }
126f2e164b0SMichael Große        return false;
127f2e164b0SMichael Große    }
128f2e164b0SMichael Große
129a02a5d81SAnna Dabrowska    /**
130a02a5d81SAnna Dabrowska     * Use cookie data to log in
131a02a5d81SAnna Dabrowska     */
132a02a5d81SAnna Dabrowska    protected function cookieLogin()
133a02a5d81SAnna Dabrowska    {
134a02a5d81SAnna Dabrowska        if (isset($_COOKIE[DOKU_COOKIE])) {
135a02a5d81SAnna Dabrowska            list($cookieuser, $cookiesticky, $auth, $servicename) = explode('|', $_COOKIE[DOKU_COOKIE]);
136a02a5d81SAnna Dabrowska            $auth = base64_decode($auth, true);
137a02a5d81SAnna Dabrowska            $servicename = base64_decode($servicename, true);
138a02a5d81SAnna Dabrowska            if ($auth === 'oauth') {
139*b8ca6a42SAnna Dabrowska                $this->relogin($servicename);
140a02a5d81SAnna Dabrowska            }
141a02a5d81SAnna Dabrowska        }
142a02a5d81SAnna Dabrowska    }
143a02a5d81SAnna Dabrowska
144a02a5d81SAnna Dabrowska    /**
145a02a5d81SAnna Dabrowska     * Use the OAuth service
146a02a5d81SAnna Dabrowska     *
147a02a5d81SAnna Dabrowska     * @param $servicename
148b2b9fbc7SMichael Große     * @param $sticky
149a02a5d81SAnna Dabrowska     * @param $page
150a02a5d81SAnna Dabrowska     * @param $params
151a02a5d81SAnna Dabrowska     * @param $existingLoginProcess
152a02a5d81SAnna Dabrowska     * @return bool
153a02a5d81SAnna Dabrowska     * @throws \OAuth\Common\Exception\Exception
154a02a5d81SAnna Dabrowska     * @throws \OAuth\Common\Http\Exception\TokenResponseException
155a02a5d81SAnna Dabrowska     * @throws \OAuth\Common\Storage\Exception\TokenNotFoundException
156a02a5d81SAnna Dabrowska     */
157a02a5d81SAnna Dabrowska    protected function serviceLogin($servicename, $sticky, $page, $params, $existingLoginProcess)
158a02a5d81SAnna Dabrowska    {
159a02a5d81SAnna Dabrowska        $service = $this->getService($servicename);
160a02a5d81SAnna Dabrowska        if (is_null($service)) {
161a02a5d81SAnna Dabrowska            $this->cleanLogout();
162a02a5d81SAnna Dabrowska            return false;
163a02a5d81SAnna Dabrowska        }
164a02a5d81SAnna Dabrowska
165a02a5d81SAnna Dabrowska        if ($service->checkToken()) {
166a02a5d81SAnna Dabrowska            if (!$this->processLogin($sticky, $service, $servicename, $page, $params)) {
167a02a5d81SAnna Dabrowska                $this->cleanLogout();
168a02a5d81SAnna Dabrowska                return false;
169a02a5d81SAnna Dabrowska            }
170a02a5d81SAnna Dabrowska            return true;
171a02a5d81SAnna Dabrowska        } else {
172a02a5d81SAnna Dabrowska            if ($existingLoginProcess) {
173a02a5d81SAnna Dabrowska                msg($this->getLang('oauth login failed'), 0);
174a02a5d81SAnna Dabrowska                $this->cleanLogout();
175a02a5d81SAnna Dabrowska                return false;
176a02a5d81SAnna Dabrowska            } else {
177a02a5d81SAnna Dabrowska                // first time here
178*b8ca6a42SAnna Dabrowska                $this->relogin($servicename);
179a02a5d81SAnna Dabrowska            }
180a02a5d81SAnna Dabrowska        }
181a02a5d81SAnna Dabrowska
182a02a5d81SAnna Dabrowska        $this->cleanLogout();
183a02a5d81SAnna Dabrowska        return false; // something went wrong during oAuth login
184a02a5d81SAnna Dabrowska    }
185a02a5d81SAnna Dabrowska
186a02a5d81SAnna Dabrowska    /**
187*b8ca6a42SAnna Dabrowska     * Relogin using auth info read from session / cookie
188*b8ca6a42SAnna Dabrowska     *
189a02a5d81SAnna Dabrowska     * @param string $servicename
190a02a5d81SAnna Dabrowska     * @return void|false
191a02a5d81SAnna Dabrowska     * @throws \OAuth\Common\Http\Exception\TokenResponseException
192a02a5d81SAnna Dabrowska     */
193*b8ca6a42SAnna Dabrowska    protected function relogin($servicename)
194a02a5d81SAnna Dabrowska    {
195a02a5d81SAnna Dabrowska        $service = $this->getService($servicename);
196a02a5d81SAnna Dabrowska        if (is_null($service)) return false;
197a02a5d81SAnna Dabrowska
198a02a5d81SAnna Dabrowska        $this->writeSession($servicename);
199a02a5d81SAnna Dabrowska        $service->login();
200a02a5d81SAnna Dabrowska    }
201a02a5d81SAnna Dabrowska
202a02a5d81SAnna Dabrowska
203a02a5d81SAnna Dabrowska    /**
204a02a5d81SAnna Dabrowska     * @param bool $sticky
205a02a5d81SAnna Dabrowska     * @param \dokuwiki\plugin\oauth\Service $service
2069928f5efSMichael Große     * @param string $servicename
207b2b9fbc7SMichael Große     * @param string $page
208188ba446SMichael Große     * @param array $params
209f07c7607SMichael Große     *
210f07c7607SMichael Große     * @return bool
211a02a5d81SAnna Dabrowska     * @throws \OAuth\Common\Exception\Exception
212f07c7607SMichael Große     */
213a02a5d81SAnna Dabrowska    protected function processLogin($sticky, $service, $servicename, $page, $params = [])
2143e7ac5b1SAndreas Gohr    {
215a02a5d81SAnna Dabrowska        $userinfo = $service->getUser();
216a02a5d81SAnna Dabrowska        $ok = $this->processUserinfo($userinfo, $servicename);
217f07c7607SMichael Große        if (!$ok) {
218f07c7607SMichael Große            return false;
219f07c7607SMichael Große        }
220a02a5d81SAnna Dabrowska        $this->setUserSession($userinfo, $servicename);
221a02a5d81SAnna Dabrowska        $this->setUserCookie($userinfo['user'], $sticky, $servicename);
222b2b9fbc7SMichael Große        if (isset($page)) {
223188ba446SMichael Große            if (!empty($params['id'])) unset($params['id']);
224188ba446SMichael Große            send_redirect(wl($page, $params, false, '&'));
225b2b9fbc7SMichael Große        }
226f07c7607SMichael Große        return true;
227f07c7607SMichael Große    }
228f07c7607SMichael Große
2299928f5efSMichael Große    /**
230a02a5d81SAnna Dabrowska     * process the user and update the user info array
2319928f5efSMichael Große     *
232a02a5d81SAnna Dabrowska     * @param array $userinfo User info received from authentication
233a02a5d81SAnna Dabrowska     * @param string $servicename Auth service
2349928f5efSMichael Große     *
2359928f5efSMichael Große     * @return bool
2369928f5efSMichael Große     */
237a02a5d81SAnna Dabrowska    protected function processUserinfo(&$userinfo, $servicename)
2383e7ac5b1SAndreas Gohr    {
239a02a5d81SAnna Dabrowska        $userinfo['user'] = $this->cleanUser((string)$userinfo['user']);
240a02a5d81SAnna Dabrowska        if (!$userinfo['name']) $userinfo['name'] = $userinfo['user'];
2419928f5efSMichael Große
242a02a5d81SAnna Dabrowska        if (!$userinfo['user'] || !$userinfo['mail']) {
2439928f5efSMichael Große            msg("$servicename did not provide the needed user info. Can't log you in", -1);
2449928f5efSMichael Große            return false;
2459928f5efSMichael Große        }
2469928f5efSMichael Große
2479928f5efSMichael Große        // see if the user is known already
248a02a5d81SAnna Dabrowska        $localUser = $this->getUserByEmail($userinfo['mail']);
249a02a5d81SAnna Dabrowska        if ($localUser) {
250a02a5d81SAnna Dabrowska            $localUserInfo = $this->getUserData($localUser);
2519928f5efSMichael Große            // check if the user allowed access via this service
252a02a5d81SAnna Dabrowska            if (!in_array($this->cleanGroup($servicename), $localUserInfo['grps'])) {
2539928f5efSMichael Große                msg(sprintf($this->getLang('authnotenabled'), $servicename), -1);
2549928f5efSMichael Große                return false;
2559928f5efSMichael Große            }
256a02a5d81SAnna Dabrowska            $userinfo['user'] = $localUser;
257a02a5d81SAnna Dabrowska            $userinfo['name'] = $localUserInfo['name'];
258a02a5d81SAnna Dabrowska            $userinfo['grps'] = array_merge((array)$userinfo['grps'], $localUserInfo['grps']);
259d313403cSAnna Dabrowska        } elseif (actionOK('register') || $this->getConf('register-on-auth')) {
260a02a5d81SAnna Dabrowska            $ok = $this->addUser($userinfo, $servicename);
2619928f5efSMichael Große            if (!$ok) {
2629928f5efSMichael Große                msg('something went wrong creating your user account. please try again later.', -1);
2639928f5efSMichael Große                return false;
2649928f5efSMichael Große            }
2659928f5efSMichael Große        } else {
2669928f5efSMichael Große            msg($this->getLang('addUser not possible'), -1);
2679928f5efSMichael Große            return false;
2689928f5efSMichael Große        }
2699928f5efSMichael Große        return true;
2709928f5efSMichael Große    }
2719928f5efSMichael Große
2729928f5efSMichael Große    /**
273b2b9fbc7SMichael Große     * new user, create him - making sure the login is unique by adding a number if needed
274b2b9fbc7SMichael Große     *
275a02a5d81SAnna Dabrowska     * @param array $userinfo user info received from the oAuth service
276b2b9fbc7SMichael Große     * @param string $servicename
277b2b9fbc7SMichael Große     *
278b2b9fbc7SMichael Große     * @return bool
279b2b9fbc7SMichael Große     */
280a02a5d81SAnna Dabrowska    protected function addUser(&$userinfo, $servicename)
2813e7ac5b1SAndreas Gohr    {
282b2b9fbc7SMichael Große        global $conf;
283a02a5d81SAnna Dabrowska        $user = $userinfo['user'];
284b2b9fbc7SMichael Große        $count = '';
285b2b9fbc7SMichael Große        while ($this->getUserData($user . $count)) {
286b2b9fbc7SMichael Große            if ($count) {
287b2b9fbc7SMichael Große                $count++;
288b2b9fbc7SMichael Große            } else {
289b2b9fbc7SMichael Große                $count = 1;
290b2b9fbc7SMichael Große            }
291b2b9fbc7SMichael Große        }
292b2b9fbc7SMichael Große        $user = $user . $count;
293a02a5d81SAnna Dabrowska        $userinfo['user'] = $user;
294b2b9fbc7SMichael Große        $groups_on_creation = array();
295b2b9fbc7SMichael Große        $groups_on_creation[] = $conf['defaultgroup'];
296b2b9fbc7SMichael Große        $groups_on_creation[] = $this->cleanGroup($servicename); // add service as group
297a02a5d81SAnna Dabrowska        $userinfo['grps'] = array_merge((array)$userinfo['grps'], $groups_on_creation);
298b2b9fbc7SMichael Große
299b2b9fbc7SMichael Große        $ok = $this->triggerUserMod(
300b2b9fbc7SMichael Große            'create',
301a02a5d81SAnna Dabrowska            array($user, auth_pwgen($user), $userinfo['name'], $userinfo['mail'], $groups_on_creation,)
302b2b9fbc7SMichael Große        );
303b2b9fbc7SMichael Große        if (!$ok) {
304b2b9fbc7SMichael Große            return false;
305b2b9fbc7SMichael Große        }
306b2b9fbc7SMichael Große
307b2b9fbc7SMichael Große        // send notification about the new user
308b2b9fbc7SMichael Große        $subscription = new Subscription();
309a02a5d81SAnna Dabrowska        $subscription->send_register($user, $userinfo['name'], $userinfo['mail']);
310b2b9fbc7SMichael Große        return true;
311b2b9fbc7SMichael Große    }
312b2b9fbc7SMichael Große
313b2b9fbc7SMichael Große    /**
314a02a5d81SAnna Dabrowska     * Find a user by email address
315b2b9fbc7SMichael Große     *
316b2b9fbc7SMichael Große     * @param $mail
317b2b9fbc7SMichael Große     * @return bool|string
318b2b9fbc7SMichael Große     */
3193e7ac5b1SAndreas Gohr    protected function getUserByEmail($mail)
3203e7ac5b1SAndreas Gohr    {
3218b214edcSAndreas Gohr        if ($this->users === null) {
3228b214edcSAndreas Gohr            if (is_callable([$this, '_loadUserData'])) {
3238b214edcSAndreas Gohr                $this->_loadUserData();
3248b214edcSAndreas Gohr            } else {
3258b214edcSAndreas Gohr                $this->loadUserData();
3268b214edcSAndreas Gohr            }
3278b214edcSAndreas Gohr        }
328b2b9fbc7SMichael Große        $mail = strtolower($mail);
329b2b9fbc7SMichael Große
330a02a5d81SAnna Dabrowska        foreach ($this->users as $user => $userinfo) {
331a02a5d81SAnna Dabrowska            if (strtolower($userinfo['mail']) == $mail) return $user;
332b2b9fbc7SMichael Große        }
333b2b9fbc7SMichael Große
334b2b9fbc7SMichael Große        return false;
335b2b9fbc7SMichael Große    }
336b2b9fbc7SMichael Große
337b2b9fbc7SMichael Große    /**
338a02a5d81SAnna Dabrowska     * unset auth cookies and session information
339a02a5d81SAnna Dabrowska     */
340a02a5d81SAnna Dabrowska    private function cleanLogout()
341a02a5d81SAnna Dabrowska    {
342a02a5d81SAnna Dabrowska        if (isset($_SESSION[DOKU_COOKIE]['oauth-done'])) {
343a02a5d81SAnna Dabrowska            unset($_SESSION[DOKU_COOKIE]['oauth-done']);
344a02a5d81SAnna Dabrowska        }
345a02a5d81SAnna Dabrowska        if (isset($_SESSION[DOKU_COOKIE]['auth'])) {
346a02a5d81SAnna Dabrowska            unset($_SESSION[DOKU_COOKIE]['auth']);
347a02a5d81SAnna Dabrowska        }
348a02a5d81SAnna Dabrowska        $this->setUserCookie('', true, '', -60);
349a02a5d81SAnna Dabrowska    }
350a02a5d81SAnna Dabrowska
351a02a5d81SAnna Dabrowska    /**
352a02a5d81SAnna Dabrowska     * @param string $servicename
353a02a5d81SAnna Dabrowska     * @return \dokuwiki\plugin\oauth\Service
354a02a5d81SAnna Dabrowska     */
355a02a5d81SAnna Dabrowska    protected function getService($servicename)
356a02a5d81SAnna Dabrowska    {
357a02a5d81SAnna Dabrowska        /** @var helper_plugin_oauth $hlp */
358a02a5d81SAnna Dabrowska        $hlp = plugin_load('helper', 'oauth');
359a02a5d81SAnna Dabrowska
360a02a5d81SAnna Dabrowska        return $hlp->loadService($servicename);
361a02a5d81SAnna Dabrowska    }
362a02a5d81SAnna Dabrowska
363a02a5d81SAnna Dabrowska
364a02a5d81SAnna Dabrowska    /**
365a02a5d81SAnna Dabrowska     * Save user and auth data
366a02a5d81SAnna Dabrowska     *
367b2b9fbc7SMichael Große     * @param array $data
368b2b9fbc7SMichael Große     * @param string $service
369b2b9fbc7SMichael Große     */
3703e7ac5b1SAndreas Gohr    protected function setUserSession($data, $service)
3713e7ac5b1SAndreas Gohr    {
372b2b9fbc7SMichael Große        global $USERINFO;
373b2b9fbc7SMichael Große
374b2b9fbc7SMichael Große        // set up groups
375b2b9fbc7SMichael Große        if (!is_array($data['grps'])) {
376b2b9fbc7SMichael Große            $data['grps'] = array();
377b2b9fbc7SMichael Große        }
378b2b9fbc7SMichael Große        $data['grps'][] = $this->cleanGroup($service);
379b2b9fbc7SMichael Große        $data['grps'] = array_unique($data['grps']);
380b2b9fbc7SMichael Große
381b2b9fbc7SMichael Große        $USERINFO = $data;
382b2b9fbc7SMichael Große        $_SERVER['REMOTE_USER'] = $data['user'];
383b2b9fbc7SMichael Große        $_SESSION[DOKU_COOKIE]['auth']['user'] = $data['user'];
384b2b9fbc7SMichael Große        $_SESSION[DOKU_COOKIE]['auth']['pass'] = $data['pass'];
385b2b9fbc7SMichael Große        $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
386b2b9fbc7SMichael Große        $_SESSION[DOKU_COOKIE]['auth']['buid'] = auth_browseruid();
387b2b9fbc7SMichael Große        $_SESSION[DOKU_COOKIE]['auth']['time'] = time();
388b2b9fbc7SMichael Große        $_SESSION[DOKU_COOKIE]['auth']['oauth'] = $service;
389b2b9fbc7SMichael Große    }
390b2b9fbc7SMichael Große
391b2b9fbc7SMichael Große    /**
3929928f5efSMichael Große     * @param string $user
393523e6571SMichael Große     * @param bool $sticky
3949928f5efSMichael Große     * @param string $servicename
395523e6571SMichael Große     * @param int $validityPeriodInSeconds optional, per default 1 Year
3969928f5efSMichael Große     */
3973e7ac5b1SAndreas Gohr    private function setUserCookie($user, $sticky, $servicename, $validityPeriodInSeconds = 31536000)
3983e7ac5b1SAndreas Gohr    {
3999928f5efSMichael Große        $cookie = base64_encode($user) . '|' . ((int)$sticky) . '|' . base64_encode('oauth') . '|' . base64_encode($servicename);
4009928f5efSMichael Große        $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'];
401523e6571SMichael Große        $time = $sticky ? (time() + $validityPeriodInSeconds) : 0;
4029928f5efSMichael Große        setcookie(DOKU_COOKIE, $cookie, $time, $cookieDir, '', ($conf['securecookie'] && is_ssl()), true);
4039928f5efSMichael Große    }
4049928f5efSMichael Große
405827232fcSMichael Große    /**
406a02a5d81SAnna Dabrowska     * @param array $session cookie auth session
407a02a5d81SAnna Dabrowska     *
408a02a5d81SAnna Dabrowska     * @return bool
409b2b9fbc7SMichael Große     */
410a02a5d81SAnna Dabrowska    protected function isSessionValid($session)
4113e7ac5b1SAndreas Gohr    {
412a02a5d81SAnna Dabrowska        /** @var helper_plugin_oauth $hlp */
413a02a5d81SAnna Dabrowska        $hlp = plugin_load('helper', 'oauth');
414a02a5d81SAnna Dabrowska        if ($hlp->validBrowserID($session)) {
415a02a5d81SAnna Dabrowska            if (!$hlp->isSessionTimedOut($session)) {
416a02a5d81SAnna Dabrowska                return true;
417a02a5d81SAnna Dabrowska            } elseif (!($hlp->isGETRequest() && $hlp->isDokuPHP())) {
418a02a5d81SAnna Dabrowska                // only force a recheck on a timed-out session during a GET request on the main script doku.php
419a02a5d81SAnna Dabrowska                return true;
420af2a4e8fSMichael Große            }
421af2a4e8fSMichael Große        }
422a02a5d81SAnna Dabrowska        return false;
423a02a5d81SAnna Dabrowska    }
424a02a5d81SAnna Dabrowska
425a02a5d81SAnna Dabrowska    /**
426a02a5d81SAnna Dabrowska     * Save login info in session
427a02a5d81SAnna Dabrowska     *
428a02a5d81SAnna Dabrowska     * @param string $servicename
429a02a5d81SAnna Dabrowska     */
430a02a5d81SAnna Dabrowska    protected function writeSession($servicename)
431a02a5d81SAnna Dabrowska    {
432a02a5d81SAnna Dabrowska        global $INPUT;
433a02a5d81SAnna Dabrowska
434*b8ca6a42SAnna Dabrowska        // FIXME delegate to SessionManager? in action/login.php as well?
435a02a5d81SAnna Dabrowska        session_start();
436a02a5d81SAnna Dabrowska        $_SESSION[DOKU_COOKIE]['oauth-inprogress']['service'] = $servicename;
437a02a5d81SAnna Dabrowska        $_SESSION[DOKU_COOKIE]['oauth-inprogress']['id'] = $INPUT->str('id');
438*b8ca6a42SAnna Dabrowska
439a02a5d81SAnna Dabrowska        $_SESSION[DOKU_COOKIE]['oauth-inprogress']['params'] = $_GET;
440a02a5d81SAnna Dabrowska
441a02a5d81SAnna Dabrowska        $_SESSION[DOKU_COOKIE]['oauth-done']['$_REQUEST'] = $_REQUEST;
442a02a5d81SAnna Dabrowska
443a02a5d81SAnna Dabrowska        if (is_array($INPUT->post->param('do'))) {
444a02a5d81SAnna Dabrowska            $doPost = key($INPUT->post->arr('do'));
445a02a5d81SAnna Dabrowska        } else {
446a02a5d81SAnna Dabrowska            $doPost = $INPUT->post->str('do');
447a02a5d81SAnna Dabrowska        }
448a02a5d81SAnna Dabrowska        $doGet = $INPUT->get->str('do');
449a02a5d81SAnna Dabrowska        if (!empty($doPost)) {
450a02a5d81SAnna Dabrowska            $_SESSION[DOKU_COOKIE]['oauth-done']['do'] = $doPost;
451a02a5d81SAnna Dabrowska        } elseif (!empty($doGet)) {
452a02a5d81SAnna Dabrowska            $_SESSION[DOKU_COOKIE]['oauth-done']['do'] = $doGet;
453a02a5d81SAnna Dabrowska        }
454a02a5d81SAnna Dabrowska
455a02a5d81SAnna Dabrowska        session_write_close();
456b2b9fbc7SMichael Große    }
457b2b9fbc7SMichael Große
458b2b9fbc7SMichael Große    /**
459*b8ca6a42SAnna Dabrowska     * Farmer plugin support
460*b8ca6a42SAnna Dabrowska     *
461*b8ca6a42SAnna Dabrowska     * When coming back to farmer instance via OAUTH redirectURI, we need to redirect again
462*b8ca6a42SAnna Dabrowska     * to a proper animal instance detected from $state
463b2b9fbc7SMichael Große     *
464311a6606SAnna Dabrowska     * @param $state
465b2b9fbc7SMichael Große     */
466311a6606SAnna Dabrowska    private function handleState($state)
4673e7ac5b1SAndreas Gohr    {
468311a6606SAnna Dabrowska        /** @var \helper_plugin_farmer $farmer */
469311a6606SAnna Dabrowska        $farmer = plugin_load('helper', 'farmer', false, true);
470311a6606SAnna Dabrowska        $data = json_decode(base64_decode(urldecode($state)));
471311a6606SAnna Dabrowska        if (empty($data->animal) || $farmer->getAnimal() == $data->animal) {
472311a6606SAnna Dabrowska            return;
473827232fcSMichael Große        }
474311a6606SAnna Dabrowska        $animal = $data->animal;
475311a6606SAnna Dabrowska        $allAnimals = $farmer->getAllAnimals();
476311a6606SAnna Dabrowska        if (!in_array($animal, $allAnimals)) {
477311a6606SAnna Dabrowska            msg('Animal ' . $animal . ' does not exist!');
478311a6606SAnna Dabrowska            return;
479827232fcSMichael Große        }
480311a6606SAnna Dabrowska        global $INPUT;
481311a6606SAnna Dabrowska        $url = $farmer->getAnimalURL($animal) . '/doku.php?' . $INPUT->server->str('QUERY_STRING');
482311a6606SAnna Dabrowska        send_redirect($url);
483b2b9fbc7SMichael Große    }
484b2b9fbc7SMichael Große}
485b2b9fbc7SMichael Große
48680852c15SAndreas Gohr// vim:ts=4:sw=4:et:
487