'Populate rosters with chatrooms' support added.
[vcard2ldap.git] / tools / Vcard2Ldap.pm
blobb0ea01f917235b0c899f580d1ccd9374666d0175
1 package Vcard2Ldap;
3 #### CONFIG
4 our $jabberd = "jabber.domain.com";
5 our $groupname = "Iris";
7 my $vcardtpl = "../ldap/vcard.xml";
9 my $basedn = "dc=nodomain";
10 my $ldapserver = "localhost";
11 my $disname="cn=admin,dc=nodomain";
12 my $ldappass= "secret";
13 my $ldapperson = "irisPerson";
14 my $ldapchatroom = "";
16 my $ldapgroup = "ou";
17 my $ldapjidattr = "irisUserPresenceID";
18 my $ldapjidmatch = qr/urn:mace:rediris.es:presence:xmpp:([\w\-_\.]+@.+)/;
20 ##########################
22 =head1 NAME
24 Vcard2Ldap - Stuff for convert LDAP entries to Jabberd roster ones.
26 =head1 SYNOPSIS
28 use Vcard2Ldap;
29 my $ldap = Vcard2Ldap::ldap_open ();
30 my $users = Vcard2Ldap::jabber_get_users ($ldap);
31 my $vcard2ldap = Vcard2Ldap::vcard_get_map ();
33 foreach ($users) {
34 print $_->{"jid"} . "\n";
35 print $_->{"rostergroup"} . "\n";
38 my $us = $ldap->search(
39 base => "dc=nodomain",
40 scope => "one",
41 filter => "(cn=*)"
44 foreach ($us->entries) {
45 print Vcard2Ldap::jabber_jid ($_) . "\n";
48 $ldap->unbind;
50 print $vcard2ldap->{"FN"} . "\n";
51 #...
53 =head1 DESCRIPTION
55 This module isn't intend for general usage, it was made for the sole purpose of
56 working together with vcard2ldap jabberd module.
58 See http://repo.or.cz/w/vcard2ldap.git for details.
60 =head2 GLOBALS
62 =over 12
64 List of global variables.
66 =item C<$jabberd>
68 The jabberd server hostname
70 =item C<$groupname>
72 The name of the roster group where jids will be stored.
74 =head2 FUNCTIONS
76 List of public functions.
78 =item C<ldap_open>
80 Open connection. Returns a LDAP handler.
82 =item C<jabber_get_users>
84 Returns a list of records: {jid,group}
86 =item C<jabber_jid>
88 Returns a jid from an LDAP entry. Empty string if none.
90 =item C<jabber_group>
92 Returns the group of the LDAP entry. Empty string if none.
94 =item C<vcard_get_map>
96 Returns the "vCard map". This hash maps XML vCard tags to LDAP attributes.
98 =cut
100 use strict;
101 use XML::Simple;
102 use Net::LDAP;
103 use Net::LDAP::Control;
105 my @users;
107 sub ldap_open {
108 my $ldap = Net::LDAP->new ($ldapserver, debug => 0) or die "$@";
109 my $mesg = $ldap->bind (
110 $disname,
111 password => $ldappass,
112 version => 3) or die "Cannot bind to ldap server ($!)";
114 die $mesg->error if $mesg->code;
116 return $ldap;
119 sub ldap_get_users {
120 my $ldap = shift;
122 my $us = $ldap->search(
123 base => "$basedn",
124 scope => "one",
125 filter => "(&(objectClass=$ldapperson)($ldapgroup=*))"
127 die $us->error if $us->code;
129 if ($#users == -1) {
130 add_users ($us);
131 add_chatrooms ($ldap) if (length ($ldapchatrooms) > 0);
134 return $us->entries;
137 sub jabber_get_users {
138 my $ldap = shift;
140 ldap_get_users ($ldap) if ($#users == -1);
142 return @users;
145 sub jabber_user {
146 my $ujid = shift;
148 foreach (Vcard2Ldap::jabber_get_users ()) {
149 return $_ if ($_->{"jid"} eq $ujid);
152 warn $ujid . ": user not in directory or malformed entry!";
153 return "";
156 sub jabber_jid {
157 my $user = shift;
158 my $attr = $user->get_value ($ldapjidattr, asref => 1);
160 if ($attr) {
161 foreach (@{$attr}) {
162 return lc ($_) if (length ($ldapjidmatch) == 0);
163 return lc ($1) if ($_ =~ $ldapjidmatch);
167 warn $user->get_value ("cn") . ": user with no jid!";
168 return "";
171 sub jabber_group {
172 my $user = shift;
173 my $group = $user->get_value ($ldapgroup, asref => 1);
175 return lc (@{$group}[0]) if ($#{$group} == 0);
177 warn $user->get_value ("cn") . ": group is unique and mandatory!";
178 return "";
181 sub vcard_get_map {
182 my $xs = new XML::Simple (keeproot => 0, suppressempty => 1);
183 my $vcard = $xs->XMLin($vcardtpl);
184 my $vcard2ldap;
186 while (my ($key, $value) = each (%$vcard)) {
187 for (split(/\n/, parse_vcard ($key, $value))) {
188 my @sp = split(/ /, $_);
189 $vcard2ldap->{$sp[0]} = $sp[1];
193 return $vcard2ldap;
196 ### private
198 sub add_users {
199 my $us = shift;
201 foreach ($us->entries) {
202 my $jid = jabber_jid ($_);
203 my $rgroup = jabber_group ($_);
205 push @users , {
206 "jid" => $jid,
207 "rostergroup" => $rgroup
208 } if ($jid && $rgroup);
212 sub add_chatrooms {
213 my $ldap = shift;
215 my $us = $ldap->search(
216 base => "$basedn",
217 scope => "one",
218 filter => "(&(objectClass=$ldapchatroom)($ldapgroup=*))"
221 die $us->error if $us->code;
223 add_users ($us);
226 sub parse_vcard {
227 my $key = shift;
228 my $value = shift;
229 my $ret = "";
231 if (!ref ($value) && !($key eq "xmlns")) {
232 $ret .= $key . " " . $value . "\n";
233 } elsif (ref ($value) eq "HASH" ) {
234 for (keys %$value) {
235 if ($_ eq "v2ln") {
236 next;
237 } elsif ($_ eq "content") {
238 $ret .= "$key". parse_vcard ("", $value->{$_});
239 } else {
240 $ret .= "$key/". parse_vcard ($_, $value->{$_});
243 } elsif (ref ($value) eq "ARRAY") {
244 for (@$value) {
245 $ret .= "$key" . parse_vcard ("", $_);
249 return $ret;