From 24e799966ebc1ba119374b99e4f9858fb0b086dd Mon Sep 17 00:00:00 2001 From: Alexei Znamensky Date: Wed, 25 Jul 2012 01:17:33 -0300 Subject: [PATCH] Bug fix, small improvements - removed the Net::Server pre-requisite from dist.ini by mistake - variable for default log file - testing for config file existence is useless, since Net::Server checks and dies if the file is not readable - fix documentation in lib/Net/LDAP/SimpleServer.pm - tidy Signed-off-by: Alexei Znamensky --- dist.ini | 4 + lib/Net/LDAP/SimpleServer.pm | 72 +++++++++--------- lib/Net/LDAP/SimpleServer/ProtocolHandler.pm | 21 +++--- t/lib/Helper.pm | 77 ++++++++++---------- 4 files changed, 95 insertions(+), 79 deletions(-) diff --git a/dist.ini b/dist.ini index 51cdc5a..f599511 100644 --- a/dist.ini +++ b/dist.ini @@ -7,3 +7,7 @@ copyright_year = 2012 [@Author::RUSSOZ] version = gitnext +[Prereqs] +; keep the line below, Net::Server is loaded dynamically and Dist::Zilla +; will not automatically recognize it as a dependency +Net::Server = 2.003 diff --git a/lib/Net/LDAP/SimpleServer.pm b/lib/Net/LDAP/SimpleServer.pm index c6d9db4..4ca815a 100644 --- a/lib/Net/LDAP/SimpleServer.pm +++ b/lib/Net/LDAP/SimpleServer.pm @@ -38,6 +38,7 @@ use Net::LDAP::SimpleServer::ProtocolHandler; my $BASEDIR = File::Spec->catfile( home(), '.ldapsimple' ); my $DEFAULT_CONFIG_FILE = File::Spec->catfile( $BASEDIR, 'server.conf' ); my $DEFAULT_DATA_FILE = File::Spec->catfile( $BASEDIR, 'server.ldif' ); +my $DEFAULT_LOG_FILE = File::Spec->catfile( $BASEDIR, 'server.log' ); my @LDAP_PRIVATE_OPTIONS = ( 'store', 'input', 'output' ); my @LDAP_PUBLIC_OPTIONS = ( 'data_file', 'root_dn', 'root_pw', 'allow_anon' ); @@ -67,7 +68,7 @@ sub default_values { my $v = {}; $v->{port} = 389; - $v->{log_file} = File::Spec->catfile( $BASEDIR, 'server.log' ); + $v->{log_file} = $DEFAULT_LOG_FILE; $v->{conf_file} = $DEFAULT_CONFIG_FILE if -r $DEFAULT_CONFIG_FILE; $v->{syslog_ident} = 'Net::LDAP::SimpleServer [' . $Net::LDAP::SimpleServer::VERSION . ']'; @@ -88,8 +89,6 @@ sub post_configure_hook { make_path($BASEDIR); #use Data::Dumper; print STDERR '# ' . Dumper( $prop ); - croak q{Cannot read configuration file (} . $prop->{conf_file} . q{)} - if ( $prop->{conf_file} && !-r $prop->{conf_file} ); croak q{Configuration has no "data_file" file!} unless $prop->{data_file}; croak qq{Cannot read data_file file (} . $prop->{data_file} . q{)} @@ -150,9 +149,8 @@ __END__ # make it spin $server->run(); -The default configuration file is: - - ${HOME}/.ldapsimpleserver/config + # make it spin with options + $server->run({ allow_anon => 0 }); =head1 DESCRIPTION @@ -169,48 +167,46 @@ notably writing into the directory tree. The constructors will follow the rules defined by L, but the most useful are the two forms described below. +C will use the directory C<< ${HOME}/.ldapsimple >> +as a C for server files. If there exists a file: + + BASEDIR/server.conf + +it will be used as the default confguration file. Similarly, if there exists +a file: + + BASEDIR/server.ldif + +it will be used as the default data file for this server. + =method new() -Attempts to create a server by using the default configuration file, -C<< ${HOME}/.ldapsimpleserver/config >>. +Instantiates a server object. If the default configuration file is available, +the options in it will be used. =method new( HASHREF ) -Attempts to create a server by using the options specified in a hash -reference rather than reading them from a configuration file. +Instantiates a server object using the options specified in a hash +reference. =method options() As specified in L, this method creates new options for the, server, namely: -=over - -data_file - the LDIF data file used by LDIFStore - -root_dn - the administrator DN of the repository +=begin :list -root_pw - the password for root_dn +* data_file - the LDIF data file used by LDIFStore +* root_dn - the administrator DN of the repository +* root_pw - the password for root_dn +* allow_anon - whether to allow for anonymous binds -=back +=end :list =method default_values() As specified in L, this method provides default values for a -number of options. In Net::LDAP::SimpleServer, this method is defined as: - - sub default_values { - return { - host => '*', - port => 389, - proto => 'tcp', - root_dn => 'cn=root', - root_pw => 'ldappw', - syslog_ident => 'Net::LDAP::SimpleServer-' - . $Net::LDAP::SimpleServer::VERSION, - conf_file => $DEFAULT_CONFIG_FILE, - }; - } +number of options. Notice that we do set a default password for the C<< cn=root >> DN. This allows for out-of-the-box testing, but make sure you change the password @@ -218,7 +214,8 @@ when putting this to production use. =method post_configure_hook() -Method specified by L to validate the passed options +Method specified by L to validate the parameters used in the +server instance. =method process_request() @@ -231,16 +228,25 @@ L. Net::LDAP::SimpleServer may use a configuration file to specify the server settings. If no file is specified and options are not passed in a hash, this module will look for a default configuration file named -C<< ${HOME}/.ldapsimpleserver/config >>. +C<< BASEDIR/server.conf >>. data_file /path/to/a/ldif/file.ldif #port 389 #root_dn cn=root #root_pw somepassword + +=cut + +=head1 TODO + +We plan to implement more options in Net::LDAP::SimpleServer. Some ideas are: + #objectclass_req (true|false) #user_tree dc=some,dc=subtree,dc=com #user_id_attr uid #user_pw_attr password +Keeping in mind we do NOT want to implement a full blown LDAP server. + =cut diff --git a/lib/Net/LDAP/SimpleServer/ProtocolHandler.pm b/lib/Net/LDAP/SimpleServer/ProtocolHandler.pm index fc5b1ec..fab5254 100644 --- a/lib/Net/LDAP/SimpleServer/ProtocolHandler.pm +++ b/lib/Net/LDAP/SimpleServer/ProtocolHandler.pm @@ -52,9 +52,9 @@ sub new { croak 'Invalid root DN' unless my $canon_dn = canonical_dn( $params->{root_dn} ); - $self->{store} = $params->{store}; - $self->{root_dn} = $canon_dn; - $self->{root_pw} = $params->{root_pw}; + $self->{store} = $params->{store}; + $self->{root_dn} = $canon_dn; + $self->{root_pw} = $params->{root_pw}; $self->{allow_anon} = $params->{allow_anon}; chomp( $self->{root_pw} ); @@ -71,7 +71,7 @@ sub unbind { return _make_result(LDAP_SUCCESS); } -sub bind { ## no critic +sub bind { ## no critic (ProhibitBuiltinHomonyms) my ( $self, $request ) = @_; #print STDERR '=' x 70 . "\n"; @@ -79,7 +79,10 @@ sub bind { ## no critic #print STDERR Dumper($request); my $ok = _make_result(LDAP_SUCCESS); - if( not $request->{name} and exists $request->{authentication}->{simple} and $self->{allow_anon} ) { + if ( not $request->{name} + and exists $request->{authentication}->{simple} + and $self->{allow_anon} ) + { return $ok; } @@ -161,14 +164,14 @@ Creates a new handler for the LDAP protocol, using STORE as the backend where the directory data is stored. The rest of the IOHANDLES are the same as in the L module. -=method unbind() - -Unbinds the connection to the server. - =method bind( REQUEST ) Handles a bind REQUEST from the LDAP client. +=method unbind() + +Unbinds the connection to the server. + =method search( REQUEST ) Performs a search in the data store. diff --git a/t/lib/Helper.pm b/t/lib/Helper.pm index a001071..54faf6f 100644 --- a/t/lib/Helper.pm +++ b/t/lib/Helper.pm @@ -10,17 +10,16 @@ use IO::Pipe; use Net::LDAP; use Net::LDAP::SimpleServer; -my $default_test_port = 30389; +my $default_test_port = 30389; my $default_start_delay = 5; -my $default_end_signal = 3; +my $default_end_signal = 3; -my $server_fixed_opts = { - log_file => '/tmp/ldapserver.log', - port => $default_test_port, - host => 'localhost', +my $server_fixed_opts = { + log_file => '/tmp/ldapserver.log', + port => $default_test_port, + host => 'localhost', }; - ############################################################################## my $alarm_wait = 5; @@ -46,10 +45,11 @@ sub _eval_params { local $SIG{ALRM} = sub { quit($OK) }; alarm $alarm_wait; + diag( "Starting server on port: " . $default_test_port ); eval { use Net::LDAP::SimpleServer; - my $s = Net::LDAP::SimpleServer->new( $server_fixed_opts ); + my $s = Net::LDAP::SimpleServer->new($server_fixed_opts); $s->run($p); }; quit( $NOK . $@ ); @@ -96,36 +96,39 @@ sub ldap_client { } sub test_requests { - my $opts = ref $_[0] eq 'HASH' ? $_[0] : { @_ }; + my $opts = ref $_[0] eq 'HASH' ? $_[0] : {@_}; - my $requests_sub = $opts->{requests_sub} || croak "Must pass 'requests_sub'"; - my $server_opts = $opts->{server_opts} || croak "Must pass 'server_opts'"; + my $requests_sub = $opts->{requests_sub} + || croak "Must pass 'requests_sub'"; + my $server_opts = $opts->{server_opts} || croak "Must pass 'server_opts'"; my $start_delay = $opts->{start_delay} || $default_start_delay; - my $end_signal = $opts->{end_signal} || $default_end_signal; - - run_fork { - parent { - my $child = shift; - - # give the server some time to start - sleep $start_delay; - - # run client - diag('Net::LDAP::SimpleServer Testing [Knive]'); - $requests_sub->(); - - kill $end_signal, $child; - } - child { - diag('Net::LDAP::SimpleServer Instantiating [Fork]'); - my $s = Net::LDAP::SimpleServer->new( $server_fixed_opts ); - - # run server - diag('Net::LDAP::SimpleServer Starting [Fork]'); - $s->run( $server_opts ); - diag('Net::LDAP::SimpleServer Server stopped [Fork]'); - diag('There is no [Spoon]'); - } - }; + my $end_signal = $opts->{end_signal} || $default_end_signal; + + run_fork { + parent { + my $child = shift; + + # give the server some time to start + sleep $start_delay; + + # run client + diag('Net::LDAP::SimpleServer Testing [Knive]'); + $requests_sub->(); + + kill $end_signal, $child; + } + child { + diag('Net::LDAP::SimpleServer Instantiating [Fork]'); + my $s = Net::LDAP::SimpleServer->new($server_fixed_opts); + + # run server + diag( 'Net::LDAP::SimpleServer Starting :' + . $default_test_port + . ' [Fork]' ); + $s->run($server_opts); + diag('Net::LDAP::SimpleServer Server stopped [Fork]'); + diag('There is no [Spoon]'); + } + }; }