Changeset 27318


Ignore:
Timestamp:
05/08/13 20:27:02 (8 years ago)
Author:
ak19
Message:

Authentication at perl level for when setting user-added comments. 1. metadata-server.plnow encrypts the key, so that it can be checked against what's in the key db. 2. gdslCGI.pm now has an encrypt_key subroutine. 3. baseaction.pm's authentication_enabled is turned on and the authenticate_user() subroutine now follows recpt's userdb.cpp::check_key by first checking for a given key when no password is given, and if the key validates and isn't stale, then its timestamp in the key db is updated. The code for checking the group that the user belongs to (which had been commented out since user comments can be set by anyone with a GS account, they don't need to belong to a collection editing group) has been moved to a new function called check_group, with the line calling it commented out. 4. style.dm passes in un and ky cgi args to the gsapi object's constructor. 5. gsajaxapi.js's constructor takes the un and ky parameters and then uses these in the Get and Post methods when making calls to metadata-server.pl.

Location:
main/trunk/greenstone2
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone2/common-src/cgi-bin/gsdlCGI.pm

    r27158 r27318  
    802802    }else{
    803803    $java_classpath = $java_gsdl3_classpath . ";" . $java_remaining_classpath;
    804     }
     804    } # can't use util::envvar_prepend(), since the $java_classpath here is not a $ENV type env variable
    805805   
    806806    my $java_command="\"$java\" -classpath \"$java_classpath\" org.greenstone.gsdl3.service.Authentication \"$password\""; # 2>&1";
     
    808808
    809809    return $hashedpwd;
     810}
     811
     812sub encrypt_key
     813{
     814    my $self = shift @_;
     815
     816    # I think the encryption method used on the key may be the same for GS3 and GS2
     817    # (The encryption method used on the pw definitely differs between the two GS versions)
     818    if (defined $self->param("ky")) {
     819    require "$self->{'gsdlhome'}/perllib/cpan/Crypt/UnixCrypt.pm";  # This is OK on Windows
     820    $self->param('-name' => "ky", '-value' => &Crypt::UnixCrypt::crypt($self->clean_param("ky"), "Tp"));
     821    }
    810822}
    811823
  • main/trunk/greenstone2/common-src/cgi-bin/metadata-server.pl

    r27295 r27318  
    5555    $gsdl_cgi->checked_chdir($gsdlhome);
    5656
    57     # Encrypt the password
     57    # Encrypt the password and key
    5858    $gsdl_cgi->encrypt_password();
     59    $gsdl_cgi->encrypt_key();
    5960
    6061    require cgiactions::metadataaction;
  • main/trunk/greenstone2/macros/style.dm

    r27313 r27318  
    240240    \}
    241241
    242     var gsapi = new GSAjaxAPI("_gwcgi_","_cgiargc_");
     242    var un = "_cgiargun_";
     243    var ky = "_cgiargky_";
     244    var gsapi = new GSAjaxAPI("_gwcgi_","_cgiargc_","_cgiargun_","_cgiargky_");
    243245   
    244246    // http://stackoverflow.com/questions/6312993/javascript-seconds-to-time-with-format-hhmmss
  • main/trunk/greenstone2/perllib/cgiactions/baseaction.pm

    r27295 r27318  
    3131use inexport;
    3232
    33 our $authentication_enabled = 0; # debugging flag (can debug without authentication when set to 0)
     33# for time conversion and formatting functions
     34use Time::Local;
     35use POSIX;
     36
     37our $authentication_enabled = 1; # debugging flag (can debug without authentication when set to 0)
    3438our $mail_enabled = 0;
    3539
     
    225229    my $collection = shift(@_);
    226230
     231    my $keydecay = 1800; # 30 mins same as in runtime-src/recpt/authentication.cpp
     232
    227233    my $gsdl_cgi = $self->{'gsdl_cgi'};
    228234
    229235    # Remove the pw argument (since this can mess up other scripts)
    230236    my $user_password = $gsdl_cgi->clean_param("pw");
     237    my $user_key = $gsdl_cgi->clean_param("ky");
     238
    231239    $gsdl_cgi->delete("pw");
    232 
    233     if ((!defined $user_password) || ($user_password =~ m/^\s*$/)) {
    234     $gsdl_cgi->generate_error("Authentication failed: no password specified.");
     240    $gsdl_cgi->delete("ky");
     241
     242    if ((!defined $user_password || $user_password =~ m/^\s*$/) && (!defined $user_key || $user_key =~ m/^\s*$/)) {
     243    $gsdl_cgi->generate_error("Authentication failed: no password or key specified.");
    235244    }
    236245
     
    259268    $gsdl_cgi->generate_error("Authentication failed: no account for user '$username'.");
    260269    }
    261 
     270   
    262271    # Check password
    263     my ($valid_user_password) = ($user_data =~ /\<password\>(.*)/);
    264     if ($user_password ne $valid_user_password) {
    265     $gsdl_cgi->generate_error("Authentication failed: incorrect password.");
     272    if(defined $user_password) {
     273    my ($valid_user_password) = ($user_data =~ /\<password\>(.*)/);
     274    if ($user_password ne $valid_user_password) {
     275        $gsdl_cgi->generate_error("Authentication failed: incorrect password.");
     276    }
     277    }
     278    else { # check $user_key #if(!defined $user_password && defined $user_key) {
     279   
     280    # check to see if there is a key for this particular user in the database that hasn't decayed.
     281    # if the key validates, refresh the key again by setting its timestamp to the present time.
     282
     283    # Use db2txt to get the key accounts information
     284    my $key_db_file_path = &util::filename_cat($etc_directory, "key.gdb");
     285   
     286    my $key_db_content = "";
     287    open(USERS_DB, "db2txt \"$key_db_file_path\" |");
     288    while (<USERS_DB>) {
     289        $key_db_content .= $_;
     290    }
     291   
     292    my %key_db_data = ();
     293    foreach my $key_db_entry (split(/-{70}/, $key_db_content)) {
     294        if ($key_db_entry =~ /\n?\[(.+)\]\n/) {
     295        $key_db_data{$1} = $key_db_entry;
     296        }
     297    }
     298
     299    # check key entry
     300    my $key_data = $key_db_data{$user_key};
     301    if (!defined $key_data) {
     302       
     303        #$gsdl_cgi->generate_error("Authentication failed: invalid key $user_key. Does not exist.");
     304        $gsdl_cgi->generate_error("Authentication failed: invalid key. No entry for the given key.");
     305    }
     306    else {
     307        my ($valid_username) = ($key_data =~ /\<user\>(.*)/);
     308        if ($username ne $valid_username) {
     309        $gsdl_cgi->generate_error("Authentication failed: key does not belong to user.");
     310        }
     311       
     312        # http://stackoverflow.com/questions/12644322/how-to-write-the-current-timestamp-in-a-file-perl
     313        # http://stackoverflow.com/questions/2149532/how-can-i-format-a-timestamp-in-perl
     314        # http://stackoverflow.com/questions/7726514/how-to-convert-text-date-to-timestamp
     315       
     316        my $current_timestamp = time; #localtime(time);
     317       
     318        my ($keycreation_time) = ($key_data =~ /\<time\>(.*)/); # of the form: 2013/05/06 14:39:23
     319        if ($keycreation_time !~ m/^\s*$/) { # not empty
     320       
     321        my ($year,$mon,$mday,$hour,$min,$sec) = split(/[\s\/:]+/, $keycreation_time); # split by space, /, :
     322        my $key_timestamp = timelocal($sec,$min,$hour,$mday,$mon-1,$year);
     323       
     324        if(($current_timestamp - $key_timestamp) > $keydecay) {
     325            $gsdl_cgi->generate_error("Authentication failed: key has expired.");
     326        } else {
     327            # succeeded, update the key's time in the database
     328           
     329            # beware http://community.activestate.com/forum/posixstrftime-problem-e-numeric-day-month
     330            my $current_time = strftime("%Y/%m/%d %H:%M:%S\n", localtime($current_timestamp)); # POSIX
     331           
     332            my $infodbtype = $self->{'infodbtype'};
     333            my $key_rec = &dbutil::read_infodb_entry($infodbtype, $key_db_file_path, $user_key);
     334            $key_rec->{"time"}->[0] = $current_time;
     335            my $status = &dbutil::set_infodb_entry($infodbtype, $key_db_file_path, $user_key, $key_rec);
     336           
     337            if ($status != 0) {
     338            $gsdl_cgi->generate_error("Error updating authentication key.");
     339            }
     340        }
     341        } else {
     342        $gsdl_cgi->generate_error("Authentication failed: Invalid key entry. No time stored for key.");
     343        }       
     344    }
    266345    }
    267346
     
    271350    # the user doesn't need to be a specific collection's editor in order to add comments to that collection.
    272351    # So we no longer check the user is in the group here.
     352#    $self->check_group($collection, $username, $user_data);
     353}
     354
     355
     356sub check_group
     357{
     358    my $self = shift @_;
     359    my $collection = shift @_;
     360    my $username = shift @_;
     361    my $user_data = shift @_;
     362
     363
     364    my $gsdl_cgi = $self->{'gsdl_cgi'};
    273365
    274366    # Check group
    275 #    my ($user_groups) = ($user_data =~ /\<groups\>(.*)/);
    276 #    if ($collection eq "") {
    277 #   # If we're not editing a collection then the user doesn't need to be in a particular group
    278 #   return $user_groups;  # Authentication successful
    279 #    }
    280 #    foreach my $user_group (split(/\,/, $user_groups)) {
     367    my ($user_groups) = ($user_data =~ /\<groups\>(.*)/);
     368    if ($collection eq "") {
     369    # If we're not editing a collection then the user doesn't need to be in a particular group
     370    return $user_groups;  # Authentication successful
     371    }
     372    foreach my $user_group (split(/\,/, $user_groups)) {
    281373    # Does this user have access to all collections?
    282 #   if ($user_group eq "all-collections-editor") {
    283 #       return $user_groups;  # Authentication successful
    284 #   }
     374    if ($user_group eq "all-collections-editor") {
     375        return $user_groups;  # Authentication successful
     376    }
    285377    # Does this user have access to personal collections, and is this one?
    286 #   if ($user_group eq "personal-collections-editor" && $collection =~ /^$username\-/) {
    287 #       return $user_groups;  # Authentication successful
    288 #   }
     378    if ($user_group eq "personal-collections-editor" && $collection =~ /^$username\-/) {
     379        return $user_groups;  # Authentication successful
     380    }
    289381    # Does this user have access to this collection
    290 #   if ($user_group eq "$collection-collection-editor") {
    291 #       return $user_groups;  # Authentication successful
    292 #   }
    293 #    }
    294 #
    295 #    $gsdl_cgi->generate_error("Authentication failed: user is not in the required group.");
    296 }
    297 
    298 
     382    if ($user_group eq "$collection-collection-editor") {
     383        return $user_groups;  # Authentication successful
     384    }
     385    }
     386   
     387    $gsdl_cgi->generate_error("Authentication failed: user is not in the required group.");
     388}
    299389
    300390sub check_installation
  • main/trunk/greenstone2/web/script/gsajaxapi.js

    r27313 r27318  
    11
    2 function GSAjaxAPI(gwcgi,collect)
     2function GSAjaxAPI(gwcgi,collect,un,ky)
    33{
    44    var gwcgi_   = gwcgi;
    55    var collect_ = collect;
     6    var un_ = un;
     7    var ky_ = ky;
    68
    79
     
    101103    }
    102104
     105       if(un_ != null) {
     106       url += "&un=" + un_;
     107       }
     108       if(ky_ != null) {
     109       url += "&ky=" + ky_;
     110       }
     111       
    103112    xmlHttp.open("GET",url,true);
    104113    xmlHttp.send(null);
     
    130139         }
    131140       }
     141
     142       if(un_ != null) {
     143       url += "&un=" + un_;
     144       }
     145       if(ky_ != null) {
     146       url += "&ky=" + ky_;
     147       }
    132148   
    133149       xmlHttp.open("GET",url,false);
     
    178194//        }
    179195//    }
     196   
     197    if(un_ != null) {
     198    params += "&un=" + un_;
     199    }
     200    if(ky_ != null) {
     201    params += "&ky=" + ky_;
     202    }
    180203
    181204    xmlHttp.send(params); // needs to be escaped/encoded
    182205
     206    //alert(scriptURL + "?" + params);
    183207    //alert(xmlHttp.responseText); // if synchronous, process xmlHttp.responseText AFTER send() call
    184208    return xmlHttp.responseText;
Note: See TracChangeset for help on using the changeset viewer.