opro 0.0.1.pre1.0.2 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. data/Gemfile +1 -0
  2. data/Gemfile.lock +4 -0
  3. data/app/controllers/oauth/auth_controller.rb +10 -0
  4. data/app/controllers/oauth/tests_controller.rb +31 -3
  5. data/app/controllers/opro_application_controller.rb +1 -1
  6. data/app/models/oauth/access_grant.rb +11 -1
  7. data/app/models/oauth/client_application.rb +4 -0
  8. data/app/views/oauth/auth/new.html.erb +24 -4
  9. data/app/views/oauth/tests/index.html.erb +1 -1
  10. data/lib/generators/active_record/templates/access_grants.rb +8 -7
  11. data/lib/generators/active_record/templates/client_applications.rb +1 -0
  12. data/lib/generators/templates/opro.rb +8 -2
  13. data/lib/opro.rb +14 -5
  14. data/lib/opro/controllers/application_controller_helper.rb +17 -4
  15. data/lib/opro/controllers/concerns/error_messages.rb +23 -0
  16. data/lib/opro/controllers/concerns/permissions.rb +89 -0
  17. data/opro.gemspec +13 -5
  18. data/test/controllers/permissions_test.rb +27 -0
  19. data/test/dummy/app/controllers/products_controller.rb +8 -0
  20. data/test/dummy/app/views/pages/index.html.erb +2 -1
  21. data/test/dummy/app/views/products/create.html.erb +1 -0
  22. data/test/dummy/config/initializers/opro.rb +7 -1
  23. data/test/dummy/config/routes.rb +2 -0
  24. data/test/dummy/db/migrate/20120514060322_create_opro_access_grants.rb +15 -0
  25. data/test/dummy/db/migrate/{20120408165730_create_opro_client_applications.rb → 20120514060323_create_opro_client_applications.rb} +1 -0
  26. data/test/dummy/db/schema.rb +5 -3
  27. data/test/integration/auth_controller_test.rb +22 -8
  28. data/test/test_helper.rb +1 -3
  29. metadata +46 -30
  30. data/test/dummy/db/migrate/20120408165729_create_opro_access_grants.rb +0 -14
data/Gemfile CHANGED
@@ -7,6 +7,7 @@ gem "rails" , ">= 3.0.7"
7
7
  gem 'bluecloth'
8
8
 
9
9
  group :development, :test do
10
+ gem 'mocha'
10
11
  gem 'jeweler', "~> 1.6.4"
11
12
  gem "bundler", ">= 1.1.3"
12
13
 
@@ -64,7 +64,10 @@ GEM
64
64
  i18n (>= 0.4.0)
65
65
  mime-types (~> 1.16)
66
66
  treetop (~> 1.4.8)
67
+ metaclass (0.0.1)
67
68
  mime-types (1.18)
69
+ mocha (0.11.4)
70
+ metaclass (~> 0.0.1)
68
71
  multi_json (1.2.0)
69
72
  nokogiri (1.5.2)
70
73
  orm_adapter (0.0.7)
@@ -132,6 +135,7 @@ DEPENDENCIES
132
135
  devise
133
136
  jeweler (~> 1.6.4)
134
137
  launchy
138
+ mocha
135
139
  rails (>= 3.0.7)
136
140
  rcov
137
141
  simplecov
@@ -6,12 +6,15 @@ class Oauth::AuthController < ApplicationController
6
6
  def new
7
7
  @redirect_uri = params[:redirect_uri]
8
8
  @client_app = Oauth::ClientApplication.find_by_app_id(params[:client_id])
9
+ @scopes = scope_from_params(params)
9
10
  end
10
11
 
11
12
  def authorize
12
13
  application = Oauth::ClientApplication.find_by_app_id(params[:client_id])
14
+ permissions = params[:permissions]
13
15
  access_grant = Oauth::AccessGrant.where( :user_id => current_user.id, :application_id => application.id).first
14
16
  access_grant ||= Oauth::AccessGrant.create(:user => current_user, :application => application)
17
+ access_grant.update_attributes(:permissions => permissions) if access_grant.permissions != permissions
15
18
  redirect_to access_grant.redirect_uri_for(params[:redirect_uri])
16
19
  end
17
20
 
@@ -57,6 +60,13 @@ class Oauth::AuthController < ApplicationController
57
60
  Oauth::AccessGrant.where(:application_id => @client_app.id, :user_id => user.id).present?
58
61
  end
59
62
 
63
+ def scope_from_params(params)
64
+ requested_scope = (params[:scope]||[]).map(&:downcase)
65
+ default_scope = ::Opro.request_permissions.map(&:to_s).map(&:downcase)
66
+ return default_scope if requested_scope.blank?
67
+ requested_scope & default_scope
68
+ end
69
+
60
70
 
61
71
  # We're verifying that a post was made from our own site, indicating a user confirmed via form
62
72
  def user_authorizes_the_request?(request)
@@ -23,6 +23,23 @@ class Oauth::TestsController < ApplicationController
23
23
  end
24
24
  end
