Added possibility to create customer at ticket create with customer hash.

This commit is contained in:
Martin Edenhofer 2018-02-02 12:27:19 +01:00
parent 7f45bf69fc
commit d2d597b05c
4 changed files with 170 additions and 54 deletions

View file

@ -0,0 +1,38 @@
module ChecksUserAttributesByCurrentUserPermission
extend ActiveSupport::Concern
private
def check_attributes_by_current_user_permission(params)
return true if current_user.permissions?('admin.user')
%i[role_ids roles].each do |key|
next if !params[key]
if current_user.permissions?('ticket.agent')
params.delete(key)
else
logger.info "Role assignment is only allowed by admin! current_user_id: #{current_user.id} assigned to #{params[key].inspect}"
raise Exceptions::NotAuthorized, 'This role assignment is only allowed by admin!'
end
end
if current_user.permissions?('ticket.agent') && !params[:role_ids] && !params[:roles] && params[:id].blank?
params[:role_ids] = Role.signup_role_ids
end
%i[group_ids groups].each do |key|
next if !params[key]
if current_user.permissions?('ticket.agent')
params.delete(key)
else
logger.info "Group relation assignment is only allowed by admin! current_user_id: #{current_user.id} assigned to #{params[key].inspect}"
raise Exceptions::NotAuthorized, 'Group relation is only allowed by admin!'
end
end
return true if current_user.permissions?('ticket.agent')
response_access_deny
false
end
end

View file

