xref: /plugin/oauth/auth.php (revision f866280e4c6c2430bc9eb6ea7dffcc074e6f0bd9)
180852c15SAndreas Gohr<?php
280852c15SAndreas Gohr/**
380852c15SAndreas Gohr * DokuWiki Plugin oauth (Auth Component)
480852c15SAndreas Gohr *
580852c15SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
680852c15SAndreas Gohr * @author  Andreas Gohr <andi@splitbrain.org>
780852c15SAndreas Gohr */
880852c15SAndreas Gohr
980852c15SAndreas Gohr// must be run within Dokuwiki
1080852c15SAndreas Gohrif(!defined('DOKU_INC')) die();
1180852c15SAndreas Gohr
12f10e09e2SAndreas Gohrclass auth_plugin_oauth extends auth_plugin_authplain {
1380852c15SAndreas Gohr
14*f866280eSAndreas Gohr    /**
15*f866280eSAndreas Gohr     * Constructor
16*f866280eSAndreas Gohr     *
17*f866280eSAndreas Gohr     * Sets capabilities.
18*f866280eSAndreas Gohr     */
1980852c15SAndreas Gohr    public function __construct() {
20f10e09e2SAndreas Gohr        parent::__construct();
2180852c15SAndreas Gohr
22f10e09e2SAndreas Gohr        $this->cando['external'] = true;
2380852c15SAndreas Gohr    }
2480852c15SAndreas Gohr
25*f866280eSAndreas Gohr    /**
26*f866280eSAndreas Gohr     * Handle the login
27*f866280eSAndreas Gohr     *
28*f866280eSAndreas Gohr     * This either trusts the session data (if any), processes the second oAuth step or simply
29*f866280eSAndreas Gohr     * executes a normal plugin against local users.
30*f866280eSAndreas Gohr     *
31*f866280eSAndreas Gohr     * @param string $user
32*f866280eSAndreas Gohr     * @param string $pass
33*f866280eSAndreas Gohr     * @param bool   $sticky
34*f866280eSAndreas Gohr     * @return bool
35*f866280eSAndreas Gohr     */
36f10e09e2SAndreas Gohr    function trustExternal($user, $pass, $sticky = false) {
37a7a8f46aSAndreas Gohr        global $INPUT;
38a7a8f46aSAndreas Gohr        global $conf;
39a7a8f46aSAndreas Gohr        global $USERINFO;
4080852c15SAndreas Gohr
41a7a8f46aSAndreas Gohr        $servicename = $INPUT->str('oa');
4280852c15SAndreas Gohr
43a7a8f46aSAndreas Gohr        // check session for existing oAuth login data
44a7a8f46aSAndreas Gohr        $session = $_SESSION[DOKU_COOKIE]['auth'];
45a7a8f46aSAndreas Gohr        if(!$servicename && isset($session['oauth'])) {
46a7a8f46aSAndreas Gohr            $servicename = $session['oauth'];
47a7a8f46aSAndreas Gohr            // check if session data is still considered valid
48a7a8f46aSAndreas Gohr            if(($session['time'] >= time() - $conf['auth_security_timeout']) &&
49*f866280eSAndreas Gohr                ($session['buid'] == auth_browseruid())
50*f866280eSAndreas Gohr            ) {
5180852c15SAndreas Gohr
52a7a8f46aSAndreas Gohr                $_SERVER['REMOTE_USER'] = $session['user'];
53a7a8f46aSAndreas Gohr                $USERINFO               = $session['info'];
5480852c15SAndreas Gohr                return true;
55f10e09e2SAndreas Gohr            }
5680852c15SAndreas Gohr        }
5780852c15SAndreas Gohr
58a7a8f46aSAndreas Gohr        // either we're in oauth login or a previous log needs to be rechecked
59a7a8f46aSAndreas Gohr        if($servicename) {
60a7a8f46aSAndreas Gohr            /** @var helper_plugin_oauth $hlp */
61a7a8f46aSAndreas Gohr            $hlp     = plugin_load('helper', 'oauth');
62a7a8f46aSAndreas Gohr            $service = $hlp->loadService($servicename);
63a7a8f46aSAndreas Gohr            if(is_null($service)) return false;
64a7a8f46aSAndreas Gohr
65a7a8f46aSAndreas Gohr            // get the token
66a7a8f46aSAndreas Gohr            if($service->checkToken()) {
67a7a8f46aSAndreas Gohr                $uinfo = $service->getUser();
68*f866280eSAndreas Gohr
69*f866280eSAndreas Gohr                // see if the user is known already
70*f866280eSAndreas Gohr                $user = $this->getUserByEmail($uinfo['mail']);
71*f866280eSAndreas Gohr                if($user) {
72*f866280eSAndreas Gohr                    $sinfo         = $this->getUserData($user);
73*f866280eSAndreas Gohr                    $uinfo['user'] = $user;
74*f866280eSAndreas Gohr                    $uinfo['name'] = $sinfo['name'];
75*f866280eSAndreas Gohr                    $uinfo['grps'] = array_merge((array) $uinfo['grps'], $sinfo['grps']);
76*f866280eSAndreas Gohr                } else {
77*f866280eSAndreas Gohr                    // new user, create him - making sure the login is unique by adding a number if needed
78*f866280eSAndreas Gohr                    $user  = $uinfo['user'];
79*f866280eSAndreas Gohr                    $count = '';
80*f866280eSAndreas Gohr                    while($this->getUserData($user.$count)) {
81*f866280eSAndreas Gohr                        if($count) {
82*f866280eSAndreas Gohr                            $count++;
83*f866280eSAndreas Gohr                        } else {
84*f866280eSAndreas Gohr                            $count = 1;
85*f866280eSAndreas Gohr                        }
86*f866280eSAndreas Gohr                    }
87*f866280eSAndreas Gohr                    $user          = $user.$count;
88*f866280eSAndreas Gohr                    $uinfo['user'] = $user;
89*f866280eSAndreas Gohr                    $uinfo['grps'] = (array) $uinfo['grps'];
90*f866280eSAndreas Gohr                    $uinfo['grps'][] = $conf['defaultgroup'];
91*f866280eSAndreas Gohr
92*f866280eSAndreas Gohr                    $this->createUser($user, auth_pwgen($user), $uinfo['name'], $uinfo['mail'], $uinfo['grps']);
93*f866280eSAndreas Gohr                }
94*f866280eSAndreas Gohr
95*f866280eSAndreas Gohr                // set user session
96a7a8f46aSAndreas Gohr                $this->setUserSession($uinfo, $servicename);
97a7a8f46aSAndreas Gohr                return true;
98a7a8f46aSAndreas Gohr            }
99a7a8f46aSAndreas Gohr
100a7a8f46aSAndreas Gohr            return false; // something went wrong during oAuth login
10180852c15SAndreas Gohr        }
10280852c15SAndreas Gohr
103a7a8f46aSAndreas Gohr        // do the "normal" plain auth login via form
104a7a8f46aSAndreas Gohr        return auth_login($user, $pass, $sticky);
105a7a8f46aSAndreas Gohr    }
10680852c15SAndreas Gohr
107a7a8f46aSAndreas Gohr    /**
108a7a8f46aSAndreas Gohr     * @param array  $data
109a7a8f46aSAndreas Gohr     * @param string $service
110a7a8f46aSAndreas Gohr     */
111a7a8f46aSAndreas Gohr    protected function setUserSession($data, $service) {
112a7a8f46aSAndreas Gohr        global $USERINFO;
113a7a8f46aSAndreas Gohr        global $conf;
114a7a8f46aSAndreas Gohr
115a7a8f46aSAndreas Gohr        // set up groups
116a7a8f46aSAndreas Gohr        if(!is_array($data['grps'])) {
117a7a8f46aSAndreas Gohr            $data['grps'] = array();
118a7a8f46aSAndreas Gohr        }
119a7a8f46aSAndreas Gohr        $data['grps'][] = $this->cleanGroup($service);
120*f866280eSAndreas Gohr        $data['grps']   = array_unique($data['grps']);
12180852c15SAndreas Gohr
122f10e09e2SAndreas Gohr        $USERINFO                               = $data;
123f10e09e2SAndreas Gohr        $_SERVER['REMOTE_USER']                 = $data['user'];
124f10e09e2SAndreas Gohr        $_SESSION[DOKU_COOKIE]['auth']['user']  = $data['user'];
125f10e09e2SAndreas Gohr        $_SESSION[DOKU_COOKIE]['auth']['pass']  = $data['pass'];
126f10e09e2SAndreas Gohr        $_SESSION[DOKU_COOKIE]['auth']['info']  = $USERINFO;
127a7a8f46aSAndreas Gohr        $_SESSION[DOKU_COOKIE]['auth']['buid']  = auth_browseruid();
128a7a8f46aSAndreas Gohr        $_SESSION[DOKU_COOKIE]['auth']['time']  = time();
129a7a8f46aSAndreas Gohr        $_SESSION[DOKU_COOKIE]['auth']['oauth'] = $service;
13080852c15SAndreas Gohr    }
13180852c15SAndreas Gohr
132*f866280eSAndreas Gohr    /**
133*f866280eSAndreas Gohr     * Find a user by his email address
134*f866280eSAndreas Gohr     *
135*f866280eSAndreas Gohr     * @param $mail
136*f866280eSAndreas Gohr     * @return bool|string
137*f866280eSAndreas Gohr     */
13838378fbbSAndreas Gohr    protected function getUserByEmail($mail) {
139*f866280eSAndreas Gohr        if($this->users === null) $this->_loadUserData();
14038378fbbSAndreas Gohr        $mail = strtolower($mail);
141*f866280eSAndreas Gohr
142*f866280eSAndreas Gohr        foreach($this->users as $user => $uinfo) {
143*f866280eSAndreas Gohr            if(strtolower($uinfo['mail']) == $mail) return $user;
14438378fbbSAndreas Gohr        }
14538378fbbSAndreas Gohr
146*f866280eSAndreas Gohr        return false;
147*f866280eSAndreas Gohr    }
14838378fbbSAndreas Gohr
149*f866280eSAndreas Gohr    /**
150*f866280eSAndreas Gohr     * Enhance function to check aainst duplicate emails
151*f866280eSAndreas Gohr     *
152*f866280eSAndreas Gohr     * @param string $user
153*f866280eSAndreas Gohr     * @param string $pwd
154*f866280eSAndreas Gohr     * @param string $name
155*f866280eSAndreas Gohr     * @param string $mail
156*f866280eSAndreas Gohr     * @param null   $grps
157*f866280eSAndreas Gohr     * @return bool|null|string
158*f866280eSAndreas Gohr     */
159*f866280eSAndreas Gohr    public function createUser($user, $pwd, $name, $mail, $grps = null) {
160*f866280eSAndreas Gohr        if($this->getUserByEmail($mail)) {
161*f866280eSAndreas Gohr            msg($this->getLang('emailduplicate'), -1);
162*f866280eSAndreas Gohr            return false;
163*f866280eSAndreas Gohr        }
164*f866280eSAndreas Gohr
16538378fbbSAndreas Gohr        return parent::createUser($user, $pwd, $name, $mail, $grps);
16638378fbbSAndreas Gohr    }
16738378fbbSAndreas Gohr
168*f866280eSAndreas Gohr    /**
169*f866280eSAndreas Gohr     * Enhance function to check aainst duplicate emails
170*f866280eSAndreas Gohr     *
171*f866280eSAndreas Gohr     * @param string $user
172*f866280eSAndreas Gohr     * @param array  $changes
173*f866280eSAndreas Gohr     * @return bool
174*f866280eSAndreas Gohr     */
17538378fbbSAndreas Gohr    public function modifyUser($user, $changes) {
176*f866280eSAndreas Gohr        if(isset($changes['mail']) && $this->getUserByEmail($changes['mail'])) {
177*f866280eSAndreas Gohr            msg($this->getLang('emailduplicate'), -1);
178*f866280eSAndreas Gohr            return false;
179*f866280eSAndreas Gohr        }
18038378fbbSAndreas Gohr
18138378fbbSAndreas Gohr        return parent::modifyUser($user, $changes);
18238378fbbSAndreas Gohr    }
18338378fbbSAndreas Gohr
18480852c15SAndreas Gohr}
18580852c15SAndreas Gohr
18680852c15SAndreas Gohr// vim:ts=4:sw=4:et: