dm-ldap-adapter 0.4.1 → 0.4.2
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/History.txt +10 -0
- data/Manifest.txt +0 -1
- data/README.txt +6 -8
- data/Rakefile +1 -1
- data/example/posix.rb +14 -14
- data/lib/adapters/ldap_adapter.rb +1 -8
- data/lib/ldap/digest.rb +2 -2
- data/lib/ldap/net_ldap_facade.rb +14 -7
- data/lib/ldap/ruby_ldap_facade.rb +9 -9
- data/spec/multi_value_attributes_spec.rb +2 -2
- data/spec/spec_helper.rb +7 -7
- metadata +4 -5
- data/example/identity_map.rb +0 -75
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
data/README.txt
CHANGED
@@ -46,8 +46,6 @@ or
|
|
46
46
|
|
47
47
|
see 'example/posix.rb' for user/group setup works with default installation of openldap on ubuntu (just change your password as needed in the code)
|
48
48
|
|
49
|
-
the 'example/identity_map.rb' shows the usage of identity maps, see also below.
|
50
|
-
|
51
49
|
== FEATURES/PROBLEMS:
|
52
50
|
|
53
51
|
* the net-ldap has some issues with not closing the connections when an exception/error got raised, with limit the search result to 126 entries which gets fixed by making consecutives searches and collect the result.
|
@@ -62,7 +60,7 @@ there are three parts which makes the DN of a model, the base from the ldap conn
|
|
62
60
|
|
63
61
|
class User
|
64
62
|
include DataMapper::Resource
|
65
|
-
property :id, Serial, :field => "
|
63
|
+
property :id, Serial, :field => "uidNumber"
|
66
64
|
dn_prefix { |user| "uid=#{user.login}"}
|
67
65
|
treebase "ou=people"
|
68
66
|
end
|
@@ -77,7 +75,7 @@ for example the ldap posixGroup has more attributes than the model class, it nee
|
|
77
75
|
|
78
76
|
class Group
|
79
77
|
include DataMapper::Resource
|
80
|
-
property :id, Serial, :field => "
|
78
|
+
property :id, Serial, :field => "gidNumber"
|
81
79
|
property :name, String, :field => "cn"
|
82
80
|
dn_prefix { |group| "cn=#{group.name}" }
|
83
81
|
treebase "ou=groups"
|
@@ -169,8 +167,8 @@ staying with posix example there the groups has a memberuid attribute BUT unlike
|
|
169
167
|
|
170
168
|
class GroupUser
|
171
169
|
include DataMapper::Resource
|
172
|
-
property :
|
173
|
-
property :
|
170
|
+
property :memberUid, String, :key => true
|
171
|
+
property :gidNumber, Integer, :key => true
|
174
172
|
dn_prefix { |group_user| "cn=#{group_user.group.name}" }
|
175
173
|
treebase "ou=groups"
|
176
174
|
ldap_properties do |group_user|
|
@@ -187,14 +185,14 @@ let's say your LDAP has multiple email values for a users then you can define yo
|
|
187
185
|
|
188
186
|
class User
|
189
187
|
include DataMapper::Resource
|
190
|
-
property :id, Serial, :field => "
|
188
|
+
property :id, Serial, :field => "uidNumber"
|
191
189
|
property :login, String, :field => "uid", :unique_index => true
|
192
190
|
property :mail, LdapArray
|
193
191
|
|
194
192
|
dn_prefix { |user| "uid=#{user.login}"}
|
195
193
|
treebase "ou=people"
|
196
194
|
ldap_properties do |user|
|
197
|
-
properties = { :objectclass => ["inetOrgPerson", "posixAccount", "shadowAccount"], :loginshell => "/bin/bash", :
|
195
|
+
properties = { :objectclass => ["inetOrgPerson", "posixAccount", "shadowAccount"], :loginshell => "/bin/bash", :gidNumber => "10000" }
|
198
196
|
properties
|
199
197
|
end
|
200
198
|
end
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ require 'spec/rake/spectask'
|
|
9
9
|
require 'pathname'
|
10
10
|
|
11
11
|
Hoe.spec('dm-ldap-adapter') do |p|
|
12
|
-
p.version = "0.4.
|
12
|
+
p.version = "0.4.2"
|
13
13
|
p.description = "ldap adapter for datamapper which uses either net-ldap or ruby-ldap"
|
14
14
|
p.developer('mkristian', 'm.kristian@web.de')
|
15
15
|
p.url = "http://dm-ldap-adapter.rubyforge.org"
|
data/example/posix.rb
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
require 'pathname'
|
2
2
|
require 'rubygems'
|
3
|
-
require 'slf4r/
|
4
|
-
|
3
|
+
require 'slf4r/logger'
|
4
|
+
require 'slf4r/ruby_logger'
|
5
5
|
require 'dm-core'
|
6
6
|
|
7
7
|
$LOAD_PATH << Pathname(__FILE__).dirname.parent.expand_path + 'lib'
|
8
8
|
|
9
|
-
Logging.init :debug, :info, :warn, :error
|
9
|
+
# Logging.init :debug, :info, :warn, :error
|
10
10
|
|
11
|
-
appender = Logging::Appender.stdout
|
12
|
-
appender.layout = Logging::Layouts::Pattern.new(:pattern => "%d [%-l] (%c) %m\n")
|
13
|
-
logger = Logging::Logger.new(:root)
|
14
|
-
logger.add_appenders(appender)
|
15
|
-
logger.level = :debug
|
16
|
-
logger.info "initialized logger . . ."
|
11
|
+
# appender = Logging::Appender.stdout
|
12
|
+
# appender.layout = Logging::Layouts::Pattern.new(:pattern => "%d [%-l] (%c) %m\n")
|
13
|
+
# logger = Logging::Logger.new(:root)
|
14
|
+
# logger.add_appenders(appender)
|
15
|
+
# logger.level = :debug
|
16
|
+
# logger.info "initialized logger . . ."
|
17
17
|
|
18
18
|
dummy = true #uncomment this to use dummy, i.e. a database instead of ldap
|
19
19
|
dummy = false # uncomment this to use ldap
|
@@ -49,9 +49,9 @@ end
|
|
49
49
|
class User
|
50
50
|
include DataMapper::Resource
|
51
51
|
|
52
|
-
property :id, Serial, :field => "
|
52
|
+
property :id, Serial, :field => "uidNumber"
|
53
53
|
property :login, String, :field => "uid"
|
54
|
-
property :hashed_password, String, :field => "
|
54
|
+
property :hashed_password, String, :field => "userPassword"
|
55
55
|
property :name, String, :field => "cn"
|
56
56
|
|
57
57
|
has n, :group_users, :child_key => [:memberuid]
|
@@ -99,7 +99,7 @@ end
|
|
99
99
|
class Group
|
100
100
|
include DataMapper::Resource
|
101
101
|
include Slf4r::Logger
|
102
|
-
property :id, Serial, :field => "
|
102
|
+
property :id, Serial, :field => "gidNumber"
|
103
103
|
property :name, String, :field => "cn"
|
104
104
|
|
105
105
|
dn_prefix { |group| "cn=#{group.name}" }
|
@@ -145,8 +145,8 @@ class GroupUser
|
|
145
145
|
ldap_properties do |group_user|
|
146
146
|
{:cn=>"#{group_user.group.name}", :objectclass => "posixGroup"}
|
147
147
|
end
|
148
|
-
property :memberuid, String, :key => true#, :field => "
|
149
|
-
property :gidnumber, Integer, :key => true#, :field => "
|
148
|
+
property :memberuid, String, :key => true#, :field => "memberUid"
|
149
|
+
property :gidnumber, Integer, :key => true#, :field => "gidNumber"
|
150
150
|
|
151
151
|
def group
|
152
152
|
Group.get!(gidnumber)
|
@@ -316,7 +316,7 @@ module DataMapper
|
|
316
316
|
end
|
317
317
|
|
318
318
|
#puts "read_many"
|
319
|
-
#p result
|
319
|
+
#p result
|
320
320
|
result = result.uniq if query.unique?
|
321
321
|
result = query.match_records(result) if query.model.multivalue_field
|
322
322
|
result = query.sort_records_case_insensitive(result)
|
@@ -332,11 +332,6 @@ module DataMapper
|
|
332
332
|
query.model.key.collect { |k| k.field },
|
333
333
|
to_ldap_conditions(query),
|
334
334
|
field_names, order_by)
|
335
|
-
#.sort! do |u1, u2|
|
336
|
-
# value1 = u1[order_by_sym].first.upcase rescue ""
|
337
|
-
# value2 = u2[order_by_sym].first.upcase rescue ""
|
338
|
-
# value1 <=> value2
|
339
|
-
# end
|
340
335
|
if query.model.multivalue_field
|
341
336
|
props_result = []
|
342
337
|
result.each do |props|
|
@@ -367,8 +362,6 @@ module DataMapper
|
|
367
362
|
end
|
368
363
|
end
|
369
364
|
end
|
370
|
-
|
371
|
-
# include ::DataMapper::Transaction::Adapter
|
372
365
|
end
|
373
366
|
end
|
374
367
|
end
|
data/lib/ldap/digest.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'sha1'
|
2
|
+
require 'base64'
|
1
3
|
module Ldap
|
2
4
|
class Digest
|
3
5
|
# method from openldap faq which produces the userPassword attribute
|
@@ -6,8 +8,6 @@ module Ldap
|
|
6
8
|
# @param salt String the salt for the password digester
|
7
9
|
# @return the encoded password/salt
|
8
10
|
def self.ssha(secret, salt)
|
9
|
-
require 'sha1'
|
10
|
-
require 'base64'
|
11
11
|
(salt.empty? ? "{SHA}": "{SSHA}") +
|
12
12
|
Base64.encode64(::Digest::SHA1.digest(secret + salt) + salt).gsub(/\n/, '')
|
13
13
|
end
|
data/lib/ldap/net_ldap_facade.rb
CHANGED
@@ -44,7 +44,7 @@ module Ldap
|
|
44
44
|
base = "#{treebase},#{@ldap.base}"
|
45
45
|
if @ldap.add( :dn => dn(dn_prefix, treebase),
|
46
46
|
:attributes => props) || @ldap.get_operation_result.code.to_s == "0"
|
47
|
-
props[key_field.
|
47
|
+
props[key_field.to_sym]
|
48
48
|
else
|
49
49
|
unless silence
|
50
50
|
msg = ldap_error("create",
|
@@ -70,13 +70,14 @@ module Ldap
|
|
70
70
|
@ldap.search( :base => "#{treebase},#{@ldap.base}",
|
71
71
|
:attributes => field_names,
|
72
72
|
:filter => filter ) do |res|
|
73
|
-
|
73
|
+
mapp = to_map(field_names, res)
|
74
|
+
|
74
75
|
#puts map[key_field.to_sym]
|
75
76
|
# TODO maybe make filter which removes this unless
|
76
77
|
# TODO move this into the ldap_Adapter to make it more general, so that
|
77
78
|
# all field with Integer gets converted, etc
|
78
|
-
result <<
|
79
|
-
|
79
|
+
result << mapp if key_fields.detect do |key_field|
|
80
|
+
mapp.keys.detect {|k| k.to_s.downcase == key_field.downcase }
|
80
81
|
end
|
81
82
|
end
|
82
83
|
result
|
@@ -140,13 +141,19 @@ module Ldap
|
|
140
141
|
# helper to extract the Hash from the ldap search result
|
141
142
|
# @param Entry from the ldap_search
|
142
143
|
# @return Hash with name/value pairs of the entry
|
143
|
-
def to_map(entry)
|
144
|
+
def to_map(field_names, entry)
|
145
|
+
fields = {:dn => :dn}
|
146
|
+
field_names.each { |f| fields[f.downcase.to_sym] = f.to_sym }
|
144
147
|
def entry.map
|
145
148
|
@myhash
|
146
149
|
end
|
147
|
-
|
150
|
+
result = {}
|
151
|
+
entry.map.each do |k,v|
|
152
|
+
result[fields[k]] = v
|
153
|
+
end
|
154
|
+
result
|
148
155
|
end
|
149
|
-
|
156
|
+
|
150
157
|
def ldap_error(method, dn)
|
151
158
|
"#{method} error: (#{@ldap.get_operation_result.code}) #{@ldap.get_operation_result.message}\n\tDN: #{dn}"
|
152
159
|
end
|
@@ -62,8 +62,7 @@ module Ldap
|
|
62
62
|
LDAP.mod(LDAP::LDAP_MOD_ADD, k.to_s, v.is_a?(::Array) ? v : [v.to_s] )
|
63
63
|
end
|
64
64
|
if @ldap2.add( dn(dn_prefix, treebase), mods)
|
65
|
-
|
66
|
-
props[key_field.downcase.to_sym]
|
65
|
+
props[key_field.to_sym]
|
67
66
|
else
|
68
67
|
unless silence
|
69
68
|
msg = ldap_error("create",
|
@@ -91,14 +90,13 @@ module Ldap
|
|
91
90
|
LDAP::LDAP_SCOPE_SUBTREE,
|
92
91
|
filter.to_s == "" ? "(objectclass=*)" : filter.to_s.gsub(/\(\(/, "(").gsub(/\)\)/, ")"),
|
93
92
|
field_names, false, 0, 0, order_field) do |res|
|
94
|
-
|
95
|
-
map = to_map(res)
|
96
|
-
#puts map[key_field.to_sym]
|
93
|
+
mapp = to_map(field_names, res)
|
97
94
|
# TODO maybe make filter which removes this unless
|
98
95
|
# TODO move this into the ldap_Adapter to make it more general, so that
|
99
96
|
# all field with Integer gets converted, etc
|
100
|
-
|
101
|
-
|
97
|
+
# NOTE: somehow the fields are downcase coming from query.model
|
98
|
+
result << mapp if key_fields.detect do |key_field|
|
99
|
+
mapp.keys.detect {|k| k.to_s.downcase == key_field.downcase }
|
102
100
|
end
|
103
101
|
end
|
104
102
|
end
|
@@ -174,10 +172,12 @@ module Ldap
|
|
174
172
|
# helper to extract the Hash from the ldap search result
|
175
173
|
# @param Entry from the ldap_search
|
176
174
|
# @return Hash with name/value pairs of the entry
|
177
|
-
def to_map(entry)
|
175
|
+
def to_map(field_names, entry)
|
176
|
+
fields = {:dn => :dn}
|
177
|
+
field_names.each { |f| fields[f.downcase.to_sym] = f.to_sym }
|
178
178
|
map = {}
|
179
179
|
LDAP::entry2hash(entry).each do |k,v|
|
180
|
-
map[k.downcase.to_sym] = v
|
180
|
+
map[fields[k.downcase.to_sym]] = v
|
181
181
|
end
|
182
182
|
map
|
183
183
|
end
|
@@ -4,9 +4,9 @@ require 'spec_helper'
|
|
4
4
|
class TestContact
|
5
5
|
include DataMapper::Resource
|
6
6
|
|
7
|
-
property :id, Serial, :field => "
|
7
|
+
property :id, Serial, :field => "uidNumber"
|
8
8
|
property :login, String, :field => "uid", :unique_index => true
|
9
|
-
property :hashed_password, String, :field => "
|
9
|
+
property :hashed_password, String, :field => "userPassword", :lazy => true
|
10
10
|
property :name, String, :field => "cn"
|
11
11
|
property :mail, ::Ldap::LdapArray
|
12
12
|
|
data/spec/spec_helper.rb
CHANGED
@@ -44,10 +44,10 @@ class User
|
|
44
44
|
include DataMapper::Resource
|
45
45
|
property :id, Serial, :field => "uidnumber"
|
46
46
|
property :login, String, :field => "uid", :unique_index => true
|
47
|
-
property :hashed_password, String, :field => "
|
47
|
+
property :hashed_password, String, :field => "userPassword", :writer => :private
|
48
48
|
property :name, String, :field => "cn"
|
49
49
|
property :mail, String
|
50
|
-
property :age, Integer, :field => "
|
50
|
+
property :age, Integer, :field => "postalCode"
|
51
51
|
property :alive, Boolean, :field => "gecos"
|
52
52
|
|
53
53
|
has n, :roles
|
@@ -96,7 +96,7 @@ end
|
|
96
96
|
|
97
97
|
class Role
|
98
98
|
include DataMapper::Resource
|
99
|
-
property :id, Serial, :field => "
|
99
|
+
property :id, Serial, :field => "gidNumber"
|
100
100
|
property :name, String, :field => "cn"
|
101
101
|
|
102
102
|
dn_prefix { |role| "cn=#{role.name}" }
|
@@ -110,7 +110,7 @@ end
|
|
110
110
|
|
111
111
|
class Group
|
112
112
|
include DataMapper::Resource
|
113
|
-
property :id, Serial, :field => "
|
113
|
+
property :id, Serial, :field => "gidNumber"
|
114
114
|
property :name, String, :field => "cn"
|
115
115
|
|
116
116
|
dn_prefix { |group| "cn=#{group.name}" }
|
@@ -127,14 +127,14 @@ class GroupUser
|
|
127
127
|
|
128
128
|
treebase "ou=groups"
|
129
129
|
|
130
|
-
multivalue_field :
|
130
|
+
multivalue_field :memberUid
|
131
131
|
|
132
132
|
ldap_properties do |group_user|
|
133
133
|
{:cn=>"#{group_user.group.name}", :objectclass => "posixGroup"}
|
134
134
|
end
|
135
135
|
|
136
|
-
property :user_id, Integer, :key => true, :field => "
|
137
|
-
property :group_id, Integer, :key => true, :field => "
|
136
|
+
property :user_id, Integer, :key => true, :field => "memberUid"
|
137
|
+
property :group_id, Integer, :key => true, :field => "gidNumber"
|
138
138
|
|
139
139
|
def group
|
140
140
|
Group.get!(group_id)
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-ldap-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 11
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 4
|
9
|
-
-
|
10
|
-
version: 0.4.
|
9
|
+
- 2
|
10
|
+
version: 0.4.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- mkristian
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-02-08 00:00:00 +05:30
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -101,7 +101,6 @@ files:
|
|
101
101
|
- README-example.markdown
|
102
102
|
- README.txt
|
103
103
|
- Rakefile
|
104
|
-
- example/identity_map.rb
|
105
104
|
- example/posix.rb
|
106
105
|
- ldap-commands.txt
|
107
106
|
- lib/adapters/ldap_adapter.rb
|
data/example/identity_map.rb
DELETED
@@ -1,75 +0,0 @@
|
|
1
|
-
require 'example/posix.rb'
|
2
|
-
|
3
|
-
USER_REPO = :default
|
4
|
-
|
5
|
-
class User
|
6
|
-
|
7
|
-
def self.ddefault_repository_name
|
8
|
-
USER_REPO
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.repository_name
|
12
|
-
USER_REPO
|
13
|
-
end
|
14
|
-
|
15
|
-
def authenticate(pwd)
|
16
|
-
require 'base64'
|
17
|
-
Base64.encode64(Digest::SHA1.digest(pwd)).gsub(/\n/, '') == attribute_get(:hashed_password)[5,1000]
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
class GroupUser
|
22
|
-
|
23
|
-
def self.ddefault_repository_name
|
24
|
-
USER_REPO
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.repository_name
|
28
|
-
USER_REPO
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
class Group
|
34
|
-
|
35
|
-
def self.ddefault_repository_name
|
36
|
-
USER_REPO
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.repository_name
|
40
|
-
USER_REPO
|
41
|
-
end
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
require 'adapters/memory_adapter'
|
46
|
-
DATA_REPO=:store
|
47
|
-
DataMapper.setup(DATA_REPO, {:adapter => 'memory'})
|
48
|
-
|
49
|
-
class Item
|
50
|
-
include DataMapper::Resource
|
51
|
-
property :id, Serial
|
52
|
-
end
|
53
|
-
|
54
|
-
|
55
|
-
DataMapper.repository(USER_REPO) do |repository|
|
56
|
-
repository.adapter.open_ldap_connection do
|
57
|
-
DataMapper.repository(DATA_REPO) do
|
58
|
-
root = User.first(:login => 'root') || User.create(:id => 0, :login => :root, :name => 'root', :password => 'none') if root.nil?
|
59
|
-
admin = Group.first(:name => 'admin') || Group.create(:name => 'admin')
|
60
|
-
root.groups << admin
|
61
|
-
|
62
|
-
p DataMapper.repository(USER_REPO).identity_map(User)
|
63
|
-
|
64
|
-
p DataMapper.repository(USER_REPO).identity_map(Group)
|
65
|
-
|
66
|
-
p root.authenticate('none')
|
67
|
-
|
68
|
-
p root.groups
|
69
|
-
|
70
|
-
(1..10).each {Item.create}
|
71
|
-
|
72
|
-
p DataMapper.repository(DATA_REPO).identity_map(Item)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|