# Copyright 2004-2007, Fred Steinberg, Brown Bear Software

# User groups from LDAP

package LDAPGroup;

use strict;
use Net::LDAP;
use Calendar::User::LDAPAuth;

our $lastError;

# Return list of user group names
sub getGroupNames {
    my $classname = shift;
    my $ldap = User::LDAPAuth->_connectToServer;
    return unless $ldap;

    my $prefs = MasterDB->new->getPreferences;
    my $base   = $prefs->LDAPGroupBase;
    my $filter = $prefs->LDAPGroupFilter;
    my $attrib = $prefs->LDAPGroupAttrib;

    # bind if anonymous searches not allowed
    User::LDAPAuth->_bind_for_search ($prefs, $ldap) || return;

    my $results = $ldap->search (base   => $base,
                                 filter => $filter);
    if (my $code = $results->code) {
        my $mess = $results->error;
        $lastError = "Search failed; code $code, '$mess'";
        return;
    }

    my @groups;
    foreach ($results->entries) {
        push @groups, $_->get_value ($attrib);
    }
    return @groups;
}

sub getGroupMembers {
    my ($classname, $groupName) = @_;

    my $ldap = User::LDAPAuth->_connectToServer;
    return unless $ldap;

    my $prefs = MasterDB->new->getPreferences;

    User::LDAPAuth->_bind_for_search ($prefs, $ldap) || return;

    my $base     = $prefs->LDAPGroupBase;
    my $filter   = $prefs->LDAPGroupAttrib . "=$groupName";
    my $attrib   = $prefs->LDAPGroupMemberAttrib;
    my $idAttrib = $prefs->LDAPUserAttrib;

    my $results = $ldap->search (base   => $base,
                                 filter => $filter);
    if (my $code = $results->code) {
        my $mess = $results->error;
        $lastError = "Search failed; code $code, '$mess'";
        return;
    }

    unless ($results->count) {
        $lastError = "Group '$groupName' not found.";
        return;
    }

    my @members;
    foreach my $group ($results->entries) { # usually only 1 result
        foreach ($group->get_value ($attrib)) {
            next unless $_;       # skip empty members
            /($idAttrib|CN)=([^,]+)/i;
            push @members, $2;    # grab just first part of dn
        }
    }
    return @members;
}

1;
