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