wikisetup.in 6.69 KB
Newer Older
1 2
#!/usr/bin/perl -w
#
3
# Copyright (c) 2005, 2010 University of Utah and the Flux Group.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
#
use English;
use Getopt::Std;

#
# Initial wiki setup. Create wiki accounts for all users and projects.
#
sub usage()
{
    print STDOUT "Usage: wikisetup\n";
    exit(-1);
}
my $optlist  = "d";
my $debug    = 0;
my $impotent = 0;

#
# Configure variables
#
my $TB		= "@prefix@";
my $TBOPS       = "@TBOPSEMAIL@";
my $CONTROL     = "@USERNODE@";
my $BOSSNODE	= "@BOSSNODE@";
my $WIKISUPPORT = @WIKISUPPORT@;
my $SSH         = "$TB/bin/sshtb";
my $WIKIPROXY   = "$TB/sbin/wikiproxy";
my $ADDWIKIUSER = "$TB/sbin/addwikiuser";
my $ADDWIKIPROJ = "$TB/sbin/addwikiproj";
my $SETWIKIGROUPS = "$TB/sbin/setwikigroups";

#
# Untaint the path
# 
$ENV{'PATH'} = "/bin:/usr/bin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

#
# Turn off line buffering on output
#
$| = 1;

#
# Load the Testbed support stuff. 
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;

#
# If no wiki support, just exit. 
#
if (! $WIKISUPPORT) {
    print "WIKI support is not enabled. Exit ...\n";
    exit(0);
}

#
# Only testbed admins.
#
if (!TBAdmin($UID)) {
    die("*** $0:\n".
	"    Must be a testbed admin to run this script\n");
}

#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
%options = ();
if (! getopts($optlist, \%options)) {
    usage();
}
if (defined($options{"d"})) {
    $debug = 1;
}
if (@ARGV) {
    usage();
}

my %wikipids   = ();	# Indexed by pid, gives wikiname.
my %wikinames  = ();	# Indexed by wikiname.

#
# Attempt to form unique wiki IDs for all users and projects. What a
# pain in the ass this is going to be.
#
# First the projects. Only main group.
#
$query_result =
    DBQueryFatal("select pid from groups where pid=gid ".
113 114 115
#		 "and (pid='testbed' or pid='emulab-ops' or pid='tbres' or ".
#		 "     pid='utahstud')" .
		 "");
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180

while (my ($pid) = $query_result->fetchrow_array()) {
    #
    # The wikirules for web names are slightly easier to deal with.
    # Note that there will also be a *Group name created from the token.
    #
    my $wikiname = ucfirst($pid);

    if ($wikiname =~ /[-_]/) {
	my @tokens = split(/[-_]/, $wikiname);

	$wikiname = "";

	#
	# Make sure the first letter of each token is a caps.
	# 
	foreach my $token (@tokens) {
	    $wikiname .= ucfirst($token);
	}
    }

    #
    # Check to make sure the wikiname does not violate the wikirules!
    # If it does, just skip. User will have to plug in a new name.
    #
    if (! ($wikiname =~ /^[A-Z]+[A-Za-z0-9]*$/)) {
	print "Bad WikiName for Project $pid: $wikiname\n";
	next;
    }

    #
    # We are not likely to get dups for a project name, but make sure
    # anyway.
    #
    if (exists($wikinames{$wikiname})) {
	my $other_pid   = $wikinames{$wikiname};

	print "Duplicate WikiName for Project: $wikiname $pid $other_pid\n";
	next;
    }
    $wikipids{$pid} = $wikiname;
}
#
# Now we are going to loop over the names, insert them into the DB, and
# then call addwikiuser to actually do the work over on ops.
#
foreach my $pid (keys(%wikipids)) {
    my $wikiname = $wikipids{$pid};

    print "Creating Wiki for project $pid ($wikiname)\n"
	if ($debug);

    if (!$impotent) {
	DBQueryFatal("update groups set wikiname='$wikiname' ".
		     "where pid='$pid' and pid=gid");

	system("$ADDWIKIPROJ $pid") == 0
	    or fatal("Could not add wiki web for $pid ($wikiname)");
    }
}

#
# Now the users.
# 
$query_result =
181
    DBQueryFatal("select distinct g.uid,u.uid_idx,u.usr_name,u.usr_email,u.wikiname ".
182
		 "  from group_membership as g ".
183
		 "left join users as u on u.uid_idx=g.uid_idx ".
184 185 186 187
		 "where u.status='active' ".
#		 "  and (g.pid='testbed' or g.pid='emulab-ops' or ".
#		 "       g.pid='tbres' or g.pid='utahstud')" .
		 "order by u.admin");
188

189 190
my %wikiuids   = ();	# Indexed by user uid_idx, gives wikiname.
my %emailaddrs = ();	# Indexed by user uid_idx, gives user email address.
191 192 193
# Clear this for next loop.
%wikinames = ();

194
while (my ($uid,$idx,$name,$email,$wikiname) = $query_result->fetchrow_array()) {
195 196
    $emailaddrs{$uid} = $email;

197 198 199 200 201
    if (!defined($wikiname) || $wikiname eq "") {
	#
	# Split the user name up into tokens. 
	#
	my @tokens = split(/\s+|-/, $name);
202

203 204 205 206 207 208
	#
	# Build a wikiname from the tokens. Lowercase each token, then
	# captialize it, then run them all together. Oh, get rid of any
	# non alphanum characters.
	#
	$wikiname = "";
209

210 211 212 213 214
	foreach my $token (@tokens) {
	    $token = ucfirst(lc($token));
	    $token =~ s/\.//g;
	    $wikiname .= $token;
	}
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
    }
    #print "$wikiname\n";

    #
    # Check to make sure the wikiname does not violate the wikirules!
    # If it does, just skip. User will have to plug in a new name.
    #
    if (! ($wikiname =~ /^[A-Z]+[a-z]+[A-Z]+[A-Za-z0-9]*$/)) {
	print "Bad WikiName: $wikiname \n";
	next;
    }
    #
    # Look to see if this wikiname exists. If it does, and the email
    # address is the same, then fine. If the email address is different,
    # then that is a problem. Skip.
    #
    if (exists($wikinames{$wikiname})) {
	my $other_uid   = $wikinames{$wikiname};
	my $other_email = $emailaddrs{$other_uid};

	if ($email ne $other_email) {
	    print "Duplicate WikiName: $wikiname $uid $other_uid\n";
	    next;
	}
    }
    $wikinames{$wikiname} = $uid;
241 242
    $wikiuids{$idx}       = [$uid, $wikiname];
    $emailaddrs{$idx}     = $email;
243 244 245 246 247 248
}

#
# Now we are going to loop over the names, insert them into the DB, and
# then call addwikiuser to actually do the work over on ops.
#
249 250
foreach my $idx (keys(%wikiuids)) {
    my ($uid, $wikiname) = @{ $wikiuids{$idx} };
251 252 253 254 255 256

    print "Creating Wiki for home page $uid ($wikiname)\n"
	if ($debug);
    
    if (!$impotent) {
	DBQueryFatal("update users set wikiname='$wikiname' ".
257
		     "where uid_idx='$idx'");
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275

	system("$ADDWIKIUSER $uid") == 0
	    or fatal("Could not add wiki account for $uid ($wikiname)");

	system("$SETWIKIGROUPS $uid") == 0
	    or fatal("Could not set wiki groups for $uid ($wikiname)");
    }
}

exit(0);

sub fatal($)
{
    my($mesg) = $_[0];

    die("*** $0:\n".
	"    $mesg\n");
}