PageRenderTime 23ms CodeModel.GetById 11ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/Facebook/FacebookSessionPersistence.php

http://github.com/FriendsOfSymfony/FOSFacebookBundle
PHP | 199 lines | 121 code | 30 blank | 48 comment | 12 complexity | 06e932406dd06efad4b03631587c1fda MD5 | raw file
  1<?php
  2
  3namespace FOS\FacebookBundle\Facebook;
  4
  5use Symfony\Component\HttpFoundation\Session\Session;
  6use Symfony\Component\HttpFoundation\Request;
  7
  8/**
  9 * Implements Symfony2 session persistence for Facebook.
 10 *
 11 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 12 */
 13class FacebookSessionPersistence extends \BaseFacebook
 14{
 15    const PREFIX = '_fos_facebook_';
 16
 17    protected $session;
 18    protected $prefix;
 19    protected static $kSupportedKeys = array('state', 'code', 'access_token', 'user_id');
 20
 21    /**
 22     * @param array   $config
 23     * @param Session $session
 24     * @param string  $prefix
 25     */
 26    public function __construct($config, Session $session, $prefix = self::PREFIX)
 27    {
 28        $this->session = $session;
 29        $this->prefix  = $prefix;
 30
 31        $this->setAppId($config['appId']);
 32        $this->setAppSecret($config['secret']);
 33        if (isset($config['fileUpload'])) {
 34            $this->setFileUploadSupport($config['fileUpload']);
 35        }
 36        // Add trustProxy configuration
 37        $this->trustForwarded = isset($config['trustForwarded']) ? $config['trustForwarded'] : Request::getTrustedProxies();
 38    }
 39
 40    /**
 41     * @param  array  $params
 42     * @return string
 43     */
 44    public function getLoginUrl($params = array())
 45    {
 46        $this->establishCSRFTokenState();
 47        $currentUrl = $this->getCurrentUrl();
 48
 49        // if 'scope' is passed as an array, convert to comma separated list
 50        $scopeParams = isset($params['scope']) ? $params['scope'] : null;
 51        if ($scopeParams && is_array($scopeParams)) {
 52            $params['scope'] = implode(',', $scopeParams);
 53        }
 54
 55        return $this->getUrl(
 56            'www',
 57            'dialog/oauth',
 58            array_merge(
 59                array(
 60                    'client_id' => $this->getAppId(),
 61                    'redirect_uri' => $currentUrl, // possibly overwritten
 62                    'state' => $this->getState(),
 63                ),
 64                $params
 65            )
 66        );
 67    }
 68
 69    /**
 70     * @return bool|mixed
 71     */
 72    protected function getCode()
 73    {
 74        if (isset($_REQUEST['code'])) {
 75            if ($this->getState() !== null &&
 76                isset($_REQUEST['state']) &&
 77                $this->getState() === $_REQUEST['state']) {
 78
 79                    // CSRF state has done its job, so clear it
 80                    $this->setState(null);
 81                    $this->clearPersistentData('state');
 82
 83                    return $_REQUEST['code'];
 84            } else {
 85                self::errorLog('CSRF state token does not match one provided.');
 86
 87                return false;
 88            }
 89        }
 90
 91        return false;
 92    }
 93
 94    protected function establishCSRFTokenState()
 95    {
 96        if ($this->getState() === null) {
 97            $this->setState(md5(uniqid(mt_rand(), true)));
 98        }
 99    }
100
101    /**
102     * Stores the given ($key, $value) pair, so that future calls to
103     * getPersistentData($key) return $value. This call may be in another request.
104     *
105     * @param string $key
106     * @param array  $value
107     *
108     * @return void
109     */
110    protected function setPersistentData($key, $value)
111    {
112        if (!in_array($key, self::$kSupportedKeys)) {
113            self::errorLog('Unsupported key passed to setPersistentData.');
114
115            return;
116        }
117
118        $this->session->set($this->constructSessionVariableName($key), $value);
119    }
120
121    /**
122     * Get the data for $key, persisted by BaseFacebook::setPersistentData()
123     *
124     * @param string  $key     The key of the data to retrieve
125     * @param boolean $default The default value to return if $key is not found
126     *
127     * @return mixed
128     */
129    protected function getPersistentData($key, $default = false)
130    {
131        if (!in_array($key, self::$kSupportedKeys)) {
132            self::errorLog('Unsupported key passed to getPersistentData.');
133
134            return $default;
135        }
136
137        $sessionVariableName = $this->constructSessionVariableName($key);
138        if ($this->session->has($sessionVariableName)) {
139            return $this->session->get($sessionVariableName);
140        }
141
142        return $default;
143    }
144
145    /**
146     * Clear the data with $key from the persistent storage
147     *
148     * @param  string $key
149     * @return void
150     */
151    protected function clearPersistentData($key)
152    {
153        if (!in_array($key, self::$kSupportedKeys)) {
154            self::errorLog('Unsupported key passed to clearPersistentData.');
155
156            return;
157        }
158
159        $this->session->remove($this->constructSessionVariableName($key));
160    }
161
162    /**
163     * Clear all data from the persistent storage
164     *
165     * @return void
166     */
167    protected function clearAllPersistentData()
168    {
169        foreach ($this->session->all() as $k => $v) {
170            if (0 !== strpos($k, $this->prefix)) {
171                continue;
172            }
173
174            $this->session->remove($k);
175        }
176    }
177
178    protected function constructSessionVariableName($key)
179    {
180        return $this->prefix.implode(
181            '_',
182            array(
183                'fb',
184                $this->getAppId(),
185                $key,
186            )
187        );
188    }
189
190    private function getState()
191    {
192        return $this->getPersistentData('state', null);
193    }
194
195    private function setState($state)
196    {
197        $this->setPersistentData('state', $state);
198    }
199}