25
25
 
26
+ def create
27
+ result = if valid_oauth?
28
+ {:status => 200, :message => 'OAuth Worked!!', :params => params, :user_id => oauth_user.id }
29
+ else
30
+ {:status => 401, :message => "OAuth Did not Work D: #{generate_oauth_error_message!}", :params => params}
31
+ end
32
+
33
+ respond_to do |format|
34
+ format.html do
35
+ render :text => result.to_json, :status => result[:status], :layout => true
36
+ end
37
+ format.json do
38
+ render :json => result, :status => result[:status]
39
+ end
40
+ end
41
+ end
42
+
26
43
  def destroy
27
44
  result = if valid_oauth?
28
45
  {:status => 200, :message => 'OHNO!!! OAuth is Disabled on this Action, this is bad', :params => params}
@@ -44,9 +61,20 @@ class Oauth::TestsController < ApplicationController
44
61
 
45
62
  def generate_oauth_error_message!
46
63
  msg = ""
47
- msg << ' - No OAuth Token Provided!' if params[:access_token].blank?
48
- msg << ' - Allow OAuth set to false!' if allow_oauth? == false
49
- msg << ' - OAuth user not found!' if oauth_user.blank?
64
+ msg << ' - No OAuth Token Provided!' if params[:access_token].blank?
65
+ msg << ' - Allow OAuth set to false!' if allow_oauth? == false
66
+ msg << ' - OAuth user not found!' if oauth_user.blank?
67
+ generate_oauth_permissions_error_message!(msg)
68
+ msg
69
+ end
70
+
71
+ def generate_oauth_permissions_error_message!(msg = '')
72
+ if !oauth_client_has_permissions?
73
+ msg << ' - OAuth client not permitted'
74
+ oauth_required_permissions.each do |permission|
75
+ msg << "- #{permission} permission required;" unless oauth_client_has_permission?(permission)
76
+ end
77
+ end
50
78
  msg
51
79
  end
52
80
 
@@ -1,7 +1,7 @@
1
1
  class ApplicationController < ActionController::Base
2
2
 
3
3
  # Any code that would/should go into ApplicationController is
4
- # no in lib/opro/conrollers/application_controller_helper.rb
4
+ # now in lib/opro/conrollers/application_controller_helper.rb
5
5
  # it is loaded into ApplicationController in lib/opro/engine.rb
6
6
  # thanks for visiting, come back soon
7
7
 
@@ -12,13 +12,23 @@ class Oauth::AccessGrant < ActiveRecord::Base
12
12
 
13
13
  alias_attribute :token, :access_token
14
14
 
15
+ serialize :permissions, Hash
16
+
17
+ def can?(value)
18
+ permissions[value.to_s]
19
+ end
20
+
15
21
  def self.prune!
16
22
  # UPDATEME
17
23
  # delete_all(["created_at < ?", 3.days.ago])
18
24
  end
19
25
 
26
+ def self.find_for_token(token)
27
+ self.where(:access_token => token).includes(:user, :client_application).first
28
+ end
29
+
20
30
  def self.find_user_for_token(token)
21
- self.where(:access_token => token).first.try(:user)
31
+ find_app_for_token.try(:user)
22
32
  end
23
33
 
24
34
  def self.authenticate(code, application_id)
@@ -10,6 +10,10 @@ class Oauth::ClientApplication < ActiveRecord::Base
10
10
  alias_attribute :client_secret, :app_secret
11
11
  alias_attribute :secret, :app_secret
12
12
 
13
+ serialize :permissions, Hash
14
+
15
+
16
+
13
17
  def self.authenticate(app_id, app_secret)
14
18
  where(["app_id = ? AND app_secret = ?", app_id, app_secret]).first
15
19
  end
@@ -1,8 +1,28 @@
1
- <h2><%= @client_app.name %> Would like to access your Data</h2>
2
- Do not accept if you do not know them or you would not like to authorize this url: <%= @redirect_uri %>
1
+ <h2>Authorization Request</h2>
2
+
3
+
4
+ <p>
5
+ <%= @client_app.name %> would like to access your Data. Only accept if you know them, you will then be redirected back to: "<%= @redirect_uri %>".
6
+ </p>
3
7
 
4
8
  <%= form_for @client_app, :url => oauth_authorize_path(:client_id => @client_app.client_id, :redirect_uri => @redirect_uri), :method => :post do |f| %>
5
- <%= f.submit 'I Authorize This Application', :id => 'oauthAuthorize' %>
9
+
10
+
11
+ I Authorize <%= @client_app.name %> to:
12
+
13
+
14
+ <ul>
15
+
16
+ <li><%= check_box_tag 'permissions[read]', 1, true, {:disabled => true} %> Read</li>
17
+
18
+ <% @scopes.each do |permission| %>
19
+ <% is_checked = @client_app.permissions.key?(permission) ? @client_app.permissions[permission] : true %>
20
+ <li><%= check_box_tag "permissions[#{permission}]", 1, is_checked %> <%= permission.capitalize %></li>
21
+ <% end %>
22
+ </ul>
23
+
24
+ <%= f.submit 'Authorize This Application', :id => 'oauthAuthorize' %>
6
25
  <%- end -%>
