oauth2_provider_engine 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,522 @@
1
+ http://github.com/Lelylan/rest-oauth2-server/raw/development/public/images/help-us.png
2
+
3
+ {The Lelylan Team}[http://lelylan.com]
4
+
5
+
6
+ = Rest OAuth 2.0 Server
7
+
8
+ <b>Rest OAuth 2.0 Server</b> is a project that easily allows the generation of an OAuth 2.0 Server following the {draft 13}[http://tools.ietf.org/html/draft-ietf-oauth-v2-13]
9
+ of the OAuth 2.0 protocol with {bearer tokens}[http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-02]. The spec
10
+ is close to settling down, and we intend to update our code to match the final OAuth 2.0 and bearer token standards.
11
+ OAuth has often been described as a "valet key for the web." It lets applications ask users for access to just the
12
+ data they need and no more, giving them the ability to enable and disable the accesses whenever they want, most of
13
+ the time without sharing their secret credentials.
14
+
15
+
16
+ = Installation
17
+
18
+ For the Rest OAuth 2.0 Server to work you need to have
19
+
20
+ * {Ruby 1.9.2}[www.ruby-lang.org/en/] (use rvm[http://screencasts.org/episodes/how-to-use-rvm?utm_source=rubyweekly&utm_medium=email] to manage versions).
21
+ * {MongoDB}[http://www.mongodb.org/].
22
+
23
+ To install the project run the following commands (remember to run <tt>$ mongod</tt> before)
24
+
25
+ $ git clone git@github.com:Lelylan/rest-oauth2-server.git
26
+ $ cd rest-oauth2-server
27
+ $ bundle install
28
+ $ rake spec
29
+ $ rails s
30
+
31
+ If everything works fine, you have your OAuth 2.0 Server up and running! We are also working at a gem and a
32
+ generator to easily integrate the Rest OAuth 2.0 server into your project, so stay tuned.
33
+
34
+
35
+ == Admin user definition
36
+
37
+ When accessing the application for the first time, click to sign up. A message will ask you to create the first
38
+ administrator user as no one have been found.
39
+
40
+ http://github.com/Lelylan/rest-oauth2-server/raw/development/public/images/screenshots/first-user-creation.png
41
+
42
+ Register, log in and access the admin dashboard where you will find the following sections.
43
+
44
+ * <b>Users</b>: list with all registered users.
45
+ * <b>Scopes</b>: authorization scopes administration.
46
+ * <b>Accesses</b>: clients that access the user's data.
47
+ * <b>Clients</b>: registered clients (third party application)
48
+
49
+ While the Users and Scopes sections are visible only to the admin, Accesses and Clients are available to every
50
+ registered user, also the ones that will grant access for their resources. To better understand what you can do
51
+ explore the Dashboard and read the following sections.
52
+
53
+ http://github.com/Lelylan/rest-oauth2-server/raw/development/public/images/screenshots/admin-dashboard.png
54
+
55
+
56
+ == Scopes explained
57
+
58
+ In a short way, scopes tell you <b>what can and can't be accessed</b>. The Rest OAuth 2.0 Server ships with a
59
+ flexible and powerful scope system which can be dynamically built.
60
+
61
+ http://github.com/Lelylan/rest-oauth2-server/raw/development/public/images/screenshots/scopes.png
62
+
63
+ To create a new scope click <b>Create a new scope</b> and you will get a simple form with two fields
64
+
65
+ * <b>Name</b>: unique alphanumeric key that identify a scope.
66
+ * <b>Values</b>: list of space separated alphanumeric strings, each of one refers to an action (built following the convention <b>{controller name}/{action name}</b>) or to an existing scope name.
67
+
68
+ Going a bit deeper you can define the accessible actions in two ways.
69
+
70
+ === Action specific values
71
+
72
+ You can specify *any* action present in your rails app. For example if you want to allow the access to the action
73
+ create in the controller pizzas you just add the string "pizzas/create". Here you can see an example on defining the
74
+ access to all RESTful actions in a sample pizzas controller.
75
+
76
+ http://github.com/Lelylan/rest-oauth2-server/raw/development/public/images/screenshots/pizzas-scope.png
77
+
78
+ === Scope name values
79
+
80
+ You can specify any group of actions adding a name scope. For example if the scope pizzas allows the access to all
81
+ actions in the pizzas controller and the scope pastas allow the access to all actions in pastas controller, then the
82
+ "all" "cope could have as values the list "pizzas pastas"
83
+
84
+ http://github.com/Lelylan/rest-oauth2-server/raw/development/public/images/screenshots/all-scope.png
85
+
86
+
87
+ == Protect your resources
88
+
89
+ After scopes are defined there is one more step. You need to protect the actions you want to authorize. To do thi
90
+ add the filter <tt>oauth_authorized</tt> in any controller you want to protect.
91
+
92
+ class PizzasController < ApplicationController
93
+ before_filter :oauth_authorized
94
+ ...
95
+
96
+ This filter verify if the client can access the specific action, regarding the scope that has been granted from the user.
97
+ You can also decide to protect all of your resources (they must accept JSON format) by uncommenting <tt>oauth_authorized</tt>
98
+ line in the {ApplicationController}[https://github.com/Lelylan/rest-oauth2-server/blob/master/app/controllers/application_controller.rb].
99
+
100
+ Last, you can make some actions public by using the <tt>exclude</tt> option.
101
+
102
+ before_filter :oauth_authorized, except: %w(index, show)
103
+
104
+
105
+ == Client definition
106
+
107
+ Every registered user can define a client (third party application). To do this access the dashboard and create your first
108
+ client filling these fields.
109
+
110
+ * <b>Name</b>: client name.
111
+ * <b>Siti URI</b>: client web site URI.
112
+ * <b>Redirect URI</b>: client redirect URI, used as callback after the user grant or deny the access.
113
+ * <b>Scope</b>: one or more scope names, separated by spaces (limit the possible accesses a client can have). By default a
114
+ scope named "all" is set as default. For this reason follow the convention to call "all" the scope that give all accesses.
115
+ * <b>Info</b>: additional information.
116
+
117
+ Once the client is create the additional field <b>client uri</b> and <b>secret</b> are generated. You will use these info
118
+ later on, during the authorization flows.
119
+
120
+ http://github.com/Lelylan/rest-oauth2-server/raw/development/public/images/screenshots/client-show.png
121
+
122
+ If you define a scope named <b>all</b> you can use one more functionality. You can click the button <b>Simulate Authorization</b>
123
+ that you can find in the end of the client detail page, and you will see the authorization page that a user would normally see
124
+ when granting access to a client.
125
+
126
+ http://github.com/Lelylan/rest-oauth2-server/raw/development/public/images/screenshots/authorization.png
127
+
128
+
129
+ === Block clients
130
+
131
+ The admin can access to all created clients and decide to block any of them, meaning all related access tokens are disabled.
132
+ This is pretty useful in cases where a client is considered "not safe". When a client is blocked every authorization request
133
+ will be disabled, until the admin unblock it.
134
+
135
+ http://github.com/Lelylan/rest-oauth2-server/raw/development/public/images/screenshots/block-clients.png
136
+
137
+
138
+ == Granted Clients (aka accesses)
139
+
140
+ Once users grant the access to their resources, the accesses list is updated. Here a user can see which clients are accessing
141
+ their resources, and with which frequency. One important functionality lies on the possibility for a user to block a specific
142
+ client, whenever it is considered "not safe".
143
+
144
+ http://github.com/Lelylan/rest-oauth2-server/raw/development/public/images/screenshots/access.png
145
+
146
+
147
+
148
+
149
+ = OAuth 2.0 flows explained
150
+
151
+ Today Rest OAuth 2.0 Server supports three flows of OAuth 2.0
152
+ * The server-side flow for web applications with servers that can securely store persistent information ({Authorization Code Flow}[http://tools.ietf.org/html/draft-ietf-oauth-v2-13#section-4.1])
153
+ * The client-side flow for JavaScript applications running in a browser ({Implicit Grant Flow}[http://tools.ietf.org/html/draft-ietf-oauth-v2-13#section-4.2])
154
+ * The native application flow for desktop and mobile applications ({Resource Owner Password Credentials Flow}[http://tools.ietf.org/html/draft-ietf-oauth-v2-13#section-4.3])
155
+
156
+
157
+ == OAuth 2.0 for server-side web applications
158
+
159
+ This flow is meant for web applications with servers that can keep secrets and maintain state.
160
+
161
+ The server-side flow has two parts. In the first part, your application asks the user for permission to access
162
+ their data. If the user approves, instead of sending an access token directly as in the client-side flow, the
163
+ Rest OAuth 2.0 Server will send to the client an authorization code. In the second part, the client will POST
164
+ that code along with its client secret to the Rest OAuth 2.0 Server in order to get the access token.
165
+
166
+ === Getting an access token
167
+
168
+ This flow begins by sending the user to the authorization endpoint <tt>/oauth/authorization</tt>
169
+ with the following query parameters
170
+
171
+ * <b>response_type</b> (REQUIRED): always use "code" as response type
172
+ * <b>client_id</b> (REQUIRED): client identifier (the URI of the client model)
173
+ * <b>redirect_uri</b> (REQUIRED): callback URI to the client application
174
+ * <b>scope</b> (REQUIRED): privileges given to the client
175
+ * <b>state</b> (OPTIONAL): opaque value used by the client to maintain state between the request and callback
176
+
177
+ Here's an example URL for a hypothetical app called "Example App" running on https://www.example.com
178
+
179
+ http://localhost:3000/oauth/authorization?
180
+ response_type=code&
181
+ client_id=http://localhost:3000/clients/a918F2fs3&
182
+ redirect_uri=httsp://www.example.com/callback&
183
+ scope=write&
184
+ state=2af5D3vds
185
+
186
+ And this is what you should see.
187
+
188
+ http://github.com/Lelylan/rest-oauth2-server/raw/development/public/images/screenshots/authorization.png
189
+
190
+ After the user approves access or chooses not to, we'll redirect to the <tt>redirect_uri</tt> you pass us. If the
191
+ user denies access, an error code is appended:
192
+
193
+ https://example.com/callback?error=access_denied&state=2af5D3vds
194
+
195
+ If the user approves access will be appended an authorization code in the query string of the URL:
196
+
197
+ https://example.com/callback?code=g2VDXwrT0S6iZeUeYQBYi2stxRy&state=2af5D3vds
198
+
199
+ Now, the client reached through the <tt>redirect_uri</tt> should swap that authorization code for an access token by POSTing
200
+ it along the following params to the token endpoint <tt>/oauth/token</tt> using the JSON format.
201
+
202
+ * <b>code</b> (REQUIRED): authorization code (from the previous step)
203
+ * <b>grant_type</b> (REQUIRED): always use "authorization_code" as grant type
204
+ * <b>client_id</b> (REQUIRED): client identifier (in our case is the uri field of the client)
205
+ * <b>client_secred</b> (REQUIRED): client secret code
206
+
207
+ Using curl the request might look like:
208
+
209
+ curl -i http://localhost:3000/oauth/token \
210
+ -H "Accept: application/json" \
211
+ -X POST -d '{
212
+ "code": "g2VDXwrT0S6iZeUeYQBYi2stxRy", \
213
+ "grant_type": "authorization_code", \
214
+ "client_id": "http://localhost:30000/clients/a918F2fs3", \
215
+ "client_secret": "a34a7afe4731e745de9d61iZeUeY" \
216
+ }'
217
+
218
+ The response is a JSON Object containing the access token:
219
+
220
+ {
221
+ "access_token": "SlAV32hkKG",
222
+ "expires_in": 1800,
223
+ "refresh_token": "Da8i1930LSj"
224
+ }
225
+
226
+ === Getting additional access tokens
227
+
228
+ When your access token expires, Rest OAuth 2.0 Server API endpoints will respond with HTTP 401 Unauthorized. At any time,
229
+ you can use the token endpoint with your refresh token with the following query parameters
230
+
231
+ * <b>grant_type</b> (REQUIRED): always use "refresh_token" as grant type
232
+ * <b>client_id</b> (REQUIRED): client identifier (in our case is the uri field of the client)
233
+ * <b>client_secred</b> (REQUIRED): client secret code
234
+ * <b>refresh_token</b> (REQUIRED): refresh token previusly received
235
+
236
+ Using curl the request might look like:
237
+
238
+ curl -i http://localhost:3000/oauth/token \
239
+ -H "Accept: application/json" \
240
+ -X POST -d '{
241
+ "grant_type": "refresh_token", \
242
+ "refresh_token": "Da8i1930LSj", \
243
+ "client_id": "http://localhost:30000/clients/a918F2fs3", \
244
+ "client_secret": "a34a7afe4731e745de9d61iZeUeY" \
245
+ }'
246
+
247
+ The response is a JSON Object containing the new access token.
248
+
249
+ {
250
+ "access_token": "AlYZ892hsKs",
251
+ "expires_in": 1800,
252
+ "refresh_token": "Da8i1930LSj"
253
+ }
254
+
255
+
256
+ === Going deep
257
+
258
+ If you are curious and you want to find more check the {acceptance}[https://github.com/Lelylan/rest-oauth2-server/blob/master/spec/acceptance/oauth/oauth_authorize_controller_spec.rb]
259
+ {tests}[https://github.com/Lelylan/rest-oauth2-server/blob/master/spec/acceptance/oauth/oauth_token_controller_spec.rb]
260
+ in the <b>authorization token flow</b> and <b>refresh token</b> context.
261
+
262
+
263
+
264
+ == OAuth 2.0 for client-side web applications
265
+
266
+ This flow is meant for JavaScript-based web applications that can't maintain state over time (it includes also ActionScript
267
+ and SilverLight).
268
+
269
+ === Getting a user's permission
270
+
271
+
272
+ This flow begins by sending the user to the authorization endpoint <tt>/oauth/authorization</tt>
273
+ with the following query parameters
274
+
275
+ * <b>response_type</b> (REQUIRED): always use "token" as response type
276
+ * <b>client_id</b> (REQUIRED): client identifier (the uri of the client model)
277
+ * <b>redirect_uri</b> (REQUIRED): callback URI to the client application
278
+ * <b>scope</b> (REQUIRED): privileges given to the client
279
+ * <b>state</b> (OPTIONAL): opaque value used by the client to maintain state between the request and callback
280
+
281
+ Here's an example URL for a hypothetical app called "Example App" running on https://www.example.com
282
+
283
+ http://localhost:3000/oauth/authorization?
284
+ response_type=token&
285
+ client_id=http://localhost:3000/clients/a918F2fs3&
286
+ redirect_uri=httsp://www.example.com/callback&
287
+ scope=write&
288
+ state=2af5D3vds
289
+
290
+ And this is what you should see.
291
+
292
+ http://github.com/Lelylan/rest-oauth2-server/raw/development/public/images/screenshots/authorization.png
293
+
294
+ After the user approves access or chooses not to, we'll redirect to the <tt>redirect_uri</tt> you pass. If the
295
+ user denies access, an error code is appended:
296
+
297
+ https://example.com/callback#error=access_denied&state=2af5D3vds
298
+
299
+ If the user approves will be appended an access token in the hash fragment of the UR:
300
+
301
+ https://example.com/callback#token=g2VDXwrT0S6iZeUeYQBYi2stxRy&expires_in=1800&state=2af5D3vds
302
+
303
+ JavaScript running on that page can grab that access token from the <tt>window.location.hash</tt> and either store it in a
304
+ cookie or POST it to a server. Note that the token is added to the {fragment URI}[http://en.wikipedia.org/wiki/Fragment_identifier].
305
+ This is done because the fragment URI can not be read from server side, but only from client-based applications.
306
+
307
+ === Getting additional access tokens
308
+
309
+ When your access token expires, our API endpoints will respond with HTTP 401 Unauthorized. At any time, you can send
310
+ your user to the same authorization endpoint you used in the previous step. If the user has already authorized your
311
+ application for the scopes you're requesting, Rest OAuth Server won't show the OAuth dialog and will immediately redirect
312
+ to the <tt>redirect_uri</tt> you pass us with a new access token.
313
+
314
+ === Going deep
315
+
316
+ If you are curious and you want to find more check the {acceptance tests}[https://github.com/Lelylan/rest-oauth2-server/blob/master/spec/acceptance/oauth/oauth_authorize_controller_spec.rb]
317
+ in the <b>implicit token flow</b> and <b>refresh implicit token flow</b> context.
318
+
319
+
320
+
321
+ == OAuth 2.0 for native applications
322
+
323
+ This flow is meant for mobile, and desktop installed applications that want access to user data (native apps).
324
+
325
+ This flow is suitable in cases where the resource owner has a trust relationship with the client, such as its computer operating
326
+ system or a highly privileged application. The authorization server should take special care when enabling the grant type, and
327
+ <b>only when other flows are not viable</b>, because username and password are shared with the client.
328
+
329
+ === Getting an access token
330
+
331
+ The client should POST to the token endpoint <tt>/oauth/token</tt> along with the following params
332
+ using the JSON format:
333
+
334
+ * <b>grant_type</b> (REQUIRED): always use "password" as grant type
335
+ * <b>username</b> (REQUIRED): resource owner email address
336
+ * <b>password</b> (REQUIRED): resource owner password
337
+ * <b>client_id</b> (REQUIRED): client identifier (the uri of the client model)
338
+ * <b>redirect_uri</b> (REQUIRED): callback URI to the client application
339
+ * <b>scope</b> (REQUIRED): privileges given to the client
340
+
341
+ Using curl the request might look like:
342
+
343
+ curl -i http://localhost:3000/oauth/token \
344
+ -H "Accept: application/json" \
345
+ -X POST -d '{
346
+ "grant_type": "password", \
347
+ "client_id": "http://localhost:3000/clients/a918F2fs3", \
348
+ "client_secret": "a34a7afe4731e745de9d61iZeUeY", \
349
+ "username": "alice@example.com", \
350
+ "password": "example", \
351
+ "scope": "write" \
352
+ }'
353
+
354
+ The response is a JSON Object containing the access token:
355
+
356
+ {
357
+ "access_token": "AlYZ892hsKs",
358
+ "expires_in": 1800,
359
+ "refresh_token": "Da8i1930LSj"
360
+ }
361
+
362
+ === Getting additional access tokens
363
+
364
+ When your access token expires, Rest OAuth 2.0 Server API endpoints will respond with HTTP 401 Unauthorized. At any time,
365
+ you can use the token endpoint with your refresh token with the following query parameters
366
+
367
+ * <b>grant_type</b> (REQUIRED): always use "refresh_token" as grant type
368
+ * <b>client_id</b> (REQUIRED): client identifier (in our case is the uri field of the client)
369
+ * <b>client_secred</b> (REQUIRED): client secret code
370
+ * <b>refresh_token</b> (REQUIRED): refresh token previusly received
371
+
372
+ Using curl the request might look like:
373
+
374
+ curl -i http://localhost:3000/oauth/token \
375
+ -H "Accept: application/json" \
376
+ -X POST -d '{
377
+ "grant_type": "refresh_token", \
378
+ "refresh_token": "Da8i1930LSj", \
379
+ "client_id": "http://localhost:30000/clients/a918F2fs3", \
380
+ "client_secret": "a34a7afe4731e745de9d61iZeUeY" \
381
+ }'
382
+
383
+ The response is a JSON Object containing the new access token.
384
+
385
+ {
386
+ "access_token": "AlYZ892hsKs",
387
+ "expires_in": 1800,
388
+ "refresh_token": "Da8i1930LSj"
389
+ }
390
+
391
+ === Going deep
392
+
393
+ If you are curious and you want to find more check the {acceptance tests}[https://github.com/Lelylan/rest-oauth2-server/blob/master/spec/acceptance/oauth/oauth_token_controller_spec.rb]
394
+ in the <b>password credentials flow</b> and <b>refresh token</b> context.
395
+
396
+
397
+
398
+ = How to use Access Token
399
+
400
+ To make API requests on the behalf of a user, pass the OAuth token in the query string, as a header, or as a parameter
401
+ in the request body when making a POST request.
402
+
403
+ Query string example.
404
+
405
+ GET /pizzas?token=AlYZ892hsKs
406
+
407
+ Header example.
408
+
409
+ GET /pizzas
410
+ Authorization: OAuth2 AlYZ892hsKs
411
+
412
+ Request body example.
413
+
414
+ POST /pizzas
415
+ token=AlYZ892hsKs&...
416
+
417
+ Note that all requests must be done using HTTPS.
418
+
419
+
420
+
421
+ = Miscellaneous
422
+
423
+ == OAuth 2.0 options
424
+
425
+ Rest OAuth 2.0 Server allows you to personalize some options changing {oauth.yml}[https://github.com/Lelylan/rest-oauth2-server/blob/master/config/oauth.yml]
426
+
427
+ * <b>token_expires_in</b>: define the seconds after which the access token expires.
428
+ * <b>authorization_expires_in</b>: define the seconds after which the authorization code expires.
429
+ * <b>secure_random</b>: define the lenght of tokens, code and secret keys.
430
+ * <b>scope_separator</b>: define the separator used between different scope keys.
431
+
432
+
433
+ == OAuth 2.0 Models
434
+
435
+ Rest OAuth 2.0 Server is working on top of 5 models. They are pretty simple so if you want to have more information about
436
+ them, check the source code, which is clearly documented.
437
+
438
+ * {OauthClient}[https://github.com/Lelylan/rest-oauth2-server/blob/master/app/models/client.rb]: represents the credentials of a client application.
439
+ * {OauthToken}[https://github.com/Lelylan/rest-oauth2-server/blob/master/app/models/oauth/oauth_token.rb]: represents the token used to access user's resources.
440
+ * {OauthAuthorizarion}[https://github.com/Lelylan/rest-oauth2-server/blob/master/app/models/oauth/oauth_authorization.rb]: represents the authorization token used to exchange an access token.
441
+ * {OauthAccess}[https://github.com/Lelylan/rest-oauth2-server/blob/master/app/models/oauth/oauth_access.rb]: represents the relation between a client and a user, whenever a user grant an authorization.
442
+ * {OauthDailyRequests}[https://github.com/Lelylan/rest-oauth2-server/blob/master/app/models/oauth/oauth_daily_request.rb]: represents a daily request from the client on behalf of a specific user.
443
+
444
+
445
+ == Basic authentication system
446
+
447
+ In addition to the models above there is a basic authentication system
448
+
449
+ * {User}[https://github.com/Lelylan/rest-oauth2-server/blob/master/app/models/user.rb]: represents the basic user authentication functionalities
450
+ * {UsersController}[https://github.com/Lelylan/rest-oauth2-server/blob/master/app/controllers/users_controller.rb]: represents the user definition
451
+ * {SessionsController}[https://github.com/Lelylan/rest-oauth2-server/blob/master/app/controllers/sessions_controller.rb]: represents the session definition
452
+
453
+ This model is kept simple on purpose, but you can easily change it with the authentication system you prefer like {Authlogic}[https://github.com/binarylogic/authlogic],
454
+ {Devise}[https://github.com/plataformatec/devise] or {Warden}[https://github.com/hassox/warden]. Just remember that your user model <b>must</b>
455
+ define an <tt>uri</tt> field, which is used as identifier on the OAuth 2.0 flows. Any help on integration is appreciated.
456
+
457
+
458
+ == Blocking system explained
459
+
460
+ One important feature lie in the ability of to block a client. Rest OAuth 2.0 server enables you two possibilities:
461
+
462
+ * <b>Client block</b> via <tt>client.block!</tt>: used to block a not safe client for all users.
463
+ * <b>User block a client</b> via <tt>access.block!</tt>: used when a user want to revoke any access to his resources to a specific client.
464
+ * <b>User block an access token</b> via <tt>token.block!</tt>: used when a user logout from the client and want to revoke the token access.
465
+
466
+ In the first two cases it is possible to unblock the client using the <tt>unblock!</tt> method.
467
+
468
+
469
+ == Testing solutions
470
+
471
+ Tests are made using {Steak}[https://github.com/cavalle/steak], {Capybara}[https://github.com/jnicklas/capybara]
472
+ and {RSpec}[https://github.com/rspec/rspec-rails]. If you want to know more check the tests about {models}[https://github.com/Lelylan/rest-oauth2-server/tree/development/spec/models]
473
+ and {acceptance tests}[https://github.com/Lelylan/rest-oauth2-server/tree/development/spec/acceptance].
474
+
475
+
476
+
477
+ = Other OAuth2 documentation
478
+
479
+ If the way OAuth2 works is not clear, you can find great documentation on the web.
480
+
481
+ * {Oauth2 Specifications}[http://tools.ietf.org/html/draft-ietf-oauth-v2-13]
482
+ * {Google OAuth2}[http://code.google.com/apis/accounts/docs/OAuth2.html]
483
+ * {Facebook OAuth2}[http://developers.facebook.com/docs/authentication]
484
+ * {Gowalla OAuth2}[http://gowalla.com/api/docs/oauth]
485
+ * {Foursquare OAuth2}[http://developer.foursquare.com/docs/oauth.html]
486
+ * {Instagram OAuth2}[http://instagram.com/developer/auth/]
487
+
488
+
489
+
490
+ = Other OAuth2 Ruby Implementations
491
+
492
+ * {Flowtown Rack OAuth2 Server}[https://github.com/flowtown/rack-oauth2-server]
493
+ * {Nov Rack OAuth2}[https://github.com/nov/rack-oauth2]
494
+ * {ThoughWorks OAuth2 Provider}[https://github.com/ThoughtWorksStudios/oauth2_provider]
495
+ * {Freerange OAuth2 Provider}[https://github.com/freerange/oauth2-provider/blob/master/lib/oauth2/provider/models/access_token.rb]
496
+
497
+
498
+
499
+ = Contributing
500
+
501
+ Follow {MongoID guidelines}[http://mongoid.org/docs/contributing.html]
502
+
503
+
504
+ = Authors
505
+
506
+ {Andrea Reginato}[mailto:andrea.reginato@gmail.com] &
507
+ {The Lelylan Team}[http://lelylan.com]
508
+
509
+ A special thanks to the OAuth 2.0 specification team, to the Flowtown Rack Oauth2 Server which gave the
510
+ initial ideas of the project and to Google OAuth 2.0 specification for making them so clear to understand.
511
+
512
+
513
+
514
+ = Changelog
515
+
516
+ See {CHANGELOG}[link:blob/master/CHANGELOG.rdoc]
517
+
518
+
519
+
520
+ = License
521
+
522
+ Rest OAuth 2.0 Server is available under the MIT license.