Commit 90dcbbe2 authored by Leigh Stoller's avatar Leigh Stoller

Okay, I think I am finally done with WikiWhacking (or WhackingTheWiki?)

for the near future. Two big changes:

* Add WikiOnly accounts. An external user can register for an account on
  the wiki. Rather then use the registration stuff that comes with TWiki,
  redirect to new Emulab web page so we can manage all of the wiki accounts
  from one place. I modified the joinproject page to spit out a subset of
  the required fields so that its simple to get a wiki only account (just a
  few things to fill in).

  In keeping with current security practices, we still generate a
  verification email message to ensure the email address works. However,
  when the user completes the verification, the wiki account is created right
  away, rather then waiting for someone to approve it (since that would
  defeat the entire point of the wiki).

  Aside: I have not thought much about the conversion from a wiki-only
  account to a real account. That is going to happen, and it would be nice
  if that step did not require one of use to go in and hack the DB. Will
  cross that moat later.

  Aside: Rather beat up on the modify user info page too much, I continue
  to spit out the same form, but mark most of the fields as not required,
  and allow wiki-only people to not specify them.

* Both the joinproject and newproject pages sport a new WikiName field so
  that users can select their own WikiName. I added some JavaScript to
  both pages that generate a suitable wikiname from the FullName field, so
  that as soon as the user clicks out of the FullName, a default wikiname is
  inserted in the field.

  Both pages verify the wikinames by checking to make sure it is not
  already in use, and that it meets the WikiRules for WikiTopic names.
  (someone please shoot me if I continue to use WikiNotation).
