Skip to content

Instantly share code, notes, and snippets.

@raldred
Created September 8, 2009 08:21
Show Gist options
  • Save raldred/182784 to your computer and use it in GitHub Desktop.
Save raldred/182784 to your computer and use it in GitHub Desktop.
package AuthControl::auth_control;
#use FindBin;
#use lib $FindBin::Bin . '/../../../cgi-bin';
use Data::Dumper;
use strict;
use Digest::MD5 qw(md5 md5_hex md5_base64);
# ::logGlobal("Loaded AuthControl Library");
sub new
{
my $class = shift;
my %args = @_;
my $self = {};
for (keys %args)
{
$self->{lc($_)} = $args{$_};
}
return bless $self,$class;
}
sub error_messages()
{
my $self = shift;
my $key = shift;
my $errors = {
'login_locked' => 'Your account is locked, please contact a manager or Axiar Support.',
};
return $errors->{$key};
}
sub init()
{
my $self = shift;
my $dbh = $self->{dbh};
## here we are going to decide what to do.
if($::CGI->{reset_code})
{
$self->reset_password();
return;
}
if($::CGI->{auth_change_password})
{
##we have a request to change the logged in users password
$self->change_password();
}
if($::CGI->{auth_create_user})
{
##we have a request to create a user account
$self->create_user();
}
# This functionality has been temporarly disabled until because it is specificly for admins assinging roles
#
# if($::CGI->{save_roles} && ($::CGI->{g} || $::CGI->{u}))
# {
# #if we have a request to change group roles or a specific users roles, do it
# $self->update_user_roles();
# }
#
# if($::CGI->{save_all_roles})
# {
# #if we have a request to change group roles, do it
# $self->update_all_group_roles();
# }
#
# if($::CGI->{save_groups} && $::CGI->{u})
# {
# #if we have a request to change user groups, do it
# $self->update_user_groups();
# }
##detect failed login
$self->logged_in_attempt_check() if $::Session->{username};
#log activity unless on login or we are running a time check
$self->logged_in_activity() if $self->{method} ne 'user_last_active' and $Global::Variable->{MV_PAGE} ne 'login';
##check to see if use requires password change
$self->logged_in_password_check() if($::Session->{username} && !$::Scratch->{on_change_password});
return;
}
sub update_user_groups()
{
my $self = shift;
my $dbh = $self->{dbh};
my $sql = "select * from access where username = ?";
my $admin_sth = $dbh->prepare($sql);
$admin_sth->execute($::CGI->{u});
while (my $admin = $admin_sth->fetchrow_hashref())
{
my $user_groups = $admin->{groups};
my $sql = "select * from access WHERE username LIKE ':%'";
my $groups_sth = $dbh->prepare($sql);
$groups_sth->execute();
while (my $group = $groups_sth->fetchrow_hashref())
{
my $thisgroup = $::Tag->admin_in_group({user=>$::CGI->{u},group=>$group->{username},grouplist=>$user_groups});
my $groupname = $group->{username};
##when stored in users groups field, groups are stored without ':'
$groupname =~ s/^://;
if($::CGI->{$group->{username}} eq 'y')
{
##group selected, if user is not already in this group, add them
if(!$thisgroup)
{
$sql = "UPDATE access SET groups = concat(groups,' ','".$groupname."') WHERE username = ? LIMIT 1";
my $update_sth = $dbh->prepare($sql);
$update_sth->execute($::CGI->{u});
$update_sth->finish();
}
}
else
{
##group not selected, if user is currently marked as in this group, remove them from it
if($thisgroup)
{
$sql = "UPDATE access SET groups = replace(groups,'".$groupname."','') WHERE username = ? LIMIT 1";
my $update_sth = $dbh->prepare($sql);
$update_sth->execute($::CGI->{u});
$update_sth->finish();
}
}
}
$groups_sth->finish();
}
$admin_sth->finish(); ##finish with the query
$::Tag->warning("Group selections saved.");
$::Tag->deliver({location=>$::Tag->area({href=>'admin/auth/user_roles',form=>'action=groups&u='.$::CGI->{u}})});
}
sub update_all_group_roles()
{
my $self = shift;
my $dbh = $self->{dbh};
my $sql = "SELECT username from access WHERE username LIKE ':%'";
my $group_sth = $dbh->prepare($sql);
$group_sth->execute();
while (my $group = $group_sth->fetchrow_hashref())
{
::logError("\nSaving roles for ".$group->{username}."\n");
$self->update_user_roles($group->{username});
}
$::Tag->warning("All role selections saved.");
$::Tag->deliver({location=>$::Tag->area({href=>'admin/auth/group_roles'})});
}
sub update_user_roles()
{
my $self = shift;
my $group = shift;
my $dbh = $self->{dbh};
my $g = $::CGI->{g} if $::CGI->{g};
$g = $::CGI->{u} if $::CGI->{u};
$g = $group if $group;
my $sql = "select yes_functions from access where username = ?";
my $admin_sth = $dbh->prepare($sql);
$admin_sth->execute($g);
while (my $admin = $admin_sth->fetchrow_hashref())
{
my $group_yes_func = $admin->{yes_functions};
my $sql = "select * from userdb_roles";
my $roles_sth = $dbh->prepare($sql);
$roles_sth->execute();
while (my $role = $roles_sth->fetchrow_hashref())
{
my $rolegroup_tmp = $g;
$rolegroup_tmp =~ s/^://;
my $rolevalue = $::CGI->{$role->{variable}};
$rolevalue = $::CGI->{$role->{variable}.'_'.$rolegroup_tmp} if $group;
my $thisrole;
$thisrole = $::Tag->group_has_access({function=>$role->{variable},value=>$group_yes_func}) if($group or $::CGI->{g});
$thisrole = $::Tag->admin_has_access({function=>$role->{variable},user => $g}) if($::CGI->{u});
if($rolevalue eq 'y')
{
##if the user didnt have access before, add it
if(!$thisrole)
{
$sql = "UPDATE access SET yes_functions = concat(yes_functions,' ".$role->{variable}."') WHERE username = ? LIMIT 1";
my $update_sth = $dbh->prepare($sql);
$update_sth->execute($g);
$update_sth->finish();
}
}
elsif(($rolevalue eq 'n') || (!$rolevalue))
{
##if the user had access remove it now
if($thisrole)
{
$sql = "UPDATE access SET yes_functions = replace(yes_functions,'".$role->{variable}."','') WHERE username = ? LIMIT 1";
my $update_sth = $dbh->prepare($sql);
$update_sth->execute($g);
$update_sth->finish();
}
}
}
$roles_sth->finish();
}
$admin_sth->finish(); ##finish with the query
if(not $group)
{
my $to_page = 'group_roles';
my $to_var = 'g';
if($::CGI->{u})
{
$to_page = 'user_roles';
$to_var = 'u';
}
$::Tag->warning("Role selections saved.");
$::Tag->deliver({location=>$::Tag->area({href=>'admin/auth/'.$to_page,form=>$to_var.'='.$g})});
}
}
sub account_activity_check()
{
my $self = shift;
my $dbh = $self->{dbh};
my $now_time = time;
my $sql = "SELECT * from userdb";
my $sth = $dbh->prepare($sql);
$sth->execute();
while (my $row = $sth->fetchrow_hashref())
{
return unless $row->{user_last_active} > 0;
my $activity_diff = ((((time - $row->{user_last_active}) / 60) / 60) / 24);
my $activity_limit = $::Variable->{ACCESS_AUTO_DISABLE} || 90; #days
if($activity_diff > $activity_limit)
{
##accounts has not been used for x amount of time, lock it.
$self->login_lock($row->{username});
}
}
return;
}
sub logged_in_activity()
{
return undef if not $::Session->{username};
##log activity this will be used for checking inactivity
my $self = shift;
my $dbh = $self->{dbh};
##first check if last activity was over allowed time, default 15minutes
my $now_time = time;
my $user_record = $self->user_record($::Session->{username});
my $activity_diff = ($now_time - $user_record->{user_last_active}) / 60;
my $activity_limit = $::Variable->{ACCESS_SESSION_TIMEOUT} || 15; #minutes
if($activity_diff > $activity_limit)
{
::logError("User $user_record->{username} inactive for $activity_diff minutes, logout forced.");
$::Tag->error({name=>"timeout", set=>"You have been automatically logged out after a period of inactivity."});
$::Tag->deliver({status=>$self->{redirect_code},location=>$::Tag->area({href=>'login'})});
return;
}
$self->log_activity();
return;
}
sub log_activity()
{
my $self = shift;
my $dbh = $self->{dbh};
my $sql = "UPDATE userdb SET user_last_active = ? WHERE username = ?";
my $sth = $dbh->prepare($sql);
$sth->execute(time,$::Session->{username});
$sth->finish();
}
sub date_difference()
{
##this function expects unix timestamps
my $self = shift;
my $d1 = shift; #oldest date
my $d2 = shift; #now or newest date
my $daydifference = sprintf "%.0f", ($d2 - $d1) / 86400;
return $daydifference;
}
sub logged_in_password_check()
{
my $self = shift;
my $dbh = $self->{dbh};
my $day_diff;
my $now_date = time;
##the the users record
my $user = $self->user_record($::Session->{username});
##if the user has the force password change flag set, sent them on their way to the change password screen
if($user->{password_change})
{
$::Tag->error({name=>'password_check',set=>'Your password has expired and needs to be changed before you can continue'});
$::Tag->del
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment