adeia 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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