activeldap 4.0.4 → 4.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4c12549921e8f9d7aa8674add95bc2f48f82afdd
4
- data.tar.gz: dd5633df0f5fc5ce5241ff4d77545bc243b8becb
3
+ metadata.gz: 4f80df61b7c3ce5999e745306e16007bc5b17f6d
4
+ data.tar.gz: 6de78b2c730aab8884c3de3d0a49efce255a45b3
5
5
  SHA512:
6
- metadata.gz: 8ef5b66f2ece4f6eea6b6c46db97df52e97dd72b3d80e47d4027ed135346780f90de594b3bce5a2cae221d1f186fb3e225627600a8bd786b2326713388064efa
7
- data.tar.gz: 580ccd4daf6d3625358be6c7ccba2f3a64aee0722dd8e9d7b2bc354c32120915692d42c59287054b1edb6cb37aee42f6b2cacfd4b0d5ead69be200b6e75f2008
6
+ metadata.gz: 2a6bbedd08e66e15391642d7c37132e4c83b90c01d2fbf213fbdcdff9352a80f0112716f28e1c373b89908f18d5a2b5f36975425c1d248c6b094cc4a02e3df4b
7
+ data.tar.gz: 472d41a261d52c4001f333fbdf5e07e4450cfbff210cf199a592e9e47c7f123032c250f6ebea79b9e7d7c9c1989e3d93742cfa92e0fb6e2404f35cf0ab7e4d70
@@ -1,5 +1,30 @@
1
1
  h1. News
2
2
 
