]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/OStatus/actions/ostatusinit.php
Merge branch '1.0.x' into feedsub-wizard
[quix0rs-gnu-social.git] / plugins / OStatus / actions / ostatusinit.php
1 <?php
2 /*
3  * StatusNet - the distributed open-source microblogging tool
4  * Copyright (C) 2010, StatusNet, Inc.
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 /**
21  * @package OStatusPlugin
22  * @maintainer James Walker <james@status.net>
23  */
24
25 if (!defined('STATUSNET')) {
26     exit(1);
27 }
28
29 class OStatusInitAction extends Action
30 {
31     var $nickname;
32     var $group;
33     var $profile;
34     var $err;
35
36     function prepare($args)
37     {
38         parent::prepare($args);
39
40         if (common_logged_in()) {
41             // TRANS: Client error.
42             $this->clientError(_m('You can use the local subscription!'));
43             return false;
44         }
45
46         // Local user or group the remote wants to subscribe to
47         $this->nickname = $this->trimmed('nickname');
48         $this->group = $this->trimmed('group');
49
50         // Webfinger or profile URL of the remote user
51         $this->profile = $this->trimmed('profile');
52
53         return true;
54     }
55
56     function handle($args)
57     {
58         parent::handle($args);
59
60         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
61             /* Use a session token for CSRF protection. */
62             $token = $this->trimmed('token');
63             if (!$token || $token != common_session_token()) {
64                 $this->showForm(_m('There was a problem with your session token. '.
65                                   'Try again, please.'));
66                 return;
67             }
68             $this->ostatusConnect();
69         } else {
70             $this->showForm();
71         }
72     }
73
74     function showForm($err = null)
75     {
76         $this->err = $err;
77         if ($this->boolean('ajax')) {
78             header('Content-Type: text/xml;charset=utf-8');
79             $this->xw->startDocument('1.0', 'UTF-8');
80             $this->elementStart('html');
81             $this->elementStart('head');
82             // TRANS: Form title.
83             $this->element('title', null, _m('Subscribe to user'));
84             $this->elementEnd('head');
85             $this->elementStart('body');
86             $this->showContent();
87             $this->elementEnd('body');
88             $this->elementEnd('html');
89         } else {
90             $this->showPage();
91         }
92     }
93
94     function showContent()
95     {
96         if ($this->group) {
97             // TRANS: Form legend.
98             $header = sprintf(_m('Join group %s'), $this->group);
99             // TRANS: Button text.
100             $submit = _m('BUTTON','Join');
101         } else {
102             // TRANS: Form legend.
103             $header = sprintf(_m('Subscribe to %s'), $this->nickname);
104             // TRANS: Button text.
105             $submit = _m('BUTTON','Subscribe');
106         }
107         $this->elementStart('form', array('id' => 'form_ostatus_connect',
108                                           'method' => 'post',
109                                           'class' => 'form_settings',
110                                           'action' => common_local_url('ostatusinit')));
111         $this->elementStart('fieldset');
112         $this->element('legend', null,  $header);
113         $this->hidden('token', common_session_token());
114
115         $this->elementStart('ul', 'form_data');
116         $this->elementStart('li', array('id' => 'ostatus_nickname'));
117         if ($this->group) {
118             // TRANS: Field label.
119             $this->input('group', _m('Group nickname'), $this->group,
120                          _m('Nickname of the group you want to join.'));
121         } else {
122             // TRANS: Field label.
123             $this->input('nickname', _m('User nickname'), $this->nickname,
124                          _m('Nickname of the user you want to follow.'));
125         }
126         $this->elementEnd('li');
127         $this->elementStart('li', array('id' => 'ostatus_profile'));
128         // TRANS: Field label.
129         $this->input('profile', _m('Profile Account'), $this->profile,
130                       // TRANS: Tooltip for field label "Profile Account".
131                      _m('Your account id (e.g. user@identi.ca).'));
132         $this->elementEnd('li');
133         $this->elementEnd('ul');
134         $this->submit('submit', $submit);
135         $this->elementEnd('fieldset');
136         $this->elementEnd('form');
137     }
138
139     function ostatusConnect()
140     {
141         $opts = array('allowed_schemes' => array('http', 'https', 'acct'));
142         if (Validate::uri($this->profile, $opts)) {
143             $bits = parse_url($this->profile);
144             if ($bits['scheme'] == 'acct') {
145                 $this->connectWebfinger($bits['path']);
146             } else {
147                 $this->connectProfile($this->profile);
148             }
149         } elseif (strpos($this->profile, '@') !== false) {
150             $this->connectWebfinger($this->profile);
151         } else {
152             // TRANS: Client error.
153             $this->clientError(_m("Must provide a remote profile."));
154         }
155     }
156
157     function connectWebfinger($acct)
158     {
159         $target_profile = $this->targetProfile();
160
161         $disco = new Discovery;
162         $result = $disco->lookup($acct);
163         if (!$result) {
164             // TRANS: Client error.
165             $this->clientError(_m("Couldn't look up OStatus account profile."));
166         }
167
168         foreach ($result->links as $link) {
169             if ($link['rel'] == 'http://ostatus.org/schema/1.0/subscribe') {
170                 // We found a URL - let's redirect!
171                 $url = Discovery::applyTemplate($link['template'], $target_profile);
172                 common_log(LOG_INFO, "Sending remote subscriber $acct to $url");
173                 common_redirect($url, 303);
174             }
175
176         }
177         // TRANS: Client error.
178         $this->clientError(_m("Couldn't confirm remote profile address."));
179     }
180
181     function connectProfile($subscriber_profile)
182     {
183         $target_profile = $this->targetProfile();
184
185         // @fixme hack hack! We should look up the remote sub URL from XRDS
186         $suburl = preg_replace('!^(.*)/(.*?)$!', '$1/main/ostatussub', $subscriber_profile);
187         $suburl .= '?profile=' . urlencode($target_profile);
188
189         common_log(LOG_INFO, "Sending remote subscriber $subscriber_profile to $suburl");
190         common_redirect($suburl, 303);
191     }
192
193     /**
194      * Build the canonical profile URI+URL of the requested user or group
195      */
196     function targetProfile()
197     {
198         if ($this->nickname) {
199             $user = User::staticGet('nickname', $this->nickname);
200             if ($user) {
201                 return common_local_url('userbyid', array('id' => $user->id));
202             } else {
203                 // TRANS: Client error.
204                 $this->clientError("No such user.");
205             }
206         } else if ($this->group) {
207             $group = Local_group::staticGet('nickname', $this->group);
208             if ($group) {
209                 return common_local_url('groupbyid', array('id' => $group->group_id));
210             } else {
211                 // TRANS: Client error.
212                 $this->clientError("No such group.");
213             }
214         } else {
215             // TRANS: Client error.
216             $this->clientError("No local user or group nickname provided.");
217         }
218     }
219
220     function title()
221     {
222       // TRANS: Page title.
223       return _m('OStatus Connect');
224     }
225 }