adeia 0.1.0 → 0.2.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 (124) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -0
  3. data/Rakefile +1 -1
  4. data/app/models/adeia/action.rb +4 -1
  5. data/app/models/adeia/element.rb +2 -0
  6. data/app/models/adeia/group.rb +4 -1
  7. data/app/models/adeia/permission.rb +27 -1
  8. data/app/models/adeia/token.rb +12 -0
  9. data/config/locales/en.yml +4 -1
  10. data/config/locales/fr.yml +4 -1
  11. data/db/migrate/20151003150524_create_adeia_tokens.rb +1 -1
  12. data/lib/adeia/authorization.rb +19 -8
  13. data/lib/adeia/controller_methods.rb +2 -2
  14. data/lib/adeia/controller_resource.rb +8 -5
  15. data/lib/adeia/database.rb +19 -8
  16. data/lib/adeia/engine.rb +7 -0
  17. data/lib/adeia/version.rb +1 -1
  18. data/spec/authorization_spec.rb +162 -0
  19. data/spec/controllers/articles_controller_spec.rb +123 -0
  20. data/spec/factories.rb +53 -0
  21. data/spec/rails_helper.rb +19 -0
  22. data/spec/spec_helper.rb +19 -0
  23. data/spec/support/spec_login_helper.rb +18 -0
  24. data/{test/dummy → spec/test_app}/Rakefile +0 -0
  25. data/{test/dummy → spec/test_app}/app/assets/javascripts/application.js +0 -0
  26. data/{test/dummy → spec/test_app}/app/assets/javascripts/sessions.js +0 -0
  27. data/{test/dummy → spec/test_app}/app/assets/stylesheets/application.css +0 -0
  28. data/{test/dummy → spec/test_app}/app/assets/stylesheets/scaffold.css +0 -0
  29. data/{test/dummy → spec/test_app}/app/assets/stylesheets/sessions.css +0 -0
  30. data/{test/dummy → spec/test_app}/app/controllers/application_controller.rb +0 -0
  31. data/{test/dummy → spec/test_app}/app/controllers/articles_controller.rb +4 -11
  32. data/{test/dummy → spec/test_app}/app/controllers/sessions_controller.rb +1 -1
  33. data/{test/dummy → spec/test_app}/app/helpers/application_helper.rb +0 -0
  34. data/{test/dummy → spec/test_app}/app/helpers/sessions_helper.rb +0 -0
  35. data/{test/dummy → spec/test_app}/app/models/article.rb +0 -0
  36. data/{test/dummy → spec/test_app}/app/models/user.rb +0 -0
  37. data/{test/dummy → spec/test_app}/app/views/articles/_form.html.erb +0 -0
  38. data/{test/dummy → spec/test_app}/app/views/articles/edit.html.erb +0 -0
  39. data/{test/dummy → spec/test_app}/app/views/articles/index.html.erb +0 -0
  40. data/{test/dummy → spec/test_app}/app/views/articles/new.html.erb +0 -0
  41. data/{test/dummy → spec/test_app}/app/views/articles/show.html.erb +0 -0
  42. data/{test/dummy → spec/test_app}/app/views/layouts/application.html.erb +1 -1
  43. data/{test/dummy → spec/test_app}/app/views/sessions/new.html.erb +0 -0
  44. data/{test/dummy → spec/test_app}/bin/bundle +0 -0
  45. data/{test/dummy → spec/test_app}/bin/rails +0 -0
  46. data/{test/dummy → spec/test_app}/bin/rake +0 -0
  47. data/{test/dummy → spec/test_app}/bin/setup +0 -0
  48. data/{test/dummy → spec/test_app}/config.ru +0 -0
  49. data/{test/dummy → spec/test_app}/config/application.rb +0 -0
  50. data/{test/dummy → spec/test_app}/config/boot.rb +0 -0
  51. data/{test/dummy → spec/test_app}/config/database.yml +0 -0
  52. data/{test/dummy → spec/test_app}/config/environment.rb +0 -0
  53. data/{test/dummy → spec/test_app}/config/environments/development.rb +0 -0
  54. data/{test/dummy → spec/test_app}/config/environments/production.rb +0 -0
  55. data/{test/dummy → spec/test_app}/config/environments/test.rb +0 -0
  56. data/{test/dummy → spec/test_app}/config/initializers/assets.rb +0 -0
  57. data/{test/dummy → spec/test_app}/config/initializers/backtrace_silencers.rb +0 -0
  58. data/{test/dummy → spec/test_app}/config/initializers/cookies_serializer.rb +0 -0
  59. data/{test/dummy → spec/test_app}/config/initializers/filter_parameter_logging.rb +0 -0
  60. data/{test/dummy → spec/test_app}/config/initializers/inflections.rb +0 -0
  61. data/{test/dummy → spec/test_app}/config/initializers/mime_types.rb +0 -0
  62. data/{test/dummy → spec/test_app}/config/initializers/session_store.rb +0 -0
  63. data/{test/dummy → spec/test_app}/config/initializers/wrap_parameters.rb +0 -0
  64. data/{test/dummy → spec/test_app}/config/locales/en.yml +0 -0
  65. data/{test/dummy → spec/test_app}/config/routes.rb +1 -1
  66. data/{test/dummy → spec/test_app}/config/secrets.yml +0 -0
  67. data/{test/dummy → spec/test_app}/db/development.sqlite3 +0 -0
  68. data/{test/dummy/db/migrate/20150930161522_create_users.rb → spec/test_app/db/migrate/20151012185720_create_users.rb} +1 -1
  69. data/{test/dummy/db/migrate/20150930161532_create_articles.rb → spec/test_app/db/migrate/20151012185726_create_articles.rb} +1 -1
  70. data/{test/dummy → spec/test_app}/db/schema.rb +2 -2
  71. data/spec/test_app/db/test.sqlite3 +0 -0
  72. data/{test/dummy → spec/test_app}/lib/tasks/init.rake +0 -0
  73. data/{test/dummy → spec/test_app}/log/development.log +1314 -0
  74. data/spec/test_app/log/test.log +24709 -0
  75. data/{test/dummy → spec/test_app}/public/404.html +0 -0
  76. data/{test/dummy → spec/test_app}/public/422.html +0 -0
  77. data/{test/dummy → spec/test_app}/public/500.html +0 -0
  78. data/{test/dummy → spec/test_app}/public/favicon.ico +0 -0
  79. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/007YZnzCZDb7P0xbxiEkmAM6-xSsxmYu_W7vnrvcDOs.cache +0 -0
  80. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/1GiUoKAP-7ewZyzr_eCTMX0R8ML5Z_VN2bfQ05RAW30.cache +0 -0
  81. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/5Lly_CA8DZvPhQV2jDQx-Y6P_y3Ygra9t5jfSlGhHDA.cache +0 -0
  82. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/6n6yNyR4eQhIVjw5Anxur-SLgdDc_rzuMuZKj6Q4FqE.cache +0 -0
  83. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/80nWjD2uxLBuIN1R5NawmTsgZWCB6nln8WXf_5gHri4.cache +0 -0
  84. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/9Fw_WnCC15QnXUQZ4eYTYLOBv20at5Z5gL-WJx_QsR4.cache +0 -0
  85. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/D4VyPOMG_wXgPRZtj-mbRdONJXbdgOZKcuwSm-lNNIA.cache +0 -0
  86. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/DmmfrCpXtt74Hr6NO54lxyOCDv6klnDyBqeDFR7oDU8.cache +0 -0
  87. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/HggfmBmV-rmvrvzJjqvjmDpwB2BTEQvh6krp0CcrI0U.cache +0 -0
  88. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/OI6uxGcnsKavdWTtwDAasU3wPx8QXhzBgV0X2n1KjMQ.cache +0 -0
  89. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/P1NOTKHlk-FIwqlw0wiyLanpgNyubwQi850S1aonsbQ.cache +0 -0
  90. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/PKcbfub75wwU6UzvVnSMFn_6wsaaPUoXMtWTnyyh5jM.cache +0 -0
  91. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/S4dXPkh6wlupsMUb-GvZ2Q5PwAZmplTCkViWCnVWWw0.cache +0 -0
  92. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/UuBE6kIOXtWOmnrnywPI98bzHE-L84SteUEfzexxVtA.cache +0 -0
  93. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/Xa5LZJIrW7sSuOWWFwCAhDkDQ71pA_cHp6H5kiTZS6E.cache +0 -0
  94. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/eQqoU12FSWEA4BsL-PjwTnIUr1bZsu27SOzFHPomG4c.cache +0 -0
  95. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/f3V_hqqK4rH7Z51LFX1Wk9hrWGjYABTZmgSeYvWKgLs.cache +0 -0
  96. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/gXIpNlfbH4G7-D0grgt2EuWuwHwTymznc1rlxJ1-C0A.cache +0 -0
  97. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/hX4wt6FzyI47gW66iiVyl2C722yfwvx3KafFEYkreEY.cache +0 -0
  98. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/hZi1k6tpxxCGYxRe7zY74ItcOI8gZrREOpGuA8JSpGg.cache +0 -0
  99. data/spec/test_app/tmp/cache/assets/development/sprockets/v3.0/m36EDdApBppvyoX6m8cNCOm1eyt7pipkfASRya0sKqM.cache +1 -0
  100. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/nZCCAAO-XWnPS2Xr9yss0VhSONvnR3emOuEIc_b-1OY.cache +0 -0
  101. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/pEhaat2KBd5SrT7szC_8R1_6hK17FTpvoRFkmCRSD3M.cache +0 -0
  102. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/r5qzpye5vWgzwRnRhhSYkUslyNZ11pyYXQZqGe8o930.cache +0 -0
  103. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/t0GCJAJcd_7X2F172TjwwDZ6rfNJc2FRbDTV5-jSqY0.cache +0 -0
  104. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/t92Y0f7B0gH-r5W-iNadtkzgjm8gxyEyttnY6AWpdmw.cache +0 -0
  105. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/tYGZjTIGEDMySqV7qHf43dq0_aB7TuSEhhZtN_9xW54.cache +0 -0
  106. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/wMjI0_cDi3gmsOV5xXr-QPQOfHCB_qea8St_udeflhE.cache +0 -0
  107. data/{test/dummy → spec/test_app}/tmp/cache/assets/development/sprockets/v3.0/z2mRCA3647ZviK5pXi1_qLwdxkiCaoIfZj7jHoMfLiI.cache +0 -0
  108. data/spec/test_app/tmp/pids/server.pid +1 -0
  109. data/spec/validations_spec.rb +37 -0
  110. metadata +219 -194
  111. data/test/dummy/db/migrate/20151003145900_create_adeia_elements.adeia.rb +0 -10
  112. data/test/dummy/db/migrate/20151003145901_create_adeia_permissions.adeia.rb +0 -17
  113. data/test/dummy/db/migrate/20151003145902_create_adeia_groups.adeia.rb +0 -10
  114. data/test/dummy/db/migrate/20151003145903_create_adeia_group_users.adeia.rb +0 -11
  115. data/test/dummy/db/migrate/20151003150941_create_adeia_tokens.adeia.rb +0 -13
  116. data/test/dummy/db/migrate/20151003150942_create_adeia_actions.adeia.rb +0 -10
  117. data/test/dummy/db/migrate/20151003150943_create_adeia_action_permissions.adeia.rb +0 -11
  118. data/test/dummy/test/controllers/articles_controller_test.rb +0 -49
  119. data/test/dummy/test/controllers/sessions_controller_test.rb +0 -7
  120. data/test/dummy/test/controllers/users_controller_test.rb +0 -49
  121. data/test/dummy/test/fixtures/articles.yml +0 -11
  122. data/test/dummy/test/fixtures/users.yml +0 -9
  123. data/test/dummy/test/models/article_test.rb +0 -7
  124. data/test/dummy/test/models/user_test.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4532656038bf240c25749082f7be357f05f7e355
