From 5381f3038d22b39c5557c5f9c98ca2e947a6ca8f Mon Sep 17 00:00:00 2001 From: Colin Kuskie Date: Mon, 15 Dec 2008 22:59:25 +0000 Subject: [PATCH] Forward port graceful handling of the deletion of the Auth LDAPLink. --- docs/changelog/7.x.x.txt | 2 + lib/WebGUI/Auth/LDAP.pm | 151 ++++++++++-------- lib/WebGUI/Operation/LDAPLink.pm | 9 +- lib/WebGUI/Operation/User.pm | 6 +- .../Workflow/Activity/SyncProfilesToLdap.pm | 1 + lib/WebGUI/i18n/English/WebGUI.pm | 12 ++ 6 files changed, 111 insertions(+), 70 deletions(-) diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index 0400ef257..46bc0fb71 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -8,6 +8,8 @@ - fixed #9274: AdminBar errors and fails when an asset class cannot be loaded - fixed #9301: Error in Shelf Template - fixed #9260: untitled (Delete icon "X" circumvents revision control) + - fixed: Deleting an LDAP connection does not take you back to the List LDAP connections screen. + - fixed #9284: User manager broken if no LDAP links exits 7.6.6 - fixed #8792: Image Preview gives ERROR in Collateral Manager diff --git a/lib/WebGUI/Auth/LDAP.pm b/lib/WebGUI/Auth/LDAP.pm index 809149983..c30e4381b 100644 --- a/lib/WebGUI/Auth/LDAP.pm +++ b/lib/WebGUI/Auth/LDAP.pm @@ -43,8 +43,9 @@ sub _isValidLDAPUser { my $self = shift; my ($error, $ldap, $search, $auth, $connectDN); my $i18n = WebGUI::International->new($self->session); - + my $connection = $self->getLDAPConnection; + return 0 unless $connection; #Check to see that the LDAP Link is valid my $ldapLink = $self->getLDAPLink; @@ -52,12 +53,19 @@ sub _isValidLDAPUser { $self->error('
  • '.$i18n->get(2,'AuthLDAP').'
  • '); return 0; } + my $username = $self->session->form->get("authLDAP_ldapId") || $self->session->form->get("username"); + my $password = $self->session->form->get("authLDAP_identifier") || $self->session->form->get("identifier"); + + my $uri = URI->new($connection->{ldapUrl}) or $error = '
  • '.$i18n->get(2,'AuthLDAP').'
  • '; + + if($error ne ""){ + $self->error($error); + return 0; + } - my $username = $self->session->form->get("authLDAP_ldapId") || $self->session->form->get("username"); - my $password = $self->session->form->get("authLDAP_identifier") || $self->session->form->get("identifier"); - # Create an LDAP object - if ($ldap = $ldapLink->connectToLDAP) { + if ($ldap = Net::LDAP->new($uri->host, (port=>$uri->port))) { + my $uri = $ldapLink->getURI; # Bind as a proxy user to search for the user trying to login if($connection->{connectDn}) { @@ -85,7 +93,7 @@ sub _isValidLDAPUser { # Remember the users DN so we can use it later. $self->setConnectDN($connectDN); $ldap->unbind; - + # Create a new LDAP object $ldap = $ldapLink->connectToLDAP or $error .= $i18n->get(2,'AuthLDAP'); @@ -117,7 +125,7 @@ sub _isValidLDAPUser { $error = '
  • '.$i18n->get(2,'AuthLDAP').'
  • '; $self->session->errorHandler->error("Couldn't create LDAP object: ".$connection->{ldapUrl}); } - + $self->error($error); # Return 1 on successful authentication @@ -148,7 +156,7 @@ sub authenticate { my $userId = $self->userId; my $identifier = $_[1]; my $userData = $self->getParams; - + $error .= '
  • '.$i18n->get(12,'AuthLDAP').'
  • ' if ($userData->{ldapUrl} eq ""); $error .= '
  • '.$i18n->get(11,'AuthLDAP').'
  • ' if ($userData->{connectDN} eq ""); $self->error($error); @@ -157,7 +165,7 @@ sub authenticate { $self->user(WebGUI::User->new($self->session,1)); return 0 ; } - + if($uri = URI->new($userData->{ldapUrl})) { # Create an LDAP object @@ -179,14 +187,14 @@ sub authenticate { $error .= '
  • LDAP error "'.$self->ldapStatusCode($auth->code).'" occured.'.$i18n->get(69).'
  • '; $self->session->errorHandler->error("LDAP error: ".$self->ldapStatusCode($auth->code)); } - + $ldap->unbind; } else { $error .= '
  • '.$i18n->get(13,'AuthLDAP').'
  • '; $self->session->errorHandler->error("Could not process this LDAP URL: ".$userData->{ldapUrl}); } - + if($error ne ""){ $self->error($error); $self->user(WebGUI::User->new($self->session,1)); @@ -208,8 +216,9 @@ sub connectToLDAP { my $self = shift; my $connectionId = $self->session->form->process("connection") || $self->session->setting->get("ldapConnection"); my $ldapLink = WebGUI::LDAPLink->new($self->session,$connectionId); + return undef unless defined $ldapLink; my $connection = $ldapLink->get; - + $self->{'_ldapLink' } = $ldapLink; $self->{'_connection'} = $connection; return $connection; @@ -227,13 +236,17 @@ sub createAccount { elsif (!$self->session->setting->get("anonymousRegistration") && !$self->session->setting->get('inboxInviteUserEnabled')) { return $self->displayLogin; } - - + + my $connection = $self->getLDAPConnection; + if (! $connection) { + $self->session->log->error('Unable to create LDAP account as there is no LDAP connection defined'); + return $self->displayLogin; + } $vars->{'create.message'} = $message if ($message); my $i18n = WebGUI::International->new($self->session,"AuthLDAP"); $vars->{'create.form.ldapConnection.label'} = $i18n->get("ldapConnection"); - + my $url = $self->session->url->page("op=auth;method=createAccount;connection="); $vars->{'create.form.ldapConnection'} = WebGUI::Form::selectBox($self->session, { name=>"ldapConnection", @@ -256,30 +269,31 @@ sub createAccount { extras => $self->getExtrasStyle($ldapPwd) }); $vars->{'create.form.password.label'} = $connection->{ldapPasswordName}; - + $vars->{'create.form.hidden'} = WebGUI::Form::hidden($self->session,{"name"=>"confirm","value"=>$confirm}); return $self->SUPER::createAccount("createAccountSave",$vars); } #------------------------------------------------------------------- sub createAccountSave { - my $self = shift; - my $username = $self->session->form->process('authLDAP_ldapId'); - my $password = $self->session->form->process('authLDAP_identifier'); - my $error = ""; - my $i18n = WebGUI::International->new($self->session); - - #Validate user in LDAP - if(!$self->_isValidLDAPUser()){ - return $self->createAccount("

    ".$i18n->get(70)."

    ".$self->error); - } - - my $connection = $self->getLDAPConnection; - my $ldapLink = $self->getLDAPLink; + my $self = shift; + my $username = $self->session->form->process('authLDAP_ldapId'); + my $password = $self->session->form->process('authLDAP_identifier'); + my $error = ""; + my $i18n = WebGUI::International->new($self->session); - #Get connectDN from settings - my $ldap = $ldapLink->connectToLDAP; - my $uri = $ldapLink->getURI; + #Validate user in LDAP + if(!$self->_isValidLDAPUser()){ + return $self->createAccount("

    ".$i18n->get(70)."

    ".$self->error); + } + + my $connection = $self->getLDAPConnection; + if (! $connection) { + return $self->createAccount("

    ".$i18n->get('no ldap link for auth')."

    ".$self->error); + } + #Get connectDN from settings + my $uri = URI->new($connection->{ldapUrl}); + my $ldap = Net::LDAP->new($uri->host, (port=>$uri->port)); my $auth; if($connection->{connectDn}) { $auth = $ldap->bind(dn=>$connection->{connectDn}, password=>$connection->{identifier}); @@ -299,28 +313,19 @@ sub createAccountSave { } } $ldap->unbind; - - + + #Check that username is valid and not a duplicate in the system. $error .= $self->error if(!$self->validUsername($username)); #Validate profile data. - my $fields = WebGUI::ProfileField->getEditableFields($self->session); - my $retHash = $self->user->validateProfileDataFromForm($fields); - my $profile = $retHash->{profile}; - my $temp = ""; - my $warning = ""; - - my $format = "
  • %s
  • "; - map { $warning .= sprintf($format,$_) } @{$retHash->{warnings}}; - map { $temp .= sprintf($format,$_) } @{$retHash->{errors}}; - + my ($profile, $temp, $warning) = WebGUI::Operation::Profile::validateProfileData($self->session); $error .= $temp; - return $self->createAccount("
  • ".$error."
  • ") unless ($error eq ""); + return $self->createAccount("
  • ".$error."") unless ($error eq ""); #If Email address is not unique, a warning is displayed if($warning ne "" && !$self->session->form->process("confirm")){ return $self->createAccount('
  • '.$i18n->get(1078).'
  • ', 1); } - + my $properties; $properties->{connectDN} = $connectDN; $properties->{ldapUrl} = $connection->{ldapUrl}; @@ -331,9 +336,9 @@ sub createAccountSave { #------------------------------------------------------------------- sub deactivateAccount { - my $self = shift; - return $self->displayLogin if($self->isVisitor); - return $self->SUPER::deactivateAccount("deactivateAccountConfirm"); + my $self = shift; + return $self->displayLogin if($self->userId eq '1'); + return $self->SUPER::deactivateAccount("deactivateAccountConfirm"); } #------------------------------------------------------------------- @@ -388,9 +393,10 @@ sub displayLogin { =cut sub editUserForm { - my $self = shift; + my $self = shift; my $userData = $self->getParams; my $connection = $self->getLDAPConnection; + return '' unless $connection; my $ldapUrl = $self->session->form->process('authLDAP_ldapUrl') || $userData->{ldapUrl} || $connection->{ldapUrl}; my $connectDN = $self->session->form->process('authLDAP_connectDN') || $userData->{connectDN}; my $ldapConnection = $self->session->form->process('authLDAP_ldapConnection') || $userData->{ldapConnection}; @@ -490,6 +496,8 @@ sub editUserSettingsFormSave { #------------------------------------------------------------------- sub getAccountTemplateId { my $self = shift; + my $ldapConnect = $self->getLDAPConnection; + return "PBtmpl0000000000000004" unless $ldapConnect; return ($self->getLDAPConnection->{ldapAccountTemplate} || "PBtmpl0000000000000004"); } @@ -502,13 +510,15 @@ sub getConnectDN { #------------------------------------------------------------------- sub getCreateAccountTemplateId { my $self = shift; + my $ldapConnect = $self->getLDAPConnection; + return "PBtmpl0000000000000005" unless $ldapConnect; return ($self->getLDAPConnection->{ldapCreateAccountTemplate} || "PBtmpl0000000000000005"); } #------------------------------------------------------------------- sub getLDAPConnection { my $self = shift; - + return $self->{_connection} if $self->{_connection}; return $self->connectToLDAP; } @@ -523,34 +533,41 @@ sub getLDAPLink { #------------------------------------------------------------------- sub getLoginTemplateId { my $self = shift; + my $ldapConnect = $self->getLDAPConnection; + return "PBtmpl0000000000000006" unless $ldapConnect; return ($self->getLDAPConnection->{ldapLoginTemplate} || "PBtmpl0000000000000006"); } #------------------------------------------------------------------- sub login { - my $self = shift; - my $i18n = WebGUI::International->new($self->session); - my $username = $self->session->form->process("username"); - my $identifier = $self->session->form->process("identifier"); - my $autoRegistration = $self->session->setting->get("automaticLDAPRegistration"); - my $hasAuthenticated = 0; - - $hasAuthenticated = 1 if ( $self->authenticate($username,$identifier) ); - + my $self = shift; + my $i18n = WebGUI::International->new($self->session); + my $username = $self->session->form->process("username"); + my $identifier = $self->session->form->process("identifier"); + my $autoRegistration = $self->session->setting->get("automaticLDAPRegistration"); + my $hasAuthenticated = 0; + + $hasAuthenticated = 1 if ( $self->authenticate($username,$identifier) ); + + my $connection = $self->getLDAPConnection; + if (! $connection) { + return $self->displayLogin("

    ".$i18n->get('no ldap logins')."

    ".$self->error); + } + # Autoregistration is on and they didn't authenticate yet if ($autoRegistration && !$hasAuthenticated) { # See if they are in LDAP and if so that they can bind with the password given. if($self->_isValidLDAPUser()) { - + # Create a WebGUI Account if ($self->validUsername($username)) { $self->SUPER::createAccountSave($username, { - connectDN => $self->getConnectDN, - ldapUrl => $self->getLDAPConnection->{ldapUrl}, - ldapConnection => $self->getLDAPConnection->{ldapLinkId}, + connectDN => $self->getConnectDN, + ldapUrl => $connection->{ldapUrl}, + ldapConnection => $connection->{ldapLinkId}, },$identifier); $hasAuthenticated = 1; - + # Pull the users profile from LDAP to WebGUI WebGUI::Workflow::Instance->create($self->session, { workflowId=>'AuthLDAPworkflow000001', @@ -579,7 +596,7 @@ sub new { #my $connection = $session->scratch->get("ldapConnection") || $session->setting->get("ldapConnection"); #my $ldaplink = WebGUI::LDAPLink->new($session,$connection); #$self->{_connection} = $ldaplink->get if $ldaplink; - + my $i18n = WebGUI::International->new($session, "AuthLDAP"); my %ldapStatusCode = map { $_ => $i18n->get("LDAPLink_".$_) } (0..21, 32,33,34,36, 48..54, 64..71, 80); @@ -600,4 +617,4 @@ sub setConnectDN { } -1; \ No newline at end of file +1; diff --git a/lib/WebGUI/Operation/LDAPLink.pm b/lib/WebGUI/Operation/LDAPLink.pm index 28d1edcf3..da7a6cc35 100644 --- a/lib/WebGUI/Operation/LDAPLink.pm +++ b/lib/WebGUI/Operation/LDAPLink.pm @@ -158,7 +158,14 @@ Deletes the requested LDAP Link in the form variable C. Returns the user sub www_deleteLDAPLink { my $session = shift; return $session->privilege->insufficient unless canView($session); - $session->db->write("delete from ldapLink where ldapLinkId=".$session->db->quote($session->form->process("llid"))); + my $llid = $session->form->process("llid"); + if ($llid) { + $session->db->write("delete from ldapLink where ldapLinkId=?", [$llid]); + } + if ($llid eq $session->setting->get('ldapConnection')) { + $session->log->warn(sprintf 'user %s deleted the LDAP connection used for user authentication', $session->user->username); + $session->setting->set('ldapConnection', ''); + } return www_listLDAPLinks($session); } diff --git a/lib/WebGUI/Operation/User.pm b/lib/WebGUI/Operation/User.pm index 807ae6dea..6ad58a36d 100644 --- a/lib/WebGUI/Operation/User.pm +++ b/lib/WebGUI/Operation/User.pm @@ -385,9 +385,11 @@ sub www_editUser { -value=>$u->authMethod, ); foreach (@{$session->config->get("authMethods")}) { - $tabform->getTab("account")->fieldSetStart($_); my $authInstance = WebGUI::Operation::Auth::getInstance($session,$_,$u->userId); - $tabform->getTab("account")->raw($authInstance->editUserForm); + my $editUserForm = $authInstance->editUserForm; + next unless $editUserForm; + $tabform->getTab("account")->fieldSetStart($_); + $tabform->getTab("account")->raw($editUserForm); $tabform->getTab("account")->fieldSetEnd; } foreach my $category (@{WebGUI::ProfileCategory->getCategories($session)}) { diff --git a/lib/WebGUI/Workflow/Activity/SyncProfilesToLdap.pm b/lib/WebGUI/Workflow/Activity/SyncProfilesToLdap.pm index 32e8df85a..89a181676 100644 --- a/lib/WebGUI/Workflow/Activity/SyncProfilesToLdap.pm +++ b/lib/WebGUI/Workflow/Activity/SyncProfilesToLdap.pm @@ -142,6 +142,7 @@ sub execute { $currentLinkId = $rowLinkId; $link = WebGUI::LDAPLink->new($self->session, $rowLinkId); + next unless $link; $ldapUrl = $link->get->{ldapUrl}; $ldap = $link->bind; diff --git a/lib/WebGUI/i18n/English/WebGUI.pm b/lib/WebGUI/i18n/English/WebGUI.pm index affd7e2d4..71fefcd89 100644 --- a/lib/WebGUI/i18n/English/WebGUI.pm +++ b/lib/WebGUI/i18n/English/WebGUI.pm @@ -3471,6 +3471,18 @@ LongTruncOk=1

    lastUpdated => 0, }, + 'no ldap link for auth' => { + message => q|Unable to create your account because no LDAP connection has been defined for this site.|, + context => 'Error message in createAccount screen when no LDAP connection is defined.', + lastUpdated => 1229376071, + }, + + 'no ldap logins' => { + message => q|Unable to log you in because no LDAP link has been defined for this site.|, + context => 'Error message for login when no LDAP connection is defined.', + lastUpdated => 1229376071, + }, + 'Select State' => { message => q|Select State|, lastUpdated => 1161388472,