parent 1b22ebcc
......@@ -58,6 +58,7 @@ ifeq ($(EVENTSYS),1)
endif
@$(MAKE) -C mote post-install
@$(MAKE) -C tools post-install
@$(MAKE) -C wiki post-install
#
# For installation on the 'ops' or 'users' node (okay, plastic)
......
......@@ -167,7 +167,8 @@ if (AuditStart(0)) {
#
$query_result =
DBQueryFatal("select u.usr_pswd,u.unix_uid,u.usr_name, ".
" u.usr_email,u.status,u.webonly,u.usr_shell,admin,u.usr_w_pswd ".
" u.usr_email,u.status,u.webonly,u.usr_shell,admin, ".
" u.usr_w_pswd,u.wikionly ".
"from users as u ".
"where u.uid='$user'");
......@@ -184,6 +185,7 @@ my $webonly = $row[5];
my $usr_shell = $row[6];
my $usr_admin = $row[7];
my $wpswd = $row[8];
my $wikionly = $row[9];
#
# Get the users earliest project membership to use as the default group
......@@ -273,10 +275,20 @@ sub AddUser()
#
# Check status. Only active users get accounts built.
#
if ($webonly || $status ne USERSTATUS_ACTIVE) {
if ($webonly || $wikionly || $status ne USERSTATUS_ACTIVE) {
if ($webonly) {
return 0;
}
if ($wikionly) {
$EUID = $UID;
# And to the wiki if enabled.
system("$ADDWIKIUSER $user")
if ($WIKISUPPORT && !$batch);
$EUID = 0;
return 0;
}
fatal("$user is not active! Cannot build an account!");
}
......
......@@ -5,7 +5,7 @@ area for your project (or group). If you are not familiar with the
information on how to write and create TWiki pages.
* YourFirstWikiTopic (See TWiki.WikiTopic for a brief description)
*
*
__This project wiki can be accessed externally as:__ [[%SCRIPTURL%/view/%WEB%][%SCRIPTURL%/view/%WEB%]]
......
......@@ -200,6 +200,10 @@ function TBvalid_usrname($token) {
return TBcheck_dbslot($token, "users", "usr_name",
TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR);
}
function TBvalid_wikiname($token) {
return TBcheck_dbslot($token, "users", "wikiname",
TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR);
}
function TBvalid_email($token) {
return TBcheck_dbslot($token, "users", "usr_email",
TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR);
......
......@@ -863,6 +863,21 @@ function TBCurrentUser($uid)
return mysql_num_rows($query_result);
}
#
# Confirm a current WikiName or not.
#
# usage TBCurrentWikiName($uid)
# returns 1 if a current wikiname.
# returns 0 if not a current wikiname
#
function TBCurrentWikiName($wikiname)
{
$query_result =
DBQueryFatal("SELECT usr_pswd FROM users WHERE wikiname='$wikiname'");
return mysql_num_rows($query_result);
}
#
# Check to see if an email is being used twice.
#
......@@ -1502,6 +1517,14 @@ function TBCvswebAllowed($uid) {
return mysql_num_rows($query_result);
}
function TBWikiOnlyUser($uid) {
$query_result =
DBQueryFatal("select wikionly from users ".
"WHERE uid='$uid' and wikionly=1");
return mysql_num_rows($query_result);
}
#
# Returns > 0 if a node has a serial console, 0 if it does not
#
......
This diff is collapsed.
......@@ -357,10 +357,18 @@ function WRITESIDEBAR() {
WRITESIDEBARBUTTON("Change Your Password",
$TBBASE, "moduserinfo.php3");
}
elseif ($login_status & CHECKLOGIN_WEBONLY) {
elseif ($login_status & CHECKLOGIN_WEBONLY|CHECKLOGIN_WIKIONLY) {
WRITESIDEBARBUTTON("My Emulab",
$TBBASE,
"showuser.php3?target_uid=$login_uid");
if ($WIKISUPPORT && $CHECKLOGIN_WIKINAME != "") {
$wikiname = $CHECKLOGIN_WIKINAME;
WRITESIDEBARBUTTON_ABSCOOL("My Wikis",
"${WIKIURL}/Main/$wikiname",
"${WIKIURL}/Main/$wikiname");
}
WRITESIDEBARBUTTON("Update User Information",
$TBBASE, "moduserinfo.php3");
......
This diff is collapsed.
......@@ -52,7 +52,8 @@ function SPITFORM($formfields, $returning, $errors)
global $TBDB_UIDLEN, $TBDB_PIDLEN, $TBDOCBASE, $WWWHOST;
global $usr_keyfile;
global $ACCOUNTWARNING, $EMAILWARNING;
global $WIKISUPPORT, $WIKIURL;
PAGEHEADER("Start a New Testbed Project");
echo "<center><font size=+1>
......@@ -92,6 +93,34 @@ function SPITFORM($formfields, $returning, $errors)
}
echo "</table><br>\n";
}
echo "<SCRIPT LANGUAGE=JavaScript>
function SetWikiName(theform)
{
var validchars = 'abcdefghijklmnopqrstuvwxyz0123456789';
var usrname = theform['formfields[usr_name]'].value;
var wikiname = '';
var docap = 1;
for (var i = 0; i < usrname.length; i++) {
var letter = usrname.charAt(i).toLowerCase();
if (validchars.indexOf(letter) == -1) {
if (letter == ' ') {
docap = 1;
}
continue;
}
else {
if (docap == 1) {
letter = usrname.charAt(i).toUpperCase()
docap = 0;
}
wikiname = wikiname + letter;
}
}
theform['formfields[wikiname]'].value = wikiname;
}
</SCRIPT>\n";
echo "<table align=center border=1>
<tr>
......@@ -100,7 +129,7 @@ function SPITFORM($formfields, $returning, $errors)
</td>
</tr>\n
<form enctype=multipart/form-data
<form enctype=multipart/form-data name=myform
action=newproject.php3 method=post>\n";
if (! $returning) {
......@@ -141,10 +170,27 @@ function SPITFORM($formfields, $returning, $errors)
<input type=text
name=\"formfields[usr_name]\"
value=\"" . $formfields[usr_name] . "\"
onchange=\"SetWikiName(myform);\"
size=30>
</td>
</tr>\n";
#
# WikiName
#
if ($WIKISUPPORT) {
echo "<tr>
<td colspan=2>*
<a href=${WIKIURL}/TWiki/WikiName
target=_blank>WikiName</a>:<td class=left>
<input type=text
name=\"formfields[wikiname]\"
value=\"" . $formfields[wikiname] . "\"
size=30>
</td>
</tr>\n";
}
#
# Title/Position:
#
......@@ -592,7 +638,18 @@ if (! $returning) {
if (count($tokens) < 2) {
$errors["Full Name"] = "Please provide a first and last name";
}
if ($WIKISUPPORT) {
if (!isset($formfields[wikiname]) ||
strcmp($formfields[wikiname], "") == 0) {
$errors["WikiName"] = "Missing Field";
}
elseif (! TBvalid_wikiname($formfields[wikiname])) {
$errors["WikiName"] = TBFieldErrorString();
}
elseif (TBCurrentWikiName($formfields[wikiname])) {
$errors["WikiName"] = "Already in use. Pick another";
}
}
if (!isset($formfields[usr_affil]) ||
strcmp($formfields[usr_affil], "") == 0) {
$errors["Affiliation"] = "Missing Field";
......@@ -795,6 +852,7 @@ if (!$returning) {
$usr_phone = $formfields[usr_phone];
$password1 = $formfields[password1];
$password2 = $formfields[password2];
$wikiname = ($WIKISUPPORT ? $formfields[wikiname] : "");
$usr_returning = "No";
if (! isset($formfields[usr_URL]) ||
......@@ -891,6 +949,7 @@ else {
$usr_country = $row[usr_country];
$usr_phone = $row[usr_phone];
$usr_URL = $row[usr_URL];
$wikiname = $row[wikiname];
$usr_returning = "Yes";
}
$pid = $formfields[pid];
......@@ -954,14 +1013,14 @@ if (! $returning) {
"(uid,usr_created,usr_expires,usr_name,usr_email,usr_addr,".
" usr_addr2,usr_city,usr_state,usr_zip,usr_country, ".
" usr_URL,usr_title,usr_affil,usr_phone,usr_shell,usr_pswd,unix_uid,".
" status,pswd_expires,usr_modified) ".
" status,pswd_expires,usr_modified,wikiname) ".
"VALUES ('$proj_head_uid', now(), '$proj_expires', '$usr_name', ".
"'$usr_email', ".
"'$usr_addr', '$usr_addr2', '$usr_city', '$usr_state', '$usr_zip', ".
"'$usr_country', ".
"'$usr_URL', '$usr_title', '$usr_affil', ".
"'$usr_phone', 'tcsh', '$encoding', NULL, 'newuser', ".
"date_add(now(), interval 1 year), now())");
"date_add(now(), interval 1 year), now(), '$wikiname')");
DBQueryFatal("INSERT INTO user_stats (uid) VALUES ('$proj_head_uid')");
......
<?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2004 University of Utah and the Flux Group.
# Copyright (c) 2000-2005 University of Utah and the Flux Group.
# All rights reserved.
#
include("defs.php3");
......@@ -11,7 +11,8 @@ include("showstuff.php3");
# Only known and logged in users can do this.
#
$uid = GETLOGIN();
LOGGEDINORDIE($uid, CHECKLOGIN_USERSTATUS|CHECKLOGIN_WEBONLY);
LOGGEDINORDIE($uid, CHECKLOGIN_USERSTATUS|
CHECKLOGIN_WEBONLY|CHECKLOGIN_WIKIONLY);
$isadmin = ISADMIN($uid);
#
......@@ -39,6 +40,7 @@ else {
if (! ($userstatus = TBUserStatus($target_uid))) {
USERERROR("The user $target_uid is not a valid user", 1);
}
$wikionly = TBWikiOnlyUser($target_uid);
#
# Verify that this uid is a member of one of the projects that the
......@@ -178,7 +180,7 @@ SUBMENUSTART("User Options");
#
WRITESUBMENUBUTTON("Edit Profile", "moduserinfo.php3?target_uid=$target_uid");
if ($isadmin || !strcmp($uid, $target_uid)) {
if (!$wikionly && ($isadmin || !strcmp($uid, $target_uid))) {
WRITESUBMENUBUTTON("Edit SSH Keys",
"showpubkeys.php3?target_uid=$target_uid");
WRITESUBMENUBUTTON("Edit SFS Keys",
......
......@@ -44,6 +44,7 @@ define("CHECKLOGIN_ADMINOFF", 0x020000);
define("CHECKLOGIN_WEBONLY", 0x040000);
define("CHECKLOGIN_PLABUSER", 0x080000);
define("CHECKLOGIN_STUDLY", 0x100000);
define("CHECKLOGIN_WIKIONLY", 0x200000);
#
# Constants for tracking possible login attacks.
......@@ -151,7 +152,8 @@ function CHECKLOGIN($uid) {
$query_result =
DBQueryFatal("select NOW()>=u.pswd_expires,l.hashkey,l.timeout, ".
" status,admin,cvsweb,g.trust,adminoff,webonly, " .
" user_interface,n.type,u.stud,u.wikiname " .
" user_interface,n.type,u.stud,u.wikiname, ".
" u.wikionly " .
" from users as u ".
"left join login as l on l.uid=u.uid ".
"left join group_membership as g on g.uid=u.uid ".
......@@ -189,6 +191,7 @@ function CHECKLOGIN($uid) {
$type = $row[10];
$stud = $row[11];
$wikiname = $row[12];
$wikionly = $row[13];
$CHECKLOGIN_NODETYPES[$type] = 1;
}
......@@ -296,6 +299,8 @@ function CHECKLOGIN($uid) {
$CHECKLOGIN_STATUS |= CHECKLOGIN_ADMINOFF;
if ($webonly)
$CHECKLOGIN_STATUS |= CHECKLOGIN_WEBONLY;
if ($wikionly)
$CHECKLOGIN_STATUS |= CHECKLOGIN_WIKIONLY;
if ($trusted)
$CHECKLOGIN_STATUS |= CHECKLOGIN_TRUSTED;
if ($stud)
......@@ -390,6 +395,8 @@ function LOGGEDINORDIE($uid, $modifier = 0, $login_url = NULL) {
USERERROR("Your account has not been approved yet!", 1);
if (($status & CHECKLOGIN_WEBONLY) && ! ISADMIN($uid))
USERERROR("Your account does not permit you to access this page!", 1);
if (($status & CHECKLOGIN_WIKIONLY) && ! ISADMIN($uid))
USERERROR("Your account does not permit you to access this page!", 1);
#
# Lastly, check for nologins here. This heads off a bunch of other
......@@ -434,6 +441,19 @@ function STUDLY() {
(CHECKLOGIN_LOGGEDIN|CHECKLOGIN_STUDLY));
}
function WIKIONLY() {
global $CHECKLOGIN_STATUS;
if ($CHECKLOGIN_STATUS == CHECKLOGIN_NOSTATUS) {
$uid=GETUID();
TBERROR("WIKIONLY: $uid is not logged in!", 1);
}
return (($CHECKLOGIN_STATUS &
(CHECKLOGIN_LOGGEDIN|CHECKLOGIN_WIKIONLY)) ==
(CHECKLOGIN_LOGGEDIN|CHECKLOGIN_WIKIONLY));
}
# Is this user a real administrator (ignore onoff bit).
function ISADMINISTRATOR() {
global $CHECKLOGIN_STATUS;
......@@ -823,16 +843,18 @@ function LASTWEBLOGIN($uid) {
function HASREALACCOUNT($uid) {
$query_result =
DBQueryFatal("select status,webonly from users where uid='$uid'");
DBQueryFatal("select status,webonly,wikionly from users ".
"where uid='$uid'");
if (!mysql_num_rows($query_result)) {
return 0;
}
$row = mysql_fetch_array($query_result);
$status = $row[0];
$webonly = $row[1];
$status = $row[0];
$webonly = $row[1];
$wikionly = $row[2];
if ($webonly ||
if ($webonly || $wikionly ||
(strcmp($status, TBDB_USERSTATUS_ACTIVE) &&
strcmp($status, TBDB_USERSTATUS_FROZEN))) {
return 0;
......
<?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2003 University of Utah and the Flux Group.
# Copyright (c) 2000-2003, 2005 University of Utah and the Flux Group.
# All rights reserved.
#
include("defs.php3");
......@@ -16,7 +16,8 @@ PAGEHEADER("Confirm Verification");
#
$uid = GETLOGIN();
LOGGEDINORDIE($uid,
CHECKLOGIN_UNVERIFIED|CHECKLOGIN_NEWUSER|CHECKLOGIN_WEBONLY);
CHECKLOGIN_UNVERIFIED|CHECKLOGIN_NEWUSER|
CHECKLOGIN_WEBONLY|CHECKLOGIN_WIKIONLY);
#
# Must provide the key!
......@@ -30,12 +31,14 @@ if (!isset($key) || strcmp($key, "") == 0) {
# Grab the status and do the modification.
#
$query_result =
DBQueryFatal("select status from users where uid='$uid'");
DBQueryFatal("select status,wikionly from users ".
"where uid='$uid'");
if (($row = mysql_fetch_row($query_result)) == 0) {
TBERROR("Database Error retrieving status for $uid!", 1);
}
$status = $row[0];
$status = $row[0];
$wikionly = $row[1];
#
# No multiple verifications!
......@@ -216,24 +219,50 @@ if (strcmp($status, TBDB_USERSTATUS_UNVERIFIED) == 0) {
"that are now available to you will appear.\n";
}
elseif (strcmp($status, TBDB_USERSTATUS_NEWUSER) == 0) {
DBQueryFatal("update users set status='unapproved' where uid='$uid'");
$newstatus = ($wikionly ? "active" : "unapproved");
DBQueryFatal("update users set status='$newstatus' where uid='$uid'");
TBMAIL($TBMAIL_AUDIT,
"User '$uid' has been verified",
"\n".
"User '$uid' has been verified.\n".
"Status has been changed from 'newuser' to 'unapproved'\n".
"Status has been changed from 'newuser' to '$newstatus'\n".
"\n".
"Testbed Operations\n",
"From: $TBMAIL_OPS\n".
"Errors-To: $TBMAIL_WWW");
INFORMLEADERS($uid);
if ($wikionly) {
#
# For wikionly accounts, build the account now.
# Just builds the wiki account of course (nothing else).
#
SUEXEC("nobody", $TBADMINGROUP, "webtbacct add $uid",
SUEXEC_ACTION_DIE);
echo "<p>".
"You have now been verified. However, your application ".
"has not yet been approved. You will receive ".
"email when that has been done.\n";
#
# The backend sets the actual WikiName
#
$query_result =
DBQueryFatal("select wikiname from users where uid='$uid'");
if (($row = mysql_fetch_row($query_result)) == 0) {
TBERROR("Database Error retrieving status for $uid!", 1);
}
$wikiname = $row[0];
echo "You have been verified. You may now access the Wiki at<br>".
"<a href='$WIKIURL/$wikiname'>$WIKIURL/$wikiname</a>\n";
}
else {
INFORMLEADERS($uid);
echo "<p>".
"You have now been verified. However, your application ".
"has not yet been approved. You will receive ".
"email when that has been done.\n";
}
}
else {
TBERROR("Bad user status '$status' for $uid!", 1);
......
<?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2002 University of Utah and the Flux Group.
# Copyright (c) 2000-2002, 2005 University of Utah and the Flux Group.
# All rights reserved.
#
include("defs.php3");
......@@ -16,7 +16,8 @@ PAGEHEADER("New User Verification");
#
$uid = GETLOGIN();
LOGGEDINORDIE($uid,
CHECKLOGIN_UNVERIFIED|CHECKLOGIN_NEWUSER|CHECKLOGIN_WEBONLY);
CHECKLOGIN_UNVERIFIED|CHECKLOGIN_NEWUSER|
CHECKLOGIN_WEBONLY|CHECKLOGIN_WIKIONLY);
echo "<p>
The purpose of this page is to verify, for security purposes, that
......
<?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2003, 2005 University of Utah and the Flux Group.
# All rights reserved.
#
$forwikionly = 1;
include("joinproject.php3");
?>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment