Skip to content
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

Add login page route for auth0 #718

Merged
merged 2 commits into from
Sep 8, 2023
Merged

Add login page route for auth0 #718

merged 2 commits into from
Sep 8, 2023

Conversation

wi11
Copy link
Contributor

@wi11 wi11 commented Jun 21, 2023

With this change, we can access the login page at /auth/auth0. After login, we are successfully redirected to the callback page which i just set as /api-docs for now.

Copy link
Member

@richardxia richardxia left a comment

Choose a reason for hiding this comment

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

Thanks for submitting this, and sorry for the late review! I haven't reviewed the OmniAuth gem or Auth0's docs, but I left initial some comments purely about the code itself.

I think there are probably a few questions that we may need to answer regarding how we want dev environments to work, and how this gets wired up in prod, but we probably need another group discussion about that.

@@ -44,6 +44,9 @@ class Application < Rails::Application
# rubocop:enable Layout/LineLength
config.x.authorization.cert = OpenSSL::X509::Certificate.new(pem)

config.middleware.use ActionDispatch::Cookies
config.middleware.use ActionDispatch::Session::CookieStore, key: '_namespace_key'
Copy link
Member

Choose a reason for hiding this comment

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

What exactly is this used for? It's not obvious how this interacts with the other stuff in this PR, and if it's something that the omniauth gem implicitly depends on, it'd be good to document it with a comment.

Also, does the key really need to be named _namespace_key? Is it possible to give it a more descriptive name?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is required to use omniauth, added a comment. Also changed the key to 'sheltertech'

@@ -0,0 +1,31 @@
# ./app/controllers/auth0_controller.rb
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Could we remove comments like this? I'm not sure if it's really helpful to have a comment at the top of each file with the file's path.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment on lines 4 to 9
redirect_to(
"https://#{AUTH0_CONFIG['auth0_domain']}/authorize?" +
"client_id=#{AUTH0_CONFIG['auth0_client_id']}&" +
"response_type=code&" +
"redirect_uri=#{URI.encode(auth_auth0_callback_url)}"
)
Copy link
Member

Choose a reason for hiding this comment

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

It'll be safer and cleaner to build this URL programmatically rather than by concatenating and interpolating strings. See https://stackoverflow.com/a/33257393, but you can use a combination of Ruby's URI::HTTPS.build method along with Rails' #to_query method that they monkeypatch onto the Hash class. #to_query also handles URI encoding, so you won't need to explicitly do that here, either.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -0,0 +1,31 @@
# ./app/controllers/auth0_controller.rb
class Auth0Controller < ApplicationController
def authentication
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Rails controller methods are generally named as verbs, e.g. create, update, etc. Could this be renamed to authenticate?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Copy link
Member

Choose a reason for hiding this comment

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

Nit: Could this be renamed to auth_controller.rb, and the class renamed to AuthController? Even though this is tightly coupled to the Auth0 service, it'll make it easier to navigate the Rails app if the controller name matches the URL route name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

config/auth0.yml Outdated
Comment on lines 1 to 6
development:
auth0_client_id: <%= ENV["AUTH0_CLIENT_ID"] %>
auth0_client_secret: <%= ENV["AUTH0_CLIENT_SECRET"] %>
auth0_domain: <%= ENV["AUTH0_DOMAIN"] %>
test:
auth0_client_id: <%= ENV["AUTH0_CLIENT_ID"] %>
Copy link
Member

Choose a reason for hiding this comment

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

Would it be possible to do this more like our other environment variables, which are read in from config/application.rb?

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like we also set some config values that are specific to our dev, test, prod environments here: config/environments.rb

EDIT: I also see a database.yml file in the config directory. Looks like we are using a few different patterns for defining ENV vars

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

# ./config/initializers/auth0.rb
AUTH0_CONFIG = Rails.application.config_for(:auth0)

Rails.application.config.middleware.use OmniAuth::Builder do
Copy link
Member

Choose a reason for hiding this comment

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

We should decide on how we want to support this for development, testing, and production environments, but if we decide to not have Auth0 enabled for development environments, we should guard all of this with a check to see whether the Auth0 integration should be enabled. You can see how we do this for other external integrations, but they generally involve checking an enabled attribute on something configured on the Rails.application.config object.

