warden-ldap 0.0.1.pre
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 +17 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/.watchr +90 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +10 -0
- data/lib/warden/ldap/configuration.rb +47 -0
- data/lib/warden/ldap/connection.rb +104 -0
- data/lib/warden/ldap/logger.rb +15 -0
- data/lib/warden/ldap/strategy.rb +33 -0
- data/lib/warden/ldap/version.rb +5 -0
- data/lib/warden/ldap.rb +31 -0
- data/spec/fixtures/warden_ldap.yml +30 -0
- data/spec/helpers/rack_helpers.rb +50 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/warden/ldap/connection_spec.rb +26 -0
- data/spec/warden/ldap/strategy_spec.rb +48 -0
- data/spec/warden/ldap_spec.rb +44 -0
- data/warden-ldap.gemspec +25 -0
- metadata +140 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.9.3-p392
|
data/.watchr
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
if __FILE__ == $0
|
2
|
+
puts "Run with: watchr #{__FILE__}. \n\nRequired gems: watchr rev"
|
3
|
+
exit 1
|
4
|
+
end
|
5
|
+
|
6
|
+
# --------------------------------------------------
|
7
|
+
# Convenience Methods
|
8
|
+
# --------------------------------------------------
|
9
|
+
def run(cmd)
|
10
|
+
sleep(2)
|
11
|
+
puts("%s %s [%s]" % ["|\n" * 5 , cmd , Time.now.to_s])
|
12
|
+
$last_test = cmd
|
13
|
+
system(cmd)
|
14
|
+
end
|
15
|
+
|
16
|
+
def run_all_specs
|
17
|
+
tags = "--tag #{ARGV[1]}" if ARGV[1]
|
18
|
+
run "bundle exec rake -s spec SPEC_OPTS='--order rand #{tags.to_s}'"
|
19
|
+
end
|
20
|
+
|
21
|
+
def run_last_test
|
22
|
+
run($last_test)
|
23
|
+
end
|
24
|
+
|
25
|
+
def run_single_spec *spec
|
26
|
+
tags = "--tag #{ARGV[1]}" if ARGV[1]
|
27
|
+
spec = spec.join(' ')
|
28
|
+
run "bundle exec rspec #{spec} -d --order rand #{tags}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def run_specs_with_shared_examples(shared_example_filename, spec_path = 'spec')
|
32
|
+
|
33
|
+
# Returns the names of the shared examples in filename
|
34
|
+
def shared_examples(filename)
|
35
|
+
lines = File.readlines(filename)
|
36
|
+
lines.grep(/shared_examples_for[\s'"]+(.+)['"]\s*[do|\{]/) do |matching_line|
|
37
|
+
$1
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns array with filenames of the specs using shared_example
|
42
|
+
def specs_with_shared_example(shared_example, path)
|
43
|
+
command = "grep -lrE 'it_should_behave_like .(#{shared_example}).' #{path}"
|
44
|
+
`#{command}`.split
|
45
|
+
end
|
46
|
+
|
47
|
+
shared_examples(shared_example_filename).each do |shared_example|
|
48
|
+
specs_to_run = specs_with_shared_example(shared_example, spec_path)
|
49
|
+
run_single_spec(specs_to_run) unless specs_to_run.empty?
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
def run_cucumber_scenario scenario_path
|
55
|
+
if scenario_path !~ /.*\.feature$/
|
56
|
+
scenario_path = $last_scenario
|
57
|
+
end
|
58
|
+
$last_scenario = scenario_path
|
59
|
+
run "bundle exec cucumber #{scenario_path} --tags @dev"
|
60
|
+
end
|
61
|
+
|
62
|
+
# --------------------------------------------------
|
63
|
+
# Watchr Rules
|
64
|
+
# --------------------------------------------------
|
65
|
+
watch( '^spec/spec_helper\.rb' ) { |m| run_last_test }
|
66
|
+
watch( '^spec/fixtures/sample_app.*\.rb' ) { run_last_test }
|
67
|
+
watch( '^spec/.*_spec\.rb' ) { |m| run_single_spec(m[0]) }
|
68
|
+
watch( '^spec/helpers\/.*\.rb' ) { |m| run_last_test }
|
69
|
+
watch( '^lib/(.*)\.rb' ) { |m| run_last_test }
|
70
|
+
|
71
|
+
|
72
|
+
# --------------------------------------------------
|
73
|
+
# Signal Handling
|
74
|
+
# --------------------------------------------------
|
75
|
+
# Ctrl-\
|
76
|
+
Signal.trap('QUIT') do
|
77
|
+
puts " --- Running all tests ---\n\n"
|
78
|
+
run_all_specs
|
79
|
+
end
|
80
|
+
|
81
|
+
# Ctrl-T
|
82
|
+
Signal.trap('TSTP') do
|
83
|
+
puts " --- Running last test --\n\n"
|
84
|
+
run_cucumber_scenario nil
|
85
|
+
end
|
86
|
+
|
87
|
+
# Ctrl-C
|
88
|
+
Signal.trap('INT') { abort("\n") }
|
89
|
+
|
90
|
+
puts "Watching.."
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Maher Hawash
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Warden::Ldap
|
2
|
+
|
3
|
+
**NOTE**: This product is still pre-release, and implementation is *not* in sync with documentation yet - hence the pre-release version. We'll follow [the Semantic Versioning Specification (Semver)](http://semver.org/), so you can assume anything at 0.x.x still has an unstable API. But we *are* actively developing this.
|
4
|
+
|
5
|
+
LDAP Strategy for Warden
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'warden-ldap'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install warden-ldap
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
TODO: Write usage instructions here
|
24
|
+
|
25
|
+
## Contributing
|
26
|
+
|
27
|
+
1. Fork it
|
28
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
30
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
31
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
module Warden
|
2
|
+
module Ldap
|
3
|
+
|
4
|
+
# Stores configruation information
|
5
|
+
#
|
6
|
+
# Configruation inforamtion is loaded from a configuration block defined within
|
7
|
+
# the client application.
|
8
|
+
#
|
9
|
+
# @example Standard settings
|
10
|
+
# Warden::Ldap.configure do |c|
|
11
|
+
# c.config_file = 'path/to/warden_config.yml'
|
12
|
+
# # ...
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
class Configuration
|
16
|
+
class << self
|
17
|
+
def define_setting(name)
|
18
|
+
defined_settings << name
|
19
|
+
attr_accessor name
|
20
|
+
end
|
21
|
+
|
22
|
+
def defined_settings
|
23
|
+
@defined_settings ||= []
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
define_setting :config_file
|
28
|
+
|
29
|
+
define_setting :env
|
30
|
+
|
31
|
+
define_setting :logger
|
32
|
+
|
33
|
+
def initialize
|
34
|
+
@logger ||= Warden::Ldap::Logger
|
35
|
+
end
|
36
|
+
|
37
|
+
def env
|
38
|
+
if defined? Rails
|
39
|
+
Rails.env
|
40
|
+
elsif @env.nil?
|
41
|
+
raise 'Must define Warden::Ldap.env'
|
42
|
+
end
|
43
|
+
@env
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Warden
|
4
|
+
module Ldap
|
5
|
+
class Connection
|
6
|
+
attr_reader :ldap, :login
|
7
|
+
def logger
|
8
|
+
Warden::Ldap.logger
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(options= {})
|
12
|
+
@login = options.delete(:username)
|
13
|
+
@password = options.delete(:password)
|
14
|
+
|
15
|
+
options[:encryption] = config["ssl"].to_sym if config["ssl"]
|
16
|
+
|
17
|
+
@ldap = Net::LDAP.new(options)
|
18
|
+
@ldap.host = config["host"]
|
19
|
+
@ldap.port = config["port"]
|
20
|
+
@ldap.base = config["base"]
|
21
|
+
|
22
|
+
@generic_credentials = config["generic_credentials"]
|
23
|
+
@attribute = [config["attributes"]].flatten
|
24
|
+
end
|
25
|
+
|
26
|
+
def ldap_param_value(param)
|
27
|
+
ldap_entry = nil
|
28
|
+
@ldap.search(:filter => ldap_username_filter) {|entry| ldap_entry = entry}
|
29
|
+
|
30
|
+
if ldap_entry
|
31
|
+
if ldap_entry[param]
|
32
|
+
logger.info("Requested param #{param} has value #{ldap_entry.send(param)}")
|
33
|
+
value = ldap_entry.send(param)
|
34
|
+
value = value.first if value.is_a?(Array) and value.count == 1
|
35
|
+
else
|
36
|
+
logger.error("Requested param #{param} does not exist")
|
37
|
+
value = nil
|
38
|
+
end
|
39
|
+
else
|
40
|
+
logger.error("Requested ldap entry does not exist")
|
41
|
+
value = nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def authenticate!
|
46
|
+
if @password
|
47
|
+
@ldap.auth(dn, @password)
|
48
|
+
@ldap.bind
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def authenticated?
|
53
|
+
authenticate!
|
54
|
+
end
|
55
|
+
|
56
|
+
def authorized?
|
57
|
+
logger.info("Authorizing user #{dn}")
|
58
|
+
authenticated?
|
59
|
+
end
|
60
|
+
|
61
|
+
def valid_login?
|
62
|
+
!search_for_login.nil?
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
# Searches the LDAP for the login
|
67
|
+
#
|
68
|
+
# @return [Object] the LDAP entry found; nil if not found
|
69
|
+
def search_for_login
|
70
|
+
logger.info("LDAP search for login: #{@attribute}=#{@login}")
|
71
|
+
ldap_entry = nil
|
72
|
+
@ldap.auth(*@generic_credentials)
|
73
|
+
@ldap.search(:filter => ldap_username_filter) {|entry| ldap_entry = entry}
|
74
|
+
ldap_entry
|
75
|
+
end
|
76
|
+
|
77
|
+
def ldap_username_filter
|
78
|
+
filters = @attribute.map { |att| Net::LDAP::Filter.eq(att, @login) }
|
79
|
+
filters.inject { |a,b| Net::LDAP::Filter.intersect(a, b) }
|
80
|
+
end
|
81
|
+
|
82
|
+
def find_ldap_user(ldap)
|
83
|
+
logger.info("Finding user: #{dn}")
|
84
|
+
ldap.search(:base => dn, :scope => Net::LDAP::SearchScope_BaseObject).try(:first)
|
85
|
+
end
|
86
|
+
|
87
|
+
def config
|
88
|
+
if File.exists?(Warden::Ldap.config_file.to_s)
|
89
|
+
@config = YAML.load_file(Warden::Ldap.config_file.to_s)[Warden::Ldap.env]
|
90
|
+
else
|
91
|
+
{}
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def dn
|
96
|
+
logger.info("LDAP dn lookup: #{@attribute}=#{@login}")
|
97
|
+
|
98
|
+
if ldap_entry = search_for_login
|
99
|
+
ldap_entry.dn
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'net/ldap'
|
3
|
+
|
4
|
+
module Warden
|
5
|
+
module Ldap
|
6
|
+
class Strategy < Warden::Strategies::Base
|
7
|
+
def valid?
|
8
|
+
credentials.all?{|c| c.to_s !~ /^\s*$/}
|
9
|
+
end
|
10
|
+
|
11
|
+
def authenticate!
|
12
|
+
username, password = credentials
|
13
|
+
connection = Warden::Ldap::Connection.new({ :username => username, :password => password })
|
14
|
+
response = connection.authenticate!
|
15
|
+
|
16
|
+
if response
|
17
|
+
user = OpenStruct.new({ :username => username,
|
18
|
+
:name => connection.ldap_param_value('cn') })
|
19
|
+
success!(user)
|
20
|
+
else
|
21
|
+
fail!("Could not log in")
|
22
|
+
end
|
23
|
+
rescue Net::LDAP::LdapError
|
24
|
+
fail!("Could not log in")
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def credentials
|
29
|
+
params.values_at('username', 'password')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/warden/ldap.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require "warden/ldap/version"
|
2
|
+
require "warden/ldap/logger"
|
3
|
+
require "warden/ldap/configuration"
|
4
|
+
require "warden/ldap/connection"
|
5
|
+
require "warden/ldap/strategy"
|
6
|
+
|
7
|
+
module Warden
|
8
|
+
module Ldap
|
9
|
+
class << self
|
10
|
+
extend Forwardable
|
11
|
+
Configuration.defined_settings.each do |setting|
|
12
|
+
def_delegators :configuration, setting, "#{setting.to_s}="
|
13
|
+
end
|
14
|
+
|
15
|
+
def configure
|
16
|
+
yield configuration if block_given?
|
17
|
+
end
|
18
|
+
|
19
|
+
def configuration
|
20
|
+
@configuration ||= Configuration.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def register
|
24
|
+
Warden::Strategies.add(:ldap, Warden::Ldap::Strategy)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Warden::Ldap.register
|
31
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
## Authorizations
|
2
|
+
# Uncomment out the merging for each enviornment that you'd like to include.
|
3
|
+
# You can also just copy and paste the tree (do not include the "authorizations") to each
|
4
|
+
# enviornment if you need something different per enviornment.
|
5
|
+
authorizations: &AUTHORIZATIONS
|
6
|
+
group_base: ou=groups,dc=test,dc=com
|
7
|
+
## Requires config.ldap_check_group_membership in devise.rb be true
|
8
|
+
# Can have multiple values, must match all to be authorized
|
9
|
+
required_groups:
|
10
|
+
# If only a group name is given, membership will be checked against "uniqueMember"
|
11
|
+
- cn=admins,ou=groups,dc=test,dc=com
|
12
|
+
- cn=users,ou=groups,dc=test,dc=com
|
13
|
+
# If an array is given, the first element will be the attribute to check against, the second the group name
|
14
|
+
- ["moreMembers", "cn=users,ou=groups,dc=test,dc=com"]
|
15
|
+
## Requires config.ldap_check_attributes in devise.rb to be true
|
16
|
+
## Can have multiple attributes and values, must match all to be authorized
|
17
|
+
require_attribute:
|
18
|
+
objectClass: inetOrgPerson
|
19
|
+
authorizationRole: postsAdmin
|
20
|
+
|
21
|
+
host: your.ldap.host.com
|
22
|
+
port: 389
|
23
|
+
attributes: [uid, cn, mail, samAccountName]
|
24
|
+
base: ou=users,ou=accounts,dc=ds,dc=renewfund,dc=com
|
25
|
+
generic_credentials: [bindaccount, ahead-example-seems-label]
|
26
|
+
# ssl: start_tls
|
27
|
+
# <<: *AUTHORIZATIONS
|
28
|
+
|
29
|
+
test:
|
30
|
+
<<: *AUTHORIZATIONS
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'warden'
|
2
|
+
require 'rack'
|
3
|
+
module Warden::Ldap::Helpers
|
4
|
+
module RackHelpers
|
5
|
+
def env_with_params(path = "/", params = {}, env = {})
|
6
|
+
method = params.delete(:method) || "GET"
|
7
|
+
env = { 'HTTP_VERSION' => '1.1', 'REQUEST_METHOD' => "#{method}" }.merge(env)
|
8
|
+
Rack::MockRequest.env_for("#{path}?#{Rack::Utils.build_query(params)}", env)
|
9
|
+
end
|
10
|
+
|
11
|
+
def setup_rack(app=nil, opts = {}, &block)
|
12
|
+
app ||= block if block_given?
|
13
|
+
|
14
|
+
opts[:failure_app] ||= failure_app
|
15
|
+
opts[:default_strategies] ||= [:ldap]
|
16
|
+
opts[:default_serializers] ||= [:session]
|
17
|
+
blk = opts[:configurator] || proc{}
|
18
|
+
|
19
|
+
Rack::Builder.new do
|
20
|
+
use opts[:session] || RackHelpers::Session
|
21
|
+
use Warden::Manager, opts, &blk
|
22
|
+
run app
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def valid_response
|
27
|
+
Rack::Response.new("OK").finish
|
28
|
+
end
|
29
|
+
|
30
|
+
def failure_app
|
31
|
+
lambda{|e|[401, {"Content-Type" => "text/plain"}, ["You Fail!"]] }
|
32
|
+
end
|
33
|
+
|
34
|
+
def success_app
|
35
|
+
lambda{|e|[200, {"Content-Type" => "text/plain"}, ["You Rock!"]] }
|
36
|
+
end
|
37
|
+
|
38
|
+
class Session
|
39
|
+
attr_accessor :app
|
40
|
+
def initialize(app,configs = {})
|
41
|
+
@app = app
|
42
|
+
end
|
43
|
+
|
44
|
+
def call(e)
|
45
|
+
e['rack.session'] ||= {}
|
46
|
+
@app.call(e)
|
47
|
+
end
|
48
|
+
end # session
|
49
|
+
end
|
50
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
|
8
|
+
Dir[File.join(File.dirname(__FILE__), "helpers", "**/*.rb")].each do |f|
|
9
|
+
require f
|
10
|
+
end
|
11
|
+
|
12
|
+
require File.join(File.dirname(__FILE__), '../lib/warden/ldap')
|
13
|
+
|
14
|
+
RSpec.configure do |config|
|
15
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
16
|
+
config.run_all_when_everything_filtered = true
|
17
|
+
config.filter_run :focus
|
18
|
+
config.include(Warden::Ldap::Helpers::RackHelpers)
|
19
|
+
|
20
|
+
# Run specs in random order to surface order dependencies. If you find an
|
21
|
+
# order dependency and want to debug it, you can fix the order by providing
|
22
|
+
# the seed, which is printed after each run.
|
23
|
+
# --seed 1234
|
24
|
+
config.order = 'random'
|
25
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
describe Warden::Ldap::Connection do
|
2
|
+
describe '#authentiate!' do
|
3
|
+
it 'does nothing if no password present' do
|
4
|
+
subject = described_class.new({'username' => 'bob'})
|
5
|
+
subject.authenticate!.should be_false
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'authenticates and binds to ldap adapter' do
|
9
|
+
subject = described_class.new({:username => 'bob', :password => 'secret'})
|
10
|
+
subject.stub(:dn => 'Sammy')
|
11
|
+
Net::LDAP.any_instance.should_receive(:auth).with('Sammy', 'secret')
|
12
|
+
Net::LDAP.any_instance.should_receive(:bind).and_return(true)
|
13
|
+
subject.authenticate!.should be_true
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'actually authenticates' do
|
17
|
+
Warden::Ldap.configure do |c|
|
18
|
+
c.config_file = "/Users/mhawash/src/hummingbird/config/ldap.yml"
|
19
|
+
c.env = 'production'
|
20
|
+
end
|
21
|
+
|
22
|
+
subject = described_class.new({:username => 'mhawash', :password => 'sarra1216'})
|
23
|
+
p subject.authenticate!
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
describe Warden::Ldap::Strategy do
|
2
|
+
subject {described_class.new(@env)}
|
3
|
+
|
4
|
+
describe '#valid?' do
|
5
|
+
|
6
|
+
it 'returns true if both username and password are passed in' do
|
7
|
+
@env = env_with_params("/", {'username' => 'test', 'password' => 'secret'})
|
8
|
+
subject.valid?.should be_true
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'returns false if password is missing' do
|
12
|
+
@env = env_with_params("/", {'username' => 'test'})
|
13
|
+
subject.valid?.should be_false
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'returns false if password is blank' do
|
17
|
+
@env = env_with_params("/", {'username' => 'test', 'password' => ''})
|
18
|
+
subject.valid?.should be_false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#authenticte!' do
|
23
|
+
before :each do
|
24
|
+
@env = env_with_params("/", {'username' => 'test', 'password' => 'secret'})
|
25
|
+
subject.stub(:valid? => true)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'succeeds if the ldap connection succeeds' do
|
29
|
+
Warden::Ldap::Connection.any_instance.stub(:authenticate! => true)
|
30
|
+
Warden::Ldap::Connection.any_instance.stub(:ldap_param_value).with('cn').and_return('Samuel')
|
31
|
+
subject.should_receive(:success!)
|
32
|
+
subject.authenticate!
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'fails if ldap connection fails' do
|
36
|
+
Warden::Ldap::Connection.any_instance.stub(:authenticate! => false)
|
37
|
+
subject.should_receive(:fail!)
|
38
|
+
subject.authenticate!
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'fails if Net::LDAP::LdapError was raised' do
|
42
|
+
Warden::Ldap::Connection.any_instance.stub(:authenticate!).and_raise(Net::LDAP::LdapError)
|
43
|
+
subject.should_receive(:fail!)
|
44
|
+
subject.authenticate!
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
describe Warden::Ldap do
|
2
|
+
before :each do
|
3
|
+
described_class.configure do |c|
|
4
|
+
c.config_file = File.join(File.dirname(__FILE__), '../fixtures/warden_ldap.yml')
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'returns 401 if not authenticated' do
|
9
|
+
env = env_with_params("/", {'username' => 'test'})
|
10
|
+
app = lambda do |env|
|
11
|
+
env['warden'].authenticate(:ldap)
|
12
|
+
throw(:warden)
|
13
|
+
end
|
14
|
+
result = setup_rack(app).call(env)
|
15
|
+
result.first.should == 401
|
16
|
+
result.last.should == ["You Fail!"]
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'returns 200 if authenticates properly' do
|
20
|
+
env = env_with_params("/", {'username' => 'bobby', 'password' => 'joel'})
|
21
|
+
app = lambda do |env|
|
22
|
+
env['warden'].authenticate(:ldap)
|
23
|
+
success_app.call(env)
|
24
|
+
end
|
25
|
+
Warden::Ldap::Connection.any_instance.stub(:authenticate! => true)
|
26
|
+
Warden::Ldap::Connection.any_instance.stub(:ldap_param_value).with('cn').and_return('Samuel')
|
27
|
+
result = setup_rack(app).call(env)
|
28
|
+
result.first.should == 200
|
29
|
+
result.last.should == ["You Rock!"]
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'returns authenticated user information' do
|
33
|
+
env = env_with_params("/", {'username' => 'bobby', 'password' => 'joel'})
|
34
|
+
app = lambda do |env|
|
35
|
+
env['warden'].authenticate(:ldap)
|
36
|
+
success_app.call(env)
|
37
|
+
end
|
38
|
+
Warden::Ldap::Connection.any_instance.stub(:authenticate! => true)
|
39
|
+
Warden::Ldap::Connection.any_instance.stub(:ldap_param_value).with('cn').and_return('Samuel')
|
40
|
+
result = setup_rack(app).call(env)
|
41
|
+
env['warden'].user.username.should == 'bobby'
|
42
|
+
env['warden'].user.name.should == 'Samuel'
|
43
|
+
end
|
44
|
+
end
|
data/warden-ldap.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'warden/ldap/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "warden-ldap"
|
8
|
+
spec.version = Warden::Ldap::VERSION
|
9
|
+
spec.authors = ["Maher Hawash"]
|
10
|
+
spec.email = ["gmhawash@gmail.com"]
|
11
|
+
spec.description = %q{Provides ldap strategy for warden}
|
12
|
+
spec.summary = %q{Provides ldap strategy for wrden}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_runtime_dependency "warden", '~> 1.2.1'
|
24
|
+
spec.add_runtime_dependency "net-ldap", '~> 0.3.1'
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: warden-ldap
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.pre
|
5
|
+
prerelease: 6
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Maher Hawash
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-13 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: warden
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.2.1
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.2.1
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: net-ldap
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.3.1
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 0.3.1
|
78
|
+
description: Provides ldap strategy for warden
|
79
|
+
email:
|
80
|
+
- gmhawash@gmail.com
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- .gitignore
|
86
|
+
- .rspec
|
87
|
+
- .ruby-version
|
88
|
+
- .watchr
|
89
|
+
- Gemfile
|
90
|
+
- LICENSE.txt
|
91
|
+
- README.md
|
92
|
+
- Rakefile
|
93
|
+
- lib/warden/ldap.rb
|
94
|
+
- lib/warden/ldap/configuration.rb
|
95
|
+
- lib/warden/ldap/connection.rb
|
96
|
+
- lib/warden/ldap/logger.rb
|
97
|
+
- lib/warden/ldap/strategy.rb
|
98
|
+
- lib/warden/ldap/version.rb
|
99
|
+
- spec/fixtures/warden_ldap.yml
|
100
|
+
- spec/helpers/rack_helpers.rb
|
101
|
+
- spec/spec_helper.rb
|
102
|
+
- spec/warden/ldap/connection_spec.rb
|
103
|
+
- spec/warden/ldap/strategy_spec.rb
|
104
|
+
- spec/warden/ldap_spec.rb
|
105
|
+
- warden-ldap.gemspec
|
106
|
+
homepage: ''
|
107
|
+
licenses:
|
108
|
+
- MIT
|
109
|
+
post_install_message:
|
110
|
+
rdoc_options: []
|
111
|
+
require_paths:
|
112
|
+
- lib
|
113
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ! '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
segments:
|
120
|
+
- 0
|
121
|
+
hash: -2051351063243103119
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
+
none: false
|
124
|
+
requirements:
|
125
|
+
- - ! '>'
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: 1.3.1
|
128
|
+
requirements: []
|
129
|
+
rubyforge_project:
|
130
|
+
rubygems_version: 1.8.23
|
131
|
+
signing_key:
|
132
|
+
specification_version: 3
|
133
|
+
summary: Provides ldap strategy for wrden
|
134
|
+
test_files:
|
135
|
+
- spec/fixtures/warden_ldap.yml
|
136
|
+
- spec/helpers/rack_helpers.rb
|
137
|
+
- spec/spec_helper.rb
|
138
|
+
- spec/warden/ldap/connection_spec.rb
|
139
|
+
- spec/warden/ldap/strategy_spec.rb
|
140
|
+
- spec/warden/ldap_spec.rb
|