dm-ldap-adapter 0.4.2 → 0.4.3
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 +7 -0
- data/README-bundler.md +34 -0
- data/{README-example.markdown → README-example.md} +0 -0
- data/{README.txt → README.md} +34 -22
- data/example/posix.rb +1 -5
- data/lib/adapters/ldap_adapter.rb +8 -5
- data/lib/dm-ldap-adapter.rb +1 -0
- data/lib/ldap/array.rb +34 -17
- data/lib/ldap/digest.rb +8 -1
- data/lib/ldap/ruby_ldap_facade.rb +23 -11
- data/lib/ldap/transactions.rb +2 -0
- data/lib/ldap/unboundid_ldap_facade.rb +188 -0
- data/lib/ldap_resource.rb +2 -1
- data/spec/assiociations_ldap_adapter_spec.rb +37 -9
- data/spec/contact.rb +58 -0
- data/spec/ldap_array_spec.rb +119 -0
- data/spec/multi_value_attributes_spec.rb +0 -1
- data/spec/spec_helper.rb +14 -6
- metadata +109 -46
- data/.project +0 -11
- data/.yardoc +0 -0
- data/Manifest.txt +0 -29
- data/Rakefile +0 -38
- data/spec/spec.opts +0 -2
- data/test.ldif +0 -46
    
        data/History.txt
    CHANGED
    
    | @@ -1,3 +1,10 @@ | |
| 1 | 
            +
            version 0.4.3
         | 
| 2 | 
            +
            =============
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            * test several environments: ruby-1.8.7/1.9.2, jruby-1.5.6/1.6.2 (1.8 and 1.9 where possible), DM-1.0.x/1.1.x, net-ldap and ruby-ldap gem as backend. run the specs against all possible combinations.
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            * improvements with LdapArray properties
         | 
| 7 | 
            +
             | 
| 1 8 | 
             
            version 0.4.2
         | 
| 2 9 | 
             
            =============
         | 
| 3 10 |  | 
    
        data/README-bundler.md
    ADDED
    
    | @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            # no Gemfile.lock on git #
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            there are two references for different DM versions
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * ~> 1.1.0
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            * ~> 1.0.0
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            with a simple symbolic link you can switch between these two profiles.
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            `$ ln -s Gemfile.lock.1.1.0 Gemfile.lock`
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            for that reason Gemfile.lock in not on github, so the script run-all.sh
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            # run specs #
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            `$ bundle exec spec spec`
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            or for some jruby versions (which needs jruby and ruby-maven gem)
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            `$ rmvn test`
         | 