config/routes.rb Outdated
Comment on lines 82 to 85
get 'auth/auth0', to: 'auth0#authentication', as: :authentication
get '/auth/failure' => 'auth0#failure'
get '/auth/logout' => 'auth0#logout'
get '/auth/auth0/callback' => 'auth0#callback'
Copy link
Member

Choose a reason for hiding this comment

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

Could you group all the routes with the same prefix under the same block? I think you can either do this with a resources call, where you set the only keyword argument to the empty list to block the creation of the usual CRUD routes, or you may be able to do this with a namespace call. I think the resources call may be preferable, since you should be able declare that all the nested routes are associated with the same Auth0Controller and not have to explicitly declare that with each route.

I haven't tested it, but I think it would look like the following:

Suggested change
get 'auth/auth0', to: 'auth0#authentication', as: :authentication
get '/auth/failure' => 'auth0#failure'
get '/auth/logout' => 'auth0#logout'
get '/auth/auth0/callback' => 'auth0#callback'
resources :auth, controller: 'auth0' do
get :auth0, to: 'auth0#authentication', as: :authentication
get :failure
get :logout
get 'auth0/callback' => 'auth0#callback'
end

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -56,3 +56,6 @@ end

gem 'pdfcrowd'
gem 'google-cloud-translate'

gem 'omniauth-auth0', '~> 3.0'
gem 'omniauth-rails_csrf_protection', '~> 1.0' # prevents forged authentication requests
Copy link
Member

Choose a reason for hiding this comment

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

Do we need this for SPAs? I'm not actually even sure how we can make this work with our app, since we would need a way to extract the CSRF token from the API responses in our client-side app.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was part of the example code, i can try it without and see if it works.

Copy link
Contributor

@schroerbrian schroerbrian left a comment

Choose a reason for hiding this comment

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

Thanks for the contribution, Will! Looking mostly good to me. Thanks again for getting this started.

config/auth0.yml Outdated
Comment on lines 1 to 6
development:
auth0_client_id: <%= ENV["AUTH0_CLIENT_ID"] %>
auth0_client_secret: <%= ENV["AUTH0_CLIENT_SECRET"] %>
auth0_domain: <%= ENV["AUTH0_DOMAIN"] %>
test:
auth0_client_id: <%= ENV["AUTH0_CLIENT_ID"] %>
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like we also set some config values that are specific to our dev, test, prod environments here: config/environments.rb

EDIT: I also see a database.yml file in the config directory. Looks like we are using a few different patterns for defining ENV vars

)
end

def callback
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like these subsequent method definitions have extra indentation. The linting tests seem to have caught this as well. If you run bundle exec rake rubocop in the app directory, it will point you to any syntactical issues with the new code

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oops fixed!

@lgarofalo
Copy link
Member

With this change, we can access the login page at /auth/auth0. After login, we are successfully redirected to the callback page which i just set as /api-docs for now.

We can access /auth/auth0 on the api server via the frontend path /api/auth/auth0, this seems to work by default, so if we were to deploy this, we would need no other changes to access it in staging.

Example from dev

askdarcel-api-api-1  | /usr/src/app/app/controllers/auth0_controller.rb:8: warning: URI.escape is obsolete
askdarcel-api-api-1  | method=GET path=/auth/auth0 format=html controller=Auth0Controller action=authentication status=302 duration=2.22 view=0.00 db=0.00 location=https:///authorize

@lgarofalo
Copy link
Member

If we need to hush up robocop linting, we can do that, some examples are in the codebase, we can also add to .rubocop.yaml

@lgarofalo
Copy link
Member

Seems good to me for testing, we'll need to make sure the env configs are wired in properly and I can add those to staging in advance if you share with me what key/values to use.

@richardxia
Copy link
Member

If we need to hush up robocop linting, we can do that, some examples are in the codebase, we can also add to .rubocop.yaml

I would strongly request that we don't silence these lint failures; they're due to inconsistently indenting sibling methods with both 2 and 4 spaces. I would really prefer that all methods in the same scope be indented by the same amount (and I would also really prefer consistently using the same indentation style for the entire codebase).

With this change, we can access the login page at /auth/auth0. After login, we are successfully redirected to the callback page which i just set as /api-docs for now.
@wi11 wi11 closed this Sep 8, 2023
@wi11 wi11 reopened this Sep 8, 2023
@wi11 wi11 merged commit 35db181 into master Sep 8, 2023
8 checks passed
@wi11 wi11 deleted the auth0 branch September 8, 2023 21:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants