File Coverage

blib/lib/Apache/Session/Store/LDAP.pm
Criterion Covered Total %
statement 9 64 14.0
branch 0 26 0.0
condition 0 2 0.0
subroutine 3 10 30.0
pod 0 7 0.0
total 12 109 11.0


line stmt bran cond sub pod time code
1             package Apache::Session::Store::LDAP;
2              
3 1     1   7 use strict;
  1         2  
  1         46  
4 1     1   15 use vars qw($VERSION);
  1         2  
  1         40  
5 1     1   3017 use Net::LDAP;
  1         1127992  
  1         9  
6              
7             $VERSION = '0.2';
8              
9             sub new {
10 0     0 0   my $class = shift;
11 0           return bless {}, $class;
12             }
13              
14             sub insert {
15 0     0 0   my $self = shift;
16 0           my $session = shift;
17 0           $self->{args} = $session->{args};
18              
19 0           my $msg = $self->ldap->add(
20             "cn=$session->{data}->{_session_id}," . $self->{args}->{ldapConfBase},
21             attrs => [
22             objectClass => [ 'top', 'applicationProcess' ],
23             cn => $session->{data}->{_session_id},
24             description => $session->{serialized},
25             ],
26             );
27 0 0         $self->logError($msg) if ( $msg->code );
28             }
29              
30             sub update {
31 0     0 0   my $self = shift;
32 0           my $session = shift;
33 0           $self->{args} = $session->{args};
34              
35 0           my $msg = $self->ldap->modify(
36             "cn=$session->{data}->{_session_id}," . $self->{args}->{ldapConfBase},
37             replace => { description => $session->{serialized}, },
38             );
39              
40 0 0         $self->logError($msg) if ( $msg->code );
41             }
42              
43             sub materialize {
44 0     0 0   my $self = shift;
45 0           my $session = shift;
46 0           $self->{args} = $session->{args};
47              
48 0           my $msg = $self->ldap->search(
49             base => "cn=$session->{data}->{_session_id},"
50             . $self->{args}->{ldapConfBase},
51             filter => '(objectClass=applicationProcess)',
52             scope => 'base',
53             attrs => ['description'],
54             );
55              
56 0 0         $self->logError($msg) if ( $msg->code );
57              
58 0           eval {
59 0           $session->{serialized} = $msg->shift_entry()->get_value('description');
60             };
61              
62 0 0         if ( !defined $session->{serialized} ) {
63 0           die "Object does not exist in data store";
64             }
65             }
66              
67             sub remove {
68 0     0 0   my $self = shift;
69 0           my $session = shift;
70 0           $self->{args} = $session->{args};
71              
72 0           $self->ldap->delete(
73             "cn=$session->{data}->{_session_id}," . $self->{args}->{ldapConfBase} );
74             }
75              
76             sub ldap {
77 0     0 0   my $self = shift;
78 0 0         return $self->{ldap} if ( $self->{ldap} );
79              
80             # Parse servers configuration
81 0           my $useTls = 0;
82 0           my $tlsParam;
83 0           my @servers = ();
84 0           foreach my $server ( split /[\s,]+/, $self->{args}->{ldapServer} ) {
85 0 0         if ( $server =~ m{^ldap\+tls://([^/]+)/?\??(.*)$} ) {
86 0           $useTls = 1;
87 0           $server = $1;
88 0   0       $tlsParam = $2 || "";
89             }
90             else {
91 0           $useTls = 0;
92             }
93 0           push @servers, $server;
94             }
95              
96             # Connect
97 0 0         my $ldap = Net::LDAP->new(
    0          
98             \@servers,
99             onerror => undef,
100             (
101             $self->{args}->{ldapPort}
102             ? ( port => $self->{args}->{ldapPort} )
103             : ()
104             ),
105             ) or die( 'Unable to connect to ' . join( ' ', @servers ) );
106              
107             # Start TLS if needed
108 0 0         if ($useTls) {
109 0           my %h = split( /[&=]/, $tlsParam );
110 0 0         $h{cafile} = $self->{args}->{caFile} if ( $self->{args}->{caFile} );
111 0 0         $h{capath} = $self->{args}->{caPath} if ( $self->{args}->{caPath} );
112 0           my $start_tls = $ldap->start_tls(%h);
113 0 0         if ( $start_tls->code ) {
114 0           $self->logError($start_tls);
115 0           return;
116             }
117             }
118              
119             # Bind with credentials
120 0           my $bind = $ldap->bind( $self->{args}->{ldapBindDN},
121             password => $self->{args}->{ldapBindPassword} );
122 0 0         if ( $bind->code ) {
123 0           $self->logError($bind);
124 0           return;
125             }
126              
127 0           $self->{ldap} = $ldap;
128 0           return $ldap;
129             }
130              
131             sub logError {
132 0     0 0   my $self = shift;
133 0           my $ldap_operation = shift;
134 0           die "LDAP error " . $ldap_operation->code . ": " . $ldap_operation->error;
135             }
136              
137             1;
138              
139             =pod
140              
141             =head1 NAME
142              
143             Apache::Session::Store::LDAP - Use LDAP to store persistent objects
144              
145             =head1 SYNOPSIS
146              
147             use Apache::Session::Store::LDAP;
148              
149             my $store = new Apache::Session::Store::LDAP;
150              
151             $store->insert($ref);
152             $store->update($ref);
153             $store->materialize($ref);
154             $store->remove($ref);
155              
156             =head1 DESCRIPTION
157              
158             This module fulfills the storage interface of Apache::Session. The serialized
159             objects are stored in an LDAP directory file using the Net::LDAP Perl module.
160              
161             =head1 OPTIONS
162              
163             This module requires one argument in the usual Apache::Session style. The
164             keys ldapServer, ldapBase, ldapBindDN, ldapBindPassword are required. The key
165             ldapPort is optional. Example:
166              
167             tie %s, 'Apache::Session::LDAP', undef,
168             {
169             ldapServer => 'localhost',
170             ldapBase => 'dc=example,dc=com',
171             ldapBindDN => 'cn=admin,dc=example,dc=com',
172             ldapBindPassword => 'pass',
173             };
174              
175             =head1 AUTHOR
176              
177             Xavier Guimard, Eguimard@E
178              
179             =head1 COPYRIGHT AND LICENSE
180              
181             Copyright (C) 2009, 2012 by Xavier Guimard
182              
183             This library is free software; you can redistribute it and/or modify
184             it under the same terms as Perl itself, either Perl version 5.10.0 or,
185             at your option, any later version of Perl 5 you may have available.
186              
187             =head1 SEE ALSO
188              
189             L
190              
191             =cut