Fixed issue #1805 - API: Ticket creation - wrong user in notifcations, activity stream.

This commit is contained in:
Rolf Schmidt 2018-02-13 17:19:22 +01:00
parent bc0777274f
commit 6daaecb5fd
3 changed files with 248 additions and 2 deletions

View file

@ -7,16 +7,55 @@ module ApplicationController::HasUser
private private
def current_user
user_on_behalf = current_user_on_behalf
return user_on_behalf if user_on_behalf
current_user_real
end
# Finds the User with the ID stored in the session with the key # Finds the User with the ID stored in the session with the key
# :current_user_id This is a common way to handle user login in # :current_user_id This is a common way to handle user login in
# a Rails application; logging in sets the session value and # a Rails application; logging in sets the session value and
# logging out removes it. # logging out removes it.
def current_user def current_user_real
return @_current_user if @_current_user return @_current_user if @_current_user
return if !session[:user_id] return if !session[:user_id]
@_current_user = User.lookup(id: session[:user_id]) @_current_user = User.lookup(id: session[:user_id])
end end
# Finds the user based on the id, login or email which is given
# in the headers. If it is found then all api activities are done
# with the behalf of user. With this functionality it is possible
# to do changes with a user which is different from the admin user.
# E.g. create a ticket as a customer user based on a user with admin rights.
def current_user_on_behalf
# check header
return if request.headers['X-On-Behalf-Of'].blank?
# return user if set
return @_user_on_behalf if @_user_on_behalf
# get current user
user_real = current_user_real
return if !user_real
# check if the user has admin rights
raise Exceptions::NotAuthorized, "Current user has no permission to use 'X-On-Behalf-Of'!" if !user_real.permissions?('admin.user')
# find user for execution based on the header
%i[id login email].each do |field|
search_attributes = {}
search_attributes[field] = request.headers['X-On-Behalf-Of']
@_user_on_behalf = User.find_by(search_attributes)
next if !@_user_on_behalf
return @_user_on_behalf
end
# no behalf of user found
raise Exceptions::NotAuthorized, "No such user '#{request.headers['X-On-Behalf-Of']}'"
end
def current_user_set(user, auth_type = 'session') def current_user_set(user, auth_type = 'session')
session[:user_id] = user.id session[:user_id] = user.id
@_auth_type = auth_type @_auth_type = auth_type

View file

@ -440,5 +440,4 @@ class ApiAuthControllerTest < ActionDispatch::IntegrationTest
assert_equal(Hash, result.class) assert_equal(Hash, result.class)
assert(result) assert(result)
end end
end end

View file

@ -0,0 +1,208 @@
require 'test_helper'
class ApiAuthControllerTest < ActionDispatch::IntegrationTest
setup do
# set accept header
@headers = { 'ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' }
# create agent
roles = Role.where(name: %w[Admin Agent])
groups = Group.all
UserInfo.current_user_id = 1
@admin = User.create_or_update(
login: 'api-admin-auth-behalf',
firstname: 'API',
lastname: 'Admin',
email: 'api-admin-auth-behalf@example.com',
password: 'adminpw',
active: true,
roles: roles,
groups: groups,
)
# create customer without org
roles = Role.where(name: 'Customer')
@customer = User.create_or_update(
login: 'api-customer1-auth-behalf@example.com',
firstname: 'API',
lastname: 'Customer1',
email: 'api-customer1-auth-behalf@example.com',
password: 'customer1pw',
active: true,
roles: roles,
)
end
test 'X-On-Behalf-Of auth - ticket create admin for customer by id' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('api-admin-auth-behalf@example.com', 'adminpw')
ticket_create_headers = @headers.merge(
'Authorization' => credentials,
'X-On-Behalf-Of' => @customer.id,
)
params = {
title: 'a new ticket #3',
group: 'Users',
priority: '2 normal',
state: 'new',
customer_id: @customer.id,
article: {
body: 'some test 123',
},
}
post '/api/v1/tickets', params: params.to_json, headers: ticket_create_headers
assert_response(201)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal(result['created_by_id'], @customer.id)
end
test 'X-On-Behalf-Of auth - ticket create admin for customer by login' do
ActivityStream.cleanup(1.year)
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('api-admin-auth-behalf@example.com', 'adminpw')
ticket_create_headers = @headers.merge(
'Authorization' => credentials,
'X-On-Behalf-Of' => @customer.login,
)
admin_headers = @headers.merge(
'Authorization' => credentials,
)
params = {
title: 'a new ticket #3',
group: 'Users',
priority: '2 normal',
state: 'new',
customer_id: @customer.id,
article: {
body: 'some test 123',
},
}
post '/api/v1/tickets', params: params.to_json, headers: ticket_create_headers
assert_response(201)
result_ticket_create = JSON.parse(@response.body)
assert_equal(Hash, result_ticket_create.class)
assert_equal(result_ticket_create['created_by_id'], @customer.id)
get '/api/v1/activity_stream', params: {}, headers: admin_headers
assert_response(200)
result_activity_stream = JSON.parse(@response.body)
assert_equal(Hash, result_activity_stream.class)
ticket_created = result_activity_stream['activity_stream'].find { |activity| activity['object'] == 'Ticket' && activity['o_id'] == result_ticket_create['id'] }
assert_equal(Hash, ticket_created.class)
assert_equal(ticket_created['created_by_id'], @customer.id)
end
test 'X-On-Behalf-Of auth - ticket create admin for customer by email' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('api-admin-auth-behalf@example.com', 'adminpw')
ticket_create_headers = @headers.merge(
'Authorization' => credentials,
'X-On-Behalf-Of' => @customer.email,
)
params = {
title: 'a new ticket #3',
group: 'Users',
priority: '2 normal',
state: 'new',
customer_id: @customer.id,
article: {
body: 'some test 123',
},
}
post '/api/v1/tickets', params: params.to_json, headers: ticket_create_headers
assert_response(201)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal(result['created_by_id'], @customer.id)
end
test 'X-On-Behalf-Of auth - ticket create admin for unknown' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('api-admin-auth-behalf@example.com', 'adminpw')
ticket_create_headers = @headers.merge(
'Authorization' => credentials,
'X-On-Behalf-Of' => 99_449_494_949,
)
params = {
title: 'a new ticket #3',
group: 'Users',
priority: '2 normal',
state: 'new',
customer_id: @customer.id,
article: {
body: 'some test 123',
},
}
post '/api/v1/tickets', params: params.to_json, headers: ticket_create_headers
assert_response(401)
assert_not(@response.header.key?('Access-Control-Allow-Origin'))
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal("No such user '99449494949'", result['error'])
end
test 'X-On-Behalf-Of auth - ticket create customer for admin' do
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('api-customer1-auth-behalf@example.com', 'customer1pw')
ticket_create_headers = @headers.merge(
'Authorization' => credentials,
'X-On-Behalf-Of' => @admin.email,
)
params = {
title: 'a new ticket #3',
group: 'Users',
priority: '2 normal',
state: 'new',
customer_id: @customer.id,
article: {
body: 'some test 123',
},
}
post '/api/v1/tickets', params: params.to_json, headers: ticket_create_headers
assert_response(401)
assert_not(@response.header.key?('Access-Control-Allow-Origin'))
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal("Current user has no permission to use 'X-On-Behalf-Of'!", result['error'])
end
test 'X-On-Behalf-Of auth - ticket create admin for customer by email but no permitted action' do
group_secret = Group.new(name: 'secret1234')
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('api-admin-auth-behalf@example.com', 'adminpw')
ticket_create_headers = @headers.merge(
'Authorization' => credentials,
'X-On-Behalf-Of' => @customer.email,
)
params = {
title: 'a new ticket #3',
group: group_secret.name,
priority: '2 normal',
state: 'new',
customer_id: @customer.id,
article: {
body: 'some test 123',
},
}
post '/api/v1/tickets', params: params.to_json, headers: ticket_create_headers
assert_response(422)
assert_not(@response.header.key?('Access-Control-Allow-Origin'))
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal('No lookup value found for \'group\': "secret1234"', result['error'])
end
end