Index: main/trunk/greenstone2/perllib/cgiactions/baseaction.pm
===================================================================
--- main/trunk/greenstone2/perllib/cgiactions/baseaction.pm	(revision 27315)
+++ main/trunk/greenstone2/perllib/cgiactions/baseaction.pm	(revision 27318)
@@ -31,5 +31,9 @@
 use inexport;
 
-our $authentication_enabled = 0; # debugging flag (can debug without authentication when set to 0)
+# for time conversion and formatting functions
+use Time::Local;
+use POSIX;
+
+our $authentication_enabled = 1; # debugging flag (can debug without authentication when set to 0)
 our $mail_enabled = 0;
 
@@ -225,12 +229,17 @@
     my $collection = shift(@_);
 
+    my $keydecay = 1800; # 30 mins same as in runtime-src/recpt/authentication.cpp
+
     my $gsdl_cgi = $self->{'gsdl_cgi'};
 
     # Remove the pw argument (since this can mess up other scripts)
     my $user_password = $gsdl_cgi->clean_param("pw");
+    my $user_key = $gsdl_cgi->clean_param("ky");
+
     $gsdl_cgi->delete("pw");
-
-    if ((!defined $user_password) || ($user_password =~ m/^\s*$/)) {
-	$gsdl_cgi->generate_error("Authentication failed: no password specified.");
+    $gsdl_cgi->delete("ky");
+
+    if ((!defined $user_password || $user_password =~ m/^\s*$/) && (!defined $user_key || $user_key =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("Authentication failed: no password or key specified.");
     }
 
@@ -259,9 +268,79 @@
 	$gsdl_cgi->generate_error("Authentication failed: no account for user '$username'.");
     }
-
+    
     # Check password
-    my ($valid_user_password) = ($user_data =~ /\<password\>(.*)/);
-    if ($user_password ne $valid_user_password) {
-	$gsdl_cgi->generate_error("Authentication failed: incorrect password.");
+    if(defined $user_password) {
+	my ($valid_user_password) = ($user_data =~ /\<password\>(.*)/);
+	if ($user_password ne $valid_user_password) {
+	    $gsdl_cgi->generate_error("Authentication failed: incorrect password.");
+	}
+    } 
+    else { # check $user_key #if(!defined $user_password && defined $user_key) {
+	
+	# check to see if there is a key for this particular user in the database that hasn't decayed.
+	# if the key validates, refresh the key again by setting its timestamp to the present time.
+
+	# Use db2txt to get the key accounts information
+	my $key_db_file_path = &util::filename_cat($etc_directory, "key.gdb");
+	
+	my $key_db_content = "";
+	open(USERS_DB, "db2txt \"$key_db_file_path\" |");
+	while (<USERS_DB>) {
+	    $key_db_content .= $_;
+	}
+	
+	my %key_db_data = ();
+	foreach my $key_db_entry (split(/-{70}/, $key_db_content)) {
+	    if ($key_db_entry =~ /\n?\[(.+)\]\n/) {
+		$key_db_data{$1} = $key_db_entry;
+	    }
+	}
+
+	# check key entry
+	my $key_data = $key_db_data{$user_key};
+	if (!defined $key_data) {
+	    
+	    #$gsdl_cgi->generate_error("Authentication failed: invalid key $user_key. Does not exist.");
+	    $gsdl_cgi->generate_error("Authentication failed: invalid key. No entry for the given key.");
+	}
+	else {
+	    my ($valid_username) = ($key_data =~ /\<user\>(.*)/);
+	    if ($username ne $valid_username) {
+		$gsdl_cgi->generate_error("Authentication failed: key does not belong to user.");
+	    }
+	    
+	    # http://stackoverflow.com/questions/12644322/how-to-write-the-current-timestamp-in-a-file-perl
+	    # http://stackoverflow.com/questions/2149532/how-can-i-format-a-timestamp-in-perl
+	    # http://stackoverflow.com/questions/7726514/how-to-convert-text-date-to-timestamp
+	    
+	    my $current_timestamp = time; #localtime(time);
+	    
+	    my ($keycreation_time) = ($key_data =~ /\<time\>(.*)/); # of the form: 2013/05/06 14:39:23
+	    if ($keycreation_time !~ m/^\s*$/) { # not empty
+		
+		my ($year,$mon,$mday,$hour,$min,$sec) = split(/[\s\/:]+/, $keycreation_time); # split by space, /, :
+		my $key_timestamp = timelocal($sec,$min,$hour,$mday,$mon-1,$year);
+		
+		if(($current_timestamp - $key_timestamp) > $keydecay) {
+		    $gsdl_cgi->generate_error("Authentication failed: key has expired.");
+		} else {
+		    # succeeded, update the key's time in the database
+		    
+		    # beware http://community.activestate.com/forum/posixstrftime-problem-e-numeric-day-month
+		    my $current_time = strftime("%Y/%m/%d %H:%M:%S\n", localtime($current_timestamp)); # POSIX
+		    
+		    my $infodbtype = $self->{'infodbtype'};
+		    my $key_rec = &dbutil::read_infodb_entry($infodbtype, $key_db_file_path, $user_key);
+		    $key_rec->{"time"}->[0] = $current_time;
+		    my $status = &dbutil::set_infodb_entry($infodbtype, $key_db_file_path, $user_key, $key_rec);
+		    
+		    if ($status != 0) {
+			$gsdl_cgi->generate_error("Error updating authentication key.");
+		    }
+		}
+	    } else {
+		$gsdl_cgi->generate_error("Authentication failed: Invalid key entry. No time stored for key.");
+	    }	    
+	}
     }
 
@@ -271,30 +350,41 @@
     # the user doesn't need to be a specific collection's editor in order to add comments to that collection.
     # So we no longer check the user is in the group here.
+#    $self->check_group($collection, $username, $user_data);
+}
+
+
+sub check_group
+{
+    my $self = shift @_;
+    my $collection = shift @_;
+    my $username = shift @_;
+    my $user_data = shift @_;
+
+
+    my $gsdl_cgi = $self->{'gsdl_cgi'};
 
     # Check group
-#    my ($user_groups) = ($user_data =~ /\<groups\>(.*)/);
-#    if ($collection eq "") {
-#	# If we're not editing a collection then the user doesn't need to be in a particular group
-#	return $user_groups;  # Authentication successful
-#    }
-#    foreach my $user_group (split(/\,/, $user_groups)) {
+    my ($user_groups) = ($user_data =~ /\<groups\>(.*)/);
+    if ($collection eq "") {
+	# If we're not editing a collection then the user doesn't need to be in a particular group
+	return $user_groups;  # Authentication successful
+    }
+    foreach my $user_group (split(/\,/, $user_groups)) {
 	# Does this user have access to all collections?
-#	if ($user_group eq "all-collections-editor") {
-#	    return $user_groups;  # Authentication successful
-#	}
+	if ($user_group eq "all-collections-editor") {
+	    return $user_groups;  # Authentication successful
+	}
 	# Does this user have access to personal collections, and is this one?
-#	if ($user_group eq "personal-collections-editor" && $collection =~ /^$username\-/) {
-#	    return $user_groups;  # Authentication successful
-#	}
+	if ($user_group eq "personal-collections-editor" && $collection =~ /^$username\-/) {
+	    return $user_groups;  # Authentication successful
+	}
 	# Does this user have access to this collection
-#	if ($user_group eq "$collection-collection-editor") {
-#	    return $user_groups;  # Authentication successful
-#	}
-#    }
-#
-#    $gsdl_cgi->generate_error("Authentication failed: user is not in the required group.");
-}
-
-
+	if ($user_group eq "$collection-collection-editor") {
+	    return $user_groups;  # Authentication successful
+	}
+    }
+    
+    $gsdl_cgi->generate_error("Authentication failed: user is not in the required group.");
+}
 
 sub check_installation
