Skip to content
Browse files

Only allow users with "signin" permission to login

Previously, AuthWrapper allowed any authenticated user to log in, meaning that
the "can sign in?" checkbox in signon didn't do anything. This commit makes
AuthWrapper pay attention to the "permissions" object in the OAuth payload, and
denies access to users without the appropriate permission.

Also add some tests for AuthWrapper that use Rack::Test.
  • Loading branch information...
1 parent 5c5f057 commit c6f98593effa71f20e5f9f17d22d93c23d9cefe4 @nickstenning nickstenning committed
Showing with 86 additions and 4 deletions.
  1. +4 −0 Gemfile
  2. +3 −0 Gemfile.lock
  3. +5 −0 jenkins.sh
  4. +13 −4 lib/authwrapper.rb
  5. +61 −0 test/test_authwrapper.rb
View
4 Gemfile
@@ -3,3 +3,7 @@ source "http://rubygems.org"
gem 'omniauth-gds', :git => 'git@github.com:alphagov/omniauth-gds.git'
gem 'kibana', :git => 'git@github.com:alphagov/Kibana.git', :branch => 'kibana-ruby'
gem 'unicorn'
+
+group :development do
+ gem 'rack-test'
+end
View
3 Gemfile.lock
@@ -49,6 +49,8 @@ GEM
rack (1.5.2)
rack-protection (1.3.2)
rack
+ rack-test (0.6.2)
+ rack (>= 1.0)
raindrops (0.10.0)
sinatra (1.3.4)
rack (~> 1.4)
@@ -71,4 +73,5 @@ PLATFORMS
DEPENDENCIES
kibana!
omniauth-gds!
+ rack-test
unicorn
View
5 jenkins.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+set -eu
+
+bundle install --path "${HOME}/bundles/${JOB_NAME}" --deployment
+exec bundle exec ruby test/test_authwrapper.rb
View
17 lib/authwrapper.rb
@@ -9,11 +9,15 @@ def initialize(app, provider, redirect_to="/")
%w(get post).each do |method|
self.class.send(method, callback_path) do
- if request.env["omniauth.auth"]
+ payload = request.env.fetch("omniauth.auth", {})
+ payload_extra = payload.fetch("extra", {})
+ permissions = payload_extra.fetch("permissions", [])
+ if permissions.include?("signin")
session[:authenticated] = true
+ redirect @redirect_to
+ else
+ redirect "/auth/unauthorized"
end
-
- redirect @redirect_to
end
end
end
@@ -26,7 +30,7 @@ def served_paths
if session[:authenticated]
["/auth/logout"]
else
- ["/auth/failure", callback_path]
+ ["/auth/failure", "/auth/unauthorized", callback_path]
end
end
@@ -47,6 +51,11 @@ def served_paths
end
get "/auth/failure" do
+ message = params["message"] or "unknown cause"
+ throw(:halt, [401, "Authentication failure: #{message}\n"])
+ end
+
+ get "/auth/unauthorized" do
throw(:halt, [401, "Not authorized\n"])
end
View
61 test/test_authwrapper.rb
@@ -0,0 +1,61 @@
+require_relative "../lib/authwrapper"
+require "omniauth"
+require "omniauth-gds"
+require "test/unit"
+require "rack/test"
+
+ENV["RACK_ENV"] = "test"
+
+OmniAuth.config.test_mode = true
+
+class TestApp < Sinatra::Base
+ get "/bar" do
+ "Got through to TestApp"
+ end
+end
+
+class AuthWrapperTest < Test::Unit::TestCase
+ include Rack::Test::Methods
+
+ def app
+ Rack::Builder.app do
+ use Rack::Session::Cookie, :secret => "TEST"
+ use OmniAuth::Builder do
+ provider :gds
+ end
+ use AuthWrapper, :gds, "/bar"
+ run TestApp
+ end
+ end
+
+ def test_redirects_to_omniauth_when_unauthorized
+ get "/bar"
+ assert last_response.redirect?
+ assert_equal "http://example.org/auth/gds", last_response["Location"]
+ end
+
+ def test_failure_without_signin_permission
+ get "/bar"
+ # Follow redirect to auth provider
+ follow_redirect!
+ # Follow redirect to callback
+ follow_redirect!
+ assert last_response.redirect?
+ assert_equal "http://example.org/auth/unauthorized", last_response["Location"]
+ end
+
+ def test_success_with_signin_permission
+ OmniAuth.config.add_mock(:gds, {:extra => {:permissions => ["signin"]}})
+ get "/bar"
+ # Follow redirect to auth provider
+ follow_redirect!
+ # Follow redirect to callback
+ follow_redirect!
+ assert last_response.redirect?
+ assert_equal "http://example.org/bar", last_response["Location"]
+ # Follow redirect to the page I requested in the first place
+ follow_redirect!
+ assert last_response.ok?
+ assert_equal "Got through to TestApp", last_response.body
+ end
+end

0 comments on commit c6f9859

Please sign in to comment.
Something went wrong with that request. Please try again.