4
- data.tar.gz: f0df2615b74907c8fa22038531358c040726a0a2
3
+ metadata.gz: bb72e440667ceb322201245578196b58cd73e5f7
4
+ data.tar.gz: 912258e0e88dc60ac9b28b370d6ba64a19f48a90
5
5
  SHA512:
6
- metadata.gz: 3d14df596215915a2101d4cdeb2d8ef7138a76aa3ce9371cb44ff3e09ba1f2521e4a028c9abea9550f3bcdeea9799e07bef822790f543bfbfc383c634fdcfb4d
7
- data.tar.gz: a90b37a268eaf2eba9c7bcd22deda19378450d7bbfc292ca7d2999bd106b4313c11d43cfafeef8bfbfc00afee53fe41a421982d7a771691d70f772eba9afda79
6
+ metadata.gz: 701bcd0c7eeb411ad63f5272160a611351e103409da5a2d61bfc59d97216257535e772eb0c90112b64166422a468c61b091815653c60cd53055e286a3dc9101e
7
+ data.tar.gz: e8c68bc12f8b1b0c799bb7a52cfd35d1a3253f1c4e2cc496febab89be45fa48dbaf66cba1bc879901c0dc31e0269f14a8e263f5d5dcb029ebd4715713a99dee8
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # Adeia
2
+
3
+ An authorization gem for Rails that allows you to have the complete control of your app.
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ rescue LoadError
5
5
  end
