Alex Franke's Page
I'm brand new to WikkaWiki (and new to wikis in general), and pretty inexperienced with PHP and open source development. I've been a C# developer for years, though, and other technologies going back. I don't get a lot of chances to work on web stuff, but it interests me. I'm trying out WikkaWiki on my personal site over at http://www.theFrankes.com. My software development-related website is http://www.codecreations.com, and my other sites aren't really applicable, so I'll leave them out. :)
What I'm Using WikkaWiki For
I'm trying it out as a way to organize and manage family information, projects, to-do lists, etc. It's actually on a windows server for now.
There are a handful of people that I want to have access, and I don't want most of the site publicly accessible. I want registered users to be able to add new registered users (e.g. my brother can add his wife if he wants), but I don't want to have a simple "secret" password.
I might be missing something simple here, but I couldn't immediately find an easy way to do this. So I started writing some code. :) If there's a better way to do this, please feel free to enlighten me. Like I say, I'm still brand spankin' new to this software, and I'm still getting used to wiki syntax. (E.g., I still need to figure out how to add a camel-case name so it doesn't get picked up as a wikiname!)
Here's what I've done:
- Make read/write ACLs default to Registered Users
- 'default_write_acl' => '+',
- 'default_read_acl' => '+',
- 'default_comment_acl' => '+',
- Turn Allow User Registration Off
- 'allow_user_registration' => '0',
- Set UserSettings and Home page read ACL to public
- Write an Add New User action (more later)
"Add New User" Action
I lifted code from other pages (mainly User Settings and Admin Users) to build a part that allows people to add new users and optionally send them an email. At first (last night) I just added it to the bottom of Admin Users, but today I moved it over to a new page that's accessible to all registered users.
I'm new to open source, and I haven't done all me reading yet, so go easy on me! But do feel free to chime in if you see any serious issues, or if there's a built-in way to handle this. Thanks!
<?php
/**
* Display a module for adding a user.
*
* This action allows users to be added (preferably by admins). As a result, a wiki
* can be configured for use by invitation only by setting allow_user_registration
* to zero and placing this action on an admin- or member-restricted page.
*/
// defaults
if (!defined('PASSWORD_MIN_LENGTH')) define('PASSWORD_MIN_LENGTH', "5");
if (!defined('VALID_EMAIL_PATTERN')) define('VALID_EMAIL_PATTERN', "/^.+?\@.+?\..+$/"); //TODO: Use central regex library
if (!defined('INPUT_ERROR_STYLE')) define('INPUT_ERROR_STYLE', 'class="highlight"');
// i18n strings
// General
if (!defined('ADD_USER_HEADING')) define('ADD_USER_HEADING', "Add new user");
if (!defined('ADD_USER_BUTTON_LABEL')) define('ADD_USER_BUTTON_LABEL', "Add User");
if (!defined('ADD_SUCCEEDED')) define('ADD_SUCCEEDED', "User has been added!");
if (!defined('EMAIL_SUBJECT')) define('EMAIL_SUBJECT', "User has been added!");
if (!defined('EMAIL_BODY')) define('EMAIL_BODY', "A wiki account has been created for you at " . $this->config['base_url'] . ". Your username/password are: ");
// GUI Labels
if (!defined('WIKINAME_LABEL')) define('WIKINAME_LABEL', "New user's <abbr title=\"A WikiName is formed by two or more capitalized words without space, e.g. JohnDoe\">WikiName</abbr>:");
if (!defined('USER_EMAIL_LABEL')) define('USER_EMAIL_LABEL', "User's email address:");
if (!defined('PASSWORD_LABEL')) define('PASSWORD_LABEL', "Password (%s+ chars):");
if (!defined('EMAIL_NEW_USER_LABEL')) define('EMAIL_NEW_USER_LABEL', "Send welcome email:");
// Validation Errors - General
if(!defined('ERROR_VALIDATION_FAILED')) define('ERROR_VALIDATION_FAILED', "Registration validation failed, please try again!");
// ...Validation Errors - Username
if (!defined('ERROR_EMPTY_USERNAME')) define('ERROR_EMPTY_USERNAME', "Please fill in your user name.");
if (!defined('ERROR_USERNAME_EXISTS')) define('ERROR_USERNAME_EXISTS', "Sorry, this user name already exists.");
if (!defined('ERROR_WIKINAME')) define('ERROR_WIKINAME', "Username must be formatted as a ##\"\"WikiName\"\"##, e.g. ##\"\"JohnDoe\"\"##.");
if (!defined('ERROR_RESERVED_PAGENAME')) define('ERROR_RESERVED_PAGENAME', "Sorry, this name is reserved for a page. Please choose a different name.");
// ...Validation Errors - Email
if (!defined('ERROR_EMAIL_ADDRESS_REQUIRED')) define('ERROR_EMAIL_ADDRESS_REQUIRED', "Please specify an email address.");
if (!defined('ERROR_INVALID_EMAIL_ADDRESS')) define('ERROR_INVALID_EMAIL_ADDRESS', "That doesn't quite look like an email address.");
// ...Validation Errors - Password
if (!defined('ERROR_EMPTY_PASSWORD')) define('ERROR_EMPTY_PASSWORD', "Please fill in a password.");
if (!defined('ERROR_NO_BLANK')) define('ERROR_NO_BLANK', "Sorry, blanks are not permitted in the password.");
if (!defined('ERROR_PASSWORD_TOO_SHORT')) define('ERROR_PASSWORD_TOO_SHORT', "Sorry, the password must contain at least %s characters.");
//initialize variables
$url = '';
$params = '';
$username = '';
$email = '';
$password = '';
$username_highlight = '';
$email_highlight = '';
$password_highlight = '';
// Create URAuth object
include_once('libs/userregistration.class.php');
$urobj = new URAuth($this);
//create URL
$url = $this->config['base_url'].$this->tag;
// append URL params depending on rewrite_mode
$params = ($this->config['rewrite_mode'] == 1) ? '?' : '&';
$regex_referrer = '@^'.preg_quote($this->config['base_url'], '@').'([^\/\?&]*)@i';
if (isset($_SERVER['HTTP_REFERER']) && preg_match($regex_referrer, $_SERVER['HTTP_REFERER'], $match))
{
if (strcasecmp($this->tag, $match[1]))
{
$_SESSION['go_back'] = $_SERVER['HTTP_REFERER'];
//We save the tag of the referring page, this tag is to be shown in label <Go back to ...>. We must use a session here because if the user
//Refresh the page by hitting <Enter> on the address bar, the value would be lost.
$_SESSION['go_back_tag'] = $match[1];
}
}
// User must be logged in
if ($user = $this->GetUser() )
{
// validate data source
$keep_post_data = FALSE;
if (isset($_POST['form_id']) && FALSE != ($aKey = $this->getSessionKey($_POST['form_id']))) # check if page key was stored in session
{
if (TRUE == ($rc = $this->hasValidSessionKey($aKey))) # check if correct name,key pair was passed
{
$keep_post_data = TRUE;
}
}
if(!$keep_post_data) unset($_POST);
// is user trying to add a user?
if (isset($_POST['action']) && ($_POST['action'] == 'adduser'))
{
// get POST parameters
$name = trim($_POST['name']);
$email = trim($this->GetSafeVar('email', 'post'));
$password = $_POST['password'];
$email_new_user = $this->GetSafeVar('email_new_user', 'post');
// validate form input
switch (TRUE)
{
// Validate the NAME
case (FALSE===$urobj->URAuthVerify()):
$error = ERROR_VALIDATION_FAILED;
break;
case (strlen($name) == 0):
$error = ERROR_EMPTY_USERNAME;
$username_highlight = INPUT_ERROR_STYLE;
break;
case (isset($_POST['name']) && $existingUser = $this->LoadUser($_POST['name'])):
$error = ERROR_USERNAME_EXISTS;
$username_highlight = INPUT_ERROR_STYLE;
break;
case (!$this->IsWikiName($name)):
$error = ERROR_WIKINAME;
$username_highlight = INPUT_ERROR_STYLE;
break;
case ($this->existsPage($name,NULL,NULL,FALSE)): // name change, new interface (check for non-active page, too)
$error = ERROR_RESERVED_PAGENAME;
$username_highlight = INPUT_ERROR_STYLE;
break;
// Valide EMAIL
case (strlen($email) == 0): //email is empty
$error = ERROR_EMAIL_ADDRESS_REQUIRED;
$email_highlight = INPUT_ERROR_STYLE;
break;
case (!preg_match(VALID_EMAIL_PATTERN, $email)): //invalid email
$error = ERROR_INVALID_EMAIL_ADDRESS;
$email_highlight = INPUT_ERROR_STYLE;
break;
// Validate PASSWORD
case (strlen($password) == 0):
$passerror = ERROR_EMPTY_PASSWORD;
$password_highlight = INPUT_ERROR_STYLE;
break;
case (preg_match("/ /", $password)):
$passerror = ERROR_NO_BLANK;
$password_highlight = INPUT_ERROR_STYLE;
break;
case (strlen($password) < PASSWORD_MIN_LENGTH):
$passerror = sprintf(ERROR_PASSWORD_TOO_SHORT, PASSWORD_MIN_LENGTH);
$password_highlight = INPUT_ERROR_STYLE;
break;
default: // input is valid
$this->Query("INSERT INTO ".$this->config['table_prefix']."users SET ".
"signuptime = now(), ".
"name = '".mysql_real_escape_string($name)."', ".
"email = '".mysql_real_escape_string($email)."', ".
"password = md5('".mysql_real_escape_string($_POST['password'])."')");
// Send mail to new user if requested
if ( $email_new_user )
{
mail( $email, EMAIL_SUBJECT, EMAIL_BODY . $name . "/" . $_POST['password'] );
}
// forward
$params .= 'added=true';
$this->Redirect($url.$params);
}
}
// display Add User form
echo $this->FormOpen();
?>
<input type="hidden" name="action" value="adduser" />
<fieldset>
<legend><?php echo ADD_USER_HEADING ?></legend>
<table class="usersettings">
<?php
// create confirmation message if needed
switch(TRUE)
{
case (isset($_GET['added']) && $_GET['added'] == 'true'):
$success = ADD_SUCCEEDED;
break;
}
// display error or confirmation message
switch(TRUE)
{
case (isset($error)):
echo '<tr><td></td><td><em class="error">'.$this->Format($error).'</em></td></tr>'."\n";
break;
case (isset($success)):
echo '<tr><td></td><td><em class="success">'.$this->Format($success).'</em></td></tr>'."\n";
break;
default:
}
?>
<tr>
<td align="right"><?php echo WIKINAME_LABEL ?></td>
<td><input <?php echo $username_highlight; ?> name="name" size="40" value="<?php echo $this->GetSafeVar('name', 'post'); ?>" /></td>
</tr>
<tr>
<td align="right"><?php echo USER_EMAIL_LABEL ?></td>
<td><input <?php echo $email_highlight; ?> name="email" size="40" value="" /></td>
</tr>
<tr>
<td align="right"><?php echo sprintf(PASSWORD_LABEL, PASSWORD_MIN_LENGTH) ?></td>
<td><input name="password" size="40" /></td>
</tr>
<tr>
<td align="right"><?php echo EMAIL_NEW_USER_LABEL ?></td>
<td><input type="hidden" name="email_new_user" value="N" /><input type="checkbox" name="email_new_user" value="Y" <?php echo $email_new_user == 'Y' ? 'checked="checked"' : '' ?> /></td>
</tr>
<tr>
<td> </td>
<td><input name="submit" type="submit" value="<?php echo ADD_USER_BUTTON_LABEL ?>" size="40" /></td>
</tr>
</table>
</fieldset>
<?php
echo $this->FormClose(); //close user settings form
}
?>
/**
* Display a module for adding a user.
*
* This action allows users to be added (preferably by admins). As a result, a wiki
* can be configured for use by invitation only by setting allow_user_registration
* to zero and placing this action on an admin- or member-restricted page.
*/
// defaults
if (!defined('PASSWORD_MIN_LENGTH')) define('PASSWORD_MIN_LENGTH', "5");
if (!defined('VALID_EMAIL_PATTERN')) define('VALID_EMAIL_PATTERN', "/^.+?\@.+?\..+$/"); //TODO: Use central regex library
if (!defined('INPUT_ERROR_STYLE')) define('INPUT_ERROR_STYLE', 'class="highlight"');
// i18n strings
// General
if (!defined('ADD_USER_HEADING')) define('ADD_USER_HEADING', "Add new user");
if (!defined('ADD_USER_BUTTON_LABEL')) define('ADD_USER_BUTTON_LABEL', "Add User");
if (!defined('ADD_SUCCEEDED')) define('ADD_SUCCEEDED', "User has been added!");
if (!defined('EMAIL_SUBJECT')) define('EMAIL_SUBJECT', "User has been added!");
if (!defined('EMAIL_BODY')) define('EMAIL_BODY', "A wiki account has been created for you at " . $this->config['base_url'] . ". Your username/password are: ");
// GUI Labels
if (!defined('WIKINAME_LABEL')) define('WIKINAME_LABEL', "New user's <abbr title=\"A WikiName is formed by two or more capitalized words without space, e.g. JohnDoe\">WikiName</abbr>:");
if (!defined('USER_EMAIL_LABEL')) define('USER_EMAIL_LABEL', "User's email address:");
if (!defined('PASSWORD_LABEL')) define('PASSWORD_LABEL', "Password (%s+ chars):");
if (!defined('EMAIL_NEW_USER_LABEL')) define('EMAIL_NEW_USER_LABEL', "Send welcome email:");
// Validation Errors - General
if(!defined('ERROR_VALIDATION_FAILED')) define('ERROR_VALIDATION_FAILED', "Registration validation failed, please try again!");
// ...Validation Errors - Username
if (!defined('ERROR_EMPTY_USERNAME')) define('ERROR_EMPTY_USERNAME', "Please fill in your user name.");
if (!defined('ERROR_USERNAME_EXISTS')) define('ERROR_USERNAME_EXISTS', "Sorry, this user name already exists.");
if (!defined('ERROR_WIKINAME')) define('ERROR_WIKINAME', "Username must be formatted as a ##\"\"WikiName\"\"##, e.g. ##\"\"JohnDoe\"\"##.");
if (!defined('ERROR_RESERVED_PAGENAME')) define('ERROR_RESERVED_PAGENAME', "Sorry, this name is reserved for a page. Please choose a different name.");
// ...Validation Errors - Email
if (!defined('ERROR_EMAIL_ADDRESS_REQUIRED')) define('ERROR_EMAIL_ADDRESS_REQUIRED', "Please specify an email address.");
if (!defined('ERROR_INVALID_EMAIL_ADDRESS')) define('ERROR_INVALID_EMAIL_ADDRESS', "That doesn't quite look like an email address.");
// ...Validation Errors - Password
if (!defined('ERROR_EMPTY_PASSWORD')) define('ERROR_EMPTY_PASSWORD', "Please fill in a password.");
if (!defined('ERROR_NO_BLANK')) define('ERROR_NO_BLANK', "Sorry, blanks are not permitted in the password.");
if (!defined('ERROR_PASSWORD_TOO_SHORT')) define('ERROR_PASSWORD_TOO_SHORT', "Sorry, the password must contain at least %s characters.");
//initialize variables
$url = '';
$params = '';
$username = '';
$email = '';
$password = '';
$username_highlight = '';
$email_highlight = '';
$password_highlight = '';
// Create URAuth object
include_once('libs/userregistration.class.php');
$urobj = new URAuth($this);
//create URL
$url = $this->config['base_url'].$this->tag;
// append URL params depending on rewrite_mode
$params = ($this->config['rewrite_mode'] == 1) ? '?' : '&';
$regex_referrer = '@^'.preg_quote($this->config['base_url'], '@').'([^\/\?&]*)@i';
if (isset($_SERVER['HTTP_REFERER']) && preg_match($regex_referrer, $_SERVER['HTTP_REFERER'], $match))
{
if (strcasecmp($this->tag, $match[1]))
{
$_SESSION['go_back'] = $_SERVER['HTTP_REFERER'];
//We save the tag of the referring page, this tag is to be shown in label <Go back to ...>. We must use a session here because if the user
//Refresh the page by hitting <Enter> on the address bar, the value would be lost.
$_SESSION['go_back_tag'] = $match[1];
}
}
// User must be logged in
if ($user = $this->GetUser() )
{
// validate data source
$keep_post_data = FALSE;
if (isset($_POST['form_id']) && FALSE != ($aKey = $this->getSessionKey($_POST['form_id']))) # check if page key was stored in session
{
if (TRUE == ($rc = $this->hasValidSessionKey($aKey))) # check if correct name,key pair was passed
{
$keep_post_data = TRUE;
}
}
if(!$keep_post_data) unset($_POST);
// is user trying to add a user?
if (isset($_POST['action']) && ($_POST['action'] == 'adduser'))
{
// get POST parameters
$name = trim($_POST['name']);
$email = trim($this->GetSafeVar('email', 'post'));
$password = $_POST['password'];
$email_new_user = $this->GetSafeVar('email_new_user', 'post');
// validate form input
switch (TRUE)
{
// Validate the NAME
case (FALSE===$urobj->URAuthVerify()):
$error = ERROR_VALIDATION_FAILED;
break;
case (strlen($name) == 0):
$error = ERROR_EMPTY_USERNAME;
$username_highlight = INPUT_ERROR_STYLE;
break;
case (isset($_POST['name']) && $existingUser = $this->LoadUser($_POST['name'])):
$error = ERROR_USERNAME_EXISTS;
$username_highlight = INPUT_ERROR_STYLE;
break;
case (!$this->IsWikiName($name)):
$error = ERROR_WIKINAME;
$username_highlight = INPUT_ERROR_STYLE;
break;
case ($this->existsPage($name,NULL,NULL,FALSE)): // name change, new interface (check for non-active page, too)
$error = ERROR_RESERVED_PAGENAME;
$username_highlight = INPUT_ERROR_STYLE;
break;
// Valide EMAIL
case (strlen($email) == 0): //email is empty
$error = ERROR_EMAIL_ADDRESS_REQUIRED;
$email_highlight = INPUT_ERROR_STYLE;
break;
case (!preg_match(VALID_EMAIL_PATTERN, $email)): //invalid email
$error = ERROR_INVALID_EMAIL_ADDRESS;
$email_highlight = INPUT_ERROR_STYLE;
break;
// Validate PASSWORD
case (strlen($password) == 0):
$passerror = ERROR_EMPTY_PASSWORD;
$password_highlight = INPUT_ERROR_STYLE;
break;
case (preg_match("/ /", $password)):
$passerror = ERROR_NO_BLANK;
$password_highlight = INPUT_ERROR_STYLE;
break;
case (strlen($password) < PASSWORD_MIN_LENGTH):
$passerror = sprintf(ERROR_PASSWORD_TOO_SHORT, PASSWORD_MIN_LENGTH);
$password_highlight = INPUT_ERROR_STYLE;
break;
default: // input is valid
$this->Query("INSERT INTO ".$this->config['table_prefix']."users SET ".
"signuptime = now(), ".
"name = '".mysql_real_escape_string($name)."', ".
"email = '".mysql_real_escape_string($email)."', ".
"password = md5('".mysql_real_escape_string($_POST['password'])."')");
// Send mail to new user if requested
if ( $email_new_user )
{
mail( $email, EMAIL_SUBJECT, EMAIL_BODY . $name . "/" . $_POST['password'] );
}
// forward
$params .= 'added=true';
$this->Redirect($url.$params);
}
}
// display Add User form
echo $this->FormOpen();
?>
<input type="hidden" name="action" value="adduser" />
<fieldset>
<legend><?php echo ADD_USER_HEADING ?></legend>
<table class="usersettings">
<?php
// create confirmation message if needed
switch(TRUE)
{
case (isset($_GET['added']) && $_GET['added'] == 'true'):
$success = ADD_SUCCEEDED;
break;
}
// display error or confirmation message
switch(TRUE)
{
case (isset($error)):
echo '<tr><td></td><td><em class="error">'.$this->Format($error).'</em></td></tr>'."\n";
break;
case (isset($success)):
echo '<tr><td></td><td><em class="success">'.$this->Format($success).'</em></td></tr>'."\n";
break;
default:
}
?>
<tr>
<td align="right"><?php echo WIKINAME_LABEL ?></td>
<td><input <?php echo $username_highlight; ?> name="name" size="40" value="<?php echo $this->GetSafeVar('name', 'post'); ?>" /></td>
</tr>
<tr>
<td align="right"><?php echo USER_EMAIL_LABEL ?></td>
<td><input <?php echo $email_highlight; ?> name="email" size="40" value="" /></td>
</tr>
<tr>
<td align="right"><?php echo sprintf(PASSWORD_LABEL, PASSWORD_MIN_LENGTH) ?></td>
<td><input name="password" size="40" /></td>
</tr>
<tr>
<td align="right"><?php echo EMAIL_NEW_USER_LABEL ?></td>
<td><input type="hidden" name="email_new_user" value="N" /><input type="checkbox" name="email_new_user" value="Y" <?php echo $email_new_user == 'Y' ? 'checked="checked"' : '' ?> /></td>
</tr>
<tr>
<td> </td>
<td><input name="submit" type="submit" value="<?php echo ADD_USER_BUTTON_LABEL ?>" size="40" /></td>
</tr>
</table>
</fieldset>
<?php
echo $this->FormClose(); //close user settings form
}
?>
CategoryUserContributions