role.rb 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
  2. class Role < ApplicationModel
  3. include HasActivityStreamLog
  4. include ChecksClientNotification
  5. include ChecksLatestChangeObserved
  6. include HasGroups
  7. load 'role/assets.rb'
  8. include Role::Assets
  9. has_and_belongs_to_many :users, after_add: :cache_update, after_remove: :cache_update
  10. has_and_belongs_to_many :permissions, after_add: :cache_update, after_remove: :cache_update, before_add: :validate_agent_limit_by_permission, before_remove: :last_admin_check_by_permission
  11. validates :name, presence: true
  12. store :preferences
  13. before_create :validate_permissions
  14. before_update :validate_permissions, :last_admin_check_by_attribute, :validate_agent_limit_by_attributes
  15. association_attributes_ignored :users
  16. activity_stream_permission 'admin.role'
  17. =begin
  18. grant permission to role
  19. role.permission_grant('permission.key')
  20. =end
  21. def permission_grant(key)
  22. permission = Permission.lookup(name: key)
  23. raise "Invalid permission #{key}" if !permission
  24. return true if permission_ids.include?(permission.id)
  25. self.permission_ids = permission_ids.push permission.id
  26. true
  27. end
  28. =begin
  29. revoke permission of role
  30. role.permission_revoke('permission.key')
  31. =end
  32. def permission_revoke(key)
  33. permission = Permission.lookup(name: key)
  34. raise "Invalid permission #{key}" if !permission
  35. return true if !permission_ids.include?(permission.id)
  36. self.permission_ids = self.permission_ids -= [permission.id]
  37. true
  38. end
  39. =begin
  40. get signup roles
  41. Role.signup_roles
  42. returns
  43. [role1, role2, ...]
  44. =end
  45. def self.signup_roles
  46. Role.where(active: true, default_at_signup: true)
  47. end
  48. =begin
  49. get signup role ids
  50. Role.signup_role_ids
  51. returns
  52. [role1, role2, ...]
  53. =end
  54. def self.signup_role_ids
  55. Role.where(active: true, default_at_signup: true).map(&:id)
  56. end
  57. =begin
  58. get all roles with permission
  59. roles = Role.with_permissions('admin.session')
  60. get all roles with permission "admin.session" or "ticket.agent"
  61. roles = Role.with_permissions(['admin.session', 'ticket.agent'])
  62. returns
  63. [role1, role2, ...]
  64. =end
  65. def self.with_permissions(keys)
  66. permission_ids = Role.permission_ids_by_name(keys)
  67. Role.joins(:roles_permissions).joins(:permissions).where(
  68. 'permissions_roles.permission_id IN (?) AND roles.active = ? AND permissions.active = ?', permission_ids, true, true
  69. ).distinct()
  70. end
  71. =begin
  72. check if roles is with permission
  73. role = Role.find(123)
  74. role.with_permission?('admin.session')
  75. get if role has permission of "admin.session" or "ticket.agent"
  76. role.with_permission?(['admin.session', 'ticket.agent'])
  77. returns
  78. true | false
  79. =end
  80. def with_permission?(keys)
  81. permission_ids = Role.permission_ids_by_name(keys)
  82. return true if Role.joins(:roles_permissions).joins(:permissions).where(
  83. 'roles.id = ? AND permissions_roles.permission_id IN (?) AND permissions.active = ?', id, permission_ids, true
  84. ).distinct().count.nonzero?
  85. false
  86. end
  87. private_class_method
  88. def self.permission_ids_by_name(keys)
  89. if keys.class != Array
  90. keys = [keys]
  91. end
  92. permission_ids = []
  93. keys.each do |key|
  94. ::Permission.with_parents(key).each do |local_key|
  95. permission = ::Permission.lookup(name: local_key)
  96. next if !permission
  97. permission_ids.push permission.id
  98. end
  99. end
  100. permission_ids
  101. end
  102. private
  103. def validate_permissions
  104. return true if !self.permission_ids
  105. permission_ids.each do |permission_id|
  106. permission = Permission.lookup(id: permission_id)
  107. raise "Unable to find permission for id #{permission_id}" if !permission
  108. raise "Permission #{permission.name} is disabled" if permission.preferences[:disabled] == true
  109. next unless permission.preferences[:not]
  110. permission.preferences[:not].each do |local_permission_name|
  111. local_permission = Permission.lookup(name: local_permission_name)
  112. next if !local_permission
  113. raise "Permission #{permission.name} conflicts with #{local_permission.name}" if permission_ids.include?(local_permission.id)
  114. end
  115. end
  116. true
  117. end
  118. def last_admin_check_by_attribute
  119. return true if !will_save_change_to_attribute?('active')
  120. return true if active != false
  121. return true if !with_permission?(['admin', 'admin.user'])
  122. raise Exceptions::UnprocessableEntity, 'Minimum one user needs to have admin permissions.' if last_admin_check_admin_count < 1
  123. true
  124. end
  125. def last_admin_check_by_permission(permission)
  126. return true if Setting.get('import_mode')
  127. return true if permission.name != 'admin' && permission.name != 'admin.user'
  128. raise Exceptions::UnprocessableEntity, 'Minimum one user needs to have admin permissions.' if last_admin_check_admin_count < 1
  129. true
  130. end
  131. def last_admin_check_admin_count
  132. admin_role_ids = Role.joins(:permissions).where(permissions: { name: ['admin', 'admin.user'], active: true }, roles: { active: true }).where.not(id: id).pluck(:id)
  133. User.joins(:roles).where(roles: { id: admin_role_ids }, users: { active: true }).count
  134. end
  135. def validate_agent_limit_by_attributes
  136. return true if !Setting.get('system_agent_limit')
  137. return true if !will_save_change_to_attribute?('active')
  138. return true if active != true
  139. return true if !with_permission?('ticket.agent')
  140. ticket_agent_role_ids = Role.joins(:permissions).where(permissions: { name: 'ticket.agent', active: true }, roles: { active: true }).pluck(:id)
  141. currents = User.joins(:roles).where(roles: { id: ticket_agent_role_ids }, users: { active: true }).pluck(:id)
  142. news = User.joins(:roles).where(roles: { id: id }, users: { active: true }).pluck(:id)
  143. count = currents.concat(news).uniq.count
  144. raise Exceptions::UnprocessableEntity, 'Agent limit exceeded, please check your account settings.' if count > Setting.get('system_agent_limit')
  145. true
  146. end
  147. def validate_agent_limit_by_permission(permission)
  148. return true if !Setting.get('system_agent_limit')
  149. return true if active != true
  150. return true if permission.active != true
  151. return true if permission.name != 'ticket.agent'
  152. ticket_agent_role_ids = Role.joins(:permissions).where(permissions: { name: 'ticket.agent' }, roles: { active: true }).pluck(:id)
  153. ticket_agent_role_ids.push(id)
  154. count = User.joins(:roles).where(roles: { id: ticket_agent_role_ids }, users: { active: true }).count
  155. raise Exceptions::UnprocessableEntity, 'Agent limit exceeded, please check your account settings.' if count > Setting.get('system_agent_limit')
  156. true
  157. end
  158. end