xref: /plugin/oauth/Session.php (revision a9ed389088d3d78c0f9ad1f5315d8707f36b61b7)
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 the environment needed to verify a login in progress
35     *
36     * @param string $servicename the name of the service used
37     * @param string $guid the GUID assigned to the user
38     * @param string $id pageID to return to after login
39     * @return void
40     */
41    public function setLoginData($servicename, $guid, $id)
42    {
43        $_SESSION[DOKU_COOKIE]['auth']['oauth'] = [
44            'servicename' => $servicename,
45            'guid' => $guid,
46            'id' => $id,
47        ];
48    }
49
50    /**
51     * Get the current login environment
52     *
53     * @return false|array Either [servicename=>*,guid=>*, id=>*] or false
54     */
55    public function getLoginData()
56    {
57        if (isset($_SESSION[DOKU_COOKIE]['auth']['oauth'])) {
58            return $_SESSION[DOKU_COOKIE]['auth']['oauth'];
59        }
60        return false;
61    }
62
63    /**
64     * Clear login environment after login
65     *
66     * @return void
67     */
68    public function clearLoginData()
69    {
70        if (isset($_SESSION[DOKU_COOKIE]['auth']['oauth'])) {
71            unset($_SESSION[DOKU_COOKIE]['auth']['oauth']);
72        }
73    }
74
75    /**
76     * This basically duplicates what DokuWiki does when a user is logged in
77     *
78     * @param array $userdata
79     * @param bool $resettime Set a new session time? False only when restoring from session
80     * @return void
81     * @throws Exception
82     */
83    public function setUser($userdata, $resettime = true)
84    {
85        global $USERINFO;
86
87        if (
88            !isset($userdata['user']) or
89            !isset($userdata['name']) or
90            !isset($userdata['mail']) or
91            !isset($userdata['grps']) or
92            !is_array($userdata['grps'])
93        ) {
94            throw new Exception('Missing user data, cannot save to session');
95        }
96
97        $USERINFO = $userdata;
98        $_SERVER['REMOTE_USER'] = $userdata['user'];
99
100        $_SESSION[DOKU_COOKIE]['auth']['user'] = $userdata['user'];
101        $_SESSION[DOKU_COOKIE]['auth']['pass'] = $userdata['pass'];
102        $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
103        $_SESSION[DOKU_COOKIE]['auth']['buid'] = auth_browseruid();
104        if ($resettime) {
105            $_SESSION[DOKU_COOKIE]['auth']['time'] = time();
106        }
107    }
108
109    /**
110     * The user data currently saved in the session if any
111     *
112     * @return false|array
113     */
114    public function getUser()
115    {
116        if (isset($_SESSION[DOKU_COOKIE]['auth']['info'])) {
117            return $_SESSION[DOKU_COOKIE]['auth']['info'];
118        }
119        return false;
120    }
121
122    /**
123     * Set oAuth info to cookie
124     *
125     * We use the same cookie as standard DokuWiki, but write different info.
126     *
127     * @param string $servicename
128     * @param string $guid
129     * @return void
130     */
131    public function setCookie($servicename, $guid)
132    {
133        global $conf;
134        $validityPeriodInSeconds = 60 * 60 * 24 * 365;
135        $cookie = "$servicename|oauth|$guid";
136        $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'];
137        $time = time() + $validityPeriodInSeconds;
138        setcookie(DOKU_COOKIE, $cookie, $time, $cookieDir, '', ($conf['securecookie'] && is_ssl()), true);
139    }
140
141    /**
142     * Get oAuth info from cookie
143     *
144     * @return array|false Either [servicename=>?, guid=>?] or false if no oauth data in cookie
145     */
146    public function getCookie()
147    {
148        if (!isset($_COOKIE[DOKU_COOKIE])) return false;
149        list($servicename, $oauth, $guid) = explode('|', $_COOKIE[DOKU_COOKIE]);
150        if ($oauth !== 'oauth') return false;
151        return ['servicename' => $servicename, 'guid' => $guid];
152    }
153
154    /**
155     * Is any auth data in the session currently trustworthy?
156     * @return bool
157     */
158    public function isValid()
159    {
160        global $conf;
161
162        if (!isset($_SESSION[DOKU_COOKIE]['auth']['buid'])) return false;
163        if (!isset($_SESSION[DOKU_COOKIE]['auth']['time'])) return false;
164        if ($_SESSION[DOKU_COOKIE]['auth']['buid'] != auth_browseruid()) return false;
165        if ($_SESSION[DOKU_COOKIE]['auth']['time'] < time() - $conf['auth_security_timeout']) return false;
166
167        return true;
168    }
169
170    /**
171     * Clear the session from auth related data
172     * @return void
173     */
174    public function clear()
175    {
176        //FIXME clear cookie?
177        $this->clearLoginData();
178
179    }
180}
181