1<?php
2
3namespace OAuth\Common\Storage;
4
5use OAuth\Common\Token\TokenInterface;
6use OAuth\Common\Storage\Exception\TokenNotFoundException;
7use OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException;
8
9/**
10 * Stores a token in a PHP session.
11 */
12class Session implements TokenStorageInterface
13{
14    /**
15     * @var bool
16     */
17    protected $startSession;
18
19    /**
20     * @var string
21     */
22    protected $sessionVariableName;
23
24    /**
25     * @var string
26     */
27    protected $stateVariableName;
28
29    /**
30     * @param bool $startSession Whether or not to start the session upon construction.
31     * @param string $sessionVariableName the variable name to use within the _SESSION superglobal
32     * @param string $stateVariableName
33     */
34    public function __construct(
35        $startSession = true,
36        $sessionVariableName = 'lusitanian_oauth_token',
37        $stateVariableName = 'lusitanian_oauth_state'
38    ) {
39        if ($startSession && !isset($_SESSION)) {
40            session_start();
41        }
42
43        $this->startSession = $startSession;
44        $this->sessionVariableName = $sessionVariableName;
45        $this->stateVariableName = $stateVariableName;
46        if (!isset($_SESSION[$sessionVariableName])) {
47            $_SESSION[$sessionVariableName] = array();
48        }
49        if (!isset($_SESSION[$stateVariableName])) {
50            $_SESSION[$stateVariableName] = array();
51        }
52    }
53
54    /**
55     * {@inheritDoc}
56     */
57    public function retrieveAccessToken($service)
58    {
59        if ($this->hasAccessToken($service)) {
60            return unserialize($_SESSION[$this->sessionVariableName][$service]);
61        }
62
63        throw new TokenNotFoundException('Token not found in session, are you sure you stored it?');
64    }
65
66    /**
67     * {@inheritDoc}
68     */
69    public function storeAccessToken($service, TokenInterface $token)
70    {
71        $serializedToken = serialize($token);
72
73        if (isset($_SESSION[$this->sessionVariableName])
74            && is_array($_SESSION[$this->sessionVariableName])
75        ) {
76            $_SESSION[$this->sessionVariableName][$service] = $serializedToken;
77        } else {
78            $_SESSION[$this->sessionVariableName] = array(
79                $service => $serializedToken,
80            );
81        }
82
83        // allow chaining
84        return $this;
85    }
86
87    /**
88     * {@inheritDoc}
89     */
90    public function hasAccessToken($service)
91    {
92        return isset($_SESSION[$this->sessionVariableName], $_SESSION[$this->sessionVariableName][$service]);
93    }
94
95    /**
96     * {@inheritDoc}
97     */
98    public function clearToken($service)
99    {
100        if (array_key_exists($service, $_SESSION[$this->sessionVariableName])) {
101            unset($_SESSION[$this->sessionVariableName][$service]);
102        }
103
104        // allow chaining
105        return $this;
106    }
107
108    /**
109     * {@inheritDoc}
110     */
111    public function clearAllTokens()
112    {
113        unset($_SESSION[$this->sessionVariableName]);
114
115        // allow chaining
116        return $this;
117    }
118
119    /**
120     * {@inheritDoc}
121     */
122    public function storeAuthorizationState($service, $state)
123    {
124        if (isset($_SESSION[$this->stateVariableName])
125            && is_array($_SESSION[$this->stateVariableName])
126        ) {
127            $_SESSION[$this->stateVariableName][$service] = $state;
128        } else {
129            $_SESSION[$this->stateVariableName] = array(
130                $service => $state,
131            );
132        }
133
134        // allow chaining
135        return $this;
136    }
137
138    /**
139     * {@inheritDoc}
140     */
141    public function hasAuthorizationState($service)
142    {
143        return isset($_SESSION[$this->stateVariableName], $_SESSION[$this->stateVariableName][$service]);
144    }
145
146    /**
147     * {@inheritDoc}
148     */
149    public function retrieveAuthorizationState($service)
150    {
151        if ($this->hasAuthorizationState($service)) {
152            return $_SESSION[$this->stateVariableName][$service];
153        }
154
155        throw new AuthorizationStateNotFoundException('State not found in session, are you sure you stored it?');
156    }
157
158    /**
159     * {@inheritDoc}
160     */
161    public function clearAuthorizationState($service)
162    {
163        if (array_key_exists($service, $_SESSION[$this->stateVariableName])) {
164            unset($_SESSION[$this->stateVariableName][$service]);
165        }
166
167        // allow chaining
168        return $this;
169    }
170
171    /**
172     * {@inheritDoc}
173     */
174    public function clearAllAuthorizationStates()
175    {
176        unset($_SESSION[$this->stateVariableName]);
177
178        // allow chaining
179        return $this;
180    }
181
182    public function __destruct()
183    {
184        if ($this->startSession) {
185            session_write_close();
186        }
187    }
188}
189