diff --git a/.gitignore b/.gitignore index bd8b459..3a93b4e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ coverage tmp -Gemfile .svn .directory diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..5f15932 --- /dev/null +++ b/Gemfile @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +source 'https://rubygems.org' do + gem 'sorted_set' +end diff --git a/init.rb b/init.rb index 77bce7d..1dd9151 100644 --- a/init.rb +++ b/init.rb @@ -16,9 +16,11 @@ #RedmineApp::Application.config.after_initialize do Rails.application.config.to_prepare do - require_dependency 'ldap_sync/core_ext' - require_dependency 'ldap_sync/infectors' + require "#{File.dirname(__FILE__)}/lib/ldap_sync/core_ext" + require "#{File.dirname(__FILE__)}/lib/ldap_sync/infectors" end # hooks -require_dependency 'ldap_sync/hooks' +require "#{File.dirname(__FILE__)}/lib/ldap_sync/hooks" + +require "#{File.dirname(__FILE__)}/lib/ldap_sync/infectors" diff --git a/lib/ldap_sync/core_ext.rb b/lib/ldap_sync/core_ext.rb index 61d626c..0463820 100644 --- a/lib/ldap_sync/core_ext.rb +++ b/lib/ldap_sync/core_ext.rb @@ -15,4 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with Redmine LDAP Sync. If not, see . -Dir[File.dirname(__FILE__) + "/core_ext/*.rb"].each { |file| require(file) } \ No newline at end of file +module LdapSync + class CoreExt + Dir[File.dirname(__FILE__) + "/core_ext/*.rb"].each { |file| require(file) } + end +end \ No newline at end of file diff --git a/lib/ldap_sync/core_ext/ber.rb b/lib/ldap_sync/core_ext/ber.rb index 72ce308..9838a98 100644 --- a/lib/ldap_sync/core_ext/ber.rb +++ b/lib/ldap_sync/core_ext/ber.rb @@ -15,48 +15,54 @@ # # You should have received a copy of the GNU General Public License # along with Redmine LDAP Sync. If not, see . -if ('0.12.0'..'0.13.0') === Gem.loaded_specs['net-ldap'].version.to_s - require 'net/ber' +module LdapSync + class CoreExt + class Ber + if ('0.12.0'..'0.13.0') === Gem.loaded_specs['net-ldap'].version.to_s + require 'net/ber' - ## - # A String object with a BER identifier attached. - # - class Net::BER::BerIdentifiedString < String - attr_accessor :ber_identifier + ## + # A String object with a BER identifier attached. + # + class Net::BER::BerIdentifiedString < String + attr_accessor :ber_identifier - # The binary data provided when parsing the result of the LDAP search - # has the encoding 'ASCII-8BIT' (which is basically 'BINARY', or 'unknown'). - # - # This is the kind of a backtrace showing how the binary `data` comes to - # BerIdentifiedString.new(data): - # - # @conn.read_ber(syntax) - # -> StringIO.new(self).read_ber(syntax), i.e. included from module - # -> Net::BER::BERParser.read_ber(syntax) - # -> (private)Net::BER::BERParser.parse_ber_object(syntax, id, data) - # - # In the `#parse_ber_object` method `data`, according to its OID, is being - # 'casted' to one of the Net::BER:BerIdentifiedXXX classes. - # - # As we are using LDAP v3 we can safely assume that the data is encoded - # in UTF-8 and therefore the only thing to be done when instantiating is to - # switch the encoding from 'ASCII-8BIT' to 'UTF-8'. - # - # Unfortunately, there are some ActiveDirectory specific attributes - # (like `objectguid`) that should remain binary (do they really?). - # Using the `#valid_encoding?` we can trap this cases. Special cases like - # Japanese, Korean, etc. encodings might also profit from this. However - # I have no clue how this encodings function. - def initialize args - super - # - # Check the encoding of the newly created String and set the encoding - # to 'UTF-8' (NOTE: we do NOT change the bytes, but only set the - # encoding to 'UTF-8'). - current_encoding = encoding - if current_encoding == Encoding::BINARY - force_encoding('UTF-8') - force_encoding(current_encoding) unless valid_encoding? + # The binary data provided when parsing the result of the LDAP search + # has the encoding 'ASCII-8BIT' (which is basically 'BINARY', or 'unknown'). + # + # This is the kind of a backtrace showing how the binary `data` comes to + # BerIdentifiedString.new(data): + # + # @conn.read_ber(syntax) + # -> StringIO.new(self).read_ber(syntax), i.e. included from module + # -> Net::BER::BERParser.read_ber(syntax) + # -> (private)Net::BER::BERParser.parse_ber_object(syntax, id, data) + # + # In the `#parse_ber_object` method `data`, according to its OID, is being + # 'casted' to one of the Net::BER:BerIdentifiedXXX classes. + # + # As we are using LDAP v3 we can safely assume that the data is encoded + # in UTF-8 and therefore the only thing to be done when instantiating is to + # switch the encoding from 'ASCII-8BIT' to 'UTF-8'. + # + # Unfortunately, there are some ActiveDirectory specific attributes + # (like `objectguid`) that should remain binary (do they really?). + # Using the `#valid_encoding?` we can trap this cases. Special cases like + # Japanese, Korean, etc. encodings might also profit from this. However + # I have no clue how this encodings function. + def initialize args + super + # + # Check the encoding of the newly created String and set the encoding + # to 'UTF-8' (NOTE: we do NOT change the bytes, but only set the + # encoding to 'UTF-8'). + current_encoding = encoding + if current_encoding == Encoding::BINARY + force_encoding('UTF-8') + force_encoding(current_encoding) unless valid_encoding? + end + end + end end end end diff --git a/lib/ldap_sync/core_ext/file_store.rb b/lib/ldap_sync/core_ext/file_store.rb index e663e4d..bf35f07 100644 --- a/lib/ldap_sync/core_ext/file_store.rb +++ b/lib/ldap_sync/core_ext/file_store.rb @@ -15,12 +15,18 @@ # # You should have received a copy of the GNU General Public License # along with Redmine LDAP Sync. If not, see . -class ActiveSupport::Cache::FileStore - def delete_unless - options = merged_options(options) - search_dir(cache_path) do |path| - key = file_path_key(path) - delete_entry(key, options) unless yield(key) +module LdapSync + class CoreExt + class FileStore + class ActiveSupport::Cache::FileStore + def delete_unless + options = merged_options(options) + search_dir(cache_path) do |path| + key = file_path_key(path) + delete_entry(key, options) unless yield(key) + end + end + end end end end \ No newline at end of file diff --git a/lib/ldap_sync/core_ext/ldap.rb b/lib/ldap_sync/core_ext/ldap.rb index 92090d5..66d33d2 100644 --- a/lib/ldap_sync/core_ext/ldap.rb +++ b/lib/ldap_sync/core_ext/ldap.rb @@ -17,8 +17,15 @@ # along with Redmine LDAP Sync. If not, see . require 'net/ldap' -class Net::LDAP - if Gem.loaded_specs['net-ldap'].version < Gem::Version.new('0.12.0') - Error = LdapError +module LdapSync + class CoreExt + class Ldap + + class Net::LDAP + if Gem.loaded_specs['net-ldap'].version < Gem::Version.new('0.12.0') + Error = LdapError + end + end + end end end \ No newline at end of file diff --git a/lib/ldap_sync/core_ext/ldap_entry.rb b/lib/ldap_sync/core_ext/ldap_entry.rb index 329493f..7111c14 100644 --- a/lib/ldap_sync/core_ext/ldap_entry.rb +++ b/lib/ldap_sync/core_ext/ldap_entry.rb @@ -17,8 +17,14 @@ # along with Redmine LDAP Sync. If not, see . require 'net/ldap' -class Net::LDAP - class Entry - include Enumerable +module LdapSync + class CoreExt + class LdapEntry + class Net::LDAP + class Entry + include Enumerable + end + end + end end end \ No newline at end of file diff --git a/lib/ldap_sync/core_ext/migration.rb b/lib/ldap_sync/core_ext/migration.rb index dd0861f..0b63052 100644 --- a/lib/ldap_sync/core_ext/migration.rb +++ b/lib/ldap_sync/core_ext/migration.rb @@ -15,12 +15,18 @@ # # You should have received a copy of the GNU General Public License # along with Redmine LDAP Sync. If not, see . -class ActiveRecord::Migration - unless defined? self.[] - - # Enables the use of versioned migrations on rails < 5 - def self.[](version) - self - end +module LdapSync + class CoreExt + class Migration + class ActiveRecord::Migration + unless defined? self.[] + + # Enables the use of versioned migrations on rails < 5 + def self.[](version) + self + end + end + end end + end end \ No newline at end of file diff --git a/lib/ldap_sync/core_ext/string.rb b/lib/ldap_sync/core_ext/string.rb index 690ada2..223a0ec 100644 --- a/lib/ldap_sync/core_ext/string.rb +++ b/lib/ldap_sync/core_ext/string.rb @@ -17,13 +17,19 @@ # along with Redmine LDAP Sync. If not, see . require 'net/ldap' -module Net::BER::Extensions::String - if Gem.loaded_specs['net-ldap'].version < Gem::Version.new('0.12.0') - def raw_utf8_encoded - if self.respond_to?(:encode) && self.encoding.name != 'ASCII-8BIT' - self.encode('UTF-8').force_encoding('ASCII-8BIT') - else - self +module LdapSync + class CoreExt + class String + module Net::BER::Extensions::String + if Gem.loaded_specs['net-ldap'].version < Gem::Version.new('0.12.0') + def raw_utf8_encoded + if self.respond_to?(:encode) && self.encoding.name != 'ASCII-8BIT' + self.encode('UTF-8').force_encoding('ASCII-8BIT') + else + self + end + end + end end end end diff --git a/lib/ldap_sync/entity_manager.rb b/lib/ldap_sync/entity_manager.rb index e049699..60cfcc4 100644 --- a/lib/ldap_sync/entity_manager.rb +++ b/lib/ldap_sync/entity_manager.rb @@ -35,7 +35,7 @@ def get_user_fields(username, user_data=nil, options={}) end return {} if user_data.nil? - user_fields = user_data.inject({}) do |fields, (attr, value)| + user_fields = user_data.to_h.inject({}) do |fields, (attr, value)| f = setting.user_field(attr) if f && fields_to_sync.include?(f) fields[f] = value.first unless value.nil? || value.first.blank? @@ -103,8 +103,8 @@ def ldap_users end end - changes[:enabled].delete(nil) - changes[:locked].delete(nil) + changes[:enabled].delete("") + changes[:locked].delete("") users_on_local = self.users.active.map {|u| u.login.downcase } users_on_ldap = changes.values.sum.map(&:downcase)