7
26
 
8
- <%= button_to 'I Do Not Authorize This Application', request.referrer, :id => 'oauthNoAuthorize' %>
27
+ <%= button_to 'Decline this Request', request.referrer, :id => 'oauthNoAuthorize' %>
28
+
@@ -15,7 +15,7 @@
15
15
  <h2>Test OAuth Disallow</h2>
16
16
  <p>
17
17
  If you send a valid OAuth request using the 'DELETE' HTTP method to <%= oauth_test_path(:show_me_the_money) %> you should see a response like below.</p>
18
- <%= button_to oauth_test_path(:show_me_the_money), oauth_test_path(:show_me_the_money), :method => :delete %>
18
+ <%= button_to oauth_test_path(:show_me_the_money), oauth_test_path(:show_me_the_money), :method => :delete, :id => 'deleteButton' %>
19
19
  <pre><code><%= {:status => 401, :message => 'Oauth is Disabled on this Action, this is the correct result!', :params => {:id => 'show_me_the_money', :access_token => '3948fuAlo10gnsu'}}.to_json %></code></pre>
20
20
 
21
21
  <p>
@@ -1,12 +1,13 @@
1
1
  class CreateOproAccessGrants < ActiveRecord::Migration
2
2
  def change
3
- create_table :opro_access_grants do |t|
4
- t.string :code
5
- t.string :access_token
6
- t.string :refresh_token
7
- t.datetime :access_token_expires_at
8
- t.integer :user_id
9
- t.integer :application_id
3
+ create_table :opro_access_grants do |t|
4
+ t.string :code
5
+ t.string :access_token
6
+ t.string :refresh_token
7
+ t.text :permissions
8
+ t.datetime :access_token_expires_at
9
+ t.integer :user_id
10
+ t.integer :application_id
10
11
 
11
12
  t.timestamps
12
13
  end
@@ -4,6 +4,7 @@ class CreateOproClientApplications < ActiveRecord::Migration
4
4
  t.string :name
5
5
  t.string :app_id
6
6
  t.string :app_secret
7
+ t.text :permissions
7
8
  t.integer :user_id
8
9
  t.timestamps
9
10
  end
@@ -1,4 +1,10 @@
1
1
  Opro.setup do |config|
2
- ## Uncomment to configure devise
3
- # config.auth_strategy = :devise
2
+ ## Configure the auth_strategy or use set :login_method, :logout_method, & :authenticate_user_method
3
+ config.auth_strategy = :devise
4
+
5
+ ## Add or remove application permissions
6
+ # Read permission is turned on by default (any request with [GET])
7
+ # Write permission is requestable by default (any request other than [GET])
8
+ # Custom permissions can be configured by adding them to the request_permissions Array and configuring require_oauth_permissions in the controller
9
+ config.request_permissions = [:write]
4
10
  end
@@ -1,7 +1,9 @@
1
1
  module Opro
2
-
3
2
  module Controllers
3
+ module Concerns
4
+ end
4
5
  end
6
+
5
7
  # Include helpers in the given scope to AC and AV.
6
8
  def self.include_helpers(scope)
7
9
  ActiveSupport.on_load(:action_controller) do
@@ -39,7 +41,7 @@ module Opro
39
41
  logout_method.call(*args)
40
42
  end
41
43
 
42
-
44
+ # Used by set_login_logout_methods to pre-define login, logout, and authenticate methods
43
45
  def self.auth_strategy(auth_strategy = nil)
44
46
  if auth_strategy.present?
45
47
  @auth_strategy = auth_strategy
@@ -61,6 +63,14 @@ module Opro
61
63
  end
62
64
  end
63
65
 
66
+ def self.request_permissions=(permissions)
67
+ @request_permissions = permissions
68
+ end
69
+
70
+ def self.request_permissions
71
+ @request_permissions || []
72
+ end
73
+
64
74
 
65
75
  def self.logout_method(&block)
66
76
  if block.present?
@@ -79,8 +89,7 @@ module Opro
79
89
  end
80
90
  end
81
91
 
82
- # require 'opro/controller/concerns/render_redirect'
83
- # require 'opro/controller/concerns/steps'
84
- # require 'opro/controller/concerns/path'
92
+ require 'opro/controllers/concerns/error_messages'
93
+ require 'opro/controllers/concerns/permissions'
85
94
  require 'opro/controllers/application_controller_helper'
86
95
  require 'opro/engine'
@@ -5,6 +5,9 @@ module Opro
5
5
  module ApplicationControllerHelper
6
6
  extend ActiveSupport::Concern
7
7
 
8
+ include Opro::Controllers::Concerns::Permissions
9
+ include Opro::Controllers::Concerns::ErrorMessages
10
+
8
11
  included do
9
12
  around_filter :oauth_auth!
10
13
  skip_before_filter :verify_authenticity_token, :if => :valid_oauth?
