warden-github-rails 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. data/.gitignore +20 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +10 -0
  4. data/Gemfile +14 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +188 -0
  7. data/Rakefile +6 -0
  8. data/VERSION +1 -0
  9. data/lib/warden/github/rails.rb +42 -0
  10. data/lib/warden/github/rails/config.rb +52 -0
  11. data/lib/warden/github/rails/controller_helpers.rb +35 -0
  12. data/lib/warden/github/rails/railtie.rb +27 -0
  13. data/lib/warden/github/rails/routes.rb +83 -0
  14. data/lib/warden/github/rails/test_helpers.rb +28 -0
  15. data/lib/warden/github/rails/test_helpers/mock_user.rb +28 -0
  16. data/lib/warden/github/rails/version.rb +9 -0
  17. data/lib/warden/github/rails/view_helpers.rb +18 -0
  18. data/spec/integration/controller_helpers_spec.rb +95 -0
  19. data/spec/integration/membership_spec.rb +183 -0
  20. data/spec/integration/route_spec.rb +82 -0
  21. data/spec/integration/scope_spec.rb +33 -0
  22. data/spec/rails_app/app/controllers/scoped_controller.rb +28 -0
  23. data/spec/rails_app/app/controllers/unscoped_controller.rb +28 -0
  24. data/spec/rails_app/config.ru +2 -0
  25. data/spec/rails_app/config/application.rb +20 -0
  26. data/spec/rails_app/config/boot.rb +3 -0
  27. data/spec/rails_app/config/environment.rb +3 -0
  28. data/spec/rails_app/config/environments/development.rb +8 -0
  29. data/spec/rails_app/config/environments/production.rb +8 -0
  30. data/spec/rails_app/config/environments/test.rb +11 -0
  31. data/spec/rails_app/config/initializers/secret_token.rb +1 -0
  32. data/spec/rails_app/config/initializers/session_store.rb +1 -0
  33. data/spec/rails_app/config/initializers/warden_github_rails.rb +12 -0
  34. data/spec/rails_app/config/initializers/wrap_parameters.rb +4 -0
  35. data/spec/rails_app/config/routes.rb +49 -0
  36. data/spec/rails_app/script/rails +6 -0
  37. data/spec/spec_helper.rb +37 -0
  38. data/spec/unit/config_spec.rb +67 -0
  39. data/spec/unit/mock_user_spec.rb +20 -0
  40. data/spec/unit/rails_spec.rb +11 -0
  41. data/spec/unit/test_helpers_spec.rb +39 -0
  42. data/warden-github-rails.gemspec +25 -0
  43. metadata +229 -0