6
6
 
7
7
 
8
- APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
8
+ APP_RAKEFILE = File.expand_path("../spec/test_app/Rakefile", __FILE__)
9
9
  load 'rails/tasks/engine.rake'
10
10
 
11
11
 
@@ -1,5 +1,8 @@
1
1
  module Adeia
2
2
  class Action < ActiveRecord::Base
3
- has_many :action_permissions
3
+ has_many :action_permissions, dependent: :destroy
4
+ has_many :permissions, through: :action_permissions
5
+
6
+ validates :name, presence: true
4
7
  end
5
8
  end
@@ -1,3 +1,5 @@
1
1
  class Adeia::Element < ActiveRecord::Base
2
2
  has_many :permissions
3
+
4
+ validates :name, presence: true
3
5
  end
@@ -1,3 +1,6 @@
1
1
  class Adeia::Group < ActiveRecord::Base
2
- has_many :group_users
2
+ has_many :group_users, dependent: :destroy
3
+ has_many :permissions, as: :owner
4
+
5
+ validates :name, presence: true
3
6
  end
@@ -1,4 +1,30 @@
1
1
  class Adeia::Permission < ActiveRecord::Base
2
- belongs_to :owner
2
+ belongs_to :owner, polymorphic: true
3
3
  belongs_to :element
