jabber2db: update/delete users.
[vcard2ldap.git] / tools / Vcard2Ldap.pm
blob379b8f00270618057c463a0bf1d218a8cb4639a8
1 package Vcard2Ldap;
3 #### CONFIG
5 our $jabberd = "jabber.domain.com";
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 $ldapgroupmatch = "";
18 my $ldapjid = "irisUserPresenceID";
19 my $ldapjidmatch = qr/urn:mace:rediris.es:presence:xmpp:([\w\-_\.]+@.+)/;
21 ##########################
23 =head1 NAME
25 Vcard2Ldap - Stuff for convert LDAP entries to Jabberd roster ones.
27 =head1 SYNOPSIS
29 use Vcard2Ldap;
30 my $ldap = Vcard2Ldap::ldap_open ();
31 my $users = Vcard2Ldap::jabber_get_users ($ldap);
32 my $vcard2ldap = Vcard2Ldap::vcard_get_map ();
34 foreach ($users) {
35 print $_->{"jid"} . "\n";
36 print $_->{"rostergroup"} . "\n";
39 my $us = $ldap->search (
40 base => "dc=nodomain",
41 scope => "one",
42 filter => "(cn=*)"
45 foreach ($us->entries) {
46 print Vcard2Ldap::jabber_jid ($_) . "\n";
49 $ldap->unbind;
51 print $vcard2ldap->{"FN"} . "\n";
52 #...
54 =head1 DESCRIPTION
56 This module isn't intend for general usage, it was made for the sole purpose of
57 working together with vcard2ldap jabberd module.
59 See http://repo.or.cz/w/vcard2ldap.git for details.
61 =head2 GLOBALS
63 =over 12
65 List of global variables.
67 =item C<$jabberd>
69 The jabberd server hostname
71 =item C<$groupname>
73 The name of the roster group where jids will be stored.
75 =head2 FUNCTIONS
77 List of public functions.
79 =item C<ldap_open>
81 Open connection. Returns a LDAP handler.
83 =item C<jabber_get_users>
85 Returns a list of records: {jid,group}
87 =item C<jabber_jid>
89 Returns a jid from an LDAP entry. Empty string if none.
91 =item C<jabber_group>
93 Returns the list of groups of the LDAP entry. Empty array if none.
95 =item C<vcard_get_map>
97 Returns the "vCard map". This hash maps XML vCard tags to LDAP attributes.
99 =cut
101 use strict;
102 use XML::Simple;
103 use Net::LDAP;
104 use Net::LDAP::Control;
106 my @users;
108 sub ldap_open {
109 my $ldap = Net::LDAP->new ($ldapserver, debug => 0) or die "$@";
110 my $mesg = $ldap->bind (
111 $disname,
112 password => $ldappass,
113 version => 3) or die "Cannot bind to ldap server ($!)";
115 die $mesg->error if $mesg->code;
117 return $ldap;
120 sub ldap_get_users {
121 my $ldap = shift;
123 my $us = $ldap->search (
124 base => "$basedn",
125 scope => "one",
126 filter => "(&(objectClass=$ldapperson)($ldapgroup=*))"
128 die $us->error if $us->code;
130 if ($#users == -1) {
131 add_users ($us);
132 add_chatrooms ($ldap) if (length ($ldapchatroom) > 0);
135 return $us->entries;
138 sub jabber_get_users {
139 my $ldap = shift;
141 ldap_get_users ($ldap) if ($#users == -1);
143 return @users;
146 sub jabber_user {
147 my $ujid = shift;
149 foreach (Vcard2Ldap::jabber_get_users ()) {
150 return $_ if ($_->{"jid"} eq $ujid);
153 warn $ujid . ": user not in directory or malformed entry!";
154 return "";
157 sub jabber_jid {
158 my $user = shift;
159 my $attr = $user->get_value ($ldapjid, asref => 1);
160 my $jid = "";
162 if ($attr) {
163 foreach (@{$attr}) {
164 if (length ($ldapjidmatch) == 0) {
165 $jid = lc ($_);
166 } elsif ($_ =~ $ldapjidmatch) {
167 $jid = lc ($1);
170 if ($jid) {
171 if (index ($jid, "@") == -1) {
172 $jid .= "\@$jabberd";
174 last;
179 warn $user->get_value ("cn") . ": user with no jid!" if (!$jid);
180 return $jid;
183 sub jabber_group {
184 my $user = shift;
185 my $attr = $user->get_value ($ldapgroup, asref => 1);
186 my @group = ();
188 if ($attr) {
189 foreach (@{$attr}) {
190 my $tmp;
192 if (length ($ldapgroupmatch) == 0) {
193 $tmp = lc ($_);
194 } elsif ($_ =~ $ldapgroupmatch) {
195 $tmp = lc ($1);
198 (push @group, $tmp) if ($tmp);
202 if ($#group == -1) {
203 warn $user->get_value ("cn") . ": group is mandatory!";
206 return @group;
209 sub vcard_get_map {
210 my $xs = new XML::Simple (keeproot => 0, suppressempty => 1);
211 my $vcard = $xs->XMLin ($vcardtpl);
212 my $vcard2ldap;
214 while (my ($key, $value) = each (%$vcard)) {
215 for (split (/\n/, parse_vcard ($key, $value))) {
216 my @sp = split (/ /, $_);
217 $vcard2ldap->{$sp[0]} = $sp[1];
221 return $vcard2ldap;
224 ### private
226 sub add_users {
227 my $us = shift;
229 foreach ($us->entries) {
230 my $jid = jabber_jid ($_);
231 my @rgroup = jabber_group ($_);
233 if ($jid) {
234 foreach (@rgroup) {
235 push @users , {
236 "jid" => $jid,
237 "rostergroup" => $_
244 sub add_chatrooms {
245 my $ldap = shift;
247 my $us = $ldap->search (
248 base => "$basedn",
249 scope => "one",
250 filter => "(&(objectClass=$ldapchatroom)($ldapgroup=*))"
253 die $us->error if $us->code;
255 add_users ($us);
258 sub parse_vcard {
259 my $key = shift;
260 my $value = shift;
261 my $ret = "";
263 if (!ref ($value) && !($key eq "xmlns")) {
264 $ret .= $key . " " . $value . "\n";
265 } elsif (ref ($value) eq "HASH" ) {
266 for (keys %$value) {
267 if ($_ eq "v2ln") {
268 next;
269 } elsif ($_ eq "content") {
270 $ret .= "$key". parse_vcard ("", $value->{$_});
271 } else {
272 $ret .= "$key/". parse_vcard ($_, $value->{$_});
275 } elsif (ref ($value) eq "ARRAY") {
276 for (@$value) {
277 $ret .= "$key" . parse_vcard ("", $_);
281 return $ret;