xref: /plugin/oauth/Session.php (revision 74b4d4a4cf1d79813740d8ba18696e5fb2b4089b)
1*74b4d4a4SAndreas Gohr<?php
2*74b4d4a4SAndreas Gohr
3*74b4d4a4SAndreas Gohrnamespace dokuwiki\plugin\oauth;
4*74b4d4a4SAndreas Gohr
5*74b4d4a4SAndreas Gohr/**
6*74b4d4a4SAndreas Gohr * Singleton to manage all oAuth related session and cookie data
7*74b4d4a4SAndreas Gohr */
8*74b4d4a4SAndreas Gohrclass Session
9*74b4d4a4SAndreas Gohr{
10*74b4d4a4SAndreas Gohr    /** @var Session */
11*74b4d4a4SAndreas Gohr    protected static $instance = null;
12*74b4d4a4SAndreas Gohr
13*74b4d4a4SAndreas Gohr    /**
14*74b4d4a4SAndreas Gohr     * hidden constructor
15*74b4d4a4SAndreas Gohr     */
16*74b4d4a4SAndreas Gohr    protected function __construct()
17*74b4d4a4SAndreas Gohr    {
18*74b4d4a4SAndreas Gohr    }
19*74b4d4a4SAndreas Gohr
20*74b4d4a4SAndreas Gohr    /**
21*74b4d4a4SAndreas Gohr     * Get Singleton Instance
22*74b4d4a4SAndreas Gohr     *
23*74b4d4a4SAndreas Gohr     * @return Session
24*74b4d4a4SAndreas Gohr     */
25*74b4d4a4SAndreas Gohr    public static function getInstance()
26*74b4d4a4SAndreas Gohr    {
27*74b4d4a4SAndreas Gohr        if (self::$instance === null) {
28*74b4d4a4SAndreas Gohr            self::$instance = new Session();
29*74b4d4a4SAndreas Gohr        }
30*74b4d4a4SAndreas Gohr        return self::$instance;
31*74b4d4a4SAndreas Gohr    }
32*74b4d4a4SAndreas Gohr
33*74b4d4a4SAndreas Gohr    /**
34*74b4d4a4SAndreas Gohr     * Set a service and guid for a login in progress
35*74b4d4a4SAndreas Gohr     *
36*74b4d4a4SAndreas Gohr     * @param string $servicename
37*74b4d4a4SAndreas Gohr     * @param string $guid
38*74b4d4a4SAndreas Gohr     * @return void
39*74b4d4a4SAndreas Gohr     */
40*74b4d4a4SAndreas Gohr    public function setLoginData($servicename, $guid)
41*74b4d4a4SAndreas Gohr    {
42*74b4d4a4SAndreas Gohr        $_SESSION[DOKU_COOKIE]['auth']['oauth']['service'] = $servicename;
43*74b4d4a4SAndreas Gohr        $_SESSION[DOKU_COOKIE]['auth']['oauth']['guid'] = $guid;
44*74b4d4a4SAndreas Gohr    }
45*74b4d4a4SAndreas Gohr
46*74b4d4a4SAndreas Gohr    /**
47*74b4d4a4SAndreas Gohr     * Get currently used login service
48*74b4d4a4SAndreas Gohr     *
49*74b4d4a4SAndreas Gohr     * @return false|array Either [servicename=>*,guid=>*] or false
50*74b4d4a4SAndreas Gohr     */
51*74b4d4a4SAndreas Gohr    public function getLoginData()
52*74b4d4a4SAndreas Gohr    {
53*74b4d4a4SAndreas Gohr        if (
54*74b4d4a4SAndreas Gohr            isset($_SESSION[DOKU_COOKIE]['auth']['oauth']['service']) and
55*74b4d4a4SAndreas Gohr            isset($_SESSION[DOKU_COOKIE]['auth']['oauth']['guid'])
56*74b4d4a4SAndreas Gohr
57*74b4d4a4SAndreas Gohr        ) {
58*74b4d4a4SAndreas Gohr            return [
59*74b4d4a4SAndreas Gohr                'servicename' => $_SESSION[DOKU_COOKIE]['auth']['oauth']['service'],
60*74b4d4a4SAndreas Gohr                'guid' => $_SESSION[DOKU_COOKIE]['auth']['oauth']['guid'],
61*74b4d4a4SAndreas Gohr            ];
62*74b4d4a4SAndreas Gohr        }
63*74b4d4a4SAndreas Gohr        return false;
64*74b4d4a4SAndreas Gohr    }
65*74b4d4a4SAndreas Gohr
66*74b4d4a4SAndreas Gohr    /**
67*74b4d4a4SAndreas Gohr     * Remove login service from session
68*74b4d4a4SAndreas Gohr     * @return void
69*74b4d4a4SAndreas Gohr     */
70*74b4d4a4SAndreas Gohr    public function clearLoginData()
71*74b4d4a4SAndreas Gohr    {
72*74b4d4a4SAndreas Gohr        if (isset($_SESSION[DOKU_COOKIE]['auth']['oauth']['service'])) {
73*74b4d4a4SAndreas Gohr            unset($_SESSION[DOKU_COOKIE]['auth']['oauth']['service']);
74*74b4d4a4SAndreas Gohr        }
75*74b4d4a4SAndreas Gohr        if (isset($_SESSION[DOKU_COOKIE]['auth']['oauth']['guid'])) {
76*74b4d4a4SAndreas Gohr            unset($_SESSION[DOKU_COOKIE]['auth']['oauth']['guid']);
77*74b4d4a4SAndreas Gohr        }
78*74b4d4a4SAndreas Gohr    }
79*74b4d4a4SAndreas Gohr
80*74b4d4a4SAndreas Gohr    /**
81*74b4d4a4SAndreas Gohr     * This basically duplicates what DokuWiki does when a user is logged in
82*74b4d4a4SAndreas Gohr     *
83*74b4d4a4SAndreas Gohr     * @param array $userdata
84*74b4d4a4SAndreas Gohr     * @param bool $resettime Set a new session time? False only when restoring from session
85*74b4d4a4SAndreas Gohr     * @return void
86*74b4d4a4SAndreas Gohr     * @throws Exception
87*74b4d4a4SAndreas Gohr     */
88*74b4d4a4SAndreas Gohr    public function setUser($userdata, $resettime = true)
89*74b4d4a4SAndreas Gohr    {
90*74b4d4a4SAndreas Gohr        global $USERINFO;
91*74b4d4a4SAndreas Gohr
92*74b4d4a4SAndreas Gohr        if (
93*74b4d4a4SAndreas Gohr            !isset($userdata['user']) or
94*74b4d4a4SAndreas Gohr            !isset($userdata['name']) or
95*74b4d4a4SAndreas Gohr            !isset($userdata['mail']) or
96*74b4d4a4SAndreas Gohr            !isset($userdata['grps']) or
97*74b4d4a4SAndreas Gohr            !is_array($userdata['grps'])
98*74b4d4a4SAndreas Gohr        ) {
99*74b4d4a4SAndreas Gohr            throw new Exception('Missing user data, cannot save to session');
100*74b4d4a4SAndreas Gohr        }
101*74b4d4a4SAndreas Gohr
102*74b4d4a4SAndreas Gohr        $USERINFO = $userdata;
103*74b4d4a4SAndreas Gohr        $_SERVER['REMOTE_USER'] = $userdata['user'];
104*74b4d4a4SAndreas Gohr
105*74b4d4a4SAndreas Gohr        $_SESSION[DOKU_COOKIE]['auth']['user'] = $userdata['user'];
106*74b4d4a4SAndreas Gohr        $_SESSION[DOKU_COOKIE]['auth']['pass'] = $userdata['pass'];
107*74b4d4a4SAndreas Gohr        $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
108*74b4d4a4SAndreas Gohr        $_SESSION[DOKU_COOKIE]['auth']['buid'] = auth_browseruid();
109*74b4d4a4SAndreas Gohr        if ($resettime) {
110*74b4d4a4SAndreas Gohr            $_SESSION[DOKU_COOKIE]['auth']['time'] = time();
111*74b4d4a4SAndreas Gohr        }
112*74b4d4a4SAndreas Gohr    }
113*74b4d4a4SAndreas Gohr
114*74b4d4a4SAndreas Gohr    /**
115*74b4d4a4SAndreas Gohr     * The user data currently saved in the session if any
116*74b4d4a4SAndreas Gohr     *
117*74b4d4a4SAndreas Gohr     * @return false|array
118*74b4d4a4SAndreas Gohr     */
119*74b4d4a4SAndreas Gohr    public function getUser()
120*74b4d4a4SAndreas Gohr    {
121*74b4d4a4SAndreas Gohr        if (isset($_SESSION[DOKU_COOKIE]['auth']['info'])) {
122*74b4d4a4SAndreas Gohr            return $_SESSION[DOKU_COOKIE]['auth']['info'];
123*74b4d4a4SAndreas Gohr        }
124*74b4d4a4SAndreas Gohr        return false;
125*74b4d4a4SAndreas Gohr    }
126*74b4d4a4SAndreas Gohr
127*74b4d4a4SAndreas Gohr    /**
128*74b4d4a4SAndreas Gohr     * Set oAuth info to cookie
129*74b4d4a4SAndreas Gohr     *
130*74b4d4a4SAndreas Gohr     * We use the same cookie as standard DokuWiki, but write different info.
131*74b4d4a4SAndreas Gohr     *
132*74b4d4a4SAndreas Gohr     * @param string $servicename
133*74b4d4a4SAndreas Gohr     * @param string $guid
134*74b4d4a4SAndreas Gohr     * @return void
135*74b4d4a4SAndreas Gohr     */
136*74b4d4a4SAndreas Gohr    public function setCookie($servicename, $guid)
137*74b4d4a4SAndreas Gohr    {
138*74b4d4a4SAndreas Gohr        global $conf;
139*74b4d4a4SAndreas Gohr        $validityPeriodInSeconds = 60 * 60 * 24 * 365;
140*74b4d4a4SAndreas Gohr        $cookie = "$servicename|oauth|$guid";
141*74b4d4a4SAndreas Gohr        $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'];
142*74b4d4a4SAndreas Gohr        $time = time() + $validityPeriodInSeconds;
143*74b4d4a4SAndreas Gohr        setcookie(DOKU_COOKIE, $cookie, $time, $cookieDir, '', ($conf['securecookie'] && is_ssl()), true);
144*74b4d4a4SAndreas Gohr    }
145*74b4d4a4SAndreas Gohr
146*74b4d4a4SAndreas Gohr    /**
147*74b4d4a4SAndreas Gohr     * Get oAuth info from cookie
148*74b4d4a4SAndreas Gohr     *
149*74b4d4a4SAndreas Gohr     * @return array|false Either [servicename=>?, guid=>?] or false if no oauth data in cookie
150*74b4d4a4SAndreas Gohr     */
151*74b4d4a4SAndreas Gohr    public function getCookie()
152*74b4d4a4SAndreas Gohr    {
153*74b4d4a4SAndreas Gohr        if (!isset($_COOKIE[DOKU_COOKIE])) return false;
154*74b4d4a4SAndreas Gohr        list($servicename, $oauth, $guid) = explode('|', $_COOKIE[DOKU_COOKIE]);
155*74b4d4a4SAndreas Gohr        if ($oauth !== 'oauth') return false;
156*74b4d4a4SAndreas Gohr        return ['servicename' => $servicename, 'guid' => $guid];
157*74b4d4a4SAndreas Gohr    }
158*74b4d4a4SAndreas Gohr
159*74b4d4a4SAndreas Gohr    /**
160*74b4d4a4SAndreas Gohr     * Is any auth data in the session currently trustworthy?
161*74b4d4a4SAndreas Gohr     * @return bool
162*74b4d4a4SAndreas Gohr     */
163*74b4d4a4SAndreas Gohr    public function isValid()
164*74b4d4a4SAndreas Gohr    {
165*74b4d4a4SAndreas Gohr        global $conf;
166*74b4d4a4SAndreas Gohr
167*74b4d4a4SAndreas Gohr        if (!isset($_SESSION[DOKU_COOKIE]['auth']['buid'])) return false;
168*74b4d4a4SAndreas Gohr        if (!isset($_SESSION[DOKU_COOKIE]['auth']['time'])) return false;
169*74b4d4a4SAndreas Gohr        if ($_SESSION[DOKU_COOKIE]['auth']['buid'] != auth_browseruid()) return false;
170*74b4d4a4SAndreas Gohr        if ($_SESSION[DOKU_COOKIE]['auth']['time'] < time() - $conf['auth_security_timeout']) return false;
171*74b4d4a4SAndreas Gohr
172*74b4d4a4SAndreas Gohr        return true;
173*74b4d4a4SAndreas Gohr    }
174*74b4d4a4SAndreas Gohr
175*74b4d4a4SAndreas Gohr    /**
176*74b4d4a4SAndreas Gohr     * Clear the session from auth related data
177*74b4d4a4SAndreas Gohr     * @return void
178*74b4d4a4SAndreas Gohr     */
179*74b4d4a4SAndreas Gohr    public function clear()
180*74b4d4a4SAndreas Gohr    {
181*74b4d4a4SAndreas Gohr        $this->clearLoginData();
182*74b4d4a4SAndreas Gohr        auth_logoff();
183*74b4d4a4SAndreas Gohr    }
184*74b4d4a4SAndreas Gohr}
185