4
+
5
+ has_many :action_permissions, dependent: :destroy
6
+ has_many :actions, through: :action_permissions
7
+
8
+ enum permission_type: [:all_entries, :on_ownerships, :on_entry]
9
+
10
+ validates :owner, presence: true
11
+ validates :element, presence: true
12
+ validates :permission_type, presence: true
13
+ validate :presence_of_resource_id
14
+ validate :presence_of_a_right
15
+
16
+ private
17
+
18
+ def presence_of_resource_id
19
+ if permission_type == "on_entry" && resource_id.nil?
20
+ errors.add(:resource_id, I18n.t("errors.messages.blank"))
21
+ end
22
+ end
23
+
24
+ def presence_of_a_right
25
+ if permission_type == "on_ownerships" && !(read_right || update_right || destroy_right || actions.any?)
26
+ errors[:base] << I18n.t("errors.messages.right_required")
27
+ end
28
+ end
29
+
4
30
  end
@@ -1,5 +1,17 @@
1
1
  module Adeia
2
2
  class Token < ActiveRecord::Base
3
3
  belongs_to :permission
4
+
5
+ validates :permission_id, presence: true
6
+ validates :exp_at, presence: true
7
+
8
+ before_create :generate_token
9
+
10
+ private
11
+
12
+ def generate_token
13
+ self.token = SecureRandom.urlsafe_base64
14
+ end
15
+
4
16
  end
5
17
  end
@@ -3,4 +3,7 @@ en:
3
3
  messages:
4
4
  login_required: "Please login before visiting this page !"
5
5
  access_denied: "You don't have access to this page !"
