Permalink
Browse files

first import

  • Loading branch information...
1 parent e6bed51 commit e4fd74b7508eef8b2a629d0529207d267aa2bf4b @mkristian committed Nov 19, 2008
View
@@ -0,0 +1,20 @@
+Copyright (c) 2008 Kristian Meier
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
@@ -0,0 +1,22 @@
+# Add your own tasks in files placed in lib/tasks ending in .rake,
+# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
+
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+require 'spec'
+require 'spec/rake/spectask'
+require 'pathname'
+
+ROOT = Pathname(__FILE__).dirname.expand_path
+
+
+desc 'Run specifications'
+Spec::Rake::SpecTask.new(:spec) do |t|
+ if File.exists?('spec/spec.opts')
+ t.spec_opts << '--options' << 'spec/spec.opts'
+ end
+ t.spec_files = Pathname.glob((ROOT + 'spec/**/*_spec.rb').to_s)
+end
+
View
@@ -0,0 +1,73 @@
+dn: dc=org
+objectClass: dcObject
+objectClass: organizationalUnit
+dc: org
+ou: Org
+
+dn: dc=dhamma,dc=org
+objectClass: dcObject
+objectClass: organizationalUnit
+dc: dhamma
+ou: Dhamma
+
+dn: dc=referral,dc=dhamma,dc=org
+objectClass: dcObject
+objectClass: organizationalUnit
+dc: referral
+ou: Referral
+
+dn: ou=people,dc=dhamma,dc=org
+objectClass: organizationalUnit
+ou: people
+
+dn: ou=groups,dc=dhamma,dc=org
+objectClass: organizationalUnit
+ou: groups
+
+dn: ou=groups,dc=referral,dc=dhamma,dc=org
+objectClass: organizationalUnit
+ou: groups
+
+dn: uid=kristian,ou=people,dc=dhamma,dc=org
+objectClass: inetOrgPerson
+objectClass: posixAccount
+uid: kristian
+sn: Meier
+givenName: Kristian
+cn: Kristian Meier
+uidNumber: 1000
+gidNumber: 10000
+userPassword: {SSHA}/o6oa2GOphls/lzOFCwVkw9ARWEEiw+x
+mail: m.kristian@web.de
+loginShell: /bin/false
+homeDirectory:
+
+dn: cn=dhammaworker,ou=groups,dc=dhamma,dc=org
+objectClass: posixGroup
+cn: dhammaworker
+gidNumber: 10000
+
+dn: cn=root,ou=groups,dc=referral,dc=dhamma,dc=org
+objectClass: posixGroup
+cn: root
+memberUid: kristian
+gidNumber: 10001
+
+dn: cn=user_admin,ou=groups,dc=referral,dc=dhamma,dc=org
+objectClass: posixGroup
+cn: user_admin
+gidNumber: 10002
+
+dn: uid=bill,ou=people,dc=dhamma,dc=org
+objectClass: inetOrgPerson
+objectClass: posixAccount
+uid: bill
+sn: bill
+givenName: bill
+cn: bill
+uidNumber: 1001
+gidNumber: 10000
+userPassword: {SSHA}/o6oa2GOphls/lzOFCwVkw9ARWEEiw+x
+mail: bill@web.de
+loginShell: /bin/false
+homeDirectory: /root
View
@@ -0,0 +1,11 @@
+ldapadd -x -w behappy -c -D "cn=admin,dc=dhamma,dc=org" < dhamma.org.ldif
+
+ldapsearch -x -w behappy -c -D "cn=admin,dc=dhamma,dc=org" -b 'dc=dhamma,dc=org'
+
+ldapsearch -x -w behappy -c -D "cn=authenticator,dc=dhamma,dc=org" -b 'dc=dhamma,dc=org'
+
+ldapsearch -x -w behappy -c -D "cn=admin,dc=dhamma,dc=org" -b 'ou=people,dc=dhamma,dc=org'
+
+ldapsearch -x -w behappy -c -D "cn=admin,dc=dhamma,dc=org" -b 'ou=groups,dc=applications,dc=dhamma,dc=org'
+
+ldapsearch -x -w behappy -c -D "cn=admin,dc=dhamma,dc=org" -b 'ou=people,dc=dhamma,dc=org' "uid=*" | grep ^uid: | sed -e "s/^.....//" -e 's/$/,ou=people,dc=dhamma,dc=org"/' -e 's/^/-x -w behappy -c -D "cn=admin,dc=dhamma,dc=org" "uid=/' | xargs -L 1 echo ldapdelete
View
@@ -0,0 +1,210 @@
+module Ldap
+
+ # the class provides two ways of getting a LdapFacade. either
+ # one which is put on the current Thread or a new one
+ class LdapConnection
+
+ def initialize(uri)
+ @ldaps = { }
+ auth = {
+ :method => :simple,
+ :username => uri[:bind_name],
+ :password => uri[:password]
+ }
+ @config = {
+ :host => uri[:host],
+ :port => uri[:port].to_i,
+ :auth => auth,
+ :base => uri[:base]
+ }
+ end
+
+ # puts a LdapFacade into the current thread and executes the
+ # given block.
+ def open
+ begin
+ Ldap::LdapFacade.open(@config) do |ldap|
+ @ldaps[Thread.current] = Ldap::LdapFacade.new(ldap)
+ yield
+ end
+ ensure
+ @ldaps[Thread.current] = nil
+ end
+ end
+
+ # @return LdapFacade either the one from the current Thread or a new one
+ def current
+ ldap = @ldaps[Thread.current]
+ if ldap
+ ldap
+ else
+ Ldap::LdapFacade.new(@config)
+ end
+ end
+ end
+end
+
+require "dm-core"
+module DataMapper
+ module Adapters
+ class LdapAdapter < SimpleAdapter
+
+ # @return LdapFacade ready to use
+ def ldap
+ @ldap_connection.current
+ end
+
+ def key_properties(resource)
+ resource.send(:key_properties).first
+ end
+
+ # helper to remove datamapper specific classes from the conditions
+ # @param conditions
+ # @retrun Array of tuples: [action, attribute name, new value]
+ def to_ldap_conditions(conditions)
+ ldap_conditions = []
+ conditions.each do |c|
+ ldap_conditions << [c[0], c[1].field, c[2]]
+ end
+ ldap_conditions
+ end
+
+ public
+
+ # @overwrite from AbstractAdapter
+ def initialize(name, uri_or_options)
+ super
+
+ @ldap_connection = ::Ldap::LdapConnection.new(@uri)
+ end
+
+ # @overwrite from SimpleAdapter
+ def create_resource(resource)
+ props = resource.class.ldap_properties(resource)
+ key = nil
+ resource.send(:properties).each do |prop|
+ value = prop.get!(resource)
+ props[prop.field.to_sym] = value.to_s unless value.nil?
+ key = prop if prop.serial?
+ end
+ key_value = ldap.create_object(resource.model.dn_prefix(resource),
+ resource.model.treebase,
+ key_properties(resource).field,
+ props)
+ if key_value
+ key.set!(resource, key_value.to_i)
+ resource
+ elsif resource.model.multivalue_field
+ multivalue_prop = resource.send(:properties).detect do |prop|
+ prop.field.to_sym == resource.model.multivalue_field
+ end
+ update_resource(resource,
+ { multivalue_prop =>
+ resource.send(resource.model.multivalue_field)})
+ else
+ nil
+ end
+ end
+
+ # @overwrite from SimpleAdapter
+ def update_resource(resource, attributes)
+ actions = attributes.collect do |property, value|
+ field = property.field.to_sym #TODO sym needed or string ???
+ if resource.model.multivalue_field == property.name
+ if value.nil?
+ [:delete, field, resource.original_values[property.name].to_s]
+ else
+ [:add, field, value.to_s]
+ end
+ elsif value.nil?
+ [:delete, field, []]
+ elsif resource.original_values[property.name].nil?
+ [:add, field, value.to_s]
+ else
+ [:replace, field, value.to_s]
+ end
+ end
+#puts "actions"
+#p actions
+#puts
+ ldap.update_object(resource.model.dn_prefix(resource),
+ resource.model.treebase,
+ actions)
+ end
+
+ # @overwrite from SimpleAdapter
+ def delete_resource(resource)
+ if resource.model.multivalue_field
+ # set the original value so update does the right thing
+ resource.send("#{resource.model.multivalue_field}=".to_sym, nil)
+ update_resource(resource,
+ { resource.send(:properties)[resource.model.multivalue_field] => nil })
+ else
+ ldap.delete_object(resource.model.dn_prefix(resource),
+ resource.model.treebase)
+ end
+ end
+
+ # @overwrite from SimpleAdapter
+ def read_resource(query)
+ result = ldap.read_objects(query.model.treebase,
+ query.model.key.collect { |k| k.field},
+ to_ldap_conditions(query.conditions))
+ if query.model.multivalue_field
+ resource = result.detect do |item|
+ # run over all values of the multivalue field
+ item[query.model.multivalue_field].any? do |value|
+ values = query.fields.collect do |f|
+ if query.model.multivalue_field == f.field.to_sym
+ value
+ else
+ item[f.field.to_sym].first
+ end
+ end
+ resource = query.model.load(values, query)
+ return resource if filter_resource(resource, query.conditions)
+ end
+ end
+ else
+ values = result.first
+ if values
+ query.fields.collect do |f|
+ values[f.field.to_sym].first
+ end
+ end
+ end
+ end
+
+ # @overwrite from SimpleAdapter
+ def read_resources(query)
+ result = ldap.read_objects(query.model.treebase,
+ query.model.key.collect { |k| k.field},
+ to_ldap_conditions(query.conditions))
+ if query.model.multivalue_field
+ props_result = []
+ result.each do |props|
+ # run over all values of the multivalue field
+ props[query.model.multivalue_field].each do |value|
+ values = query.fields.collect do |f|
+ if query.model.multivalue_field == f.field.to_sym
+ value
+ else
+ props[f.field.to_sym].first
+ end
+ end
+ resource = query.model.load(values, query)
+ props_result << resource if filter_resource(resource, query.conditions)
+ end
+ end
+ props_result
+ else # no multivalue field
+ result.collect do |props|
+ query.fields.collect do |f|
+ props[f.field.to_sym].first
+ end
+ end
+ end
+ end
+ end
+ end
+end
Oops, something went wrong.

0 comments on commit e4fd74b

Please sign in to comment.