@ -3,6 +3,7 @@
class TicketsController < ApplicationController class TicketsController < ApplicationController
include CreatesTicketArticles include CreatesTicketArticles
include ClonesTicketArticleAttachments include ClonesTicketArticleAttachments
include ChecksUserAttributesByCurrentUserPermission
include TicketStats include TicketStats
prepend_before_action :authentication_check prepend_before_action :authentication_check
@ -77,6 +78,12 @@ class TicketsController < ApplicationController
# POST /api/v1/tickets # POST /api/v1/tickets
def create def create
customer = {}
if params[:customer].class == ActionController::Parameters
customer = params[:customer]
params.delete(:customer)
end
clean_params = Ticket.association_name_to_id_convert(params) clean_params = Ticket.association_name_to_id_convert(params)
# overwrite params # overwrite params
@ -88,16 +95,16 @@ class TicketsController < ApplicationController
end end
# try to create customer if needed # try to create customer if needed
if clean_params[:customer_id] && clean_params[:customer_id] =~ /^guess:(.+?)$/ if clean_params[:customer_id].present? && clean_params[:customer_id] =~ /^guess:(.+?)$/
email = $1 email = $1
if email !~ /@/ || email =~ /(>|<|\||\!|"|§|'|\$|%|&|\(|\)|\?|\s)/ if email !~ /@/ || email =~ /(>|<|\||\!|"|§|'|\$|%|&|\(|\)|\?|\s)/
render json: { error: 'Invalid email of customer' }, status: :unprocessable_entity render json: { error: 'Invalid email of customer' }, status: :unprocessable_entity
return return
end end
customer = User.find_by(email: email.downcase) local_customer = User.find_by(email: email.downcase)
if !customer if !local_customer
role_ids = Role.signup_role_ids role_ids = Role.signup_role_ids
customer = User.create( local_customer = User.create(
firstname: '', firstname: '',
lastname: '', lastname: '',
email: email, email: email,
@ -106,7 +113,30 @@ class TicketsController < ApplicationController
role_ids: role_ids, role_ids: role_ids,
) )
end end
clean_params[:customer_id] = customer.id clean_params[:customer_id] = local_customer.id
end
# try to create customer if needed
if clean_params[:customer_id].blank? && customer.present?
check_attributes_by_current_user_permission(customer)
clean_customer = User.association_name_to_id_convert(customer)
local_customer = nil
if !local_customer && clean_customer[:id].present?
local_customer = User.find_by(id: clean_customer[:id])
end
if clean_customer[:email].present?
local_customer = User.find_by(email: clean_customer[:email].downcase)
end
if !local_customer && clean_customer[:login].present?
local_customer = User.find_by(login: clean_customer[:login].downcase)
end
if !local_customer
role_ids = Role.signup_role_ids
local_customer = User.new(clean_customer)
local_customer.role_ids = role_ids
local_customer.save!
end
clean_params[:customer_id] = local_customer.id
end end
clean_params = Ticket.param_cleanup(clean_params, true) clean_params = Ticket.param_cleanup(clean_params, true)

View file

@ -1,6 +1,8 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class UsersController < ApplicationController class UsersController < ApplicationController
include ChecksUserAttributesByCurrentUserPermission
prepend_before_action :authentication_check, except: %i[create password_reset_send password_reset_verify image] prepend_before_action :authentication_check, except: %i[create password_reset_send password_reset_verify image]
prepend_before_action :authentication_check_only, only: [:create] prepend_before_action :authentication_check_only, only: [:create]
@ -175,7 +177,7 @@ class UsersController < ApplicationController
else else
# permission check # permission check
permission_check_by_permission(params) check_attributes_by_current_user_permission(params)
user = User.new(clean_params) user = User.new(clean_params)
user.associations_from_param(params) user.associations_from_param(params)
@ -259,13 +261,13 @@ class UsersController < ApplicationController
# @response_message 200 [User] Updated User record. # @response_message 200 [User] Updated User record.
# @response_message 401 Invalid session. # @response_message 401 Invalid session.
def update def update
permission_check_by_permission(params) check_attributes_by_current_user_permission(params)
user = User.find(params[:id]) user = User.find(params[:id])
access!(user, 'change') access!(user, 'change')
# permission check # permission check
permission_check_by_permission(params) check_attributes_by_current_user_permission(params)
user.with_lock do user.with_lock do
clean_params = User.association_name_to_id_convert(params) clean_params = User.association_name_to_id_convert(params)
clean_params = User.param_cleanup(clean_params, true) clean_params = User.param_cleanup(clean_params, true)
@ -1074,35 +1076,4 @@ curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content
true true
end end
def permission_check_by_permission(params)
return true if current_user.permissions?('admin.user')
%i[role_ids roles].each do |key|
next if !params[key]
if current_user.permissions?('ticket.agent')
params.delete(key)
else
logger.info "Role assignment is only allowed by admin! current_user_id: #{current_user.id} assigned to #{params[key].inspect}"
raise Exceptions::NotAuthorized, 'This role assignment is only allowed by admin!'
end
end
if current_user.permissions?('ticket.agent') && !params[:role_ids] && !params[:roles] && params[:id].blank?
params[:role_ids] = Role.signup_role_ids
end
%i[group_ids groups].each do |key|
next if !params[key]
if current_user.permissions?('ticket.agent')
params.delete(key)
else
logger.info "Group relation assignment is only allowed by admin! current_user_id: #{current_user.id} assigned to #{params[key].inspect}"
raise Exceptions::NotAuthorized, 'Group relation is only allowed by admin!'
end
end
return true if current_user.permissions?('ticket.agent')
response_access_deny
false
end
end end

View file

@ -127,7 +127,30 @@ class TicketsControllerTest < ActionDispatch::IntegrationTest
assert_equal(@agent.id, result['created_by_id']) assert_equal(@agent.id, result['created_by_id'])
end end
test '01.04 ticket create with agent - wrong owner_id - 0' do test '01.04 ticket create with agent - minimal article and customer.email' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = {
title: 'a new ticket #3',
group: 'Users',
priority: '2 normal',
state: 'new',
customer: @customer_without_org.email,
article: {
body: 'some test 123',
},
}
post '/api/v1/tickets', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
assert_response(201)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal(Ticket::State.lookup(name: 'new').id, result['state_id'])
assert_equal('a new ticket #3', result['title'])
assert_equal(@customer_without_org.id, result['customer_id'])
assert_equal(@agent.id, result['updated_by_id'])
assert_equal(@agent.id, result['created_by_id'])
end
test '01.05 ticket create with agent - wrong owner_id - 0' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw') credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = { params = {
title: 'a new ticket #4', title: 'a new ticket #4',
@ -147,7 +170,7 @@ class TicketsControllerTest < ActionDispatch::IntegrationTest
assert_equal('Invalid value for param \'owner_id\': 0', result['error']) assert_equal('Invalid value for param \'owner_id\': 0', result['error'])
end end
test '01.05 ticket create with agent - wrong owner_id - ""' do test '01.06 ticket create with agent - wrong owner_id - ""' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw') credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = { params = {
title: 'a new ticket #5', title: 'a new ticket #5',
@ -175,7 +198,7 @@ class TicketsControllerTest < ActionDispatch::IntegrationTest
assert_equal(@agent.id, result['created_by_id']) assert_equal(@agent.id, result['created_by_id'])
end end
test '01.06 ticket create with agent - wrong owner_id - 99999' do test '01.07 ticket create with agent - wrong owner_id - 99999' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw') credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = { params = {
title: 'a new ticket #6', title: 'a new ticket #6',
@ -195,7 +218,7 @@ class TicketsControllerTest < ActionDispatch::IntegrationTest
assert_equal('Invalid value for param \'owner_id\': 99999', result['error']) assert_equal('Invalid value for param \'owner_id\': 99999', result['error'])
end end
test '01.07 ticket create with agent - wrong owner_id - nil' do test '01.08 ticket create with agent - wrong owner_id - nil' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw') credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = { params = {
title: 'a new ticket #7', title: 'a new ticket #7',
@ -219,7 +242,7 @@ class TicketsControllerTest < ActionDispatch::IntegrationTest
assert_equal(@agent.id, result['created_by_id']) assert_equal(@agent.id, result['created_by_id'])
end end
test '01.08 ticket create with agent - minimal article with guess customer' do test '01.09 ticket create with agent - minimal article with guess customer' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw') credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = { params = {
title: 'a new ticket #8', title: 'a new ticket #8',
@ -242,7 +265,7 @@ class TicketsControllerTest < ActionDispatch::IntegrationTest
assert_equal(@agent.id, result['created_by_id']) assert_equal(@agent.id, result['created_by_id'])
end end
test '01.09 ticket create with agent - minimal article with guess customer' do test '01.10 ticket create with agent - minimal article with guess customer' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw') credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = { params = {
title: 'a new ticket #9', title: 'a new ticket #9',
@ -263,7 +286,32 @@ class TicketsControllerTest < ActionDispatch::IntegrationTest
assert_equal(@agent.id, result['created_by_id']) assert_equal(@agent.id, result['created_by_id'])
end end
test '01.10 ticket create with agent - minimal article with missing body - with customer' do test '01.11 ticket create with agent - minimal article with customer hash' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = {
title: 'a new ticket #9',
group: 'Users',
customer: {
firstname: 'some firstname',
lastname: 'some lastname',
email: 'some_new_customer@example.com',
},
article: {
body: 'some test 123',
},
}
post '/api/v1/tickets', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
assert_response(201)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal(Ticket::State.lookup(name: 'new').id, result['state_id'])
assert_equal('a new ticket #9', result['title'])
assert_equal(User.lookup(email: 'some_new_customer@example.com').id, result['customer_id'])
assert_equal(@agent.id, result['updated_by_id'])
assert_equal(@agent.id, result['created_by_id'])
end
test '01.12 ticket create with agent - minimal article with missing body - with customer.id' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw') credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = { params = {
title: 'a new ticket #10', title: 'a new ticket #10',
@ -280,7 +328,7 @@ class TicketsControllerTest < ActionDispatch::IntegrationTest
assert_equal('Need at least article: { body: "some text" }', result['error']) assert_equal('Need at least article: { body: "some text" }', result['error'])
end end
test '01.11 ticket create with agent - minimal article and attachment with customer' do test '01.13 ticket create with agent - minimal article and attachment with customer' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw') credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = { params = {
title: 'a new ticket #11', title: 'a new ticket #11',
@ -316,7 +364,7 @@ class TicketsControllerTest < ActionDispatch::IntegrationTest
assert_not(file.preferences['Content-ID']) assert_not(file.preferences['Content-ID'])
end end
test '01.12 ticket create with agent - minimal article and attachment with customer' do test '01.14 ticket create with agent - minimal article and attachment with customer' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw') credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = { params = {
title: 'a new ticket #12', title: 'a new ticket #12',
@ -359,7 +407,7 @@ class TicketsControllerTest < ActionDispatch::IntegrationTest
assert_not(file.preferences['Content-ID']) assert_not(file.preferences['Content-ID'])
end end
test '01.13 ticket create with agent - minimal article and attachment missing mine-type with customer' do test '01.15 ticket create with agent - minimal article and attachment missing mine-type with customer' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw') credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = { params = {
title: 'a new ticket #13', title: 'a new ticket #13',
@ -382,7 +430,7 @@ class TicketsControllerTest < ActionDispatch::IntegrationTest
assert_equal('Invalid base64 for attachment with index \'0\'', result['error']) assert_equal('Invalid base64 for attachment with index \'0\'', result['error'])
end end
test '01.14 ticket create with agent - minimal article and attachment invalid base64 with customer' do test '01.16 ticket create with agent - minimal article and attachment invalid base64 with customer' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw') credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = { params = {
title: 'a new ticket #14', title: 'a new ticket #14',
@ -404,7 +452,7 @@ class TicketsControllerTest < ActionDispatch::IntegrationTest
assert_equal('Attachment needs \'mime-type\' param for attachment with index \'0\'', result['error']) assert_equal('Attachment needs \'mime-type\' param for attachment with index \'0\'', result['error'])
end end
test '01.15 ticket create with agent - minimal article and inline attachments with customer' do test '01.17 ticket create with agent - minimal article and inline attachments with customer' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw') credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = { params = {
title: 'a new ticket #15', title: 'a new ticket #15',
@ -444,7 +492,7 @@ AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
assert(file.preferences['Content-ID']) assert(file.preferences['Content-ID'])
end end
test '01.16 ticket create with agent - minimal article and inline attachments with customer' do test '01.18 ticket create with agent - minimal article and inline attachments with customer' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw') credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
params = { params = {
title: 'a new ticket #16', title: 'a new ticket #16',
@ -925,7 +973,36 @@ AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
assert_equal(@customer_without_org.id, result['created_by_id']) assert_equal(@customer_without_org.id, result['created_by_id'])
end end
test '03.03 ticket with wrong ticket id' do test '03.03 ticket create with customer with wrong customer hash' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-customer1@example.com', 'customer1pw')
params = {
title: 'a new ticket #c2',
state: 'new',
priority: '2 normal',
group: 'Users',
customer: {
firstname: @agent.firstname,
lastname: @agent.lastname,
email: @agent.email,
},
article: {
content_type: 'text/plain', # or text/html
body: 'some body',
sender: 'System',
},
}
post '/api/v1/tickets', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
assert_response(201)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal(Ticket::State.lookup(name: 'new').id, result['state_id'])
assert_equal('a new ticket #c2', result['title'])
assert_equal(@customer_without_org.id, result['customer_id'])
assert_equal(@customer_without_org.id, result['updated_by_id'])
assert_equal(@customer_without_org.id, result['created_by_id'])
end
test '03.04 ticket with wrong ticket id' do
ticket = Ticket.create!( ticket = Ticket.create!(
title: 'ticket with wrong ticket id', title: 'ticket with wrong ticket id',
group: Group.lookup(name: 'Users'), group: Group.lookup(name: 'Users'),
@ -958,7 +1035,7 @@ AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
assert_equal('Not authorized', result['error']) assert_equal('Not authorized', result['error'])
end end
test '03.04 ticket with correct ticket id' do test '03.05 ticket with correct ticket id' do
title = "ticket with corret ticket id testme#{rand(999_999_999)}" title = "ticket with corret ticket id testme#{rand(999_999_999)}"
ticket = Ticket.create!( ticket = Ticket.create!(
title: title, title: title,