6
- missing_params: "params %{params} is missing !"
6
+ missing_params: "params %{params} is missing !"
7
+ errors:
8
+ messages:
9
+ right_required: "If you want to add a permission linked to user's ownerships, please check at least one right or add an action"
@@ -3,4 +3,7 @@ fr:
3
3
  messages:
4
4
  login_required: "Veuillez vous connecter pour accéder à cette page !"
5
5
  access_denied: "Vous n'êtes pas autorisé à accéder à cette page !"
6
- missing_params: "Le paramètre %{params} est manquant !"
6
+ missing_params: "Le paramètre %{params} est manquant !"
7
+ errors:
8
+ messages:
9
+ right_required: "Lorsque vous voulez créer une permission liée aux possessions de l'utilisateur, vous devez cocher au moins un droit ou ajouter une action"
@@ -2,7 +2,7 @@ class CreateAdeiaTokens < ActiveRecord::Migration
2
2
  def change
3
3
  create_table :adeia_tokens do |t|
4
4
  t.string :token
5
- t.boolean :valid
5
+ t.boolean :is_valid
6
6
  t.references :permission, index: true, foreign_key: true
7
7
  t.date :exp_at
8
8
 
@@ -6,15 +6,21 @@ module Adeia
6
6
  class Authorization < Database
7
7
 
8
8
  def authorize!
9
- @rights = token_rights(right_name)
10
- raise LoginRequired if @rights.empty? && @user.nil?
11
- @rights.push(send("#{right_name}_rights")) if @user
12
- raise AccessDenied unless authorize?
9
+ rights = token_rights(right_name)
10
+ raise LoginRequired if rights[:rights].empty? && @user.nil?
11
+ rights = rights.merge(send("#{right_name}_rights")) { |key, v1, v2| v1 + v2 } if @user
12
+ @rights, @resource_ids = rights[:rights], rights[:resource_ids]
13
+ raise AccessDenied unless @rights.any? && authorize?
14
+ end
15
+
16
+ def check_permissions!
17
+ load_permissions
18
+ raise AccessDenied unless @rights.any?
13
19
  end
14
20
 
15
21
  def can?
16
- @rights = token_rights.push(send("#{right_name}_rights"))
17
- authorize?
22
+ load_permissions
23
+ @rights.any? && authorize?
18
24
  end
19
25
 
20
26
  private
@@ -28,11 +34,11 @@ module Adeia
28
34
  end
29
35
 
30
36
  def on_ownerships?
31
- @rights.any? { |r| r.permission_type == "on_ownerships" } && @user && @resource.try(:user) == @user
37
+ @user && @resource && @rights.any? { |r| r.permission_type == "on_ownerships" } && @resource.user == @user
32
38
  end
33
39
 
34
40
  def on_entry?
35
- @rights.pluck(:resource_id).compact.include? @resource.try(:id)
41
+ @resource && @resource_ids.include?(@resource.id)
36
42
  end
37
43
 
38
44
  def right_names
@@ -43,6 +49,11 @@ module Adeia
43
49
  right_names.select { |k, v| v.include? @action.to_sym }.keys[0] || :action
44
50
  end
45
51
 
52
+ def load_permissions
53
+ rights = token_rights(right_name).merge(send("#{right_name}_rights")) { |key, v1, v2| v1 + v2 }
54
+ @rights, @resource_ids = rights[:rights], rights[:resource_ids]
55
+ end
56
+
46
57
  end
47
58
 
48
59
  end
@@ -7,7 +7,7 @@ module Adeia
7
7
  module ClassMethods
8
8
 
9
9
  def load_and_authorize(**args)
10
- ControllerResource.add_before_filter(self, :load_resoure_or_records_and_authorize, **args)
10
+ ControllerResource.add_before_filter(self, :load_resource_or_records_and_authorize, **args)
11
11
  end
12
12
 
13
13
  end
@@ -26,7 +26,7 @@ module Adeia
26
26
 
27
27
  def authorize_and_load_records!(**args)
28
28
  controller_resource = ControllerResource.new(self, **args)
29
- controller_resource.authorize!
29
+ controller_resource.check_permissions!
30
30
  return controller_resource.load_records
31
31
  end
32
32
 
