-
Notifications
You must be signed in to change notification settings - Fork 252
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for rfc3062 Password Modify, closes #163 #178
Conversation
@mynameisrufus thanks for creating this PR. One of us will take a look when we free up a bit, possibly tomorrow. |
@@ -31,4 +31,5 @@ the most recent LDAP RFCs (4510-4519, plutions of 4520-4532).} | |||
|
|||
s.add_development_dependency("flexmock", "~> 1.3") | |||
s.add_development_dependency("rake", "~> 10.0") | |||
s.add_development_dependency("pry") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👎 as much as I like pry
, I don't think this is a necessary development dependency.
Thanks for submitting this! My only gripe would be the Caveat lector: I'm not intimately familiar with extended operations and how other APIs implement this. From taking a quick look at the Perl Net::LDAP library, its API is different enough such that returning a message object that responds to |
Thanks for the great feedback, agree on all points. |
return if pdu && pdu.app_tag == tag | ||
raise Net::LDAP::LdapError, 'response missing or invalid' | ||
end | ||
private :assert_response! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 to this abstraction.
Couple of nitpicks:
- What's your reasoning for adding the
!
inassert_response!
? - Minitest assertions typically have the expected value as the first argument, and the subject under test as the 2nd. It'd be good to flip the order of your argument list to match unless there's a good reason otherwise.
- Rather than raise an exception, you can use
flunk
with a descriptive message. Something like:
unless pdu && pdu.app_tag == tag
flunk "Expected #{tag.inspect}, but got #{(pdu && pdu.app_tag).inspect}"
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jch this is a runtime assertion, not in test. We were already enforcing this assertion, but it was repeated everywhere, hence the abstraction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aaah, sorry. My brain automatically assumed it was a test helper. I guess the bang !
is because it raises an exception.
Rebased with feedback changes made, I have left the extended response a little raw as I think migrating to a better approach would require drastic changes like you said. Supporting auto generated password is a bit of a cherry on top anyway, I actually don't need it but figured implementing the entire operation as per the spec would be a win. ldap.get_operation_result.extended_response[0][0] #=> 'VtcgGf/G' If I get time I will look around at other libs an see what a good way of doing this would be, maybe open a separate PR.... |
Any chance of getting this merged? |
@mynameisrufus I'm really only blocked on researching the |
I have moved the the value from primitive into I could be wrong but other libs I have been reading do not really concern themselves with these types, they work more along the line of (python3-ldap): o = ModifyPassword.new(connection, options)
o.result #=> '2ex7c3' Here it just assumes it's getting back a sequence? |
I have captured a response from wireshark: decode = ->(str) { str.split(':').map(&:hex).map(&:chr).join }
data = '30:1a:02:01:02:78:15:0a:01:00:04:00:04:00:8b:0c:30:0a:80:08:66:47:6d:63:75:62:34:71'
str = decode.call(data)
str #=> "0\x1A\x02\x01\x02x\x15\n\x01\x00\x04\x00\x04\x00\x8B\f0\n\x80\bfGmcub4q"
bytes = []
io = StringIO.new(str)
while byte = io.getbyte
bytes << byte
end
bytes #=> [48, 26, 2, 1, 2, 120, 21, 10, 1, 0, 4, 0, 4, 0, 139, 12, 48, 10, 128, 8, 102, 71, 109, 99, 117, 98, 52, 113]
139.chr #=> "\x8B" |
@mtodd looks like unicode 139, 008B is https://github.com/osstech-jp/openldap/blob/master/libraries/liblunicode/UnicodeData.txt#L140 The response should look like this:
I'm having trouble actually printing that out properly in irb 😞 |
@@ -309,7 +309,14 @@ class Net::LDAP | |||
:constructed => constructed, | |||
} | |||
|
|||
universal = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mtodd I have moved the value into universal, context specific constructed will not work because it starts at 160 and it's not a primitive.
To be honest I don't know why this stuff is written the way it is when all that is resulted is an array with 256 length with values at index with the types, why not just one simple flat dict.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mynameisrufus I agree 100% that the parsing behavior needs to be refactored.
I'm uncomfortable accepting this as is without a better understanding of the specific value we're adding here. This change doesn't align with my understanding of the ExtendedResponse
mechanics. I don't want to accept something that makes it work but isn't clear why because it will likely have unintended/unaccounted for consequences.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean by 'specific value'?, to me the specific value is in the title of the PR, support for modify password http://tools.ietf.org/html/rfc3062.
What is your understanding of the mechanics of ExtendedResponse
, if you could share with me your understanding I would be happy to make changes to this PR.
I have invested considerable time in understanding this codebase and have addressed every point raised by yourself and @jch. I have sniffed packets, groked Open LDAP source and the source of many other libs in order to comprehensively document and explain each change I have made, I am committed to delivering this feature and like I said, I am happy to address any concerns you have or explain the workings of LDAP or this library. I fully understand that you have inherited this codebase so I understand the fear you may have in accepting changes to this lib.
This implements the password modify extended request http://tools.ietf.org/html/rfc3062
Support for rfc3062 Password Modify, closes #163
@mynameisrufus thanks for following through on this PR. I think you did a great job addressing all of our concerns. There's more cleanup we could do to the general API, but that's out of scope for your changes, and I think this feature has merit on it's own. I just released 0.13.0, so I will wait a bit in case there are other PR's to merge before cutting a new release. Thanks! |
@jch happy new year and thank you. |
=== Net::LDAP 0.14.0 * Normalize the encryption parameter passed to the LDAP constructor {#264}[ruby-ldap/ruby-net-ldap#264] * Update Docs: Net::LDAP now requires ruby >= 2 {#261}[ruby-ldap/ruby-net-ldap#261] * fix symbol proc {#255}[ruby-ldap/ruby-net-ldap#255] * fix trailing commas {#256}[ruby-ldap/ruby-net-ldap#256] * fix deprecated hash methods {#254}[ruby-ldap/ruby-net-ldap#254] * fix space after comma {#253}[ruby-ldap/ruby-net-ldap#253] * fix space inside brackets {#252}[ruby-ldap/ruby-net-ldap#252] * Rubocop style fixes {#249}[ruby-ldap/ruby-net-ldap#249] * Lazy initialize Net::LDAP::Connection's internal socket {#235}[ruby-ldap/ruby-net-ldap#235] * Support for rfc3062 Password Modify, closes #163 {#178}[ruby-ldap/ruby-net-ldap#178]
This implements the password modify extended request
http://tools.ietf.org/html/rfc3062
Change existing password:
Or get the LDAP server to generate a password for you: