Special Ops 2.50
[specialops2.git] / register.php
blob0750de9c22a7ad820d4ed702ebf2ded75fd0c4be
1 <?php
2 /**
3 * User Account Registration
5 * @author Ant P <p@cpi.merseine.nu>
6 * @license file://COPYING
7 * @version 2.15
8 */
10 require 'con.php';
11 SO2::$Page->title = 'Account Registration';
13 if ( SO2::$User instanceof User_Authenticated ) {
14 isset($_POST['login'])
15 ? (header('Location: http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['REQUEST_URI']).'/') && exit)
16 : SO2::$Page->message('You\'re already registered!');
19 if ( isset($_POST['prompt']) ) {
20 $_GET = $_POST;
23 $uri = new HTML_Select('uri', 3);
24 $uri->add_item('mailto:', 'E-Mail');
25 $uri->add_item('xmpp:', 'Jabber/GTalk');
26 $uri->add_item('aim:', 'AIM');
27 $uri->add_item('http://');
28 $uri->add_item('irc://');
29 $uri->add_item('', 'Other (specify)');
30 $uri->set_default('mailto:');
32 if ( isset($_POST['something']) ) {
34 // Data validation
35 try {
36 // Referrer check
37 if ( !isset($_SERVER['HTTP_REFERER']) || !preg_match('/register/', $_SERVER['HTTP_REFERER']) ||
38 strpos($_SERVER['HTTP_REFERER'], 'http://'.$_SERVER['HTTP_HOST']) !== 0 ) {
39 throw new InvalidInputException('Invalid HTTP referrer sent.');
42 // Check address
43 $uri->check_value($_POST['uri']);
44 if ( empty($_POST['uri']) && !preg_match('/^[a-zA-Z0-9]+:/', $_POST['addr']) ) {
45 throw new InvalidInputException('Contact method not specified.');
48 // Set $address if valid
49 if ( 'Other (specify)' == $_POST['uri'] ) {
50 $address = $_POST['addr'];
51 } else {
52 $address = $_POST['uri'].$_POST['addr'];
55 // Blank fields
56 if ( empty($_POST['reg_u']) || empty($_POST['reg_p']) || empty($_POST['addr']) ) {
57 throw new InvalidInputException('You left one or more fields empty.');
60 // Mismatched passwords
61 if ( $_POST['reg_p'] !== $_POST['reg_c'] ) {
62 throw new InvalidInputException('Both passwords must match exactly.');
65 // Username
66 $_POST['reg_u'] = trim($_POST['reg_u']);
67 if ( preg_match('/\s{2,}|[<>&]|[Pp]ojr/', $_POST['reg_u']) ) {
68 throw new InvalidInputException('Username contains invalid characters.');
71 // Username in use
72 if ( SO2::$DB->q('SELECT COUNT(*) FROM users WHERE alias = ?', $_POST['reg_u'], SO2_PDO::QVALUE) ) {
73 throw new InvalidInputException('That username is already in use. Try a different name.');
76 // Invite system
77 if ( isset($_GET['code'])
78 && isset($_GET['user'])
79 && SO2::$DB->q('SELECT COUNT(*) FROM things WHERE what = \'invite\' AND data = ? AND userid = ?',
80 array($_GET['code'], $_GET['user']), SO2_PDO::QVALUE) ) {
81 define('INVITED', true);
84 if ( defined('INVITE_ONLY') && !defined('INVITED') ) {
85 sleep(7);
86 throw new InvalidInputException('Form data was submitted incorrectly.');
89 // Flood protection
90 if ( SO2::$DB->q('SELECT COUNT(*) FROM users WHERE reg_ip = INET_ATON(?)', $_SERVER['REMOTE_ADDR'], SO2_PDO::QVALUE) ) {
91 throw new RateLimitException(
92 'You can only register one account. If you lost your password, contact an admin'.
93 ' and a new one will be sent to the URI you specified when you signed up.');
96 SO2::$DB->beginTransaction();
98 SO2::$DB->q('SET @userip = INET_ATON(?)', $_SERVER['REMOTE_ADDR']);
100 // Retard protection
101 if ( empty($_POST['CYA']) ) {
102 header('HTTP/1.1 403 Forbidden');
103 SO2::$DB->exec('SET @userpass = \'banned\'');
104 } else {
105 header('HTTP/1.1 202 Accepted');
106 SO2::$DB->q('SET @userpass = AES_ENCRYPT(?, @userip)', $_POST['reg_p']);
109 SO2::$DB->q('INSERT INTO users ('.
110 'alias, referrer, reg_contact, points, passwd, last_login_ip, reg_ip, register_date, last_active_date'.
111 ') VALUES (?, ?, ?, ?, @userpass, @userip, @userip, UNIX_TIMESTAMP(), UNIX_TIMESTAMP() )',
112 array( $_POST['reg_u'], (defined('INVITED') ? $_GET['user'] : null), $address, intval(defined('INVITED')) )
115 $u = SO2::$DB->lastInsertId();
116 SO2::$DB->q('SET @userid = ?', $u);
117 SO2::$User = new User_Authenticated($u);
119 if ( defined('INVITED') ) {
120 SO2::$DB->q('DELETE FROM things WHERE what = \'invite\' AND data = ? AND userid = ?',
121 array($_GET['code'], $_GET['user']) );
124 setcookie('u', $_POST['reg_u'], T_NOW+86400);
125 setcookie('p', $_POST['reg_p'], T_NOW+86400);
127 SO2::$Page->pageheader();
129 if ( empty($_POST['CYA']) ) {
130 echo '<p class="error">TOS Rejected - Account Banned.</p>';
131 } else {
132 echo '<p class="info">Your account has been created!</p>';
135 SO2::$DB->commit();
136 exit;
138 } catch ( InvalidInputException $e ) {
139 header('HTTP/1.1 400 Bad Request');
140 SO2::$Page->pageheader();
141 echo '<p class="error">',$e->getMessage(),'</p>';
142 } catch ( RateLimitException $e ) {
143 header('HTTP/1.1 400 Bad Request');
144 SO2::$Page->pageheader();
145 echo '<p class="error">',$e->getMessage(),'</p>';
148 } elseif ( defined('INVITE_ONLY')
149 && ! ( isset($_GET['code'])
150 && isset($_GET['user'])
151 && SO2::$DB->q('SELECT COUNT(*) FROM things NATURAL LEFT JOIN users '.
152 'WHERE what = \'invite\' AND data = ? AND users.userid IS NOT NULL AND things.userid = ?',
153 array($_GET['code'], $_GET['user']), SO2_PDO::QVALUE)
156 SO2::$Page->pageheader();
159 <p class="error">You need a valid invitation code to create an account.</p>
160 <p>Enter the registration code you were given and the user ID number of the person who gave you it.</p>
161 <form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="get">
162 <table class="inputlist">
163 <tr><th scope="row">Code</th><td><input type="text" name="code" size="36" maxlength="36"/></td></tr>
164 <tr><th scope="row">User ID</th><td><input type="text" name="user" size="5"/></td></tr>
165 </table>
166 <p><button type="submit">Confirm</button></p>
167 <p>Don't have an invite? One of our members might.</p>
168 </form>
170 <?php
171 exit;
172 } else {
173 SO2::$Page->pageheader();
177 if ( ip2long($_SERVER['REMOTE_ADDR']) === false ) { // ipv6 doesn't work yet
178 echo '<p class="error">Error: You have to register from an IPv4 address.</p>',"\n";
179 exit;
182 if ( isset($_GET['user'], $_GET['code']) ) {
183 printf('<form action="%s?user=%d;code=%s" method="post">',
184 $_SERVER['PHP_SELF'], intval($_GET['user']), htmlentities($_GET['code']));
185 } else {
186 echo '<form action="',$_SERVER['PHP_SELF'],'" method="post">';
189 $q = SO2::$DB->query('SELECT COLUMN_NAME, CHARACTER_MAXIMUM_LENGTH '.
190 'FROM information_schema.COLUMNS '.
191 'WHERE TABLE_SCHEMA = \''.SO2::$Cfg['db']['name'].'\' '.
192 'AND TABLE_NAME = \'users\' '.
193 'AND COLUMN_NAME IN(\'alias\', \'passwd\', \'reg_contact\')');
194 while ( $row = $q->fetch() ) {
195 $limits[$row[0]] = $row[1];
197 $q = null;
199 function field($which=null, $range=null)
201 if ( $which && !empty($_POST[$which]) ) {
202 if ( is_numeric($range) ) {
203 echo ' maxlength="',$range,'" value="',htmlspecialchars($_POST[$which]),'"';
204 } elseif ( true === $range ) {
205 echo ' checked="checked"';
207 } elseif ( is_numeric($range) ) {
208 echo ' maxlength="',$range,'"';
213 <fieldset><legend>Register Account</legend>
214 <p>All fields are required.</p>
215 <table class="inputlist">
216 <tr>
217 <th scope="row">Username <small>(max <?php echo $limits['alias'] ?> characters)</small></th>
218 <td><input type="text" name="reg_u"<?php field('reg_u', $limits['alias']) ?>/></td>
219 </tr>
220 <tr>
221 <th scope="row">Password</th>
222 <td><input type="password" name="reg_p"<?php field(null, $limits['passwd']) ?>/></td>
223 </tr>
224 <tr>
225 <th scope="row">Confirm Password</th>
226 <td><input type="password" name="reg_c"<?php field(null, $limits['passwd']) ?>/></td>
227 </tr>
228 <tr>
229 <th scope="row">Contact URI</th>
230 <td><?php echo $uri ?><input type="text" name="addr"<?php field('addr', $limits['reg_contact']-10) ?>/></td>
231 </tr>
232 </table>
234 <?php readfile('res/tos.xml'); ?>
236 <p><label>
237 <input type="checkbox" name="CYA"<?php field('CYA', true); ?>/>
238 I have read and agree to follow the board rules.
239 </label></p>
240 <p>Enter the CAPTCHA: <input type="text" name="captcha"/><br/><img src="/stuff/magiceye.jpg" alt="Enter these letters"/></p>
241 <p>Reading the <a href="stuff#faq">FAQ</a> is also advised.</p>
242 <p><button type="submit" name="something">Create Account</button></p>
243 </fieldset>
244 </form>