From 87aedd8cc5f3d78d9cf595995e9226bbb19047cf Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Tue, 18 Apr 2017 09:38:53 +0200 Subject: [PATCH] Added agent limit support. --- app/models/role.rb | 13 +++- app/models/user.rb | 14 ++++- .../20170418000001_validate_agent_limit.rb | 17 +++++ db/seeds.rb | 10 +++ test/unit/role_validate_agent_limit_test.rb | 62 +++++++++++++++++++ test/unit/user_validate_agent_limit_test.rb | 55 ++++++++++++++++ 6 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20170418000001_validate_agent_limit.rb create mode 100644 test/unit/role_validate_agent_limit_test.rb create mode 100644 test/unit/user_validate_agent_limit_test.rb diff --git a/app/models/role.rb b/app/models/role.rb index 7341d1add..3c5ca4bbb 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -6,7 +6,7 @@ class Role < ApplicationModel include LatestChangeObserved has_and_belongs_to_many :users, after_add: :cache_update, after_remove: :cache_update - has_and_belongs_to_many :permissions, after_add: :cache_update, after_remove: :cache_update + has_and_belongs_to_many :permissions, after_add: :cache_update, after_remove: :cache_update, before_add: :validate_agent_limit validates :name, presence: true store :preferences @@ -135,4 +135,15 @@ returns } end + def validate_agent_limit(permission) + return if !Setting.get('system_agent_limit') + return if permission.name != 'ticket.agent' + + ticket_agent_role_ids = Role.joins(:permissions).where(permissions: { name: 'ticket.agent' }).pluck(:id) + ticket_agent_role_ids.push(id) + count = User.joins(:roles).where(roles: { id: ticket_agent_role_ids }, users: { active: true }).count + + raise Exceptions::UnprocessableEntity, 'Agent limit exceeded, please check your account settings.' if count > Setting.get('system_agent_limit') + end + end diff --git a/app/models/user.rb b/app/models/user.rb index 92d46d715..16d3071b9 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -45,7 +45,7 @@ class User < ApplicationModel after_destroy :avatar_destroy has_and_belongs_to_many :groups, after_add: :cache_update, after_remove: :cache_update, class_name: 'Group' - has_and_belongs_to_many :roles, after_add: [:cache_update, :check_notifications], after_remove: :cache_update, class_name: 'Role' + has_and_belongs_to_many :roles, after_add: [:cache_update, :check_notifications], after_remove: :cache_update, before_add: :validate_agent_limit, class_name: 'Role' has_and_belongs_to_many :organizations, after_add: :cache_update, after_remove: :cache_update, class_name: 'Organization' #has_many :permissions, class_name: 'Permission', through: :roles, class_name: 'Role' has_many :tokens, after_add: :cache_update, after_remove: :cache_update @@ -860,6 +860,18 @@ returns } end + def validate_agent_limit(role) + return if !Setting.get('system_agent_limit') + + ticket_agent_role_ids = Role.joins(:permissions).where(permissions: { name: 'ticket.agent' }).pluck(:id) + count = User.joins(:roles).where(roles: { id: ticket_agent_role_ids }, users: { active: true }).count + if ticket_agent_role_ids.include?(role.id) + count += 1 + end + + raise Exceptions::UnprocessableEntity, 'Agent limit exceeded, please check your account settings.' if count > Setting.get('system_agent_limit') + end + def domain_based_assignment return if !email return if organization_id diff --git a/db/migrate/20170418000001_validate_agent_limit.rb b/db/migrate/20170418000001_validate_agent_limit.rb new file mode 100644 index 000000000..9b648d77c --- /dev/null +++ b/db/migrate/20170418000001_validate_agent_limit.rb @@ -0,0 +1,17 @@ +class ValidateAgentLimit < ActiveRecord::Migration + def up + # return if it's a new setup + return if !Setting.find_by(name: 'system_init_done') + + Setting.create_if_not_exists( + title: 'Set limit of agents', + name: 'system_agent_limit', + area: 'Core::Online', + description: 'Defines the limit of the agents.', + options: {}, + state: false, + preferences: { online_service_disable: true }, + frontend: false + ) + end +end diff --git a/db/seeds.rb b/db/seeds.rb index 4b9c5946b..2ff8f33f6 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -2719,6 +2719,16 @@ Setting.create_if_not_exists( ], frontend: false ) +Setting.create_if_not_exists( + title: 'Set limit of agents', + name: 'system_agent_limit', + area: 'Core::Online', + description: 'Defines the limit of the agents.', + options: {}, + state: false, + preferences: { online_service_disable: true }, + frontend: false +) signature = Signature.create_if_not_exists( id: 1, diff --git a/test/unit/role_validate_agent_limit_test.rb b/test/unit/role_validate_agent_limit_test.rb new file mode 100644 index 000000000..fef223564 --- /dev/null +++ b/test/unit/role_validate_agent_limit_test.rb @@ -0,0 +1,62 @@ +# encoding: utf-8 +require 'test_helper' + +class RoleValidateAgentLimit < ActiveSupport::TestCase + test 'role_validate_agent_limit' do + + users = User.of_role('Agent') + UserInfo.current_user_id = 1 + Setting.set('system_agent_limit', users.count + 2) + + permission_ticket_agent = Permission.where(name: 'ticket.agent') + + role_agent_limit_success = Role.create( + name: 'agent-limit-test-success', + note: 'agent-limit-test-success Role.', + permissions: [], + updated_by_id: 1, + created_by_id: 1 + ) + role_agent_limit_fail = Role.create( + name: 'agent-limit-test-fail', + note: 'agent-limit-test-fail Role.', + permissions: [], + updated_by_id: 1, + created_by_id: 1 + ) + + user1 = User.create( + firstname: 'Firstname', + lastname: 'Lastname', + email: 'some@example.com', + login: 'some-agentlimit@example.com', + roles: [role_agent_limit_success], + ) + user2 = User.create( + firstname: 'Firstname1', + lastname: 'Lastname1', + email: 'some-agentlimit-1@example.com', + login: 'some-agentlimit-1@example.com', + roles: [role_agent_limit_success], + ) + user3 = User.create( + firstname: 'Firstname2', + lastname: 'Lastname2', + email: 'some-agentlimit-2@example.com', + login: 'some-agentlimit-2@example.com', + roles: [role_agent_limit_fail], + ) + + role_agent_limit_success.permissions = permission_ticket_agent + assert_raises(Exceptions::UnprocessableEntity) { + role_agent_limit_fail.permissions = permission_ticket_agent + } + + user1.destroy + user2.destroy + user3.destroy + role_agent_limit_success.destroy + role_agent_limit_fail.destroy + Setting.set('system_agent_limit', nil) + end +end diff --git a/test/unit/user_validate_agent_limit_test.rb b/test/unit/user_validate_agent_limit_test.rb new file mode 100644 index 000000000..a28f147ff --- /dev/null +++ b/test/unit/user_validate_agent_limit_test.rb @@ -0,0 +1,55 @@ +# encoding: utf-8 +require 'test_helper' + +class UserValidateAgentLimit < ActiveSupport::TestCase + test 'user_validate_agent_limit' do + + users = User.of_role('Agent') + UserInfo.current_user_id = 1 + Setting.set('system_agent_limit', users.count + 2) + role_agent = Role.lookup(name: 'Agent') + role_customer = Role.lookup(name: 'Customer') + + user1 = User.create( + firstname: 'Firstname', + lastname: 'Lastname', + email: 'some@example.com', + login: 'some-agentlimit@example.com', + roles: [role_agent], + ) + user2 = User.create( + firstname: 'Firstname1', + lastname: 'Lastname1', + email: 'some-agentlimit-1@example.com', + login: 'some-agentlimit-1@example.com', + roles: [role_agent], + ) + + assert_raises(Exceptions::UnprocessableEntity) { + user3 = User.create( + firstname: 'Firstname2', + lastname: 'Lastname2', + email: 'some-agentlimit-2@example.com', + login: 'some-agentlimit-2@example.com', + roles: [role_agent], + ) + } + + user3 = User.create( + firstname: 'Firstname2', + lastname: 'Lastname2', + email: 'some-agentlimit-2@example.com', + login: 'some-agentlimit-2@example.com', + roles: [role_customer], + ) + + assert_raises(Exceptions::UnprocessableEntity) { + user3.roles = [role_agent] + } + + user1.destroy + user2.destroy + user3.destroy + Setting.set('system_agent_limit', nil) + end +end