oauth2_provider_engine 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 (132) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +3 -0
  3. data/Rakefile +40 -0
  4. data/app/assets/javascripts/oauth2_provider/application.js +52 -0
  5. data/app/assets/javascripts/oauth2_provider/highcharts.js +162 -0
  6. data/app/assets/javascripts/oauth2_provider/jquery.tagsinput.js +218 -0
  7. data/app/assets/stylesheets/oauth2_provider/gh-buttons.css +388 -0
  8. data/app/assets/stylesheets/oauth2_provider/gh-icons.png +0 -0
  9. data/app/assets/stylesheets/oauth2_provider/jquery.tagsinput.css +6 -0
  10. data/app/assets/stylesheets/oauth2_provider/reset.css +2 -0
  11. data/app/assets/stylesheets/oauth2_provider/template.css +52 -0
  12. data/app/controllers/oauth2_provider/accesses_controller.rb +39 -0
  13. data/app/controllers/oauth2_provider/application_controller.rb +17 -0
  14. data/app/controllers/oauth2_provider/authorize_controller.rb +141 -0
  15. data/app/controllers/oauth2_provider/clients_controller.rb +85 -0
  16. data/app/controllers/oauth2_provider/scopes_controller.rb +63 -0
  17. data/app/controllers/oauth2_provider/token_controller.rb +187 -0
  18. data/app/helpers/clients_helper.rb +5 -0
  19. data/app/helpers/oauth2_provider/application_helper.rb +4 -0
  20. data/app/models/oauth2_provider/client.rb +129 -0
  21. data/app/models/oauth2_provider/document.rb +15 -0
  22. data/app/models/oauth2_provider/oauth_access.rb +80 -0
  23. data/app/models/oauth2_provider/oauth_authorization.rb +70 -0
  24. data/app/models/oauth2_provider/oauth_daily_request.rb +54 -0
  25. data/app/models/oauth2_provider/oauth_refresh_token.rb +20 -0
  26. data/app/models/oauth2_provider/oauth_token.rb +78 -0
  27. data/app/models/oauth2_provider/scope.rb +39 -0
  28. data/app/views/layouts/oauth2_provider/application.html.erb +62 -0
  29. data/app/views/oauth2_provider/accesses/index.html.erb +25 -0
  30. data/app/views/oauth2_provider/accesses/show.html.erb +35 -0
  31. data/app/views/oauth2_provider/clients/_form.html.erb +50 -0
  32. data/app/views/oauth2_provider/clients/edit.html.erb +9 -0
  33. data/app/views/oauth2_provider/clients/index.html.erb +43 -0
  34. data/app/views/oauth2_provider/clients/new.html.erb +8 -0
  35. data/app/views/oauth2_provider/clients/show.html.erb +49 -0
  36. data/app/views/oauth2_provider/scopes/_form.html.erb +35 -0
  37. data/app/views/oauth2_provider/scopes/edit.html.erb +8 -0
  38. data/app/views/oauth2_provider/scopes/index.html.erb +27 -0
  39. data/app/views/oauth2_provider/scopes/new.html.erb +7 -0
  40. data/app/views/oauth2_provider/scopes/show.html.erb +19 -0
  41. data/app/views/shared/authorize.html.erb +34 -0
  42. data/app/views/shared/token.json.erb +8 -0
  43. data/config/locales/en.yml +31 -0
  44. data/config/oauth.yml +4 -0
  45. data/config/routes.rb +25 -0
  46. data/lib/oauth2_provider.rb +38 -0
  47. data/lib/oauth2_provider/controller_mixin.rb +53 -0
  48. data/lib/oauth2_provider/engine.rb +4 -0
  49. data/lib/oauth2_provider_engine.rb +1 -0
  50. data/lib/oauth2_provider_engine/version.rb +3 -0
  51. data/test/dummy/CHANGELOG.rdoc +67 -0
  52. data/test/dummy/Gemfile +53 -0
  53. data/test/dummy/Gemfile.lock +254 -0
  54. data/test/dummy/README.rdoc +522 -0
  55. data/test/dummy/Rakefile +7 -0
  56. data/test/dummy/VERSION +1 -0
  57. data/test/dummy/app/assets/stylesheets/reset.css +2 -0
  58. data/test/dummy/app/assets/stylesheets/template.css +52 -0
  59. data/test/dummy/app/controllers/application_controller.rb +52 -0
  60. data/test/dummy/app/controllers/pastas_controller.rb +23 -0
  61. data/test/dummy/app/controllers/pizzas_controller.rb +23 -0
  62. data/test/dummy/app/controllers/sessions_controller.rb +26 -0
  63. data/test/dummy/app/controllers/users_controller.rb +59 -0
  64. data/test/dummy/app/models/user.rb +50 -0
  65. data/test/dummy/app/views/layouts/application.html.erb +65 -0
  66. data/test/dummy/app/views/sessions/new.html.erb +25 -0
  67. data/test/dummy/app/views/shared/403.json.erb +4 -0
  68. data/test/dummy/app/views/shared/404.json.erb +6 -0
  69. data/test/dummy/app/views/shared/422.json.erb +5 -0
  70. data/test/dummy/app/views/shared/500.json.erb +4 -0
  71. data/test/dummy/app/views/shared/html/404.html.erb +0 -0
  72. data/test/dummy/app/views/shared/html/422.html.erb +0 -0
  73. data/test/dummy/app/views/users/_form.html.erb +27 -0
  74. data/test/dummy/app/views/users/edit.html.erb +8 -0
  75. data/test/dummy/app/views/users/index.html.erb +20 -0
  76. data/test/dummy/app/views/users/new.html.erb +46 -0
  77. data/test/dummy/app/views/users/show.html.erb +15 -0
  78. data/test/dummy/app/views/users/show.json.erb +6 -0
  79. data/test/dummy/config.ru +4 -0
  80. data/test/dummy/config/application.rb +57 -0
  81. data/test/dummy/config/boot.rb +13 -0
  82. data/test/dummy/config/cucumber.yml +8 -0
  83. data/test/dummy/config/environment.rb +5 -0
  84. data/test/dummy/config/environments/development.rb +32 -0
  85. data/test/dummy/config/environments/production.rb +58 -0
  86. data/test/dummy/config/environments/test.rb +35 -0
  87. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  88. data/test/dummy/config/initializers/inflections.rb +10 -0
  89. data/test/dummy/config/initializers/mime_types.rb +5 -0
  90. data/test/dummy/config/initializers/secret_token.rb +7 -0
  91. data/test/dummy/config/initializers/session_store.rb +8 -0
  92. data/test/dummy/config/initializers/test.rb +3 -0
  93. data/test/dummy/config/locales/en.yml +1 -0
  94. data/test/dummy/config/mongoid.yml +20 -0
  95. data/test/dummy/config/routes.rb +22 -0
  96. data/test/dummy/db/seeds.rb +7 -0
  97. data/test/dummy/doc/README_FOR_APP +2 -0
  98. data/test/dummy/lib/tasks/cucumber.rake +53 -0
  99. data/test/dummy/lib/tasks/watchr.rake +5 -0
  100. data/test/dummy/public/404.html +26 -0
  101. data/test/dummy/public/422.html +26 -0
  102. data/test/dummy/public/500.html +4 -0
  103. data/test/dummy/public/favicon.ico +0 -0
  104. data/test/dummy/public/robots.txt +5 -0
  105. data/test/dummy/script/cucumber +10 -0
  106. data/test/dummy/script/rails +6 -0
  107. data/test/dummy/spec/acceptance/acceptance_helper.rb +5 -0
  108. data/test/dummy/spec/acceptance/accesses_controller_spec.rb +77 -0
  109. data/test/dummy/spec/acceptance/clients_controller_spec.rb +218 -0
  110. data/test/dummy/spec/acceptance/oauth_authorize_controller_spec.rb +241 -0
  111. data/test/dummy/spec/acceptance/oauth_token_controller_spec.rb +196 -0
  112. data/test/dummy/spec/acceptance/resource_controller_spec.rb +143 -0
  113. data/test/dummy/spec/acceptance/scopes_controller_spec.rb +227 -0
  114. data/test/dummy/spec/acceptance/support/helpers.rb +81 -0
  115. data/test/dummy/spec/acceptance/support/paths.rb +9 -0
  116. data/test/dummy/spec/acceptance/support/view_helpers.rb +52 -0
  117. data/test/dummy/spec/acceptance/users_controller_spec.rb +198 -0
  118. data/test/dummy/spec/extras/scope_spec.rb +105 -0
  119. data/test/dummy/spec/factories/oauth.rb +106 -0
  120. data/test/dummy/spec/models/oauth/client_spec.rb +123 -0
  121. data/test/dummy/spec/models/oauth/oauth_access_spec.rb +48 -0
  122. data/test/dummy/spec/models/oauth/oauth_authorization_spec.rb +50 -0
  123. data/test/dummy/spec/models/oauth/oauth_daily_request_spec.rb +14 -0
  124. data/test/dummy/spec/models/oauth/oauth_refresh_token_spec.rb +11 -0
  125. data/test/dummy/spec/models/oauth/oauth_token_spec.rb +55 -0
  126. data/test/dummy/spec/models/scope_spec.rb +17 -0
  127. data/test/dummy/spec/spec_helper.rb +39 -0
  128. data/test/dummy/spec/support/settings_helper.rb +28 -0
  129. data/test/dummy/test/initializers/capybara_headers_hack.rb +23 -0
  130. data/test/oauth2_provider_test.rb +7 -0
  131. data/test/test_helper.rb +15 -0
  132. metadata +387 -0