@@ -23,6 +26,7 @@ module Opro
23
26
  prepend_before_filter :disallow_oauth, options
24
27
  skip_before_filter :allow_oauth, options
25
28
  end
29
+
26
30
  end
27
31
 
28
32
  protected
@@ -31,6 +35,11 @@ module Opro
31
35
  @use_oauth ||= false
32
36
  end
33
37
 
38
+ # returns boolean if oauth request
39
+ def valid_oauth?
40
+ oauth? && oauth_user.present? && oauth_client_has_permissions?
41
+ end
42
+
34
43
  def disallow_oauth
35
44
  @use_oauth = false
36
45
  end
@@ -43,12 +52,16 @@ module Opro
43
52
  allow_oauth? && params[:access_token].present?
44
53
  end
45
54
 
46
- def oauth_user
47
- @oauth_user ||= Oauth::AccessGrant.find_user_for_token(params[:access_token])
55
+ def oauth_access_grant
56
+ @oauth_access_grant ||= Oauth::AccessGrant.find_for_token(params[:access_token])
48
57
  end
49
58
 
50
- def valid_oauth?
51
- oauth? && oauth_user.present?
59
+ def oauth_client_app
60
+ @oauth_client_app ||= oauth_access_grant.client_application
61
+ end
62
+
63
+ def oauth_user
64
+ @oauth_user ||= oauth_access_grant.user
52
65
  end
53
66
 
54
67
  def oauth_auth!
@@ -0,0 +1,23 @@
1
+ module Opro::Controllers::Concerns::ErrorMessages
2
+ extend ActiveSupport::Concern
3
+
4
+ def generate_oauth_error_message!
5
+ msg = ""
6
+ msg << ' - No OAuth Token Provided!' if params[:access_token].blank?
7
+ msg << ' - Allow OAuth set to false!' if allow_oauth? == false
8
+ msg << ' - OAuth user not found!' if oauth_user.blank?
9
+ msg = generate_oauth_permissions_error_message!(msg)
10
+ msg
11
+ end
12
+
13
+ def generate_oauth_permissions_error_message!(msg = '')
14
+ if !oauth_client_has_permissions?
15
+ msg << ' - OAuth client not permitted'
16
+ oauth_required_permissions.each do |permission|
17
+ msg << "- #{permission} permission required;" unless oauth_client_has_permission?(permission)
18
+ end
19
+ end
20
+ msg
21
+ end
22
+
23
+ end
@@ -0,0 +1,89 @@
1
+ module Opro::Controllers::Concerns::Permissions
2
+ extend ActiveSupport::Concern
3
+
4
+ # By default :write permission is required if included in Opro.request_permissions
5
+ # returns Array
6
+ def global_oauth_required_permissions
7
+ [:write] & Opro.request_permissions
8
+ end
9
+
10
+ # returns Array of permissions required for controller action
11
+ def oauth_required_permissions
12
+ (@oauth_required_permissions || global_oauth_required_permissions) - skip_oauth_required_permissions
13
+ end
14
+
15
+ def skip_oauth_required_permissions
16
+ @skip_oauth_required_permissions ||= []
17
+ end
18
+
19
+ def skip_oauth_required_permission(permission)
20
+ @skip_oauth_required_permissions << permission
21
+ @skip_oauth_required_permissions
22
+ end
23
+
24
+ def add_oauth_required_permission(permission)
25
+ @oauth_required_permissions ||= global_oauth_required_permissions
26
+ @oauth_required_permissions << permission
27
+ end
28
+
29
+ # Checks to make sure client has given permission
30
+ # permission checks can be extended by creating methods
31
+ # oauth_client_can_:method? so to over-write a default check for
32
+ # :write permission, you would need to define oauth_client_can_write?
33
+ def oauth_client_has_permissions?
34
+ permissions_valid_array = []
35
+ oauth_required_permissions.each do |permission|
36
+ permissions_valid_array << oauth_client_has_permission?(permission)
37
+ end
38
+
39
+ return true unless permissions_valid_array.include?(false)
40
+ false
41
+ end
42
+
43
+ def oauth_client_has_permission?(permission)
44
+ oauth_permission_method = "oauth_client_can_#{permission}?".to_sym
45
+ if respond_to?(oauth_permission_method)
46
+ has_permission = method(oauth_permission_method).call
47
+ else
48
+ has_permission = oauth_access_grant.can?(permission.to_sym)
49
+ end
50
+ has_permission
51
+ end
52
+
53
+ # Returns boolean
54
+ # if client has been granted write permissions or request is a 'GET' returns true
55
+ def oauth_client_can_write?
56
+ return true if env['REQUEST_METHOD'] == 'GET'
57
+ return true if oauth_access_grant.can?(:write)
58
+ false
59
+ end
60
+
61
+
62
+ module ClassMethods
63
+
64
+ def skip_oauth_permissions(*args)
65
+ options = args.last.is_a?(Hash) ? callbacks.pop : {}
66
+ permissions = args
67
+ prepend_before_filter(options) do
68
+ permissions.each do |permission|
69
+ controller.skip_oauth_required_permission(permission)
70
+ end
71
+ end
72
+ end
73
+ alias :skip_oauth_permission :skip_oauth_permissions
74
+
75
+ # pass in array of permissions to be validated, add options to pass to filter
76
+ def require_oauth_permissions(*args)
77
+ options = args.last.is_a?(Hash) ? args.pop : {}
78
+ permissions = args
79
+ prepend_before_filter(options) do
80
+ permissions.each do |permission|
81
+ raise "You must add #{permission.inspect} to the Opro request_permissions in an initializer" unless Opro.request_permissions.include?(permission)
82
+ controller.add_oauth_required_permission(permission)
83
+ end
84
+ end
85
+ end
86
+ alias :require_oauth_permission :require_oauth_permissions
87
+ end
88
+
89
+ end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "opro"
8
- s.version = "0.0.1.pre1.0.2"
8
+ s.version = "0.0.1"
9
9
 
