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

[#153072577] First steps to admin app: Base rails app with OAuth #1

Merged
merged 40 commits into from
Dec 14, 2017

Conversation

chrisfarms
Copy link
Contributor

@chrisfarms chrisfarms commented Dec 7, 2017

What

We're building a web UI for the paas.

This is the first steps to that end:

  • A base Rails app to build upon
  • Login/Authentication via UAA/OAuth
  • A basic CF API Client
  • A page that lists org names as an example
  • Some tests

How to review

Who can review

Not @chrisfarms nor @henrytk nor @camelpunch nor @carolinegreen

Caroline Green and others added 21 commits December 4, 2017 12:05
--skip-turbolinks
--skip-test
--skip-active-record
--skip-coffee paas-admin
Choose two instances and 256M for now
Add rspec and pry-byebug

We expect that org listing will eventually move to e.g. /orgs
This means that every action (except excluded sessions controller)
requires auth.
It's a global configuration, so the aim of this line is to tidy up, not
set up.
Capybara follows redirects automatically, behaves more like a user.
This removes a warning about OpenSSL::Digest::Digest being deprecated
Remove logging output from test
Reset global state after each example
Fake and real implementations. Fake stores state in memory. Real
currently is a no-op. Shared examples to ensure they're in sync.
Without this change, bundler generate bad binstubs that don't accept
arguments.

Upstream issue: rubygems/bundler#6149
@chrisfarms chrisfarms changed the title WIP [#153072577] First steps to admin app: Base rails app with OAuth [#153072577] First steps to admin app: Base rails app with OAuth Dec 7, 2017
@dcarley
Copy link
Contributor

dcarley commented Dec 8, 2017

I've enabled Travis for this repo and triggered a build through their admin UI.

@dcarley dcarley self-assigned this Dec 8, 2017
@chrisfarms
Copy link
Contributor Author

chrisfarms commented Dec 8, 2017

I have added a .travis.yml that should trigger the (non-integration) tests.

...but travis seems confused and is running against master?

@chrisfarms
Copy link
Contributor Author

Ignore that. Travis seems to have fixed itself.

Copy link
Contributor

@dcarley dcarley left a comment

Choose a reason for hiding this comment

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

Works 👍

I've left some minor comments and questions.

I like the structure of the commits. Reading them through one-by-one helped me understand it a bit more, even if some code was replaced in later commits. Though as someone that hasn't developed a Rails app for scratch before I would have liked a bit more description of "why" in the commit messages to describe the reason for changes.

I feel a bit nervous that, although I understand the basics of what authentication and validation is being done, I haven't reviewed the code for scenarios where it might be bypassed or broken. Should we? How can we?

'/oauth/authorize',
"?client_id=#{ENV.fetch('OAUTH_CLIENT_ID')}",
'&response_type=code',
"&redirect_uri=#{CGI.escape("http://example.org/auth/cloudfoundry/callback")}",
Copy link
Contributor

Choose a reason for hiding this comment

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

Where does http://example.org/ come from?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We discarded this technique for testing the auth once we realized all we were testing was OmniAuth and that it was near imposible to test without mocking UAA too .... we then found OmniAuth has some documented ways of mocking the auth and used that method instead.

Essentially we trust that OmniAuth works and currently have no integration tests to prove that (once we have a CI build pipeline we would probably want to add those sorts of integration/acceptance tests).

Copy link
Contributor

Choose a reason for hiding this comment

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

To answer @dcarley's question: it's the default 'fake' app host that rack-test uses.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks and thanks 👍

@@ -1,5 +1,5 @@
class OrgsController < ApplicationController
def index
redirect_to Rails.configuration.x.oauth.redirect_url
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we set this config option to '/auth/cloudfoundry' and continue using it?

Copy link
Contributor

Choose a reason for hiding this comment

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

(this change has been rebased away)

Gemfile Outdated
@@ -10,7 +10,7 @@ end
gem 'rails', '~> 5.1.4'
gem 'puma', '~> 3.7'
gem 'uglifier', '>= 1.3.0'
gem 'omniauth-uaa-oauth2'
gem 'omniauth-uaa-oauth2', github: 'cloudfoundry/omniauth-uaa-oauth2'
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we be concerned that subsequent versions (up to 0.0.6) haven't been released to https://rubygems.org/ or that a relatively simple PR to merge a deprecated warning (cloudfoundry/omniauth-uaa-oauth2#9) hasn't been merged?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is concerning. We should complain, or do a spike into using vanilla oauth with https://github.com/omniauth/omniauth-oauth2

Copy link
Contributor

Choose a reason for hiding this comment

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

I hadn't notice this before, which is more concerning: cloudfoundry/omniauth-uaa-oauth2#10

@alext any thoughts? Should we merge this as-is and have a story to look at changing it afterwards?

Copy link
Contributor

Choose a reason for hiding this comment

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

@camelpunch @alext and I talked about this: we decided to leave it as-is for this PR and @camelpunch will write a follow-up story to investigate omniauth/omniauth-oauth2.

</head>

<body>
<img src="https://static1.squarespace.com/static/59698a7d29687fd47a2a7c52/599a2c9837c581a0f21a7030/5998fbff17bffc5c4b7d0f04/1503700549384/construction_worker.jpg" border="0" width="125">
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we vendor this rather than hotlink?

Copy link
Contributor

Choose a reason for hiding this comment

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

👍 We should be hosting that ourselves - makes us better Internet citizens, and also we can't be sure of the longevity of that link etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I love your optimism that Construction Duck will last persist long enough to be worried about this.

.envrc Outdated
export CF_AUTH_ENDPOINT=$(cf curl /v2/info | jq -r .authorization_endpoint)
export CF_TOKEN_ENDPOINT=$(cf curl /v2/info | jq -r .token_endpoint)
export CF_CLIENT_ID="paas-admin"
export CF_CLIENT_SECRET=$(aws s3 cp s3://gds-paas-${DEPLOY_ENV}-state/cf-secrets.yml - | awk '/uaa_clients_paas_admin_secret/ { print $2 }')
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we include things that are so specific to our development environments? Do we want other people to use the app in the future?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have mixed feelings.

Setting up these variables for running in dev is painful. But I understand this is so specific to us that would be annoying for outsiders.

Henry created some scripts for running (to replace/augment .envrc) ... maybe we should document the "standard" way ie CF_AUTH_ENDPOINT=xx CF_TOKEN_ENDPOINT=yy rails s in the README for all to enjoy ... but then have some additional documentation for paas-specific-ness?

Copy link
Contributor

Choose a reason for hiding this comment

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

That sounds good. I definitely appreciated having an easy way to run it against my dev environment, but I think it would be easier to understand if we provided generic instructions foremost.

bin/bundle Outdated
@@ -1,3 +1,105 @@
#!/usr/bin/env ruby
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you know why we need a binstub for Bundler?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

something something bug in bundler todo with binstubs .... /cc @camelpunch

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't know why bundler (or Rails) introduced a binstub for bundler itself. I assume it's to lock the version of bundler for the app.

The bug that @chrisfarms is referring to is here, but not sure if this is related to the question: rubygems/bundler#6149

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm inclined to delete it rather than worry about when we can update/remove the backported fix. It doesn't seem as important the rails binstub, which appears to be a standard for Rails apps.

Copy link
Contributor

Choose a reason for hiding this comment

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

The fix was primarily for stubs like rspec, which are used a lot. I think the only risk here is if someone:

a) Decides to run e.g. bundle binstubs rspec-core and
b) Commits the change

Otherwise if we're concerned about bundler versions, we should downgrade to 1.15, as one of the comments on the Rails bug thread suggested, because 1.15 doesn't generate incompatible binstubs by default (1.16 is fine if you also supply --force)

@chrisfarms chrisfarms force-pushed the uaa-auth-153072577 branch 3 times, most recently from f0ac730 to 95f450e Compare December 12, 2017 11:00
chrisfarms added 7 commits December 12, 2017 15:38
By default rubocop is a tad overzealous.  We use the config from the
govuk-lint[1] repo to rein it in a bit and we expect to modify it to our
liking over time.

Rubocop version is pinned in Gemfile as recormended and binstubs are
generated.

We exclude the 'bin/*' dir since files generated there are generally out
of our control.

[1] https://github.com/alphagov/govuk-lint

fixup: add rubocop/gem/binstubs/exclude-bindir

fixup: add rubocop/gem/binstubs/exclude-bindir

rubocop binstub
api_endpoint is ambiguous. Rename to cf_api_endpoint to avoid confusion.
The main change here is preventing RSpec monkey-patching the environment
which means `describe` blocks must be namespaced correctly.

The state file is also configured now so is added to the gitignore.
* Autocorrections
  Many style fixes applied by executing `./bin/rubocop -a`
* Rubocop says: no-class-vars
  Class vars can be confusing when combined with inheritance[1] so prefur
  class-instance variables instead.
* Rubocop says: use Rails.root.join('path', 'to')
  The point of path join methods is to avoid hardcoding path seperators
  which are platform dependent.
* Rubocop says: Avoid using Time without time zone
  Using time without specifying a timezone can lead to confusion, so use
  ActiveSupport's Time.zone extension by setting config.time_zone to a
  known value and only requesting/parsing Time values via Time.zone
  Use Time.now.to_i or Time.zone.now

[1] https://github.com/bbatsov/ruby-style-guide#no-class-vars
Adds a new "design" environment mode for when you just want to run the
app without requiring a real cloudfoundry deployment with real cloud
controller access, uaa clients etc.

In this mode:

* Authentication is bypassed (OmniAuth test mode enabled)
* The FakeClient implementation is used for cf communication
* Some fixtures are populated (see design.rb)

This is useful if you are just working on styling or other tasks.
chrisfarms added 2 commits December 12, 2017 16:23
Previously we had some .envrc magic and some scripts for running the app
against a paas-cf dev environment and the README was geared towards
this.

We want to try to stay a little more agnostic about who might be running
this (even if it is just us for now).

So we will favour adding more generic instructions to the README along
with outling the scripts for how to get up and running quickly with
GOV.UK PaaS
It's a pain to have to set all the environment config to junk values
when you only want to run unit tests.

This sets all the required vars to "none" unless the CONTRACT_TEST_TOKEN
is set (which is what triggers integration test execution)
Copy link
Contributor

@dcarley dcarley left a comment

Choose a reason for hiding this comment

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

Just one request and then this is good to :shipit:

Gemfile Outdated
gem 'listen', '>= 3.0.5', '< 3.2'
gem 'rubocop', '~> 0.51.0', require: false
Copy link
Contributor

Choose a reason for hiding this comment

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

We should use govuk-lint as a gem and govuk-lint-ruby as the command, because then we don't need to vendor all of it's .rubocop.yml and it will get updated when we pull in new versions of the gem.

You can refer to alphagov/paas-cf for an example:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure if that's the best move tbh. I can see two issues with that:

  1. Anyone who has an editor/plugin that does rubocop linting for them would not understand the "govuk-lint-ruby" command and would expect to find the rubocop.yml file in the root. I find it very useful to get the cop feedback as I'm typing and it would be a real shame to lose that.

  2. The govuk-lint version is not a perfect fit... I had to enable the rails specific cops and had to modify the include/excludes to ensure that certain cops are excluded from some rails specific files (large blocks in environment configs are expected for one) and needed to exclude the vendor dir so travis didnt attempt to lint the entire vendor bundle.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

... just talking with @alext ... we think we can have our cake and eat it ... investigating

Copy link
Contributor

Choose a reason for hiding this comment

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

The README says that there's a -R flag to enable Rails cops:

I think it's worth trying to find solutions to because people have already done the hard work of maintaining an acceptable config ❤️

Copy link
Contributor Author

Choose a reason for hiding this comment

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

🙌 ...sorted!

Found a way to inherit the config from the govuk-lint gem so that standard rubocop commands work as expected and we get the best of both worlds.

chrisfarms added 2 commits December 14, 2017 12:14
By inheriting rubocop configuration from the govuk-lint gem we can stay
in sync with upstream changes by updating the gem.

We extend the base config to enable the Rails and Rspec cops then rein
in the Rspec cops a bit as they are a bit too agressive by default.

The large-block cop is excluded from the rails config dir since it is
expected to always have large blocks.
Some tweaks at the request of rubocop
@dcarley
Copy link
Contributor

dcarley commented Dec 14, 2017

Nice!! Thanks 👍

@dcarley dcarley merged commit 9852b69 into master Dec 14, 2017
@paroxp paroxp deleted the uaa-auth-153072577 branch March 20, 2018 15:49
@paroxp paroxp restored the uaa-auth-153072577 branch March 20, 2018 15:49
@paroxp paroxp deleted the uaa-auth-153072577 branch March 23, 2018 16:31
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.

5 participants