@@ -0,0 +1,81 @@
1
+ module HelperMethods
2
+
3
+ def login(user, password = "example")
4
+ visit "/log_in"
5
+ fill_in "email", with: user.email
6
+ fill_in "password", with: password
7
+ click_button "Log in"
8
+ end
9
+
10
+
11
+ # Driver switch
12
+ def use_javascript
13
+ Capybara.default_driver = :selenium
14
+ Capybara.javascript_driver = :selenium
15
+ end
16
+
17
+ def use_default
18
+ Capybara.default_driver = :rack_test
19
+ Capybara.javascript_driver = :rack_test
20
+ end
21
+
22
+
23
+ # Authorization page URIs
24
+ def authorization_grant_page(client, scope)
25
+ uri = "/oauth/authorize?response_type=code" + authorization_params(client, scope)
26
+ return URI.escape(uri)
27
+ end
28
+
29
+ def implicit_grant_page(client, scope)
30
+ uri = "/oauth/authorize?response_type=token" + authorization_params(client, scope)
31
+ return URI.escape(uri)
32
+ end
33
+
34
+ def authorization_params(client, scope)
35
+ uri = "&scope=#{scope}"
36
+ uri += "&client_id=#{client.uri}"
37
+ uri += "&redirect_uri=#{client.redirect_uri}"
38
+ end
39
+
40
+
41
+ # Redirect URIs
42
+ def authorization_grant_uri(client)
43
+ authorization = Oauth2Provider::OauthAuthorization.last
44
+ client.redirect_uri + "?code=" + authorization.code
45
+ end
46
+
47
+ def implicit_grant_uri(client)
48
+ token = Oauth2Provider::OauthToken.last
49
+ token.token.should_not be_nil
50
+ uri = client.redirect_uri + "#token=" + token.token + "&expires_in=" + Oauth2Provider.settings["token_expires_in"]
51
+ end
52
+
53
+ def authorization_denied_uri(client)
54
+ client.redirect_uri + "?error=access_denied"
55
+ end
56
+
57
+ def implicit_denied_uri(client)
58
+ client.redirect_uri + "#error=access_denied"
59
+ end
60
+
61
+
62
+ # Token generation (via POST requests)
63
+ def create_token_uri(attributes)
64
+ uri = Addressable::URI.new
65
+ uri.query_values = attributes
66
+ page.driver.post("/oauth/token", uri.query)
67
+ end
68
+
69
+ def response_should_have_access_token
70
+ token = Oauth2Provider::OauthToken.last
71
+ page.should have_content(token.token)
72
+ end
73
+
74
+ def response_should_have_refresh_token
75
+ refresh_token = Oauth2Provider::OauthRefreshToken.last
76
+ page.should have_content(refresh_token.refresh_token)
77
+ end
78
+
79
+ end
80
+
81
+ RSpec.configuration.include HelperMethods, :type => :acceptance
@@ -0,0 +1,9 @@
1
+ module NavigationHelpers
2
+ # Put helper methods related to the paths in your application here.
3
+
4
+ def homepage
5
+ "/"
6
+ end
7
+ end
8
+
9
+ RSpec.configuration.include NavigationHelpers, :type => :acceptance
@@ -0,0 +1,52 @@
1
+ module ViewHelperMethods
2
+
3
+ # Scope
4
+ def should_visualize_scope(scope)
5
+ page.should have_content(scope.name)
6
+ page.should have_content(scope.values_pretty)
7
+ end
8
+
9
+ def fill_scope(name, values)
10
+ fill_in 'Name', with: name
11
+ fill_in 'Values', with: values
12
+ end
13
+
14
+ # User
15
+ def should_visualize_user(user)
16
+ page.should have_content(user.email)
17
+ end
18
+
19
+ # Client
20
+ def should_visualize_client(client)
21
+ page.should have_content(client.name)
22
+ end
23
+
24
+ def should_visualize_client_details(client)
25
+ page.should have_content(client.name)
26
+ page.should have_content(client.uri)
27
+ page.should have_content(client.secret)
28
+ page.should have_content(client.site_uri)
29
+ page.should have_content(client.redirect_uri)
30
+ page.should have_content(client.scope_values_pretty)
31
+ page.should have_content("pizzas/create")
32
+ page.should have_content(client.info)
33
+ end
34
+
35
+ def fill_client(name = "example")
36
+ fill_in "Name", with: name
37
+ fill_in "Site", with: HOST
38
+ fill_in "Redirect", with: REDIRECT_URI
39
+ fill_in "Scope", with: "pizzas"
40
+ fill_in "Info", with: "This is an example app"
41
+ end
42
+
43
+ # bearer token
44
+ def should_not_be_authorized
45
+ page.status_code.should == 401
46
+ page.should have_content "Unauthorized access"
47
+ end
48
+
49
+ end
50
+
51
+ RSpec.configuration.include ViewHelperMethods, :type => :acceptance
52
+
@@ -0,0 +1,198 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/acceptance_helper')
2
+
3
+ feature "UsersController" do
4
+ before { host! "http://" + host }
5
+ before { @user = FactoryGirl.create(:user) }
6
+ before { @bob = FactoryGirl.create(:user_bob) }
7
+ before { @admin = FactoryGirl.create(:admin) }
8
+
9
+
10
+ context ".index" do
11
+ before { @uri = "/users" }
12
+
13
+ context "when not logged in" do
14
+ scenario "is not authorized" do
15
+ visit @uri
16
+ current_url.should == host + "/log_in"
17
+ end
18
+ end
19
+
20
+ context "when logged in" do
21
+ context "when admin" do
22
+ before { login(@admin) }
23
+ scenario "list all resources" do
24
+ visit @uri
25
+ [@user, @bob].each do |user|
26
+ should_visualize_user(user)
27
+ end
28
+ end
29
+ end
30
+
31
+ context "when not admin" do
32
+ before { login(@user) }
33
+ scenario "do not list all resources" do
34
+ visit @uri
35
+ page.should have_content "Unauthorized access"
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+
42
+ context ".show" do
43
+ before { @uri = "/users/" + @user.id.as_json }
44
+
45
+ context "when not logged in" do
46
+ scenario "is not authorized" do
47
+ visit @uri
48
+ current_url.should == host + "/log_in"
49
+ end
50
+ end
51
+
52
+ context "when logged in" do
53
+ before { login(@user) }
54
+
55
+ scenario "view a resource" do
56
+ visit @uri
57
+ should_visualize_user(@user)
58
+ end
59
+
60
+ scenario "resource not found" do
61
+ @user.destroy
62
+ visit @uri
63
+ current_url.should == host + "/log_in"
64
+ end
65
+
66
+ scenario "access other users profile" do
67
+ login @bob
68
+ visit @uri
69
+ page.should have_content "Resource not found"
70
+ end
71
+
72
+ scenario "access with illegal id" do
73
+ visit "/users/0"
74
+ page.should have_content "Resource not found"
75
+ end
76
+ end
77
+ end
78
+
79
+
80
+ context ".create" do
81
+ before { @uri = "/sign_up" }
82
+
83
+ context "when valid" do
84
+ before do
85
+ visit @uri
86
+ fill_in "Email", with: "new@example.com"
87
+ fill_in "Password", with: "example"
88
+ click_button 'Create User'
89
+ end
90
+
91
+ scenario "create a resource" do
92
+ page.should have_content "Signed up"
93
+ end
94
+ end
95
+
96
+ context "when not valid" do
97
+ scenario "fails" do
98
+ visit @uri
99
+ fill_in "Email", with: ""
100
+ fill_in "Password", with: ""
101
+ click_button 'Create User'
102
+ page.should have_content "Email can't be blank"
103
+ page.should have_content "Password can't be blank"
104
+ end
105
+ end
106
+
107
+ context "when no admin exists" do
108
+ before { @admin.destroy }
109
+ scenario "create admin" do
110
+ visit @uri
111
+ page.should have_content "admin"
112
+ fill_in "Email", with: "new@example.com"
113
+ fill_in "Password", with: "example"
114
+ click_button 'Create User'
115
+ User.last.should be_admin
116
+ end
117
+ end
118
+ end
119
+
120
+
121
+ context ".update" do
122
+ before { @uri = "/users/" + @user.id.as_json + "/edit" }
123
+
124
+ context "when not logged in" do
125
+ scenario "is not authorized" do
126
+ visit @uri
127
+ current_url.should == host + "/log_in"
128
+ end
129
+ end
130
+
131
+ context "when logged in" do
132
+ before { login(@user) }
133
+ let(:name) { "Alice is my name" }
134
+
135
+ scenario "when update fields" do
136
+ visit @uri
137
+ fill_in "Name", with: name
138
+ click_button "Update User"
139
+ page.should have_content(name)
140
+ end
141
+
142
+ context "when update the password" do
143
+ let(:new_pass) { "asecurepassword"}
144
+
145
+ context "when valid" do
146
+ before do
147
+ visit @uri
148
+ fill_in "Password", with: new_pass
149
+ click_button "Update User"
150
+ click_link "Log out"
151
+ end
152
+
153
+ scenario "should log with new pass" do
154
+ login(@user, new_pass)
155
+ page.should have_content "Logged in"
156
+ end
157
+
158
+ scenario "should not log with old pass" do
159
+ login(@user)
160
+ page.should_not have_content "Logged in"
161
+ page.should have_content "Invalid email or password"
162
+ end
163
+ end
164
+
165
+ scenario "when empty" do
166
+ visit @uri
167
+ fill_in "Password", with: ""
168
+ click_button "Update User"
169
+ click_link "Log out"
170
+ login(@user)
171
+ page.should have_content "Logged in"
172
+ end
173
+ end
174
+
175
+ scenario "when resource not found" do
176
+ @user.destroy
177
+ visit @uri
178
+ current_url.should == host + "/log_in"
179
+ end
180
+
181
+ scenario "when illegal id" do
182
+ visit "/users/0"
183
+ page.should have_content "Resource not found"
184
+ end
185
+
186
+ scenario "when edit other users profile" do
187
+ login @bob
188
+ visit @uri
189
+ page.should have_content "Resource not found"
190
+ end
191
+ end
192
+ end
193
+
194
+ #context ".destroy" do
195
+ #end
196
+
197
+ end
198
+
@@ -0,0 +1,105 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Oauth" do
4
+ before { Oauth2Provider::Scope.destroy_all }
5
+
6
+ before { @scope = FactoryGirl.create(:scope_pizzas_read) }
7
+ before { @scope = FactoryGirl.create(:scope_pizzas_all) }
8
+ before { @scope = FactoryGirl.create(:scope_pastas_read) }
9
+ before { @scope = FactoryGirl.create(:scope_pastas_all) }
10
+ before { @scope = FactoryGirl.create(:scope_read) }
11
+ before { @scope = FactoryGirl.create(:scope_all) }
12
+
13
+ context "#normalize_scope" do
14
+ context "single resource" do
15
+ context "single action" do
16
+ let(:normalized) { Oauth2Provider.normalize_scope("pizzas/index") }
17
+ subject { normalized }
18
+ it { should include "pizzas/index" }
19
+ end
20
+
21
+ context "read actions" do
22
+ let(:normalized) { Oauth2Provider.normalize_scope("pizzas/read") }
23
+ subject { normalized }
24
+
25
+ it { should include "pizzas/index" }
26
+ it { should include "pizzas/show" }
27
+ it { should_not include "pizzas/create"}
28
+ end
29
+
30
+ context "read actions and create action" do
31
+ let(:normalized) { Oauth2Provider.normalize_scope("pizzas/read pizzas/create") }
32
+ subject { normalized }
33
+
34
+ it { should include "pizzas/index" }
35
+ it { should include "pizzas/show" }
36
+ it { should include "pizzas/create"}
37
+ end
38
+
39
+ context "all rest actions" do
40
+ let(:normalized) { Oauth2Provider.normalize_scope("pizzas") }
41
+ subject { normalized }
42
+
43
+ it { should include "pizzas/index" }
44
+ it { should include "pizzas/show" }
45
+ it { should include "pizzas/create" }
46
+ it { should include "pizzas/update" }
47
+ it { should include "pizzas/destroy"}
48
+ it { should_not include "pastas/index" }
49
+ it { should_not include "pizzas" }
50
+ end
51
+ end
52
+
53
+ context "all resources" do
54
+ context "single actions" do
55
+ let(:normalized) { Oauth2Provider.normalize_scope("pizzas/index pastas/index") }
56
+ subject { normalized }
57
+ it { should include "pizzas/index" }
58
+ it { should_not include "pizzas/show" }
59
+ it { should include "pastas/index" }
60
+ it { should_not include "pastas/show" }
61
+ end
62
+
63
+ context "read actions" do
64
+ let(:normalized) { Oauth2Provider.normalize_scope("read") }
65
+ subject { normalized }
66
+
67
+ it { should include "pizzas/index" }
68
+ it { should include "pizzas/show" }
69
+ it { should_not include "pizzas/create"}
70
+
71
+ it { should include "pastas/index" }
72
+ it { should include "pastas/show" }
73
+ it { should_not include "pastas/create"}
74
+
75
+ it { should_not include "read" }
76
+ it { should_not include "pizzas/read" }
77
+ it { should_not include "pastas/read" }
78
+ end
79
+
80
+ context "all rest actions" do
81
+ let(:normalized) { Oauth2Provider.normalize_scope("all") }
82
+ subject { normalized }
83
+
84
+ it { should include "pizzas/index" }
85
+ it { should include "pizzas/show" }
86
+ it { should include "pizzas/create" }
87
+ it { should include "pizzas/update" }
88
+ it { should include "pizzas/destroy"}
89
+
90
+ it { should include "pastas/index" }
91
+ it { should include "pastas/show" }
92
+ it { should include "pastas/create" }
93
+ it { should include "pastas/update" }
94
+ it { should include "pastas/destroy"}
95
+
96
+ it { should_not include "all"}
97
+ it { should_not include "pizzas"}
98
+ it { should_not include "pastas"}
99
+ it { should_not include "pizzas/read"}
100
+ it { should_not include "pastas/read"}
101
+ end
102
+ end
103
+
104
+ end
105
+ end