Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Fixes #21605 - more authorization options #639

Merged
merged 1 commit into from
Mar 8, 2019

Conversation

iNecas
Copy link
Member

@iNecas iNecas commented Mar 5, 2019

Before this change, when using authorization helpers, one got all or
nothing, without any chance to use the authorization just of a subset of
the requests.

This patch introduces Sinatra::Authorization::Helpers that provide
do_authorize* methods that are not wrapped in the before block. so that
they their usage is more flexible.

There are at least 3 places I know of that would benefit from this change:

iNecas added a commit to mvollmer/smart_proxy_remote_execution_ssh that referenced this pull request Mar 5, 2019
Since the `/pubkey` endpoint is not authorized, we need to add an ability
to smart proxy theforeman/smart-proxy#639 and
then we can use `do_authorize` method at the beginning of our protected
method.
Copy link
Member

@ares ares left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

works well, makes sense, just one suggestion for name but I don't insist, let me know what you think

@@ -40,6 +55,27 @@ def authorize_with_ssl_client
end
end

# Common set of authorization methods used in foreman-proxy
def do_authorize
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perform_authorization perhaps?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've seen some old code of mine, so you know I don't mind long names, but I still, prefer a bit shorter variant:

["do_authorize_with_ssl_client", "perform_authorization_with_ssl_client"].map(&:size)
=> [28, 37]

Let's see if there is anyone else that would choose what version is better?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm I kinda don't like this very generic do_authorize because it does not tell anything about how the authorization is performed. I suggest do_authorize_any because basically this is the actual semantics.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to do_authorize_any

@lzap
Copy link
Member

lzap commented Mar 7, 2019

Works for me. Rubocop failed.

@iNecas
Copy link
Member Author

iNecas commented Mar 7, 2019

Rubocop failures unrelated

require 'json'
require 'sinatra/base'

ENV['RACK_ENV'] = 'test'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've seen this in multiple places, but the test_helper also sets this. Isn't it really redundant?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed and seemed it still worked. Also removed the require 'json' as we didn't need it actually

get '/public'
assert last_response.ok?
get '/private'
assert last_response.ok?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is interesting and not something I thought about. We added the v2 features endpoint in root, but I suspect that's exposed over https without authentication. Perhaps we need some authentication method that enforces some authentication.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having tested this: this relies on localhost being in the trusted_hosts. On a HTTP call it uses reverse DNS + forward DNS. This isn't very secure but since the default deployment only enabled modules on HTTP when they are designed to assume no security it's not that big of a deal.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is how it have been done for a while: using authenticated http is not very secure and people should count on it. Anyway, not trying to address it here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think it would be good to capture this in a test. Perhaps set the trusted hosts to empty or something different and assert that the response it not ok? Could be separate tests.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The subject of this test is ensuring the authorization helpers are available. I'm not touching the authorization algorigth itself, and the tests for it are somewhere else: I would prefer keeping this PR focused on thing only: which is making the methods available outside of the before filters, that right now we are constraint with.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, more tests is good but I want this to be merged ASAP, let's improve somewhere else.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My argument was that if the response is ok, you still don't really know if the authorization was properly called.


before do
def do_authorize_with_trusted_hosts
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you add the do_ prefix to it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to make it different than already existing methods: I don't like to have methods with the same name doing a bit different thing

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I missed that it's the helpers module vs methods on the higher level. This part of Ruby is still rather new to me.

Before this change, when using authorization helpers, one got all or
nothing, without any chance to use the authorization just of a subset of
the requests.

This patch introduces `Sinatra::Authorization::Helpers` that provide
`do_authorize*` methods that are not wrapped in the before block. so that
they their usage is more flexible.
Copy link
Member

@lzap lzap left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am good, works fine. Thanks.

@lzap lzap merged commit 56f9095 into theforeman:develop Mar 8, 2019
@@ -40,6 +55,27 @@ def authorize_with_ssl_client
end
end

# Common set of authorization methods used in foreman-proxy
def do_authorize_any
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO any is a bit ambiguous. Any could also mean authorized any client without authentication. Perhaps do_authorize_any_method would be clearer but naming is hard.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I was thinking maybe do_authorize_all because we actually do not authorize but rather refuse unauthorized requests (the opposite). It's complicated, I was thinking like any reads a bit cleaner in a sense "any method will do it".

# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants