cantango-api 0.0.0 → 0.1.0

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 (51) hide show
  1. data/Gemfile +8 -5
  2. data/Gemfile.lock +20 -24
  3. data/README.mdown +73 -0
  4. data/VERSION +1 -1
  5. data/cantango-api.gemspec +42 -23
  6. data/lib/cantango/api/ability/account.rb +6 -6
  7. data/lib/cantango/api/ability/user.rb +1 -0
  8. data/lib/cantango/api/account.rb +9 -11
  9. data/lib/cantango/api/attributes.rb +1 -1
  10. data/lib/cantango/api/can/account.rb +2 -2
  11. data/lib/cantango/api/can/dsl/relation.rb +67 -0
  12. data/lib/cantango/api/can/dsl/scope.rb +24 -0
  13. data/lib/cantango/api/can/dsl.rb +26 -0
  14. data/lib/cantango/api/can/user.rb +1 -1
  15. data/lib/cantango/api/can.rb +1 -1
  16. data/lib/cantango/api/common.rb +16 -3
  17. data/lib/cantango/api/model/account.rb +9 -16
  18. data/lib/cantango/api/model/user.rb +10 -17
  19. data/lib/cantango/api/model.rb +3 -1
  20. data/lib/cantango/api/scope/account.rb +8 -5
  21. data/lib/cantango/api/scope/user.rb +1 -0
  22. data/lib/cantango/api/session/account.rb +1 -1
  23. data/lib/cantango/api/user.rb +9 -11
  24. data/lib/cantango/api.rb +7 -4
  25. data/lib/cantango/api_ext/macros/account.rb +8 -0
  26. data/lib/cantango/api_ext/macros/clazz.rb +17 -0
  27. data/lib/cantango/api_ext/macros/user.rb +8 -0
  28. data/lib/cantango/api_ext/macros.rb +12 -0
  29. data/lib/cantango/api_ext.rb +5 -0
  30. data/spec/cantango/api/ability/account_spec.rb +14 -15
  31. data/spec/cantango/api/ability/user_spec.rb +18 -22
  32. data/spec/cantango/api/account_spec.rb +40 -0
  33. data/spec/cantango/api/attributes_spec.rb +13 -14
  34. data/spec/cantango/api/can/account_spec.rb +40 -47
  35. data/spec/cantango/api/can/user_spec.rb +56 -83
  36. data/spec/cantango/api/common_spec.rb +37 -0
  37. data/spec/cantango/api/model/account_spec.rb +38 -0
  38. data/spec/cantango/api/model/user_spec.rb +35 -0
  39. data/spec/cantango/api/options_spec.rb +23 -0
  40. data/spec/cantango/api/scope/account_spec.rb +43 -0
  41. data/spec/cantango/api/scope/user_spec.rb +19 -51
  42. data/spec/cantango/api/session/account_spec.rb +0 -0
  43. data/spec/cantango/api/session/user_spec.rb +0 -0
  44. data/spec/cantango/api/user_spec.rb +40 -0
  45. data/spec/cantango/api_ext/macros/account_spec.rb +16 -0
  46. data/spec/cantango/api_ext/macros/clazz_spec.rb +26 -0
  47. data/spec/cantango/api_ext/macros/user_spec.rb +17 -0
  48. data/spec/fixtures/models/user_account.rb +1 -15
  49. data/spec/helpers/current_user_accounts.rb +1 -1
  50. data/spec/spec_helper.rb +0 -1
  51. metadata +55 -28
@@ -3,8 +3,8 @@ module CanTango::Api
3
3
  module User
4
4
  attr_writer :active_user, :active_account, :ability_class
5
5
 
6
- def self.included(base)
7
- CanTango.config.users.register base
6
+ def self.included(clazz)
7
+ CanTango.config.users.register_user clazz
8
8
  end
9
9
 
10
10
  def active_user
@@ -17,23 +17,16 @@ module CanTango::Api
17
17
  raise "No account could be found for user: #{self}"
18
18
  end
19
19
 
20
- def can? *args
21
- ability.can?(*args)
22
- end
23
-
24
- def cannot? *args
25
- ability.cannot?(*args)
26
- end
20
+ # from sugar-high or Active Support
21
+ delegate :can?, :cannot?, :to => :ability
27
22
 
28
23
  protected
29
-
30
- def ability
31
- ability_class.new(active_user)
32
- end
33
-
34
- def ability_class
35
- CanTango::Ability::Executor::Modes
36
- end
24
+
25
+ include CanTango::Api::Common
26
+
27
+ def ability opts = {}
28
+ create_ability active_user, opts = {}
29
+ end
37
30
  end
38
31
  end
39
32
  end
@@ -1,5 +1,7 @@
1
+ require 'sugar-high/delegate'
2
+
1
3
  module CanTango::Api
2
- module Session
4
+ module Model
3
5
  autoload_modules :User, :Account
4
6
  end
5
7
  end
@@ -1,24 +1,27 @@
1
1
  module CanTango::Api
2
2
  module Scope
3
3
  module Account
4
- def account_scope scope, options = {}, &block
4
+ include CanTango::Api::Ability::Account
5
+
6
+ def scope_account scope, options = {}, &block
5
7
  account = scoped_account(scope)
6
- ab_scope = account_ability_scope(account, options)
8
+ ab_scope = account_ability_scope(account, options.merge(:masquerade => true))
7
9
  yield ab_scope if block
8
10
  ab_scope
9
11
  end
12
+ alias_method :account_scope, :scope_account
10
13
 
11
- def as_real_account scope, options = {}, &block
14
+ def real_account scope, options = {}, &block
12
15
  scope_account scope, options.merge(:masquerade => false), &block
13
16
  end
14
17
 
15
18
  protected
16
19
 
17
20
  def account_ability_scope account, options = {}
18
- CanTango::Ability::Scope.new user_account_ability(account, options)
21
+ CanTango::Scope::Ability.new account_ability(account, options)
19
22
  end
20
23
 
21
- def scoped_acount scope
24
+ def scoped_account scope
22
25
  send(:"current_#{scope}_account")
23
26
  end
24
27
  end
@@ -7,6 +7,7 @@ module CanTango::Api
7
7
  yield ab_scope if block
8
8
  ab_scope
9
9
  end
10
+ alias_method :user_scope, :scope_user
10
11
 
11
12
  def real_user scope, options = {}, &block
12
13
  scope_user scope, options.merge(:masquerade => false), &block
@@ -2,7 +2,7 @@ module CanTango::Api
2
2
  module Session
3
3
  module Account
4
4
  def self.included(base)
