fake_net_ldap 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ *.gem
2
+ .bundle
3
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
@@ -0,0 +1,26 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ fake_net_ldap (0.0.1)
5
+ net-ldap
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ diff-lcs (1.1.2)
11
+ net-ldap (0.2.2)
12
+ rspec (2.6.0)
13
+ rspec-core (~> 2.6.0)
14
+ rspec-expectations (~> 2.6.0)
15
+ rspec-mocks (~> 2.6.0)
16
+ rspec-core (2.6.4)
17
+ rspec-expectations (2.6.0)
18
+ diff-lcs (~> 1.1.2)
19
+ rspec-mocks (2.6.0)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ fake_net_ldap!
26
+ rspec
@@ -0,0 +1,96 @@
1
+ = FakeNetLdap
2
+
3
+ FakeNetLdap is a helper for faking LDAP sarches made via the net-ldap library.
4
+ It works at a global level, without requiring modification of code or writing
5
+ of extensive stubs.
6
+
7
+
8
+ == FEATURES/PROBLEMS:
9
+
10
+ It is pretty limited in what it can do.
11
+
12
+ If it is used, all calls to bind, auth, and search are intercepted and not passed on
13
+ to the net-ldap library.
14
+
15
+ Queries must be made using Net::LDAP search method.
16
+
17
+ Responses to queries must be registered otherwise a
18
+ FakeNetLdap::ConnectionNotAllowed exception is raised.
19
+
20
+ The registered responses are yielded to a block passed to the search method.
21
+
22
+ == EXAMPLES:
23
+
24
+ Start by requiring FakeNetLdap:
25
+
26
+ require 'rubygems'
27
+ require 'fake_net_ldap'
28
+
29
+ === Registering users for binding
30
+
31
+ FakeNetLdap.register_user(:username => "fred", :password => "secret")
32
+
33
+ connection = Net::LDAP.new
34
+ connection.auth("fred", "secret")
35
+ connection.bind # returns true
36
+ connection.auth("fred", "forgotten")
37
+ connection.bind # returns false
38
+
39
+ === Registering basic hash responses to searches
40
+
41
+ For situations where you want to fake a single response to the search
42
+
43
+ user_filter = Net::LDAP::Filter.eq('uid', 'some-user')
44
+ FakeNetLdap.register_query(user_filter, {"name" => "Fred Blogs"})
45
+
46
+ connection = Net::LDAP.new
47
+ results = []
48
+ connection.search(:filter=> user_filter) { |r| results << r }
49
+ puts results.inspect # => [{"name" => "Fred Blogs"}]
50
+
51
+ === Registering a response to unregistered queries
52
+
53
+ To provide a default response to any queries that have not been registered
54
+ use:
55
+
56
+ FakeNetLdap.clear_query_registrations
57
+ FakeNetLdap.register_query(:unregistered_query, [{"name" => "Fred Blogs"}, {"name" => "John Smith"}])
58
+
59
+ unregistered_filter = Net::LDAP::Filter.eq('uid', 'some-user')
60
+ connection = Net::LDAP.new
61
+ results = []
62
+ connection.search(:filter=> unregistered_filter) { |r| results << r }
63
+ puts results.inspect # => [{"name" => "Fred Blogs"}, {"name" => "John Smith"}]
64
+
65
+ == REQUIREMENTS:
66
+
67
+ net-ldap
68
+
69
+ == INSTALL:
70
+
71
+ gem install fake_net_ldap
72
+
73
+ == LICENSE:
74
+
75
+ (The MIT License)
76
+
77
+ Copyright (c) 2011 roovo
78
+
79
+ Permission is hereby granted, free of charge, to any person obtaining a copy
80
+ of this software and associated documentation files (the "Software"), to deal
81
+ in the Software without restriction, including without limitation the rights
82
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
83
+ copies of the Software, and to permit persons to whom the Software is
84
+ furnished to do so, subject to the following conditions:
85
+
86
+ The above copyright notice and this permission notice shall be included in
87
+ all copies or substantial portions of the Software.
88
+
89
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
90
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
91
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
92
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
93
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
94
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
95
+ THE SOFTWARE.
96
+
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "fake_net_ldap/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "fake_net_ldap"
7
+ s.version = FakeNetLdap::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Rupert Voelcker", "Richard Pilkington"]
10
+ s.email = ["rupert.voelcker@bt.com", "richard.pilkington@bt.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{Use to fake out calls to Net::LDAP}
13
+
14
+ s.add_dependency "net-ldap"
15
+
16
+ s.add_development_dependency "rspec"
17
+
18
+ s.rubyforge_project = "fake_net_ldap"
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
23
+ s.require_paths = ["lib"]
24
+ end
@@ -0,0 +1,100 @@
1
+ require 'singleton'
2
+
3
+ require 'fake_net_ldap/ext/net_ldap'
4
+ require 'fake_net_ldap/registry'
5
+ require 'fake_net_ldap/responder'
6
+
7
+ module FakeNetLdap
8
+
9
+ # This exception is raised if you try to make a query you haven't
10
+ # registered.
11
+ class ConnectionNotAllowed < StandardError ; end ;
12
+
13
+ # call-seq:
14
+ # FakeNetLdap.clear_user_registrations
15
+ #
16
+ # clears all previously set user registrations
17
+ #
18
+ def self.clear_user_registrations
19
+ Registry.instance.clear_user_registrations
20
+ end
21
+
22
+ # call-seq:
23
+ # FakeNetLdap.register_user(:username => 'some-user', :password => 'a-password')
24
+ #
25
+ # Register a username/password which can be used when binding to the faked Net::LDAP.
26
+ #
27
+ def self.register_user(attrs)
28
+ Registry.instance.register_user(attrs)
29
+ end
30
+
31
+ # call-seq:
32
+ # FakeNetLdap.user_registered?(filter)
33
+ #
34
+ # Returns true if the username and password have been registered with FakeNetLdap.
35
+ #
36
+ def self.user_registered?(attrs)
37
+ Registry.instance.user_registered?(attrs)
38
+ end
39
+
40
+ # call-seq:
41
+ # FakeNetLdap.clear_query_registrations
42
+ #
43
+ # clears all previously set query registrations
44
+ #
45
+ def self.clear_query_registrations
46
+ Registry.instance.clear_query_registrations
47
+ end
48
+
49
+ # call-seq:
50
+ # FakeNetLdap.register_query(filter, response)
51
+ #
52
+ # Register a query filter and it's response. The +query+ should be a
53
+ # Net::LDAP::Filter It can also be set to the symbol :unregistered_query, in which
54
+ # case any calls to the Net::LDAP search method with unregistered queries
55
+ # will result in the response provided being yielded.
56
+ #
57
+ # Responses will be yielded to a call to the Net::LDAP search method.
58
+ # method. The +response+ must be one of the following types:
59
+ #
60
+ # <tt>Hash</tt>::
61
+ # For cases where a single response is expected from the LDAP directory.
62
+ # The hash will be yielded as a result of calling the LDAP::Conn.search2 method.
63
+ # Example:
64
+ # filter = Net::LDAP::Filter.eq('uid', 'some-user')
65
+ # FakeNetLdap.register_query(filter, {"uid" => "some-user"})
66
+ # <tt>Array</tt>::
67
+ # For cases where multiple responses are expected fron the LDAP directory.
68
+ # This should be an array of hashes. Each hash in the array will be yielded
69
+ # in turn. Example:
70
+ # filter = Net::LDAP::Filter.eq('gid', 'users')
71
+ # FakeNetLdap.register_query(filter, [{"uid" => "Fred Blogs"}, {"uid" => "John Smith"}])
72
+ # <tt>Exception</tt>::
73
+ # The specified exception will be raised when the query is made.
74
+ # Any +Exception+ class is valid. Example:
75
+ # filter = Net::LDAP::Filter.eq('gid', 'users')
76
+ # FakeNetLdap.register_query(filter, MyLdapError)
77
+ #
78
+ def self.register_query(filter, response)
79
+ Registry.instance.register_query(filter, response)
80
+ end
81
+
82
+ # call-seq:
83
+ # FakeNetLdap.query_registered?(filter)
84
+ #
85
+ # Returns true if +filter+ is registered with FakeNetLdap. This will always
86
+ # return true if the response for :unregistered_query has been registered.
87
+ #
88
+ def self.query_registered?(filter)
89
+ Registry.instance.query_registered?(filter)
90
+ end
91
+
92
+ # call-seq:
93
+ # FakeNetLdap.response_for(filter)
94
+ #
95
+ # Returns the faked response object associated with +filter+.
96
+ #
97
+ def self.response_for(filter, &block)
98
+ Registry.instance.response_for(filter, &block)
99
+ end
100
+ end
@@ -0,0 +1,23 @@
1
+ require 'net/ldap'
2
+
3
+ class Net::LDAP
4
+
5
+ def auth(username, password)
6
+ @username = username
7
+ @password = password
8
+ end
9
+
10
+ def bind
11
+ FakeNetLdap.user_registered?(:username => @username, :password => @password)
12
+ end
13
+
14
+ def search(attrs, &block)
15
+ if FakeNetLdap.query_registered?(attrs[:filter])
16
+ FakeNetLdap.response_for(attrs[:filter], &block)
17
+ else
18
+ raise FakeNetLdap::ConnectionNotAllowed,
19
+ "Real LDAP connections are disabled. Unregistered query: #{attrs[:filter]}"
20
+ end
21
+ end
22
+
23
+ end
@@ -0,0 +1,50 @@
1
+ module FakeNetLdap
2
+
3
+ class Registry #:nodoc:
4
+
5
+ include Singleton
6
+
7
+ def initialize
8
+ clear_query_registrations
9
+ clear_user_registrations
10
+ end
11
+
12
+ def clear_user_registrations
13
+ @user_map = {}
14
+ end
15
+
16
+ def register_user(attrs)
17
+ @user_map[attrs[:username]] = attrs[:password]
18
+ end
19
+
20
+ def user_registered?(attrs)
21
+ @user_map.has_key?(attrs[:username]) && (@user_map[attrs[:username]] == attrs[:password])
22
+ end
23
+
24
+ def clear_query_registrations
25
+ @query_map = {}
26
+ end
27
+
28
+ def register_query(query, response)
29
+ @query_map[query.to_s] = FakeNetLdap::Responder.new(query, response)
30
+ end
31
+
32
+ def query_registered?(query)
33
+ @query_map.has_key?(query.to_s) || @query_map.has_key?('unregistered_query')
34
+ end
35
+
36
+ def response_for(query, &block)
37
+ registered = query_registered?(query.to_s)
38
+ if registered && @query_map.has_key?(query.to_s)
39
+ response = @query_map[query.to_s]
40
+ elsif registered
41
+ response = @query_map['unregistered_query']
42
+ else
43
+ return nil
44
+ end
45
+
46
+ response.respond(&block)
47
+ end
48
+ end
49
+ end
50
+
@@ -0,0 +1,22 @@
1
+ module FakeNetLdap
2
+
3
+ class Responder #:nodoc:
4
+
5
+ def initialize(query, response)
6
+ @query = query
7
+ @response = response
8
+ end
9
+
10
+ def respond(&block)
11
+ case @response
12
+ when Hash
13
+ yield @response
14
+ when Array
15
+ @response.each { |r| yield r }
16
+ when Class
17
+ raise @response.new
18
+ end
19
+ end
20
+ end
21
+ end
22
+
@@ -0,0 +1,3 @@
1
+ module FakeNetLdap
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe "clearing query registrations" do
4
+
5
+ let(:filter) { Net::LDAP::Filter.present("objectclass") }
6
+
7
+ it "it should not show a query as registered after query registrations have been cleared" do
8
+ FakeNetLdap.register_query(filter, {"name" => "Fred Blogs"})
9
+ FakeNetLdap.clear_query_registrations
10
+ FakeNetLdap.query_registered?(filter).should be_false
11
+ end
12
+
13
+ it "it should raise an ConnectionNotAllowed exception after query registrations have been cleared" do
14
+ FakeNetLdap.register_query(filter, {"name" => "Fred Blogs"})
15
+ FakeNetLdap.clear_query_registrations
16
+ connection = ldap_connection
17
+ lambda { connection.search(:base => 'cn=plop', :filter => filter) { |r| } }.should raise_error(FakeNetLdap::ConnectionNotAllowed)
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe "clearing user registrations" do
4
+
5
+ it "it should not show a user as registered after user registrations have been cleared" do
6
+ FakeNetLdap.register_user(:username => "fred", :password => "secret")
7
+ FakeNetLdap.clear_user_registrations
8
+ FakeNetLdap.user_registered?(:username => "fred", :password => "secret").should be_false
9
+ end
10
+
11
+ it "it should not allow binds once user registrations have been cleared" do
12
+ FakeNetLdap.register_user(:username => "fred", :password => "secret")
13
+ FakeNetLdap.clear_user_registrations
14
+ connection = ldap_connection
15
+ connection.auth("fred", "secret")
16
+ connection.bind.should be_false
17
+ end
18
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe "registering queries" do
4
+
5
+ let(:filter) { Net::LDAP::Filter.present("objectclass") }
6
+
7
+ before do
8
+ FakeNetLdap.clear_query_registrations
9
+ end
10
+
11
+ it "should allow queries to be registered to respond with a hash (for a single response)" do
12
+ FakeNetLdap.register_query(filter, {"name" => "Fred Blogs"})
13
+ FakeNetLdap.query_registered?(filter).should be_true
14
+ end
15
+
16
+ it "should allow queries to be registered to respond with an array (for multiple responses)" do
17
+ FakeNetLdap.register_query(filter, [{"name" => "Fred Blogs"}, {"name" => "John Smith"}])
18
+ FakeNetLdap.query_registered?(filter).should be_true
19
+ end
20
+
21
+ it "should allow queries to be registered which should raise an exception" do
22
+ FakeNetLdap.register_query(filter, StandardError)
23
+ FakeNetLdap.query_registered?(filter).should be_true
24
+ end
25
+
26
+ it "shold show an unregistered query as unregistered" do
27
+ FakeNetLdap.query_registered?(filter).should be_false
28
+ end
29
+
30
+ it "should yield the registered response if a hash response is registered" do
31
+ FakeNetLdap.register_query(filter, {"name" => "Fred Blogs"})
32
+ responses = []
33
+ connection = ldap_connection
34
+ connection.search(:base => 'cn=plop', :filter => filter) do |result|
35
+ responses << result
36
+ end
37
+ responses.should == [{"name" => "Fred Blogs"}]
38
+ end
39
+
40
+ it "should yield the registered response if an array response is registered" do
41
+ FakeNetLdap.register_query(filter, [{"name" => "Fred Blogs"}, {"name" => "John Smith"}])
42
+ filter_copy = Net::LDAP::Filter.present("objectclass")
43
+ responses = []
44
+ connection = ldap_connection
45
+ connection.search(:base => 'cn=plop', :filter => filter_copy) do |result|
46
+ responses << result
47
+ end
48
+ responses.should == [{"name" => "Fred Blogs"}, {"name" => "John Smith"}]
49
+ end
50
+
51
+ it "should raise an exception if an exception response is registered" do
52
+ class ExpectedException < StandardError ; end ;
53
+ FakeNetLdap.register_query(filter, ExpectedException)
54
+ connection = ldap_connection
55
+ lambda { connection.search(:base => 'cn=plop', :filter => filter) { |r| } }.should raise_error(ExpectedException)
56
+ end
57
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe "registering users" do
4
+
5
+ before do
6
+ FakeNetLdap.clear_user_registrations
7
+ end
8
+
9
+ it "should return true when binding for a registered user" do
10
+ FakeNetLdap.register_user(:username => "fred", :password => "secret")
11
+ connection = ldap_connection
12
+ connection.auth("fred", "secret")
13
+ connection.bind.should be_true
14
+ end
15
+
16
+ it "should return false when binding for an unregistered user" do
17
+ connection = ldap_connection
18
+ connection.auth("fred", "secret")
19
+ connection.bind.should be_false
20
+ end
21
+
22
+ it "should return false when binding for a registered user with the wrong password" do
23
+ FakeNetLdap.register_user(:username => "fred", :password => "secret")
24
+ connection = ldap_connection
25
+ connection.auth("fred", "wrong_password")
26
+ connection.bind.should be_false
27
+ end
28
+ end
29
+
@@ -0,0 +1,18 @@
1
+ require 'bundler'
2
+ Bundler.require
3
+ require 'net/ldap'
4
+
5
+
6
+ $:.unshift(File.expand_path('../../lib', __FILE__))
7
+ require 'fake_net_ldap'
8
+
9
+ RSpec.configure do |c|
10
+ c.formatter = :doc
11
+ end
12
+
13
+ LDAP_HOST = "ldap.example.com"
14
+ LDAP_PORT = 389
15
+
16
+ def ldap_connection
17
+ Net::LDAP.new
18
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe "registering a response to unregistered queries" do
4
+
5
+ let(:filter) { Net::LDAP::Filter.present("objectclass") }
6
+
7
+ before do
8
+ FakeNetLdap.clear_query_registrations
9
+ end
10
+
11
+ it "should raise an ConnectionNotAllowed exception if the response to unregistered queries has not been set" do
12
+ FakeNetLdap.query_registered?(filter).should be_false
13
+ connection = ldap_connection
14
+ lambda { connection.search(:base => 'cn=plop', :filter => filter) { |r| } }.should raise_error(FakeNetLdap::ConnectionNotAllowed)
15
+ end
16
+
17
+ it "should say that a query is registered if it hasn't been but the response to unregistered queries has been set" do
18
+ FakeNetLdap.register_query(:unregistered_query, {"name" => "Fred Blogs"})
19
+ FakeNetLdap.query_registered?(filter).should be_true
20
+ end
21
+
22
+ it "should return the response if the response to unregistered queries has been set" do
23
+ FakeNetLdap.register_query(:unregistered_query, {"name" => "Fred Blogs"})
24
+ responses = []
25
+ connection = ldap_connection
26
+ connection.search(:base => 'cn=plop', :filter => filter) do |result|
27
+ responses << result
28
+ end
29
+ responses.should == [{"name" => "Fred Blogs"}]
30
+ end
31
+ end
32
+
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fake_net_ldap
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Rupert Voelcker
14
+ - Richard Pilkington
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2011-07-06 00:00:00 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: net-ldap
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: rspec
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id002
49
+ description:
50
+ email:
51
+ - rupert.voelcker@bt.com
52
+ - richard.pilkington@bt.com
53
+ executables: []
54
+
55
+ extensions: []
56
+
57
+ extra_rdoc_files: []
58
+
59
+ files:
60
+ - .gitignore
61
+ - Gemfile
62
+ - Gemfile.lock
63
+ - README.rdoc
64
+ - Rakefile
65
+ - fake_net_ldap.gemspec
66
+ - lib/fake_net_ldap.rb
67
+ - lib/fake_net_ldap/ext/net_ldap.rb
68
+ - lib/fake_net_ldap/registry.rb
69
+ - lib/fake_net_ldap/responder.rb
70
+ - lib/fake_net_ldap/version.rb
71
+ - spec/clear_query_registrations_spec.rb
72
+ - spec/clear_user_registrations_spec.rb
73
+ - spec/register_query_spec.rb
74
+ - spec/register_user_spec.rb
75
+ - spec/spec_helper.rb
76
+ - spec/unregistered_query_spec.rb
77
+ homepage: ""
78
+ licenses: []
79
+
80
+ post_install_message:
81
+ rdoc_options: []
82
+
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ hash: 3
91
+ segments:
92
+ - 0
93
+ version: "0"
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ hash: 3
100
+ segments:
101
+ - 0
102
+ version: "0"
103
+ requirements: []
104
+
105
+ rubyforge_project: fake_net_ldap
106
+ rubygems_version: 1.7.2
107
+ signing_key:
108
+ specification_version: 3
109
+ summary: Use to fake out calls to Net::LDAP
110
+ test_files:
111
+ - spec/clear_query_registrations_spec.rb
112
+ - spec/clear_user_registrations_spec.rb
113
+ - spec/register_query_spec.rb
114
+ - spec/register_user_spec.rb
115
+ - spec/spec_helper.rb
116
+ - spec/unregistered_query_spec.rb