ldap-filter 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 +4 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/README.md +34 -0
- data/Rakefile +1 -0
- data/ldap-filter.gemspec +21 -0
- data/lib/ldap-filter.rb +1 -0
- data/lib/ldap/filter.rb +5 -0
- data/lib/ldap/filter/and_filter.rb +10 -0
- data/lib/ldap/filter/base.rb +43 -0
- data/lib/ldap/filter/compound.rb +64 -0
- data/lib/ldap/filter/or_filter.rb +10 -0
- data/lib/ldap/filter/version.rb +5 -0
- data/spec/filter/and_filter_spec.rb +13 -0
- data/spec/filter/base_spec.rb +51 -0
- data/spec/filter/compound_spec.rb +106 -0
- data/spec/filter/or_filter_spec.rb +13 -0
- metadata +78 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# ldap-filter
|
2
|
+
|
3
|
+
While working on a Rails application that leaned heavily on my school's LDAP server, I started off writing inflexible methods like:
|
4
|
+
|
5
|
+
def uid_filter(uid)
|
6
|
+
"(uid=#{uid})"
|
7
|
+
end
|
8
|
+
|
9
|
+
def uid_or_email_filter(uid, email)
|
10
|
+
"(|(#{uid_filter(uid)})(#{email_filter(email)}))"
|
11
|
+
end
|
12
|
+
|
13
|
+
And decided it would be easier to do:
|
14
|
+
|
15
|
+
filter = LDAP::Filter::Base.new :uid, 'mrhalp' # (uid=mrhalp)
|
16
|
+
if search[:email] # mrhalp@email.org
|
17
|
+
email = LDAP::Filter::Base.new :mail, search[:email]
|
18
|
+
filter = filter | email
|
19
|
+
end
|
20
|
+
MyLDAPLibrary.search filter.to_s # (|(email=mrhalp@email.org)(uid=mrhalp))
|
21
|
+
|
22
|
+
You also don't have to worry about all those nested parentheses.
|
23
|
+
|
24
|
+
## Install
|
25
|
+
|
26
|
+
gem install ldap-filter
|
27
|
+
|
28
|
+
With Bundler:
|
29
|
+
|
30
|
+
gem 'ldap-filter'
|
31
|
+
|
32
|
+
## Usage
|
33
|
+
|
34
|
+
More to come soon.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/ldap-filter.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "ldap/filter/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "ldap-filter"
|
7
|
+
s.version = LDAP::Filter::VERSION
|
8
|
+
s.authors = ["Eduardo Gutierrez"]
|
9
|
+
s.email = ["edd_d@mit.edu"]
|
10
|
+
s.homepage = "https://github.com/ecbypi/ldap-filter"
|
11
|
+
s.summary = %q{DSL for building LDAP filters}
|
12
|
+
s.description = %q{DSL for dynamically building complex LDAP filters without concern for closing parentheses}
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
# specify any dependencies here; for example:
|
20
|
+
s.add_development_dependency "rspec"
|
21
|
+
end
|
data/lib/ldap-filter.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'ldap/filter'
|
data/lib/ldap/filter.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
module LDAP
|
2
|
+
module Filter
|
3
|
+
class Base
|
4
|
+
attr_accessor :key, :value
|
5
|
+
|
6
|
+
def initialize key, value, inverse=false
|
7
|
+
@key = key
|
8
|
+
@value = value.to_s
|
9
|
+
@not = inverse
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
filter = '('
|
14
|
+
filter << '!' if @not
|
15
|
+
filter << condition
|
16
|
+
filter << ')'
|
17
|
+
end
|
18
|
+
|
19
|
+
def !
|
20
|
+
@not = !@not
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def << value
|
25
|
+
OrFilter.new @key, @value, value
|
26
|
+
end
|
27
|
+
|
28
|
+
def | filter
|
29
|
+
OrFilter.new [self, filter]
|
30
|
+
end
|
31
|
+
|
32
|
+
def & filter
|
33
|
+
AndFilter.new [self, filter]
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def condition
|
39
|
+
[@key, '=', @value].join
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module LDAP
|
2
|
+
module Filter
|
3
|
+
class Compound
|
4
|
+
|
5
|
+
attr_reader :children, :operator
|
6
|
+
|
7
|
+
def initialize operator, key_or_mappings, *values
|
8
|
+
@children = case key_or_mappings
|
9
|
+
when Symbol then populate_from_values key_or_mappings, values
|
10
|
+
when Array then grep key_or_mappings
|
11
|
+
when Hash then populate_from_hash key_or_mappings
|
12
|
+
end
|
13
|
+
@operator = operator unless @operator
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
filter = '('
|
18
|
+
filter << @operator.to_s
|
19
|
+
filter << @children.map(&:to_s).join
|
20
|
+
filter << ')'
|
21
|
+
end
|
22
|
+
|
23
|
+
def << filter
|
24
|
+
raise ArgumentError, 'invalid representation of a filter' unless valid_filter?(filter)
|
25
|
+
@children << filter
|
26
|
+
end
|
27
|
+
|
28
|
+
def | filter
|
29
|
+
OrFilter.new [self, filter]
|
30
|
+
end
|
31
|
+
|
32
|
+
def & filter
|
33
|
+
AndFilter.new [self, filter]
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def valid_filter? filter
|
39
|
+
filter.kind_of?(Base) ||
|
40
|
+
filter.kind_of?(Compound)
|
41
|
+
end
|
42
|
+
|
43
|
+
def grep filters
|
44
|
+
filters.select { |filter| valid_filter? filter }
|
45
|
+
end
|
46
|
+
|
47
|
+
def populate_from_hash mappings
|
48
|
+
raise ArgumentError, 'compound filters require more than one key' if mappings.keys.size < 2
|
49
|
+
mappings.map do |key, values|
|
50
|
+
case values
|
51
|
+
when Array then Compound.new('|', key, *values)
|
52
|
+
else Base.new(key, values)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def populate_from_values key, values
|
58
|
+
raise ArgumentError, 'need more than one value for compound filter on the same key' if values.size < 2
|
59
|
+
@operator = '|' # Cannot &'d values on the same key
|
60
|
+
values.map { |value| Base.new(key, value) }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'ldap-filter'
|
2
|
+
|
3
|
+
module LDAP
|
4
|
+
module Filter
|
5
|
+
describe AndFilter do
|
6
|
+
|
7
|
+
it "subclases LDAP::Filter::Compound, defaulting the operator to :&" do
|
8
|
+
filter = AndFilter.new(givenName: 'John', sn: 'Smith')
|
9
|
+
filter.operator.to_s.should eq '&'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'ldap-filter'
|
2
|
+
|
3
|
+
module LDAP
|
4
|
+
module Filter
|
5
|
+
|
6
|
+
describe Base do
|
7
|
+
let(:filter) { Base.new(:givenName, 'John') }
|
8
|
+
|
9
|
+
describe "#to_s" do
|
10
|
+
it "puts together the pieces and returns usable filter" do
|
11
|
+
filter.to_s.should eq '(givenName=John)'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#!" do
|
16
|
+
it "inverts the filter" do
|
17
|
+
!filter
|
18
|
+
filter.to_s.should eq '(!givenName=John)'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "compound methods" do
|
23
|
+
let(:other) { Base.new(:sn, 'Smith') }
|
24
|
+
|
25
|
+
describe "#<<" do
|
26
|
+
it "creates an OrFilter object under the same key" do
|
27
|
+
compound = filter << 'Smith'
|
28
|
+
compound.should be_a OrFilter
|
29
|
+
compound.to_s.should eq '(|(givenName=John)(givenName=Smith))'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#|" do
|
34
|
+
it "builds an OrFilter of itself and the argument filter" do
|
35
|
+
compound = filter | other
|
36
|
+
compound.should be_a OrFilter
|
37
|
+
compound.to_s.should eq '(|(givenName=John)(sn=Smith))'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#&" do
|
42
|
+
it "builds an AndFilter of itself and the argument filter" do
|
43
|
+
compound = filter & other
|
44
|
+
compound.should be_a AndFilter
|
45
|
+
compound.to_s.should eq '(&(givenName=John)(sn=Smith))'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'ldap-filter'
|
2
|
+
|
3
|
+
module LDAP
|
4
|
+
module Filter
|
5
|
+
|
6
|
+
describe Compound do
|
7
|
+
let(:operator) { '&' } # AndOperator
|
8
|
+
|
9
|
+
describe "#to_s" do
|
10
|
+
it "builds all children filters and combines them with the operator" do
|
11
|
+
filter = Compound.new(operator, { givenName: 'John', sn: ['Smith', 'Smithers']})
|
12
|
+
filter.to_s.should eq '(&(givenName=John)(|(sn=Smith)(sn=Smithers)))'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "can be built from a hash" do
|
17
|
+
it "with key value pairs for base filters" do
|
18
|
+
attributes = {
|
19
|
+
givenName: 'John',
|
20
|
+
sn: 'Smith'
|
21
|
+
}
|
22
|
+
filter = Compound.new(operator, attributes)
|
23
|
+
filter.children.size.should eq 2
|
24
|
+
filter.children.first.should be_instance_of LDAP::Filter::Base
|
25
|
+
end
|
26
|
+
|
27
|
+
it "with key values pairs to create nested compound filters" do
|
28
|
+
attributes = {
|
29
|
+
givenName: ['John', 'Mary', 'Tyler'],
|
30
|
+
sn: 'Smith'
|
31
|
+
}
|
32
|
+
filter = Compound.new(operator, attributes)
|
33
|
+
filter.children.size.should eq 2
|
34
|
+
filter.children.first.should be_a LDAP::Filter::Compound
|
35
|
+
filter.children.first.children.size.should eq 3
|
36
|
+
end
|
37
|
+
|
38
|
+
it "so long as more than one key is supplied" do
|
39
|
+
expect { Compound.new('|', { givenName: 'John' }) }.to raise_error ArgumentError
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "can be built from an array of string values" do
|
44
|
+
it "can be built using a key and an array of values" do
|
45
|
+
filter = Compound.new(operator, :givenName, 'Mary', 'John', 'Tyler')
|
46
|
+
filter.operator.should eq '|'
|
47
|
+
filter.children.size.should eq 3
|
48
|
+
end
|
49
|
+
|
50
|
+
it "so long as there is more than one value provided" do
|
51
|
+
expect { Compound.new('|', :givenName, 'Mary') }.to raise_error ArgumentError
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "when built from other filter objects" do
|
56
|
+
let(:given_name) { Base.new(:givenName, 'John') }
|
57
|
+
let(:surname) { Base.new(:sn, 'Smith') }
|
58
|
+
|
59
|
+
it "is done using an array of filter objects" do
|
60
|
+
filter = Compound.new(operator, [given_name, surname])
|
61
|
+
filter.children.size.should eq 2
|
62
|
+
filter.children.first.should eq given_name
|
63
|
+
filter.children.last.should eq surname
|
64
|
+
end
|
65
|
+
|
66
|
+
it "takes out non-filter objects when built with an array of filters" do
|
67
|
+
filter = Compound.new(operator, [given_name, surname, 'invalid'])
|
68
|
+
filter.children.size.should eq 2
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "compound methods" do
|
73
|
+
let(:compound) { Compound.new '|', { givenName: 'John', sn: 'Smith' } }
|
74
|
+
let(:base) { Base.new :mail, 'smith@email.org' }
|
75
|
+
|
76
|
+
describe "#<<" do
|
77
|
+
it "adds a filter to it's children" do
|
78
|
+
expect { compound << base }.to change { compound.children.size }.by 1
|
79
|
+
end
|
80
|
+
|
81
|
+
it "only accepts filter objects" do
|
82
|
+
expect { compound << 'smith@email.org' }.to raise_error ArgumentError
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "#|" do
|
87
|
+
it "creates a new OrFilter" do
|
88
|
+
new_filter = compound | base
|
89
|
+
new_filter.children.should include(compound)
|
90
|
+
new_filter.children.should include(base)
|
91
|
+
new_filter.operator.should eq '|'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "#&" do
|
96
|
+
it "creates a new AndFilter" do
|
97
|
+
new_filter = compound & base
|
98
|
+
new_filter.children.should include(compound)
|
99
|
+
new_filter.children.should include(base)
|
100
|
+
new_filter.operator.should eq '&'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'ldap-filter'
|
2
|
+
|
3
|
+
module LDAP
|
4
|
+
module Filter
|
5
|
+
describe OrFilter do
|
6
|
+
|
7
|
+
it "subclases LDAP::Filter::Compound, defaulting the operator to :&" do
|
8
|
+
filter = OrFilter.new(givenName: 'John', sn: 'Smith')
|
9
|
+
filter.operator.to_s.should eq '|'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ldap-filter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Eduardo Gutierrez
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-28 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &70129611592680 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70129611592680
|
25
|
+
description: DSL for dynamically building complex LDAP filters without concern for
|
26
|
+
closing parentheses
|
27
|
+
email:
|
28
|
+
- edd_d@mit.edu
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- .gitignore
|
34
|
+
- .rspec
|
35
|
+
- Gemfile
|
36
|
+
- README.md
|
37
|
+
- Rakefile
|
38
|
+
- ldap-filter.gemspec
|
39
|
+
- lib/ldap-filter.rb
|
40
|
+
- lib/ldap/filter.rb
|
41
|
+
- lib/ldap/filter/and_filter.rb
|
42
|
+
- lib/ldap/filter/base.rb
|
43
|
+
- lib/ldap/filter/compound.rb
|
44
|
+
- lib/ldap/filter/or_filter.rb
|
45
|
+
- lib/ldap/filter/version.rb
|
46
|
+
- spec/filter/and_filter_spec.rb
|
47
|
+
- spec/filter/base_spec.rb
|
48
|
+
- spec/filter/compound_spec.rb
|
49
|
+
- spec/filter/or_filter_spec.rb
|
50
|
+
homepage: https://github.com/ecbypi/ldap-filter
|
51
|
+
licenses: []
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
requirements: []
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.8.10
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: DSL for building LDAP filters
|
74
|
+
test_files:
|
75
|
+
- spec/filter/and_filter_spec.rb
|
76
|
+
- spec/filter/base_spec.rb
|
77
|
+
- spec/filter/compound_spec.rb
|
78
|
+
- spec/filter/or_filter_spec.rb
|