# BEGIN LICENSE BLOCK
#
# Copyright (c) 2005 Nathan Mehl <rt-ad-sso@memory.blank.org>
# (Except where explictly superceded by other copyright notices)
# portions Copyright (c) 2004 Petter Reinholdtsen <pere@hungry.com>
# portions Copyright (c) 2004 Jesse Vincent <jesse@fsck.com>
#
# This work is made available to you under the terms of Version 2 of
# the GNU General Public License. A copy of that license should have
# been provided with this software, but in any event can be snarfed
# from www.gnu.org.
#
# This work is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# Unless otherwise specified, all modifications, corrections or
# extensions to this work which alter its source code become the
# property of Best Practical Solutions, LLC when submitted for
# inclusion in the work.
#
#
# END LICENSE BLOCK

package RT::Interface::Web;

no warnings qw(redefine);

# {{{ WebExternalAutoInfo

=head2 WebExternalAutoInfo($user);

Returns a hash of user attributes, used when WebExternalAuto is set.

=cut

sub WebExternalAutoInfo {
    my $user = shift;

    my %user_info;

    $user_info{'Privileged'} = 0;

    $RT::Logger->debug( "WebExternalAutoInfo: Looking for ", $user );
    my ($UserFoundInExternalDatabase, %ExternalUserInfo) =
        LookupExternalUsername( $user );

    # populate user fields from the ldap directory
    if ($UserFoundInExternalDatabase) {
	$user_info{'RealName'} = $ExternalUserInfo{'RealName'} if defined $ExternalUserInfo{'RealName'};
	$user_info{'Name'} = $ExternalUserInfo{'Name'} if defined $ExternalUserInfo{'Name'};
	$user_info{'EmailAddress'} = $ExternalUserInfo{'EmailAddress'} if defined $ExternalUserInfo{'EmailAddress'};
    } elsif ($^O !~ /^(?:riscos|MacOS|MSWin32|dos|os2)$/) {
	# Populate fields with information from Unix /etc/passwd
	my ($comments, $realname) = (getpwnam($user))[5, 6];
	$user_info{'Comments'} = $comments if defined $comments;
	$user_info{'RealName'} = $realname if defined $realname;
    }
    elsif ($^O eq 'MSWin32' and eval 'use Net::AdminMisc; 1') {
	# Populate fields with information from NT domain controller
    }

    # and return the wad of stuff
    return {%user_info};
}

# }}}

sub LookupExternalUsername {
  my %UserInfo = ();
  $UserInfo{'Name'} = shift;
  $UserInfo{'Name'} =~ s/\"//g;

  my $FoundInExternalDatabase = 0;

  $RT::Logger->debug( "LookupExternalUsername: Looking for ", $UserInfo{'Name'} );
  # Name is the RT username you want to use for this user.
  my %LdapUserInfo = LdapUserFindByUsername($UserInfo{'Name'});
  if ($LdapUserInfo{'Name'}) {
      $FoundInExternalDatabase = 1;
      $RT::Logger->debug("LookupExternalUsername: Mapping '".
                        $UserInfo{'Name'} .
                        "' to '" .
                        $LdapUserInfo{'EmailAddress'} . "'");
      foreach my $key (keys %LdapUserInfo) {
          $UserInfo{$key} = $LdapUserInfo{$key};
      }
  } else {
      $RT::Logger->debug("LookupExternalUsername: Fail to find username for '".
                        $UserInfo{'Name'}."'");
  }

  return ($FoundInExternalDatabase, %UserInfo);
}

sub LdapUserFindByUsername {
    my $username = shift;
    my %UserInfo = ();

    my $ldap = RT::User::LdapConnect();
    my $filter = "(&($RT::LdapAuthUidAttr=$username)$RT::LdapMailFilter)";
    my @attr = keys %RT::LdapMailResultMap;
    $RT::Logger->debug( "LdapUserFindByUsername: Looking for ",
                           join(" ", @attr), " filter=", $filter );
    my $mesg = $ldap->search(
                          base       => $RT::LdapMailBase,
                          scope      => $RT::LdapMailScope,
                          filter     => $filter,
                          attributes => [@attr],
                          );
    if ( ($mesg->code != LDAP_SUCCESS) and
         ($mesg->code != LDAP_PARTIAL_RESULTS) ) {
        $RT::Logger->critical("LdapUserFindByUsername: Search failed: ",
                              "retval=", $mesg->code, " ",
                              ldap_error_name($mesg->code));
        RT::User::LdapDisconnect($ldap);
        return undef;
    }

    if (1 != $mesg->count) {
        $RT::Logger->critical("LdapUserFindByUsername: Search returned 0 results: ",
                              "retval=", $mesg->code, " ",
                              ldap_error_name($mesg->code));
        RT::User::LdapDisconnect($ldap);
        return undef;
    }

    while( my $entry = $mesg->shift_entry) {
        foreach my $attr (keys %RT::LdapMailResultMap) {
            foreach my $value ($entry->get_value($attr)) {
                $UserInfo{$RT::LdapMailResultMap{$attr}} = $value;
            }
        }
    }
    RT::User::LdapDisconnect($ldap);
    return %UserInfo;
}

1;
