el_dap 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.
- data/.gitignore +5 -0
- data/.rspec +2 -0
- data/.rvmrc +11 -0
- data/CHANGELOG +8 -0
- data/Gemfile +16 -0
- data/LICENSE +20 -0
- data/README.rdoc +70 -0
- data/Rakefile +2 -0
- data/el_dap.gemspec +21 -0
- data/lib/el_dap.rb +9 -0
- data/lib/el_dap/.rvmrc +10 -0
- data/lib/el_dap/api_methods.rb +18 -0
- data/lib/el_dap/base.rb +79 -0
- data/lib/el_dap/constants.rb +7 -0
- data/lib/el_dap/version.rb +3 -0
- data/spec/el_dap/api_methods_spec.rb +36 -0
- data/spec/el_dap/base_spec.rb +111 -0
- data/spec/el_dap/constants_spec.rb +23 -0
- data/spec/spec_helper.rb +13 -0
- metadata +64 -0
data/.rspec
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
environment_id="ruby-1.9.2-head@el_dap"
|
3
|
+
|
4
|
+
if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
|
5
|
+
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]] ; then
|
6
|
+
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
7
|
+
else
|
8
|
+
# If the environment file has not yet been created, use the RVM CLI to select.
|
9
|
+
rvm --create "$environment_id"
|
10
|
+
fi
|
11
|
+
|
data/CHANGELOG
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in el_dap.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
gem 'net-ldap'
|
7
|
+
|
8
|
+
group :development, :test do
|
9
|
+
gem 'autotest'
|
10
|
+
gem 'autotest-notification'
|
11
|
+
gem 'bundler'
|
12
|
+
gem 'launchy'
|
13
|
+
gem 'rcov'
|
14
|
+
gem 'rspec'
|
15
|
+
end
|
16
|
+
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Ed James
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
= El Dap
|
2
|
+
|
3
|
+
A simple search and authentication tool for Active Directory using LDAP.
|
4
|
+
|
5
|
+
== Why make this?
|
6
|
+
|
7
|
+
The need for this gem arose out of a business requirement for all user authentication to be done against Active Directory.
|
8
|
+
Our users were tired of having to remember multiple usernames and passwords, and asked if they could simply use their network
|
9
|
+
credentials to log into our applications. This gem passes off their username and password to an Active Directory / LDAP
|
10
|
+
server for authentication.
|
11
|
+
|
12
|
+
Additionally, users are also able to search the Active Directory.
|
13
|
+
|
14
|
+
== Installation
|
15
|
+
|
16
|
+
Just add this to your gem file:
|
17
|
+
|
18
|
+
gem 'el_dap'
|
19
|
+
|
20
|
+
== Features
|
21
|
+
|
22
|
+
* Easily perform authentication against an Active Directory / LDAP server
|
23
|
+
* Search an Active Directory based on wildcard search criteria
|
24
|
+
|
25
|
+
== Usage
|
26
|
+
|
27
|
+
Assuming we have an Active Directory called *ad.domain.com* which can also be referred to simply as *ad*,
|
28
|
+
the following examples are valid:
|
29
|
+
|
30
|
+
=== Authenticate a user
|
31
|
+
|
32
|
+
ElDap.configure do |c|
|
33
|
+
c.server_ips = ['127.0.0.1']
|
34
|
+
c.treebase = 'dc=ad,dc=domain,dc=com'
|
35
|
+
end
|
36
|
+
|
37
|
+
ElDap.validate("ad\\ed.james", 'password') # will return true if username and password are valid
|
38
|
+
ElDap.validate("ed.james@ad.domain.com", 'password') # will return true if username and password are valid
|
39
|
+
|
40
|
+
=== Search the directory
|
41
|
+
|
42
|
+
ElDap.configure do |c|
|
43
|
+
c.username = 'service.account@ad.domain.com'
|
44
|
+
c.password = 'password'
|
45
|
+
c.server_ips = ['127.0.0.1']
|
46
|
+
c.treebase = 'dc=ad,dc=domain,dc=com'
|
47
|
+
end
|
48
|
+
|
49
|
+
ElDap.search('some guy') # will return an array of OpenStruct objects for each matching search result.
|
50
|
+
|
51
|
+
== Contributing to El Dap
|
52
|
+
|
53
|
+
My understanding of LDAP limited. This gem has only been tested on a Linux server which queries Active Directory. The gem is in
|
54
|
+
production, but I'm not sure how well it will perform in another kind of LDAP-enabled architecture. Any comments or assistence
|
55
|
+
would be greatly appreciated.
|
56
|
+
|
57
|
+
If you want to contribute:
|
58
|
+
|
59
|
+
* Check out the latest master to make sure the feature hasn’t been implemented or the bug hasn’t been fixed yet
|
60
|
+
* Check out the issue tracker to make sure someone already hasn’t requested it and/or contributed it
|
61
|
+
* Fork the project
|
62
|
+
* Start a feature/bugfix branch
|
63
|
+
* Commit and push until you are happy with your contribution
|
64
|
+
* Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.
|
65
|
+
* Please try not to mess with the Rakefile, version, or history.
|
66
|
+
|
67
|
+
== Copyright
|
68
|
+
|
69
|
+
Copyright (c) 2011 Ed James. See LICENSE for details.
|
70
|
+
|
data/Rakefile
ADDED
data/el_dap.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "el_dap/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "el_dap"
|
7
|
+
s.version = ElDap::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Ed James"]
|
10
|
+
s.email = ["ed.james.email@gmail.com"]
|
11
|
+
s.homepage = "https://github.com/edjames/el_dap"
|
12
|
+
s.summary = %q{A simple search and authentication tool for Active Directory using LDAP.}
|
13
|
+
s.description = %q{A simple search and authentication tool for Active Directory using LDAP.}
|
14
|
+
|
15
|
+
s.rubyforge_project = "el_dap"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
end
|
data/lib/el_dap.rb
ADDED
data/lib/el_dap/.rvmrc
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
environment_id="ruby-1.9.2-head@el_dap"
|
3
|
+
|
4
|
+
if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
|
5
|
+
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]] ; then
|
6
|
+
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
7
|
+
else
|
8
|
+
rvm --create "$environment_id"
|
9
|
+
fi
|
10
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module ElDap
|
2
|
+
module ApiMethods
|
3
|
+
|
4
|
+
def configure
|
5
|
+
@@worker = Base.new
|
6
|
+
yield(@@worker)
|
7
|
+
end
|
8
|
+
|
9
|
+
def validate(username, password)
|
10
|
+
@@worker.validate(username, password)
|
11
|
+
end
|
12
|
+
|
13
|
+
def search(search_string)
|
14
|
+
@@worker.search(search_string)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
data/lib/el_dap/base.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
module ElDap
|
2
|
+
class Base
|
3
|
+
include Constants
|
4
|
+
|
5
|
+
attr_accessor :server_ips, :username, :password, :timeout, :treebase
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@server_ips = []
|
9
|
+
@timeout = 15
|
10
|
+
yield(self) if block_given?
|
11
|
+
end
|
12
|
+
|
13
|
+
def validate(uname, pword)
|
14
|
+
return false if uname.nil? || uname.empty? || pword.nil? || pword.empty?
|
15
|
+
workers(uname, pword).each do |worker|
|
16
|
+
begin
|
17
|
+
Timeout::timeout(self.timeout) do
|
18
|
+
return worker.bind
|
19
|
+
end
|
20
|
+
rescue Timeout::Error
|
21
|
+
next
|
22
|
+
end
|
23
|
+
end
|
24
|
+
false
|
25
|
+
end
|
26
|
+
|
27
|
+
def search(search_string)
|
28
|
+
return nil if search_string.nil? || search_string.empty?
|
29
|
+
search_result = nil
|
30
|
+
workers(self.username, self.password).each do |worker|
|
31
|
+
begin
|
32
|
+
Timeout::timeout(self.timeout) do
|
33
|
+
search_result ||= search_active_directory(worker, search_string)
|
34
|
+
end
|
35
|
+
rescue Timeout::Error
|
36
|
+
next
|
37
|
+
end
|
38
|
+
end
|
39
|
+
create_result_collection search_result
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
def workers(uname = self.username, pword = self.password)
|
44
|
+
self.server_ips.map do |ip|
|
45
|
+
create_worker uname, pword, ip
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def create_worker(uname, pword, server_ip)
|
50
|
+
obj = ::Net::LDAP.new
|
51
|
+
obj.host = server_ip
|
52
|
+
obj.auth uname, pword
|
53
|
+
obj
|
54
|
+
end
|
55
|
+
|
56
|
+
def search_active_directory(worker, search_string)
|
57
|
+
filters = LDAP_FILTERS & ::Net::LDAP::Filter.eq(LDAP_SEARCH_FIELD, "*#{search_string}*")
|
58
|
+
result = worker.search(:base => self.treebase,
|
59
|
+
:filter => filters,
|
60
|
+
:attributes => LDAP_ATTRS,
|
61
|
+
:return_result => true)
|
62
|
+
# search will return false if unable to bind
|
63
|
+
# e.g. service account credentials have expired
|
64
|
+
result || []
|
65
|
+
end
|
66
|
+
|
67
|
+
def create_result_collection(collection = [])
|
68
|
+
collection ||= []
|
69
|
+
collection.map { |entry| create_struct entry }
|
70
|
+
end
|
71
|
+
|
72
|
+
def create_struct(hash = {})
|
73
|
+
key_values = {}
|
74
|
+
hash.each{|k, v| key_values[k] = v[0]}
|
75
|
+
OpenStruct.new(key_values)
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module ElDap
|
4
|
+
describe ApiMethods do
|
5
|
+
before(:each) do
|
6
|
+
@base = mock(ElDap::Base)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should setup a new instance of the Base class" do
|
10
|
+
@base.should_receive(:username=).with('username')
|
11
|
+
@base.should_receive(:password=).with('password')
|
12
|
+
@base.should_receive(:server_ips=).with(['1.2.3.4'])
|
13
|
+
@base.should_receive(:treebase=).with('dc=ad,dc=example,dc=com')
|
14
|
+
ElDap::Base.should_receive(:new).and_return(@base)
|
15
|
+
ElDap.configure do |l|
|
16
|
+
l.username = 'username'
|
17
|
+
l.password = 'password'
|
18
|
+
l.server_ips = ['1.2.3.4']
|
19
|
+
l.treebase = 'dc=ad,dc=example,dc=com'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should perform the validate method on the worker" do
|
24
|
+
ElDap::ApiMethods.class_variable_set(:@@worker, @base)
|
25
|
+
@base.should_receive(:validate).with('username', 'password')
|
26
|
+
ElDap.validate('username', 'password')
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should perform the search method on the worker" do
|
30
|
+
ElDap::ApiMethods.class_variable_set(:@@worker, @base)
|
31
|
+
@base.should_receive(:search).with('search string')
|
32
|
+
ElDap.search('search string')
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module ElDap
|
4
|
+
describe Base do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@instance = Base.new
|
8
|
+
@ldap = mock(Net::LDAP)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "ElDap check for blank parameters" do
|
12
|
+
it "should not attempt validation if username or password are blank" do
|
13
|
+
@instance.validate('username', '').should be_false
|
14
|
+
@instance.validate('username', nil).should be_false
|
15
|
+
@instance.validate('', 'password').should be_false
|
16
|
+
@instance.validate(nil, 'password').should be_false
|
17
|
+
@instance.validate('', '').should be_false
|
18
|
+
@instance.validate(nil, nil).should be_false
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should not attempt to search if no search criteria are provided" do
|
22
|
+
@worker.should_not_receive(:search)
|
23
|
+
@instance.search('').should be_false
|
24
|
+
@instance.search(nil).should be_nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "protected methods" do
|
29
|
+
it "should create an internal worker for each ip address" do
|
30
|
+
@instance.stub!(:server_ips).and_return(['1.1.1.1', '2.2.2.2'])
|
31
|
+
@instance.should_receive(:create_worker).with('username', 'password', '1.1.1.1').and_return('worker1')
|
32
|
+
@instance.should_receive(:create_worker).with('username', 'password', '2.2.2.2').and_return('worker2')
|
33
|
+
@instance.send(:workers, 'username', 'password').should == ['worker1', 'worker2']
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should create a Net::LDAP instance with the correct parameters" do
|
37
|
+
Net::LDAP.should_receive(:new).and_return(@ldap)
|
38
|
+
@ldap.should_receive(:host=).with('1.1.1.1')
|
39
|
+
@ldap.should_receive(:auth).with(/username/, /password/)
|
40
|
+
@instance.send(:create_worker, 'username', 'password', '1.1.1.1').should == @ldap
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should transform a search result into a collection of structs" do
|
44
|
+
@instance.stub!(:create_struct).and_return('struct')
|
45
|
+
@instance.send(:create_result_collection, ['result']).should == ['struct']
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should create a struct from a search result hash" do
|
49
|
+
search_result = {:cn => ['cn'], :mail => ['mail']}
|
50
|
+
struct = OpenStruct.new(:cn => 'cn',:mail => 'mail')
|
51
|
+
@instance.send(:create_struct, search_result).should == struct
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "search_active_directory method" do
|
55
|
+
it "should search active directory using the correct filters and parameters" do
|
56
|
+
filter1 = Net::LDAP::Filter.eq("objectcategory", "person")
|
57
|
+
filter2 = Net::LDAP::Filter.eq("cn", "*search-string*")
|
58
|
+
@ldap.should_receive(:search).with(
|
59
|
+
:base => @instance.treebase,
|
60
|
+
:filter => filter1 & filter2,
|
61
|
+
:attributes => Base.const_get('LDAP_ATTRS'),
|
62
|
+
:return_result => true
|
63
|
+
).and_return(['result'])
|
64
|
+
@instance.send(:search_active_directory, @ldap, 'search-string').should == ['result']
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should return a valid result when search cannot bind to the domain" do
|
68
|
+
@ldap.should_receive(:search).and_return(false)
|
69
|
+
@instance.send(:search_active_directory, @ldap, 'search-string').should == []
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "validate method" do
|
74
|
+
it "should attempt validation when username and password are provided" do
|
75
|
+
@instance.should_receive(:workers).with(/username/, /password/).and_return([@ldap])
|
76
|
+
@ldap.should_receive(:bind).and_return(true)
|
77
|
+
@instance.validate('username', 'password').should be_true
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should stop the validation cycle when the first result if received" do
|
81
|
+
ldap2 = mock(Net::LDAP)
|
82
|
+
ldap2.should_not_receive(:bind)
|
83
|
+
@ldap.should_receive(:bind).and_return(true)
|
84
|
+
@instance.stub!(:workers).and_return([@ldap, ldap2])
|
85
|
+
@instance.validate('username', 'password').should be_true
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should return false when a timeout occurs" do
|
89
|
+
@instance.stub!(:workers).and_return([@ldap])
|
90
|
+
@ldap.should_receive(:bind).and_raise(Timeout::Error)
|
91
|
+
@instance.validate('username', 'password').should be_false
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe 'search method' do
|
96
|
+
it "should complete gracefully if invalid credentials are used for search (search returns false)" do
|
97
|
+
@instance.should_receive(:workers).and_return([@ldap])
|
98
|
+
@ldap.should_receive(:search).and_return(false)
|
99
|
+
@instance.search('string').should == []
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should sanitize the Net::LDAP search result into an array of generic structures" do
|
103
|
+
@instance.should_receive(:workers).and_return([])
|
104
|
+
@instance.should_receive(:create_result_collection).and_return([])
|
105
|
+
@instance.search('search-string').should == []
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module ElDap
|
4
|
+
describe Constants do
|
5
|
+
class TestThing
|
6
|
+
include ElDap::Constants
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should define LDAP_ATTRS" do
|
10
|
+
TestThing.const_get('LDAP_ATTRS').
|
11
|
+
should == ['cn', 'samaccountname', 'displayname', 'name', 'telephonenumber', 'userprincipalname', 'mail']
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should define LDAP_FILTERS" do
|
15
|
+
TestThing.const_get('LDAP_FILTERS').should == Net::LDAP::Filter.eq("objectcategory", "person")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should define LDAP_SEARCH_FIELD" do
|
19
|
+
TestThing.const_get('LDAP_SEARCH_FIELD').should == 'cn'
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rspec'
|
5
|
+
require 'el_dap'
|
6
|
+
|
7
|
+
# Requires supporting files with custom matchers and macros, etc,
|
8
|
+
# in ./support/ and its subdirectories.
|
9
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: el_dap
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ed James
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-04-19 00:00:00.000000000Z
|
13
|
+
dependencies: []
|
14
|
+
description: A simple search and authentication tool for Active Directory using LDAP.
|
15
|
+
email:
|
16
|
+
- ed.james.email@gmail.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitignore
|
22
|
+
- .rspec
|
23
|
+
- .rvmrc
|
24
|
+
- CHANGELOG
|
25
|
+
- Gemfile
|
26
|
+
- LICENSE
|
27
|
+
- README.rdoc
|
28
|
+
- Rakefile
|
29
|
+
- el_dap.gemspec
|
30
|
+
- lib/el_dap.rb
|
31
|
+
- lib/el_dap/.rvmrc
|
32
|
+
- lib/el_dap/api_methods.rb
|
33
|
+
- lib/el_dap/base.rb
|
34
|
+
- lib/el_dap/constants.rb
|
35
|
+
- lib/el_dap/version.rb
|
36
|
+
- spec/el_dap/api_methods_spec.rb
|
37
|
+
- spec/el_dap/base_spec.rb
|
38
|
+
- spec/el_dap/constants_spec.rb
|
39
|
+
- spec/spec_helper.rb
|
40
|
+
homepage: https://github.com/edjames/el_dap
|
41
|
+
licenses: []
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ! '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ! '>='
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
requirements: []
|
59
|
+
rubyforge_project: el_dap
|
60
|
+
rubygems_version: 1.7.2
|
61
|
+
signing_key:
|
62
|
+
specification_version: 3
|
63
|
+
summary: A simple search and authentication tool for Active Directory using LDAP.
|
64
|
+
test_files: []
|