function raw_content() { if (!array_key_exists('id', $_GET)) { http_response_code(404); $error_page = 'error_404_content'; } $user = fetch_one_or_none('users', 'id', $_GET['id']); if (!$user || is_null($user->date_verified)) { http_response_code(404); $error_page = 'error_404_content'; } global $config; $title = $config['title']; $uid = $user->id; $uname = $user->name; $gedcom = <<<EOF 0 HEAD 1 SOUR {$title} 1 SUBM @U{$uid}@ 1 GEDC 2 VERS 5.5 2 FORM LINEAGE-LINKED 1 CHAR UTF-8 0 @U{$uid}@ SUBM 1 NAME {$uname} 0 TRLR EOF; header('Content-Type: application/x-gedcom'); echo $gedcom; }
function content() { if (!user_logged_in()) { return must_log_in(); } $user = fetch_one_or_none('users', 'id', user_logged_in()); if (!array_key_exists('token', $_GET) || !$_GET['token'] || $_GET['token'] != sha1($user->new_email_address)) { $errors[] = 'Invalid reset token'; } # This can happen if two accounts try to change address at similar times. if (count($errors) == 0 && count(fetch_all('users', 'email_address', $user->new_email_address))) { $errors[] = "A user with this email address already exists"; } if (count($errors) == 0) { update_all('users', array('email_address' => $user->new_email_address, 'new_email_address' => null), 'id', user_logged_in()); ?> <h2>Address changed</h2> <p>Your email address has been changed to <tt><?php esc($user->new_email_address); ?> </tt>.</p> <?php return; } page_header('Address verification failed'); show_error_list($errors); }
function content() { if (!user_logged_in()) { return must_log_in(); } $user = fetch_one_or_none('users', 'id', user_logged_in()); $errors = array(); if (array_key_exists('change', $_POST)) { if (!isset($_POST['email']) || !$_POST['email']) { $errors[] = "Please enter an email address"; } else { $email = $_POST['email']; if ($email && !validate_email_address($email)) { $errors[] = "Invalid email address"; } if (count($errors) == 0 && count(fetch_all('users', 'email_address', $email))) { $errors[] = "A user with this email address already exists"; } if (count($errors) == 0) { update_all('users', array('new_email_address' => $email), 'id', user_logged_in()); send_email_change_email($email, $user->name); ?> <p>We have sent an email to your new address requesting that you confirm that change of address.</p> <?php return; } } } $fields = array(); page_header('Change email address'); show_error_list($errors); ?> <form method="post" action="" accept-charset="UTF-8"> <div class="fieldrow"> <div class="field"> <label>Current address:</label> <div><tt><?php esc($user->email_address); ?> </tt></div> </div> </div> <div class="fieldrow"> <?php text_field($fields, 'email', 'New address'); ?> </div> <div class="fieldrow"> <input type="submit" name="change" value="Change"/> </div> </form> <?php }
function content() { $errors = array(); if (!array_key_exists('token', $_GET) || !$_GET['token']) { $errors[] = 'Invalid activation token'; } $token = $_GET['token']; $user = fetch_one_or_none('users', 'activation_token', $_GET['token']); if (!$user) { $errors[] = 'Invalid activation token'; } if (count($errors)) { page_header('Activation failed'); show_error_list($errors); return; } $admins = fetch_wol('*', 'users', 'date_verified IS NOT NULL AND date_approved IS NOT NULL', 'id ASC'); $sets = array('activation_token' => null, 'date_verified' => date('Y-m-d H:i:s')); # Auto-approve user 1. if (count($admins) == 0) { $sets['date_approved'] = $sets['date_verified']; $sets['approved_by'] = 1; } update_all('users', $sets, 'id', $user->id); page_header('Account activated'); if (count($admins)) { send_approval_request($user, $admins); ?> <p>Thank you for activating your account. Your request for an account has been forwarded to a site administrator for approval. You will be notified by email when it is approved.</p> <?php } else { register_user_rdf($user); # Don't set login cookie now. This is to prevent someone hijacking # a login token, using it, and benefiting from a pre-logged-in session. # This way, they still need a password. global $config; ?> <p>Thank you for activating your account. You shouldn't need to do that again. You may now want to <a href="<?php esc($config['http_path']); ?> account/login">log in</a>.</p> <?php } }
function preload_user() { global $user, $error_page; if (!array_key_exists('id', $_GET)) { http_response_code(404); $error_page = 'error_404_content'; } $user = fetch_one_or_none('users', 'id', $_GET['id']); if (!$user || is_null($user->date_verified)) { http_response_code(404); $error_page = 'error_404_content'; } }
function content() { $errors = array(); page_header('Request password reset'); if (array_key_exists('reset', $_POST)) { if (!isset($_POST['email']) || !$_POST['email']) { $errors[] = "Please enter an email address"; } else { $user = fetch_one_or_none('users', 'email_address', $_POST['email']); if (!$user) { $errors[] = "Incorrect email address supplied"; } if (count($errors) == 0) { $token = make_random_token(); update_all('users', array('activation_token' => $token), 'id', $user->id); send_reset_email($user->email_address, $user->name, $token); ?> <p>We have sent you an email containing a link allowing you to reset your password.</p> <?php return; } } } ?> <p>If you have forgotten your password and need it resetting, please enter your email address below and we will send you an email allowing you to reset your password.</p> <?php show_error_list($errors); ?> <form method="post" action="" accept-charset="UTF-8"> <div class="fieldrow"> <?php text_field($_POST, 'email', 'Email address'); ?> </div> <div class="fieldrow"> <input type="submit" name="reset" value="Reset" /> </div> </form> <?php }
function content() { global $config; if (!user_logged_in()) { return must_log_in(); } $errors = array(); if (!array_key_exists('id', $_GET)) { $errors[] = 'No user ID'; } if (count($errors) == 0) { $user = fetch_one_or_none('users', 'id', $_GET['id']); if (!$user) { $errors[] = 'No such user'; } if (!$user->date_verified) { $errors[] = 'User has not yet been verified'; } if ($user->date_approved) { $errors[] = 'User has already been approved'; } } if (count($errors)) { page_header("Error approving account"); show_error_list($errors); return; } if (!$user->date_approved) { update_all('users', array('date_approved' => date('Y-m-d H:i:s'), 'approved_by' => user_logged_in()), 'id', $user->id); } $root = 'http://' . $config['domain'] . $config['http_path']; $msg = "Your " . $config['title'] . " account has been approved. " . "To log in, please follow \n" . "the following link:\n" . "\n" . " {$root}account/login\n" . "\n"; mail(sprintf('"%s" <%s>', $user->name, $user->email_address), $config['title'] . " account approved", $msg) or die('Unable to send email'); register_user_rdf($user); page_header("Account approved"); ?> <p>Thank you for approving <?php esc($user->name); ?> 's account.</p> <?php }
function raw_content() { global $config; if (!array_key_exists('id', $_GET)) { error(); } $user = fetch_one_or_none('users', 'id', $_GET['id']); if (!$user || is_null($user->date_verified)) { error(); } $mime = 'application/rdf+xml'; if (array_key_exists('extension', $_GET)) { $ext = $_GET['extension']; if ($ext == 'ttl' || $ext == 'turtle') { $mime = 'text/turtle'; } else { if ($ext == 'nt' || $ext == 'n3') { $mime = 'application/n-triples'; } } } header("Content-Type: {$mime}"); echo retrieve_rdf($user, $mime); }
function content() { $errors = array(); if (user_logged_in()) { $uid = user_logged_in(); } else { if (!array_key_exists('token', $_GET) || !$_GET['token']) { $errors[] = 'Invalid reset token'; } $token = $_GET['token']; $user = fetch_one_or_none('users', 'activation_token', $_GET['token']); if (count($user) != 1) { $errors[] = 'Invalid reset token'; } if (count($errors)) { page_header('Reset failed'); show_error_list($errors); return; } $uid = $user->id; } page_header('Reset password'); if (array_key_exists('reset', $_POST)) { if (!isset($_POST['password']) || !isset($_POST['password2']) || !$_POST['password']) { $errors[] = "Please provide a password"; } else { $password = $_POST['password']; $password2 = $_POST['password2']; if ($password != $password2) { $errors[] = "Passwords do not match"; } else { update_all('users', array('password_crypt' => crypt($password), 'activation_token' => null), 'id', $uid); ?> <p>Your password has been reset.<?php if (!user_logged_in()) { ?> You may now wish to <a href="login">log in</a>.<?php } ?> </p> <?php return; } } show_error_list($errors); } ?> <form method="post" action="" accept-charset="UTF-8"> <div class="fieldrow"> <div> <label for="password">Password</label> <input type="password" id="password" name="password" value="<?php esc($_POST['password']); ?> " /> </div> <div> <label for="password2">Confirm password</label> <input type="password" id="password2" name="password2" value="<?php esc($_POST['password2']); ?> " /> </div> </div> <div class="fieldrow"> <input type="submit" name="reset" value="Reset" /> </div> </form> <?php }
function fetch_one($table, $key, $id, $fields = null) { $obj = fetch_one_or_none($table, $key, $id, $fields) or die('No such ' . $table); return $obj; }
function raw_content() { global $error_page; if ($_SERVER['REQUEST_METHOD'] != 'HEAD' && $_SERVER['REQUEST_METHOD'] != 'GET') { http_response_code(405); header('Allow: GET, HEAD'); exit; } if (!array_key_exists('id', $_GET)) { http_response_code(404); $error_page = "error_404_content"; return; } $f = fetch_one_or_none('files', 'id', $_GET['id']); if (is_null($f)) { http_response_code(404); $error_page = "error_404_content"; return; } # If someone fetches /files/NN.png, give an error if this is not a png. if (array_key_exists('extension', $_GET)) { if ($f->extension != $_GET['extension']) { http_response_code(404); $error_page = "error_404_content"; return; } } header('Cache-Control: public'); # TODO: If it's not public: if (0) { # Cache-Control: private allows private caching, that is caching that # is limited to a single user (as, for example, might happen in a web # browser). Public caching, e.g. in a ISP's caching proxy, is not # permitted. header('Cache-Control: private'); # In principle this tells the browser to clear the cache on logout, # though in practice I'm not sure this does anything useful. header('Vary: Cookie'); } # Send the Content-Type too, as otherwise PHP will use text/html header('Content-Type: ' . $f->mime_type); # Only disclose the ETag now that we've checked the user is authorised. # We do this before handling If-None-Match, because that header may contain # multiple ETags, and if so, we need to disclose which one matched. header('ETag: ' . $f->sha1); # This is complicated by the fact that If-None-Match can be combined with # If-Modified-Since, and then we only 304 if both match. Once we set # $match = 0, we know we've failed. If it is 1, we know that all of the # conditions currently tested have succeed. If it's null, then we've not # yet found a precondition to test. $match = null; if ($match !== 0 && array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER)) { $match = 0; $etags = strtolower(str_replace(' ', '', $_SERVER['HTTP_IF_NONE_MATCH'])); if ($etags == '*') { $match = 1; } else { foreach (explode(',', $etags) as $e) { if ($e == strtolower($f->sha1)) { $match = 1; } } } } if ($match !== 0 && array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER)) { $match = 0; $fmt = 'Y-M-d\\TH:i:s'; if (date_format(date_create($_SERVER['HTTP_IF_MODIFIED_SINCE']), $fmt) >= date_format(date_create($f->date_uploaded), $fmt)) { $match = 1; } } # If all conditions have succeeded, we send exit with a 304 Not Modified. if ($match) { http_response_code(304); exit; } header('Content-Size: ' . $f->length); header('Last-Modified: ' . date_format(date_create($f->date_uploaded), 'D, d M Y H:i:s O')); # Add an RFC 5988 Link header. This is the recommended means of linking # a resource to its description in POWDER, and, even though we're not # using POWDER, it's a standard means of metadata discovery c.f. various # W3C 'CSV on the Web' drafts. $base = "http://" . $config['domain'] . $config['http_path'] . 'files/'; $url = $base . $f->id . '.' . $f->extension; header("Link: <{$url}.rdf>; " . 'rel="describedby"; type="application/rdf+xml"'); if ($_SERVER['REQUEST_METHOD'] != 'HEAD') { $mog = new MogileFs(); global $config; $cfg = $config['mogilefs']; $mog->connect($cfg['hostname'], $cfg['port'], $cfg['domain']); # Fetch the metadata from mogilefs $metadata = $mog->get($f->id); # Pick a path at random $pathn = rand(1, $metadata['paths']); $path = $metadata['path' . $pathn]; error_log("Fetching file #{$id}'s data from {$path}"); $fh = fopen($path, 'rb'); fpassthru($fh); fclose($fh); } }
function content() { if (!user_logged_in()) { return must_log_in(); } $user = fetch_one_or_none('users', 'id', user_logged_in()); page_header('Account'); $errors = array(); if (array_key_exists('apply', $_POST)) { if (!isset($_POST['name']) || !$_POST['name']) { $errors[] = "Please provide a name"; } if (count($errors) == 0) { $sets = array('name' => $_POST['name']); update_all('users', $sets, 'id', $user->id); update_local_object($user, $sets); ?> <p>Your changes have been applied. Return to <a href=".">account</a> page.</p> <?php return; } show_error_list($errors); } $fields = array('name' => $user->name, 'email' => $user->email_address); ?> <form method="post" action="" accept-charset="UTF-8"> <fieldset> <legend>Details</legend> <div class="fieldrow"> <?php text_field($fields, 'name', 'Name', 'publicly visible'); ?> </div> <div class="fieldrow"> <div class="field"> <label>Email address</label> <div><tt><?php esc($fields['email']); ?> </tt> <a class="control small" style="padding-left: 1em" href="change-email">Change</a></div> </div> </div> <div class="fieldrow"> <div class="field"> <label>Password</label> <div><tt>********</tt> <a class="control small" style="padding-left: 1em" href="reset-password">Change</a></div> </div> </div> <div class="fieldrow"> <input type="submit" name="apply" value="Update"/> </div> </fieldset> <fieldset> <legend>Contact details</legend> <p>Any details entered here will be made publicly available.</p> <?php /*NAME, ADDR, PHON, EMAIL, FAX, WWW, OBJE, LANG, RFN, RIN, NOTE, CHAN*/ ?> </fieldset> </form> <?php }