@@ -11,7 +11,7 @@ module Adeia
11
11
  end
12
12
  end
13
13
 
14
- def self.load_resoure_or_records_and_authorize(controller)
14
+ def self.load_resource_or_records_and_authorize(controller)
15
15
  if controller.action_name == "index"
16
16
  controller.authorize_and_load_records!
17
17
  else
@@ -38,12 +38,12 @@ module Adeia
38
38
  end
39
39
 
40
40
  def load_records
41
- rights = authorization.read_rights + authorization.token_rights
42
- resource_ids = rights.pluck(:resource_id).compact
41
+ rights = authorization.read_rights.merge(authorization.token_rights(:read)) { |key, v1, v2| v1 + v2 }
42
+ rights, resource_ids = rights[:rights], rights[:resource_ids]
43
43
  @records ||= if rights.any? { |r| r.permission_type == "all_entries" }
44
44
  resource_class.all
45
45
  elsif rights.any? { |r| r.permission_type == "on_ownerships" }
46
- resource_class.where(user_id: @user.id, id: resource_ids)
46
+ resource_class.where("user_id = ? OR id IN (?)", @user.id, resource_ids)
47
47
  elsif rights.any? { |r| r.permission_type == "on_entry" }
48
48
  resource_class.where(id: resource_ids)
49
49
  else
@@ -56,11 +56,14 @@ module Adeia
56
56
  @authorization ||= Authorization.new(@controller_name, @action_name, @token, @resource, @user)
57
57
  end
58
58
 
59
-
60
59
  def authorize!
61
60
  authorization.authorize!
62
61
  end
63
62
 
63
+ def check_permissions!
64
+ authorization.check_permissions!
65
+ end
66
+
64
67
  def can?
65
68
  authorization.can?
66
69
  end
@@ -11,31 +11,42 @@ module Adeia
11
11
  end
12
12
 
13
13
  def read_rights
14
- @read_rights ||= Adeia::Permission.joins(:element).where(owner: owners, read_right: true, elements: {name: @controller})
14
+ @read_rights ||= Adeia::Permission.joins(:element).where(owner: owners, read_right: true, adeia_elements: {name: @controller})
15
+ @read_resource_ids ||= @read_rights.pluck(:resource_id).compact
16
+ return { rights: @read_rights, resource_ids: @read_resource_ids }
15
17
  end
16
18
 
17
19
  def create_rights
18
- @create_rights ||= Adeia::Permission.joins(:element).where(owner: owners, create_right: true, elements: {name: @controller})
20
+ @create_rights ||= Adeia::Permission.joins(:element).where(owner: owners, create_right: true, adeia_elements: {name: @controller})
21
+ return { rights: @create_rights }
19
22
  end
20
23
 
21
24
  def update_rights
22
- @update_rights ||= Adeia::Permission.joins(:element).where(owner: owners, update_right: true, elements: {name: @controller})
25
+ @update_rights ||= Adeia::Permission.joins(:element).where(owner: owners, update_right: true, adeia_elements: {name: @controller})
26
+ @update_resource_ids ||= @update_rights.pluck(:resource_id).compact
27
+ return { rights: @update_rights, resource_ids: @update_resource_ids }
23
28
  end
24
29
 
25
30
  def destroy_rights
26
- @destroy_rights ||= Adeia::Permission.joins(:element).where(owner: owners, destroy_right: true, elements: {name: @controller})
31
+ @destroy_rights ||= Adeia::Permission.joins(:element).where(owner: owners, destroy_right: true, adeia_elements: {name: @controller})
32
+ @destroy_resource_ids ||= @destroy_rights.pluck(:resource_id).compact
33
+ return { rights: @destroy_rights, resource_ids: @destroy_resource_ids }
27
34
  end
28
35
 
29
36
  def action_rights
30
- @action_rights ||= Adeia::Permission.joins(:actions, :element).where(owner: owners, elements: {name: @controller}, actions: {name: @action})
37
+ @action_rights ||= Adeia::Permission.joins(:actions, :element).where(owner: owners, adeia_elements: {name: @controller}, adeia_actions: {name: @action})
38
+ @action_resource_ids ||= @action_rights.pluck(:resource_id).compact
39
+ return { rights: @action_rights, resource_ids: @action_resource_ids }
31
40
  end
