warden-github-rails-thinknear-fork 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +20 -0
- data/.rspec +2 -0
- data/.travis.yml +39 -0
- data/CHANGELOG.md +20 -0
- data/Gemfile +27 -0
- data/LICENSE.txt +22 -0
- data/README.md +250 -0
- data/Rakefile +6 -0
- data/VERSION +1 -0
- data/lib/warden/github/rails.rb +39 -0
- data/lib/warden/github/rails/config.rb +49 -0
- data/lib/warden/github/rails/controller_helpers.rb +39 -0
- data/lib/warden/github/rails/railtie.rb +42 -0
- data/lib/warden/github/rails/routes.rb +83 -0
- data/lib/warden/github/rails/test_helpers.rb +28 -0
- data/lib/warden/github/rails/test_helpers/mock_user.rb +30 -0
- data/lib/warden/github/rails/version.rb +9 -0
- data/spec/integration/controller_helpers_spec.rb +95 -0
- data/spec/integration/membership_spec.rb +183 -0
- data/spec/integration/route_spec.rb +82 -0
- data/spec/integration/scope_spec.rb +33 -0
- data/spec/integration/view_helpers_spec.rb +19 -0
- data/spec/rails_app/app/controllers/scoped_controller.rb +28 -0
- data/spec/rails_app/app/controllers/unscoped_controller.rb +28 -0
- data/spec/rails_app/app/controllers/view_tests_controller.rb +2 -0
- data/spec/rails_app/app/views/view_tests/authenticated.html.erb +1 -0
- data/spec/rails_app/app/views/view_tests/user.html.erb +1 -0
- data/spec/rails_app/config.ru +2 -0
- data/spec/rails_app/config/application.rb +20 -0
- data/spec/rails_app/config/boot.rb +3 -0
- data/spec/rails_app/config/environment.rb +3 -0
- data/spec/rails_app/config/environments/development.rb +8 -0
- data/spec/rails_app/config/environments/production.rb +8 -0
- data/spec/rails_app/config/environments/test.rb +11 -0
- data/spec/rails_app/config/initializers/secret_token.rb +1 -0
- data/spec/rails_app/config/initializers/session_store.rb +1 -0
- data/spec/rails_app/config/initializers/warden_github_rails.rb +12 -0
- data/spec/rails_app/config/initializers/wrap_parameters.rb +4 -0
- data/spec/rails_app/config/routes.rb +53 -0
- data/spec/rails_app/script/rails +6 -0
- data/spec/spec_helper.rb +40 -0
- data/spec/unit/config_spec.rb +67 -0
- data/spec/unit/mock_user_spec.rb +21 -0
- data/spec/unit/rails_spec.rb +11 -0
- data/spec/unit/test_helpers_spec.rb +39 -0
- data/warden-github-rails.gemspec +25 -0
- metadata +215 -0
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'request to a protected resource' do
|
4
|
+
subject { get '/protected' }
|
5
|
+
|
6
|
+
context 'when not logged in' do
|
7
|
+
it { should be_github_oauth_redirect }
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'when logged in' do
|
11
|
+
before { github_login }
|
12
|
+
it { should be_ok }
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'with multiple scopes' do
|
16
|
+
subject { get '/admin/protected' }
|
17
|
+
|
18
|
+
context 'when logged in in the wrong scope' do
|
19
|
+
before { github_login }
|
20
|
+
it { should be_github_oauth_redirect }
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when logged in in the correct scope' do
|
24
|
+
before { github_login(:admin) }
|
25
|
+
it { should be_ok }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'request to a resource that only exists when logged in' do
|
31
|
+
subject { get '/conditional' }
|
32
|
+
|
33
|
+
context 'when not logged in' do
|
34
|
+
it { should be_not_found }
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when logged in' do
|
38
|
+
before { github_login }
|
39
|
+
it { should be_ok }
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'with mutliple scopes' do
|
43
|
+
subject { get '/admin/conditional' }
|
44
|
+
|
45
|
+
context 'when logged in in the wrong scope' do
|
46
|
+
before { github_login }
|
47
|
+
it { should be_not_found }
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when logged in in the correct scope' do
|
51
|
+
before { github_login(:admin) }
|
52
|
+
it { should be_ok }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 'request to a resource that only exists when logged out' do
|
58
|
+
subject { get '/conditional_inverse' }
|
59
|
+
|
60
|
+
context 'when not logged in' do
|
61
|
+
it { should be_ok }
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'when logged in' do
|
65
|
+
before { github_login }
|
66
|
+
it { should be_not_found }
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'with mutliple scopes' do
|
70
|
+
subject { get '/admin/conditional_inverse' }
|
71
|
+
|
72
|
+
context 'when logged in in the wrong scope' do
|
73
|
+
before { github_login }
|
74
|
+
it { should be_ok }
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'when logged in in the correct scope' do
|
78
|
+
before { github_login(:admin) }
|
79
|
+
it { should be_not_found }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Test if the configs in rails_app/config/initializers/warden_github_rails.rb
|
4
|
+
# are actually being set and used by warden.
|
5
|
+
describe 'request to custom configured scope' do
|
6
|
+
def test_redirect(url, args)
|
7
|
+
request = get url
|
8
|
+
params = Addressable::URI.parse(request.location).query_values
|
9
|
+
|
10
|
+
expect(request).to be_github_oauth_redirect
|
11
|
+
expect(params.fetch('client_id')).to eq(args.fetch(:client_id))
|
12
|
+
expect(params.fetch('redirect_uri')).to match(args.fetch(:redirect_uri))
|
13
|
+
expect(params.fetch('scope')).to eq(args.fetch(:scope))
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'user' do
|
17
|
+
it 'passes the correct configs to the oauth flow' do
|
18
|
+
test_redirect('/protected',
|
19
|
+
:client_id => 'foo',
|
20
|
+
:redirect_uri => /\/protected$/,
|
21
|
+
:scope => 'user')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'admin' do
|
26
|
+
it 'passes the correct configs to the oauth flow' do
|
27
|
+
test_redirect('/admin/protected',
|
28
|
+
:client_id => 'abc',
|
29
|
+
:redirect_uri => /\/admin\/login\/callback$/,
|
30
|
+
:scope => 'repo')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'view helpers' do
|
4
|
+
describe '#github_user' do
|
5
|
+
subject(:request) { get "/view_tests/user" }
|
6
|
+
|
7
|
+
it 'is defined' do
|
8
|
+
expect(request.body).to include('true')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#github_authenticated?' do
|
13
|
+
subject(:request) { get "/view_tests/authenticated" }
|
14
|
+
|
15
|
+
it 'is defined' do
|
16
|
+
expect(request.body).to include('true')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class ScopedController < ActionController::Base
|
2
|
+
def authenticate
|
3
|
+
github_authenticate!(:admin)
|
4
|
+
render :nothing => true
|
5
|
+
end
|
6
|
+
|
7
|
+
def logout
|
8
|
+
was_logged_in = !github_user(:admin).nil?
|
9
|
+
github_logout(:admin)
|
10
|
+
render :text => was_logged_in
|
11
|
+
end
|
12
|
+
|
13
|
+
def authenticated
|
14
|
+
render :text => github_authenticated?(:admin)
|
15
|
+
end
|
16
|
+
|
17
|
+
def user
|
18
|
+
render :text => github_user(:admin)
|
19
|
+
end
|
20
|
+
|
21
|
+
def session
|
22
|
+
if (session = github_session(:admin))
|
23
|
+
session[:foo] = :bar
|
24
|
+
end
|
25
|
+
|
26
|
+
render :text => github_session(:admin)
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class UnscopedController < ActionController::Base
|
2
|
+
def authenticate
|
3
|
+
github_authenticate!
|
4
|
+
render :nothing => true
|
5
|
+
end
|
6
|
+
|
7
|
+
def logout
|
8
|
+
was_logged_in = !github_user.nil?
|
9
|
+
github_logout
|
10
|
+
render :text => was_logged_in
|
11
|
+
end
|
12
|
+
|
13
|
+
def authenticated
|
14
|
+
render :text => github_authenticated?
|
15
|
+
end
|
16
|
+
|
17
|
+
def user
|
18
|
+
render :text => github_user
|
19
|
+
end
|
20
|
+
|
21
|
+
def session
|
22
|
+
if (session = github_session)
|
23
|
+
session[:foo] = :bar
|
24
|
+
end
|
25
|
+
|
26
|
+
render :text => github_session
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= !!defined?(github_authenticated?) %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= !!defined?(github_user) %>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.expand_path('../boot', __FILE__)
|
2
|
+
|
3
|
+
require 'action_controller/railtie'
|
4
|
+
require 'warden/github/rails'
|
5
|
+
|
6
|
+
unless Rails.env.test?
|
7
|
+
begin
|
8
|
+
require 'debugger'
|
9
|
+
rescue LoadError
|
10
|
+
require 'ruby-debug'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module RailsApp
|
15
|
+
class Application < Rails::Application
|
16
|
+
config.encoding = "utf-8"
|
17
|
+
config.filter_parameters += [:password]
|
18
|
+
config.active_support.escape_html_entities_in_json = true
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
RailsApp::Application.configure do
|
2
|
+
config.cache_classes = false
|
3
|
+
config.whiny_nils = true
|
4
|
+
config.consider_all_requests_local = true
|
5
|
+
config.action_controller.perform_caching = false
|
6
|
+
config.active_support.deprecation = :log
|
7
|
+
config.action_dispatch.best_standards_support = :builtin
|
8
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
RailsApp::Application.configure do
|
2
|
+
config.cache_classes = true
|
3
|
+
config.consider_all_requests_local = false
|
4
|
+
config.action_controller.perform_caching = true
|
5
|
+
config.serve_static_assets = false
|
6
|
+
config.i18n.fallbacks = true
|
7
|
+
config.active_support.deprecation = :notify
|
8
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
RailsApp::Application.configure do
|
2
|
+
config.cache_classes = true
|
3
|
+
config.serve_static_assets = true
|
4
|
+
config.static_cache_control = "public, max-age=3600"
|
5
|
+
config.whiny_nils = true
|
6
|
+
config.consider_all_requests_local = true
|
7
|
+
config.action_controller.perform_caching = false
|
8
|
+
config.action_dispatch.show_exceptions = false
|
9
|
+
config.action_controller.allow_forgery_protection = false
|
10
|
+
config.active_support.deprecation = :stderr
|
11
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
RailsApp::Application.config.secret_token = '81fe673d8f0ffe90945ee8d493f8c0c474dc18ab9ff0a7e58af85d7870a56f3324f0d034131e5b5c2816c8a690cd13f9a46f484222dad475b734462b90e90527'
|
@@ -0,0 +1 @@
|
|
1
|
+
RailsApp::Application.config.session_store :cookie_store, :key => '_rails_app_session'
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Warden::GitHub::Rails.setup do |config|
|
2
|
+
config.add_scope :user, :client_id => ENV['GITHUB_CLIENT_ID'] || 'foo',
|
3
|
+
:client_secret => ENV['GITHUB_CLIENT_SECRET'] || 'bar',
|
4
|
+
:scope => 'user'
|
5
|
+
|
6
|
+
config.add_scope :admin, :client_id => ENV['GITHUB_CLIENT_ID'] || 'abc',
|
7
|
+
:client_secret => ENV['GITHUB_CLIENT_SECRET'] || 'xyz',
|
8
|
+
:redirect_uri => '/admin/login/callback',
|
9
|
+
:scope => 'repo'
|
10
|
+
|
11
|
+
config.add_team :marketing, 456
|
12
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
RailsApp::Application.routes.draw do
|
2
|
+
responses = {
|
3
|
+
200 => lambda { |env| [200, {}, ['welcome']] },
|
4
|
+
404 => lambda { |env| [404, {}, ['not found']] }
|
5
|
+
}
|
6
|
+
|
7
|
+
# Routes for route constraints tests:
|
8
|
+
|
9
|
+
github_authenticate { get '/protected' => responses[200] }
|
10
|
+
github_authenticated { get '/conditional' => responses[200] }
|
11
|
+
github_unauthenticated { get '/conditional_inverse' => responses[200] }
|
12
|
+
|
13
|
+
github_authenticate(:admin) { get '/admin/protected' => responses[200] }
|
14
|
+
github_authenticate(:admin) { get '/admin/login/callback' => redirect('/admin/protected') }
|
15
|
+
github_authenticated(:admin) { get '/admin/conditional' => responses[200] }
|
16
|
+
github_unauthenticated(:admin) { get '/admin/conditional_inverse' => responses[200] }
|
17
|
+
|
18
|
+
github_authenticate(:team => 123) { get '/team/protected' => responses[200] }
|
19
|
+
github_authenticated(:team => 123) { get '/team/conditional' => responses[200] }
|
20
|
+
|
21
|
+
github_authenticate(:team => :marketing) { get '/team_alias/protected' => responses[200] }
|
22
|
+
github_authenticated(:team => :marketing) { get '/team_alias/conditional' => responses[200] }
|
23
|
+
|
24
|
+
github_authenticate(:org => :foobar_inc) { get '/org/protected' => responses[200] }
|
25
|
+
github_authenticated(:org => :foobar_inc) { get '/org/conditional' => responses[200] }
|
26
|
+
|
27
|
+
github_authenticate(:organization => 'some_org') { get '/organization/protected' => responses[200] }
|
28
|
+
github_authenticated(:organization => 'some_org') { get '/organization/conditional' => responses[200] }
|
29
|
+
|
30
|
+
github_authenticated(:org => lambda { |req| req.params[:id] }) do
|
31
|
+
get '/dynamic_org/:id' => responses[200]
|
32
|
+
end
|
33
|
+
|
34
|
+
github_authenticated(:team => lambda { |req| req.params[:id] }) do
|
35
|
+
get '/dynamic_team/:id' => responses[200]
|
36
|
+
end
|
37
|
+
|
38
|
+
# Routes for controller helpers tests:
|
39
|
+
|
40
|
+
%w[ unscoped scoped ].each do |type|
|
41
|
+
%w[ authenticate logout authenticated user session ].each do |method|
|
42
|
+
get "/#{type}/#{method}" => "#{type}##{method}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
%w[ user authenticated ].each do |method|
|
47
|
+
get "/view_tests/#{method}" => "view_tests##{method}"
|
48
|
+
end
|
49
|
+
|
50
|
+
# Everything else should be a 404:
|
51
|
+
|
52
|
+
get '*all' => responses[404]
|
53
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
3
|
+
|
4
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
5
|
+
require File.expand_path('../../config/boot', __FILE__)
|
6
|
+
require 'rails/commands'
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
unless ENV['CI']
|
2
|
+
require 'simplecov'
|
3
|
+
SimpleCov.start do
|
4
|
+
add_filter '/spec'
|
5
|
+
add_filter '/example'
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'rack/test'
|
10
|
+
require 'warden/github/rails/test_helpers'
|
11
|
+
require 'addressable/uri'
|
12
|
+
|
13
|
+
# Load the test rails app:
|
14
|
+
ENV['RAILS_ENV'] ||= 'test'
|
15
|
+
require 'rails_app/config/environment'
|
16
|
+
|
17
|
+
# Setup configs needed to run:
|
18
|
+
ENV['GITHUB_CLIENT_ID'] = 'test_client_id'
|
19
|
+
ENV['GITHUB_CLIENT_SECRET'] = 'test_client_secret'
|
20
|
+
|
21
|
+
RSpec.configure do |config|
|
22
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
23
|
+
config.run_all_when_everything_filtered = true
|
24
|
+
config.filter_run :focus
|
25
|
+
config.order = 'random'
|
26
|
+
config.expect_with :rspec do |c|
|
27
|
+
c.syntax = :expect
|
28
|
+
end
|
29
|
+
|
30
|
+
config.include Rack::Test::Methods
|
31
|
+
config.include Warden::GitHub::Rails::TestHelpers
|
32
|
+
|
33
|
+
# Reset warden's login states after each test.
|
34
|
+
config.after { Warden.test_reset! }
|
35
|
+
|
36
|
+
# This is how rack-test gets access to the app.
|
37
|
+
def app
|
38
|
+
RailsApp::Application
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Warden::GitHub::Rails::Config do
|
4
|
+
subject(:config) { described_class.new }
|
5
|
+
|
6
|
+
describe '#default_scope' do
|
7
|
+
it 'defaults to :user' do
|
8
|
+
expect(config.default_scope).to eq(:user)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#scopes' do
|
13
|
+
it 'defaults to an empty hash' do
|
14
|
+
expect(config.scopes).to eq({})
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#teams' do
|
19
|
+
it 'defaults to an empty hash' do
|
20
|
+
expect(config.scopes).to eq({})
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#add_scope' do
|
25
|
+
it 'adds a scope with its configs' do
|
26
|
+
scope_config = double
|
27
|
+
config.add_scope :admin, scope_config
|
28
|
+
expect(config.scopes[:admin]).to eq(scope_config)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#add_team' do
|
33
|
+
it 'adds a name mapping for a team' do
|
34
|
+
config.add_team :marketing, 1234
|
35
|
+
expect(config.teams[:marketing]).to eq(1234)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'normalizes the input' do
|
39
|
+
config.add_team 'marketing', '1234'
|
40
|
+
expect(config.teams[:marketing]).to eq(1234)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#team_id' do
|
45
|
+
context 'when passed a numeric value' do
|
46
|
+
it 'returns that value' do
|
47
|
+
expect(config.team_id('1234')).to eq(1234)
|
48
|
+
expect(config.team_id(1234)).to eq(1234)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'when passed an alias' do
|
53
|
+
it 'returns the id for the alias' do
|
54
|
+
config.add_team :marketing, 1234
|
55
|
+
expect(config.team_id(:marketing)).to eq(1234)
|
56
|
+
expect(config.team_id('marketing')).to eq(1234)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'when no mapping exists' do
|
61
|
+
it 'raises a BadConfig' do
|
62
|
+
expect { config.team_id(:foobar) }.
|
63
|
+
to raise_error(Warden::GitHub::Rails::Config::BadConfig)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|