permissions.rb 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. module User::Permissions
  3. extend ActiveSupport::Concern
  4. included do
  5. has_many :permissions, -> { where(roles: { active: true }, active: true) }, through: :roles
  6. association_attributes_ignored :permissions
  7. # Gets all users with the given permission names
  8. # @param permission_names [Array<String>] list of permission_names
  9. # @example
  10. # User.with_permissions('ticket.agent', 'admin')
  11. # @return [Array<User>]
  12. scope :with_permissions, lambda { |*permission_names|
  13. permission_names.flatten!
  14. role_ids = Role.with_permissions(permission_names)
  15. return none if role_ids.blank?
  16. joins(:roles_users)
  17. .where(users: { active: true }, roles_users: { role_id: role_ids })
  18. .distinct
  19. .reorder(:id)
  20. }
  21. end
  22. =begin
  23. returns all accessable permission ids of user
  24. user = User.find(123)
  25. user.permissions_with_child_ids
  26. returns
  27. [permission1_id, permission2_id, permission3_id]
  28. =end
  29. def permissions_with_child_ids
  30. permissions_with_child_elements.pluck(:id)
  31. end
  32. =begin
  33. returns all accessable permission names of user
  34. user = User.find(123)
  35. user.permissions_with_child_names
  36. returns
  37. [permission1_name, permission2_name, permission3_name]
  38. =end
  39. def permissions_with_child_names
  40. permissions_with_child_elements.pluck(:name)
  41. end
  42. def permissions?(query)
  43. Auth::Permissions.authorized?(self, query)
  44. end
  45. def permissions!(query)
  46. return true if permissions?(query)
  47. raise Exceptions::Forbidden, __('User authorization failed.')
  48. end
  49. def permissions_with_child_and_parent_elements
  50. permission_names = permissions.pluck(:name)
  51. names_including_ancestor = permission_names.flat_map { |name| Permission.with_parents(name) }.uniq
  52. base_query = Permission.reorder(:name).where(active: true)
  53. permission_names
  54. .reduce(base_query.where(name: names_including_ancestor)) do |memo, name|
  55. memo.or(base_query.where('permissions.name LIKE ?', "#{SqlHelper.quote_like(name)}.%"))
  56. end
  57. .tap do |permissions|
  58. ancestor_names = names_including_ancestor - permission_names
  59. permissions
  60. .select { |permission| permission.name.in?(ancestor_names) }
  61. .each { |permission| permission.preferences['disabled'] = true }
  62. end
  63. end
  64. private
  65. def permissions_with_child_elements
  66. where = ''
  67. where_bind = [true]
  68. permissions.pluck(:name).each do |permission_name|
  69. where += ' OR ' if where != ''
  70. where += 'permissions.name = ? OR permissions.name LIKE ?'
  71. where_bind.push permission_name
  72. where_bind.push "#{SqlHelper.quote_like(permission_name)}.%"
  73. end
  74. return [] if where == ''
  75. ::Permission.where("permissions.active = ? AND (#{where})", *where_bind)
  76. end
  77. end