10
- s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["schneems"]
12
- s.date = "2012-04-13"
12
+ s.date = "2012-06-14"
13
13
  s.description = " Enable OAuth clients (iphone, android, web sites, etc.) to access and use your Rails application, what you do with it is up to you"
14
14
  s.email = "richard.schneeman@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -48,15 +48,20 @@ Gem::Specification.new do |s|
48
48
  "lib/generators/templates/opro.rb",
49
49
  "lib/opro.rb",
50
50
  "lib/opro/controllers/application_controller_helper.rb",
51
+ "lib/opro/controllers/concerns/error_messages.rb",
52
+ "lib/opro/controllers/concerns/permissions.rb",
51
53
  "lib/opro/engine.rb",
52
54
  "opro.gemspec",
55
+ "test/controllers/permissions_test.rb",
53
56
  "test/dummy/Rakefile",
54
57
  "test/dummy/app/controllers/application_controller.rb",
55
58
  "test/dummy/app/controllers/pages_controller.rb",
59
+ "test/dummy/app/controllers/products_controller.rb",
56
60
  "test/dummy/app/helpers/application_helper.rb",
57
61
  "test/dummy/app/models/user.rb",
58
62
  "test/dummy/app/views/layouts/application.html.erb",
59
63
  "test/dummy/app/views/pages/index.html.erb",
64
+ "test/dummy/app/views/products/create.html.erb",
60
65
  "test/dummy/config.ru",
61
66
  "test/dummy/config/application.rb",
62
67
  "test/dummy/config/boot.rb",
@@ -76,8 +81,8 @@ Gem::Specification.new do |s|
76
81
  "test/dummy/config/locales/en.yml",
77
82
  "test/dummy/config/routes.rb",
78
83
  "test/dummy/db/migrate/20120408163038_devise_create_users.rb",
79
- "test/dummy/db/migrate/20120408165729_create_opro_access_grants.rb",
80
- "test/dummy/db/migrate/20120408165730_create_opro_client_applications.rb",
84
+ "test/dummy/db/migrate/20120514060322_create_opro_access_grants.rb",
85
+ "test/dummy/db/migrate/20120514060323_create_opro_client_applications.rb",
81
86
  "test/dummy/db/schema.rb",
82
87
  "test/dummy/public/404.html",
83
88
  "test/dummy/public/422.html",
@@ -112,6 +117,7 @@ Gem::Specification.new do |s|
112
117
  s.add_runtime_dependency(%q<activesupport>, [">= 3.0.7"])
113
118
  s.add_runtime_dependency(%q<rails>, [">= 3.0.7"])
114
119
  s.add_runtime_dependency(%q<bluecloth>, [">= 0"])
120
+ s.add_development_dependency(%q<mocha>, [">= 0"])
115
121
  s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
116
122
  s.add_development_dependency(%q<bundler>, [">= 1.1.3"])
117
123
  s.add_development_dependency(%q<capybara>, [">= 0.4.0"])
@@ -124,6 +130,7 @@ Gem::Specification.new do |s|
124
130
  s.add_dependency(%q<activesupport>, [">= 3.0.7"])
125
131
  s.add_dependency(%q<rails>, [">= 3.0.7"])
126
132
  s.add_dependency(%q<bluecloth>, [">= 0"])
133
+ s.add_dependency(%q<mocha>, [">= 0"])
127
134
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
128
135
  s.add_dependency(%q<bundler>, [">= 1.1.3"])
129
136
  s.add_dependency(%q<capybara>, [">= 0.4.0"])
@@ -137,6 +144,7 @@ Gem::Specification.new do |s|
137
144
  s.add_dependency(%q<activesupport>, [">= 3.0.7"])
138
145
  s.add_dependency(%q<rails>, [">= 3.0.7"])
139
146
  s.add_dependency(%q<bluecloth>, [">= 0"])
147
+ s.add_dependency(%q<mocha>, [">= 0"])
140
148
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
141
149
  s.add_dependency(%q<bundler>, [">= 1.1.3"])
