]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - actions/twitterauthorization.php
Merge branch 'twitter-oauth' into 0.8.x
[quix0rs-gnu-social.git] / actions / twitterauthorization.php
1 <?php
2 /**
3  * Laconica, the distributed open-source microblogging tool
4  *
5  * Class for doing OAuth authentication against Twitter
6  *
7  * PHP version 5
8  *
9  * LICENCE: This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU Affero General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Affero General Public License for more details.
18  *
19  * You should have received a copy of the GNU Affero General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  * @category  Twitter
23  * @package   Laconica
24  * @author    Zach Copely <zach@controlyourself.ca>
25  * @copyright 2009 Control Yourself, Inc.
26  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
27  * @link      http://laconi.ca/
28  */
29
30 if (!defined('LACONICA')) {
31     exit(1);
32 }
33
34 /**
35  * Class for doing OAuth authentication against Twitter
36  *
37  * Peforms the OAuth "dance" between Laconica and Twitter -- requests a token,
38  * authorizes it, and exchanges it for an access token.  It also creates a link
39  * (Foreign_link) between the Laconica user and Twitter user and stores the
40  * access token and secret in the link.
41  *
42  * @category Twitter
43  * @package  Laconica
44  * @author   Zach Copley <zach@controlyourself.ca>
45  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
46  * @link     http://laconi.ca/
47  *
48  */
49 class TwitterauthorizationAction extends Action
50 {
51     /**
52      * Initialize class members. Looks for 'oauth_token' parameter.
53      *
54      * @param array $args misc. arguments
55      *
56      * @return boolean true
57      */
58     function prepare($args)
59     {
60         parent::prepare($args);
61
62         $this->oauth_token = $this->arg('oauth_token');
63
64         return true;
65     }
66
67     /**
68      * Handler method
69      *
70      * @param array $args is ignored since it's now passed in in prepare()
71      *
72      * @return nothing
73      */
74     function handle($args)
75     {
76         parent::handle($args);
77
78         if (!common_logged_in()) {
79             $this->clientError(_('Not logged in.'), 403);
80         }
81
82         $user  = common_current_user();
83         $flink = Foreign_link::getByUserID($user->id, TWITTER_SERVICE);
84
85         // If there's already a foreign link record, it means we already
86         // have an access token, and this is unecessary. So go back.
87
88         if (isset($flink)) {
89             common_redirect(common_local_url('twittersettings'));
90         }
91
92         // $this->oauth_token is only populated once Twitter authorizes our
93         // request token. If it's empty we're at the beginning of the auth
94         // process
95
96         if (empty($this->oauth_token)) {
97             $this->authorizeRequestToken();
98         } else {
99             $this->saveAccessToken();
100         }
101     }
102
103     /**
104      * Asks Twitter for a request token, and then redirects to Twitter
105      * to authorize it.
106      *
107      * @return nothing
108      */
109     function authorizeRequestToken()
110     {
111         try {
112
113             // Get a new request token and authorize it
114
115             $client  = new TwitterOAuthClient();
116             $req_tok =
117               $client->getRequestToken(TwitterOAuthClient::$requestTokenURL);
118
119             // Sock the request token away in the session temporarily
120
121             $_SESSION['twitter_request_token']        = $req_tok->key;
122             $_SESSION['twitter_request_token_secret'] = $req_tok->secret;
123
124             $auth_link = $client->getAuthorizeLink($req_tok);
125
126         } catch (TwitterOAuthClientException $e) {
127             $msg = sprintf('OAuth client cURL error - code: %1s, msg: %2s',
128                            $e->getCode(), $e->getMessage());
129             $this->serverError(_('Couldn\'t link your Twitter account.'));
130         }
131
132         common_redirect($auth_link);
133     }
134
135     /**
136      * Called when Twitter returns an authorized request token. Exchanges
137      * it for an access token and stores it.
138      *
139      * @return nothing
140      */
141     function saveAccessToken()
142     {
143
144         // Check to make sure Twitter returned the same request
145         // token we sent them
146
147         if ($_SESSION['twitter_request_token'] != $this->oauth_token) {
148             $this->serverError(_('Couldn\'t link your Twitter account.'));
149         }
150
151         try {
152
153             $client = new TwitterOAuthClient($_SESSION['twitter_request_token'],
154                 $_SESSION['twitter_request_token_secret']);
155
156             // Exchange the request token for an access token
157
158             $atok = $client->getAccessToken(TwitterOAuthClient::$accessTokenURL);
159
160             // Test the access token and get the user's Twitter info
161
162             $client       = new TwitterOAuthClient($atok->key, $atok->secret);
163             $twitter_user = $client->verifyCredentials();
164
165         } catch (OAuthClientException $e) {
166             $msg = sprintf('OAuth client cURL error - code: %1$s, msg: %2$s',
167                            $e->getCode(), $e->getMessage());
168             $this->serverError(_('Couldn\'t link your Twitter account.'));
169         }
170
171         // Save the access token and Twitter user info
172
173         $this->saveForeignLink($atok, $twitter_user);
174
175         // Clean up the the mess we made in the session
176
177         unset($_SESSION['twitter_request_token']);
178         unset($_SESSION['twitter_request_token_secret']);
179
180         common_redirect(common_local_url('twittersettings'));
181     }
182
183     /**
184      * Saves a Foreign_link between Twitter user and local user,
185      * which includes the access token and secret.
186      *
187      * @param OAuthToken $access_token the access token to save
188      * @param mixed      $twitter_user twitter API user object
189      *
190      * @return nothing
191      */
192     function saveForeignLink($access_token, $twitter_user)
193     {
194         $user = common_current_user();
195
196         $flink = new Foreign_link();
197
198         $flink->user_id     = $user->id;
199         $flink->foreign_id  = $twitter_user->id;
200         $flink->service     = TWITTER_SERVICE;
201
202         $creds = TwitterOAuthClient::packToken($access_token);
203
204         $flink->credentials = $creds;
205         $flink->created     = common_sql_now();
206
207         // Defaults: noticesync on, everything else off
208
209         $flink->set_flags(true, false, false, false);
210
211         $flink_id = $flink->insert();
212
213         if (empty($flink_id)) {
214             common_log_db_error($flink, 'INSERT', __FILE__);
215                 $this->serverError(_('Couldn\'t link your Twitter account.'));
216         }
217
218         save_twitter_user($twitter_user->id, $twitter_user->screen_name);
219     }
220
221 }
222