| 22 | 
            +
            `$ rmvn test --Djruby.versions=1.5.6,1.6.2 -Djruby.18and19
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            # build gem
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            for the ruby platform
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            `$ gem build dm-ldap-adapter.gemspec`
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            or for java platform (needs jruby and ruby-maven gem)
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            `$ rmvn package`
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            gem will be inside target/dm-ldap-adapter directory.
         | 
| 
            File without changes
         | 
    
        data/{README.txt → README.md}
    RENAMED
    
    | @@ -1,20 +1,32 @@ | |
| 1 | 
            -
             | 
| 1 | 
            +
            # dm-ldap-adapter
         | 
| 2 2 |  | 
| 3 | 
            -
            *Homepage*: | 
| 3 | 
            +
            *Homepage*: [http://github.com/mkristian/dm-ldap-adapter](http://github.com/mkristian/dm-ldap-adapter)
         | 
| 4 4 |  | 
| 5 | 
            -
            *Git*: | 
| 5 | 
            +
            *Git*: [git://github.com/mkristian/dm-ldap-adapter.git](git://github.com/mkristian/dm-ldap-adapter.git)
         | 
| 6 6 |  | 
| 7 7 | 
             
            *Author*:    Kristian Meier
         | 
| 8 8 |  | 
| 9 9 | 
             
            *Copyright*: 2008-2009
         | 
| 10 10 |  | 
| 11 | 
            -
             | 
| 11 | 
            +
            ## Note on Patches/Pull Requests
         | 
| 12 12 |  | 
| 13 | 
            -
             | 
| 13 | 
            +
            * Fork the project.
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            * Make your feature addition or bug fix.
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            * Add tests for it. This is important so I don't break it in a future version unintentionally.
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            * Send me a pull request.
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            ## DESCRIPTION:
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            ### usecase
         | 
| 14 26 |  | 
| 15 27 | 
             
            the usecase for that implementation was using an ldap server for user authentication and authorization. the ldap server is configured to have posixAccounts and posixGroups. on the datamapper side these accounts/groups are modeled with many-to-many relationship. further more the model classes should be in such a way that they can be used with another repository as well, i.e. they carry some ldap related configuration but this is only relevant for the ldap-adapter.
         | 
| 16 28 |  | 
| 17 | 
            -
             | 
| 29 | 
            +
            ### low level ldap library
         | 
| 18 30 |  | 
| 19 31 | 
             
            the ldap library which does the actual ldap protocol stuff is [http://rubyforge.org/projects/net-ldap] which is the default. the other ldap library is [http://rubyforge.org/projects/ruby-ldap]. just add a facade parameter when setting up DataMapper
         | 
| 20 32 |  | 
| @@ -30,7 +42,7 @@ or | |
| 30 42 | 
             
                               :facade => :net_ldap,
         | 
| 31 43 | 
             
                 .... })
         | 
| 32 44 |  | 
| 33 | 
            -
             | 
| 45 | 
            +
            ### setup DataMapper
         | 
| 34 46 |  | 
| 35 47 | 
             
                DataMapper.setup(:ldap, {
         | 
| 36 48 | 
             
                               :adapter  => 'ldap',
         | 
| @@ -42,19 +54,19 @@ or | |
| 42 54 | 
             
                               :password => "behappy"
         | 
| 43 55 | 
             
                 })
         | 
| 44 56 |  | 
| 45 | 
            -
             | 
| 57 | 
            +
            ### examples
         | 
| 46 58 |  | 
| 47 59 | 
             
            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 60 |  | 
| 49 | 
            -
             | 
| 61 | 
            +
            ## FEATURES/PROBLEMS:
         | 
| 50 62 |  | 
| 51 63 | 
             
            * 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.
         | 
| 52 64 |  | 
| 53 65 | 
             
            * error from the ldap server are only logged and do not raise any exceptions (to be changed in next release) with one exception: when creating a new ldap entry a duplicated entry will raise DataMapper::PersistenceError
         | 
| 54 66 |  | 
| 55 | 
            -
             | 
| 67 | 
            +
            ## SYNOPSIS:
         | 
| 56 68 |  | 
| 57 | 
            -
             | 
| 69 | 
            +
            ### distinguished name (DN) of a model
         | 
| 58 70 |  | 
| 59 71 | 
             
            there are three parts which makes the DN of a model, the base from the ldap conncetion, the `treebase` of the model and `dn_prefix` of an instance.
         | 
| 60 72 |  | 
| @@ -69,7 +81,7 @@ with a base `dc=example,dc=com` we get a DN like the user 'admin' | |
| 69 81 |  | 
| 70 82 | 
             
                uid=admin,ou=people,dc=example,dc=com
         | 
| 71 83 |  | 
| 72 | 
            -
             | 
| 84 | 
            +
            ### ldap entities are bigger than the model
         | 
| 73 85 |  | 
| 74 86 | 
             
            for example the ldap posixGroup has more attributes than the model class, it needs the `objectclass` attribute set to `posixGroup`.
         | 
| 75 87 |  | 
| @@ -84,11 +96,11 @@ for example the ldap posixGroup has more attributes than the model class, it nee | |
| 84 96 |  | 
| 85 97 | 
             
            so with the help of the `ldap_properties` you can define a block which returns an hash with extra attributes. with such block you can make some calculations if needed, i.e. :homedirectory => "/home/#{login}" for the posixAccount.
         | 
| 86 98 |  | 
| 87 | 
            -
             | 
| 99 | 
            +
            ### authentication
         | 
| 88 100 |  | 
| 89 101 | 
             
            this uses the underlying bind of a ldap connection. so on any model where you have the `dn_prefix` and the `treebase` configured, you can call the method `authenticate(password)`. this will forward the request to the ldap server.
         | 
| 90 102 |  | 
| 91 | 
            -
             | 
| 103 | 
            +
            ### queries
         | 
| 92 104 |  | 
| 93 105 | 
             
            conditions in ldap depend on the attributes definition in the ldap schema. here is the list of what is working with that ldap adapter side and the usual AND between the conditions:
         | 
| 94 106 |  | 
| @@ -110,13 +122,13 @@ and | |
| 110 122 |  | 
| 111 123 | 
             
            gives the same result when *all* names are `NULL` !!!
         | 
| 112 124 |  | 
| 113 | 
            -
             | 
| 125 | 
            +
            ### OR conditions
         | 
| 114 126 |  | 
| 115 127 | 
             
            or-conditions can be done with :conditions option but only of the form "<property_name> <comparator> <value> [or <property_name> <comparator> <value>]*" where the comparator is one of "=", "like". it can be also combined with extra ANDs like this example
         | 
| 116 128 |  | 
| 117 129 | 
             
                Contact.all(:name.like => "A%", :conditions => ["phone like '+49%' or mobile like '+49%'"])
         | 
| 118 130 |  | 
| 119 | 
            -
             | 
| 131 | 
            +
            ### multiple repositories
         | 
| 120 132 |  | 
| 121 133 | 
             
            most probably you have to work with ldap as one repository and a database as a second repository. for me it worked best to define the `default_repository` for each model in the model itself:
         | 
| 122 134 |  | 
| @@ -155,13 +167,13 @@ and to let the ldap resources use the ldap respository it is best to bind it to | |
| 155 167 | 
             
                end
         | 
| 156 168 | 
             
              end
         | 
| 157 169 |  | 
| 158 | 
            -
             | 
| 170 | 
            +
            ### transactions
         | 
| 159 171 |  | 
| 160 172 | 
             
            the adapter offers a noop transaction, i.e. you can wrap everything into a transaction but the ldap part has no functionality.
         | 
| 161 173 |  | 
| 162 174 | 
             
            *note*: the ldap protocol does not know transactions
         | 
| 163 175 |  | 
| 164 | 
            -
             | 
| 176 | 
            +
            ### many-to-many associations
         | 
| 165 177 |  | 
| 166 178 | 
             
            staying with posix example there the groups has a memberuid attribute BUT unlike with relational databases it can have multiple values. to achieve a relationship with these values the underlying adapter needs to know that this specific attribute needs to be handled differently. for this `multivalue_field` comes into play. the ldap adapter clones the model and places the each memberuid in its own clone.
         | 
| 167 179 |  | 
| @@ -179,7 +191,7 @@ staying with posix example there the groups has a memberuid attribute BUT unlike | |
| 179 191 |  | 
| 180 192 | 
             
                end
         | 
| 181 193 |  | 
| 182 | 
            -
             | 
| 194 | 
            +
            ### ldap attributes with many values
         | 
| 183 195 |  | 
| 184 196 | 
             
            let's say your LDAP has multiple email values for a users then you can define your resource class like that using the type *LdapArray* for such multivalue fields
         | 
| 185 197 |  | 
| @@ -197,7 +209,7 @@ let's say your LDAP has multiple email values for a users then you can define yo | |
| 197 209 | 
             
                  end
         | 
| 198 210 | 
             
                end
         | 
| 199 211 |  | 
| 200 | 
            -
             | 
| 212 | 
            +
            ## REQUIREMENTS:
         | 
| 201 213 |  | 
| 202 214 | 
             
            * slf4r the logging facade
         | 
| 203 215 | 
             
            * net-ldap pure ruby ldap library
         | 
| @@ -205,11 +217,11 @@ let's say your LDAP has multiple email values for a users then you can define yo | |
| 205 217 | 
             
            * logging (optional) if logging via logging is desired
         | 
| 206 218 | 
             
            * log4r (optional) if logging via log4r is desired
         | 
| 207 219 |  | 
| 208 | 
            -
             | 
| 220 | 
            +
            ## INSTALL:
         | 
| 209 221 |  | 
| 210 222 | 
             
            * sudo gem install dm-ldap-adapter
         | 
| 211 223 |  | 
| 212 | 
            -
             | 
| 224 | 
            +
            ## LICENSE:
         | 
| 213 225 |  | 
| 214 226 | 
             
            (The MIT License)
         | 
| 215 227 |  | 
    
        data/example/posix.rb
    CHANGED
    
    | @@ -15,14 +15,10 @@ $LOAD_PATH << Pathname(__FILE__).dirname.parent.expand_path + 'lib' | |
| 15 15 | 
             
            # logger.level = :debug
         | 
| 16 16 | 
             
            # logger.info "initialized logger . . ."
         | 
| 17 17 |  | 
| 18 | 
            -
            dummy =  | 
| 19 | 
            -
            dummy = false # uncomment this to use ldap
         | 
| 18 | 
            +
            dummy = false # uncomment this to use ldap, dummy = false uses the database
         | 
| 20 19 | 
             
            unless dummy
         | 
| 21 20 | 
             
              require 'ldap_resource'
         | 
| 22 21 |  | 
| 23 | 
            -
              # comment this out if you want to use "net/ldap"
         | 
| 24 | 
            -
              require 'ldap/ruby_ldap_facade'
         | 
| 25 | 
            -
             | 
| 26 22 | 
             
              require 'adapters/ldap_adapter'
         | 
| 27 23 |  | 
| 28 24 | 
             
              DataMapper.setup(:default, {
         | 
| @@ -82,8 +82,10 @@ module DataMapper | |
| 82 82 | 
             
                end
         | 
| 83 83 |  | 
| 84 84 | 
             
                def sort_records_case_insensitive(records)
         | 
| 85 | 
            +
                  #Return unsorted records unless we have order defined
         | 
| 86 | 
            +
                  return records unless order
         | 
| 85 87 | 
             
                  sort_order = order.map { |direction| [ direction.target, direction.operator == :asc ] }
         | 
| 86 | 
            -
             | 
| 88 | 
            +
                  
         | 
| 87 89 | 
             
                  records.sort_by do |record|
         | 
| 88 90 | 
             
                    sort_order.map do |(property, ascending)|
         | 
| 89 91 | 
             
                      SortCaseInsensitive.new(record_value(record, property), ascending)
         | 
| @@ -171,9 +173,7 @@ module DataMapper | |
| 171 173 |  | 
| 172 174 | 
             
                  def create(resources)
         | 
| 173 175 | 
             
                    resources.select do |resource|
         | 
| 174 | 
            -
             | 
| 175 176 | 
             
                      create_resource(resource)
         | 
| 176 | 
            -
             | 
| 177 177 | 
             
                    end.size # just return the number of create resources
         | 
| 178 178 | 
             
                  end
         | 
| 179 179 |  | 
| @@ -306,6 +306,7 @@ module DataMapper | |
| 306 306 | 
             
                  # @see AbstractAdapter#read
         | 
| 307 307 | 
             
                  def read(query)
         | 
| 308 308 | 
             
                    result = []
         | 
| 309 | 
            +
                    #get data values out of the query
         | 
| 309 310 | 
             
                    resources = read_resources(query)
         | 
| 310 311 | 
             
                    resources.each do |resource|
         | 
| 311 312 | 
             
                      map = {}
         | 
| @@ -325,8 +326,10 @@ module DataMapper | |
| 325 326 | 
             
                  end
         | 
| 326 327 |  | 
| 327 328 | 
             
                  def read_resources(query)
         | 
| 328 | 
            -
                     | 
| 329 | 
            -
                     | 
| 329 | 
            +
                    query_order = query.order.first.target.field if query.order
         | 
| 330 | 
            +
                    #Use empty string as default for order in query
         | 
| 331 | 
            +
                    order_by = query_order || ''
         | 
| 332 | 
            +
             | 
| 330 333 | 
             
                    field_names = query.fields.collect {|f| f.field }
         | 
| 331 334 | 
             
                    result = ldap.read_objects(query.model.treebase,
         | 
| 332 335 | 
             
                                               query.model.key.collect { |k| k.field },
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            require 'adapter/ldap-adapter'
         | 
    
        data/lib/ldap/array.rb
    CHANGED
    
    | @@ -74,32 +74,49 @@ module Ldap | |
| 74 74 | 
             
                           end
         | 
| 75 75 | 
             
                end
         | 
| 76 76 |  | 
| 77 | 
            -
                 | 
| 77 | 
            +
                # keep the *args so it works for both DM-1.1.x and DM-1.0.x
         | 
| 78 | 
            +
                def initialize(_model = nil, _name = nil, options = {}, *args)
         | 
| 78 79 | 
             
                  super
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                  add_writer(model,name) unless options[:writer] == :private || options[:accessor] == :private
         | 
| 82 | 
            +
                  add_reader(model,name) unless options[:reader] == :private || options[:accessor] == :private        
         | 
| 83 | 
            +
                end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                private
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                def add_reader(model, name)
         | 
| 88 | 
            +
                  #Creates instance method for reader
         | 
| 79 89 | 
             
                  model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
         | 
| 80 | 
            -
                    def #{name | 
| 81 | 
            -
             | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 89 | 
            -
             | 
| 90 | 
            +
                    def #{name}
         | 
| 91 | 
            +
                     attr_data = attribute_get(:#{name})
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                     case attr_data
         | 
| 94 | 
            +
                     when Ldap::Array
         | 
| 95 | 
            +
                       attr_data.setup(self, properties[:#{name}])
         | 
| 96 | 
            +
                     else
         | 
| 97 | 
            +
                       new_ldap_array = Ldap::Array.new(self, properties[:#{name}])
         | 
| 98 | 
            +
                       new_ldap_array.replace(attr_data || [])
         | 
| 99 | 
            +
                     end
         | 
| 90 100 | 
             
                    end
         | 
| 101 | 
            +
                  RUBY
         | 
| 102 | 
            +
                end
         | 
| 91 103 |  | 
| 92 | 
            -
             | 
| 93 | 
            -
             | 
| 94 | 
            -
             | 
| 104 | 
            +
                def add_writer(model, name)
         | 
| 105 | 
            +
                  #Creates instance method for writer
         | 
| 106 | 
            +
                  model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
         | 
| 107 | 
            +
                    def #{name}=(input)
         | 
| 108 | 
            +
                      data = case input
         | 
| 95 109 | 
             
                      when Ldap::Array
         | 
| 96 | 
            -
                         | 
| 110 | 
            +
                        input.setup(self, properties[:#{name}])
         | 
| 97 111 | 
             
                      else
         | 
| 98 | 
            -
                         | 
| 99 | 
            -
                         | 
| 112 | 
            +
                        new_ldap_array = Ldap::Array.new(self, properties[:#{name}])
         | 
| 113 | 
            +
                        new_ldap_array.replace(input || [])
         | 
| 100 114 | 
             
                      end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                      attribute_set(:#{name}, data)
         | 
| 101 117 | 
             
                    end
         | 
| 102 118 | 
             
                  RUBY
         | 
| 103 119 | 
             
                end
         | 
| 120 | 
            +
             | 
| 104 121 | 
             
              end
         | 
| 105 122 | 
             
            end
         | 
    
        data/lib/ldap/digest.rb
    CHANGED
    
    
| @@ -83,12 +83,18 @@ module Ldap | |
| 83 83 | 
             
                # @param Array of conditions for the search
         | 
| 84 84 | 
             
                # @return Array of Hashes with a name/values pair for each attribute
         | 
| 85 85 | 
             
                def read_objects(treebase, key_fields, conditions, field_names, order_field = '')      
         | 
| 86 | 
            -
                   | 
| 86 | 
            +
                  
         | 
| 87 | 
            +
                  if !conditions.nil? and conditions.size > 0
         | 
| 88 | 
            +
                    filter = Conditions2Filter.convert(conditions).to_s
         | 
| 89 | 
            +
                  else
         | 
| 90 | 
            +
                    filter = "(objectclass=*)"
         | 
| 91 | 
            +
                  end
         | 
| 92 | 
            +
             | 
| 87 93 | 
             
                  result = []
         | 
| 88 94 | 
             
                  begin
         | 
| 89 95 | 
             
                  @ldap2.search("#{treebase},#{@ldap2.base}",
         | 
| 90 96 | 
             
                                LDAP::LDAP_SCOPE_SUBTREE,
         | 
| 91 | 
            -
                                filter | 
| 97 | 
            +
                                filter,
         | 
| 92 98 | 
             
                                field_names, false, 0, 0, order_field) do |res|
         | 
| 93 99 | 
             
                    mapp = to_map(field_names, res)
         | 
| 94 100 | 
             
                    # TODO maybe make filter which removes this unless
         | 
| @@ -148,15 +154,21 @@ module Ldap | |
| 148 154 | 
             
                # @param dn String for identifying the ldap object
         | 
| 149 155 | 
             
                # @param password String to be used for authenticate to the dn
         | 
| 150 156 | 
             
                def authenticate(dn, password)
         | 
| 151 | 
            -
                   | 
| 152 | 
            -
             | 
| 153 | 
            -
             | 
| 154 | 
            -
             | 
| 155 | 
            -
             | 
| 156 | 
            -
             | 
| 157 | 
            -
             | 
| 158 | 
            -
             | 
| 159 | 
            -
             | 
| 157 | 
            +
                  bound = false
         | 
| 158 | 
            +
                  ldap_con = LDAP::Conn.new(@ldap2.host, @ldap2.port)
         | 
| 159 | 
            +
                  ldap_con.set_option( LDAP::LDAP_OPT_PROTOCOL_VERSION, 3 )
         | 
| 160 | 
            +
                  begin
         | 
| 161 | 
            +
                    ldap_con.bind(dn, password, LDAP::LDAP_AUTH_SIMPLE) do
         | 
| 162 | 
            +
                      bound = true
         | 
| 163 | 
            +
                    end
         | 
| 164 | 
            +
                  rescue LDAP::ResultError => msg
         | 
| 165 | 
            +
                    if msg.to_s =~ /Invalid\ credentials/i
         | 
| 166 | 
            +
                      logger.info("Invalid Credentials: #{dn}")
         | 
| 167 | 
            +
                    else 
         | 
| 168 | 
            +
                      logger.warn "Authentication Error: #{msg.to_s}"
         | 
| 169 | 
            +
                    end
         | 
| 170 | 
            +
                  end
         | 
| 171 | 
            +
                  bound
         | 
| 160 172 | 
             
                end
         | 
| 161 173 |  | 
| 162 174 | 
             
                # helper to concat the dn from the various parts
         | 
| @@ -0,0 +1,188 @@ | |
| 1 | 
            +
            require 'ldap'
         | 
| 2 | 
            +
            require 'slf4r'
         | 
| 3 | 
            +
            require 'ldap/conditions_2_filter'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Ldap
         | 
| 6 | 
            +
              # class Connection < LDAP::Conn
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              #   attr_reader :base, :host, :port
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              #   def initialize(config)
         | 
| 11 | 
            +
              #     super(config[:host], config[:port])
         | 
| 12 | 
            +
              #     @base = config[:base]
         | 
| 13 | 
            +
              #     @port = config[:port]
         | 
| 14 | 
            +
              #     @host = config[:host]
         | 
| 15 | 
            +
              #     set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
         | 
| 16 | 
            +
              #   end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              # end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              class RubyLdapFacade
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                # @param config Hash for the ldap connection
         | 
| 23 | 
            +
                def self.open(config)
         | 
| 24 | 
            +
                  ldap3 = com.unboundid.ldap.sdk.LDAPConnection.new(config[:host], config[:port], config[:base] + "." + config[:auth][:username], config[:auth][:password])
         | 
| 25 | 
            +
                  
         | 
| 26 | 
            +
                  yield ldap
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                include ::Slf4r::Logger
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                # @param config Hash for the ldap connection
         | 
| 32 | 
            +
                def initialize(config)
         | 
| 33 | 
            +
                  if config.is_a? Hash
         | 
| 34 | 
            +
                    @ldap2 = Connection.new(config)
         | 
| 35 | 
            +
                    @ldap2.bind(config[:auth][:username], config[:auth][:password])
         | 
| 36 | 
            +
                  else
         | 
| 37 | 
            +
                    @ldap2 = config
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                def retrieve_next_id(treebase, key_field)
         | 
| 42 | 
            +
                  max = 0
         | 
| 43 | 
            +
                  @ldap2.search("#{treebase},#{@ldap2.base}",
         | 
| 44 | 
            +
                                LDAP::LDAP_SCOPE_SUBTREE,
         | 
| 45 | 
            +
                                "(objectclass=*)",
         | 
| 46 | 
            +
                                 [key_field]) do |entry|
         | 
| 47 | 
            +
                    n = (entry.vals(key_field) || [0]).first.to_i
         | 
| 48 | 
            +
                    max = n if max < n
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                  max + 1
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                # @param dn_prefix String the prefix of the dn
         | 
| 54 | 
            +
                # @param treebase the treebase of the dn or any search
         | 
| 55 | 
            +
                # @param key_field field which carries the integer unique id of the entity
         | 
| 56 | 
            +
                # @param props Hash of the ldap attributes of the new ldap object
         | 
| 57 | 
            +
                # @return nil in case of an error or the new id of the created object
         | 
| 58 | 
            +
                def create_object(dn_prefix, treebase, key_field, props, silence = false)
         | 
| 59 | 
            +
                  base = "#{treebase},#{@ldap2.base}"
         | 
| 60 | 
            +
                  mods = props.collect do |k,v|
         | 
| 61 | 
            +
                    LDAP.mod(LDAP::LDAP_MOD_ADD, k.to_s, v.is_a?(::Array) ? v : [v.to_s] )
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
                  if @ldap2.add( dn(dn_prefix, treebase), mods)
         | 
| 64 | 
            +
            #                    :attributes => props) and @ldap.get_operation_result.code.to_s == "0"
         | 
| 65 | 
            +
                    props[key_field.downcase.to_sym]
         | 
| 66 | 
            +
                  else
         | 
| 67 | 
            +
                    unless silence
         | 
| 68 | 
            +
                      msg = ldap_error("create",
         | 
| 69 | 
            +
                                         dn(dn_prefix, treebase)) + "\n\t#{props.inspect}"
         | 
| 70 | 
            +
                      # TODO maybe raise always an error
         | 
| 71 | 
            +
                      if @ldap2.get_operation_result.code.to_s == "68"
         | 
| 72 | 
            +
                        raise ::DataMapper::PersistenceError.new(msg)
         | 
| 73 | 
            +
                      else
         | 
| 74 | 
            +
                        logger.warn(msg)
         | 
| 75 | 
            +
                      end
         | 
| 76 | 
            +
                    end
         | 
| 77 | 
            +
                    nil
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                # @param treebase the treebase of the search
         | 
| 82 | 
            +
                # @param key_fields Array of fields which carries the integer unique id(s) of the entity
         | 
| 83 | 
            +
                # @param Array of conditions for the search
         | 
| 84 | 
            +
                # @return Array of Hashes with a name/values pair for each attribute
         | 
| 85 | 
            +
                def read_objects(treebase, key_fields, conditions, field_names, order_field = '')      
         | 
| 86 | 
            +
                  filter = Conditions2Filter.convert(conditions)
         | 
| 87 | 
            +
                  result = []
         | 
| 88 | 
            +
                  begin
         | 
| 89 | 
            +
                  @ldap2.search("#{treebase},#{@ldap2.base}",
         | 
| 90 | 
            +
                                LDAP::LDAP_SCOPE_SUBTREE,
         | 
| 91 | 
            +
                                filter.to_s == "" ? "(objectclass=*)" : filter.to_s.gsub(/\(\(/, "(").gsub(/\)\)/, ")"),
         | 
| 92 | 
            +
                                field_names, false, 0, 0, order_field) do |res|
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                    map = to_map(res)
         | 
| 95 | 
            +
                    #puts map[key_field.to_sym]
         | 
| 96 | 
            +
                    # TODO maybe make filter which removes this unless
         | 
| 97 | 
            +
                    # TODO move this into the ldap_Adapter to make it more general, so that
         | 
| 98 | 
            +
                    # all field with Integer gets converted, etc
         | 
| 99 | 
            +
                    result << map if key_fields.detect do |key_field|
         | 
| 100 | 
            +
                        map.member? key_field.to_sym
         | 
| 101 | 
            +
                      end
         | 
| 102 | 
            +
                    end
         | 
| 103 | 
            +
                  end
         | 
| 104 | 
            +
                  result
         | 
| 105 | 
            +
                end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
             | 
| 108 | 
            +
                # @param dn_prefix String the prefix of the dn
         | 
| 109 | 
            +
                # @param treebase the treebase of the dn or any search
         | 
| 110 | 
            +
                # @param actions the add/replace/delete actions on the attributes
         | 
| 111 | 
            +
                # @return nil in case of an error or true
         | 
| 112 | 
            +
                def update_object(dn_prefix, treebase, actions)
         | 
| 113 | 
            +
                  mods = actions.collect do |act|
         | 
| 114 | 
            +
                    mod_op = case act[0]
         | 
| 115 | 
            +
                          when :add
         | 
| 116 | 
            +
                            LDAP::LDAP_MOD_ADD
         | 
| 117 | 
            +
                          when :replace
         | 
| 118 | 
            +
                            LDAP::LDAP_MOD_REPLACE
         | 
| 119 | 
            +
                          when :delete
         | 
| 120 | 
            +
                            LDAP::LDAP_MOD_DELETE
         | 
| 121 | 
            +
                          end
         | 
| 122 | 
            +
                    LDAP.mod(mod_op, act[1].to_s, act[2] == [] ? [] : [act[2].to_s])
         | 
| 123 | 
            +
                  end
         | 
| 124 | 
            +
                  if @ldap2.modify( dn(dn_prefix, treebase),
         | 
| 125 | 
            +
                                   mods )
         | 
| 126 | 
            +
                    true
         | 
| 127 | 
            +
                  else
         | 
| 128 | 
            +
                    logger.warn(ldap_error("update",
         | 
| 129 | 
            +
                                           dn(dn_prefix, treebase) + "\n\t#{actions.inspect}"))
         | 
| 130 | 
            +
                    nil
         | 
| 131 | 
            +
                  end
         | 
| 132 | 
            +
                end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                # @param dn_prefix String the prefix of the dn
         | 
| 135 | 
            +
                # @param treebase the treebase of the dn or any search
         | 
| 136 | 
            +
                # @return nil in case of an error or true
         | 
| 137 | 
            +
                def delete_object(dn_prefix, treebase)
         | 
| 138 | 
            +
                  if @ldap2.delete( dn(dn_prefix, treebase) )
         | 
| 139 | 
            +
                    true
         | 
| 140 | 
            +
                  else
         | 
| 141 | 
            +
                    logger.warn(ldap_error("delete",
         | 
| 142 | 
            +
                                           dn(dn_prefix, treebase)))
         | 
| 143 | 
            +
             | 
| 144 | 
            +
                    nil
         | 
| 145 | 
            +
                  end
         | 
| 146 | 
            +
                end
         | 
| 147 | 
            +
             | 
| 148 | 
            +
             | 
| 149 | 
            +
                # @param dn String for identifying the ldap object
         | 
| 150 | 
            +
                # @param password String to be used for authenticate to the dn
         | 
| 151 | 
            +
                def authenticate(dn, password)
         | 
| 152 | 
            +
                  Net::LDAP.new( { :host => @ldap2.host,
         | 
| 153 | 
            +
                                   :port => @ldap2.port,
         | 
| 154 | 
            +
                                   :auth => {
         | 
| 155 | 
            +
                                     :method => :simple,
         | 
| 156 | 
            +
                                     :username => dn,
         | 
| 157 | 
            +
                                     :password => password
         | 
| 158 | 
            +
                                   },
         | 
| 159 | 
            +
                                   :base => @ldap2.base
         | 
| 160 | 
            +
                                 } ).bind
         | 
| 161 | 
            +
                end
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                # helper to concat the dn from the various parts
         | 
| 164 | 
            +
                # @param dn_prefix String the prefix of the dn
         | 
| 165 | 
            +
                # @param treebase the treebase of the dn or any search
         | 
| 166 | 
            +
                # @return the complete dn String
         | 
| 167 | 
            +
                def dn(dn_prefix, treebase)
         | 
| 168 | 
            +
                  "#{dn_prefix},#{treebase},#{@ldap2.base}"
         | 
| 169 | 
            +
                end
         | 
| 170 | 
            +
             | 
| 171 | 
            +
                private
         | 
| 172 | 
            +
             | 
| 173 | 
            +
                # helper to extract the Hash from the ldap search result
         | 
| 174 | 
            +
                # @param Entry from the ldap_search
         | 
| 175 | 
            +
                # @return Hash with name/value pairs of the entry
         | 
| 176 | 
            +
                def to_map(entry)
         | 
| 177 | 
            +
                  map = {}
         | 
| 178 | 
            +
                  LDAP::entry2hash(entry).each do |k,v|
         | 
| 179 | 
            +
                    map[k.downcase.to_sym] = v
         | 
| 180 | 
            +
                  end
         | 
| 181 | 
            +
                  map
         | 
| 182 | 
            +
                end
         | 
| 183 | 
            +
             | 
| 184 | 
            +
                def ldap_error(method, dn)
         | 
| 185 | 
            +
                  "#{method} error: (#{@ldap2.get_operation_result.code}) #{@ldap2.get_operation_result.message}\n\tDN: #{dn}"
         | 
| 186 | 
            +
                end
         | 
| 187 | 
            +
              end
         | 
| 188 | 
            +
            end
         | 
    
        data/lib/ldap_resource.rb
    CHANGED
    
    | @@ -12,7 +12,8 @@ module DataMapper | |
| 12 12 | 
             
                    discriminator   = properties(repository_name).discriminator
         | 
| 13 13 | 
             
                    no_reload       = !query.reload?
         | 
| 14 14 |  | 
| 15 | 
            -
                    field_map =  | 
| 15 | 
            +
                    field_map = {}
         | 
| 16 | 
            +
                    fields.each { |property| field_map[property] = property.field }
         | 
| 16 17 |  | 
| 17 18 | 
             
                    records.map do |record|
         | 
| 18 19 | 
             
                      identity_map = nil
         | 
| @@ -4,18 +4,42 @@ require 'spec_helper' | |
| 4 4 | 
             
            describe DataMapper::Adapters::LdapAdapter do
         | 
| 5 5 |  | 
| 6 6 | 
             
              before do
         | 
| 7 | 
            -
             | 
| 8 7 | 
             
                DataMapper.repository(:ldap) do
         | 
| 9 8 | 
             
                  User.all(:login.like => "b%").destroy!
         | 
| 10 9 | 
             
                  Group.all(:name.like => "test_%").destroy!
         | 
| 11 | 
            -
                   | 
| 12 | 
            -
                   | 
| 13 | 
            -
                   | 
| 10 | 
            +
                  
         | 
| 11 | 
            +
                  #First we create some items.
         | 
| 12 | 
            +
                  user1 = User.create(:login => "black", :name => 'Black', :age => 0)
         | 
| 13 | 
            +
                  user2 = User.create(:login => "brown", :name => 'Brown', :age => 25)
         | 
| 14 | 
            +
                  user3 = User.create(:login => "blue", :name => 'Blue',  :age => nil)
         | 
| 14 15 |  | 
| 15 | 
            -
                   | 
| 16 | 
            -
                   | 
| 16 | 
            +
                  group1 = Group.create(:name => "test_root_group")
         | 
| 17 | 
            +
                  group2 = Group.create(:name => "test_admin_group")
         | 
| 18 | 
            +
                  
         | 
| 19 | 
            +
                  #Then we retrive the items we created earlier and use them for tests.
         | 
| 20 | 
            +
                  @user1 = User.get!(user1.id)
         | 
| 21 | 
            +
                  @user2 = User.get!(user2.id)
         | 
| 22 | 
            +
                  @user3 = User.get!(user3.id)
         | 
| 23 | 
            +
                  
         | 
| 24 | 
            +
                  @group1 = Group.get!(group1.id)
         | 
| 25 | 
            +
                  @group2 = Group.get!(group2.id)      
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
              
         | 
| 29 | 
            +
              after(:all) do
         | 
| 30 | 
            +
                DataMapper.repository(:ldap) do
         | 
| 31 | 
            +
                  User.all(:login.like => "b%").destroy!
         | 
| 32 | 
            +
                  Group.all(:name.like => "test_%").destroy!
         | 
| 17 33 | 
             
                end
         | 
| 18 34 | 
             
              end
         | 
| 35 | 
            +
              
         | 
| 36 | 
            +
              it 'should have valid testing data' do
         | 
| 37 | 
            +
                @user1.should be_a_kind_of(User)
         | 
| 38 | 
            +
                @user2.should be_a_kind_of(User)
         | 
| 39 | 
            +
                @user3.should be_a_kind_of(User)
         | 
| 40 | 
            +
                @group1.should be_a_kind_of(Group)
         | 
| 41 | 
            +
                @group2.should be_a_kind_of(Group)
         | 
| 42 | 
            +
              end
         | 
| 19 43 |  | 
| 20 44 | 
             
              it 'should successfully save an object' do
         | 
| 21 45 | 
             
                DataMapper.repository(:ldap) do
         | 
| @@ -129,12 +153,16 @@ describe DataMapper::Adapters::LdapAdapter do | |
| 129 153 |  | 
| 130 154 | 
             
              it 'should be able to delete a user from a group' do
         | 
| 131 155 | 
             
                DataMapper.repository(:ldap) do
         | 
| 132 | 
            -
                   | 
| 133 | 
            -
             | 
| 156 | 
            +
                  size_before = GroupUser.all.size
         | 
| 157 | 
            +
             | 
| 134 158 | 
             
                  @user1.groups << @group1
         | 
| 159 | 
            +
                  GroupUser.all.size.should == size_before+1
         | 
| 160 | 
            +
              
         | 
| 135 161 | 
             
                  @user1.groups << @group2
         | 
| 162 | 
            +
                  GroupUser.all.size.should == size_before+2
         | 
| 163 | 
            +
             | 
| 136 164 | 
             
                  @user2.groups << @group1
         | 
| 137 | 
            -
                  GroupUser.all.size.should ==  | 
| 165 | 
            +
                  GroupUser.all.size.should == size_before+3
         | 
| 138 166 | 
             
                end
         | 
| 139 167 | 
             
                DataMapper.repository(:ldap) do
         | 
| 140 168 | 
             
                  @user1 = User.get!(@user1.id)
         | 
    
        data/spec/contact.rb
    ADDED
    
    | @@ -0,0 +1,58 @@ | |
| 1 | 
            +
            class Contact
         | 
| 2 | 
            +
            	include DataMapper::Resource
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            	def self.auto_upgrade!(args = nil)
         | 
| 5 | 
            +
            		DataMapper.logger.warn("Skipping #{self.name}.auto_upgrade!")
         | 
| 6 | 
            +
            	end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            	def self.default_repository_name
         | 
| 9 | 
            +
            		:ldap
         | 
| 10 | 
            +
            	end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            	def self.repository_name
         | 
| 13 | 
            +
            		:ldap
         | 
| 14 | 
            +
            	end
         | 
| 15 | 
            +
            	
         | 
| 16 | 
            +
            	property :id,						Serial, :field => 'uid'
         | 
| 17 | 
            +
            	property :cn,						String, :required => true
         | 
| 18 | 
            +
            	property :salutation,					String, :lazy => [:view]
         | 
| 19 | 
            +
            	property :title,					String, :lazy => [:view]
         | 
| 20 | 
            +
            	property :givenname,					String
         | 
| 21 | 
            +
            	property :sn,						String, :required => true
         | 
| 22 | 
            +
            	property :o,						String
         | 
| 23 | 
            +
            	property :postaladdress,				String, :lazy => [:view]
         | 
| 24 | 
            +
            	property :postalcode,					String, :lazy => [:view]
         | 
| 25 | 
            +
            	property :l,						String
         | 
| 26 | 
            +
            	property :st,						String, :lazy => [:view]
         | 
| 27 | 
            +
            	property :c,						String, :lazy => [:view]
         | 
| 28 | 
            +
            	property :telephonenumber,				String
         | 
| 29 | 
            +
            	property :facsimiletelephonenumber,			String, :lazy => [:view]
         | 
| 30 | 
            +
            	property :pager,					String, :lazy => [:view]
         | 
| 31 | 
            +
            	property :jpegphoto,					LdapArray, :lazy => true
         | 
| 32 | 
            +
            	property :mobile,					String, :lazy => [:view]
         | 
| 33 | 
            +
            	property :anniversary,					String, :lazy => [:view]
         | 
| 34 | 
            +
            	property :mail,						LdapArray
         | 
| 35 | 
            +
            	property :labeleduri,					LdapArray, :lazy => [:view]
         | 
| 36 | 
            +
            	property :marker,					LdapArray, :lazy => [:view]
         | 
| 37 | 
            +
            	property :description,					LdapArray, :lazy => [:view]
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            	dn_prefix do |u|
         | 
| 40 | 
            +
            		"uid=#{u.id}"
         | 
| 41 | 
            +
            	end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            	ldap_properties do |u|
         | 
| 44 | 
            +
                      properties = { :objectclass => ['inetOrgPerson']}#, "posixAccount", "shadowAccount"]}#'contactPerson'] }
         | 
| 45 | 
            +
            		properties
         | 
| 46 | 
            +
            	end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            	treebase 'ou=people'
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            	before :save, :fix_object
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            private
         | 
| 53 | 
            +
             | 
| 54 | 
            +
            	def fix_object
         | 
| 55 | 
            +
            		self.cn = "#{self.givenname} #{self.sn}".strip
         | 
| 56 | 
            +
            	end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
            end
         | 
| @@ -0,0 +1,119 @@ | |
| 1 | 
            +
            $LOAD_PATH << Pathname(__FILE__).dirname.parent.expand_path + 'lib'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'ldap/array'
         | 
| 4 | 
            +
            require 'dm-migrations'
         | 
| 5 | 
            +
            require 'dm-sqlite-adapter'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            class A
         | 
| 8 | 
            +
              
         | 
| 9 | 
            +
              include DataMapper::Resource
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              property :id, Serial
         | 
| 12 | 
            +
              property :list,         ::Ldap::LdapArray,    :accessor => :public
         | 
| 13 | 
            +
              property :hidden_list,  ::Ldap::LdapArray,    :accessor => :private
         | 
| 14 | 
            +
              property :write_list,   ::Ldap::LdapArray,    :reader => :private, :writer => :public
         | 
| 15 | 
            +
              property :read_list,    ::Ldap::LdapArray,    :reader => :public, :writer => :private
         | 
| 16 | 
            +
            end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            require 'fileutils'
         | 
| 19 | 
            +
            FileUtils.mkdir_p("target")
         | 
| 20 | 
            +
            DataMapper.setup(:default, 'sqlite3:target/test.sqlite3')
         | 
| 21 | 
            +
            DataMapper.finalize
         | 
| 22 | 
            +
            DataMapper.auto_migrate!(:default)
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            describe Ldap::LdapArray do
         | 
| 25 | 
            +
              before { @resource = A.new }
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              it 'should create new with array' do
         | 
| 28 | 
            +
                @resource.list = ["1", "2"]
         | 
| 29 | 
            +
                @resource.dirty?.should be_true
         | 
| 30 | 
            +
                @resource.save
         | 
| 31 | 
            +
                resource = A.first(:id => @resource.id)
         | 
| 32 | 
            +
                resource.list.should == ["1", "2"]
         | 
| 33 | 
            +
                resource.list.class.should == Ldap::Array
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              it 'should have empty array on new resource' do
         | 
| 37 | 
            +
                @resource.list << "1"
         | 
| 38 | 
            +
                @resource.dirty?.should be_true
         | 
| 39 | 
            +
                @resource.save
         | 
| 40 | 
            +
                resource = A.first(:id => @resource.id)
         | 
| 41 | 
            +
                resource.list.should == ["1"]
         | 
| 42 | 
            +
                resource.list.class.should == Ldap::Array
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              it 'should save after adding an element' do
         | 
| 46 | 
            +
                @resource.list = ["1", "2"]
         | 
| 47 | 
            +
                @resource.save
         | 
| 48 | 
            +
                @resource.list << "4"
         | 
| 49 | 
            +
                @resource.save
         | 
| 50 | 
            +
                resource = A.first(:id => @resource.id)
         | 
| 51 | 
            +
                resource.list.should == ["1", "2", "4"]
         | 
| 52 | 
            +
                resource.list.class.should == Ldap::Array
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
              it 'should save after changing an element' do
         | 
| 56 | 
            +
                @resource.list = ["1", "2"]
         | 
| 57 | 
            +
                @resource.save
         | 
| 58 | 
            +
                @resource.list[1] = "4"
         | 
| 59 | 
            +
                @resource.save
         | 
| 60 | 
            +
                resource = A.first(:id => @resource.id)
         | 
| 61 | 
            +
                resource.list.should == ["1", "4"]
         | 
| 62 | 
            +
                resource.list.class.should == Ldap::Array
         | 
| 63 | 
            +
              end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
              it 'should save after deleting element from list' do
         | 
| 66 | 
            +
                @resource.list = ["1", "2"]
         | 
| 67 | 
            +
                @resource.save
         | 
| 68 | 
            +
                @resource.list.delete("1")
         | 
| 69 | 
            +
                @resource.save
         | 
| 70 | 
            +
                resource = A.first(:id => @resource.id)
         | 
| 71 | 
            +
                resource.list.should == ["2"]
         | 
| 72 | 
            +
                resource.list.class.should == Ldap::Array
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
              
         | 
| 75 | 
            +
              context 'when :accessor property is set to :private' do 
         | 
| 76 | 
            +
                it 'should not create a write accessor' do
         | 
| 77 | 
            +
                  @resource.should_not respond_to(:hidden_list=)
         | 
| 78 | 
            +
                end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                it 'should not create a reade accessor' do
         | 
| 81 | 
            +
                  @resource.should_not respond_to(:hidden_list)
         | 
| 82 | 
            +
                end  
         | 
| 83 | 
            +
              end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
              context 'when :accessor property is set to :public' do 
         | 
| 86 | 
            +
                it 'should create a write accessor' do
         | 
| 87 | 
            +
                  @resource.should respond_to(:list=)
         | 
| 88 | 
            +
                end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                it 'should create a reade accessor' do
         | 
| 91 | 
            +
                  @resource.should respond_to(:list)
         | 
| 92 | 
            +
                end  
         | 
| 93 | 
            +
              end
         | 
| 94 | 
            +
              
         | 
| 95 | 
            +
              context 'when :writer property is set to :public' do
         | 
| 96 | 
            +
                it 'should create a write accessor' do
         | 
| 97 | 
            +
                  @resource.should respond_to(:write_list=)
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
              end
         | 
| 100 | 
            +
             | 
| 101 | 
            +
              context 'when :writer property is set to :private' do
         | 
| 102 | 
            +
                it 'should not create a write accessor' do
         | 
| 103 | 
            +
                  @resource.should_not respond_to(:read_list=)
         | 
| 104 | 
            +
                end
         | 
| 105 | 
            +
              end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
              context 'when :reader property is set to :public' do
         | 
| 108 | 
            +
                it 'should create a read accessor' do
         | 
| 109 | 
            +
                  @resource.should respond_to(:read_list)
         | 
| 110 | 
            +
                end
         | 
| 111 | 
            +
              end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
              context 'when :reader property is set to :private' do
         | 
| 114 | 
            +
                it 'should not create a read accessor' do
         | 
| 115 | 
            +
                  @resource.should_not respond_to(:write_list)
         | 
| 116 | 
            +
                end
         | 
| 117 | 
            +
              end
         | 
| 118 | 
            +
             | 
| 119 | 
            +
            end
         | 
| @@ -151,7 +151,6 @@ describe DataMapper.repository(:ldap).adapter.class do | |
| 151 151 | 
             
                end
         | 
| 152 152 |  | 
| 153 153 | 
             
                it 'should be able to use multilines with LdapArray' do
         | 
| 154 | 
            -
                  pending "not working for net-ldap" if DataMapper.repository(:ldap).adapter.ldap.class.to_s == 'Ldap::NetLdapFacade'
         | 
| 155 154 | 
             
                  DataMapper.repository(:ldap) do
         | 
| 156 155 | 
             
                    @contact.mail = ["email1\nmail2\nmail2\nmail4", "email1"]
         | 
| 157 156 | 
             
                    @contact.save
         | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            require 'rubygems'
         | 
| 2 2 |  | 
| 3 3 | 
             
            require 'slf4r/ruby_logger'
         | 
| 4 | 
            -
            Slf4r::LoggerFacade4RubyLogger.level = : | 
| 4 | 
            +
            Slf4r::LoggerFacade4RubyLogger.level = :warn
         | 
| 5 5 |  | 
| 6 6 | 
             
            require 'dm-sqlite-adapter'
         | 
| 7 7 | 
             
            require 'dm-migrations'
         | 
| @@ -26,6 +26,8 @@ DataMapper.setup(:ldap, { | |
| 26 26 | 
             
                               :password => "behappy"
         | 
| 27 27 | 
             
            })
         | 
| 28 28 |  | 
| 29 | 
            +
            puts "using facade #{(ENV['FACADE'] || :net_ldap).to_sym}"
         | 
| 30 | 
            +
             | 
| 29 31 | 
             
            module DataMapper
         | 
| 30 32 | 
             
              module Resource
         | 
| 31 33 | 
             
                class State
         | 
| @@ -55,25 +57,30 @@ class User | |
| 55 57 | 
             
              has n, :group_users
         | 
| 56 58 |  | 
| 57 59 | 
             
              def groups
         | 
| 58 | 
            -
                groups = GroupUser.all(:user_id =>  | 
| 60 | 
            +
                groups = GroupUser.all(:user_id => login).collect{ |gu| gu.group }
         | 
| 61 | 
            +
             | 
| 59 62 | 
             
                def groups.user=(user)
         | 
| 60 63 | 
             
                  @user = user
         | 
| 61 64 | 
             
                end
         | 
| 65 | 
            +
             | 
| 62 66 | 
             
                groups.user = self
         | 
| 67 | 
            +
             | 
| 63 68 | 
             
                def groups.<<(group)
         | 
| 64 69 | 
             
                  unless member? group
         | 
| 65 | 
            -
                    GroupUser.create(:user_id => @user. | 
| 70 | 
            +
                    GroupUser.create(:user_id => @user.login, :group_id => group.id)
         | 
| 66 71 | 
             
                    super
         | 
| 67 72 | 
             
                  end
         | 
| 68 73 | 
             
                  self
         | 
| 69 74 | 
             
                end
         | 
| 75 | 
            +
             | 
| 70 76 | 
             
                def groups.delete(group)
         | 
| 71 | 
            -
                  gu = GroupUser.first(:user_id => @user. | 
| 77 | 
            +
                  gu = GroupUser.first(:user_id => @user.login, :group_id => group.id)
         | 
| 72 78 | 
             
                  if gu
         | 
| 73 79 | 
             
                    gu.destroy
         | 
| 74 80 | 
             
                    super
         | 
| 75 81 | 
             
                  end
         | 
| 76 82 | 
             
                end
         | 
| 83 | 
            +
             | 
| 77 84 | 
             
                groups
         | 
| 78 85 | 
             
              end
         | 
| 79 86 |  | 
| @@ -90,7 +97,8 @@ class User | |
| 90 97 | 
             
              end
         | 
| 91 98 |  | 
| 92 99 | 
             
              def password=(password)
         | 
| 93 | 
            -
                 | 
| 100 | 
            +
                salt = "--#{Time.now}--#{login}--"
         | 
| 101 | 
            +
                attribute_set(:hashed_password, Ldap::Digest.ssha(password, salt)) if password
         | 
| 94 102 | 
             
              end
         | 
| 95 103 | 
             
            end
         | 
| 96 104 |  | 
| @@ -133,7 +141,7 @@ class GroupUser | |
| 133 141 | 
             
                {:cn=>"#{group_user.group.name}",  :objectclass => "posixGroup"}
         | 
| 134 142 | 
             
              end
         | 
| 135 143 |  | 
| 136 | 
            -
              property :user_id,  | 
| 144 | 
            +
              property :user_id, String, :key => true, :field => "memberUid"
         | 
| 137 145 | 
             
              property :group_id, Integer, :key => true, :field => "gidNumber"
         | 
| 138 146 |  | 
| 139 147 | 
             
              def group
         | 
    
        metadata
    CHANGED
    
    | @@ -1,37 +1,38 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: dm-ldap-adapter
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
              hash:  | 
| 5 | 
            -
              prerelease:  | 
| 4 | 
            +
              hash: 9
         | 
| 5 | 
            +
              prerelease: 
         | 
| 6 6 | 
             
              segments: 
         | 
| 7 7 | 
             
              - 0
         | 
| 8 8 | 
             
              - 4
         | 
| 9 | 
            -
              -  | 
| 10 | 
            -
              version: 0.4. | 
| 9 | 
            +
              - 3
         | 
| 10 | 
            +
              version: 0.4.3
         | 
| 11 11 | 
             
            platform: ruby
         | 
| 12 12 | 
             
            authors: 
         | 
| 13 13 | 
             
            - mkristian
         | 
| 14 | 
            +
            - xertres
         | 
| 14 15 | 
             
            autorequire: 
         | 
| 15 16 | 
             
            bindir: bin
         | 
| 16 17 | 
             
            cert_chain: []
         | 
| 17 18 |  | 
| 18 | 
            -
            date: 2011- | 
| 19 | 
            +
            date: 2011-06-06 00:00:00 +05:30
         | 
| 19 20 | 
             
            default_executable: 
         | 
| 20 21 | 
             
            dependencies: 
         | 
| 21 22 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 22 | 
            -
              name:  | 
| 23 | 
            +
              name: net-ldap
         | 
| 23 24 | 
             
              prerelease: false
         | 
| 24 25 | 
             
              requirement: &id001 !ruby/object:Gem::Requirement 
         | 
| 25 26 | 
             
                none: false
         | 
| 26 27 | 
             
                requirements: 
         | 
| 27 | 
            -
                - -  | 
| 28 | 
            +
                - - ~>
         | 
| 28 29 | 
             
                  - !ruby/object:Gem::Version 
         | 
| 29 | 
            -
                    hash:  | 
| 30 | 
            +
                    hash: 19
         | 
| 30 31 | 
             
                    segments: 
         | 
| 31 32 | 
             
                    - 0
         | 
| 32 | 
            -
                    -  | 
| 33 | 
            -
                    -  | 
| 34 | 
            -
                    version: 0. | 
| 33 | 
            +
                    - 2
         | 
| 34 | 
            +
                    - 2
         | 
| 35 | 
            +
                    version: 0.2.2
         | 
| 35 36 | 
             
              type: :runtime
         | 
| 36 37 | 
             
              version_requirements: *id001
         | 
| 37 38 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| @@ -40,12 +41,14 @@ dependencies: | |
| 40 41 | 
             
              requirement: &id002 !ruby/object:Gem::Requirement 
         | 
| 41 42 | 
             
                none: false
         | 
| 42 43 | 
             
                requirements: 
         | 
| 43 | 
            -
                - -  | 
| 44 | 
            +
                - - ~>
         | 
| 44 45 | 
             
                  - !ruby/object:Gem::Version 
         | 
| 45 | 
            -
                    hash:  | 
| 46 | 
            +
                    hash: 11
         | 
| 46 47 | 
             
                    segments: 
         | 
| 47 48 | 
             
                    - 0
         | 
| 48 | 
            -
                     | 
| 49 | 
            +
                    - 4
         | 
| 50 | 
            +
                    - 2
         | 
| 51 | 
            +
                    version: 0.4.2
         | 
| 49 52 | 
             
              type: :runtime
         | 
| 50 53 | 
             
              version_requirements: *id002
         | 
| 51 54 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| @@ -56,74 +59,134 @@ dependencies: | |
| 56 59 | 
             
                requirements: 
         | 
| 57 60 | 
             
                - - ~>
         | 
| 58 61 | 
             
                  - !ruby/object:Gem::Version 
         | 
| 59 | 
            -
                    hash:  | 
| 62 | 
            +
                    hash: 15
         | 
| 60 63 | 
             
                    segments: 
         | 
| 61 64 | 
             
                    - 1
         | 
| 62 65 | 
             
                    - 0
         | 
| 63 | 
            -
                     | 
| 64 | 
            -
                    version: 1.0.0
         | 
| 66 | 
            +
                    version: "1.0"
         | 
| 65 67 | 
             
              type: :runtime
         | 
| 66 68 | 
             
              version_requirements: *id003
         | 
| 67 69 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 68 | 
            -
              name:  | 
| 70 | 
            +
              name: dm-transactions
         | 
| 69 71 | 
             
              prerelease: false
         | 
| 70 72 | 
             
              requirement: &id004 !ruby/object:Gem::Requirement 
         | 
| 71 73 | 
             
                none: false
         | 
| 72 74 | 
             
                requirements: 
         | 
| 73 | 
            -
                - -  | 
| 75 | 
            +
                - - ~>
         | 
| 74 76 | 
             
                  - !ruby/object:Gem::Version 
         | 
| 75 | 
            -
                    hash:  | 
| 77 | 
            +
                    hash: 15
         | 
| 78 | 
            +
                    segments: 
         | 
| 79 | 
            +
                    - 1
         | 
| 80 | 
            +
                    - 0
         | 
| 81 | 
            +
                    version: "1.0"
         | 
| 82 | 
            +
              type: :runtime
         | 
| 83 | 
            +
              version_requirements: *id004
         | 
| 84 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 85 | 
            +
              name: dm-sqlite-adapter
         | 
| 86 | 
            +
              prerelease: false
         | 
| 87 | 
            +
              requirement: &id005 !ruby/object:Gem::Requirement 
         | 
| 88 | 
            +
                none: false
         | 
| 89 | 
            +
                requirements: 
         | 
| 90 | 
            +
                - - ~>
         | 
| 91 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 92 | 
            +
                    hash: 15
         | 
| 93 | 
            +
                    segments: 
         | 
| 94 | 
            +
                    - 1
         | 
| 95 | 
            +
                    - 0
         | 
| 96 | 
            +
                    version: "1.0"
         | 
| 97 | 
            +
              type: :development
         | 
| 98 | 
            +
              version_requirements: *id005
         | 
| 99 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 100 | 
            +
              name: dm-migrations
         | 
| 101 | 
            +
              prerelease: false
         | 
| 102 | 
            +
              requirement: &id006 !ruby/object:Gem::Requirement 
         | 
| 103 | 
            +
                none: false
         | 
| 104 | 
            +
                requirements: 
         | 
| 105 | 
            +
                - - ~>
         | 
| 106 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 107 | 
            +
                    hash: 15
         | 
| 108 | 
            +
                    segments: 
         | 
| 109 | 
            +
                    - 1
         | 
| 110 | 
            +
                    - 0
         | 
| 111 | 
            +
                    version: "1.0"
         | 
| 112 | 
            +
              type: :development
         | 
| 113 | 
            +
              version_requirements: *id006
         | 
| 114 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 115 | 
            +
              name: rspec
         | 
| 116 | 
            +
              prerelease: false
         | 
| 117 | 
            +
              requirement: &id007 !ruby/object:Gem::Requirement 
         | 
| 118 | 
            +
                none: false
         | 
| 119 | 
            +
                requirements: 
         | 
| 120 | 
            +
                - - ~>
         | 
| 121 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 122 | 
            +
                    hash: 23
         | 
| 76 123 | 
             
                    segments: 
         | 
| 77 124 | 
             
                    - 2
         | 
| 78 | 
            -
                    -  | 
| 125 | 
            +
                    - 6
         | 
| 79 126 | 
             
                    - 0
         | 
| 80 | 
            -
                    version: 2. | 
| 127 | 
            +
                    version: 2.6.0
         | 
| 81 128 | 
             
              type: :development
         | 
| 82 | 
            -
              version_requirements: * | 
| 129 | 
            +
              version_requirements: *id007
         | 
| 130 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 131 | 
            +
              name: ruby-ldap
         | 
| 132 | 
            +
              prerelease: false
         | 
| 133 | 
            +
              requirement: &id008 !ruby/object:Gem::Requirement 
         | 
| 134 | 
            +
                none: false
         | 
| 135 | 
            +
                requirements: 
         | 
| 136 | 
            +
                - - ~>
         | 
| 137 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 138 | 
            +
                    hash: 45
         | 
| 139 | 
            +
                    segments: 
         | 
| 140 | 
            +
                    - 0
         | 
| 141 | 
            +
                    - 9
         | 
| 142 | 
            +
                    - 11
         | 
| 143 | 
            +
                    version: 0.9.11
         | 
| 144 | 
            +
              type: :development
         | 
| 145 | 
            +
              version_requirements: *id008
         | 
| 83 146 | 
             
            description: ldap adapter for datamapper which uses either net-ldap or ruby-ldap
         | 
| 84 147 | 
             
            email: 
         | 
| 85 148 | 
             
            - m.kristian@web.de
         | 
| 149 | 
            +
            - ""
         | 
| 86 150 | 
             
            executables: []
         | 
| 87 151 |  | 
| 88 152 | 
             
            extensions: []
         | 
| 89 153 |  | 
| 90 154 | 
             
            extra_rdoc_files: 
         | 
| 91 155 | 
             
            - History.txt
         | 
| 92 | 
            -
            -  | 
| 93 | 
            -
            - README.txt
         | 
| 156 | 
            +
            - README.md
         | 
| 94 157 | 
             
            - ldap-commands.txt
         | 
| 95 158 | 
             
            files: 
         | 
| 96 | 
            -
            - .project
         | 
| 97 | 
            -
            - .yardoc
         | 
| 98 159 | 
             
            - History.txt
         | 
| 99 160 | 
             
            - MIT-LICENSE
         | 
| 100 | 
            -
            - Manifest.txt
         | 
| 101 | 
            -
            - README-example.markdown
         | 
| 102 | 
            -
            - README.txt
         | 
| 103 | 
            -
            - Rakefile
         | 
| 104 | 
            -
            - example/posix.rb
         | 
| 105 161 | 
             
            - ldap-commands.txt
         | 
| 162 | 
            +
            - README.md
         | 
| 163 | 
            +
            - README-example.md
         | 
| 164 | 
            +
            - README-bundler.md
         | 
| 106 165 | 
             
            - lib/adapters/ldap_adapter.rb
         | 
| 107 166 | 
             
            - lib/adapters/noop_transaction.rb
         | 
| 167 | 
            +
            - lib/dm-ldap-adapter.rb
         | 
| 168 | 
            +
            - lib/ldap_resource.rb
         | 
| 108 169 | 
             
            - lib/dummy_ldap_resource.rb
         | 
| 109 | 
            -
            - lib/ldap/ | 
| 110 | 
            -
            - lib/ldap/ | 
| 170 | 
            +
            - lib/ldap/version.rb
         | 
| 171 | 
            +
            - lib/ldap/unboundid_ldap_facade.rb
         | 
| 172 | 
            +
            - lib/ldap/transactions.rb
         | 
| 173 | 
            +
            - lib/ldap/ruby_ldap_facade.rb
         | 
| 111 174 | 
             
            - lib/ldap/digest.rb
         | 
| 112 175 | 
             
            - lib/ldap/net_ldap_facade.rb
         | 
| 113 | 
            -
            - lib/ldap/ | 
| 114 | 
            -
            - lib/ldap/ | 
| 115 | 
            -
            - lib/ldap_resource.rb
         | 
| 116 | 
            -
            - spec/assiociations_ldap_adapter_spec.rb
         | 
| 117 | 
            -
            - spec/authentication_ldap_adapter_spec.rb
         | 
| 118 | 
            -
            - spec/ldap_adapter_spec.rb
         | 
| 119 | 
            -
            - spec/multi_repository_spec.rb
         | 
| 176 | 
            +
            - lib/ldap/conditions_2_filter.rb
         | 
| 177 | 
            +
            - lib/ldap/array.rb
         | 
| 120 178 | 
             
            - spec/multi_value_attributes_spec.rb
         | 
| 121 179 | 
             
            - spec/sorting_spec.rb
         | 
| 122 | 
            -
            - spec/ | 
| 180 | 
            +
            - spec/multi_repository_spec.rb
         | 
| 181 | 
            +
            - spec/contact.rb
         | 
| 123 182 | 
             
            - spec/spec_helper.rb
         | 
| 124 | 
            -
            -  | 
| 183 | 
            +
            - spec/ldap_adapter_spec.rb
         | 
| 184 | 
            +
            - spec/authentication_ldap_adapter_spec.rb
         | 
| 185 | 
            +
            - spec/assiociations_ldap_adapter_spec.rb
         | 
| 186 | 
            +
            - spec/ldap_array_spec.rb
         | 
| 187 | 
            +
            - example/posix.rb
         | 
| 125 188 | 
             
            has_rdoc: true
         | 
| 126 | 
            -
            homepage: http://dm-ldap-adapter | 
| 189 | 
            +
            homepage: http://github.com/mkristian/dm-ldap-adapter
         | 
| 127 190 | 
             
            licenses: []
         | 
| 128 191 |  | 
| 129 192 | 
             
            post_install_message: 
         | 
| @@ -152,8 +215,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 152 215 | 
             
                  version: "0"
         | 
| 153 216 | 
             
            requirements: []
         | 
| 154 217 |  | 
| 155 | 
            -
            rubyforge_project:  | 
| 156 | 
            -
            rubygems_version: 1.3 | 
| 218 | 
            +
            rubyforge_project: 
         | 
| 219 | 
            +
            rubygems_version: 1.5.3
         | 
| 157 220 | 
             
            signing_key: 
         | 
| 158 221 | 
             
            specification_version: 3
         | 
| 159 222 | 
             
            summary: ""
         | 
    
        data/.project
    DELETED
    
    
    
        data/.yardoc
    DELETED
    
    | Binary file | 
    
        data/Manifest.txt
    DELETED
    
    | @@ -1,29 +0,0 @@ | |
| 1 | 
            -
            .project
         | 
| 2 | 
            -
            .yardoc
         | 
| 3 | 
            -
            History.txt
         | 
| 4 | 
            -
            MIT-LICENSE
         | 
| 5 | 
            -
            Manifest.txt
         | 
| 6 | 
            -
            README-example.markdown
         | 
| 7 | 
            -
            README.txt
         | 
| 8 | 
            -
            Rakefile
         | 
| 9 | 
            -
            example/posix.rb
         | 
| 10 | 
            -
            ldap-commands.txt
         | 
| 11 | 
            -
            lib/adapters/ldap_adapter.rb
         | 
| 12 | 
            -
            lib/adapters/noop_transaction.rb
         | 
| 13 | 
            -
            lib/dummy_ldap_resource.rb
         | 
| 14 | 
            -
            lib/ldap/array.rb
         | 
| 15 | 
            -
            lib/ldap/conditions_2_filter.rb
         | 
| 16 | 
            -
            lib/ldap/digest.rb
         | 
| 17 | 
            -
            lib/ldap/net_ldap_facade.rb
         | 
| 18 | 
            -
            lib/ldap/ruby_ldap_facade.rb
         | 
| 19 | 
            -
            lib/ldap/version.rb
         | 
| 20 | 
            -
            lib/ldap_resource.rb
         | 
| 21 | 
            -
            spec/assiociations_ldap_adapter_spec.rb
         | 
| 22 | 
            -
            spec/authentication_ldap_adapter_spec.rb
         | 
| 23 | 
            -
            spec/ldap_adapter_spec.rb
         | 
| 24 | 
            -
            spec/multi_repository_spec.rb
         | 
| 25 | 
            -
            spec/multi_value_attributes_spec.rb
         | 
| 26 | 
            -
            spec/sorting_spec.rb
         | 
| 27 | 
            -
            spec/spec.opts
         | 
| 28 | 
            -
            spec/spec_helper.rb
         | 
| 29 | 
            -
            test.ldif
         | 
    
        data/Rakefile
    DELETED
    
    | @@ -1,38 +0,0 @@ | |
| 1 | 
            -
            # -*- ruby -*-
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            require 'rubygems'
         | 
| 4 | 
            -
            require 'hoe'
         | 
| 5 | 
            -
            require './lib/ldap/version.rb'
         | 
| 6 | 
            -
             | 
| 7 | 
            -
            require 'spec'
         | 
| 8 | 
            -
            require 'spec/rake/spectask'
         | 
| 9 | 
            -
            require 'pathname'
         | 
| 10 | 
            -
             | 
| 11 | 
            -
            Hoe.spec('dm-ldap-adapter') do |p|
         | 
| 12 | 
            -
              p.version = "0.4.2"
         | 
| 13 | 
            -
              p.description = "ldap adapter for datamapper which uses either net-ldap or ruby-ldap"
         | 
| 14 | 
            -
              p.developer('mkristian', 'm.kristian@web.de')
         | 
| 15 | 
            -
              p.url = "http://dm-ldap-adapter.rubyforge.org"
         | 
| 16 | 
            -
              p.extra_deps = [['ruby-net-ldap', '=0.0.4'],['slf4r', '>=0'], ['dm-core', '~>1.0.0']]
         | 
| 17 | 
            -
              p.remote_rdoc_dir = '' # Release to root
         | 
| 18 | 
            -
            end
         | 
| 19 | 
            -
             | 
| 20 | 
            -
            desc 'Install the package as a gem.'
         | 
| 21 | 
            -
            task :install => [:clean, :package] do
         | 
| 22 | 
            -
              gem = Dir['pkg/*.gem'].first
         | 
| 23 | 
            -
              sh "gem install --local #{gem} --no-ri --no-rdoc"
         | 
| 24 | 
            -
            end
         | 
| 25 | 
            -
             | 
| 26 | 
            -
            desc 'Run specifications'
         | 
| 27 | 
            -
            Spec::Rake::SpecTask.new(:spec) do |t|
         | 
| 28 | 
            -
              if File.exists?('spec/spec.opts')
         | 
| 29 | 
            -
                t.spec_opts << '--options' << 'spec/spec.opts'
         | 
| 30 | 
            -
              end
         | 
| 31 | 
            -
              t.spec_files = Pathname.glob('./spec/**/*_spec.rb')
         | 
| 32 | 
            -
            end
         | 
| 33 | 
            -
             | 
| 34 | 
            -
            #require 'yard'
         | 
| 35 | 
            -
             | 
| 36 | 
            -
            #YARD::Rake::YardocTask.new
         | 
| 37 | 
            -
             | 
| 38 | 
            -
            # vim: syntax=Ruby
         | 
    
        data/spec/spec.opts
    DELETED
    
    
    
        data/test.ldif
    DELETED
    
    | @@ -1,46 +0,0 @@ | |
| 1 | 
            -
            dn: ou=people,dc=example,dc=com
         | 
| 2 | 
            -
            objectClass: organizationalUnit
         | 
| 3 | 
            -
            ou: people
         | 
| 4 | 
            -
             | 
| 5 | 
            -
            dn: ou=groups,dc=example,dc=com
         | 
| 6 | 
            -
            objectClass: organizationalUnit
         | 
| 7 | 
            -
            ou: groups
         | 
| 8 | 
            -
             | 
| 9 | 
            -
            dn: uid=kristian,ou=people,dc=example,dc=com
         | 
| 10 | 
            -
            objectClass: inetOrgPerson
         | 
| 11 | 
            -
            objectClass: posixAccount
         | 
| 12 | 
            -
            uid: kristian
         | 
| 13 | 
            -
            sn: Meier
         | 
| 14 | 
            -
            givenName: Kristian
         | 
| 15 | 
            -
            cn: Kristian Meier
         | 
| 16 | 
            -
            uidNumber: 1000
         | 
| 17 | 
            -
            gidNumber: 10000
         | 
| 18 | 
            -
            userPassword: {SSHA}/o6oa2GOphls/lzOFCwVkw9ARWEEiw+x
         | 
| 19 | 
            -
            mail: m.kristian@web.de
         | 
| 20 | 
            -
            loginShell: /bin/false
         | 
| 21 | 
            -
            homeDirectory: 
         | 
| 22 | 
            -
             | 
| 23 | 
            -
            dn: cn=manager,ou=groups,dc=example,dc=com
         | 
| 24 | 
            -
            objectClass: posixGroup
         | 
| 25 | 
            -
            cn: manager
         | 
| 26 | 
            -
            gidNumber: 10000
         | 
| 27 | 
            -
             | 
| 28 | 
            -
            dn: cn=admin,ou=groups,dc=example,dc=com
         | 
| 29 | 
            -
            objectClass: posixGroup
         | 
| 30 | 
            -
            cn: admin
         | 
| 31 | 
            -
            gidNumber: 10001
         | 
| 32 | 
            -
            memberUid: kristian
         | 
| 33 | 
            -
             | 
| 34 | 
            -
            dn: uid=bill,ou=people,dc=example,dc=com
         | 
| 35 | 
            -
            objectClass: inetOrgPerson
         | 
| 36 | 
            -
            objectClass: posixAccount
         | 
| 37 | 
            -
            uid: bill
         | 
| 38 | 
            -
            sn: bill
         | 
| 39 | 
            -
            givenName: bill
         | 
| 40 | 
            -
            cn: bill
         | 
| 41 | 
            -
            uidNumber: 1001
         | 
| 42 | 
            -
            gidNumber: 10000
         | 
| 43 | 
            -
            userPassword: {SSHA}/o6oa2GOphls/lzOFCwVkw9ARWEEiw+x
         | 
| 44 | 
            -
            mail: bill@web.de
         | 
| 45 | 
            -
            loginShell: /bin/false
         | 
| 46 | 
            -
            homeDirectory: /root
         |