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.
- data/.gitignore +20 -0
- data/.rspec +2 -0
- data/.travis.yml +10 -0
- data/Gemfile +14 -0
- data/LICENSE.txt +22 -0
- data/README.md +188 -0
- data/Rakefile +6 -0
- data/VERSION +1 -0
- data/lib/warden/github/rails.rb +42 -0
- data/lib/warden/github/rails/config.rb +52 -0
- data/lib/warden/github/rails/controller_helpers.rb +35 -0
- data/lib/warden/github/rails/railtie.rb +27 -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 +28 -0
- data/lib/warden/github/rails/version.rb +9 -0
- data/lib/warden/github/rails/view_helpers.rb +18 -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/rails_app/app/controllers/scoped_controller.rb +28 -0
- data/spec/rails_app/app/controllers/unscoped_controller.rb +28 -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 +49 -0
- data/spec/rails_app/script/rails +6 -0
- data/spec/spec_helper.rb +37 -0
- data/spec/unit/config_spec.rb +67 -0
- data/spec/unit/mock_user_spec.rb +20 -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 +229 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'warden/github'
|
2
|
+
require 'warden/github/rails/test_helpers/mock_user'
|
3
|
+
|
4
|
+
module Warden
|
5
|
+
module GitHub
|
6
|
+
module Rails
|
7
|
+
module TestHelpers
|
8
|
+
include ::Warden::Test::Helpers
|
9
|
+
|
10
|
+
# Login a mock GitHub user and return it.
|
11
|
+
def github_login(scope=Rails.default_scope)
|
12
|
+
MockUser.new.tap do |user|
|
13
|
+
login_as(user, :scope => scope)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Add a method to Rack::Response to easily determine if a request resulted in an
|
22
|
+
# OAuth redirect to GitHub.
|
23
|
+
class Rack::Response
|
24
|
+
def github_oauth_redirect?
|
25
|
+
redirect? and
|
26
|
+
location.start_with?('https://github.com/login/oauth/authorize')
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Warden
|
2
|
+
module GitHub
|
3
|
+
module Rails
|
4
|
+
module TestHelpers
|
5
|
+
class MockUser < User
|
6
|
+
attr_reader :memberships
|
7
|
+
|
8
|
+
def initialize(*args)
|
9
|
+
super
|
10
|
+
@memberships = { :team => [], :org => [] }
|
11
|
+
end
|
12
|
+
|
13
|
+
def stub_membership(membership)
|
14
|
+
memberships.fetch(membership.keys.first) << membership.values.first
|
15
|
+
end
|
16
|
+
|
17
|
+
def team_member?(id)
|
18
|
+
memberships[:team].include?(id)
|
19
|
+
end
|
20
|
+
|
21
|
+
def organization_member?(id)
|
22
|
+
memberships[:org].include?(id)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Warden
|
2
|
+
module GitHub
|
3
|
+
module Rails
|
4
|
+
module ViewHelpers
|
5
|
+
# Checks whether a user is logged in for the specified scope.
|
6
|
+
def github_authenticated?(scope=Rails.default_scope)
|
7
|
+
request.env['warden'].authenticated?(scope)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Returns the currently signed in user for the specified scope. See the
|
11
|
+
# documentation for Warden::GitHub::User for available methods.
|
12
|
+
def github_user(scope=Rails.default_scope)
|
13
|
+
request.env['warden'].user(scope)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'controller helpers' do
|
4
|
+
{
|
5
|
+
:scoped => :admin,
|
6
|
+
:unscoped => Warden::GitHub::Rails.default_scope
|
7
|
+
}.each do |type, scope|
|
8
|
+
context "when using #{type}" do
|
9
|
+
describe '#github_authenticate!' do
|
10
|
+
subject(:request) { get "/#{type}/authenticate" }
|
11
|
+
|
12
|
+
context 'when not logged in' do
|
13
|
+
it 'initiates the oauth flow' do
|
14
|
+
request.should be_github_oauth_redirect
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when logged in' do
|
19
|
+
before { github_login(scope) }
|
20
|
+
it 'does nothing' do
|
21
|
+
request.should be_ok
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#github_logout' do
|
27
|
+
context 'when not logged in' do
|
28
|
+
it 'does nothing' do
|
29
|
+
get("/#{type}/logout").body.should eq 'false'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'when logged in' do
|
34
|
+
it 'logs out the user' do
|
35
|
+
github_login(scope)
|
36
|
+
get("/#{type}/logout").body.should eq 'true'
|
37
|
+
get("/#{type}/logout").body.should eq 'false'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#github_authenticated?' do
|
43
|
+
subject(:request) { get "/#{type}/authenticated" }
|
44
|
+
|
45
|
+
context 'when not logged in' do
|
46
|
+
it 'returns false' do
|
47
|
+
request.body.should eq 'false'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'when logged in' do
|
52
|
+
it 'returns true' do
|
53
|
+
github_login(scope)
|
54
|
+
request.body.should eq 'true'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#github_user' do
|
60
|
+
subject(:request) { get "/#{type}/user" }
|
61
|
+
|
62
|
+
context 'when not logged in' do
|
63
|
+
it 'returns nil' do
|
64
|
+
request.body.should be_blank
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'when logged in' do
|
69
|
+
it 'returns the logged in user' do
|
70
|
+
github_login(scope)
|
71
|
+
request.body.
|
72
|
+
should include 'Warden::GitHub::Rails::TestHelpers::MockUser'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe '#github_session' do
|
78
|
+
subject(:request) { get "/#{type}/session" }
|
79
|
+
|
80
|
+
context 'when not logged in' do
|
81
|
+
it 'should be nil' do
|
82
|
+
request.body.should be_blank
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'when logged in' do
|
87
|
+
it "returns the user's session" do
|
88
|
+
github_login(scope)
|
89
|
+
request.body.should == { :foo => :bar }.to_s
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'request to a protected resource' do
|
4
|
+
context 'that requires a team membership' do
|
5
|
+
context 'which is specified by a numeric team id' do
|
6
|
+
subject { get '/team/protected' }
|
7
|
+
|
8
|
+
context 'when not logged in' do
|
9
|
+
it { should be_github_oauth_redirect }
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'when logged in' do
|
13
|
+
context 'and team member' do
|
14
|
+
before do
|
15
|
+
user = github_login
|
16
|
+
user.stub_membership(:team => 123)
|
17
|
+
end
|
18
|
+
|
19
|
+
it { should be_ok }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'and not team member' do
|
23
|
+
before { github_login }
|
24
|
+
it { should be_not_found}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'which is specified by a team alias' do
|
30
|
+
subject { get '/team_alias/protected' }
|
31
|
+
|
32
|
+
context 'when not logged in' do
|
33
|
+
it { should be_github_oauth_redirect }
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when logged in' do
|
37
|
+
context 'and team member' do
|
38
|
+
before do
|
39
|
+
user = github_login
|
40
|
+
user.stub_membership(:team => 456)
|
41
|
+
end
|
42
|
+
|
43
|
+
it { should be_ok }
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'and not team member' do
|
47
|
+
before { github_login }
|
48
|
+
it { should be_not_found}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'which is specified by a lambda' do
|
54
|
+
subject { get '/dynamic_team/123' }
|
55
|
+
|
56
|
+
context 'when logged in' do
|
57
|
+
context 'and team member' do
|
58
|
+
before do
|
59
|
+
user = github_login
|
60
|
+
user.stub_membership(:team => 123)
|
61
|
+
end
|
62
|
+
|
63
|
+
it { should be_ok }
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'and not team member' do
|
67
|
+
before { github_login }
|
68
|
+
it { should be_not_found}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'that requires an organization membership' do
|
75
|
+
{ :org => :foobar_inc, :organization => 'some_org' }.each do |key, value|
|
76
|
+
context "which is specified as #{key}" do
|
77
|
+
subject { get "/#{key}/protected" }
|
78
|
+
|
79
|
+
context 'when not logged in' do
|
80
|
+
it { should be_github_oauth_redirect }
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'when logged in' do
|
84
|
+
context 'and organization member' do
|
85
|
+
before do
|
86
|
+
user = github_login
|
87
|
+
user.stub_membership(:org => value)
|
88
|
+
end
|
89
|
+
|
90
|
+
it { should be_ok }
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'and not organization member' do
|
94
|
+
before { github_login }
|
95
|
+
it { should be_not_found }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'which is specified by a lambda' do
|
102
|
+
subject { get '/dynamic_org/some_org' }
|
103
|
+
|
104
|
+
context 'when logged in' do
|
105
|
+
context 'and organization member' do
|
106
|
+
before do
|
107
|
+
user = github_login
|
108
|
+
user.stub_membership(:org => 'some_org')
|
109
|
+
end
|
110
|
+
|
111
|
+
it { should be_ok }
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'and not organization member' do
|
115
|
+
before { github_login }
|
116
|
+
it { should be_not_found}
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe 'request to a resource that only exists when logged in' do
|
124
|
+
context 'that requires a team membership' do
|
125
|
+
context 'which is specified by a numeric team id' do
|
126
|
+
subject { get '/team/conditional' }
|
127
|
+
|
128
|
+
context 'when team member' do
|
129
|
+
before do
|
130
|
+
user = github_login
|
131
|
+
user.stub_membership(:team => 123)
|
132
|
+
end
|
133
|
+
|
134
|
+
it { should be_ok }
|
135
|
+
end
|
136
|
+
|
137
|
+
context 'when not team member' do
|
138
|
+
before { github_login }
|
139
|
+
it { should be_not_found}
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context 'which is specified by a team alias' do
|
144
|
+
subject { get '/team_alias/conditional' }
|
145
|
+
|
146
|
+
context 'when team member' do
|
147
|
+
before do
|
148
|
+
user = github_login
|
149
|
+
user.stub_membership(:team => 456)
|
150
|
+
end
|
151
|
+
|
152
|
+
it { should be_ok }
|
153
|
+
end
|
154
|
+
|
155
|
+
context 'when not team member' do
|
156
|
+
before { github_login }
|
157
|
+
it { should be_not_found}
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context 'that requires an organization membership' do
|
163
|
+
{ :org => :foobar_inc, :organization => 'some_org' }.each do |key, value|
|
164
|
+
context "which is specified as #{key}" do
|
165
|
+
subject { get "/#{key}/conditional" }
|
166
|
+
|
167
|
+
context 'when organization member' do
|
168
|
+
before do
|
169
|
+
user = github_login
|
170
|
+
user.stub_membership(:org => value)
|
171
|
+
end
|
172
|
+
|
173
|
+
it { should be_ok }
|
174
|
+
end
|
175
|
+
|
176
|
+
context 'when not organization member' do
|
177
|
+
before { github_login }
|
178
|
+
it { should be_not_found }
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -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
|