1 | <?php |
---|
2 | /*! |
---|
3 | * HybridAuth |
---|
4 | * http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth |
---|
5 | * (c) 2009-2012, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html |
---|
6 | */ |
---|
7 | |
---|
8 | /** |
---|
9 | * Hybrid_Provider_Adapter is the basic class which Hybrid_Auth will use |
---|
10 | * to connect users to a given provider. |
---|
11 | * |
---|
12 | * Basically Hybrid_Provider_Adapterwill create a bridge from your php |
---|
13 | * application to the provider api. |
---|
14 | * |
---|
15 | * Hybrid_Auth will automatically load Hybrid_Provider_Adapter and create |
---|
16 | * an instance of it for each authenticated provider. |
---|
17 | */ |
---|
18 | class Hybrid_Provider_Adapter |
---|
19 | { |
---|
20 | /* Provider ID (or unique name) */ |
---|
21 | public $id = NULL ; |
---|
22 | |
---|
23 | /* Provider adapter specific config */ |
---|
24 | public $config = NULL ; |
---|
25 | |
---|
26 | /* Provider adapter extra parameters */ |
---|
27 | public $params = NULL ; |
---|
28 | |
---|
29 | /* Provider adapter wrapper path */ |
---|
30 | public $wrapper = NULL ; |
---|
31 | |
---|
32 | /* Provider adapter instance */ |
---|
33 | public $adapter = NULL ; |
---|
34 | |
---|
35 | // -------------------------------------------------------------------- |
---|
36 | |
---|
37 | /** |
---|
38 | * create a new adapter switch IDp name or ID |
---|
39 | * |
---|
40 | * @param string $id The id or name of the IDp |
---|
41 | * @param array $params (optional) required parameters by the adapter |
---|
42 | */ |
---|
43 | function factory( $id, $params = NULL ) |
---|
44 | { |
---|
45 | Hybrid_Logger::info( "Enter Hybrid_Provider_Adapter::factory( $id )" ); |
---|
46 | |
---|
47 | # init the adapter config and params |
---|
48 | $this->id = $id; |
---|
49 | $this->params = $params; |
---|
50 | $this->id = $this->getProviderCiId( $this->id ); |
---|
51 | $this->config = $this->getConfigById( $this->id ); |
---|
52 | |
---|
53 | # check the IDp id |
---|
54 | if( ! $this->id ){ |
---|
55 | throw new Exception( "No provider ID specified.", 2 ); |
---|
56 | } |
---|
57 | |
---|
58 | # check the IDp config |
---|
59 | if( ! $this->config ){ |
---|
60 | throw new Exception( "Unknown Provider ID, check your configuration file.", 3 ); |
---|
61 | } |
---|
62 | |
---|
63 | # check the IDp adapter is enabled |
---|
64 | if( ! $this->config["enabled"] ){ |
---|
65 | throw new Exception( "The provider '{$this->id}' is not enabled.", 3 ); |
---|
66 | } |
---|
67 | |
---|
68 | # include the adapter wrapper |
---|
69 | if( isset( $this->config["wrapper"] ) && is_array( $this->config["wrapper"] ) ){ |
---|
70 | require_once $this->config["wrapper"]["path"]; |
---|
71 | |
---|
72 | if( ! class_exists( $this->config["wrapper"]["class"] ) ){ |
---|
73 | throw new Exception( "Unable to load the adapter class.", 3 ); |
---|
74 | } |
---|
75 | |
---|
76 | $this->wrapper = $this->config["wrapper"]["class"]; |
---|
77 | } |
---|
78 | else{ |
---|
79 | require_once Hybrid_Auth::$config["path_providers"] . $this->id . ".php" ; |
---|
80 | |
---|
81 | $this->wrapper = "Hybrid_Providers_" . $this->id; |
---|
82 | } |
---|
83 | |
---|
84 | # create the adapter instance, and pass the current params and config |
---|
85 | $this->adapter = new $this->wrapper( $this->id, $this->config, $this->params ); |
---|
86 | |
---|
87 | return $this; |
---|
88 | } |
---|
89 | |
---|
90 | // -------------------------------------------------------------------- |
---|
91 | |
---|
92 | /** |
---|
93 | * Hybrid_Provider_Adapter::login(), prepare the user session and the authentication request |
---|
94 | * for index.php |
---|
95 | */ |
---|
96 | function login() |
---|
97 | { |
---|
98 | Hybrid_Logger::info( "Enter Hybrid_Provider_Adapter::login( {$this->id} ) " ); |
---|
99 | |
---|
100 | if( ! $this->adapter ){ |
---|
101 | throw new Exception( "Hybrid_Provider_Adapter::login() should not directly used." ); |
---|
102 | } |
---|
103 | |
---|
104 | // clear all unneeded params |
---|
105 | foreach( Hybrid_Auth::$config["providers"] as $idpid => $params ){ |
---|
106 | Hybrid_Auth::storage()->delete( "hauth_session.{$idpid}.hauth_return_to" ); |
---|
107 | Hybrid_Auth::storage()->delete( "hauth_session.{$idpid}.hauth_endpoint" ); |
---|
108 | Hybrid_Auth::storage()->delete( "hauth_session.{$idpid}.id_provider_params" ); |
---|
109 | } |
---|
110 | |
---|
111 | // make a fresh start |
---|
112 | $this->logout(); |
---|
113 | |
---|
114 | # get hybridauth base url |
---|
115 | $HYBRID_AUTH_URL_BASE = Hybrid_Auth::$config["base_url"]; |
---|
116 | |
---|
117 | # we make use of session_id() as storage hash to identify the current user |
---|
118 | # using session_regenerate_id() will be a problem, but .. |
---|
119 | $this->params["hauth_token"] = session_id(); |
---|
120 | |
---|
121 | # set request timestamp |
---|
122 | $this->params["hauth_time"] = time(); |
---|
123 | |
---|
124 | # for default HybridAuth endpoint url hauth_login_start_url |
---|
125 | # auth.start required the IDp ID |
---|
126 | # auth.time optional login request timestamp |
---|
127 | $this->params["login_start"] = $HYBRID_AUTH_URL_BASE . ( strpos( $HYBRID_AUTH_URL_BASE, '?' ) ? '&' : '?' ) . "hauth.start={$this->id}&hauth.time={$this->params["hauth_time"]}"; |
---|
128 | |
---|
129 | # for default HybridAuth endpoint url hauth_login_done_url |
---|
130 | # auth.done required the IDp ID |
---|
131 | $this->params["login_done"] = $HYBRID_AUTH_URL_BASE . ( strpos( $HYBRID_AUTH_URL_BASE, '?' ) ? '&' : '?' ) . "hauth.done={$this->id}"; |
---|
132 | |
---|
133 | Hybrid_Auth::storage()->set( "hauth_session.{$this->id}.hauth_return_to" , $this->params["hauth_return_to"] ); |
---|
134 | Hybrid_Auth::storage()->set( "hauth_session.{$this->id}.hauth_endpoint" , $this->params["login_done"] ); |
---|
135 | Hybrid_Auth::storage()->set( "hauth_session.{$this->id}.id_provider_params" , $this->params ); |
---|
136 | |
---|
137 | // store config to be used by the end point |
---|
138 | Hybrid_Auth::storage()->config( "CONFIG", Hybrid_Auth::$config ); |
---|
139 | |
---|
140 | // move on |
---|
141 | Hybrid_Logger::debug( "Hybrid_Provider_Adapter::login( {$this->id} ), redirect the user to login_start URL." ); |
---|
142 | |
---|
143 | Hybrid_Auth::redirect( $this->params["login_start"] ); |
---|
144 | } |
---|
145 | |
---|
146 | // -------------------------------------------------------------------- |
---|
147 | |
---|
148 | /** |
---|
149 | * let hybridauth forget all about the user for the current provider |
---|
150 | */ |
---|
151 | function logout() |
---|
152 | { |
---|
153 | $this->adapter->logout(); |
---|
154 | } |
---|
155 | |
---|
156 | // -------------------------------------------------------------------- |
---|
157 | |
---|
158 | /** |
---|
159 | * return true if the user is connected to the current provider |
---|
160 | */ |
---|
161 | public function isUserConnected() |
---|
162 | { |
---|
163 | return $this->adapter->isUserConnected(); |
---|
164 | } |
---|
165 | |
---|
166 | // -------------------------------------------------------------------- |
---|
167 | |
---|
168 | /** |
---|
169 | * handle : |
---|
170 | * getUserProfile() |
---|
171 | * getUserContacts() |
---|
172 | * getUserActivity() |
---|
173 | * setUserStatus() |
---|
174 | */ |
---|
175 | public function __call( $name, $arguments ) |
---|
176 | { |
---|
177 | Hybrid_Logger::info( "Enter Hybrid_Provider_Adapter::$name(), Provider: {$this->id}" ); |
---|
178 | |
---|
179 | if ( ! $this->isUserConnected() ){ |
---|
180 | throw new Exception( "User not connected to the provider {$this->id}.", 7 ); |
---|
181 | } |
---|
182 | |
---|
183 | if ( ! method_exists( $this->adapter, $name ) ){ |
---|
184 | throw new Exception( "Call to undefined function Hybrid_Providers_{$this->id}::$name()." ); |
---|
185 | } |
---|
186 | |
---|
187 | if( count( $arguments ) ){ |
---|
188 | return $this->adapter->$name( $arguments[0] ); |
---|
189 | } |
---|
190 | else{ |
---|
191 | return $this->adapter->$name(); |
---|
192 | } |
---|
193 | } |
---|
194 | |
---|
195 | // -------------------------------------------------------------------- |
---|
196 | |
---|
197 | /** |
---|
198 | * If the user is connected, then return the access_token and access_token_secret |
---|
199 | * if the provider api use oauth |
---|
200 | */ |
---|
201 | public function getAccessToken() |
---|
202 | { |
---|
203 | if( ! $this->adapter->isUserConnected() ){ |
---|
204 | Hybrid_Logger::error( "User not connected to the provider." ); |
---|
205 | |
---|
206 | throw new Exception( "User not connected to the provider.", 7 ); |
---|
207 | } |
---|
208 | |
---|
209 | return |
---|
210 | ARRAY( |
---|
211 | "access_token" => $this->adapter->token( "access_token" ) , // OAuth access token |
---|
212 | "access_token_secret" => $this->adapter->token( "access_token_secret" ), // OAuth access token secret |
---|
213 | "refresh_token" => $this->adapter->token( "refresh_token" ) , // OAuth refresh token |
---|
214 | "expires_in" => $this->adapter->token( "expires_in" ) , // OPTIONAL. The duration in seconds of the access token lifetime |
---|
215 | "expires_at" => $this->adapter->token( "expires_at" ) , // OPTIONAL. Timestamp when the access_token expire. if not provided by the social api, then it should be calculated: expires_at = now + expires_in |
---|
216 | ); |
---|
217 | } |
---|
218 | |
---|
219 | // -------------------------------------------------------------------- |
---|
220 | |
---|
221 | /** |
---|
222 | * Naive getter of the current connected IDp API client |
---|
223 | */ |
---|
224 | function api() |
---|
225 | { |
---|
226 | if( ! $this->adapter->isUserConnected() ){ |
---|
227 | Hybrid_Logger::error( "User not connected to the provider." ); |
---|
228 | |
---|
229 | throw new Exception( "User not connected to the provider.", 7 ); |
---|
230 | } |
---|
231 | |
---|
232 | return $this->adapter->api; |
---|
233 | } |
---|
234 | |
---|
235 | // -------------------------------------------------------------------- |
---|
236 | |
---|
237 | /** |
---|
238 | * redirect the user to hauth_return_to (the callback url) |
---|
239 | */ |
---|
240 | function returnToCallbackUrl() |
---|
241 | { |
---|
242 | // get the stored callback url |
---|
243 | $callback_url = Hybrid_Auth::storage()->get( "hauth_session.{$this->id}.hauth_return_to" ); |
---|
244 | |
---|
245 | // remove some unneed'd stored data |
---|
246 | Hybrid_Auth::storage()->delete( "hauth_session.{$this->id}.hauth_return_to" ); |
---|
247 | Hybrid_Auth::storage()->delete( "hauth_session.{$this->id}.hauth_endpoint" ); |
---|
248 | Hybrid_Auth::storage()->delete( "hauth_session.{$this->id}.id_provider_params" ); |
---|
249 | |
---|
250 | // back to home |
---|
251 | Hybrid_Auth::redirect( $callback_url ); |
---|
252 | } |
---|
253 | |
---|
254 | // -------------------------------------------------------------------- |
---|
255 | |
---|
256 | /** |
---|
257 | * return the provider config by id |
---|
258 | */ |
---|
259 | function getConfigById( $id ) |
---|
260 | { |
---|
261 | if( isset( Hybrid_Auth::$config["providers"][$id] ) ){ |
---|
262 | return Hybrid_Auth::$config["providers"][$id]; |
---|
263 | } |
---|
264 | |
---|
265 | return NULL; |
---|
266 | } |
---|
267 | |
---|
268 | // -------------------------------------------------------------------- |
---|
269 | |
---|
270 | /** |
---|
271 | * return the provider config by id; insensitive |
---|
272 | */ |
---|
273 | function getProviderCiId( $id ) |
---|
274 | { |
---|
275 | foreach( Hybrid_Auth::$config["providers"] as $idpid => $params ){ |
---|
276 | if( strtolower( $idpid ) == strtolower( $id ) ){ |
---|
277 | return $idpid; |
---|
278 | } |
---|
279 | } |
---|
280 | |
---|
281 | return NULL; |
---|
282 | } |
---|
283 | } |
---|