32
41
 
33
42
  def token_rights(right_name)
34
43
  @permission_token ||= Adeia::Token.find_by_token(@token)
35
- if @permission_token && @permission_token.valid
36
- @token_rights ||= Adeia::Permission.joins(:element).where("ownerships.id = ? AND elements.name = ? AND #{right_name}_right = ?", @permission_token.permission_id, @controller, true)
44
+ if @permission_token && @permission_token.is_valid
45
+ @token_rights ||= Adeia::Permission.joins(:element).where(id: @permission_token.permission_id, adeia_elements: { name: @controller }, "#{right_name}_right": true)
46
+ @token_resource_ids ||= @token_rights.pluck(:resource_id).compact
47
+ return { rights: @token_rights, resource_ids: @token_resource_ids }
37
48
  else
38
- @token_rights ||= Adeia::Permission.none
49
+ return { rights: Adeia::Permission.none }
39
50
  end
40
51
  end
41
52
 
data/lib/adeia/engine.rb CHANGED
@@ -4,6 +4,13 @@ module Adeia
4
4
  class Engine < ::Rails::Engine
5
5
  isolate_namespace Adeia
6
6
 
7
+ config.generators do |g|
8
+ g.test_framework :rspec
9
+ g.assets false
10
+ g.helper false
11
+ g.factory_girl false
12
+ end
13
+
7
14
  initializer 'Adeia.controller' do |app|
8
15
  ActionController::Base.send :include, Adeia::ControllerMethods
9
16
  end