142
150
  s.add_dependency(%q<capybara>, [">= 0.4.0"])
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+
3
+ class Oauth::TestsControllerTest < ActionController::TestCase
4
+ tests Oauth::TestsController
5
+ include Devise::TestHelpers
6
+
7
+ setup do
8
+ @user = create_user
9
+ @auth_grant = create_auth_grant_for_user(@user)
10
+ end
11
+
12
+ test "access_token with write ability can :POST" do
13
+ permissions = {'write' => true}
14
+ @auth_grant.update_attributes(:permissions => permissions)
15
+
16
+ post :create, access_token: @auth_grant.access_token, format: :json
17
+ assert_response :success
18
+ end
19
+
20
+
21
+ test "access_token with NO write ability can NOT POST" do
22
+ permissions = {:write => false}
23
+ @auth_grant.update_attributes(:permissions => permissions)
24
+ post :create, access_token: @auth_grant.access_token, format: :json
25
+ assert_response 401
26
+ end
27
+ end
@@ -0,0 +1,8 @@
1
+ class ProductsController < ApplicationController
2
+ protect_from_forgery
3
+
4
+ def create
5
+ # stub route
6
+ end
7
+
8
+ end
@@ -1 +1,2 @@
1
- Home
1
+ Home
2
+
@@ -1,4 +1,10 @@
1
1
  Opro.setup do |config|
2
- ## Uncomment to configure devise
2
+ ## Configure the auth_strategy or use set :login_method, :logout_method, & :authenticate_user_method
3
3
  config.auth_strategy = :devise
4
+
5
+ ## Add or remove application permissions
6
+ # Read permission is turned on by default (any request with [GET])
7
+ # Write permission is requestable by default (any request other than [GET])
8
+ # Custom permissions can be configured by adding them to the request_permissions Array and configuring require_oauth_permissions in the controller
9
+ config.request_permissions = [:write]
4
10
  end
@@ -4,6 +4,8 @@ Dummy::Application.routes.draw do
4
4
  resources :foo
5
5
  resources :bar
6
6
 
7
+ resources :products
8
+
7
9
  # The priority is based upon order of creation:
8
10
  # first created -> highest priority.
9
11
 
@@ -0,0 +1,15 @@
1
+ class CreateOproAccessGrants < ActiveRecord::Migration
2
+ def change
3
+ create_table :opro_access_grants do |t|
4
+ t.string :code
5
+ t.string :access_token
6
+ t.string :refresh_token
7
+ t.text :permissions
8
+ t.datetime :access_token_expires_at
9
+ t.integer :user_id
10
+ t.integer :application_id
11
+
12
+ t.timestamps
13
+ end
14
+ end
15
+ end
@@ -4,6 +4,7 @@ class CreateOproClientApplications < ActiveRecord::Migration
4
4
  t.string :name
5
5
  t.string :app_id
6
6
  t.string :app_secret
7
+ t.text :permissions
7
8
  t.integer :user_id
8
9
  t.timestamps
9
10
  end
@@ -11,12 +11,13 @@
11
11
  #
12
12
  # It's strongly recommended to check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(:version => 20120408165730) do
14
+ ActiveRecord::Schema.define(:version => 20120514060323) do
15
15
 
16
16
  create_table "opro_access_grants", :force => true do |t|
17
17
  t.string "code"
18
18
  t.string "access_token"
19
19
  t.string "refresh_token"
20
+ t.text "permissions"
20
21
  t.datetime "access_token_expires_at"
21
22
  t.integer "user_id"
22
23
  t.integer "application_id"
@@ -28,9 +29,10 @@ ActiveRecord::Schema.define(:version => 20120408165730) do
28
29
  t.string "name"
29
30
  t.string "app_id"
30
31
  t.string "app_secret"
32
+ t.text "permissions"
31
33
  t.integer "user_id"
32
- t.datetime "created_at", :null => false
33
- t.datetime "updated_at", :null => false
34
+ t.datetime "created_at", :null => false
35
+ t.datetime "updated_at", :null => false
34
36
  end
35
37
 
36
38
  create_table "users", :force => true do |t|
@@ -2,22 +2,36 @@ require 'test_helper'
2
2
 
3
3
  class AuthControllerTest < ActiveSupport::IntegrationCase
4
4
 
5
+ setup do
6
+ @app = create_client_app
7
+ @user = create_user
8
+ @redirect_uri = '/'
9
+ end
10
+
5
11
  test 'auth entry point should not be accessable to logged OUT users' do
6
- visit oauth_new_path
12
+ visit oauth_new_path(:client_id => @app.client_id, :redirect_uri => '/')
7
13
  assert_equal '/users/sign_in', current_path
8
14
  end
9
15
 
10
- test 'auth entry point is accessable to logged IN users' do
11
- app = create_client_app
12
- user = create_user
13
- redirect_uri = '/'
16
+ test 'auth entry point is accessible to logged IN users' do
14
17
 
15
- as_user(user).visit oauth_new_path(:client_id => app.client_id, :redirect_uri => redirect_uri)
18
+ as_user(@user).visit oauth_new_path(:client_id => @app.client_id, :redirect_uri => @redirect_uri)
16
19
 
