diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt
index 2cead9696..15ab292e0 100644
--- a/docs/changelog/7.x.x.txt
+++ b/docs/changelog/7.x.x.txt
@@ -24,6 +24,11 @@
- Added option to WebGUI Auth module to require strong passwords. Admins can
now require users to enter a specific combination of characters, etc.
- Added skeleton code for writing WebGUI utility scripts.
+ - Added auto-registration via LDAP. This allows users to simply login and
+ have a WebGUI account created if their credentials are validated by the
+ directory.
+ - Added a Sync Profile to LDAP workflow activity that will grab a single user
+ profile from LDAP instead of all of them.
7.0.9
- Removed the need for DateTime::Cron::Simple, which also added the ability
diff --git a/docs/upgrades/upgrade_7.0.9-7.1.0.pl b/docs/upgrades/upgrade_7.0.9-7.1.0.pl
index 0ea244c2f..27a601ddb 100755
--- a/docs/upgrades/upgrade_7.0.9-7.1.0.pl
+++ b/docs/upgrades/upgrade_7.0.9-7.1.0.pl
@@ -12,7 +12,7 @@ use lib "../../lib";
use strict;
use Getopt::Long;
use WebGUI::Session;
-
+use WebGUI::Workflow;
my $toVersion = "7.1.0"; # make this match what version you're going to
my $quiet; # this line required
@@ -25,9 +25,34 @@ updateProductsTable($session);
makeLdapRecursiveFiltersText($session);
addImageStuffToCs($session);
addNewAuthSettings($session);
+addAutoLDAPRegistration($session);
finish($session); # this line required
+#-------------------------------------------------
+sub addAutoLDAPRegistration {
+ my $session = shift;
+ print "\tAdding new feature that allows autoregistration of WebGUI users from LDAP directories.\n" unless $quiet;
+
+ # Put an entry in the settings table to turn this thing on and off
+ $session->db-write("insert into settings (name,value) values ('automaticLDAPRegistration',0)");
+
+ # Enable our new workflow activity in the config file
+ my $activities = $session->config->get("workflowActivities");
+ push (@{$activities->{'WebGUI::User'}}, 'WebGUI::Workflow::Activity::SyncProfileToLdap');
+ $session->config->set("workflowActivities", $activities);
+
+ # Add a workflow that the LDAP auth module can kick off to pull the users info from LDAP to their wG user profile.
+ my $workflow = WebGUI::Workflow->create($session, {
+ type=>"WebGUI::User",
+ enabled=>1,
+ description=>"Synchronizes a users LDAP information to their WebGUI User Profile",
+ title=>"Synchronize Profile To LDAP"
+ }, "AuthLDAPworkflow000001");
+ my $activity = $workflow->addActivity("WebGUI::Workflow::Activity::SyncProfileToLdap");
+ $activity->set("title","Synchronize Profile To LDAP");
+}
+
#-------------------------------------------------
sub addNewAuthSettings {
my $session = shift;
@@ -65,20 +90,21 @@ sub recalculateProjectCompletion {
}
}
-
+#-------------------------------------------------
sub updateSqlReportTable {
my $session = shift;
print "\tUpdating SQLReport table structure.\n" unless ($quiet);
$session->db->write("alter table `SQLReport` ADD COLUMN ( downloadType varchar(255), downloadFilename varchar(255), downloadTemplateId varchar(22), downloadMimeType varchar(255), downloadUserGroup varchar(22))");
}
-
+#-------------------------------------------------
sub updateProductsTable {
my $session = shift;
print "\tUpdating products table structure.\n" unless ($quiet);
$session->db->write("alter table products add column (groupId varchar(22), groupExpiresOffset varchar(16))");
}
+#-------------------------------------------------
sub makeLdapRecursiveFiltersText {
my $session = shift;
print "\tMaking LDAP recursive filters text fields.\n" unless $quiet;
diff --git a/lib/WebGUI/Auth/LDAP.pm b/lib/WebGUI/Auth/LDAP.pm
index 7206b9539..75aa33e67 100644
--- a/lib/WebGUI/Auth/LDAP.pm
+++ b/lib/WebGUI/Auth/LDAP.pm
@@ -16,6 +16,7 @@ use WebGUI::HTMLForm;
use WebGUI::Form;
use WebGUI::LDAPLink;
use WebGUI::Utility;
+use WebGUI::Workflow;
use WebGUI::Operation::Shared;
use WebGUI::Asset::Template;
use URI;
@@ -25,103 +26,184 @@ our @ISA = qw(WebGUI::Auth);
#-------------------------------------------------------------------
+=head2 sub _isValidLDAPUser ( )
+
+Private method that gets username and password supplied by a user attempting to
+login and then attempts to bind to the LDAP server using credentials provided.
+If the bind is successful, the user is considered valid and authenticated as far
+as LDAP is concerned.
+
+Note: This method does not ensure that the user is valid in WebGUI.
+i.e., it does not validate their username or ensure their account is active.
+
+=cut
+
sub _isValidLDAPUser {
my $self = shift;
- my ($uri, $error, $ldap, $search, $auth, $connectDN);
- my $i18n = WebGUI::International->new($self->session);
- my $connection = $self->{_connection};
+ my ($uri, $error, $ldap, $search, $auth, $connectDN, $username, $password);
+ my $i18n = WebGUI::International->new($self->session);
+ my $connection = $self->getLDAPConnection;
+
+ $username = $self->session->form->get("authLDAP_ldapId") || $self->session->form->get("username");
+ $password = $self->session->form->get("authLDAP_identifier") || $self->session->form->get("identifier");
+
$uri = URI->new($connection->{ldapUrl}) or $error = $i18n->get(2,'AuthLDAP');
+
if($error ne ""){
$self->error($error);
- return 0;
+ return 0;
}
+ # Create an LDAP object
if ($ldap = Net::LDAP->new($uri->host, (port=>$uri->port))) {
+
+ # Bind as a proxy user to search for the user trying to login
if($connection->{connectDn}) {
- $auth = $ldap->bind(dn=>$connection->{connectDn}, password=>$connection->{identifier});
- }else{
- $auth = $ldap->bind;
- }
+ $auth = $ldap->bind(dn=>$connection->{connectDn}, password=>$connection->{identifier});
+ }
+ else { # No proxy user specified, try to bind anonymously for the search
+ $auth = $ldap->bind;
+ }
+
+ # If we were able to bind
if ($auth) {
- $search = $ldap->search ( base=>$uri->dn, filter=>$connection->{ldapIdentity}."=".$self->session->form->process('authLDAP_ldapId'));
- if (defined $search->entry(0)) {
- if ($connection->{ldapUserRDN} eq 'dn') {
- $connectDN = $search->entry(0)->dn;
- } else {
- $connectDN = $search->entry(0)->get_value($connection->{ldapUserRDN});
- }
- $ldap->unbind;
- $ldap = Net::LDAP->new($uri->host, (port=>$uri->port)) or $error .= $i18n->get(2,'AuthLDAP');
- $auth = $ldap->bind(dn=>$connectDN, password=>$self->session->form->process('authLDAP_identifier'));
- if ($auth->code == 48 || $auth->code == 49) {
- $error .= '
'.$i18n->get(68).'';
- $self->session->errorHandler->warn("Invalid LDAP information for registration of LDAP ID: ".$self->session->form->process('authLDAP_ldapId'));
- } elsif ($auth->code > 0) {
- $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(68).'';
- $self->session->errorHandler->warn("Invalid LDAP information for registration of LDAP ID: ".$self->session->form->process("authLDAP_ldapId"));
+
+ # Search for the user trying to login
+ $search = $ldap->search(base=>$uri->dn, filter=>$connection->{ldapIdentity}.'='.$username);
+
+ # If we found a match
+ if (defined $search->entry(0)) {
+
+ # Determine the users distinguished name using dn
+ if ($connection->{ldapUserRDN} eq 'dn') {
+ $connectDN = $search->entry(0)->dn;
}
- } else {
- $error = $i18n->get(2,'AuthLDAP');
- $self->session->errorHandler->error("Couldn't bind to LDAP server: ".$connection->{ldapUrl});
- }
- } else {
- $error = $i18n->get(2,'AuthLDAP');
- $self->session->errorHandler->error("Couldn't create LDAP object: ".$uri->host);
- }
- $self->error($error);
- return $error eq "";
+ else { # or... use a releative distinguished name instead
+ $connectDN = $search->entry(0)->get_value($connection->{ldapUserRDN});
+ }
+
+ # Remember the users DN so we can use it later.
+ $self->setConnectDN($connectDN);
+ $ldap->unbind;
+
+ # Create a new LDAP object
+ $ldap = Net::LDAP->new($uri->host, (port=>$uri->port)) or $error .= $i18n->get(2,'AuthLDAP');
+
+ # Try to bind to the directory using the users dn and password
+ $auth = $ldap->bind(dn=>$connectDN, password=>$password);
+
+ # Invalid login credentials, directory did not authenticate the user
+ if ($auth->code == 48 || $auth->code == 49) {
+ $error .= ''.$i18n->get(68).'';
+ $self->session->errorHandler->warn("Invalid LDAP information for registration of LDAP ID: ".$self->session->form->process('authLDAP_ldapId'));
+ }
+ elsif ($auth->code > 0) { # Some other LDAP error occured
+ $error .= 'LDAP error "'.$self->ldapStatusCode($auth->code).'" occured. '.$i18n->get(69).'';
+ $self->session->errorHandler->error("LDAP error: ".$self->ldapStatusCode($auth->code));
+ }
+ $ldap->unbind;
+ }
+ else { # Could not find the user in the directory to build a DN
+ $error .= ''.$i18n->get(68).'';
+ $self->session->errorHandler->warn("Invalid LDAP information for registration of LDAP ID: ".$self->session->form->process("authLDAP_ldapId"));
+ }
+ }
+ else { # Unable to bind with proxy user credentials or anonymously for our search
+ $error = $i18n->get(2,'AuthLDAP');
+ $self->session->errorHandler->error("Couldn't bind to LDAP server: ".$connection->{ldapURL});
+ }
+ }
+ else { # Could not create our LDAP object
+ $error = $i18n->get(2,'AuthLDAP');
+ $self->session->errorHandler->error("Couldn't create LDAP object: ".$uri->host);
+ }
+
+ $self->error($error);
+
+ # Return 1 on successful authentication
+ return $error eq "";
}
#-------------------------------------------------------------------
+=head2 sub authenticate ( $username, $password )
+
+This method checks a given username and password for the following:
+
+1) Is there a WebGUI user account for the user and is it active
+2) Does the user account have the properties set necessary to authenticate using
+ LDAP.
+3) Can we bind to the LDAP server using their account information
+
+Returns 1 on success.
+
+=cut
+
sub authenticate {
- my $self = shift;
- my ($uri, $ldap, $auth, $result, $error);
- return 0 if !$self->SUPER::authenticate($_[0]); #authenticate that the username entered actually exists and is active
- my $userId = $self->userId;
- my $identifier = $_[1];
- my $userData = $self->getParams;
+ my $self = shift;
+ my ($uri, $ldap, $auth, $result, $error);
+ my $i18n = WebGUI::International->new($self->session);
+ return 0 if !$self->SUPER::authenticate($_[0]); #see that the username entered actually exists and is active in webgui
+
+ 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);
+
+ if($error ne ""){
+ $self->user(WebGUI::User->new($self->session,1));
+ return 0 ;
+ }
- my $i18n = WebGUI::International->new($self->session);
- $error .= $i18n->get(12,'AuthLDAP') if ($userData->{ldapUrl} eq "");
- $error .= $i18n->get(11,'AuthLDAP') if ($userData->{connectDN} eq "");
+ if($uri = URI->new($userData->{ldapUrl})) {
+
+ # Create an LDAP object
+ $ldap = Net::LDAP->new($uri->host, (port=>$uri->port)) or $error .= $i18n->get(2,'AuthLDAP');
+
+ if($error ne ""){
+ $self->user(WebGUI::User->new($self->session,1));
+ return 0 ;
+ }
+
+ # Try to bind using the users dn and password
+ $auth = $ldap->bind(dn=>$userData->{connectDN}, password=>$identifier);
+
+ # Authentication failed
+ if ($auth->code == 48 || $auth->code == 49){
+ $error .= $i18n->get(68);
+ }
+ elsif ($auth->code > 0) { # Some other LDAP error happened
+ $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});
+ }
- $self->error($error);
- if($error ne ""){
- $self->user(WebGUI::User->new($self->session,1));
- return 0 ;
- }
-
- if($uri = URI->new($userData->{ldapUrl})) {
- $ldap = Net::LDAP->new($uri->host, (port=>$uri->port)) or $error .= $i18n->get(2,'AuthLDAP');
- if($error ne ""){
- $self->user(WebGUI::User->new($self->session,1));
- return 0 ;
- }
- $auth = $ldap->bind(dn=>$userData->{connectDN}, password=>$identifier);
- if ($auth->code == 48 || $auth->code == 49){
- $error .= $i18n->get(68);
- }elsif($auth->code > 0){
- $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));
- }
- return $error eq "";
+ if($error ne ""){
+ $self->error($error);
+ $self->user(WebGUI::User->new($self->session,1));
+ }
+
+ return $error eq "";
}
+#-------------------------------------------------------------------
+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);
+ my $connection = $ldapLink->get;
+
+ $self->{_connection} = $connection;
+ return $connection;
+}
#-------------------------------------------------------------------
sub createAccount {
@@ -135,11 +217,8 @@ sub createAccount {
return $self->displayLogin;
}
- if($self->session->form->process("connection")) {
- $self->session->scratch->set("ldapConnection",$self->session->form->process("connection"));
- $self->{_connection} = WebGUI::LDAPLink->new($self->session,$self->session->form->process("connection"))->get;
- }
- my $connection = $self->{_connection};
+
+ my $connection = $self->getLDAPConnection;
$vars->{'create.message'} = $message if ($message);
my $i18n = WebGUI::International->new($self->session,"AuthLDAP");
$vars->{'create.form.ldapConnection.label'} = $i18n->get("ldapConnection");
@@ -173,9 +252,9 @@ sub createAccountSave {
return $self->createAccount("".$i18n->get(70)."
".$self->error);
}
- my $connection = $self->{_connection};
+ my $connection = $self->getLDAPConnection;
#Get connectDN from settings
- my $uri = URI->new($connection->{ldapUrl});
+ my $uri = URI->new($connection->{ldapURL});
my $ldap = Net::LDAP->new($uri->host, (port=>$uri->port));
my $auth;
if($connection->{connectDn}) {
@@ -209,7 +288,7 @@ sub createAccountSave {
my $properties;
$properties->{connectDN} = $connectDN;
- $properties->{ldapUrl} = $connection->{ldapUrl};
+ $properties->{ldapUrl} = $connection->{ldapURL};
return $self->SUPER::createAccountSave($username,$properties,$password,$profile);
}
@@ -264,8 +343,8 @@ sub displayLogin {
sub editUserForm {
my $self = shift;
my $userData = $self->getParams;
- my $connection = $self->{_connection};
- my $ldapUrl = $self->session->form->process('authLDAP_ldapUrl') || $userData->{ldapUrl} || $connection->{ldapUrl};
+ my $connection = $self->getLDAPConnection;
+ 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};
my $ldapLinks = $self->session->db->buildHashRef("select ldapLinkId,ldapUrl from ldapLink");
@@ -355,40 +434,83 @@ sub editUserSettingsForm {
#-------------------------------------------------------------------
sub editUserSettingsFormSave {
- my $self = shift;
- my $f = $self->session->form;
- my $s = $self->session->setting;
- $s->set("ldapConnection", $f->process("ldapConnection","selectBox"));
+ my $self = shift;
+ my $f = $self->session->form;
+ my $s = $self->session->setting;
+ $s->set("ldapConnection", $f->process("ldapConnection","selectBox"));
}
#-------------------------------------------------------------------
sub getAccountTemplateId {
my $self = shift;
- return ($self->{_connection}->{ldapAccountTemplate} || "PBtmpl0000000000000004");
+ return ($self->getLDAPConnection->{ldapAccountTemplate} || "PBtmpl0000000000000004");
+}
+
+#-------------------------------------------------------------------
+sub getConnectDN {
+ my $self = shift;
+ return $self->{_connectDN};
}
#-------------------------------------------------------------------
sub getCreateAccountTemplateId {
my $self = shift;
- return ($self->{_connection}->{ldapCreateAccountTemplate} || "PBtmpl0000000000000005");
+ return ($self->getLDAPConnection->{ldapCreateAccountTemplate} || "PBtmpl0000000000000005");
+}
+
+#-------------------------------------------------------------------
+sub getLDAPConnection {
+ my $self = shift;
+
+ return $self->{_connection} if $self->{_connection};
+ return $self->connectToLDAP;
}
#-------------------------------------------------------------------
sub getLoginTemplateId {
my $self = shift;
- return ($self->{_connection}->{ldapLoginTemplate} || "PBtmpl0000000000000006");
+ return ($self->getLDAPConnection->{ldapLoginTemplate} || "PBtmpl0000000000000006");
}
#-------------------------------------------------------------------
sub login {
my $self = shift;
- if(!$self->authenticate($self->session->form->process("username"),$self->session->form->process("identifier"))){
- $self->session->errorHandler->security("login to account ".$self->session->form->process("username")." with invalid information.");
- my $i18n = WebGUI::International->new($self->session);
- return $self->displayLogin("".$i18n->get(70)."
".$self->error);
+ 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) );
+
+ # 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}
+ },$identifier);
+ $hasAuthenticated = 1;
+
+ # Pull the users profile from LDAP to WebGUI
+ WebGUI::Workflow::Instance->create($self->session, {
+ workflowId=>'AuthLDAPworkflow000001',
+ methodName=>"new",
+ className=>"WebGUI::User",
+ parameters=>$self->session->user->userId,
+ priority=>3
+ });
+ }
+ }
}
- $self->session->scratch->delete("ldapConnection");
- return $self->SUPER::login(); #Standard login routine for login
+ return $self->SUPER::login() if $hasAuthenticated; #Standard login routine for login
+
+ $self->session->errorHandler->security("login to account ".$self->session->form->process("username")." with invalid information.");
+ return $self->displayLogin("".$i18n->get(70)."
".$self->error);
}
#-------------------------------------------------------------------
@@ -399,9 +521,10 @@ sub new {
my $userId = $_[1];
my @callable = ('createAccount','deactivateAccount','displayAccount','displayLogin','login','logout','createAccountSave','deactivateAccountConfirm');
my $self = WebGUI::Auth->new($session,$authMethod,$userId,\@callable);
- my $connection = $session->scratch->get("ldapConnection") || $session->setting->get("ldapConnection");
- my $ldaplink = WebGUI::LDAPLink->new($session,$connection);
- $self->{_connection} = $ldaplink->get if $ldaplink;
+ #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);
@@ -413,8 +536,14 @@ sub new {
sub ldapStatusCode {
my ($self, $code) = @_;
return $self->{_statusCode}->{$code};
-
}
+#-------------------------------------------------------------------
+sub setConnectDN {
+ my $self = shift;
+ $self->{_connectDN} = $_[0];
+}
+
+
1;
diff --git a/lib/WebGUI/Operation/Settings.pm b/lib/WebGUI/Operation/Settings.pm
index 2efc6de1f..3debf661c 100644
--- a/lib/WebGUI/Operation/Settings.pm
+++ b/lib/WebGUI/Operation/Settings.pm
@@ -256,6 +256,14 @@ sub definition {
hoverHelp=>$i18n->get('118 description'),
defaultValue=>$session->setting->get("anonymousRegistration")
});
+ push(@fields, {
+ tab=>"user",
+ fieldType=>"yesNo",
+ name=>"automaticLDAPRegistration",
+ label=>$i18n->echo("Automatic LDAP Registration"),
+ hoverHelp=>$i18n->echo('When set to yes, a WebGUI user account will be created and the user logged in, if the credentials entered are validated by LDAP.'),
+ defaultValue=>$session->setting->get("automaticLDAPRegistration")
+ });
push(@fields, {
tab=>"user",
fieldType=>"workflow",
diff --git a/lib/WebGUI/Workflow/Activity/SyncProfileToLdap.pm b/lib/WebGUI/Workflow/Activity/SyncProfileToLdap.pm
new file mode 100644
index 000000000..4fd75ae7f
--- /dev/null
+++ b/lib/WebGUI/Workflow/Activity/SyncProfileToLdap.pm
@@ -0,0 +1,152 @@
+package WebGUI::Workflow::Activity::SyncProfileToLdap;
+
+
+=head1 LEGAL
+
+ -------------------------------------------------------------------
+ WebGUI is Copyright 2001-2006 Plain Black Corporation.
+ -------------------------------------------------------------------
+ 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 strict;
+use base 'WebGUI::Workflow::Activity';
+use Net::LDAP;
+use WebGUI::Auth;
+use WebGUI::User;
+
+=head1 NAME
+
+Package WebGUI::Workflow::Activity::SyncProfileToLdap
+
+=head1 DESCRIPTION
+
+Synchoronizes the data for one user in your LDAP directory with the WebGUI user's profile. This is a one way sync, so data comes from LDAP to WebGUI, not the other way around.
+
+=head1 SYNOPSIS
+
+See WebGUI::Workflow::Activity for details on how to use any activity.
+
+=head1 METHODS
+
+These methods are available from this class:
+
+=cut
+
+
+#-------------------------------------------------------------------
+
+=head2 definition ( session, definition )
+
+See WebGUI::Workflow::Activity::defintion() for details.
+
+=cut
+
+sub definition {
+ my $class = shift;
+ my $session = shift;
+ my $definition = shift;
+ my $i18n = WebGUI::International->new($session, "AuthLDAP");
+ push(@{$definition}, {
+ name=>$i18n->echo("Synchronize Profile To LDAP"),
+ properties=> { }
+ });
+ return $class->SUPER::definition($session,$definition);
+}
+
+
+
+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)',
+ 10=>'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=>'LDAP Entry Does Not Exist (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)',70=>'The results of the request are to large (70)',
+ 71=>'Affects Multiple DSAs (71)', 80=>'other (80)',81=>'Net::LDAP cannot establish a connection or the connection has been lost (81)',
+ 85=>'Net::LDAP timeout while waiting for a response from the server (85)',
+ 86=>'The method of authentication requested in a bind request is unknown to the server (86)',
+ 87=>'An error occurred while encoding the given search filter. (87)',
+ 89=>'An invalid parameter was specified (89)',90=>'Out of Memory (90)',91=>'A connection to the server could not be established (91)',
+ 92=>'An attempt has been made to use a feature not supported by Net::LDAP (92)');
+
+#-------------------------------------------------------------------
+sub _alias {
+ my %alias = (
+ firstName=>"cn",
+ lastName=>"sn",
+ email=>"mail",
+ companyName=>"o"
+ );
+ return $alias{$_[0]} || $_[0];
+}
+
+#-------------------------------------------------------------------
+
+=head2 execute ( )
+
+See WebGUI::Workflow::Activity::execute() for details.
+
+=cut
+
+sub execute {
+ my $self = shift;
+ my $userObject = shift; # Set to the current user by the instance
+ my ($userId, $u, $userData, $uri, $port, %args, $fieldName, $ldap, $search, $a, $b);
+
+ $userId = $userObject->userId;
+ my $auth = WebGUI::Auth->new($self->session, "LDAP",$userId);
+ $userData = $auth->getParams;
+ $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);
+ if ($ldap) {
+ my $result = $ldap->bind;
+ if ($result->code == 0) {
+ $search = $ldap->search( base=>$userData->{connectDN}, filter=>"&(objectClass=*)" );
+ if($search->code) {
+ $self->session->errorHandler->warn("Couldn't search LDAP ".$uri->host." to find user ".$u->username." (".$userId.").\nError Message from LDAP: ".$ldapStatusCode{$search->code});
+ }
+ elsif ($search->count == 0) {
+ $self->session->errorHandler->warn("No results returned for user with dn ".$userData->{connectDN});
+ }
+ else {
+ $b = $self->session->db->read("select fieldName from userProfileField where profileCategoryId<>4");
+ while (($fieldName) = $b->array) {
+ if ($search->entry(0)->get_value(_alias($fieldName)) ne "") {
+ $userObject->profileField($fieldName,$search->entry(0)->get_value(_alias($fieldName)));
+ }
+ }
+ $b->finish;
+ }
+ $ldap->unbind;
+ }
+ else {
+ $self->session->errorHandler->warn("Couldn't bind to LDAP host ".$uri->host."\nError Message from LDAP: ".$ldapStatusCode{$result->code});
+ }
+
+ }
+ $a->finish;
+ return $self->COMPLETE;
+}
+
+1;