data/lib/adeia/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Adeia
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,162 @@
1
+ require 'rails_helper'
2
+
3
+ module Adeia
4
+
5
+ describe Authorization do
6
+ let(:user) { mock_model(User) }
7
+
8
+ it "does not allow a visitor without a token" do
9
+ authorization = Authorization.new("admin/articles", "new", nil, nil, nil)
10
+ expect { authorization.authorize! }.to raise_error LoginRequired
11
+ end
12
+
13
+ it "allows a visitor with a valid token" do
14
+ permission = create(:permission, create_right: true)
15
+ token = create(:token, permission: permission).token
16
+ authorization = Authorization.new("admin/articles", "new", token, nil, nil)
17
+ expect { authorization.authorize! }.not_to raise_error
18
+ end
19
+
20
+ it "does not allow a user without a permission" do
21
+ authorization = Authorization.new("admin/articles", "new", nil, nil, user)
22
+ expect { authorization.authorize! }.to raise_error AccessDenied
23
+ end
24
+
25
+ it "does not allow a user with a wrong permission" do
26
+ create(:permission, owner: user, read_right: true, update_right: true, destroy_right: true)
27
+ authorization = Authorization.new("admin/articles", "new", nil, nil, user)
28
+ expect { authorization.authorize! }.to raise_error AccessDenied
29
+ end
30
+
31
+ context "with read permission" do
32
+ before(:each) { create(:permission, owner: user, read_right: true) }
33
+
34
+ it "allows the user in the index action" do
35
+ authorization = Authorization.new("admin/articles", "index", nil, nil, user)
36
+ expect { authorization.authorize! }.not_to raise_error
37
+ end
38
+
39
+ it "allows the user in the show action" do
40
+ authorization = Authorization.new("admin/articles", "show", nil, nil, user)
41
+ expect { authorization.authorize! }.not_to raise_error
42
+ end
43
+
44
+ end
45
+
46
+ context "with create permission" do
47
+ before(:each) { create(:permission, owner: user, create_right: true) }
48
+
49
+ it "allows the user in the new action" do
50
+ authorization = Authorization.new("admin/articles", "new", nil, nil, user)
51
+ expect { authorization.authorize! }.not_to raise_error
52
+ end
53
+
54
+ it "allows the user in the create action" do
55
+ authorization = Authorization.new("admin/articles", "create", nil, nil, user)
56
+ expect { authorization.authorize! }.not_to raise_error
57
+ end
58
+
59
+ end
60
+
61
+ context "with update permission" do
62
+ before(:each) { create(:permission, owner: user, update_right: true) }
63
+
64
+ it "allows the user in the edit action" do
65
+ authorization = Authorization.new("admin/articles", "edit", nil, nil, user)
66
+ expect { authorization.authorize! }.not_to raise_error
67
+ end
68
+
69
+ it "allows the user in the update action" do
70
+ authorization = Authorization.new("admin/articles", "update", nil, nil, user)
71
+ expect { authorization.authorize! }.not_to raise_error
72
+ end
73
+
74
+ end
75
+
76
+ context "with destroy permission" do
77
+ before(:each) { create(:permission, owner: user, destroy_right: true) }
78
+
79
+ it "allows the user in the destroy action" do
80
+ authorization = Authorization.new("admin/articles", "destroy", nil, nil, user)
81
+ expect { authorization.authorize! }.not_to raise_error
82
+ end
83
+
84
+ end
85
+
86
+ context "with an specific action permission" do
87
+ before(:each) { create(:permission, owner: user, action: "share") }
88
+
89
+ it "allows the user in the destroy action" do
90
+ authorization = Authorization.new("admin/articles", "share", nil, nil, user)
91
+ expect { authorization.authorize! }.not_to raise_error
92
+ end
93
+
94
+ end
95
+
96
+ context "with an 'on ownership' permission" do
97
+ let!(:permission) { create(:permission, owner: user, update_right: true, type_name: "on_ownerships") }
98
+
99
+ it "does not allow a visitor" do
100
+ token = create(:token, permission: permission).token
101
+ authorization = Authorization.new("admin/articles", "edit", token, nil, nil)
102
+ expect { authorization.authorize! }.to raise_error AccessDenied
103
+ end
104
+
105
+ it "does not allow when no resource is provided" do
106
+ authorization = Authorization.new("admin/articles", "edit", nil, nil, user)
107
+ expect { authorization.authorize! }.to raise_error AccessDenied
108
+ end
109
+
110
+ it "does not allow when the resource is not his" do
111
+ foreign_user = mock_model(User)
112
+ article = mock_model(Article, user: foreign_user)
113
+ authorization = Authorization.new("admin/articles", "edit", nil, article, user)
114
+ expect { authorization.authorize! }.to raise_error AccessDenied
115
+ end
116
+
117
+ it "allows the user" do
118
+ article = mock_model(Article, user: user)
119
+ authorization = Authorization.new("admin/articles", "edit", nil, article, user)
120
+ expect { authorization.authorize! }.not_to raise_error
121
+ end
122
+
123
+ end
124
+
125
+ context "with an 'on entry' permission" do
126
+
127
+ it "does not allow when there is no resource" do
128
+ permission = create(:permission, owner: user, update_right: true, type_name: "on_entry", resource_id: 1)
129
+ authorization = Authorization.new("admin/articles", "edit", nil, nil, user)
130
+ expect { authorization.authorize! }.to raise_error AccessDenied
131
+ end
132
+
133
+ it "does not allow when the resource is not allowed" do
134
+ article = mock_model(Article)
135
+ permission = create(:permission, owner: user, update_right: true, type_name: "on_entry", resource_id: article.id + 1)
136
+ authorization = Authorization.new("admin/articles", "edit", nil, article, user)
137
+ expect { authorization.authorize! }.to raise_error AccessDenied
138
+ end
139
+
140
+ it "allows the user" do
141
+ article = mock_model(Article)
142
+ permission = create(:permission, owner: user, update_right: true, type_name: "on_entry", resource_id: article.id)
143
+ authorization = Authorization.new("admin/articles", "edit", nil, article, user)
144
+ expect { authorization.authorize! }.not_to raise_error
145
+ end
146
+
147
+ end
148
+
149
+ context "with an inherited permission" do
150
+
151
+ it "allows the user" do
152
+ group = create(:user_group, user: user).group
153
+ permission = create(:permission, owner: group, create_right: true)
154
+ authorization = Authorization.new("admin/articles", "new", nil, nil, user)
155
+ expect { authorization.authorize! }.not_to raise_error
156
+ end
157
+
158
+ end
159
+
160
+ end
161
+
162
+ end