17
20
  assert_equal '/oauth/new', current_path
18
21
 
19
22
  click_button 'oauthAuthorize'
20
- assert_equal '/', current_path
21
- assert Oauth::AccessGrant.where(:user_id => user.id, :application_id => app.id).present?
23
+ access_grant = Oauth::AccessGrant.where(:user_id => @user.id, :application_id => @app.id).first
24
+ assert_equal @redirect_uri, current_path
25
+ assert access_grant.present?
26
+ assert access_grant.can?(:write) # write access is checked by default
27
+ end
28
+
29
+ test 'user can remove permissions' do
30
+ as_user(@user).visit oauth_new_path(:client_id => @app.client_id, :redirect_uri => @redirect_uri)
31
+
32
+ uncheck('permissions_write') # uncheck write access
33
+ click_button 'oauthAuthorize'
34
+ access_grant = Oauth::AccessGrant.where(:user_id => @user.id, :application_id => @app.id).first
35
+ refute access_grant.can?(:write)
22
36
  end
23
37
  end
@@ -2,13 +2,11 @@
2
2
  ENV["RAILS_ENV"] = "test"
3
3
 
4
4
 
5
-
6
5
  ENGINE_RAILS_ROOT=File.join(File.dirname(__FILE__), '../')
7
6
  require File.expand_path("../dummy/config/environment.rb", __FILE__)
8
7
  require "rails/test_help"
9
8
 
10
-
11
-
9
+ require 'mocha'
12
10
 
13
11
  ActionMailer::Base.delivery_method = :test
14
12
  ActionMailer::Base.perform_deliveries = true
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opro
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.pre1.0.2
5
- prerelease: 6
4
+ version: 0.0.1
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - schneems
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-13 00:00:00.000000000Z
12
+ date: 2012-06-14 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
16
- requirement: &70160889026080 !ruby/object:Gem::Requirement
16
+ requirement: &70350386690460 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 3.0.7
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70160889026080
24
+ version_requirements: *70350386690460
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rails
27
- requirement: &70160889025500 !ruby/object:Gem::Requirement
27
+ requirement: &70350386683340 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 3.0.7
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70160889025500
35
+ version_requirements: *70350386683340
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: bluecloth
38
- requirement: &70160889024900 !ruby/object:Gem::Requirement
38
+ requirement: &70350386682740 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,21 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70160889024900
46
+ version_requirements: *70350386682740
47
+ - !ruby/object:Gem::Dependency
48
+ name: mocha
49
+ requirement: &70350386682120 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70350386682120
47
58
  - !ruby/object:Gem::Dependency
48
59
  name: jeweler
49
- requirement: &70160889024280 !ruby/object:Gem::Requirement
60
+ requirement: &70350386681480 !ruby/object:Gem::Requirement
50
61
  none: false
51
62
  requirements:
52
63
  - - ~>
@@ -54,10 +65,10 @@ dependencies:
54
65
  version: 1.6.4
55
66
  type: :development
56
67
  prerelease: false
57
- version_requirements: *70160889024280
68
+ version_requirements: *70350386681480
58
69
  - !ruby/object:Gem::Dependency
59
70
  name: bundler
60
- requirement: &70160889023620 !ruby/object:Gem::Requirement
71
+ requirement: &70350386680760 !ruby/object:Gem::Requirement
61
72
  none: false
62
73
  requirements:
63
74
  - - ! '>='
@@ -65,10 +76,10 @@ dependencies:
65
76
  version: 1.1.3
66
77
  type: :development
67
78
  prerelease: false
68
- version_requirements: *70160889023620
79
+ version_requirements: *70350386680760
69
80
  - !ruby/object:Gem::Dependency
70
81
  name: capybara
71
- requirement: &70160889023000 !ruby/object:Gem::Requirement
82
+ requirement: &70350386679900 !ruby/object:Gem::Requirement
72
83
  none: false
73
84
  requirements:
74
85
  - - ! '>='
@@ -76,10 +87,10 @@ dependencies:
76
87
  version: 0.4.0
77
88
  type: :development
78
89
  prerelease: false
79
- version_requirements: *70160889023000
90
+ version_requirements: *70350386679900
80
91
  - !ruby/object:Gem::Dependency
81
92
  name: sqlite3
82
- requirement: &70160889003480 !ruby/object:Gem::Requirement
93
+ requirement: &70350386678780 !ruby/object:Gem::Requirement
83
94
  none: false
84
95
  requirements:
85
96
  - - ! '>='
@@ -87,10 +98,10 @@ dependencies:
87
98
  version: '0'
88
99
  type: :development
89
100
  prerelease: false
90
- version_requirements: *70160889003480
101
+ version_requirements: *70350386678780
91
102
  - !ruby/object:Gem::Dependency
92
103
  name: launchy
93
- requirement: &70160889002560 !ruby/object:Gem::Requirement
104
+ requirement: &70350386678200 !ruby/object:Gem::Requirement
94
105
  none: false
