]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - actions/register.php
CSRF protection in user registration
[quix0rs-gnu-social.git] / actions / register.php
1 <?php
2 /*
3  * Laconica - a distributed open-source microblogging tool
4  * Copyright (C) 2008, Controlez-Vous, 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 if (!defined('LACONICA')) { exit(1); }
21
22 class RegisterAction extends Action {
23
24         function handle($args) {
25                 parent::handle($args);
26
27                 if (common_config('site', 'closed')) {
28                         common_user_error(_('Registration not allowed.'));
29                 } else if (common_logged_in()) {
30                         common_user_error(_('Already logged in.'));
31                 } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
32                         $this->try_register();
33                 } else {
34                         $this->show_form();
35                 }
36         }
37
38         function try_register() {
39                 
40                 $token = $this->trimmed('token');
41                 if (!$token || $token != common_session_token()) {
42                         $this->show_form(_('There was a problem with your session token. Try again, please.'));
43                         return;
44                 }
45
46                 $nickname = $this->trimmed('nickname');
47                 $email = $this->trimmed('email');
48                 $fullname = $this->trimmed('fullname');
49                 $homepage = $this->trimmed('homepage');
50                 $bio = $this->trimmed('bio');
51                 $location = $this->trimmed('location');
52
53                 # We don't trim these... whitespace is OK in a password!
54
55                 $password = $this->arg('password');
56                 $confirm = $this->arg('confirm');
57
58                 # Input scrubbing
59
60                 $nickname = common_canonical_nickname($nickname);
61                 $email = common_canonical_email($email);
62
63                 if (!$this->boolean('license')) {
64                         $this->show_form(_('You can\'t register if you don\'t agree to the license.'));
65                 } else if ($email && !Validate::email($email, true)) {
66                         $this->show_form(_('Not a valid email address.'));
67                 } else if (!Validate::string($nickname, array('min_length' => 1,
68                                                                                                           'max_length' => 64,
69                                                                                                           'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) {
70                         $this->show_form(_('Nickname must have only lowercase letters and numbers and no spaces.'));
71                 } else if ($this->nickname_exists($nickname)) {
72                         $this->show_form(_('Nickname already in use. Try another one.'));
73                 } else if (!User::allowed_nickname($nickname)) {
74                         $this->show_form(_('Not a valid nickname.'));
75                 } else if ($this->email_exists($email)) {
76                         $this->show_form(_('Email address already exists.'));
77                 } else if (!is_null($homepage) && (strlen($homepage) > 0) &&
78                                    !Validate::uri($homepage, array('allowed_schemes' => array('http', 'https')))) {
79                         $this->show_form(_('Homepage is not a valid URL.'));
80                         return;
81                 } else if (!is_null($fullname) && strlen($fullname) > 255) {
82                         $this->show_form(_('Full name is too long (max 255 chars).'));
83                         return;
84                 } else if (!is_null($bio) && strlen($bio) > 140) {
85                         $this->show_form(_('Bio is too long (max 140 chars).'));
86                         return;
87                 } else if (!is_null($location) && strlen($location) > 255) {
88                         $this->show_form(_('Location is too long (max 255 chars).'));
89                         return;
90                 } else if ($password != $confirm) {
91                         $this->show_form(_('Passwords don\'t match.'));
92                 } else if ($user = User::register(array('nickname' => $nickname, 'password' => $password, 'email' => $email,
93                                                                                                 'fullname' => $fullname, 'homepage' => $homepage, 'bio' => $bio, 
94                                                                                                 'location' => $location))) {
95                         if (!$user) {
96                                 $this->show_form(_('Invalid username or password.'));
97                                 return;
98                         }
99                         # success!
100                         if (!common_set_user($user)) {
101                                 common_server_error(_('Error setting user.'));
102                                 return;
103                         }
104                         # this is a real login
105                         common_real_login(true);
106                         if ($this->boolean('rememberme')) {
107                                 common_debug('Adding rememberme cookie for ' . $nickname);
108                                 common_rememberme($user);
109                         }
110                         # Re-init language env in case it changed (not yet, but soon)
111                         common_init_language();
112                         $this->show_success();
113                 } else {
114                         $this->show_form(_('Invalid username or password.'));
115                 }
116         }
117
118         # checks if *CANONICAL* nickname exists
119
120         function nickname_exists($nickname) {
121                 $user = User::staticGet('nickname', $nickname);
122                 return ($user !== false);
123         }
124
125         # checks if *CANONICAL* email exists
126
127         function email_exists($email) {
128                 $email = common_canonical_email($email);
129                 $user = User::staticGet('email', $email);
130                 return ($user !== false);
131         }
132
133         function show_top($error=NULL) {
134                 if ($error) {
135                         common_element('p', 'error', $error);
136                 } else {
137                         common_element('div', 'instructions',
138                                                    _('You can create a new account to start posting notices.'));
139                 }
140         }
141
142         function show_form($error=NULL) {
143                 global $config;
144
145                 common_show_header(_('Register'), NULL, $error, array($this, 'show_top'));
146                 common_element_start('form', array('method' => 'post',
147                                                                                    'id' => 'login',
148                                                                                    'action' => common_local_url('register')));
149                 common_hidden('token', common_session_token());
150                 common_input('nickname', _('Nickname'), $this->trimmed('nickname'),
151                                          _('1-64 lowercase letters or numbers, no punctuation or spaces. Required.'));
152                 common_password('password', _('Password'),
153                                                 _('6 or more characters. Required.'));
154                 common_password('confirm', _('Confirm'),
155                                                 _('Same as password above. Required.'));
156                 common_input('email', _('Email'), $this->trimmed('email'),
157                                          _('Used only for updates, announcements, and password recovery'));
158                 common_input('fullname', _('Full name'),
159                                          $this->trimmed('fullname'),
160                                           _('Longer name, preferably your "real" name'));
161                 common_input('homepage', _('Homepage'),
162                                          $this->trimmed('homepage'),
163                                          _('URL of your homepage, blog, or profile on another site'));
164                 common_textarea('bio', _('Bio'),
165                                                 $this->trimmed('bio'),
166                                                  _('Describe yourself and your interests in 140 chars'));
167                 common_input('location', _('Location'),
168                                          $this->trimmed('location'),
169                                          _('Where you are, like "City, State (or Region), Country"'));
170                 common_checkbox('rememberme', _('Remember me'), 
171                                                 $this->boolean('rememberme'),
172                                 _('Automatically login in the future; not for shared computers!'));
173                 common_element_start('p');
174                 $attrs = array('type' => 'checkbox',
175                                            'id' => 'license',
176                                            'name' => 'license',
177                                            'value' => 'true');
178                 if ($this->boolean('license')) {
179                         $attrs['checked'] = 'checked';
180                 }
181                 common_element('input', $attrs);
182             common_text(_('My text and files are available under '));
183                 common_element('a', array(href => $config['license']['url']),
184                                            $config['license']['title']);
185                 common_text(_(' except this private data: password, email address, IM address, phone number.'));
186                 common_element_end('p');
187                 common_submit('submit', _('Register'));
188                 common_element_end('form');
189                 common_show_footer();
190         }
191                                                 
192         function show_success() {
193                 $nickname = $this->arg('nickname');
194                 common_show_header(_('Registration successful'));
195                 common_element_start('div', 'success');
196                 $instr = sprintf(_('Congratulations, %s! And welcome to %%%%site.name%%%%. From here, you may want to...'. "\n\n" .
197                                                    '* Go to [your profile](%s) and post your first message.' .  "\n" .
198                                                    '* Add a [Jabber/GTalk address](%%%%action.imsettings%%%%) so you can send notices through instant messages.' . "\n" .
199                                                    '* [Search for people](%%%%action.peoplesearch%%%%) that you may know or that share your interests. ' . "\n" .
200                                                    '* Update your [profile settings](%%%%action.profilesettings%%%%) to tell others more about you. ' . "\n" .
201                                                    '* Read over the [online docs](%%%%doc.help%%%%) for features you may have missed. ' . "\n\n" .
202                                                    'Thanks for signing up and we hope you enjoy using this service.'),
203                                                  $nickname, common_local_url('showstream', array('nickname' => $nickname)));
204                 common_raw(common_markup_to_html($instr));
205                 $have_email = $this->trimmed('email');
206                 if ($have_email) {
207                         $emailinstr = _('(You should receive a message by email momentarily, with ' .
208                                                         'instructions on how to confirm your email address.)');
209                         common_raw(common_markup_to_html($emailinstr));
210                 }
211                 common_element_end('div');
212                 common_show_footer();
213         }
214                                                 
215 }