devise_oauth 2.0.0 → 2.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 (67) hide show
  1. data/.gitignore +7 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +17 -0
  4. data/Gemfile.lock +136 -0
  5. data/README.md +77 -0
  6. data/app/controllers/{oauth → devise/oauth}/access_tokens_controller.rb +0 -0
  7. data/app/controllers/{oauth → devise/oauth}/accesses_controller.rb +0 -0
  8. data/app/controllers/{oauth → devise/oauth}/authorizations_controller.rb +0 -0
  9. data/app/controllers/{oauth → devise/oauth}/clients_controller.rb +0 -0
  10. data/app/models/{oauth → devise/oauth}/access.rb +0 -0
  11. data/app/models/{oauth → devise/oauth}/access_token.rb +0 -0
  12. data/app/models/{oauth → devise/oauth}/authorization.rb +0 -0
  13. data/app/models/{oauth → devise/oauth}/client.rb +0 -0
  14. data/devise_oauth.gemspec +27 -0
  15. data/lib/devise/oauth/engine.rb +7 -2
  16. data/lib/devise/oauth/version.rb +1 -1
  17. data/script/rails +8 -0
  18. data/spec/controllers/access_tokens_controller_spec.rb +208 -0
  19. data/spec/controllers/authorizations_controller_spec.rb +53 -0
  20. data/spec/controllers/protected_resources_controller_spec.rb +79 -0
  21. data/spec/dummy/README.rdoc +261 -0
  22. data/spec/dummy/Rakefile +7 -0
  23. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  24. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  25. data/spec/dummy/app/controllers/application_controller.rb +7 -0
  26. data/spec/dummy/app/controllers/protected_resources_controller.rb +14 -0
  27. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  28. data/spec/dummy/app/mailers/.gitkeep +0 -0
  29. data/spec/dummy/app/models/.gitkeep +0 -0
  30. data/spec/dummy/app/models/ability.rb +15 -0
  31. data/spec/dummy/app/models/user.rb +13 -0
  32. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  33. data/spec/dummy/config.ru +4 -0
  34. data/spec/dummy/config/application.rb +67 -0
  35. data/spec/dummy/config/boot.rb +10 -0
  36. data/spec/dummy/config/database.yml +25 -0
  37. data/spec/dummy/config/environment.rb +5 -0
  38. data/spec/dummy/config/environments/development.rb +37 -0
  39. data/spec/dummy/config/environments/production.rb +67 -0
  40. data/spec/dummy/config/environments/test.rb +37 -0
  41. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  42. data/spec/dummy/config/initializers/devise.rb +216 -0
  43. data/spec/dummy/config/initializers/inflections.rb +15 -0
  44. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  45. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  46. data/spec/dummy/config/initializers/session_store.rb +8 -0
  47. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  48. data/spec/dummy/config/locales/devise.en.yml +57 -0
  49. data/spec/dummy/config/locales/en.yml +5 -0
  50. data/spec/dummy/config/routes.rb +7 -0
  51. data/spec/dummy/db/migrate/20120622183848_devise_create_users.rb +46 -0
  52. data/spec/dummy/db/schema.rb +34 -0
  53. data/spec/dummy/lib/assets/.gitkeep +0 -0
  54. data/spec/dummy/log/.gitkeep +0 -0
  55. data/spec/dummy/public/404.html +26 -0
  56. data/spec/dummy/public/422.html +26 -0
  57. data/spec/dummy/public/500.html +25 -0
  58. data/spec/dummy/public/favicon.ico +0 -0
  59. data/spec/dummy/script/rails +6 -0
  60. data/spec/factories.rb +34 -0
  61. data/spec/models/oauth/access_token_spec.rb +25 -0
  62. data/spec/models/oauth/authorization_spec.rb +19 -0
  63. data/spec/models/oauth/client_spec.rb +31 -0
  64. data/spec/models/user_spec.rb +10 -0
  65. data/spec/spec_helper.rb +39 -0
  66. data/spec/support/match_json.rb +6 -0
  67. metadata +134 -30
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ .bundle/
2
+ log/*.log
3
+ pkg/
4
+ spec/dummy/db/*.sqlite3
5
+ spec/dummy/log/*.log
6
+ spec/dummy/tmp/
7
+ spec/dummy/.sass-cache
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Declare your gem's dependencies in devise_oauth.gemspec.
4
+ # Bundler will treat runtime dependencies like base dependencies, and
5
+ # development dependencies will be added by default to the :development group.
6
+ gemspec
7
+
8
+ # jquery-rails is used by the dummy application
9
+ gem 'jquery-rails'
10
+ gem 'devise'
11
+
12
+ gem 'database_cleaner'
13
+ gem 'factory_girl_rails'
14
+ gem 'rspec-rails', '>= 2.0'
15
+ gem 'shoulda-matchers'
16
+
17
+ gem 'cancan'
data/Gemfile.lock ADDED
@@ -0,0 +1,136 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ devise_oauth (2.0.1)
5
+ devise (>= 2.1)
6
+ rails (>= 3.2.0)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ actionmailer (3.2.6)
12
+ actionpack (= 3.2.6)
13
+ mail (~> 2.4.4)
14
+ actionpack (3.2.6)
15
+ activemodel (= 3.2.6)
16
+ activesupport (= 3.2.6)
17
+ builder (~> 3.0.0)
18
+ erubis (~> 2.7.0)
19
+ journey (~> 1.0.1)
20
+ rack (~> 1.4.0)
21
+ rack-cache (~> 1.2)
22
+ rack-test (~> 0.6.1)
23
+ sprockets (~> 2.1.3)
24
+ activemodel (3.2.6)
25
+ activesupport (= 3.2.6)
26
+ builder (~> 3.0.0)
27
+ activerecord (3.2.6)
28
+ activemodel (= 3.2.6)
29
+ activesupport (= 3.2.6)
30
+ arel (~> 3.0.2)
31
+ tzinfo (~> 0.3.29)
32
+ activeresource (3.2.6)
33
+ activemodel (= 3.2.6)
34
+ activesupport (= 3.2.6)
35
+ activesupport (3.2.6)
36
+ i18n (~> 0.6)
37
+ multi_json (~> 1.0)
38
+ arel (3.0.2)
39
+ bcrypt-ruby (3.0.1)
40
+ builder (3.0.0)
41
+ cancan (1.6.7)
42
+ database_cleaner (0.8.0)
43
+ devise (2.1.0)
44
+ bcrypt-ruby (~> 3.0)
45
+ orm_adapter (~> 0.0.7)
46
+ railties (~> 3.1)
47
+ warden (~> 1.1.1)
48
+ diff-lcs (1.1.3)
49
+ erubis (2.7.0)
50
+ factory_girl (3.4.0)
51
+ activesupport (>= 3.0.0)
52
+ factory_girl_rails (3.4.0)
53
+ factory_girl (~> 3.4.0)
54
+ railties (>= 3.0.0)
55
+ hike (1.2.1)
56
+ i18n (0.6.0)
57
+ journey (1.0.4)
58
+ jquery-rails (2.0.2)
59
+ railties (>= 3.2.0, < 5.0)
60
+ thor (~> 0.14)
61
+ json (1.7.3)
62
+ mail (2.4.4)
63
+ i18n (>= 0.4.0)
64
+ mime-types (~> 1.16)
65
+ treetop (~> 1.4.8)
66
+ mime-types (1.19)
67
+ multi_json (1.3.6)
68
+ orm_adapter (0.0.7)
69
+ polyglot (0.3.3)
70
+ rack (1.4.1)
71
+ rack-cache (1.2)
72
+ rack (>= 0.4)
73
+ rack-ssl (1.3.2)
74
+ rack
75
+ rack-test (0.6.1)
76
+ rack (>= 1.0)
77
+ rails (3.2.6)
78
+ actionmailer (= 3.2.6)
79
+ actionpack (= 3.2.6)
80
+ activerecord (= 3.2.6)
81
+ activeresource (= 3.2.6)
82
+ activesupport (= 3.2.6)
83
+ bundler (~> 1.0)
84
+ railties (= 3.2.6)
85
+ railties (3.2.6)
86
+ actionpack (= 3.2.6)
87
+ activesupport (= 3.2.6)
88
+ rack-ssl (~> 1.3.2)
89
+ rake (>= 0.8.7)
90
+ rdoc (~> 3.4)
91
+ thor (>= 0.14.6, < 2.0)
92
+ rake (0.9.2.2)
93
+ rdoc (3.12)
94
+ json (~> 1.4)
95
+ rspec (2.10.0)
96
+ rspec-core (~> 2.10.0)
97
+ rspec-expectations (~> 2.10.0)
98
+ rspec-mocks (~> 2.10.0)
99
+ rspec-core (2.10.1)
100
+ rspec-expectations (2.10.0)
101
+ diff-lcs (~> 1.1.3)
102
+ rspec-mocks (2.10.1)
103
+ rspec-rails (2.10.1)
104
+ actionpack (>= 3.0)
105
+ activesupport (>= 3.0)
106
+ railties (>= 3.0)
107
+ rspec (~> 2.10.0)
108
+ shoulda-matchers (1.2.0)
109
+ activesupport (>= 3.0.0)
110
+ sprockets (2.1.3)
111
+ hike (~> 1.2)
112
+ rack (~> 1.0)
113
+ tilt (~> 1.1, != 1.3.0)
114
+ sqlite3 (1.3.6)
115
+ thor (0.15.3)
116
+ tilt (1.3.3)
117
+ treetop (1.4.10)
118
+ polyglot
119
+ polyglot (>= 0.3.1)
120
+ tzinfo (0.3.33)
121
+ warden (1.1.1)
122
+ rack (>= 1.0)
123
+
124
+ PLATFORMS
125
+ ruby
126
+
127
+ DEPENDENCIES
128
+ cancan
129
+ database_cleaner
130
+ devise
131
+ devise_oauth!
132
+ factory_girl_rails
133
+ jquery-rails
134
+ rspec-rails (>= 2.0)
135
+ shoulda-matchers
136
+ sqlite3
data/README.md CHANGED
@@ -1,3 +1,80 @@
1
1
  # Devise::Oauth
2
2
 
3
+ ## Installation
4
+
5
+ Add it to your Gemfile
6
+
7
+ ```ruby
8
+ gem 'devise_oauth'
9
+ ```
10
+
11
+ Mount engine in your routes.rb file
12
+
13
+ ```ruby
14
+ mount Devise::Oauth::Engine => '/oauth'
15
+ ```
16
+
17
+ Define possible scopes in your application.rb
18
+
19
+ ```ruby
20
+ Devise::Oauth.scopes = [:read, :write]
21
+ ```
22
+
23
+ Add strategies to your User model
24
+
25
+ ```ruby
26
+ class User < ActiveRecord::Base
27
+ devise :database_authenticatable,
28
+ #:registerable,
29
+ #:recoverable,
30
+ #:rememberable,
31
+ #:trackable,
32
+ #:omniauthable,
33
+
34
+ # OAuth provider
35
+ :access_token_authenticatable,
36
+ :client_ownable,
37
+ :resource_ownable
38
+ ```
39
+
40
+ Create migration [TODO: write generator]
41
+
42
+ look at `db/migrate/20120622164619_devise_create_oauth.rb` for now
43
+
44
+ ## CanCan support
45
+
46
+ if your app is accessed with `access_token` then we set it as `oauth_token` to current_user
47
+
48
+ ```ruby
49
+ class Ability
50
+ include CanCan::Ability
51
+
52
+ def initialize(user)
53
+ user ||= User.new # guest user (not logged in)
54
+ if user.oauth_token?
55
+ # has access_token, so we set access rights with scope
56
+ setup_client(user)
57
+ else
58
+ # normal user access rights setup
59
+ setup(user)
60
+ end
61
+
62
+ # See the wiki for details: https://github.com/ryanb/cancan/wiki/Defining-Abilities
63
+ end
64
+
65
+ private
66
+
67
+ def setup_client(user)
68
+ if user.oauth_scope? :write
69
+ can :create, :protected_resource
70
+ end
71
+ end
72
+
73
+ def setup(user)
74
+
75
+ end
76
+ end
77
+ ```
78
+
79
+
3
80
  This project rocks and uses MIT-LICENSE.
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,27 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ require "devise/oauth/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "devise_oauth"
7
+ s.version = Devise::Oauth::VERSION
8
+ s.authors = ["Yury Korolev"]
9
+ s.email = ["yury.korolev@gmail.com"]
10
+ s.homepage = "https://github.com/anjlab/devise_oauth"
11
+ s.summary = "Oauth 2.0 provider implementation on top of devise."
12
+ s.description = "The OAuth 2.0 Authorization Framework draft-ietf-oauth-v2-28 implementation on top of devise."
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_dependency "rails", ">= 3.2.0"
20
+ s.add_dependency "devise", ">= 2.1"
21
+
22
+ s.add_development_dependency "sqlite3"
23
+ s.add_development_dependency "factory_girl_rails"
24
+ s.add_development_dependency "rspec-rails", ">= 2.0"
25
+ s.add_development_dependency "database_cleaner"
26
+ s.add_development_dependency "shoulda-matchers"
27
+ end
@@ -1,13 +1,18 @@
1
1
  module Devise::Oauth
2
2
  class Engine < ::Rails::Engine
3
+
4
+ NAME = "oauth"
5
+
3
6
  def table_name_prefix
4
- "oauth"
7
+ NAME
5
8
  end
6
9
 
7
10
  def self.generate_railtie_name(mod)
8
- "oauth"
11
+ NAME
9
12
  end
10
13
 
14
+ engine_name NAME
15
+
11
16
  isolate_namespace Devise::Oauth
12
17
 
13
18
  initializer "devise_oauth.initialize_application", before: :load_config_initializers do |app|
@@ -1,5 +1,5 @@
1
1
  module Devise
2
2
  module Oauth
3
- VERSION = "2.0.0"
3
+ VERSION = "2.0.1"
4
4
  end
5
5
  end
data/script/rails ADDED
@@ -0,0 +1,8 @@
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
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
5
+ ENGINE_PATH = File.expand_path('../../lib/devise/oauth/engine', __FILE__)
6
+
7
+ require 'rails/all'
8
+ require 'rails/engine/commands'
@@ -0,0 +1,208 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples "client is blocked flow" do
4
+ before do
5
+ client.block!
6
+ post :create, attributes
7
+ end
8
+
9
+ it { should respond_with :unprocessable_entity }
10
+ it { should respond_with_content_type :json }
11
+ it "should have error 'invalid_request'" do
12
+ res = JSON.load(response.body)
13
+ res['error'].should == "invalid_request"
14
+ res['error_description'].should == "Client Blocked"
15
+ end
16
+ end
17
+
18
+ shared_examples "access is blocked (resource owner block a client) flow" do
19
+ before do
20
+ access.block!
21
+ post :create, attributes
22
+ end
23
+ it { should respond_with :unprocessable_entity }
24
+ it { should respond_with_content_type :json }
25
+ end
26
+
27
+ shared_examples "invalid client_id flow" do
28
+ before do
29
+ attributes.merge!(client_id: "not_existing")
30
+ post :create, attributes
31
+ end
32
+
33
+ it { should respond_with :unprocessable_entity }
34
+ it { should respond_with_content_type :json }
35
+
36
+ it "should have error 'invalid_request'" do
37
+ res = JSON.load(response.body)
38
+ res['error'].should == "invalid_request"
39
+ res['error_description'].should == "Client not found"
40
+ end
41
+ end
42
+
43
+ describe Devise::Oauth::AccessTokensController do
44
+ before(:each) {
45
+ @routes = Devise::Oauth::Engine.routes
46
+ @user = create(:user)
47
+ @client = create(:client)
48
+ @authorization = create(:authorization, client: @client, resource_owner: @user)
49
+ @access = create(:access, client: @client, resource_owner: @user)
50
+ }
51
+
52
+ let(:user) { @user }
53
+ let(:client) { @client }
54
+ let(:authorization) { @authorization }
55
+ let(:access) { @access}
56
+
57
+ context "Authorization code" do
58
+ let(:attributes) {
59
+ {
60
+ grant_type: "authorization_code",
61
+ client_id: client.identifier,
62
+ client_secret: client.secret,
63
+ code: authorization.code,
64
+ redirect_uri: client.redirect_uris.first
65
+ }
66
+ }
67
+
68
+ context "main flow" do
69
+ before do
70
+ post :create, attributes
71
+ end
72
+ let (:access_token) { @access_token = Devise::Oauth::AccessToken.last }
73
+
74
+ it { should respond_with :ok }
75
+ it { should respond_with_content_type :json }
76
+ it "should create new access token" do
77
+ access_token.should be_present
78
+ end
79
+
80
+ it "has valid access token in response" do
81
+ response.body.should match_json(access_token.token_response)
82
+ end
83
+ end
84
+
85
+ context "not valid code flow" do
86
+ before do
87
+ attributes.merge!(code: "not_existing")
88
+ post :create, attributes
89
+ end
90
+
91
+ it { should respond_with :unprocessable_entity }
92
+ it { should respond_with_content_type :json }
93
+ it "should have error 'invalid_request'" do
94
+ res = JSON.load(response.body)
95
+ res['error'].should == "invalid_request"
96
+ res['error_description'].should == "Authorization not found"
97
+ end
98
+ end
99
+
100
+ context "authorization is expired flow" do
101
+ before do
102
+ authorization.expire!
103
+ post :create, attributes
104
+ end
105
+
106
+ it { should respond_with :unprocessable_entity }
107
+ it { should respond_with_content_type :json }
108
+
109
+ it "should have error 'invalid_request'" do
110
+ res = JSON.load(response.body)
111
+ res['error'].should == "invalid_request"
112
+ res['error_description'].should == 'Authorization expired'
113
+ end
114
+ end
115
+
116
+ it_behaves_like "client is blocked flow"
117
+ it_behaves_like "access is blocked (resource owner block a client) flow"
118
+ it_behaves_like "invalid client_id flow"
119
+ end
120
+
121
+ context "Password credentials" do
122
+ let(:attributes) {
123
+ {
124
+ grant_type: "password",
125
+ client_id: client.identifier,
126
+ client_secret: client.secret,
127
+ username: user.email,
128
+ password: user.password,
129
+ scope: ""
130
+ }
131
+ }
132
+
133
+ context "main flow" do
134
+ before do
135
+ post :create, attributes
136
+ end
137
+ let (:access_token) { @access_token = Devise::Oauth::AccessToken.last }
138
+
139
+ it { should respond_with :ok }
140
+ it { should respond_with_content_type :json }
141
+ it "should create new access token" do
142
+ access_token.should be_present
143
+ end
144
+
145
+ it "has valid access token in response" do
146
+ response.body.should match_json(access_token.token_response)
147
+ end
148
+ end
149
+
150
+ context "not valid user password flow" do
151
+ before do
152
+ attributes.merge!(password: "not_existing")
153
+ post :create, attributes
154
+ end
155
+ ## TODO: bad request? or may be unauthorized?
156
+ it { should respond_with :bad_request }
157
+ it { should respond_with_content_type :json }
158
+ end
159
+
160
+ it_behaves_like "client is blocked flow"
161
+ it_behaves_like "access is blocked (resource owner block a client) flow"
162
+ it_behaves_like "invalid client_id flow"
163
+ end
164
+
165
+ context "Refresh Token" do
166
+ let(:token) { create(:access_token, resource_owner: user, client: client) }
167
+
168
+ let(:attributes) {
169
+ {
170
+ grant_type: "refresh_token",
171
+ refresh_token: token.refresh_token,
172
+ client_id: client.identifier,
173
+ client_secret: client.secret
174
+ }
175
+ }
176
+
177
+ context "main flow" do
178
+ before do
179
+ post :create, attributes
180
+ end
181
+ let (:access_token) { @access_token = Devise::Oauth::AccessToken.last }
182
+
183
+ it { should respond_with :ok }
184
+ it { should respond_with_content_type :json }
185
+ it "should create new access token" do
186
+ access_token.should be_present
187
+ end
188
+
189
+ it "has valid access token in response" do
190
+ response.body.should match_json(access_token.token_response)
191
+ end
192
+ end
193
+
194
+ context "no valid refresh token flow" do
195
+ before do
196
+ attributes.merge!(refresh_token: "not_existing")
197
+ post :create, attributes
198
+ end
199
+ it { should respond_with :bad_request }
200
+ it { should respond_with_content_type :json }
201
+ # page.should have_content "Refresh token not found"
202
+ end
203
+
204
+ it_behaves_like "client is blocked flow"
205
+ it_behaves_like "access is blocked (resource owner block a client) flow"
206
+ it_behaves_like "invalid client_id flow"
207
+ end
208
+ end