3
+ h2(#release-4-0-5). 4.0.5: 2016-01-20
4
+
5
+ h3. Improvements
6
+
7
+ * Supported @unicodePwd@ in Active Directory
8
+ [GitHub#105] [Reported by Laas Toom]
9
+ * Supported Blowfish, SHA-256 and SHA-512 password hash with salt.
10
+ [GitHub#108] [Patch by Gary Richards]
11
+ * Supported Ruby 2.2.
12
+ [GitHub#115] [Reported by Jan Zikan]
13
+ [GitHub#125] [Patch by Bohuslav Blín]
14
+ * Supported Ruby 2.3.
15
+
16
+ h3. Fixes
17
+
18
+ * Fixed documentation for @rails generate@.
19
+ [GitHub#107] [Patch by Gary Richards]
20
+
21
+ h3. Thanks
22
+
23
+ * Laas Toom
24
+ * Gary Richards
25
+ * Jan Zikan
26
+ * Bohuslav Blín
27
+
3
28
  h2(#release-4-0-4). 4.0.4: 2014-10-11
4
29
 
5
30
  h3. Improvements
@@ -96,7 +96,7 @@ end
96
96
  You can also generate a Group model by the following command:
97
97
 
98
98
  <pre class="command">
99
- % script/rails generate model Group --classes PosixGroup
99
+ % script/rails generate active_ldap:model Group --classes PosixGroup
100
100
  </pre>
101
101
 
102
102
  app/model/group.rb:
@@ -55,7 +55,7 @@ module ActiveLdap
55
55
  def clear_active_connection_name
56
56
  @active_connection_name = nil
57
57
  ObjectSpace.each_object(Class) do |klass|
58
- if klass < self and !klass.name.blank?
58
+ if klass < self and !klass.name.blank? and !klass.frozen?
59
59
  klass.instance_variable_set("@active_connection_name", nil)
60
60
  end
61
61
  end
@@ -140,6 +140,8 @@ module ActiveLdap
140
140
  def read_external_file
141
141
  uri_string = @scanner.scan(URI::ABS_URI)
142
142
  raise uri_is_missing if uri_string.nil?
143
+ uri_string.chomp!
144
+
143
145
  uri = nil
144
146
  begin
145
147
  uri = URI.parse(uri_string)
@@ -441,6 +443,10 @@ module ActiveLdap
441
443
  invalid_ldif(_("URI is invalid: %s: %s") % [uri_string, message])
442
444
  end
443
445
 
446
+ def uri_is_missing
447
+ invalid_ldif(_("URI is missing"))
448
+ end
449
+
444
450
  def modify_spec_separator_is_missing
445
451
  invalid_ldif(_("'-' is missing"))
446
452
  end
@@ -5,11 +5,11 @@ module ActiveLdap
5
5
  module Railties
6
6
  module ControllerRuntime #:nodoc:
7
7
  extend ActiveSupport::Concern
8
-
8
+
9
9
  protected
10
-
10
+
11
11
  attr_internal :ldap_runtime
12
-
12
+
13
13
  def process_action(action, *args)
14
14
  # We also need to reset the runtime before each action
15
15
  # because of queries in middleware or in cases we are streaming
@@ -17,7 +17,7 @@ module ActiveLdap
17
17
  ActiveLdap::LogSubscriber.reset_runtime
18
18
  super
19
19
  end
20
-
20
+
21
21
  def cleanup_view_runtime
22
22
  if ActiveLdap::Base.connected?
23
23
  ldap_rt_before_render = ActiveLdap::LogSubscriber.reset_runtime
@@ -29,12 +29,12 @@ module ActiveLdap
29
29
  super
30
30
  end
31
31
  end
32
-
32
+
33
33
  def append_info_to_payload(payload)
34
34
  super
35
35
  payload[:ldap_runtime] = ldap_runtime
36
36
  end
37
-
37
+
38
38
  module ClassMethods
39
39
  def log_process_action(payload)
40
40
  messages, ldap_runtime = super, payload[:ldap_runtime]
@@ -191,10 +191,15 @@ module ActiveLdap
191
191
  fraction = match_data[-2]
192
192
  fraction = fraction.to_f if fraction
193
193
  time_zone = match_data[-1]
194
+ arguments = [
195
+ year, month, day, hour, minute, second, fraction, time_zone,
196
+ Time.now,
197
+ ]
198
+ if Time.method(:make_time).arity == 10
199
+ arguments.unshift(value)
200
+ end
194
201
  begin
195
- Time.send(:make_time,
196
- year, month, day, hour, minute, second, fraction,
197
- time_zone, Time.now)
202
+ Time.send(:make_time, *arguments)
198
203
  rescue ArgumentError
199
204
  raise if year >= 1700
200
205
  out_of_range_messages = ["argument out of range",
@@ -444,6 +449,25 @@ module ActiveLdap
444
449
  # String(NT-Sec-Desc) 1.2.840.113556.1.4.907
445
450
  SYNTAXES["1.2.840.113556.1.4.907"] = self
446
451
  end
452
+
453
+ class UnicodePwd < OctetString
454
+ # @see http://msdn.microsoft.com/en-us/library/cc220961.aspx
455
+ # cn: Unicode-Pwd
456
+ # ldapDisplayName: unicodePwd
457
+ # attributeId: 1.2.840.113556.1.4.90
458
+ # attributeSyntax: 2.5.5.10
459
+ # omSyntax: 4
460
+ # isSingleValued: TRUE
461
+ # schemaIdGuid: bf9679e1-0de6-11d0-a285-00aa003049e2
462
+ # systemOnly: FALSE
463
+ # searchFlags: 0
464
+ # systemFlags: FLAG_SCHEMA_BASE_OBJECT
465
+ # schemaFlagsEx: FLAG_ATTR_IS_CRITICAL
466
+ #
467
+ # @see http://msdn.microsoft.com/en-us/library/cc223177.aspx
468
+ # String(Octet) 2.5.5.10
469
+ SYNTAXES["1.2.840.113556.1.4.90"] = self
470
+ end
447
471
  end
448
472
  end
449
473
  end
@@ -5,6 +5,8 @@ require 'digest/sha1'
5
5
 
6
6
  module ActiveLdap
7
7
  module UserPassword
8
+ include GetText
9
+
8
10
  module_function
9
11
  def valid?(password, hashed_password)
10
12
  unless /^\{([A-Za-z][A-Za-z\d]+)\}/ =~ hashed_password
@@ -37,10 +39,18 @@ module ActiveLdap
37
39
  end
38
40
 
39
41
  def extract_salt_for_crypt(crypted_password)
40
- if /^\$1\$/ =~ crypted_password
41
- $MATCH + $POSTMATCH[0, 8].sub(/\$.*/, '') + "$"
42
+ if /\A\$(?:1|5|6|2a)\$[a-zA-Z0-9.\/]{,16}\$/ =~ crypted_password
43
+ $MATCH
42
44
  else
43
- crypted_password[0, 2]
45
+ salt = crypted_password[0, 2]
46
+ if salt.size != 2
47
+ raise ArgumentError, _("salt size must be 2: <%s>") % salt
48
+ end
49
+ unless /\A[a-zA-Z0-9.\/]{2}\z/ =~ salt
50
+ message = _("salt character must be [a-zA-Z0-9./]: <%s>") % salt
51
+ raise ArgumentError, message
52
+ end
53
+ salt
44
54
  end
45
55
  end
46
56
 
@@ -1,3 +1,3 @@
1
1
  module ActiveLdap
2
- VERSION = "4.0.4"
2
+ VERSION = "4.0.5"
3
3
  end
@@ -1247,6 +1247,27 @@ uid: hjensen
1247
1247
  EOL
1248
1248
  end
1249
1249
 
1250
+ def test_record_with_external_file_reference_is_invalid
1251
+ ldif_source = <<-EOL
1252
+ version: 1
1253
+ dn: cn=Horatio Jensen, ou=Product Testing, dc=airius, dc=com
1254
+ objectclass: top
1255
+ objectclass: person
1256
+ objectclass: organizationalPerson
1257
+ cn: Horatio Jensen
1258
+ sn: Jensen
1259
+ uid: hjensen
1260
+ jpegphoto:< INVALID_URI
1261
+ EOL
1262
+
1263
+ ldif_source_with_error_mark = <<-EOL
1264
+ jpegphoto:< |@|INVALID_URI
1265
+ EOL
1266
+
1267
+ assert_invalid_ldif("URI is missing",
1268
+ ldif_source, 9, 13, ldif_source_with_error_mark)
1269
+ end
1270
+
1250
1271
  def test_records_with_option_attributes
1251
1272
  ldif_source = <<-EOL
1252
1273
  version: 1
@@ -24,25 +24,107 @@ class TestUserPassword < Test::Unit::TestCase
24
24
  end
25
25
  end
26
26
 
27
- def test_crypt
28
- salt = ".WoUoU9f3IlUx9Hh7D/8y.xA6ziklGib"
29
- assert_equal("{CRYPT}.W57FZhV52w0s",
30
- ActiveLdap::UserPassword.crypt("password", salt))
31
-
32
- password = "PASSWORD"
33
- hashed_password = ActiveLdap::UserPassword.crypt(password)
34
- salt = hashed_password.sub(/^\{CRYPT\}/, '')
35
- assert_equal(hashed_password,
36
- ActiveLdap::UserPassword.crypt(password, salt))
37
- end
27
+ sub_test_case("crypt") do
28
+ def test_encrypt
29
+ salt = ".WoUoU9f3IlUx9Hh7D/8y.xA6ziklGib"
30
+ assert_equal("{CRYPT}.W57FZhV52w0s",
31
+ ActiveLdap::UserPassword.crypt("password", salt))
32
+
33
+ password = "PASSWORD"
34
+ hashed_password = ActiveLdap::UserPassword.crypt(password)
35
+ salt = hashed_password.sub(/^\{CRYPT\}/, '')
36
+ assert_equal(hashed_password,
37
+ ActiveLdap::UserPassword.crypt(password, salt))
38
+ end
38
39
 
39
- def test_extract_salt_for_crypt
40
- assert_extract_salt(:crypt, "AB", "ABCDE")
41
- assert_extract_salt(:crypt, "$1", "$1")
42
- assert_extract_salt(:crypt, "$1$$", "$1$")
43
- assert_extract_salt(:crypt, "$1$$", "$1$$")
44
- assert_extract_salt(:crypt, "$1$abcdefgh$", "$1$abcdefgh$")
45
- assert_extract_salt(:crypt, "$1$abcdefgh$", "$1$abcdefghi$")
40
+ sub_test_case("extract_salt") do
41
+ sub_test_case("base format") do
42
+ def test_less
43
+ message = "salt size must be 2: <a>"
44
+ assert_raise(ArgumentError.new(message)) do
45
+ extract_salt(:crypt, "a")
46
+ end
47
+ end
48
+
49
+ def test_exact
50
+ assert_extract_salt(:crypt, "ab", "ab")
51
+ end
52
+
53
+ def test_more
54
+ assert_extract_salt(:crypt, "ab", "abc")
55
+ end
56
+ end
57
+
58
+ sub_test_case("glibc2 format") do
59
+ sub_test_case("ID") do
60
+ def test_md5
61
+ assert_extract_salt(:crypt, "$1$abcdefgh$", "$1$abcdefgh$")
62
+ end
63
+
64
+ def test_blowfish
65
+ assert_extract_salt(:crypt, "$2a$abcdefgh$", "$2a$abcdefgh$")
66
+ end
67
+
68
+ def test_sha256
69
+ assert_extract_salt(:crypt, "$5$abcdefgh$", "$5$abcdefgh$")
70
+ end
71
+
72
+ def test_sha512
73
+ assert_extract_salt(:crypt, "$6$abcdefgh$", "$6$abcdefgh$")
74
+ end
75
+ end
76
+
77
+ sub_test_case("salt") do
78
+ def test_not_teminated
79
+ message = "salt character must be [a-zA-Z0-9./]: <$1>"
80
+ assert_raise(ArgumentError.new(message)) do
81
+ extract_salt(:crypt, "$1$")
82
+ end
83
+ end
84
+
85
+ def test_empty
86
+ assert_extract_salt(:crypt, "$1$$", "$1$$")
87
+ end
88
+
89
+ def test_lower_case
90
+ assert_extract_salt(:crypt, "$1$abc$", "$1$abc$")
91
+ end
92
+
93
+ def test_upper_case
94
+ assert_extract_salt(:crypt, "$1$ABC$", "$1$ABC$")
95
+ end
96
+
97
+ def test_digit
98
+ assert_extract_salt(:crypt, "$1$012$", "$1$012$")
99
+ end
100
+
101
+ def test_dot
102
+ assert_extract_salt(:crypt, "$1$...$", "$1$...$")
103
+ end
104
+
105
+ def test_slash
106
+ assert_extract_salt(:crypt, "$1$///$", "$1$///$")
107
+ end
108
+
109
+ def test_mix
110
+ assert_extract_salt(:crypt, "$1$aA0./$", "$1$aA0./$")
111
+ end
112
+
113
+ def test_max
114
+ assert_extract_salt(:crypt,
115
+ "$1$0123456789abcdef$",
116
+ "$1$0123456789abcdef$")
117
+ end
118
+
119
+ def test_over
120
+ message = "salt character must be [a-zA-Z0-9./]: <$1>"
121
+ assert_raise(ArgumentError.new(message)) do
122
+ extract_salt(:crypt, "$1$0123456789abcdefg$")
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
46
128
  end
47
129
 
48
130
  def test_md5
@@ -94,10 +176,12 @@ class TestUserPassword < Test::Unit::TestCase
94
176
  end
95
177
 
96
178
  private
179
+ def extract_salt(type, hashed_password)
180
+ ActiveLdap::UserPassword.send("extract_salt_for_#{type}",
181
+ hashed_password)
182
+ end
97
183
  def assert_extract_salt(type, expected, hashed_password)
98
- actual = ActiveLdap::UserPassword.send("extract_salt_for_#{type}",
99
- hashed_password)
100
- assert_equal(expected, actual)
184
+ assert_equal(expected, extract_salt(type, hashed_password))
101
185
  end
102
186
 
103
187
  def encode64(string)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeldap
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.4
4
+ version: 4.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Will Drewry
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-10-11 00:00:00.000000000 Z
12
+ date: 2016-01-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel
@@ -347,7 +347,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
347
347
  version: '0'
348
348
  requirements: []
349
349
  rubyforge_project: ruby-activeldap
350
- rubygems_version: 2.2.2
350
+ rubygems_version: 2.4.5.1
351
351
  signing_key:
352
352
  specification_version: 4
353
353
  summary: ActiveLdap is a object-oriented API to LDAP