From 7af36f0c037bfc4fc615655f1a4c5df9bf25c452 Mon Sep 17 00:00:00 2001 From: Martin Kamerbeek Date: Mon, 18 Nov 2002 17:44:14 +0000 Subject: [PATCH] Adding pluggable authentication --- lib/WebGUI/Authentication.pm | 35 ++++++ lib/WebGUI/Authentication/LDAP.pm | 173 ++++++++++++++++++++++++++++ lib/WebGUI/Authentication/WebGUI.pm | 85 ++++++++++++++ lib/WebGUI/Operation/Account.pm | 144 +++++++---------------- lib/WebGUI/Operation/Settings.pm | 20 ++-- lib/WebGUI/Operation/User.pm | 69 ++++++----- lib/WebGUI/Session.pm | 30 +++++ lib/WebGUI/User.pm | 51 +------- 8 files changed, 421 insertions(+), 186 deletions(-) create mode 100644 lib/WebGUI/Authentication.pm create mode 100644 lib/WebGUI/Authentication/LDAP.pm create mode 100644 lib/WebGUI/Authentication/WebGUI.pm diff --git a/lib/WebGUI/Authentication.pm b/lib/WebGUI/Authentication.pm new file mode 100644 index 000000000..c751da15b --- /dev/null +++ b/lib/WebGUI/Authentication.pm @@ -0,0 +1,35 @@ +package WebGUI::Authentication; + +use WebGUI::Authentication::LDAP; +use WebGUI::Authentication::WebGUI; +use WebGUI::SQL; +use strict; + +sub saveParams { + my ($uid, $authMethod, $data, @values); + + ($uid, $authMethod, $data) = @_; + foreach (keys(%$data)) { + my $sql = "replace into authentication set userId=$uid, authMethod=".quote($authMethod).", fieldData=".quote($$data{$_}).", fieldName=".quote($_); + WebGUI::SQL->write($sql); + } +} + +sub getParams { + my ($uid, $authMethod, $data); + + $uid = shift; + $authMethod = shift; + $data = WebGUI::SQL->buildHashRef("select fieldName, fieldData from authentication where userId=$uid and authMethod='$authMethod'"); + return $data; +} + +sub deleteParams { + my $uid = shift; + + if ($uid) { + WebGUI::SQL->write("delete from authentication where userId=$uid"); + } +} + +1; diff --git a/lib/WebGUI/Authentication/LDAP.pm b/lib/WebGUI/Authentication/LDAP.pm new file mode 100644 index 000000000..bb8db1f75 --- /dev/null +++ b/lib/WebGUI/Authentication/LDAP.pm @@ -0,0 +1,173 @@ +package WebGUI::Authentication::LDAP; + +use strict; +use WebGUI::SQL; +use WebGUI::Session; +use WebGUI::HTMLForm; +use WebGUI::Authentication; +use URI; +use Net::LDAP; + +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 formAddUser { + my $fo; + + $fo = WebGUI::HTMLForm->new; + $fo->readOnly("LDAP Authentication Options"); + $fo->url("ldapURL",WebGUI::International::get(165),$session{setting}{ldapURL}); + $fo->text("connectDN",WebGUI::International::get(166),$session{form}{connectDN}); + + return $fo->printRowsOnly; +} + +sub saveAddUser { + WebGUI::Authentication::saveParams($session{form}{uid},'LDAP',{connectDN => $session{form}{connectDN}, ldapURL => $session{form}{ldapURL}}); +} + +sub formEditUserSettings { + my $f; + + $f = WebGUI::HTMLForm->new; + $f->url("ldapURL",WebGUI::International::get(120),$session{setting}{ldapURL}); + $f->text("ldapId",WebGUI::International::get(121),$session{setting}{ldapId}); + $f->text("ldapIdName",WebGUI::International::get(122),$session{setting}{ldapIdName}); + $f->text("ldapPasswordName",WebGUI::International::get(123),$session{setting}{ldapPasswordName}); + return $f->printRowsOnly; +} + +#sub saveEditUserSettings { +# WebGUI::Operation::Settings::_saveSetting("ldapURL"); +# WebGUI::Operation::Settings::_saveSetting("ldapId"); +# WebGUI::Operation::Settings::_saveSetting("ldapIdName"); +# WebGUI::Operation::Settings::_saveSetting("ldapPasswordName"); +#} + +sub formEditUser { + my ($f, $userData); + $userData = WebGUI::Authentication::getParams($session{form}{uid}, 'LDAP'); + + $f = WebGUI::HTMLForm->new; + $f->readOnly('LDAP Authentication Options'); + $f->url("ldapURL",WebGUI::International::get(165),$$userData{ldapURL}); + $f->text("connectDN",WebGUI::International::get(166),$$userData{connectDN}); + + return $f->printRowsOnly; +} + +sub saveEditUser { + WebGUI::Authentication::saveParams($session{form}{uid},'LDAP',{connectDN => $session{form}{connectDN}, ldapURL => $session{form}{ldapURL}}); +} + +sub formCreateAccount { + my $f; + + $f = WebGUI::HTMLForm->new; + $f->password("ldapPassword",$session{setting}{ldapPasswordName}); + + return $f->printRowsOnly; +} + +sub saveCreateAccount { + my($uri, $port, %args, $ldap, $auth, $search, $connectDN, $uid); + + my $uid = shift; + + $uri = URI->new($session{setting}{ldapURL}); + if ($uri->port < 1) { + $port = 389; + } else { + $port = $uri->port; + } + + %args = (port => $port); + $ldap = Net::LDAP->new($uri->host, %args); + $ldap->bind; + $search = $ldap->search (base => $uri->dn, filter => $session{setting}{ldapId}."=".$session{form}{loginId}); + if (defined $search->entry(0)) { + $connectDN = "cn=".$search->entry(0)->get_value("cn"); + } + $ldap->unbind; + + WebGUI::Authentication::saveParams($uid,'LDAP',{connectDN => $connectDN, ldapURL => $session{setting}{ldapURL}}); +} + +sub hasBadUserData { + my($uri, $port, %args, $ldap, $auth, $error, $search, $connectDN); + $uri = URI->new($session{setting}{ldapURL}); + if ($uri->port < 1) { + $port = 389; + } else { + $port = $uri->port; + } + %args = (port => $port); + $ldap = Net::LDAP->new($uri->host, %args) or $error .= WebGUI::International::get(79); + return $error if ($error); + $ldap->bind; + $search = $ldap->search (base => $uri->dn, filter => $session{setting}{ldapId}."=".$session{form}{ldapId}); + if (defined $search->entry(0)) { + $connectDN = "cn=".$search->entry(0)->get_value("cn"); + $ldap->unbind; + $ldap = Net::LDAP->new($uri->host, %args) or $error .= WebGUI::International::get(79); + $auth = $ldap->bind(dn=>$connectDN, password=>$session{form}{ldapPassword}); + 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}{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}{ldapId}); + } + + return $error; +} + +sub validateUser { + my ($userId, $password, $userData, $uri, $port, %args, $ldap, $auth, $error); + ($userId, $password) = @_; + + $userData = WebGUI::Authentication::getParams($userId, 'LDAP'); + + $uri = URI->new($userData->{ldapURL}); + if ($uri->port < 1) { + $port = 389; + } else { + $port = $uri->port; + } + %args = (port => $port); + $ldap = Net::LDAP->new($uri->host, %args) or $error = WebGUI::International::get(79); + return $error if $error; + $auth = $ldap->bind(dn=>$$userData{connectDN}, password=>$session{form}{identifier}); + if ($auth->code == 48 || $auth->code == 49) { + $error = WebGUI::International::get(68); + WebGUI::ErrorHandler::security("login to account ".$session{form}{username}." with invalid information."); + } elsif ($auth->code > 0) { + $error .= 'LDAP error "'.$ldapStatusCode{$auth->code}.'" occured.'; + $error .= WebGUI::International::get(69); + WebGUI::ErrorHandler::warn("LDAP error: ".$ldapStatusCode{$auth->code}); + } else { + $error = 1; + } + $ldap->unbind; + return $error +} + +1; diff --git a/lib/WebGUI/Authentication/WebGUI.pm b/lib/WebGUI/Authentication/WebGUI.pm new file mode 100644 index 000000000..e49bc1128 --- /dev/null +++ b/lib/WebGUI/Authentication/WebGUI.pm @@ -0,0 +1,85 @@ +package WebGUI::Authentication::WebGUI; + +use strict; +use WebGUI; +use WebGUI::Session; +use WebGUI::Authentication; +use WebGUI::HTMLForm; +use Digest::MD5; + +sub formAddUser { + my $f; + + $f = WebGUI::HTMLForm->new; + $f->readOnly("WebGUI Authentication options"); + $f->password("identifier",WebGUI::International::get(51)); + return $f->printRowsOnly; +} + +sub saveAddUser { + my $encryptedPassword; + + $encryptedPassword = Digest::MD5::md5_base64($session{form}{identifier}); + WebGUI::Authentication::saveParams($session{form}{uid},'WebGUI',{identifier => $encryptedPassword}); +} + +sub formEditUser { + my $f; + + $f = WebGUI::HTMLForm->new; + $f->readOnly('WebGUI Authentication Options'); + $f->password("identifier",WebGUI::International::get(51),"password"); +} + +sub saveEditUser { + my ($encryptedPassword); + + if ($session{form}{identifier} ne "password") { + $encryptedPassword = Digest::MD5::md5_base64($session{form}{identifier}); + WebGUI::Authentication::saveParams($session{form}{uid}, 'WebGUI', {identifier => $encryptedPassword}); + } +} + +sub formEditUserSettings { + return ''; +} + +sub saveEditUserSettings { +} + +sub formCreateAccount { + my $f; + + $f = WebGUI::HTMLForm->new; + $f->password("identifier1",WebGUI::International::get(51)); + $f->password("identifier2",WebGUI::International::get(55)); + return $f->printRowsOnly; +} + +sub saveCreateAccount { + my ($encryptedPassword, $uid); + + $uid = shift; + $encryptedPassword = Digest::MD5::md5_base64($session{form}{identifier1}); + WebGUI::Authentication::saveParams($uid, 'WebGUI', {identifier => $encryptedPassword}); +} + +sub hasBadUserData { + return WebGUI::Operation::Account::_hasBadPassword($session{form}{identifier1},$session{form}{identifier2}); +} + +sub validateUser { + my ($userId, $identifier, $userData, $success); + ($userId, $identifier) = @_; + + $userData = WebGUI::Authentication::getParams($userId, 'WebGUI'); + if ((Digest::MD5::md5_base64($identifier) eq $$userData{identifier}) && ($identifier ne "")) { + $success = 1; + } else { + $success = WebGUI::International::get(68); + WebGUI::ErrorHandler::security("login to account ".$session{form}{username}." with invalid information."); + } + return $success; +} + +1; \ No newline at end of file diff --git a/lib/WebGUI/Operation/Account.pm b/lib/WebGUI/Operation/Account.pm index f7d2b5ec6..2ba591d12 100644 --- a/lib/WebGUI/Operation/Account.pm +++ b/lib/WebGUI/Operation/Account.pm @@ -13,7 +13,9 @@ package WebGUI::Operation::Account; use Digest::MD5 qw(md5_base64); use Exporter; use Net::LDAP; -use strict; +use strict qw(vars subs); +#use warnings; +#use strict; use URI; use WebGUI::DateTime; use WebGUI::ErrorHandler; @@ -29,24 +31,10 @@ use WebGUI::SQL; use WebGUI::URL; use WebGUI::User; use WebGUI::Utility; +use WebGUI::Authentication; our @ISA = qw(Exporter); our @EXPORT = qw(&www_viewMessageLogMessage &www_viewMessageLog &www_viewProfile &www_editProfile &www_editProfileSave &www_createAccount &www_deactivateAccount &www_deactivateAccountConfirm &www_displayAccount &www_displayLogin &www_login &www_logout &www_recoverPassword &www_recoverPasswordFinish &www_createAccountSave &www_updateAccount); -our %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 _accountOptions { @@ -135,7 +123,7 @@ sub _validateProfileData { #------------------------------------------------------------------- sub www_createAccount { - my ($output, %language, @array, + my ($output, %language, @array, $cmd, $return, $previousCategory, $category, $f, $a, %data, $default, $label, $values, $method); tie %data, 'Tie::CPHash'; if ($session{user}{userId} != 1) { @@ -144,20 +132,21 @@ sub www_createAccount { $output .= www_displayLogin(); } else { $output .= '

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

    '; + $f = WebGUI::HTMLForm->new(); $f->hidden("op","createAccountSave"); - unless ($session{setting}{authMethod} eq "LDAP" && $session{setting}{usernameBinding}) { + unless ($session{setting}{authMethod} ne "WebGUI" && $session{setting}{usernameBinding}) { $f->text("username",WebGUI::International::get(50),$session{form}{username}); } - if ($session{setting}{authMethod} eq "LDAP") { - $f->hidden("identifier1","ldap-password"); - $f->hidden("identifier2","ldap-password"); - $f->text("ldapId",$session{setting}{ldapIdName}); - $f->password("ldapPassword",$session{setting}{ldapPasswordName}); - } else { - $f->password("identifier1",WebGUI::International::get(51)); - $f->password("identifier2",WebGUI::International::get(55)); + unless ($session{setting}{authMethod} eq 'WebGUI') { + $f->text("loginId", 'loginName'); } + + $cmd = $session{authentication}{$session{setting}{authMethod}} . "::formCreateAccount"; + $return = eval {&$cmd}; + WebGUI::ErrorHandler::fatalError("Unable to load method formCreateAccount on Authentication module: $session{setting}{authMethod}. ".$@) if($@); + $f->raw($return); + $a = WebGUI::SQL->read("select * from userProfileField,userProfileCategory where userProfileField.profileCategoryId=userProfileCategory.profileCategoryId order by userProfileCategory.sequenceNumber,userProfileField.sequenceNumber"); @@ -196,10 +185,12 @@ sub www_createAccount { $output .= '
    '; } return $output; @@ -207,54 +198,30 @@ sub www_createAccount { #------------------------------------------------------------------- sub www_createAccountSave { - my ($profile, $u, $username, $uri, $temp, $ldap, $port, %args, $search, + my ($profile, $u, $username, $uri, $temp, $ldap, $port, %args, $search, $cmd, $connectDN, $auth, $output, $error, $uid, $encryptedPassword, $fieldName); - if ($session{setting}{authMethod} eq "LDAP" && $session{setting}{usernameBinding}) { - $username = $session{form}{ldapId}; + if ($session{setting}{authMethod} ne "WebGUI" && $session{setting}{usernameBinding}) { + $username = $session{form}{loginId}; } else { $username = $session{form}{username}; } $error = _hasBadUsername($username); - $error .= _hasBadPassword($session{form}{identifier1},$session{form}{identifier2}); - if ($session{setting}{authMethod} eq "LDAP") { - $uri = URI->new($session{setting}{ldapURL}); - if ($uri->port < 1) { - $port = 389; - } else { - $port = $uri->port; - } - %args = (port => $port); - $ldap = Net::LDAP->new($uri->host, %args) or $error .= WebGUI::International::get(79); - $ldap->bind; - $search = $ldap->search (base => $uri->dn, filter => $session{setting}{ldapId}."=".$session{form}{ldapId}); - if (defined $search->entry(0)) { - $connectDN = "cn=".$search->entry(0)->get_value("cn"); - $ldap->unbind; - $ldap = Net::LDAP->new($uri->host, %args) or $error .= WebGUI::International::get(79); - $auth = $ldap->bind(dn=>$connectDN, password=>$session{form}{ldapPassword}); - 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}{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}{ldapId}); - } - } + + $cmd = $session{authentication}{$session{setting}{authMethod}} . '::hasBadUserData'; + $error .= eval {&$cmd}; + WebGUI::ErrorHandler::fatalError("Unable to load method hasBadUserData on Authentication module: $session{setting}{authMethod}. ".$@) if($@); + ($profile, $temp) = _validateProfileData(); $error .= $temp; if ($error eq "") { - $encryptedPassword = Digest::MD5::md5_base64($session{form}{identifier1}); $u = WebGUI::User->new("new"); $u->username($username); - $u->identifier($encryptedPassword); $u->authMethod($session{setting}{authMethod}); - $u->ldapURL($session{setting}{ldapURL}); - $u->connectDN($connectDN); + + $cmd = $session{authentication}{$session{setting}{authMethod}} . '::saveCreateAccount'; + eval {&$cmd($u->userId)}; + WebGUI::ErrorHandler::fatalError("Unable to load method saveCreateAccount on Authentication module: $session{setting}{authMethod}. ".$@) if($@); + $u->karma($session{setting}{karmaPerLogin},"Login","Just for logging in.") if ($session{setting}{useKarma}); foreach $fieldName (keys %{$profile}) { $u->profileField($fieldName,${$profile}{$fieldName}); @@ -307,13 +274,15 @@ sub www_displayAccount { $f = WebGUI::HTMLForm->new; $f->hidden("op","updateAccount"); $f->readOnly($session{user}{karma},WebGUI::International::get(537)) if ($session{setting}{useKarma}); - if ($session{user}{authMethod} eq "LDAP" && $session{setting}{usernameBinding}) { + + if ($session{user}{authMethod} ne "WebGUI" && $session{setting}{usernameBinding}) { $f->hidden("username",$session{user}{username}); $f->readOnly($session{user}{username},WebGUI::International::get(50)); } else { $f->text("username",WebGUI::International::get(50),$session{user}{username}); } - if ($session{user}{authMethod} eq "LDAP") { + + if ($session{user}{authMethod} ne "WebGUI") { $f->hidden("identifier1","password"); $f->hidden("identifier2","password"); } else { @@ -432,48 +401,23 @@ sub www_editProfileSave { #------------------------------------------------------------------- sub www_login { - my ($uri, $port, $ldap, %args, $auth, $error, $uid, $success, $u); + my ($cmd, $uid, $success, $u); + ($uid) = WebGUI::SQL->quickArray("select userId from users where username=".quote($session{form}{username})); $u = WebGUI::User->new($uid); - if ($u->authMethod eq "LDAP") { - $uri = URI->new($u->ldapURL); - if ($uri->port < 1) { - $port = 389; - } else { - $port = $uri->port; - } - %args = (port => $port); - $ldap = Net::LDAP->new($uri->host, %args) or $error = WebGUI::International::get(79); - $auth = $ldap->bind(dn=>$u->connectDN, password=>$session{form}{identifier}); - if ($auth->code == 48 || $auth->code == 49) { - $error = WebGUI::International::get(68); - WebGUI::ErrorHandler::security("login to account ".$session{form}{username}." with invalid information."); - _logLogin($uid,"invalid username/password"); - } elsif ($auth->code > 0) { - $error .= 'LDAP error "'.$ldapStatusCode{$auth->code}.'" occured.'; - $error .= WebGUI::International::get(69); - WebGUI::ErrorHandler::warn("LDAP error: ".$ldapStatusCode{$auth->code}); - _logLogin($uid,"LDAP error: ".$ldapStatusCode{$auth->code}); - } else { - $success = 1; - } - $ldap->unbind; - } else { - if (Digest::MD5::md5_base64($session{form}{identifier}) eq $u->identifier && $session{form}{identifier} ne "") { - $success = 1; - } else { - $error = WebGUI::International::get(68); - WebGUI::ErrorHandler::security("login to account ".$session{form}{username}." with invalid information."); - _logLogin($uid,"invalid username/password"); - } - } - if ($success) { + + $cmd = $session{authentication}{$u->authMethod}."::validateUser"; + $success = eval{&$cmd($uid, $session{form}{identifier})}; + WebGUI::ErrorHandler::fatalError("Unable to load method validateUser on Authentication module: $_. ".$@) if($@); + + if ($success == 1) { WebGUI::Session::start($uid); $u->karma($session{setting}{karmaPerLogin},"Login","Just for logging in.") if ($session{setting}{useKarma}); _logLogin($uid,"success"); return ""; } else { - return "

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

    ".$error.www_displayLogin(); + _logLogin($uid, $success); + return "

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

    ".$success.www_displayLogin(); } } diff --git a/lib/WebGUI/Operation/Settings.pm b/lib/WebGUI/Operation/Settings.pm index 093b84c98..4ff9a4f10 100644 --- a/lib/WebGUI/Operation/Settings.pm +++ b/lib/WebGUI/Operation/Settings.pm @@ -11,7 +11,7 @@ package WebGUI::Operation::Settings; #------------------------------------------------------------------- use Exporter; -use strict; +use strict qw(Vars Subs); use WebGUI::DateTime; use WebGUI::HTMLForm; use WebGUI::Icon; @@ -38,8 +38,10 @@ sub _submenu { #------------------------------------------------------------------- sub www_editUserSettings { WebGUI::Privilege::adminOnly() unless (WebGUI::Privilege::isInGroup(3)); - my ($output, %authMethod, $f); - %authMethod = ('WebGUI'=>'WebGUI', 'LDAP'=>'LDAP'); + my ($output, %authMethod, $f, $cmd, $html); + + %authMethod = map {$_ => $_} @{$session{authentication}{available}}; + $output .= helpIcon(2); $output .= '

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

    '; $f = WebGUI::HTMLForm->new; @@ -53,10 +55,14 @@ sub www_editUserSettings { $f->interval("sessionTimeout",WebGUI::International::get(142),WebGUI::DateTime::secondsToInterval($session{setting}{sessionTimeout})); $f->select("authMethod",\%authMethod,WebGUI::International::get(119),[$session{setting}{authMethod}]); $f->yesNo("usernameBinding",WebGUI::International::get(306),$session{setting}{usernameBinding}); - $f->url("ldapURL",WebGUI::International::get(120),$session{setting}{ldapURL}); - $f->text("ldapId",WebGUI::International::get(121),$session{setting}{ldapId}); - $f->text("ldapIdName",WebGUI::International::get(122),$session{setting}{ldapIdName}); - $f->text("ldapPasswordName",WebGUI::International::get(123),$session{setting}{ldapPasswordName}); + + foreach (@{$session{authentication}{available}}) { + $cmd = "WebGUI::Authentication::".$_."::formEditUserSettings"; + $html = eval{&$cmd}; + WebGUI::ErrorHandler::fatalError("Unable to load method formEditUserSettings on Authentication module: $_. ".$@) if($@); + $f->raw($html); + } + $f->submit; $output .= $f->print; return _submenu($output); diff --git a/lib/WebGUI/Operation/User.pm b/lib/WebGUI/Operation/User.pm index 2562cafdb..c155b5558 100644 --- a/lib/WebGUI/Operation/User.pm +++ b/lib/WebGUI/Operation/User.pm @@ -12,7 +12,7 @@ package WebGUI::Operation::User; use Digest::MD5 qw(md5_base64); use Exporter; -use strict; +use strict qw(vars subs); use Tie::CPHash; use WebGUI::DateTime; use WebGUI::HTMLForm; @@ -55,7 +55,7 @@ sub _submenu { #------------------------------------------------------------------- sub www_addUser { - my (@array, $output, $groups, %hash, $f); + my (@array, $output, $groups, %hash, $f, $cmd, $html); tie %hash, 'Tie::IxHash'; return WebGUI::Privilege::adminOnly() unless (WebGUI::Privilege::isInGroup(3)); $output .= helpIcon(5); @@ -68,10 +68,17 @@ sub www_addUser { $f->text("username",WebGUI::International::get(50),$session{form}{username}); $f->password("identifier",WebGUI::International::get(51)); $f->email("email",WebGUI::International::get(56)); - %hash = ('WebGUI'=>'WebGUI', 'LDAP'=>'LDAP'); - $f->select("authMethod",\%hash,WebGUI::International::get(164),[$session{setting}{authMethod}]); - $f->url("ldapURL",WebGUI::International::get(165),$session{setting}{ldapURL}); - $f->text("connectDN",WebGUI::International::get(166),$session{form}{connectDN}); + + %hash = map {$_ => $_} @{$session{authentication}{available}}; + $f->select("authMethod",\%hash,WebGUI::International::get(164),[$session{setting}{authMethod}]); + + foreach (@{$session{authentication}{available}}) { + $cmd = "WebGUI::Authentication::".$_."::formAddUser"; + $html = eval{&$cmd}; + WebGUI::ErrorHandler::fatalError("Unable to load method formAddUser on Authentication module: $_. ".$@) if($@); + $f->raw($html); + } + push(@array,1); #visitors push(@array,2); #registered users push(@array,7); #everyone @@ -84,16 +91,20 @@ sub www_addUser { #------------------------------------------------------------------- sub www_addUserSave { - my (@groups, $uid, $u, $gid, $encryptedPassword, $expireAfter); + my (@groups, $uid, $u, $gid, $encryptedPassword, $expireAfter, $cmd); return WebGUI::Privilege::adminOnly() unless (WebGUI::Privilege::isInGroup(3)); ($uid) = WebGUI::SQL->quickArray("select userId from users where username=".quote($session{form}{username})); unless ($uid) { $encryptedPassword = Digest::MD5::md5_base64($session{form}{identifier}); $u = WebGUI::User->new("new"); $u->username($session{form}{username}); - $u->identifier($encryptedPassword); - $u->connectDN($session{form}{connectDN}); - $u->ldapURL($session{form}{ldapURL}); + + foreach (@{$session{authentication}{available}}) { + $cmd = "WebGUI::Authentication::".$_."::saveAddUser"; + eval{&$cmd}; + WebGUI::ErrorHandler::fatalError("Unable to load method saveAddUser on Authentication module: $_. ".$@) if($@); + } + $u->authMethod($session{form}{authMethod}); @groups = $session{cgi}->param('groups'); $u->addToGroups(\@groups); @@ -198,7 +209,7 @@ sub www_editGroupingSave { #------------------------------------------------------------------- sub www_editUser { return WebGUI::Privilege::adminOnly() unless (WebGUI::Privilege::isInGroup(3)); - my ($output, $f, $u); + my ($output, $f, $u, $cmd, $html, %hash); $u = WebGUI::User->new($session{form}{uid}); $output .= helpIcon(5); $output .= '

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

    '; @@ -210,18 +221,17 @@ sub www_editUser { $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->password("identifier",WebGUI::International::get(51),"password"); - $f->select( - -name=>"authMethod", - -options=>{ - 'WebGUI'=>'WebGUI', - 'LDAP'=>'LDAP' - }, - -label=>WebGUI::International::get(164), - -value=>[$u->authMethod] - ); - $f->url("ldapURL",WebGUI::International::get(165),$u->ldapURL); - $f->text("connectDN",WebGUI::International::get(166),$u->connectDN); + + %hash = map {$_ => $_} @{$session{authentication}{available}}; + $f->select("authMethod",\%hash,WebGUI::International::get(164),[$session{setting}{authMethod}]); + + foreach (@{$session{authentication}{available}}) { + $cmd = "WebGUI::Authentication::".$_."::formEditUser"; + $html = eval{&$cmd}; + WebGUI::ErrorHandler::fatalError("Unable to load method formEditUser on Authentication module: $_. ".$@) if($@); + $f->raw($html); + } + $f->submit; $output .= $f->print; return _submenu($output); @@ -230,18 +240,17 @@ sub www_editUser { #------------------------------------------------------------------- sub www_editUserSave { return WebGUI::Privilege::adminOnly() unless (WebGUI::Privilege::isInGroup(3)); - my ($error, $uid, $u, $encryptedPassword, $passwordStatement); + my ($error, $uid, $u, $encryptedPassword, $passwordStatement, $cmd); ($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}); - if ($session{form}{identifier} ne "password") { - $encryptedPassword = Digest::MD5::md5_base64($session{form}{identifier}); - $u->identifier($encryptedPassword); - } $u->username($session{form}{username}); $u->authMethod($session{form}{authMethod}); - $u->connectDN($session{form}{connectDN}); - $u->ldapURL($session{form}{ldapURL}); + foreach (@{$session{authentication}{available}}) { + $cmd = "WebGUI::Authentication::".$_."::saveEditUser"; + eval{&$cmd}; + WebGUI::ErrorHandler::fatalError("Unable to load method saveEditUser on Authentication module: $_. ".$@) if($@); + } } else { $error = ''; } diff --git a/lib/WebGUI/Session.pm b/lib/WebGUI/Session.pm index a1dd51b83..c44162137 100644 --- a/lib/WebGUI/Session.pm +++ b/lib/WebGUI/Session.pm @@ -106,6 +106,35 @@ sub _getUserInfo { return \%user; } +#------------------------------------------------------------------- +sub _loadAuthentication { + my ($dir, @files, $slash, $file, $cmd, $namespace, $exclude, @availableModules); + $slash = ($^O =~ /Win/i) ? "\\" : "/"; + $dir = $slash."lib".$slash."WebGUI".$slash."Authentication"; + opendir (DIR,$session{config}{webguiRoot}.$dir) or WebGUI::ErrorHandler::fatalError("Can't open Authentication module directory!"); + @files = readdir(DIR); + foreach $file (@files) { + if ($file =~ /(.*?)\.pm$/) { + $namespace = $1; + $cmd = "use WebGUI::Authentication::".$namespace; + eval($cmd); + unless ($@) { + $exclude = $session{config}{excludeAuthentication}; + $exclude =~ s/ //g; + unless (isIn($namespace, split(/,/,$exclude))) { + $session{authentication}{$namespace} = 'WebGUI::Authentication::' . $namespace; + push(@availableModules, $namespace); + } + } else { + WebGUI::ErrorHandler::warn("Authentication module failed to compile: $namespace. ".$@); + $session{authentication}{failed} .= "[".$namespace."] "; + } + } + } + $session{authentication}{available} = \@availableModules; + closedir(DIR); +} + #------------------------------------------------------------------- sub _loadMacros { my ($slash, $namespace, $cmd, @files, $file, $dir, $exclude); @@ -274,6 +303,7 @@ sub open { ### loading plugins _loadWobjects(); _loadMacros(); + _loadAuthentication(); } #------------------------------------------------------------------- diff --git a/lib/WebGUI/User.pm b/lib/WebGUI/User.pm index ddebd0d26..9dc44d463 100644 --- a/lib/WebGUI/User.pm +++ b/lib/WebGUI/User.pm @@ -20,6 +20,7 @@ use WebGUI::International; use WebGUI::Session; use WebGUI::SQL; use WebGUI::URL; +use WebGUI::Authentication; =head1 NAME @@ -31,12 +32,10 @@ use WebGUI::URL; $u = WebGUI::User->new(3); or $f = WebGUI::User->new("new"); $authMethod = $u->authMethod("WebGUI"); - $connectDN = $u->authMethod("cn=Jon Doe"); $dateCreated = $u->dateCreated; $identifier = $u->identifier("somepassword"); $karma = $u->karma; $lastUpdated = $u->lastUpdated; - $ldapURL = $u->ldapURL("ldap://ldap.mycompany.com:389/o=MyCompany"); $languagePreference = $u->profileField("language",1); $username = $u->username("jonboy"); @@ -114,30 +113,6 @@ sub authMethod { #------------------------------------------------------------------- -=head2 connectDN ( [ value ] ) - - Returns the connection distinguished name for this user. - -=item value - - If specified, the connectDN is set to this value. - -=cut - -sub connectDN { - my ($class, $value); - $class = shift; - $value = shift; - if (defined $value) { - $class->{_user}{"connectDN"} = $value; - WebGUI::SQL->write("update users set connectDN=".quote($value).", - lastUpdated=".time()." where userId=$class->{_userId}"); - } - return $class->{_user}{"connectDN"}; -} - -#------------------------------------------------------------------- - =head2 dateCreated ( ) Returns the epoch for when this user was created. @@ -164,6 +139,7 @@ sub delete { WebGUI::SQL->write("delete from groupings where userId=".$class->{_userId}); WebGUI::SQL->write("delete from messageLog where userId=".$class->{_userId}); WebGUI::SQL->write("delete from userSession where userId=".$class->{_userId}); + WebGUI::Authentication::deleteParams($class->{_userId}); } #------------------------------------------------------------------- @@ -258,29 +234,6 @@ sub lastUpdated { #------------------------------------------------------------------- -=head2 ldapURL ( [ value ] ) - - Returns the LDAP URL for this user. - -=item value - - If specified, the ldapURL is set to this value. - -=cut - -sub ldapURL { - my ($class, $value); - $class = shift; - $value = shift; - if (defined $value) { - $class->{_user}{"ldapURL"} = $value; - WebGUI::SQL->write("update users set ldapURL=".quote($value).", lastUpdated=".time()." where userId=$class->{_userId}"); - } - return $class->{_user}{"ldapURL"}; -} - -#------------------------------------------------------------------- - =head2 new ( userId ) Constructor.