#!/usr/bin/perl

=pod

=head1 NAME

make_test_user.pl - Make a test user on a LON-CAPA system to help with automated testing of the web interface

=cut

# The LearningOnline Network
# make_test_user.pl - Make a test user on the LON-CAPA system
#
# $Id: make_test_user.pl,v 1.2 2003/02/03 18:03:52 harris41 Exp $
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#
# YEAR=2002
#
###

=pod

=head1 DESCRIPTION

Automates the steps for creating a test user.  This
program also describes a manual procedure (see below).

These are the steps that are executed on the linux operating system:

=over 4

=item * 

Tests to see if user already exists for LON-CAPA, if so,
then erase user (to start cleanly).

=item *

Creates a linux system user

=item *

Sets password

=item *

Creates a LON-CAPA lonUsers directory for user

=item *

Sets LON-CAPA password mechanism to be "crypt"

=item *

Set roles.hist and roles.db

=back

=cut

print "Making test user ZXQTEST...\n";

# ------------------------------------------------------------------ Am I root?
unless ($< == 0) {
    print "**** ERROR **** You need to run this test as 'root'.\n";
    exit 1;
}

# ---------------------------------------------------- Configure general values

my %perlvar;
$perlvar{'lonUsersDir'}='/home/httpd/lonUsers';

=pod

=head1 OPTIONS

There are no flags to this script.

usage: make_test_user.pl [NAME_EXT] [DOMAIN] 

The password is accepted through standard input.

The first argument specifies
what string to append to "ZXQTEST".
It should consist of only alphanumeric characters.

The second argument specifies the password for the test user
coordinator and should only consist of printable ASCII
characters and be a string of length greater than 5 characters.

=cut

# ----------------------------------------------- So, are we invoked correctly?
# Two arguments or abort
if (@ARGV!=2) {
    die 'usage: make_test_user.pl [USERNAME] [DOMAIN] '."\n".
	'(and password through standard input)'."\n";
}
my ($username,$domain)=(@ARGV); shift @ARGV; shift @ARGV;
$username='ZXQTEST'.$username;
unless ($username=~/^\w+$/ and $username!~/\_/) {
    die 'Username '.$username.' must consist only of alphanumeric characters'.
	"\n";
}
unless ($domain=~/^\w+$/ and $domain!~/\_/) {
    die 'Domain '.$domain.' must consist only of alphanumeric characters'.
	"\n";
}

my $passwd=<>; # read in password from standard input
chomp($passwd);

if (length($passwd)<6 or length($passwd)>30) {
    die 'Password is an unreasonable length.'."\n";
}
my $pbad=0;
foreach (split(//,$passwd)) {if ((ord($_)<32)||(ord($_)>126)){$pbad=1;}}
if ($pbad) {
    die 'Password must consist of standard ASCII characters'."\n";
}

# And does user already exist

my $udpath=propath($domain,$username);
if (-d $udpath) {
    print $username.' is already defined as a LON-CAPA user.'."\n";
    print 'Cleaning up ...'."\n";
    `rm -Rf $udpath`
	if $udpath=~/^\/home\/httpd\/lonUsers\/$domain\/Z\/X\/Q\/ZXQTEST/;
    # SAFETY: must check $udpath above because we are using rm -Rf!!!
}

=pod

=head1 MANUAL PROCEDURE

There are 10 steps to a manual procedure.

You need to decide on three pieces of information
to create a domain coordinator.

 * USERNAME (ZXQTESTkermit, ZXQTESTalbert, ZXQTESTjoe, etc)
 * DOMAIN (should be the same as lonDefDomain in /etc/httpd/conf/access.conf)
 * PASSWORD (don't tell me)

The examples in these instructions will be based
on three example pieces of information:

 * USERNAME=ZXQTEST
 * DOMAIN=103
 * PASSWORD=sesame

You will also need to know your "root" password
and your "www" password.

=over 4

=item 1.

login as root on your Linux system
 [prompt %] su

=cut

=item 3 (as root). enter in a password

 Command: [prompt %] passwd USERNAME
          New UNIX password: PASSWORD
          Retype new UNIX passwd: PASSWORD
 Example: [prompt %] passwd dc103
          New UNIX password: sesame
          Retype new UNIX passwd: sesame

=cut

=pod

=cut

=pod

=item 4. login as user=www

 Command: [prompt %] su www
 Password: WWWPASSWORD

=item 5. (as www). cd /home/httpd/lonUsers

=item 6. (as www) Create user directory for your new user.

 Let U equal first letter of USERNAME
 Let S equal second letter of USERNAME
 Let E equal third letter of USERNAME
 Command: [prompt %] install -d DOMAIN/U/S/E/USERNAME
 Example: [prompt %] install -d 103/Z/X/Q/ZXQTEST

=cut

`install -o www -g www -d $udpath`;

=pod

=item 7. (as www) Enter the newly created user directory.

 Command: [prompt %] cd DOMAIN/U/S/E/USERNAME
 Example: [prompt %] cd 103/Z/X/Q/ZXQTEST

=item 8. (as www). Set your password mechanism to 'internal' 

 Command: [prompt %] echo "internal:$epasswd" > passwd

To determine the value of $epasswd, you should look at the
internals of this perl script, make_test_user.pl.

=cut

my $salt=time;
$salt=substr($salt,6,2);
my $epasswd=crypt($passwd,$salt);
open OUT, ">$udpath/passwd";
print OUT 'internal:'."$epasswd\n";
close OUT;
`chown www:www $udpath/passwd`;

=pod

=item 9. (as www). Make user to be an author:

This will involve manual modification of roles.hist and roles.db.
Please refer to the internals of the make_test_user.pl perl
script.

=cut

use GDBM_File;
my %hash;
        tie(%hash,'GDBM_File',"$udpath/roles.db",
	    &GDBM_WRCREAT,0640);

$hash{'/'.$domain.'/_au'}='au_0_'.time;
open OUT, ">$udpath/roles.hist";
map {
    print OUT $_.' : '.$hash{$_}."\n";
} keys %hash;
close OUT;

untie %hash;
`chown www:www $udpath/roles.hist`;
`chown www:www $udpath/roles.db`;

print "$username is now a test user (author)\n";
my $hostname=`hostname`; chomp $hostname;

# ----------------------------------------------------------------- SUBROUTINES
sub propath {
    my ($udom,$uname)=@_;
    $udom=~s/\W//g;
    $uname=~s/\W//g;
    my $subdir=$uname.'__';
    $subdir =~ s/(.)(.)(.).*/$1\/$2\/$3/;
    my $proname="$perlvar{'lonUsersDir'}/$udom/$subdir/$uname";
    return $proname;
}

=pod

=head1 PREREQUISITES

GDBM_File

=head1 AUTHOR


=cut
