diff --git a/docs/migration.txt b/docs/migration.txt index 8f33a2cef..99f82c2ef 100644 --- a/docs/migration.txt +++ b/docs/migration.txt @@ -39,7 +39,17 @@ There have currently been no changes to the macro API. There have currently been no changes to the authentication API. In 6.0 all Authentication modules will need to be rewritten as Auth modules according to the new -Auth API in WebGUI::Auth. Details to follow. +Auth API in WebGUI::Auth. + +The following modules will no longer be needed: +WebGUI::Authentication::WebGUI +WebGUI::Authentication::LDAP +WebGUI::Authentication::SMB + +WebGUI::Authentication +WebGUI::Operation::Account + +Details to follow. diff --git a/lib/WebGUI/Auth.pm b/lib/WebGUI/Auth.pm new file mode 100644 index 000000000..b64689809 --- /dev/null +++ b/lib/WebGUI/Auth.pm @@ -0,0 +1,651 @@ +package WebGUI::Auth; + +=head1 LEGAL + + ------------------------------------------------------------------- + WebGUI is Copyright 2001-2003 Plain Black LLC. + ------------------------------------------------------------------- + Please read the legal notices (docs/legal.txt) and the license + (docs/license.txt) that came with this distribution before using + this software. + ------------------------------------------------------------------- + http://www.plainblack.com info@plainblack.com + ------------------------------------------------------------------- + +=cut + +use CGI::Util qw(rearrange); +use DBI; +use strict qw(subs vars); +use Tie::IxHash; +use WebGUI::DateTime; +use WebGUI::FormProcessor; +use WebGUI::HTML; +use WebGUI::HTMLForm; +use WebGUI::Icon; +use WebGUI::International; +use WebGUI::Macro; +use WebGUI::Node; +use WebGUI::Page; +use WebGUI::Session; +use WebGUI::SQL; +use WebGUI::TabForm; +use WebGUI::Template; +use WebGUI::URL; +use WebGUI::Utility; +use WebGUI::Operation::Profile; +use WebGUI::Operation::Auth; + +=head1 NAME + +Package WebGUI::Auth + +=head1 DESCRIPTION + +An abstract class for all authentication modules to extend. + +=head1 SYNOPSIS + + use WebGUI::Auth; + our @ISA = qw(WebGUI::Auth); + +=head1 METHODS + +These methods are available from this class: + +=cut + +#------------------------------------------------------------------- +sub _isDuplicateUsername { + my $self = shift; + my $username = shift; + #Return false if the user is already logged in, but not changing their username. + return 0 if($self->userId != 1 && $session{user}{username} eq $username); + my ($otherUser) = WebGUI::SQL->quickArray("select count(*) from users where username=".quote($username)); + return 0 if !$otherUser; + $self->error('
  • '.WebGUI::International::get(77).' "'.$username.'too", "'.$username.'2", '.'"'.$username.'_'.WebGUI::DateTime::epochToHuman(time(),"%y").'"'); + return 1; +} + +#------------------------------------------------------------------- + +=head2 _isValidPassword ( ) + + Validates the password. + +=cut + +sub _isValidPassword { + my $self = shift; + my $password = shift; + my $confirm = shift; + my $error = ""; + + if ($password ne $confirm) { + $error .= '
  • '.WebGUI::International::get(3,'Auth/WebGUI'); + } + if ($password eq "") { + $error .= '
  • '.WebGUI::International::get(4,'Auth/WebGUI'); + } + + if ($self->getSetting("passwordLength") && length($password) < $self->getSetting("passwordLength")){ + $error .= '
  • '.WebGUI::International::get(7,'Auth/WebGUI')." ".$self->getSetting("passwordLength"); + } + + $self->error($error); + return $error eq ""; +} + +#------------------------------------------------------------------- + +=head2 _isValidUsername ( username ) + + Validates the username passed in. + +=cut + +sub _isValidUsername { + my $self = shift; + my $username = shift; + my $error = ""; + + return 1 if($self->userId != 1 && $session{user}{username} eq $username); + + if ($username =~ /^\s/ || $username =~ /\s$/) { + $error .= '
  • '.WebGUI::International::get(724); + } + if ($username eq "") { + $error .= '
  • '.WebGUI::International::get(725); + } + unless ($username =~ /^[A-Za-z0-9\-\_\.\,\@]+$/) { + $error .= '
  • '.WebGUI::International::get(747); + } + $self->error($error); + return $error eq ""; +} + +#------------------------------------------------------------------- +sub _logLogin { + WebGUI::SQL->write("insert into userLoginLog values ('$_[0]','$_[1]',".time().",".quote($session{env}{REMOTE_ADDR}).",".quote($session{env}{HTTP_USER_AGENT}).")"); +} + +#------------------------------------------------------------------- + +=head2 addUserForm ( userId ) + + Creates user form elements specific to this Auth Method. + +=cut + +sub addUserForm { + #Added for interface purposes only. Needs to be implemented in the subclass. +} + +#------------------------------------------------------------------- + +=head2 addUserFormSave ( properties [,userId] ) + + Saves user elements unique to this authentication method + +=cut + +sub addUserFormSave { + my $self = shift; + $self->saveParams(($_[1] || $self->userId),$self->authMethod,$_[0]); +} + +#------------------------------------------------------------------- + +=head2 authenticate ( ) + + Superclass method that performs standard login routines. This method should return true or false. + +=cut + +sub authenticate { + my $self = shift; + my $user = WebGUI::SQL->quickHashRef("select userId,authMethod,status from users where username=".quote($session{form}{username})); + my $uid = $user->{userId}; + #If userId does not exist or is not active, fail login + if(!$uid){ + $self->error(WebGUI::International::get(68)); + return 0; + } elsif($user->{status} ne 'Active'){ + $self->error(WebGUI::International::get(820)); + _logLogin($uid, "failure"); + return 0; + } + + #Set User Id + $self->user(WebGUI::User->new($uid)); + return 1; +} + +#------------------------------------------------------------------- +=head2 authMethod ( [authMethod] ) + + Gets or sets the authMethod in the Auth Object + +=cut + +sub authMethod { + my $self = shift; + return $self->{authMethod} if(!$_[0]); + $self->{authMethod} = $_[0]; +} + +#------------------------------------------------------------------- +sub createAccount { + my $self = shift; + my $method = $_[0]; + my $vars = $_[1]; + my $template = $_[2] || 'Auth/'.$self->authMethod.'/Create'; + $vars->{displayTitle} = '

    '.WebGUI::International::get(54).'

    '; + + $vars->{'create.form.header'} = "\n\n".WebGUI::Form::formHeader({}); + $vars->{'create.form.hidden'} .= WebGUI::Form::hidden({"name"=>"op","value"=>"auth"}); + $vars->{'create.form.hidden'} .= WebGUI::Form::hidden({"name"=>"method","value"=>$method}); + + #User Defined Options + $vars->{'create.form.profile'} = WebGUI::Operation::Profile::getRequiredProfileFields(); + + $vars->{'create.form.submit'} = WebGUI::Form::submit({}); + $vars->{'create.form.footer'} = ""; + + $vars->{'create.options.accountExists'} = ''.WebGUI::International::get(58).''; + + if ($self->getSetting("passwordRecovery")) { + $vars->{'create.options.passwordRecovery'} = ''.WebGUI::International::get(59).''; + } + return WebGUI::Template::process(WebGUI::Template::get(1,$template), $vars); +} + +#------------------------------------------------------------------- +sub deactivateAccount { + my $self = shift; + my $method = $_[0]; + my ($output); + $output = '

    '.WebGUI::International::get(42).'

    '; + $output .= WebGUI::International::get(60).'

    '; + $output .= '

    '.WebGUI::International::get(44).''; + $output .= '    '.WebGUI::International::get(45).'
    '; + return $output; +} + +#------------------------------------------------------------------- +sub deactivateAccountConfirm { + my $self = shift; + my ($u); + $u = WebGUI::User->new($session{user}{userId}); + $u->status("Selfdestructed"); + WebGUI::Session::end($session{var}{sessionId}); + WebGUI::Session::start(1); +} + +#------------------------------------------------------------------- + +=head2 deleteParams ( ) + +Removes the user's authentication parameters from the database for all authentication methods. This is primarily useful when deleting the user's account. + +=cut + +sub deleteParams { + my $self = shift; + WebGUI::SQL->write("delete from authentication where userId=".quote($self->userId)); +} + +#------------------------------------------------------------------- + +=head2 displayAccount ( ) + + Superclass method that has a basic displayAccount template. + +=cut + +sub displayAccount { + my $self = shift; + my $method = $_[0]; + my $vars = $_[1]; + my $template = $_[2] || 'Auth/'.$self->authMethod.'/Account'; + + $vars->{displayTitle} = '

    '.WebGUI::International::get(61).'

    '; + + $vars->{'account.form.header'} = "\n\n".WebGUI::Form::formHeader({}); + $vars->{'account.form.hidden'} = WebGUI::Form::hidden({"name"=>"op","value"=>"auth"}); + $vars->{'account.form.hidden'} .= WebGUI::Form::hidden({"name"=>"method","value"=>$method}); + if($session{setting}{useKarma}){ + $vars->{'account.form.karma'} = $session{user}{karma}; + $vars->{'account.form.karma.label'} = WebGUI::International::get(537); + } + $vars->{'account.form.submit'} = WebGUI::Form::submit({}); + $vars->{'account.form.footer'} = ""; + + $vars->{'account.options'} = WebGUI::Operation::Profile::accountOptions(); + return WebGUI::Template::process(WebGUI::Template::get(1,$template), $vars); +} + +#------------------------------------------------------------------- + +=head2 displayLogin ( ) + + Superclass method that has a basic displayLogin template. + This method should be called unless login methods are completely different than WebGUI's standard + +=cut + +sub displayLogin { + my $self = shift; + my $method = $_[0] || "login"; + my $vars = $_[1]; + my $template = $_[2] || 'Auth/'.$self->authMethod.'/Login'; + + unless ($session{env}{REQUEST_URI} =~ "displayLogin" || $session{env}{REQUEST_URI} =~ "displayAccount" || + $session{env}{REQUEST_URI} =~ "logout" || $session{env}{REQUEST_URI} =~ "deactivateAccount"){ + WebGUI::Session::setScratch("redirectAfterLogin",$session{env}{REQUEST_URI}); + } + + $vars->{displayTitle} = '

    '.WebGUI::International::get(66).'

    '; + $vars->{'login.form.header'} = "\n\n".WebGUI::Form::formHeader({}); + if ($session{setting}{encryptLogin}) { + $vars->{'login.form.header'} =~ s/http:/https:/; + } + $vars->{'login.form.hidden'} = WebGUI::Form::hidden({"name"=>"op","value"=>"auth"}); + $vars->{'login.form.hidden'} .= WebGUI::Form::hidden({"name"=>"method","value"=>$method}); + $vars->{'login.form.username'} = WebGUI::Form::text({"name"=>"username"}); + $vars->{'login.form.username.label'} = WebGUI::International::get(50); + $vars->{'login.form.password'} = WebGUI::Form::password({"name"=>"identifier"}); + $vars->{'login.form.password.label'} = WebGUI::International::get(51); + $vars->{'login.form.submit'} = WebGUI::Form::submit({"value"=>WebGUI::International::get(52)}); + $vars->{'login.form.footer'} = ""; + + if ($session{setting}{anonymousRegistration}) { + $vars->{'login.options.anonymousRegistration'} = ''.WebGUI::International::get(67).''; + } + if ($self->getSetting("passwordRecovery")) { + $vars->{'login.options.passwordRecovery'} = ''.WebGUI::International::get(59).''; + } + return WebGUI::Template::process(WebGUI::Template::get(1,$template), $vars); +} + +#------------------------------------------------------------------- + +=head2 editUserForm ( ) + + Creates user form elements specific to this Auth Method. + +=cut + +sub editUserForm { + #Added for interface purposes only. Needs to be implemented in the subclass. +} + +#------------------------------------------------------------------- + +=head2 editUserFormSave ( properties ) + + Saves user elements unique to this authentication method + +=cut + +sub editUserFormSave { + my $self = shift; + $self->saveParams($self->userId,$self->authMethod,$_[0]); +} + +#------------------------------------------------------------------- + +=head2 error ( [errorMsg] ) + + Sets or returns the error currently stored in the object + +=cut + +sub error { + my $self = shift; + return $self->{error} if (!$_[0]); + $self->{error} = $_[0]; +} + +#------------------------------------------------------------------- + +=head2 getParams () + + Returns a hash reference with the user's authentication information. This method uses data stored in the instance of the object. + +=cut + +sub getParams { + my $self = shift; + my $userId = $_[0] || $self->userId; + my $authMethod = $_[1] || $self->authMethod; + return WebGUI::SQL->buildHashRef("select fieldName, fieldData from authentication where userId=".quote($userId)." and authMethod=".quote($authMethod)); +} + +#------------------------------------------------------------------- + +=head2 getSetting ( setting ) + + Returns a setting for this authMethod instance. If none is specified, returns the system authMethod setting + +=over + +=item setting + + Specify a setting to retrieve + +=back + +=cut + +sub getSetting { + my $self = shift; + my $setting = $_[0]; + $setting = lc($self->authMethod).ucfirst($setting); + return $session{setting}{$setting}; +} + +#------------------------------------------------------------------- + +=head2 isCallable ( method ) + + Returns whether or not a method is callable + +=cut + +sub isCallable { + my $self = shift; + return isIn($_[0],@{$self->{callable}}) +} + + +#------------------------------------------------------------------- + +=head2 login ( ) + + Superclass method that performs standard login routines. This is what should happen after a user has been authenticated + +=cut + +sub login { + my $self = shift; + my ($cmd, $uid, $u, $authMethod,$msg,$userData,$expireDate); + + #Create a new user + $uid = $self->userId; + $u = WebGUI::User->new($uid); + WebGUI::Session::convertVisitorToUser($session{var}{sessionId},$uid); + $u->karma($session{setting}{karmaPerLogin},"Login","Just for logging in.") if ($session{setting}{useKarma}); + _logLogin($uid,"success"); + + if ($session{scratch}{redirectAfterLogin}) { + $session{header}{redirect} = WebGUI::Session::httpRedirect($session{scratch}{redirectAfterLogin}); + WebGUI::Session::deleteScratch("redirectAfterLogin"); + } + return ""; +} + +#------------------------------------------------------------------- +=head2 logout ( ) + + Superclass method that performs standard logout routines. + +=cut + +sub logout { + WebGUI::Session::end($session{var}{sessionId}); + WebGUI::Session::start(1); + return ""; +} + +#------------------------------------------------------------------- + +=head2 new ( ) + +Constructor. + +=cut + +sub new { + my $self = {}; + shift; + + #Initialize data + $self->{authMethod} = $_[0]; + my $userId = $_[1] || $session{user}{userId}; + my $u = WebGUI::User->new($userId); + $self->{user} = $u; + $self->{error} = ""; + $self->{profile} = (); + $self->{warning} = ""; + my @callable = ('init',@{$_[2]}); + $self->{callable} = \@callable; + bless($self); + return $self; +} + +#------------------------------------------------------------------- + +=head2 profile () + + Sets or returns the Profile hash for a user. + +=cut + +sub profile { + my $self = shift; + return $self->{profile} if ($_[0]); + $self->{profile} = $_[0]; +} + + +#------------------------------------------------------------------- +sub recoverPassword { + my $self = shift; + my $method = $_[0]; + my $vars = $_[1]; + + $vars->{displayTitle} = '

    '.WebGUI::International::get(71).'

    '; + + my $output = '

    '.WebGUI::International::get(71).'

    '; + $vars->{'recover.form.header'} = "\n\n".WebGUI::Form::formHeader({}); + $vars->{'recover.form.hidden'} = WebGUI::Form::hidden({"name"=>"op","value"=>"auth"}); + $vars->{'recover.form.hidden'} .= WebGUI::Form::hidden({"name"=>"method","value"=>$method}); + + $vars->{'recover.form.submit'} = WebGUI::Form::submit({}); + $vars->{'recover.form.footer'} = ""; + + $vars->{'recover.options.accountExists'} = ''.WebGUI::International::get(73).''; + if ($session{setting}{anonymousRegistration}) { + $vars->{'recover.options.anonymousRegistration'} = ''.WebGUI::International::get(67).''; + } +} + +#------------------------------------------------------------------- +sub setCallable { + my $self = shift; + my @callable = @{$self->{callable}}; + @callable = (@callable,@{$_[0]}); +} + +#------------------------------------------------------------------- + +=head2 saveParams ( userId, authMethod, data ) + +Saves the user's authentication parameters to the database. + +=over + +=item userId + +Specify a user id. + +=item authMethod + +Specify the authentication method to save these paramaters under. + +=item data + +A hash reference containing parameter names and values to be saved. + +=back + +=cut + +sub saveParams { + my $self = shift; + my ($uid, $authMethod, $data) = @_; + foreach (keys %{$data}) { + WebGUI::SQL->write("delete from authentication where userId=$uid and authMethod=".quote($authMethod)." and fieldName=".quote($_)); + WebGUI::SQL->write("insert into authentication (userId,authMethod,fieldData,fieldName) values ($uid,".quote($authMethod).",".quote($data->{$_}).",".quote($_).")"); + } +} + +#------------------------------------------------------------------- + +=head2 user ( [user] ) + + Sets or Returns the user object stored in the wobject + +=cut + +sub user { + my $self = shift; + return $self->{user} if (!$_[0]); + $self->{user} = $_[0]; +} + +#------------------------------------------------------------------- + +=head2 userId ( ) + + Returns the userId currently stored in the object + +=cut + +sub userId { + my $self = shift; + my $u = $self->user; + return $u->userId; +} + +#------------------------------------------------------------------- + +=head2 username ( ) + + Returns the username currently stored in the object + +=cut + +sub username { + my $self = shift; + my $u = $self->user; + return $u->username; +} + +#------------------------------------------------------------------- + +=head2 validUsernameAndPassword ( username,password,passwordConfirm ) + + Validates the account form. + +=cut + +sub validUsernameAndPassword { + my $self = shift; + my $username = $_[0]; + my $password = $_[1]; + my $passwordConfirm = $_[2]; + my $error = ""; + + if($self->_isDuplicateUsername($username)){ + $error .= $self->error; + } + + if(!$self->_isValidUsername($username)){ + $error .= $self->error; + } + + if(!$self->_isValidPassword($password,$passwordConfirm)){ + $error .= $self->error; + } + + $self->error($error); + return $error eq ""; +} + +#------------------------------------------------------------------- + +=head2 warning ( [warningMsg] ) + + Sets or Returns a warning in the object + +=cut + +sub warning { + my $self = shift; + return $self->{warning} if (!$_[0]); + $self->{warning} = $_[0]; +} + +1; diff --git a/lib/WebGUI/Auth/LDAP.pm b/lib/WebGUI/Auth/LDAP.pm new file mode 100644 index 000000000..584185402 --- /dev/null +++ b/lib/WebGUI/Auth/LDAP.pm @@ -0,0 +1,368 @@ +package WebGUI::Auth::LDAP; + +#------------------------------------------------------------------- +# WebGUI is Copyright 2001-2003 Plain Black LLC. +#------------------------------------------------------------------- +# Please read the legal notices (docs/legal.txt) and the license +# (docs/license.txt) that came with this distribution before using +# this software. +#------------------------------------------------------------------- +# http://www.plainblack.com info@plainblack.com +#------------------------------------------------------------------- + +use strict; +use WebGUI::Auth; +use WebGUI::DateTime; +use WebGUI::HTMLForm; +use WebGUI::Form; +use WebGUI::Mail; +use WebGUI::Session; +use WebGUI::SQL; +use WebGUI::Utility; +use URI; +use Net::LDAP; + +our @ISA = qw(WebGUI::Auth); + +my %ldapStatusCode = ( 0=>'success (0)', 1=>'Operations Error (1)', 2=>'Protocol Error (2)', + 3=>'Time Limit Exceeded (3)', 4=>'Size Limit Exceeded (4)', 5=>'Compare False (5)', + 6=>'Compare True (6)', 7=>'Auth Method Not Supported (7)', 8=>'Strong Auth Required (8)', + 9=>'Referral (10)', 11=>'Admin Limit Exceeded (11)', 12=>'Unavailable Critical Extension (12)', + 13=>'Confidentiality Required (13)', 14=>'Sasl Bind In Progress (14)', + 15=>'No Such Attribute (16)', 17=>'Undefined Attribute Type (17)', + 18=>'Inappropriate Matching (18)', 19=>'Constraint Violation (19)', + 20=>'Attribute Or Value Exists (20)', 21=>'Invalid Attribute Syntax (21)', 32=>'No Such Object (32)', + 33=>'Alias Problem (33)', 34=>'Invalid DN Syntax (34)', 36=>'Alias Dereferencing Problem (36)', + 48=>'Inappropriate Authentication (48)', 49=>'Invalid Credentials (49)', + 50=>'Insufficient Access Rights (50)', 51=>'Busy (51)', 52=>'Unavailable (52)', + 53=>'Unwilling To Perform (53)', 54=>'Loop Detect (54)', 64=>'Naming Violation (64)', + 65=>'Object Class Violation (65)', 66=>'Not Allowed On Non Leaf (66)', 67=>'Not Allowed On RDN (67)', + 68=>'Entry Already Exists (68)', 69=>'Object Class Mods Prohibited (69)', + 71=>'Affects Multiple DSAs (71)', 80=>'other (80)'); + +#------------------------------------------------------------------- +sub _isValidLDAPUser { + my $self = shift; + my ($uri, $error, $ldap, $search, $auth, $connectDN); + + $uri = URI->new($session{setting}{ldapURL}) or $error = WebGUI::International::get(2,'Auth/LDAP'); + if($error ne ""){ + $self->error($error); + return 0; + } + + if ($ldap = Net::LDAP->new($uri->host, (port=>$uri->port))) { + if ($ldap->bind) { + $search = $ldap->search (base=>$uri->dn,filter=>$session{setting}{ldapId}."=".$session{form}{'authLDAP.ldapId'}); + if (defined $search->entry(0)) { + if ($session{setting}{ldapUserRDN} eq 'dn') { + $connectDN = $search->entry(0)->dn; + } else { + $connectDN = $search->entry(0)->get_value($session{setting}{ldapUserRDN}); + } + $ldap->unbind; + $ldap = Net::LDAP->new($uri->host, (port=>$uri->port)) or $error .= WebGUI::International::get(2,'Auth/LDAP'); + $auth = $ldap->bind(dn=>$connectDN, password=>$session{form}{'authLDAP.password'}); + if ($auth->code == 48 || $auth->code == 49) { + $error .= '
  • '.WebGUI::International::get(68); + WebGUI::ErrorHandler::warn("Invalid LDAP information for registration of LDAP ID: ".$session{form}{'authLDAP.ldapId'}); + } elsif ($auth->code > 0) { + $error .= '
  • LDAP error "'.$ldapStatusCode{$auth->code}.'" occured. '.WebGUI::International::get(69); + WebGUI::ErrorHandler::warn("LDAP error: ".$ldapStatusCode{$auth->code}); + } + $ldap->unbind; + } else { + $error .= '
  • '.WebGUI::International::get(68); + WebGUI::ErrorHandler::warn("Invalid LDAP information for registration of LDAP ID: ".$session{form}{'authLDAP.ldapId'}); + } + } else { + $error = WebGUI::International::get(2,'Auth/LDAP'); + WebGUI::ErrorHandler::warn("Couldn't bind to LDAP server: ".$session{setting}{ldapURL}); + } + } else { + $error = WebGUI::International::get(2,'Auth/LDAP'); + WebGUI::ErrorHandler::warn("Couldn't create LDAP object: ".$uri->host); + } + $self->error($error); + return $error eq ""; +} +#------------------------------------------------------------------- + +=head2 addUserForm ( ) + + Creates user form elements specific to this Auth Method. + +=cut + +sub addUserForm { + my $self = shift; + my $userData = $self->getParams; + my $ldapUrl = $session{form}{'authLDAP.ldapUrl'} || $userData->{ldapUrl} || $session{setting}{ldapURL}; + my $connectDN = $session{form}{'authLDAP.connectDN'} || $userData->{connectDN}; + + my $f = WebGUI::HTMLForm->new; + $f->url("authLDAP.ldapUrl",WebGUI::International::get(3,'Auth/LDAP'),$ldapUrl); + $f->text("authLDAP.connectDN",WebGUI::International::get(4,'Auth/LDAP'),$connectDN); + return $f->printRowsOnly; +} + +#------------------------------------------------------------------- + +=head2 addUserFormSave ( ) + + Saves user elements unique to this authentication method + +=cut + +sub addUserFormSave { + my $self = shift; + my $properties; + $properties->{connectDN} = $session{form}{'authLDAP.connectDN'}; + $properties->{ldapUrl} = $session{form}{'authLDAP.ldapUrl'}; + $self->SUPER::addUserFormSave($properties); +} + +#------------------------------------------------------------------- +sub authenticate { + my $self = shift; + my ($uri, $ldap, $auth, $result, $error); + return 0 if !$self->SUPER::authenticate(); #authenticate that the username entered actually exists and is active + my $userId = $self->userId; + my $identifier = $_[0]; + my $userData = $self->getParams; + + + $error .= WebGUI::International::get(12,'Auth/LDAP') if ($userData->{ldapUrl} eq ""); + $error .= WebGUI::International::get(11,'Auth/LDAP') if ($userData->{connectDN} eq ""); + + $self->error($error); + if($error ne ""){ + $self->user(WebGUI::User->new(1)); + return 0 ; + } + + if($uri = URI->new($userData->{ldapUrl})) { + $ldap = Net::LDAP->new($uri->host, (port=>$uri->port)) or $error .= WebGUI::International::get(2,'Auth/LDAP'); + if($error ne ""){ + $self->user(WebGUI::User->new(1)); + return 0 ; + } + $auth = $ldap->bind(dn=>$userData->{connectDN}, password=>$identifier); + if ($auth->code == 48 || $auth->code == 49){ + $error .= WebGUI::International::get(68); + }elsif($auth->code > 0){ + $error .= 'LDAP error "'.$ldapStatusCode{$auth->code}.'" occured.'.WebGUI::International::get(69); + WebGUI::ErrorHandler::warn("LDAP error: ".$ldapStatusCode{$auth->code}); + } + $ldap->unbind; + }else{ + $error .= WebGUI::International::get(13,'Auth/LDAP'); + WebGUI::ErrorHandler::warn("Could not process this LDAP URL: ".$userData->{ldapUrl}); + } + if($error ne ""){ + $self->error($error); + $self->user(WebGUI::User->new(1)); + } + return $error eq ""; +} + + +#------------------------------------------------------------------- +sub createAccount { + my $self = shift; + my $vars; + if ($session{user}{userId} != 1) { + return $self->displayAccount; + } elsif (!$session{setting}{anonymousRegistration}) { + return $self->displayLogin; + } + + $vars->{'create.message'} = $_[0] if ($_[0]); + $vars->{'create.form.ldapId'} = WebGUI::Form::text({"name"=>"authLDAP.ldapId","value"=>$session{form}{"authLDAP.ldapId"}}); + $vars->{'create.form.ldapId.label'} = $session{setting}{ldapIdName}; + $vars->{'create.form.password'} = WebGUI::Form::password({"name"=>"authLDAP.identifier","value"=>$session{form}{"authLDAP.identifier"}}); + $vars->{'create.form.password.label'} = $session{setting}{ldapPasswordName}; + + $vars->{'create.form.hidden'} = WebGUI::Form::hidden({"name"=>"confirm","value"=>$session{form}{confirm}}); + return $self->SUPER::createAccount("createAccountSave",$vars); +} + +#------------------------------------------------------------------- +sub createAccountSave { + my $self = shift; + if(!$self->_isValidLDAPUser()){ + return $self->createAccount("

    ".WebGUI::International::get(70)."

    ".$self->error); + } + + my $username = $session{form}{'authWebGUI.ldapId'}; + my $password = $session{form}{'authWebGUI.identifier'}; + my $passConfirm = $session{form}{'authWebGUI.identifierConfirm'}; + + my $error = $self->error if(!$self->validUsernameAndPassword($username,$password,$password)); + my ($profile, $temp, $warning) = WebGUI::Operation::Profile::validateProfileData(); + $error .= $temp; + + return $self->createAccount("

    ".WebGUI::International::get(70)."

    ".$error) unless ($error eq ""); + + #If Email address is not unique, a warning is displayed + if($warning ne "" && !$session{form}{confirm}){ + $session{form}{confirm} = 1; + return $self->createAccount('
  • '.WebGUI::International::get(1078)); + } + + my $uri = URI->new($session{setting}{ldapURL}); + my $ldap = Net::LDAP->new($uri->host, (port=>$uri->port)); + $ldap->bind; + my $search = $ldap->search (base => $uri->dn, filter=>$session{setting}{ldapId}."=".$username); + my $connectDN = ""; + if (defined $search->entry(0)) { + if ($session{setting}{ldapUserRDN} eq 'dn') { + $connectDN = $search->entry(0)->dn; + } else { + $connectDN = $search->entry(0)->get_value($session{setting}{ldapUserRDN}); + } + } + $ldap->unbind; + + my $u = WebGUI::User->new("new"); + $self->user($u); + my $userId = $u->userId; + $u->username($username); + $u->authMethod($self->authMethod); + $u->karma($session{setting}{karmaPerLogin},"Login","Just for logging in.") if ($session{setting}{useKarma}); + WebGUI::Operation::Profile::saveProfileFields($u,$profile); + + my $properties; + $properties->{connectDN} = $connectDN; + $properties->{ldapUrl} = $session{setting}{ldapURL}; + + $self->saveParams($userId,$self->authMethod,$properties); + + my $authInfo = "\n\n".WebGUI::International::get(50).": ".$username."\n".WebGUI::International::get(51).": ".$password."\n\n"; + WebGUI::MessageLog::addEntry($self->userId,"",WebGUI::International::get(870),$session{setting}{ldapWelcomeMessage}.$authInfo) if ($session{setting}{ldapSendWelcomeMessage}); + + WebGUI::Session::convertVisitorToUser($session{var}{sessionId},$userId); + $self->_logLogin($userId,"success"); + system(WebGUI::Macro::process($session{setting}{runOnRegistration})) if ($session{setting}{runOnRegistration} ne ""); + WebGUI::MessageLog::addInternationalizedEntry('',$session{setting}{onNewUserAlertGroup},'',536) if ($session{setting}{alertOnNewUser}); + return ""; +} + +#------------------------------------------------------------------- +sub deactivateAccount { + my $self = shift; + return $self->displayLogin if($self->userId == 1); + return WebGUI::Privilege::vitalComponent() if($self->userId < 26); + return WebGUI::Privilege::adminOnly() if(!$session{setting}{selfDeactivation}); + return $self->SUPER::deactivateAccount("deactivateAccountConfirm"); +} + +#------------------------------------------------------------------- +sub deactivateAccountConfirm { + my $self = shift; + return WebGUI::Privilege::vitalComponent() if ($self->userId < 26); + return $self->displayLogin unless ($session{setting}{selfDeactivation}); + return $self->SUPER::deactivateAccountConfirm; +} + +#------------------------------------------------------------------- +sub displayAccount { + my $self = shift; + my $vars; + return $self->displayLogin($_[0]) if ($self->userId == 1); + $vars->{displayTitle} = '

    '.WebGUI::International::get(61).'

    '; + $vars->{'account.message'} = WebGUI::International::get(856); + if($session{setting}{useKarma}){ + $vars->{'account.form.karma'} = $session{user}{karma}; + $vars->{'account.form.karma.label'} = WebGUI::International::get(537); + } + $vars->{'account.options'} = WebGUI::Operation::Profile::accountOptions(); + return WebGUI::Template::process(WebGUI::Template::get(1,'Auth/LDAP/Account'), $vars); +} + +#------------------------------------------------------------------- +sub displayLogin { + my $self = shift; + my $vars; + return $self->displayAccount($_[0]) if ($self->userId != 1); + $vars->{'login.message'} = $_[0] if ($_[0]); + return $self->SUPER::displayLogin("login",$vars); +} + +#------------------------------------------------------------------- + +=head2 editUserForm ( ) + + Creates user form elements specific to this Auth Method. + +=cut + +sub editUserForm { + my $self = shift; + return $self->addUserForm; +} + +#------------------------------------------------------------------- + +=head2 editUserFormSave ( ) + + Saves user elements unique to this authentication method + +=cut + +sub editUserFormSave { + my $self = shift; + return $self->addUserFormSave; +} + +#------------------------------------------------------------------- + +=head2 editUserSettingsForm ( ) + + Creates form elements for user settings page custom to this auth module + +=cut + +sub editUserSettingsForm { + my $self = shift; + my $f = WebGUI::HTMLForm->new; + $f->text("ldapUserRDN",WebGUI::International::get(9,'Auth/LDAP'),$session{setting}{ldapUserRDN}); + $f->text("ldapURL",WebGUI::International::get(5,'Auth/LDAP'),$session{setting}{ldapURL}); + $f->text("ldapId",WebGUI::International::get(6,'Auth/LDAP'),$session{setting}{ldapId}); + $f->text("ldapIdName",WebGUI::International::get(7,'Auth/LDAP'),$session{setting}{ldapIdName}); + $f->text("ldapPasswordName",WebGUI::International::get(8,'Auth/LDAP'),$session{setting}{ldapPasswordName}); + $f->yesNo( + -name=>"ldapSendWelcomeMessage", + -value=>$session{setting}{ldapSendWelcomeMessage}, + -label=>WebGUI::International::get(868) + ); + $f->textarea( + -name=>"ldapWelcomeMessage", + -value=>$session{setting}{ldapWelcomeMessage}, + -label=>WebGUI::International::get(869) + ); + return $f->printRowsOnly; +} + +#------------------------------------------------------------------- +sub login { + my $self = shift; + if(!$self->authenticate($session{form}{identifier})){ + WebGUI::ErrorHandler::security("login to account ".$session{form}{username}." with invalid information."); + return $self->displayLogin("

    ".WebGUI::International::get(70)."

    ".$self->error); + } + return $self->SUPER::login(); #Standard login routine for login +} + +#------------------------------------------------------------------- +sub new { + my $class = shift; + my $authMethod = $_[0]; + my $userId = $_[1]; + my @callable = ('createAccount','deactivateAccount','displayAccount','displayLogin','login','logout','createAccountSave','deactivateAccountConfirm'); + my $self = WebGUI::Auth->new($authMethod,$userId,\@callable); + bless $self, $class; +} + +1; + diff --git a/lib/WebGUI/Auth/WebGUI.pm b/lib/WebGUI/Auth/WebGUI.pm new file mode 100644 index 000000000..edd68e01e --- /dev/null +++ b/lib/WebGUI/Auth/WebGUI.pm @@ -0,0 +1,447 @@ +package WebGUI::Auth::WebGUI; + +#------------------------------------------------------------------- +# WebGUI is Copyright 2001-2003 Plain Black LLC. +#------------------------------------------------------------------- +# Please read the legal notices (docs/legal.txt) and the license +# (docs/license.txt) that came with this distribution before using +# this software. +#------------------------------------------------------------------- +# http://www.plainblack.com info@plainblack.com +#------------------------------------------------------------------- + +use Digest::MD5; +use strict; +use WebGUI::Auth; +use WebGUI::DateTime; +use WebGUI::HTMLForm; +use WebGUI::Mail; +use WebGUI::Session; +use WebGUI::SQL; +use WebGUI::Utility; + +our @ISA = qw(WebGUI::Auth); + +#------------------------------------------------------------------- + +=head2 addUserForm ( ) + + Creates user form elements specific to this Auth Method. + +=cut + +sub addUserForm { + my $self = shift; + my $userData = $self->getParams; + my $f = WebGUI::HTMLForm->new; + $f->password("authWebGUI.identifier",WebGUI::International::get(51),"password"); + $f->interval("authWebGUI.passwordTimeout",WebGUI::International::get(16,'Auth/WebGUI'),WebGUI::DateTime::secondsToInterval(($userData->{passwordTimeout} || $session{setting}{webguiPasswordTimeout}))); + return $f->printRowsOnly; +} + +#------------------------------------------------------------------- + +=head2 addUserFormSave ( ) + + Saves user elements unique to this authentication method + +=cut + +sub addUserFormSave { + my $self = shift; + my $properties; + unless ($session{form}{'authWebGUI.identifier'} eq "password") { + $properties->{identifier} = Digest::MD5::md5_base64($session{form}{'authWebGUI.identifier'}); + } + + $properties->{passwordTimeout} = WebGUI::DateTime::intervalToSeconds($session{form}{'authWebGUI.passwordTimeout_interval'},$session{form}{'authWebGUI.passwordTimeout_units'}); + $properties->{passwordLastUpdated} = time(); + if($session{setting}{webguiExpirePasswordOnCreation}){ + $properties->{passwordLastUpdated} = time() - $properties->{passwordTimeout}; + } + + $self->SUPER::addUserFormSave($properties); +} + +#------------------------------------------------------------------- +sub authenticate { + my $self = shift; + my ($identifier, $userData, $auth); + + $auth = $self->SUPER::authenticate(); + return 0 if !$auth; + + $identifier = $_[0]; + $userData = $self->getParams; + if ((Digest::MD5::md5_base64($identifier) eq $$userData{identifier}) && ($identifier ne "")) { + return 1; + } + $self->user(WebGUI::User->new(1)); + $self->error(WebGUI::International::get(68)); + return 0; +} + +#------------------------------------------------------------------- +sub createAccount { + my $self = shift; + my $vars; + if ($session{user}{userId} != 1) { + return $self->displayAccount; + } elsif (!$session{setting}{anonymousRegistration}) { + return $self->displayLogin; + } + $vars->{'create.message'} = $_[0] if ($_[0]); + $vars->{'create.form.username'} = WebGUI::Form::text({"name"=>"authWebGUI.username","value"=>$session{form}{"authWebGUI.username"}}); + $vars->{'create.form.username.label'} = WebGUI::International::get(50); + $vars->{'create.form.password'} = WebGUI::Form::password({"name"=>"authWebGUI.identifier","value"=>$session{form}{"authWebGUI.identifier"}}); + $vars->{'create.form.password.label'} = WebGUI::International::get(51); + $vars->{'create.form.passwordConfirm'} = WebGUI::Form::password({"name"=>"authWebGUI.identifierConfirm","value"=>$session{form}{"authWebGUI.identifierConfirm"}}); + $vars->{'create.form.passwordConfirm.label'} = WebGUI::International::get(2,'Auth/WebGUI'); + $vars->{'create.form.hidden'} = WebGUI::Form::hidden({"name"=>"confirm","value"=>$session{form}{confirm}}); + return $self->SUPER::createAccount("createAccountSave",$vars); +} + +#------------------------------------------------------------------- +sub createAccountSave { + my $self = shift; + + return $self->displayAccount if ($session{user}{userId} != 1); + + my $username = $session{form}{'authWebGUI.username'}; + my $password = $session{form}{'authWebGUI.identifier'}; + my $passConfirm = $session{form}{'authWebGUI.identifierConfirm'}; + + my $error = $self->error if(!$self->validUsernameAndPassword($username,$password,$passConfirm)); + my ($profile, $temp, $warning) = WebGUI::Operation::Profile::validateProfileData(); + $error .= $temp; + + return $self->createAccount($error) unless ($error eq ""); + + #If Email address is not unique, a warning is displayed + if($warning ne "" && !$session{form}{confirm}){ + $session{form}{confirm} = 1; + return $self->createAccount('
  • '.WebGUI::International::get(1078)); + } + + my $lastUpdated = time(); + + my $u = WebGUI::User->new("new"); + $self->user($u); + my $userId = $u->userId; + $u->username($username); + $u->authMethod($self->authMethod); + $u->karma($session{setting}{karmaPerLogin},"Login","Just for logging in.") if ($session{setting}{useKarma}); + WebGUI::Operation::Profile::saveProfileFields($u,$profile); + + my %properties; + $properties{identifier} = Digest::MD5::md5_base64($password); + $properties{passwordLastUpdated} = $lastUpdated; + $properties{passwordTimeout} = $session{setting}{webguiPasswordTimeout}; + $self->saveParams($userId,$self->authMethod,\%properties); + my $authInfo = "\n\n".WebGUI::International::get(50).": ".$username."\n".WebGUI::International::get(51).": ".$password."\n\n"; + WebGUI::MessageLog::addEntry($self->userId,"",WebGUI::International::get(870),$session{setting}{webguiWelcomeMessage}.$authInfo) if ($session{setting}{webguiSendWelcomeMessage}); + + WebGUI::Session::convertVisitorToUser($session{var}{sessionId},$userId); + $self->_logLogin($userId,"success"); + system(WebGUI::Macro::process($session{setting}{runOnRegistration})) if ($session{setting}{runOnRegistration} ne ""); + WebGUI::MessageLog::addInternationalizedEntry('',$session{setting}{onNewUserAlertGroup},'',536) if ($session{setting}{alertOnNewUser}); + return ""; +} + +#------------------------------------------------------------------- +sub deactivateAccount { + my $self = shift; + return $self->displayLogin if($self->userId == 1); + return WebGUI::Privilege::vitalComponent() if($self->userId < 26); + return WebGUI::Privilege::adminOnly() if(!$session{setting}{selfDeactivation}); + return $self->SUPER::deactivateAccount("deactivateAccountConfirm"); +} + +#------------------------------------------------------------------- +sub deactivateAccountConfirm { + my $self = shift; + return WebGUI::Privilege::vitalComponent() if ($self->userId < 26); + return $self->displayLogin unless ($session{setting}{selfDeactivation}); + return $self->SUPER::deactivateAccountConfirm; +} + +#------------------------------------------------------------------- +sub displayAccount { + my $self = shift; + my $vars; + return $self->displayLogin($_[0]) if ($self->userId == 1); + $vars->{'account.message'} = $_[0] if ($_[0]); + $vars->{'account.form.username'} = WebGUI::Form::text({"name"=>"authWebGUI.username","value"=>$self->username}); + $vars->{'account.form.username.label'} = WebGUI::International::get(50); + $vars->{'account.form.password'} = WebGUI::Form::password({"name"=>"authWebGUI.identifier","value"=>"password"}); + $vars->{'account.form.password.label'} = WebGUI::International::get(51); + $vars->{'account.form.passwordConfirm'} = WebGUI::Form::password({"name"=>"authWebGUI.identifierConfirm","value"=>"password"}); + $vars->{'account.form.passwordConfirm.label'} = WebGUI::International::get(2,'Auth/WebGUI'); + return $self->SUPER::displayAccount("updateAccount",$vars); +} + +#------------------------------------------------------------------- + +=head2 displayLogin ( ) + + The initial login screen an unauthenticated user sees + +=cut + +sub displayLogin { + my $self = shift; + my $vars; + return $self->displayAccount($_[0]) if ($self->userId != 1); + $vars->{'login.message'} = $_[0] if ($_[0]); + return $self->SUPER::displayLogin("login",$vars); +} + +#------------------------------------------------------------------- + +=head2 editUserForm ( ) + + Creates user form elements specific to this Auth Method. + +=cut + +sub editUserForm { + my $self = shift; + return $self->addUserForm; +} + +#------------------------------------------------------------------- + +=head2 editUserFormSave ( ) + + Saves user elements unique to this authentication method + +=cut + +sub editUserFormSave { + my $self = shift; + my $properties; + my $userData = $self->getParams; + unless (!$session{form}{'authWebGUI.identifier'} || $session{form}{'authWebGUI.identifier'} eq "password") { + $properties->{identifier} = Digest::MD5::md5_base64($session{form}{'authWebGUI.identifier'}); + if($userData->{identifier} ne $properties->{identifier}){ + $properties->{passwordLastUpdated} = time(); + } + } + $properties->{passwordTimeout} = WebGUI::DateTime::intervalToSeconds($session{form}{'authWebGUI.passwordTimeout_interval'},$session{form}{'authWebGUI.passwordTimeout_units'}); + $self->SUPER::editUserFormSave($properties); +} + +#------------------------------------------------------------------- + +=head2 editUserSettingsForm ( ) + + Creates form elements for user settings page custom to this auth module + +=cut + +sub editUserSettingsForm { + my $self = shift; + my $f = WebGUI::HTMLForm->new; + $f->text( + -name=>"webguiPasswordLength", + -value=>$session{setting}{webguiPasswordLength}, + -label=>WebGUI::International::get(15,'Auth/WebGUI'), + -size=>5, + -maxLength=>5, + ); + $f->interval("webguiPasswordTimeout",WebGUI::International::get(16,'Auth/WebGUI'),WebGUI::DateTime::secondsToInterval($session{setting}{webguiPasswordTimeout})); + $f->yesNo( + -name=>"webguiExpirePasswordOnCreation", + -value=>$session{setting}{webguiExpirePasswordOnCreation}, + -label=>WebGUI::International::get(9,'Auth/WebGUI') + ); + $f->yesNo( + -name=>"webguiSendWelcomeMessage", + -value=>$session{setting}{webguiSendWelcomeMessage}, + -label=>WebGUI::International::get(868) + ); + $f->textarea( + -name=>"webguiWelcomeMessage", + -value=>$session{setting}{webguiWelcomeMessage}, + -label=>WebGUI::International::get(869) + ); + $f->yesNo( + -name=>"webguiPasswordRecovery", + -value=>$session{setting}{webguiPasswordRecovery}, + -label=>WebGUI::International::get(6,'Auth/WebGUI') + ); + $f->textarea("webguiRecoverPasswordEmail",WebGUI::International::get(134),$session{setting}{webguiRecoverPasswordEmail}); + return $f->printRowsOnly; +} + +#------------------------------------------------------------------- +sub login { + my $self = shift; + if(!$self->authenticate($session{form}{identifier})){ + WebGUI::ErrorHandler::security("login to account ".$session{form}{username}." with invalid information."); + return $self->displayLogin("

    ".WebGUI::International::get(70)."

    ".$self->error); + } + + my $userData = $self->getParams; + if($self->getSetting("passwordTimeout") && $userData->{passwordTimeout}){ + my $expireTime = $userData->{passwordLastUpdated} + $userData->{passwordTimeout}; + if(time() >= $expireTime){ + $session{form}{uid} = $self->userId; + $self->logout; + return $self->resetExpiredPassword; + } + } + + return $self->SUPER::login(); +} + +#------------------------------------------------------------------- +sub new { + my $class = shift; + my $authMethod = $_[0]; + my $userId = $_[1]; + my @callable = ('createAccount','deactivateAccount','displayAccount','displayLogin','login','logout','recoverPassword','resetExpiredPasswordSave','recoverPasswordFinish','createAccountSave','deactivateAccountConfirm','resetExpiredPasswordSave','updateAccount'); + my $self = WebGUI::Auth->new($authMethod,$userId,\@callable); + bless $self, $class; +} + + +#------------------------------------------------------------------- +sub recoverPassword { + my $self = shift; + my $vars; + return $self->displayLogin if($self->userId != 1); + $vars->{'recover.message'} = $_[0] if ($_[0]); + $vars->{'recover.form.email'} = WebGUI::Form::text({"name"=>"email"}); + $vars->{'recover.form.email.label'} = WebGUI::International::get(56); + $self->SUPER::recoverPassword("recoverPasswordFinish",$vars); + return WebGUI::Template::process(WebGUI::Template::get(1,'Auth/WebGUI/Recovery'), $vars); +} + +#------------------------------------------------------------------- +sub recoverPasswordFinish { + my $self = shift; + return $self->recoverPassword('') if ($session{form}{email} eq ""); + return $self->displayLogin unless ($session{setting}{webguiPasswordRecovery}); + + my($sth,$username,$userId,$password,$flag,$message,$output,$encryptedPassword,$authMethod); + $sth = WebGUI::SQL->read("select users.username,users.userId from users, userProfileData where users.userId=userProfileData.userId and + users.authMethod='WebGUI' and userProfileData.fieldName='email' and userProfileData.fieldData=".quote($session{form}{email})); + $flag = 0; + while (($username,$userId) = $sth->array) { + my $len = $session{setting}{webguiPasswordLength} || 6; + my $len = 6; + $password = ""; + for(my $i = 0; $i < $len; $i++) { + $password .= chr(ord('A') + randint(32)); + } + $encryptedPassword = Digest::MD5::md5_base64($password); + $self->saveParams($userId,"WebGUI",{identifier=>$encryptedPassword}); + $message = $session{setting}{webguiRecoverPasswordEmail}; + $message .= "\n".WebGUI::International::get(50).": ".$username."\n"; + $message .= WebGUI::International::get(51).": ".$password."\n"; + WebGUI::Mail::send($session{form}{email},WebGUI::International::get(74),$message); + $flag++; + } + $sth->finish(); + + return $self->displayLogin('') if($flag); + return $self->recoverPassword(''); +} + +#------------------------------------------------------------------- +sub resetExpiredPassword { + my $self = shift; + my $vars; + + $vars->{displayTitle} = '

    '.WebGUI::International::get(8,'Auth/WebGUI').'

    '; + $vars->{'expired.message'} = $_[0] if($_[0]); + $vars->{'expired.form.header'} = "\n\n".WebGUI::Form::formHeader({}); + $vars->{'expired.form.hidden'} = WebGUI::Form::hidden({"name"=>"op","value"=>"auth"}); + $vars->{'expired.form.hidden'} .= WebGUI::Form::hidden({"name"=>"method","value"=>"resetExpiredPasswordSave"}); + $vars->{'expired.form.hidden'} .= WebGUI::Form::hidden({"name"=>"uid","value"=>$session{form}{uid}}); + + $vars->{'expired.form.oldPassword'} = WebGUI::Form::password({"name"=>"oldPassword"}); + $vars->{'expired.form.oldPassword.label'} = WebGUI::International::get(10,'Auth/WebGUI'); + $vars->{'expired.form.password'} = WebGUI::Form::password({"name"=>"identifier"}); + $vars->{'expired.form.password.label'} = WebGUI::International::get(11,'Auth/WebGUI'); + $vars->{'expired.form.passwordConfirm'} = WebGUI::Form::password({"name"=>"identifierConfirm"}); + $vars->{'expired.form.passwordConfirm.label'} = WebGUI::International::get(2,'Auth/WebGUI'); + $vars->{'expired.form.submit'} = WebGUI::Form::submit({}); + $vars->{'expired.form.footer'} = ""; + + return WebGUI::Template::process(WebGUI::Template::get(1,'Auth/WebGUI/Expired'), $vars); +} + +#------------------------------------------------------------------- +sub resetExpiredPasswordSave { + my $self = shift; + my ($error,$u,$properties,$msg); + + $u = WebGUI::User->new($session{form}{uid}); + $session{form}{username} = $u->username; + + $error .= $self->error if(!$self->authenticate($session{form}{oldPassword})); + $error .= '
  • '.WebGUI::International::get(5,'Auth/WebGUI') if($session{form}{identifier} eq "password"); + $error .= '
  • '.WebGUI::International::get(12,'Auth/WebGUI') if ($session{form}{oldPassword} eq $session{form}{identifier}); + $error .= $self->error if(!$self->_isValidPassword($session{form}{identifier},$session{form}{identifierConfirm})); + + return $self->resetExpiredPassword("

    ".WebGUI::International::get(70)."

    ".$error) if($error ne ""); + + $properties->{identifier} = Digest::MD5::md5_base64($session{form}{identifier}); + $properties->{passwordLastUpdated} = time(); + + $self->saveParams($u->userId,$self->authMethod,$properties); + + $msg = $self->login; + if($msg eq ""){ + $msg = "
  • ".WebGUI::International::get(17,'Auth/WebGUI'); + } + return $self->displayLogin($msg); +} + +#------------------------------------------------------------------- + +=head2 updateAccount ( ) + + Sets properties to update and passes them to the superclass + +=cut + +sub updateAccount { + my $self = shift; + + my $username = $session{form}{'authWebGUI.username'}; + my $password = $session{form}{'authWebGUI.identifier'}; + my $passConfirm = $session{form}{'authWebGUI.identifierConfirm'}; + my $display = '
  • '.WebGUI::International::get(81).'

    '; + + if($self->userId == 1){ + return $self->displayLogin; + } + + if(!$self->validUsernameAndPassword($username,$password,$passConfirm)){ + $display = $self->error; #overwrite display + } + + my $properties; + my $u = $self->user; + $u->username($username); + my $userData = $self->getParams; + + unless ($password eq "password") { + $properties->{identifier} = Digest::MD5::md5_base64($password); + if($userData->{identifier} ne $properties->{identifier}){ + $properties->{passwordLastUpdated} = time(); + } + } + + $session{form}{uid} = $u->userId; + $self->saveParams($u->userId,$self->authMethod,$properties); + WebGUI::Session::refreshUserInfo($u->userId); + + return $self->displayAccount($display); +} + +1; + diff --git a/lib/WebGUI/Operation.pm b/lib/WebGUI/Operation.pm index 17591d32f..373695281 100644 --- a/lib/WebGUI/Operation.pm +++ b/lib/WebGUI/Operation.pm @@ -11,7 +11,8 @@ package WebGUI::Operation; #------------------------------------------------------------------- use strict; -use WebGUI::Operation::Account; +#use WebGUI::Operation::Account; +use WebGUI::Operation::Auth; use WebGUI::Operation::Admin; use WebGUI::Operation::Clipboard; use WebGUI::Operation::Collateral; @@ -19,8 +20,10 @@ use WebGUI::Operation::DatabaseLink; use WebGUI::Operation::Group; use WebGUI::Operation::Help; use WebGUI::Operation::International; +use WebGUI::Operation::MessageLog; use WebGUI::Operation::Package; use WebGUI::Operation::Page; +use WebGUI::Operation::Profile; use WebGUI::Operation::ProfileSettings; use WebGUI::Operation::Replacements; use WebGUI::Operation::Root; @@ -28,6 +31,7 @@ use WebGUI::Operation::Scratch; use WebGUI::Operation::Search; use WebGUI::Operation::Settings; use WebGUI::Operation::Statistics; +use WebGUI::Operation::Style; use WebGUI::Operation::Template; use WebGUI::Operation::Theme; use WebGUI::Operation::Trash; diff --git a/lib/WebGUI/Operation/Auth.pm b/lib/WebGUI/Operation/Auth.pm new file mode 100644 index 000000000..4b138d19f --- /dev/null +++ b/lib/WebGUI/Operation/Auth.pm @@ -0,0 +1,103 @@ +package WebGUI::Operation::Auth; + +#------------------------------------------------------------------- +# WebGUI is Copyright 2001-2003 Plain Black LLC. +#------------------------------------------------------------------- +# Please read the legal notices (docs/legal.txt) and the license +# (docs/license.txt) that came with this distribution before using +# this software. +#------------------------------------------------------------------- +# http://www.plainblack.com info@plainblack.com +#------------------------------------------------------------------- +# The Operation WebGUI::Operation::Auth is responsible for instansiating +# and calling methods in the Auth Module. This method also has some core +# logic that defines how Authentication should happen + +use Exporter; +use strict qw(vars subs); +use URI; +use WebGUI::ErrorHandler; +use WebGUI::Session; +use WebGUI::SQL; +use WebGUI::URL; +use WebGUI::User; +use WebGUI::Utility; + +our @ISA = qw(Exporter); +our @EXPORT = qw(&www_auth &www_displayLogin &www_login &www_displayAccount &www_createAccount &www_deactivateAccount &www_logout &www_recoverPassword &www_init); +#------------------------------------------------------------------- + +=head2 getInstance ( ) + +Get the instance of this object or create a new instance if none exists + +=cut + +sub getInstance { + #Get Auth Settings + my $authMethod = $session{user}{authMethod} || $session{setting}{authMethod}; + $authMethod = $session{setting}{authMethod} if($session{user}{userId} == 1); + $authMethod = $_[0] if($_[0] && isIn($_[0], @{$session{config}{authMethods}})); + my $userId = $_[1]; + #Create Auth Object + my $cmd = "WebGUI::Auth::".$authMethod; + my $auth = eval{$cmd->new($authMethod,$userId)}; + WebGUI::ErrorHandler::fatalError("Couldn't instanciate authentication module: $authMethod. Root cause: ".$@) if($@); + return $auth; +} + +#------------------------------------------------------------------- +sub www_auth { + my $auth; + ($auth) = WebGUI::SQL->quickArray("select authMethod from users where username=".quote($session{form}{username})) if($session{form}{username}); + my $authMethod = getInstance($auth); + my $methodCall = $session{form}{method} || $_[0]; + if(!$authMethod->isCallable($methodCall)){ + WebGUI::ErrorHandler::security("access uncallable auth method on page '".$session{page}{title}."' [".$session{page}{pageId}."]."); + return WebGUI::International::get(1077); + } + return $authMethod->$methodCall; +} + +#------------------------------------------------------------------- +sub www_createAccount { + return www_auth("createAccount"); +} + +#------------------------------------------------------------------- +sub www_deactivateAccount { + return www_auth("deactivateAccount"); +} + +#------------------------------------------------------------------- +sub www_displayAccount { + return www_auth("displayAccount"); +} + +#------------------------------------------------------------------- +sub www_displayLogin { + return www_auth("displayLogin"); +} + +#------------------------------------------------------------------- +sub www_init { + return www_auth("init"); +} + +#Deprecated. Kept for backwards compatibility. Use op=auth&method=login +#------------------------------------------------------------------- +sub www_login { + return www_auth("login"); +} + +#------------------------------------------------------------------- +sub www_logout { + return www_auth("logout"); +} + +#------------------------------------------------------------------- +sub www_recoverPassword { + return www_auth("recoverPassword"); +} + +1; \ No newline at end of file diff --git a/lib/WebGUI/Operation/MessageLog.pm b/lib/WebGUI/Operation/MessageLog.pm new file mode 100644 index 000000000..5579b3e6c --- /dev/null +++ b/lib/WebGUI/Operation/MessageLog.pm @@ -0,0 +1,109 @@ +package WebGUI::Operation::MessageLog; + +#------------------------------------------------------------------- +# WebGUI is Copyright 2001-2003 Plain Black LLC. +#------------------------------------------------------------------- +# Please read the legal notices (docs/legal.txt) and the license +# (docs/license.txt) that came with this distribution before using +# this software. +#------------------------------------------------------------------- +# http://www.plainblack.com info@plainblack.com +#------------------------------------------------------------------- + +use Exporter; +use strict qw(vars subs); +use URI; +use WebGUI::DateTime; +use WebGUI::ErrorHandler; +use WebGUI::FormProcessor; +use WebGUI::HTMLForm; +use WebGUI::International; +use WebGUI::Macro; +use WebGUI::Mail; +use WebGUI::MessageLog; +use WebGUI::Paginator; +use WebGUI::Privilege; +use WebGUI::Session; +use WebGUI::SQL; +use WebGUI::URL; +use WebGUI::User; +use WebGUI::Utility; +use WebGUI::Operation::Profile; + +our @ISA = qw(Exporter); +our @EXPORT = qw(&www_viewMessageLog &www_viewMessageLogMessage); + +#------------------------------------------------------------------- +sub www_viewMessageLog { + my (%status, @data, $output, $sth, @row, $i, $p); + if (WebGUI::Privilege::isInGroup(2,$session{user}{userId})) { + %status = (notice=>WebGUI::International::get(551),pending=>WebGUI::International::get(552),completed=>WebGUI::International::get(350)); + $output = '

    '.WebGUI::International::get(159).'

    '; + $sth = WebGUI::SQL->read("select messageLogId,subject,url,dateOfEntry,status from messageLog where userId=$session{user}{userId} order by dateOfEntry desc"); + while (@data = $sth->array) { + $row[$i] = ''; + $row[$i] .= ''.$data[1].''; + $row[$i] .= ''; + if ($data[2] ne "") { + $data[2] = WebGUI::URL::append($data[2],'mlog='.$data[0]); + $row[$i] .= ''; + } + $row[$i] .= $status{$data[4]}; + if ($data[2] ne "") { + $row[$i] .= ''; + } + $row[$i] .= ''.epochToHuman($data[3]).''; + $i++; + } + $sth->finish; + $p = WebGUI::Paginator->new(WebGUI::URL::page('op=viewMessageLog'),\@row); + $output .= ''; + $output .= ' + + '; + if ($p->getPage($session{form}{pn}) eq "") { + $output .= ''; + } else { + $output .= $p->getPage($session{form}{pn}); + } + $output .= '
    '.WebGUI::International::get(351).''.WebGUI::International::get(553).''.WebGUI::International::get(352).'
    '.WebGUI::International::get(353).'
    '; + $output .= $p->getBarSimple($session{form}{pn}); + $output .= WebGUI::Operation::Profile::accountOptions(); + } else { + $output = WebGUI::Privilege::insufficient(); + } + return $output; +} + +#------------------------------------------------------------------- +sub www_viewMessageLogMessage { + my (%status, %data, $output, $sth, @row, $i, $p); + tie %data, 'Tie::CPHash'; + if (WebGUI::Privilege::isInGroup(2,$session{user}{userId})) { + %status = (notice=>WebGUI::International::get(551),pending=>WebGUI::International::get(552),completed=>WebGUI::International::get(350)); + $output = '

    '.WebGUI::International::get(159).'

    '; + %data = WebGUI::SQL->quickHash("select * from messageLog where messageLogId=$session{form}{mlog} and userId=$session{user}{userId}"); + $output .= ''.$data{subject}.'
    '; + $output .= epochToHuman($data{dateOfEntry}).'
    '; + if ($data{url} ne "" && $data{status} eq 'pending') { + $data{url} = WebGUI::URL::append($data{url},'mlog='.$data{messageLogId}); + $output .= ''; + } + $output .= $status{$data{status}}.'
    '; + if ($data{url} ne "") { + $output .= '
    '; + } + unless ($data{message} =~ /\/ig || $data{message} =~ /\/ig || $data{message} =~ /\/ig) { + $data{message} =~ s/\n/\/g; + } + $output .= '
    '.$data{message}.'

    '; + if ($data{url} ne "" && $data{status} eq 'pending') { + $output .= ''.WebGUI::International::get(554).' · '; + } + $output .= ''.WebGUI::International::get(354).'

    '; + $output .= WebGUI::Operation::Profile::_accountOptions(); + } else { + $output = WebGUI::Privilege::insufficient(); + } + return $output; +} \ No newline at end of file diff --git a/lib/WebGUI/Operation/Profile.pm b/lib/WebGUI/Operation/Profile.pm new file mode 100644 index 000000000..613dcffae --- /dev/null +++ b/lib/WebGUI/Operation/Profile.pm @@ -0,0 +1,281 @@ +package WebGUI::Operation::Profile; + +#------------------------------------------------------------------- +# WebGUI is Copyright 2001-2003 Plain Black LLC. +#------------------------------------------------------------------- +# Please read the legal notices (docs/legal.txt) and the license +# (docs/license.txt) that came with this distribution before using +# this software. +#------------------------------------------------------------------- +# http://www.plainblack.com info@plainblack.com +#------------------------------------------------------------------- + +use Exporter; +use strict qw(vars subs); +use URI; +use WebGUI::Operation::Auth; +use WebGUI::DateTime; +use WebGUI::ErrorHandler; +use WebGUI::FormProcessor; +use WebGUI::HTMLForm; +use WebGUI::International; +use WebGUI::Macro; +use WebGUI::Mail; +use WebGUI::MessageLog; +use WebGUI::Paginator; +use WebGUI::Privilege; +use WebGUI::Session; +use WebGUI::SQL; +use WebGUI::URL; +use WebGUI::User; +use WebGUI::Utility; + +our @ISA = qw(Exporter); +our @EXPORT = qw(&www_editProfile &www_editProfileSave &www_viewProfile); + +#------------------------------------------------------------------- + sub accountOptions { + my ($output); + $output = '

    '; + return $output; +} + +#------------------------------------------------------------------- +# Builds Extra form requirements for anonymous registration. +sub getRequiredProfileFields { + my ($f,$a,$method,$label,$default,$values,$data,@array); + + #$f = WebGUI::HTMLForm->new(); + + $a = WebGUI::SQL->read("select * from userProfileField, userProfileCategory where userProfileField.profileCategoryId=userProfileCategory.profileCategoryId and + userProfileField.required=1 order by userProfileCategory.sequenceNumber,userProfileField.sequenceNumber"); + while($data = $a->hashRef) { + my %hash = (); + $method = $data->{dataType}; + $label = eval $data->{fieldLabel}; + $default = eval $data->{dataDefault}; + if ($method eq "selectList") { + $values = eval $data->{dataValues}; + # note: this big if statement doesn't look elegant, but doing regular ORs caused problems with the array reference. + if ($session{form}{$data->{fieldName}}) { + $default = [$session{form}{$data->{fieldName}}]; + } elsif ($session{user}{$data->{fieldName}}) { + $default = [$session{user}{$data->{fieldName}}]; + } + $hash{'profile.formElement'} = WebGUI::Form::selectList({ + "name"=>$data->{fieldName}, + "options"=>$values, + "value"=>$default + }); + } else { + if ($session{form}{$data->{fieldName}}) { + $default = $session{form}{$data->{fieldName}}; + } elsif (exists $session{user}{$data->{fieldName}}) { + $default = $session{user}{$data->{fieldName}}; + } + my $cmd = 'WebGUI::Form::'.$method.'({"name"=>$data->{fieldName},"value"=>$default})'; + $hash{'profile.formElement'} = eval($cmd); + + } + $hash{'profile.formElement.label'} = $label; + push(@array,\%hash) + } + $a->finish; + return \@array; +} + +#------------------------------------------------------------------- +=head2 isDuplicateEmail ( ) + + Checks the value of the email address passed in to see if it is duplicated in the system. Returns true of false. Will return false if the email address passed in is + same as the email address of the current user. + +=over + +=item email + + email address to check for duplication + +=back + +=cut + +sub isDuplicateEmail { + my $email = shift; + my ($otherEmail) = WebGUI::SQL->quickArray("select count(*) from userProfileData where fieldName='email' and fieldData = ".quote($email)." and userId <> ".$session{user}{userId}); + return ($otherEmail > 0); +} + +#------------------------------------------------------------------- +sub saveProfileFields { + my $u = shift; + my $profile = shift; + + foreach my $fieldName (keys %{$profile}) { + $u->profileField($fieldName,${$profile}{$fieldName}); + } +} + +#------------------------------------------------------------------- +sub validateProfileData { + my (%data, $error, $a, %field, $warning); + tie %field, 'Tie::CPHash'; + $a = WebGUI::SQL->read("select * from userProfileField,userProfileCategory where userProfileField.profileCategoryId=userProfileCategory.profileCategoryId + and userProfileCategory.editable=1 and userProfileField.editable=1 order by userProfileCategory.sequenceNumber,userProfileField.sequenceNumber"); + while (%field = $a->hash) { + $data{$field{fieldName}} = WebGUI::FormProcessor::process($field{fieldName},$field{dataType}); + if ($field{required} && $data{$field{fieldName}} eq "") { + $error .= '
  • '.(eval $field{fieldLabel}).' '.WebGUI::International::get(451); + }elsif($field{fieldName} eq "email" && isDuplicateEmail($data{$field{fieldName}})){ + $warning .= '
  • '.WebGUI::International::get(1072); + } + } + $a->finish; + return (\%data, $error, $warning); +} + + +#------------------------------------------------------------------- +sub www_editProfile { + my ($output, $f, $a, %data, $method, $values, $category, $label, $default, $previousCategory, $subtext); + return WebGUI::Operation::Auth::www_displayLogin() if($session{user}{userId} == 1); + + tie %data, 'Tie::CPHash'; + $output .= '

    '.WebGUI::International::get(338).'

    '; + $f = WebGUI::HTMLForm->new; + $f->hidden("op","editProfileSave"); + $f->hidden("uid",$session{user}{userId}); + $a = WebGUI::SQL->read("select * from userProfileField,userProfileCategory where userProfileField.profileCategoryId=userProfileCategory.profileCategoryId + and userProfileCategory.editable=1 and userProfileField.editable=1 order by userProfileCategory.sequenceNumber,userProfileField.sequenceNumber"); + + while(%data = $a->hash) { + $category = eval $data{categoryName}; + if ($category ne $previousCategory) { + $f->raw(''.$category.''); + } + $values = eval $data{dataValues}; + $method = $data{dataType}; + $label = eval $data{fieldLabel}; + $subtext = ""; + if ($data{required}) { + $subtext = "*"; + } + + $default = eval $data{dataDefault}; + + if ($method eq "selectList") { + # note: this big if statement doesn't look elegant, but doing regular ORs caused problems with the array reference. + if ($session{form}{$data{fieldName}}) { + $default = [$session{form}{$data{fieldName}}]; + } elsif ($session{user}{$data{fieldName}}) { + $default = [$session{user}{$data{fieldName}}]; + } + + $f->select( + -name=>$data{fieldName}, + -options=>$values, + -label=>$label, + -value=>$default, + -subtext=>$subtext + ); + } else { + if ($session{form}{$data{fieldName}}) { + $default = $session{form}{$data{fieldName}}; + } elsif (exists $session{user}{$data{fieldName}}) { + $default = $session{user}{$data{fieldName}}; + } + + $f->$method( + -name=>$data{fieldName}, + -label=>$label, + -value=>$default, + -subtext=>$subtext + ); + } + $previousCategory = $category; + } + $a->finish; + $f->submit; + $output .= $f->print; + $output .= accountOptions(); + return $output; +} + +#------------------------------------------------------------------- +sub www_editProfileSave { + my ($profile, $fieldName, $error, $u, $warning); + return WebGUI::Operation::Auth::www_displayLogin() if ($session{user}{userId} == 1); + + ($profile, $error, $warning) = validateProfileData(); + $error .= $warning; + + return ''.www_editProfile() if($error ne ""); + + $u = WebGUI::User->new($session{user}{userId}); + foreach $fieldName (keys %{$profile}) { + $u->profileField($fieldName,${$profile}{$fieldName}); + } + return WebGUI::Operation::Auth::www_displayAccount(); +} + +#------------------------------------------------------------------- +sub www_viewProfile { + my ($a, %data, $category, $label, $value, $previousCategory, $output, $u, %gender); + %gender = ('neuter'=>WebGUI::International::get(403),'male'=>WebGUI::International::get(339),'female'=>WebGUI::International::get(340)); + $u = WebGUI::User->new($session{form}{uid}); + my $header = '

    '.WebGUI::International::get(347).' '.$u->username.'

    '; + return WebGUI::Privilege::notMember() if($u->username eq ""); + return $header.WebGUI::International::get(862) if($u->profileField("publicProfile") < 1); + return WebGUI::Privilege::insufficient() if(!WebGUI::Privilege::isInGroup(2)); + $output = $header; + $output .= ''; + $a = WebGUI::SQL->read("select * from userProfileField,userProfileCategory where userProfileField.profileCategoryId=userProfileCategory.profileCategoryId + and userProfileCategory.visible=1 and userProfileField.visible=1 order by userProfileCategory.sequenceNumber,userProfileField.sequenceNumber"); + while (%data = $a->hash) { + $category = eval $data{categoryName}; + if ($category ne $previousCategory) { + $output .= ''; + } + $label = eval $data{fieldLabel}; + if ($data{dataValues}) { + $value = eval $data{dataValues}; + $value = ${$value}{$u->profileField($data{fieldName})}; + } else { + $value = $u->profileField($data{fieldName}); + } + if ($data{dataType} eq "date") { + $value = WebGUI::DateTime::epochToHuman($value,"%z"); + } + unless ($data{fieldName} eq "email" and $u->profileField("publicEmail") < 1) { + $output .= ''; + } + $previousCategory = $category; + } + $a->finish; + $output .= '
    '.$category.'
    '.$label.''.$value.'
    '; + if ($session{user}{userId} == $session{form}{uid}) { + $output .= accountOptions(); + } + return $output; + +} \ No newline at end of file diff --git a/lib/WebGUI/Operation/Settings.pm b/lib/WebGUI/Operation/Settings.pm index 5c9a8142e..5e4e2875f 100644 --- a/lib/WebGUI/Operation/Settings.pm +++ b/lib/WebGUI/Operation/Settings.pm @@ -12,7 +12,6 @@ package WebGUI::Operation::Settings; use Exporter; use strict qw(vars subs); -use WebGUI::Authentication; use WebGUI::DateTime; use WebGUI::HTMLForm; use WebGUI::Icon; @@ -65,6 +64,7 @@ sub www_editContentSettings { $f->hidden("op","saveSettings"); $f->select("defaultPage",$pages,WebGUI::International::get(527),[$session{setting}{defaultPage}]); $f->select("notFoundPage",$pages,WebGUI::International::get(141),[$session{setting}{notFoundPage}]); + $f->text("docTypeDec",WebGUI::International::get(398),$session{setting}{docTypeDec}); $f->text( -name=>"favicon", -label=>WebGUI::International::get(897), @@ -135,29 +135,46 @@ sub www_editMiscSettings { #------------------------------------------------------------------- sub www_editUserSettings { - return WebGUI::Privilege::adminOnly() unless (WebGUI::Privilege::isInGroup(3)); - my ($output, $f, $cmd, $html, $options); - $output .= helpIcon(2); - $output .= '

    '.WebGUI::International::get(117).'

    '; - $f = WebGUI::HTMLForm->new; - $f->hidden("op","saveSettings"); - $f->yesNo("anonymousRegistration",WebGUI::International::get(118),$session{setting}{anonymousRegistration}); - $f->text("runOnRegistration",WebGUI::International::get(559),$session{setting}{runOnRegistration}); - $f->yesNo("useKarma",WebGUI::International::get(539),$session{setting}{useKarma}); - $f->integer("karmaPerLogin",WebGUI::International::get(540),$session{setting}{karmaPerLogin}); - $f->interval("sessionTimeout",WebGUI::International::get(142),WebGUI::DateTime::secondsToInterval($session{setting}{sessionTimeout})); - $f->yesNo("selfDeactivation",WebGUI::International::get(885),$session{setting}{selfDeactivation}); - $f->yesNo("encryptLogin",WebGUI::International::get(1006),$session{setting}{encryptLogin}); + return WebGUI::Privilege::adminOnly() unless (WebGUI::Privilege::isInGroup(3)); + my ($output, $f, $cmd, $html, $options); + $output .= helpIcon(2); + $output .= '

    '.WebGUI::International::get(117).'

    '; + $output .= WebGUI::Form::_javascriptFile("swapLayers.js"); + $output .= ''; + $f = WebGUI::HTMLForm->new("","","","","","border='0' cellpadding='0' cellspacing='0' width='800'"); + $f->hidden("op","saveSettings"); + $f->raw('  '); + $f->yesNo("anonymousRegistration",WebGUI::International::get(118),$session{setting}{anonymousRegistration}); + $f->text("runOnRegistration",WebGUI::International::get(559),$session{setting}{runOnRegistration}); + $f->yesNo("useKarma",WebGUI::International::get(539),$session{setting}{useKarma}); + $f->integer("karmaPerLogin",WebGUI::International::get(540),$session{setting}{karmaPerLogin}); + $f->interval("sessionTimeout",WebGUI::International::get(142),WebGUI::DateTime::secondsToInterval($session{setting}{sessionTimeout})); + $f->yesNo("selfDeactivation",WebGUI::International::get(885),$session{setting}{selfDeactivation}); + $f->yesNo("encryptLogin",WebGUI::International::get(1006),$session{setting}{encryptLogin}); + + my $options; + foreach (@{$session{config}{authMethods}}) { + $options->{$_} = $_; + } + $f->select( + -name=>"authMethod", + -options=>$options, + -label=>WebGUI::International::get(164), + -value=>[$session{setting}{authMethod}], + -extras=>"onChange=\"active=operateHidden(this.options[this.selectedIndex].value,active)\"" + ); + my $jscript = '"; + + $f->submit( -label=>" "); $output .= $f->print; - return _submenu($output); + $output .= $jscript; + return _submenu($output); } #------------------------------------------------------------------- diff --git a/lib/WebGUI/Operation/User.pm b/lib/WebGUI/Operation/User.pm index da181c696..d954833de 100644 --- a/lib/WebGUI/Operation/User.pm +++ b/lib/WebGUI/Operation/User.pm @@ -21,6 +21,7 @@ use WebGUI::HTMLForm; use WebGUI::Icon; use WebGUI::International; use WebGUI::Operation::Shared; +use WebGUI::Operation::Auth; use WebGUI::Paginator; use WebGUI::Privilege; use WebGUI::Session; @@ -30,7 +31,8 @@ use WebGUI::User; use WebGUI::Utility; our @ISA = qw(Exporter); -our @EXPORT = qw(&www_editUserKarma &www_editUserKarmaSave &www_editUserGroup &www_editUserProfile &www_editUserProfileSave &www_addUserToGroupSave &www_deleteGrouping &www_editGrouping &www_editGroupingSave &www_becomeUser &www_addUser &www_addUserSave &www_deleteUser &www_deleteUserConfirm &www_editUser &www_editUserSave &www_listUsers &www_addUserSecondary &www_addUserSecondarySave); +#&www_addUserSecondary &www_addUserSecondarySave +our @EXPORT = qw(&www_editUserKarma &www_editUserKarmaSave &www_editUserGroup &www_editUserProfile &www_editUserProfileSave &www_addUserToGroupSave &www_deleteGrouping &www_editGrouping &www_editGroupingSave &www_becomeUser &www_addUser &www_addUserSave &www_deleteUser &www_deleteUserConfirm &www_editUser &www_editUserSave &www_listUsers); #------------------------------------------------------------------- @@ -54,119 +56,92 @@ sub _submenu { } $menu{WebGUI::URL::page("op=listUsers")} = WebGUI::International::get(456); } else { - $menu{WebGUI::URL::page("op=addUserSecondary")} = WebGUI::International::get(169); + $menu{WebGUI::URL::page("op=addUser")} = WebGUI::International::get(169); } return menuWrapper($_[0],\%menu); } #------------------------------------------------------------------- sub www_addUser { - my ($output, $f, $cmd, $html, %status); - return WebGUI::Privilege::adminOnly() unless (WebGUI::Privilege::isInGroup(3)); - $output .= helpIcon(5); + my ($output, $f, $cmd, $html, %status); + return WebGUI::Privilege::adminOnly() unless (WebGUI::Privilege::isInGroup(3) || WebGUI::Privilege::isInGroup(11)); + $output .= helpIcon(5); $output .= '

    '.WebGUI::International::get(163).'

    '; - $f = WebGUI::HTMLForm->new; + $output .= WebGUI::Form::_javascriptFile("swapLayers.js"); + $output .= ''; + if ($session{form}{op} eq "addUserSave") { $output .= ''; } - $f->hidden("op","addUserSave"); - $f->text("username",WebGUI::International::get(50),$session{form}{username}); - $f->email("email",WebGUI::International::get(56)); - - tie %status, 'Tie::IxHash'; - %status = ( - Active =>WebGUI::International::get(817), - Deactivated =>WebGUI::International::get(818) - ); - $f->select("status",\%status,WebGUI::International::get(816), ['Active']); - $f->group( - -name=>"groups", - -excludeGroups=>[1,2,7], - -label=>WebGUI::International::get(605), - -size=>5, - -multiple=>1 - ); + + $f = WebGUI::HTMLForm->new(-tableOptions=>"border=0 cellspacing=0 cellpadding=0"); + $f->hidden("op","addUserSave"); + $f->raw('  '); + $f->text("username",WebGUI::International::get(50),$session{form}{username}); + $f->email("email",WebGUI::International::get(56)); + + if(WebGUI::Privilege::isInGroup(3)){ + tie %status, 'Tie::IxHash'; + %status = ( + Active =>WebGUI::International::get(817), + Deactivated =>WebGUI::International::get(818) + ); + $f->select("status",\%status,WebGUI::International::get(816), ['Active']); + $f->group( + -name=>"groups", + -excludeGroups=>[1,2,7], + -label=>WebGUI::International::get(605), + -size=>5, + -multiple=>1 + ); + }else{ + $f->hidden("status","Active"); + } my $options; foreach (@{$session{config}{authMethods}}) { $options->{$_} = $_; } - $f->select("authMethod",$options,WebGUI::International::get(164),[$session{setting}{authMethod}]); + $f->select( + -name=>"authMethod", + -options=>$options, + -label=>WebGUI::International::get(164), + -value=>[$session{setting}{authMethod}], + -extras=>"onChange=\"active=operateHidden(this.options[this.selectedIndex].value,active)\"" + ); + my $jscript = '"; $f->submit; $output .= $f->print; - return _submenu($output); + $output .= $jscript; + return _submenu($output); } #------------------------------------------------------------------- sub www_addUserSave { - my (@groups, $uid, $u); - return WebGUI::Privilege::adminOnly() unless (WebGUI::Privilege::isInGroup(3)); + my (@groups, $uid, $u); + return WebGUI::Privilege::adminOnly() unless (WebGUI::Privilege::isInGroup(3) || WebGUI::Privilege::isInGroup(11)); ($uid) = WebGUI::SQL->quickArray("select userId from users where username=".quote($session{form}{username})); - unless ($uid) { - $u = WebGUI::User->new("new"); - $session{form}{uid}=$u->userId; - $u->username($session{form}{username}); - foreach (@{$session{config}{authMethods}}) { - WebGUI::Authentication::adminFormSave($u->userId,$_); - } - $u->status($session{form}{status}); - $u->authMethod($session{form}{authMethod}); - @groups = $session{cgi}->param('groups'); - $u->addToGroups(\@groups); - $u->profileField("email",$session{form}{email}); - return www_editUser(); - } else { - $session{form}{op} = "addUser"; - return www_addUser(); + return www_addUser if ($uid); + + $u = WebGUI::User->new("new"); + $u->username($session{form}{username}); + foreach (@{$session{config}{authMethods}}) { + my $authInstance = WebGUI::Operation::Auth::getInstance($_,$u->userId); + $authInstance->addUserFormSave; } -} - -#------------------------------------------------------------------- -sub www_addUserSecondary { - return WebGUI::Privilege::adminOnly() unless (WebGUI::Privilege::isInGroup(11)); - my $output .= '

    '.WebGUI::International::get(163).'

    '; - my $f = WebGUI::HTMLForm->new; - if ($session{form}{op} eq "addUserSecondarySave") { - $output .= ''; - } - $f->hidden("op","addUserSecondarySave"); - $f->text("username",WebGUI::International::get(50),$session{form}{username}); - $f->email("email",WebGUI::International::get(56)); - my $options; - foreach (@{$session{config}{authMethods}}) { - $options->{$_} = $_; - } - $f->select("authMethod",$options,WebGUI::International::get(164),[$session{setting}{authMethod}]); - foreach (@{$session{config}{authMethods}}) { - $f->raw(WebGUI::Authentication::adminForm(0,$_)); - } - $f->submit; - $output .= $f->print; - return _submenu($output); -} - -#------------------------------------------------------------------- -sub www_addUserSecondarySave { - my (@groups, $uid, $u); - return WebGUI::Privilege::adminOnly() unless (WebGUI::Privilege::isInGroup(11)); - ($uid) = WebGUI::SQL->quickArray("select userId from users where username=".quote($session{form}{username})); - unless ($uid) { - $u = WebGUI::User->new("new"); - $session{form}{uid}=$u->userId; - $u->username($session{form}{username}); - foreach (@{$session{config}{authMethods}}) { - WebGUI::Authentication::adminFormSave($u->userId,$_); - } - $u->status('Active'); - $u->authMethod($session{form}{authMethod}); - $u->profileField("email",$session{form}{email}); - return _submenu(WebGUI::International::get(978)); - } else { - $session{form}{op} = "addUserSecondary"; - return www_addUserSecondary(); - } + $session{form}{uid}=$u->userId; + $u->status($session{form}{status}); + $u->authMethod($session{form}{authMethod}); + @groups = $session{cgi}->param('groups'); + $u->addToGroups(\@groups); + $u->profileField("email",$session{form}{email}); + return _submenu(WebGUI::International::get(978)) if(!WebGUI::Privilege::isInGroup(3)); + return www_editUser(); } #------------------------------------------------------------------- @@ -223,14 +198,13 @@ sub www_deleteUser { sub www_deleteUserConfirm { return WebGUI::Privilege::adminOnly() unless (WebGUI::Privilege::isInGroup(3)); my ($u); - if ($session{form}{uid} < 26) { - return WebGUI::Privilege::vitalComponent(); - } else { - $u = WebGUI::User->new($session{form}{uid}); - WebGUI::Authentication::deleteParams($u->userId); - $u->delete; - return www_listUsers(); - } + if ($session{form}{uid} < 26) { + return WebGUI::Privilege::vitalComponent(); + } else { + $u = WebGUI::User->new($session{form}{uid}); + $u->delete; + return www_listUsers(); + } } #------------------------------------------------------------------- @@ -267,18 +241,21 @@ sub www_editGroupingSave { #------------------------------------------------------------------- sub www_editUser { return WebGUI::Privilege::adminOnly() unless (WebGUI::Privilege::isInGroup(3)); - my ($output, $f, $u, $cmd, $html, %status); + my ($output, $f, $u, $cmd, $html, %status); $u = WebGUI::User->new($session{form}{uid}); - $output .= helpIcon(5); + $output .= WebGUI::Form::_javascriptFile("swapLayers.js"); + $output .= ''; + $output .= helpIcon(5); $output .= '

    '.WebGUI::International::get(168).'

    '; $f = WebGUI::HTMLForm->new; - $f->hidden("op","editUserSave"); - $f->hidden("uid",$session{form}{uid}); - $f->readOnly($session{form}{uid},WebGUI::International::get(378)); - $f->readOnly($u->karma,WebGUI::International::get(537)) if ($session{setting}{useKarma}); - $f->readOnly(epochToHuman($u->dateCreated,"%z"),WebGUI::International::get(453)); - $f->readOnly(epochToHuman($u->lastUpdated,"%z"),WebGUI::International::get(454)); - $f->text("username",WebGUI::International::get(50),$u->username); + $f->hidden("op","editUserSave"); + $f->hidden("uid",$session{form}{uid}); + $f->raw('  '); + $f->readOnly($session{form}{uid},WebGUI::International::get(378)); + $f->readOnly($u->karma,WebGUI::International::get(537)) if ($session{setting}{useKarma}); + $f->readOnly(epochToHuman($u->dateCreated,"%z"),WebGUI::International::get(453)); + $f->readOnly(epochToHuman($u->lastUpdated,"%z"),WebGUI::International::get(454)); + $f->text("username",WebGUI::International::get(50),$u->username); tie %status, 'Tie::IxHash'; %status = ( Active =>WebGUI::International::get(817), @@ -290,34 +267,48 @@ sub www_editUser { } else { $f->select("status",\%status,WebGUI::International::get(816),[$u->status]); } + my $options; - foreach (@{$session{config}{authMethods}}) { - $options->{$_} = $_; - } - $f->select("authMethod",$options,WebGUI::International::get(164),[$u->authMethod]); foreach (@{$session{config}{authMethods}}) { - $f->raw(WebGUI::Authentication::adminForm($u->userId,$_)); - } - $f->submit; + $options->{$_} = $_; + } + $f->select( + -name=>"authMethod", + -options=>$options, + -label=>WebGUI::International::get(164), + -value=>[$u->authMethod], + -extras=>"onChange=\"active=operateHidden(this.options[this.selectedIndex].value,active)\"" + ); + my $jscript = '"; + $f->submit; $output .= $f->print; + $output .= $jscript; return _submenu($output); } #------------------------------------------------------------------- sub www_editUserSave { return WebGUI::Privilege::adminOnly() unless (WebGUI::Privilege::isInGroup(3)); - my ($error, $uid, $u); - ($uid) = WebGUI::SQL->quickArray("select userId from users where username=".quote($session{form}{username})); - if ($uid == $session{form}{uid} || $uid < 1) { - $u = WebGUI::User->new($session{form}{uid}); - $u->username($session{form}{username}); - $u->authMethod($session{form}{authMethod}); - $u->status($session{form}{status}); - foreach (@{$session{config}{authMethods}}) { - WebGUI::Authentication::adminFormSave($u->userId,$_); - } + my ($error, $uid, $u); + ($uid) = WebGUI::SQL->quickArray("select userId from users where username=".quote($session{form}{username})); + + if ($uid == $session{form}{uid} || $uid < 1) { + $u = WebGUI::User->new($session{form}{uid}); + $u->username($session{form}{username}); + $u->authMethod($session{form}{authMethod}); + $u->status($session{form}{status}); + foreach (@{$session{config}{authMethods}}) { + my $authInstance = WebGUI::Operation::Auth::getInstance($_,$u->userId); + $authInstance->editUserFormSave; + } } else { - $error = ''; + $error = ''; } return $error.www_editUser(); } diff --git a/lib/WebGUI/User.pm b/lib/WebGUI/User.pm index 82c3fe1cd..db0674257 100644 --- a/lib/WebGUI/User.pm +++ b/lib/WebGUI/User.pm @@ -22,7 +22,7 @@ use WebGUI::International; use WebGUI::Session; use WebGUI::SQL; use WebGUI::URL; -use WebGUI::Authentication; +use WebGUI::Operation::Auth; =head1 NAME @@ -39,7 +39,7 @@ This package provides an object-oriented way of managing WebGUI users as well as $authMethod = $u->authMethod("WebGUI"); $dateCreated = $u->dateCreated; - $karma = $u->karma; + $karma = $u->karma; $lastUpdated = $u->lastUpdated; $languagePreference = $u->profileField("language",1); $referringAffiliate = $u->referringAffiliate; @@ -137,18 +137,20 @@ Deletes this user. =cut sub delete { - my ($class); + my ($class,$authMethod); $class = shift; WebGUI::SQL->write("delete from users where userId=".$class->{_userId}); WebGUI::SQL->write("delete from userProfileData where userId=".$class->{_userId}); WebGUI::Grouping::deleteUsersFromGroups([$class->{_userId}],WebGUI::Grouping::getGroupsForUser($class->{_userId})); WebGUI::SQL->write("delete from messageLog where userId=".$class->{_userId}); - WebGUI::Authentication::deleteParams($class->{_userId}); - my $sth = WebGUI::SQL->read("select sessionId from userSession where userId=$class->{_userId}"); - while (my ($sid) = $sth->array) { - WebGUI::Sesssion::end($sid); - } - $sth->finish; + + my $authMethod = WebGUI::Operation::Auth::getInstance($class->authMethod,$class->{_userId}); + $authMethod->deleteParams($class->{_userId}); + my $sth = WebGUI::SQL->read("select sessionId from userSession where userId=$class->{_userId}"); + while (my ($sid) = $sth->array) { + WebGUI::Sesssion::end($sid); + } + $sth->finish; } #------------------------------------------------------------------- @@ -172,7 +174,7 @@ sub deleteFromGroups { } #------------------------------------------------------------------- -# This method is depricated and is provided only for reverse compatibility. See WebGUI::Authentication instead. +# This method is depricated and is provided only for reverse compatibility. See WebGUI::Auth instead. sub identifier { my ($class, $value); $class = shift; diff --git a/www/extras/swapLayers.js b/www/extras/swapLayers.js new file mode 100644 index 000000000..b9c717a2c --- /dev/null +++ b/www/extras/swapLayers.js @@ -0,0 +1,5 @@ +function operateHidden(newId,oldId){ + document.getElementById(oldId).style.display='none'; + document.getElementById(newId).style.display=''; + return newId; +} \ No newline at end of file