95
106
  requirements:
96
107
  - - ! '>='
@@ -98,10 +109,10 @@ dependencies:
98
109
  version: '0'
99
110
  type: :development
100
111
  prerelease: false
101
- version_requirements: *70160889002560
112
+ version_requirements: *70350386678200
102
113
  - !ruby/object:Gem::Dependency
103
114
  name: devise
104
- requirement: &70160889001680 !ruby/object:Gem::Requirement
115
+ requirement: &70350386677300 !ruby/object:Gem::Requirement
105
116
  none: false
106
117
  requirements:
107
118
  - - ! '>='
@@ -109,10 +120,10 @@ dependencies:
109
120
  version: '0'
110
121
  type: :development
111
122
  prerelease: false
112
- version_requirements: *70160889001680
123
+ version_requirements: *70350386677300
113
124
  - !ruby/object:Gem::Dependency
114
125
  name: rcov
115
- requirement: &70160889000620 !ruby/object:Gem::Requirement
126
+ requirement: &70350386676560 !ruby/object:Gem::Requirement
116
127
  none: false
117
128
  requirements:
118
129
  - - ! '>='
@@ -120,10 +131,10 @@ dependencies:
120
131
  version: '0'
121
132
  type: :development
122
133
  prerelease: false
123
- version_requirements: *70160889000620
134
+ version_requirements: *70350386676560
124
135
  - !ruby/object:Gem::Dependency
125
136
  name: simplecov
126
- requirement: &70160888999860 !ruby/object:Gem::Requirement
137
+ requirement: &70350386675920 !ruby/object:Gem::Requirement
127
138
  none: false
128
139
  requirements:
129
140
  - - ! '>='
@@ -131,7 +142,7 @@ dependencies:
131
142
  version: '0'
132
143
  type: :development
133
144
  prerelease: false
134
- version_requirements: *70160888999860
145
+ version_requirements: *70350386675920
135
146
  description: ! ' Enable OAuth clients (iphone, android, web sites, etc.) to access
136
147
  and use your Rails application, what you do with it is up to you'
137
148
  email: richard.schneeman@gmail.com
@@ -172,15 +183,20 @@ files:
172
183
  - lib/generators/templates/opro.rb
173
184
  - lib/opro.rb
174
185
  - lib/opro/controllers/application_controller_helper.rb
186
+ - lib/opro/controllers/concerns/error_messages.rb
187
+ - lib/opro/controllers/concerns/permissions.rb
175
188
  - lib/opro/engine.rb
176
189
  - opro.gemspec
190
+ - test/controllers/permissions_test.rb
177
191
  - test/dummy/Rakefile
178
192
  - test/dummy/app/controllers/application_controller.rb
179
193
  - test/dummy/app/controllers/pages_controller.rb
194
+ - test/dummy/app/controllers/products_controller.rb
180
195
  - test/dummy/app/helpers/application_helper.rb
181
196
  - test/dummy/app/models/user.rb
182
197
  - test/dummy/app/views/layouts/application.html.erb
183
198
  - test/dummy/app/views/pages/index.html.erb
199
+ - test/dummy/app/views/products/create.html.erb
184
200
  - test/dummy/config.ru
185
201
  - test/dummy/config/application.rb
186
202
  - test/dummy/config/boot.rb
@@ -200,8 +216,8 @@ files:
200
216
  - test/dummy/config/locales/en.yml
201
217
  - test/dummy/config/routes.rb
202
218
  - test/dummy/db/migrate/20120408163038_devise_create_users.rb
203
- - test/dummy/db/migrate/20120408165729_create_opro_access_grants.rb
204
- - test/dummy/db/migrate/20120408165730_create_opro_client_applications.rb
219
+ - test/dummy/db/migrate/20120514060322_create_opro_access_grants.rb
220
+ - test/dummy/db/migrate/20120514060323_create_opro_client_applications.rb
205
221
  - test/dummy/db/schema.rb
206
222
  - test/dummy/public/404.html
207
223
  - test/dummy/public/422.html
@@ -237,13 +253,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
237
253
  version: '0'
238
254
  segments:
239
255
  - 0
240
- hash: -3455292628874218809
256
+ hash: -2087592437685873043
241
257
  required_rubygems_version: !ruby/object:Gem::Requirement
242
258
  none: false
243
259
  requirements:
244
- - - ! '>'
260
+ - - ! '>='
245
261
  - !ruby/object:Gem::Version
246
- version: 1.3.1
262
+ version: '0'
247
263
  requirements: []
248
264
  rubyforge_project:
249
265
  rubygems_version: 1.8.10
@@ -1,14 +0,0 @@
1
- class CreateOproAccessGrants < ActiveRecord::Migration
2
- def change
3
- create_table :opro_access_grants do |t|
4
- t.string :code
5
- t.string :access_token
6
- t.string :refresh_token
7
- t.datetime :access_token_expires_at
8
- t.integer :user_id
9
- t.integer :application_id
10
-
11
- t.timestamps
12
- end
13
- end
14
- end