@@ -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
+ request.should be_github_oauth_redirect
11
+ params.fetch('client_id').should eq args.fetch(:client_id)
12
+ params.fetch('redirect_uri').should =~ args.fetch(:redirect_uri)
13
+ params.fetch('scope').should 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,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,2 @@
1
+ require ::File.expand_path('../config/environment', __FILE__)
2
+ run RailsApp::Application
@@ -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,3 @@
1
+ require 'rubygems'
2
+
3
+ $:.unshift File.expand_path('../../../../lib', __FILE__)
@@ -0,0 +1,3 @@
1
+ require File.expand_path('../application', __FILE__)
2
+
3
+ RailsApp::Application.initialize!
@@ -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,4 @@
1
+ ActiveSupport.on_load(:action_controller) do
2
+ wrap_parameters :format => [:json]
3
+ end
4
+
@@ -0,0 +1,49 @@
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
+ # Everything else should be a 404:
47
+
48
+ match '*all' => responses[404]
49
+ 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'
@@ -0,0 +1,37 @@
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
+
27
+ config.include Rack::Test::Methods
28
+ config.include Warden::GitHub::Rails::TestHelpers
29
+
30
+ # Reset warden's login states after each test.
31
+ config.after { Warden.test_reset! }
32
+
33
+ # This is how rack-test gets access to the app.
34
+ def app
35
+ RailsApp::Application
36
+ end
37
+ 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
+ config.default_scope.should be :user
9
+ end
10
+ end
11
+
12
+ describe '#scopes' do
13
+ it 'defaults to an empty hash' do
14
+ config.scopes.should == {}
15
+ end
16
+ end
17
+
18
+ describe '#teams' do
19
+ it 'defaults to an empty hash' do
20
+ config.scopes.should == {}
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
+ config.scopes[:admin].should 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
+ config.teams[:marketing].should eq 1234
36
+ end
37
+
38
+ it 'normalizes the input' do
39
+ config.add_team 'marketing', '1234'
40
+ config.teams[:marketing].should 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
+ config.team_id('1234').should eq 1234
48
+ config.team_id(1234).should 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
+ config.team_id(:marketing).should eq 1234
56
+ config.team_id('marketing').should 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
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe Warden::GitHub::Rails::TestHelpers::MockUser do
4
+ it { should be_a Warden::GitHub::User }
5
+
6
+ describe '#stub_membership' do
7
+ subject(:user) { described_class.new }
8
+
9
+ it 'stubs memberships' do
10
+ user.should_not be_team_member(123)
11
+ user.should_not be_organization_member('foobar')
12
+
13
+ user.stub_membership(:team => 123)
14
+ user.stub_membership(:org => 'foobar')
15
+
16
+ user.should be_team_member(123)
17
+ user.should be_organization_member('foobar')
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Warden::GitHub::Rails do
4
+ describe '.setup' do
5
+ it 'yields a config instance' do
6
+ described_class.setup do |config|
7
+ config.should be_a described_class::Config
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe Warden::GitHub::Rails::TestHelpers do
4
+ describe '#github_login' do
5
+ context 'when no scope is specified' do
6
+ it 'uses the default scope from config to login' do
7
+ Warden::GitHub::Rails.stub(:default_scope => :foobar)
8
+ should_receive(:login_as).with do |_, opts|
9
+ opts.fetch(:scope).should be :foobar
10
+ end
11
+
12
+ github_login
13
+ end
14
+ end
15
+
16
+ context 'when a scope is specified' do
17
+ it 'uses that scope to login' do
18
+ should_receive(:login_as).with do |_, opts|
19
+ opts.fetch(:scope).should be :admin
20
+ end
21
+
22
+ github_login(:admin)
23
+ end
24
+ end
25
+
26
+ it 'logs in a mock user' do
27
+ expected_user = nil
28
+
29
+ should_receive(:login_as).with do |user, _|
30
+ expected_user = user
31
+ user.should be_a Warden::GitHub::Rails::TestHelpers::MockUser
32
+ end
33
+
34
+ user = github_login
35
+
36
+ user.should be expected_user
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,25 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'warden/github/rails/version'
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = 'warden-github-rails'
7
+ gem.version = Warden::GitHub::Rails::VERSION
8
+ gem.authors = ['Philipe Fatio']
9
+ gem.email = ['me@phili.pe']
10
+ gem.summary = %q{An easy drop in solution for rails to use GitHub authentication.}
11
+ gem.description = gem.summary
12
+ gem.homepage = 'https://github.com/fphilipe/warden-github-rails'
13
+
14
+ gem.files = `git ls-files`.split($/) - Dir.glob('example/**/*')
15
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
16
+
17
+ gem.add_development_dependency 'rspec', '~> 2.12'
18
+ gem.add_development_dependency 'simplecov'
19
+ gem.add_development_dependency 'rails', '~> 3.2'
20
+ gem.add_development_dependency 'rack-test', '~> 0.6'
21
+ gem.add_development_dependency 'addressable', '~> 2.3'
22
+
23
+ gem.add_dependency 'warden-github', '~> 0.13.2'
24
+ gem.add_dependency 'railties', '~> 3.2'
25
+ end