5
- ::CanTango.config.user_accounts.registered.each do |type|
5
+ ::CanTango.config.accounts.registered.each do |type|
6
6
  base.class_eval %{
7
7
  def session_#{type}_account
8
8
  current_#{type}_account if respond_to? :current_#{type}_account
@@ -1,19 +1,17 @@
1
1
  module CanTango::Api
2
2
  module User
3
- module All
4
- def self.included base
5
- apis.each do |api|
6
- base.send :include, clazz(api)
7
- end
3
+ def self.included base
4
+ apis.each do |api|
5
+ base.send :include, clazz(api)
8
6
  end
7
+ end
9
8
 
10
- def self.apis
11
- [:ability, :can, :scope, :session]
12
- end
9
+ def self.apis
10
+ [:ability, :can, :scope, :session]
11
+ end
13
12
 
14
- def clazz api
15
- "CanTango::Api::#{api.to_s.camelize}::User".constantize
16
- end
13
+ def self.clazz api
14
+ "CanTango::Api::#{api.to_s.camelize}::User".constantize
17
15
  end
18
16
  end
19
17
  end
data/lib/cantango/api.rb CHANGED
@@ -3,12 +3,13 @@ require 'sugar-high/blank'
3
3
  require 'hashie'
4
4
  require 'sweetloader'
5
5
 
6
- AutoLoader.namespaces = {:CanTango => 'cantango'}
6
+ SweetLoader.namespaces = {:CanTango => 'cantango'}
7
+ SweetLoader.mode = :require
7
8
 
8
9
  module CanTango
9
10
  module Api
10
- autoload_modules :Ability, :Account, :Attributes, :Can
11
- autoload_modules :Common, :Options, :Model, :Scope, :Session, :User
11
+ sweetload :Attributes, :Options, :Common, :Ability, :Account, :Can
12
+ sweetload :Model, :Scope, :Session, :User
12
13
 
13
14
  def self.apis
14
15
  [:ability, :can, :scope, :session]
@@ -21,6 +22,8 @@ module CanTango
21
22
  end
22
23
 
23
24
  # FIX - sweetloader, camelize there!
24
- autoload_modules *apis.map{|api| api.to_s.camelize}
25
+ sweetload *apis.map{|api| api.to_s.camelize}
25
26
  end
26
27
  end
28
+
29
+ require 'cantango/api_ext'
@@ -0,0 +1,8 @@
1
+ module CanTango::Macros
2
+ module Account
3
+ def tango_account options = {}
4
+ self.send :include, CanTango::Api::Model::Account
5
+ end
6
+ alias_method :cantango_account, :tango_account
7
+ end
8
+ end
@@ -0,0 +1,17 @@
1
+ module CanTango::Macros
2
+ module Clazz
3
+ include CanTango::Macros::Account
4
+ include CanTango::Macros::User
5
+
6
+ def cantango type = nil
7
+ # determine if user or account
8
+ if !type
9
+ (name =~ /.+Account$/) ? tango_account : tango_user
10
+ else
11
+ tango_account and return if type.to_s == 'account'
12
+ tango_user and return if type.to_s == 'user'
13
+ raise ArgumentError, "Unable to determine type of class to register; Please specify :user or :account as argument"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ module CanTango::Macros
2
+ module User
3
+ def tango_user options = {}
4
+ self.send :include, CanTango::Api::Model::User
5
+ end
6
+ alias_method :cantango_user, :tango_user
7
+ end
8
+ end
@@ -0,0 +1,12 @@
1
+ module CanTango
2
+ module Macros
3
+ sweet_scope :ns => {:CanTango => 'cantango/api_ext'} do
4
+ autoload_modules :Account, :User, :Clazz
5
+ end
6
+ end
7
+ end
8
+
9
+ class Class
10
+ include CanTango::Macros::Clazz
11
+ end
12
+
@@ -0,0 +1,5 @@
1
+ module CanTango
2
+ sweet_scope :ns => {:CanTango => 'cantango/api_ext'} do
3
+ sweetload :Macros
4
+ end
5
+ end
@@ -1,34 +1,33 @@
1
- require 'spec_helper'
2
-
3
- # require 'cantango/configuration/engines/store_engine_shared'
1
+ require 'cantango/config'
2
+ require 'fixtures/models'
4
3
 
5
4
  CanTango.configure do |config|
6
- config.users.register :user, User
5
+ config.users.register :user, User
7
6
  config.users.register :admin, Admin
8
7
 
9
- config.accounts.register :user, UserAccount
8
+ config.accounts.register :user, UserAccount
10
9
  config.accounts.register :admin, AdminAccount
11
-
12
- # config.cache_engine.set :off
13
- # config.permit_engine.set :on
14
10
  end
15
11
 
12
+ require 'spec_helper'
13
+ require 'helpers/current_user_accounts'
14
+
16
15
  class Context
17
- include CanTango::Api::Account::Ability
16
+ include CanTango::Api::Ability::Account
18
17
 
19
18
  include_and_extend ::CurrentUserAccounts
20
19
  end
21
20
 
22
- describe CanTango::Api::UserAccount::Ability do
21
+ describe CanTango::Api::Ability::Account do
23
22
  subject { Context.new }
24
23
 
25
- describe 'user_account_ability' do
26
- specify { subject.user_account_ability(subject.current_user_account).should be_a CanTango::Ability }
27
- specify { subject.user_account_ability(subject.current_admin_account).should be_a CanTango::Ability }
24
+ describe 'account_ability' do
25
+ specify { subject.account_ability(subject.current_user_account).should be_a CanTango::Ability::Executor }
26
+ specify { subject.account_ability(subject.current_admin_account).should be_a CanTango::Ability::Executor }
28
27
  end
29
28
 
30
29
  describe 'current_account_ability' do
31
- specify { subject.current_account_ability(:user).should be_a CanTango::Ability }
32
- specify { subject.current_account_ability(:admin).should be_a CanTango::Ability }
30
+ specify { subject.current_account_ability(:user).should be_a CanTango::Ability::Executor }
31
+ specify { subject.current_account_ability(:admin).should be_a CanTango::Ability::Executor }
33
32
  end
34
33
  end
@@ -1,9 +1,5 @@
1
- require 'rspec'
2
- require 'cantango'
3
- require 'simple_roles'
1
+ require 'cantango/config'
4
2
  require 'fixtures/models'
5
- require 'cantango/api/current_users'
6
- # require 'cantango/configuration/engines/store_engine_shared'
7
3
 
8
4
  class User
9
5
  include_and_extend SimpleRoles
@@ -13,44 +9,44 @@ class Admin < User
13
9
  end
14
10
 
15
11
  CanTango.configure do |config|
16
- config.users.register :user, User
17
- config.users.register :admin, Admin
18
-
19
- config.cache_engine.set :off
20
- config.permit_engine.set :on
12
+ config.users.register :user, User
13
+ config.users.register :admin, Admin
21
14
  end
22
15
 
16
+ require 'spec_helper'
17
+ require 'helpers/current_user_accounts'
18
+
23
19
  class Context
24
- include CanTango::Api::User::Ability
20
+ include CanTango::Api::Ability::User
25
21
 
26
22
  include_and_extend ::CurrentUsers
27
23
  end
28
24
 
29
- describe CanTango::Api::User::Ability do
25
+ describe CanTango::Api::Ability::User do
30
26
  subject { Context.new }
31
27
 
32
28
  describe 'user_ability user' do
33
- specify { subject.user_ability(subject.current_user).should be_a CanTango::Ability }
29
+ specify { subject.user_ability(subject.current_user).should be_a CanTango::Ability::Executor }
34
30
  end
35
31
 
36
32
  describe 'user_ability admin' do
37
- specify { subject.user_ability(subject.current_admin).should be_a CanTango::Ability }
33
+ specify { subject.user_ability(subject.current_admin).should be_a CanTango::Ability::Executor }
38
34
  end
39
35
 
40
36
  describe 'current_user_ability :user' do
41
- specify { subject.current_user_ability(:user).should be_a CanTango::Ability }
37
+ specify { subject.current_user_ability(:user).should be_a CanTango::Ability::Executor }
42
38
 
43
- it 'should set the :user user correctly on ability' do
44
- subject.current_user_ability(:user).user.should == subject.current_user
45
- end
39
+ # it 'should set the :user user correctly on ability' do
40
+ # subject.current_user_ability(:user).user.should == subject.current_user
41
+ # end
46
42
  end
47
43
 
48
44
  describe 'current_user_ability :admin' do
49
- specify { subject.current_user_ability(:admin).should be_a CanTango::Ability }
45
+ specify { subject.current_user_ability(:admin).should be_a CanTango::Ability::Executor }
50
46
 
51
- it 'should set the :admin user correctly on ability' do
52
- subject.current_user_ability(:admin).user.should == subject.current_admin
53
- end
47
+ # it 'should set the :admin user correctly on ability' do
48
+ # subject.current_user_ability(:admin).user.should == subject.current_admin
49
+ # end
54
50
  end
55
51
  end
56
52
 
@@ -0,0 +1,40 @@
1
+ require 'cantango/config'
2
+ require 'fixtures/models'
3
+
4
+ CanTango.configure do |config|
5
+ config.accounts.register :user, UserAccount
6
+ end
7
+
8
+ require 'spec_helper'
9
+
10
+ class AccountContext
11
+ include CanTango::Api::Account
12
+ end
13
+
14
+ describe CanTango::Api::Account do
15
+ subject { AccountContext.new }
16
+
17
+ describe 'Ability API included' do
18
+ [:account_ability, :current_account_ability].each do |name|
19
+ specify { subject.should respond_to name }
20
+ end
21
+ end
22
+
23
+ describe 'Can API included' do
24
+ [:user_account_can?, :user_account_cannot?].each do |name|
25
+ specify { subject.should respond_to name }
26
+ end
27
+ end
28
+
29
+ describe 'Scope API included' do
30
+ [:scope_account, :account_scope, :real_account].each do |name|
31
+ specify { subject.should respond_to name }
32
+ end
33
+ end
34
+
35
+ describe 'Session API included' do
36
+ [:any_account, :active_account, :active_account=].each do |name|
37
+ specify { subject.should respond_to name }
38
+ end
39
+ end
40
+ end
@@ -1,25 +1,24 @@
1
1
  require 'spec_helper'
2
- require 'helpers/current_users'
3
-
4
- CanTango.config.users.register :user, User
5
- CanTango.config.users.register :admin, Admin
6
2
 
7
3
  class Context
8
- include CanTango::Api::User::Ability
9
-
10
- include CurrentUsers
11
- extend ::CurrentUsers
4
+ include CanTango::Api::Attributes
12
5
  end
13
6
 
14
- describe CanTango::Api::User::Ability do
7
+ describe CanTango::Api::Attributes do
15
8
  subject { Context.new }
16
9
 
17
- describe 'user_ability user' do
18
- specify { subject.user_ability(subject.current_user).should be_a CanTango::Ability }
19
- end
10
+ [:read, :edit].each do |action|
11
+ describe ":#{action} attribute" do
12
+ specify do
13
+ subject.send(:"#{action}_attribute", :post).should == :"#{action}_attr_post"
14
+ end
15
+ end
20
16
 
21
- describe 'user_ability admin' do
22
- specify { subject.user_ability(subject.current_admin).should be_a CanTango::Ability }
17
+ describe ":#{action} attributes" do
18
+ specify do
19
+ subject.send(:"#{action}_attributes", :post, :project).should include(:"#{action}_attr_post")
20
+ end
21
+ end
23
22
  end
24
23
  end
25
24
 
@@ -1,51 +1,59 @@
1
- require 'spec_helper'
2
-
3
- require 'helpers/current_user_accounts'
4
- # require 'cantango/configuration/engines/store_engine_shared'
5
-
6
- class User
7
- include_and_extend SimpleRoles
8
- end
1
+ require 'cantango/config'
2
+ require 'fixtures/models'
9
3
 
10
4
  CanTango.configure do |config|
11
- config.users.register :user, User
5
+ config.users.register :user, User
12
6
  config.users.register :admin, Admin
13
7
 
14
- config.accounts.register :user, UserAccount
8
+ config.accounts.register :user, UserAccount
15
9
  config.accounts.register :admin, AdminAccount
16
-
17
- #config.cache_engine.set :off
18
- #config.permit_engine.set :on
19
- end
20
-
21
- class UserRolePermit < CanTango::RolePermit
22
- def permit_rules
23
- can :edit, Article
24
- cannot :edit, User
25
- end
26
- end
27
-
28
- class AdminRolePermit < CanTango::RolePermit
29
- def permit_rules
30
- can :edit, Article
31
- cannot :edit, User
32
- end
10
+
11
+ config.modes.register :no_cache, CanTango::Ability::Mode::NoCache
12
+ config.ability.mode = :no_cache
33
13
  end
34
14
 
35
- class User
36
- include CanTango::Users::Masquerade
37
- end
15
+ require 'spec_helper'
16
+ require 'helpers/current_user_accounts'
38
17
 
39
18
  class Context
40
- include CanTango::Api::UserAccount::Can
19
+ include CanTango::Api::Can::Account
41
20
 
42
21
  include_and_extend ::CurrentUserAccounts
43
22
  end
44
23
 
45
- describe "CanTango::Api::Can::Account" do
24
+ module CanTango::Ability::Mode
25
+ class NoCache
26
+ def calculate_rules
27
+ can :edit, Article
28
+ cannot :edit, User
29
+ end
30
+ end
31
+ end
32
+
33
+ describe CanTango::Api::Can::Account do
46
34
  subject { Context.new }
47
35
 
48
36
  describe 'user_account' do
37
+ specify do
38
+ subject.current_account_ability(:user).should be_a CanTango::Ability::Executor::Modal
39
+ end
40
+
41
+ specify do
42
+ subject.current_account_ability(:user).modes.should == [:no_cache]
43
+ end
44
+
45
+ specify do
46
+ subject.current_account_ability(:user).should respond_to(:can?)
47
+ end
48
+
49
+ specify do
50
+ subject.current_account_ability(:user).rules.should_not be_empty
51
+ end
52
+
53
+ specify do
54
+ subject.current_account_ability(:user).can?(:edit, Article).should be_true
55
+ end
56
+
49
57
  # user can edit Article, not Admin
50
58
  specify do
51
59
  subject.user_account_can?(:edit, Article).should be_true
@@ -65,21 +73,6 @@ describe "CanTango::Api::Can::Account" do
65
73
  subject.admin_account_cannot?(:edit, Article).should be_false
66
74
  end
67
75
  end
68
-
69
- describe 'admin masquerades as user' do
70
- before do
71
- Context.current_admin.masquerade_as Context.current_user
72
- end
73
-
74
- # admin masquerading as user can do same as user
75
- specify do
76
- subject.admin_account_can?(:edit, Article).should be_true
77
- subject.admin_account_can?(:edit, User).should be_false
78
-
79
- subject.admin_account_cannot?(:edit, User).should be_true
80
- subject.admin_account_cannot?(:edit, Article).should be_false
81
- end
82
- end
83
76
  end
84
77
 
85
78