diff --git a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee index e62f7ef52..a73fce115 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee @@ -106,6 +106,10 @@ class App.TicketZoom extends App.Controller @load(data, force) App.Store.write( @key, data ) + if !@doNotLog + @doNotLog = 1 + @recentView( 'Ticket', ticket_id ) + error: (xhr, status, error) => # do not close window if request is aborted @@ -118,9 +122,6 @@ class App.TicketZoom extends App.Controller App.TaskManager.remove( @task_key ) ) - if !@doNotLog - @doNotLog = 1 - @recentView( 'Ticket', ticket_id ) load: (data, force) => diff --git a/app/models/organization.rb b/app/models/organization.rb index dcf58eb6e..43890885b 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -1,6 +1,7 @@ # Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/ class Organization < ApplicationModel + include Organization::Permission load 'organization/assets.rb' include Organization::Assets extend Organization::Search diff --git a/app/models/organization/permission.rb b/app/models/organization/permission.rb new file mode 100644 index 000000000..57e987824 --- /dev/null +++ b/app/models/organization/permission.rb @@ -0,0 +1,38 @@ +# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/ + +module Organization::Permission + +=begin + +check if user has access to user + + user = Organization.find(123) + result = Organization.permission( :type => 'rw', :current_user => User.find(123) ) + +returns + + result = true|false + +=end + + def permission (data) + + # check customer + if data[:current_user].is_role('Customer') + + # access ok if its own organization + return false if data[:type] != 'ro' + return false if !data[:current_user].organization_id + return true if self.id == data[:current_user].organization_id + + # no access + return false + end + + # check agent + return true if data[:current_user].is_role('Admin') + return true if data[:current_user].is_role('Agent') + return false + end + +end \ No newline at end of file diff --git a/app/models/recent_view.rb b/app/models/recent_view.rb index 79561cf4d..55ca7060c 100644 --- a/app/models/recent_view.rb +++ b/app/models/recent_view.rb @@ -9,14 +9,17 @@ class RecentView < ApplicationModel def self.log( object, o_id, user ) + # access check + return if !access( object, o_id, user ) + # lookups object_lookup_id = ObjectLookup.by_name( object ) # create entry record = { - :o_id => o_id, - :recent_view_object_id => object_lookup_id.to_i, - :created_by_id => user.id, + :o_id => o_id, + :recent_view_object_id => object_lookup_id.to_i, + :created_by_id => user.id, } RecentView.create(record) end @@ -45,9 +48,14 @@ class RecentView < ApplicationModel list = [] recent_views.each { |item| - data = item.attributes + data = item.attributes data['object'] = ObjectLookup.by_id( data['recent_view_object_id'] ) data.delete( 'recent_view_object_id' ) + + # access check + next if !access( data['object'], data['o_id'], user ) + + # add to result list list.push data } list @@ -70,11 +78,26 @@ class RecentView < ApplicationModel self.created_by_id, { :event => 'RecentView::changed', - :data => {} + :data => {} } ) end - class Object < ApplicationModel + private + + def self.access(object, o_id, user) + + # check if object exists + begin + return if !Kernel.const_get( object ) + record = Kernel.const_get( object ).where( :id => o_id ).first + return if !record + rescue + return + end + + # check permission + return if !record.respond_to?(:permission) + record.permission( :current_user => user ) end end \ No newline at end of file diff --git a/app/models/ticket/permission.rb b/app/models/ticket/permission.rb index 6a81de573..1d20ed4f4 100644 --- a/app/models/ticket/permission.rb +++ b/app/models/ticket/permission.rb @@ -44,4 +44,4 @@ returns return false end -end +end \ No newline at end of file diff --git a/app/models/user.rb b/app/models/user.rb index c920e7dc5..695d66f18 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -24,6 +24,7 @@ require 'digest/md5' # @property active [Boolean] The flag that shows the active state of the User. # @property note [String] The note or comment stored to the User. class User < ApplicationModel + include User::Permission load 'user/assets.rb' include User::Assets extend User::Search diff --git a/app/models/user/permission.rb b/app/models/user/permission.rb new file mode 100644 index 000000000..960cfdb5e --- /dev/null +++ b/app/models/user/permission.rb @@ -0,0 +1,36 @@ +# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/ + +module User::Permission + +=begin + +check if user has access to user + + user = User.find(123) + result = user.permission( :type => 'rw', :current_user => User.find(123) ) + +returns + + result = true|false + +=end + + def permission (data) + + # check customer + if data[:current_user].is_role('Customer') + + # access ok if its own user + return true if self.id == data[:current_user].id + + # no access + return false + end + + # check agent + return true if data[:current_user].is_role('Admin') + return true if data[:current_user].is_role('Agent') + return false + end + +end \ No newline at end of file diff --git a/test/unit/recent_view_test.rb b/test/unit/recent_view_test.rb index 7235c52e4..73b55ec28 100644 --- a/test/unit/recent_view_test.rb +++ b/test/unit/recent_view_test.rb @@ -6,23 +6,23 @@ class RecentViewTest < ActiveSupport::TestCase test 'simple tests' do ticket1 = Ticket.create( - :title => 'RecentViewTest 1 some title äöüß', - :group => Group.lookup( :name => 'Users'), - :customer_id => 2, - :state => Ticket::State.lookup( :name => 'new' ), - :priority => Ticket::Priority.lookup( :name => '2 normal' ), - :updated_by_id => 1, - :created_by_id => 1, + :title => 'RecentViewTest 1 some title äöüß', + :group => Group.lookup( :name => 'Users'), + :customer_id => 2, + :state => Ticket::State.lookup( :name => 'new' ), + :priority => Ticket::Priority.lookup( :name => '2 normal' ), + :updated_by_id => 1, + :created_by_id => 1, ) assert( ticket1, "ticket created" ) ticket2 = Ticket.create( - :title => 'RecentViewTest 2 some title äöüß', - :group => Group.lookup( :name => 'Users'), - :customer_id => 2, - :state => Ticket::State.lookup( :name => 'new' ), - :priority => Ticket::Priority.lookup( :name => '2 normal' ), - :updated_by_id => 1, - :created_by_id => 1, + :title => 'RecentViewTest 2 some title äöüß', + :group => Group.lookup( :name => 'Users'), + :customer_id => 2, + :state => Ticket::State.lookup( :name => 'new' ), + :priority => Ticket::Priority.lookup( :name => '2 normal' ), + :updated_by_id => 1, + :created_by_id => 1, ) assert( ticket2, "ticket created" ) user1 = User.find(2) @@ -56,4 +56,133 @@ class RecentViewTest < ActiveSupport::TestCase list = RecentView.list( user1 ) assert( !list[0], 'check if recent view list is empty' ) end -end + + test 'existing tests' do + user = User.find(2) + + # log entry of not existing object + RecentView.user_log_destroy(user) + RecentView.log( 'ObjectNotExisting', 1, user ) + + # check if list is empty + list = RecentView.list( user ) + assert( !list[0], 'check if recent view list is empty' ) + + + # log entry of not existing record + RecentView.user_log_destroy(user) + RecentView.log( 'User', 99999999, user ) + + # check if list is empty + list = RecentView.list( user ) + assert( !list[0], 'check if recent view list is empty' ) + + + # log entry of not existing model with permission check + RecentView.user_log_destroy(user) + RecentView.log( 'Overview', 99999999, user ) + + # check if list is empty + list = RecentView.list( user ) + assert( !list[0], 'check if recent view list is empty' ) + end + + test 'permission tests' do + customer = User.find(2) + + groups = Group.where( :name => 'Users' ) + roles = Role.where( :name => 'Agent' ) + agent = User.create_or_update( + :login => 'recent-viewed-agent@example.com', + :firstname => 'RecentViewed', + :lastname => 'Agent', + :email => 'recent-viewed-agent@example.com', + :password => 'agentpw', + :active => true, + :roles => roles, + :groups => groups, + :updated_by_id => 1, + :created_by_id => 1, + ) + Group.create_if_not_exists( + :name => 'WithoutAccess', + :note => 'Test for not access check.', + :updated_by_id => 1, + :created_by_id => 1 + ) + + # no access for customer + ticket1 = Ticket.create( + :title => 'RecentViewTest 1 some title äöüß', + :group => Group.lookup( :name => 'WithoutAccess'), + :customer_id => 1, + :state => Ticket::State.lookup( :name => 'new' ), + :priority => Ticket::Priority.lookup( :name => '2 normal' ), + :updated_by_id => 1, + :created_by_id => 1, + ) + assert( ticket1, "ticket created" ) + + # log entry of not existing object + RecentView.user_log_destroy(customer) + RecentView.log( ticket1.class.to_s, ticket1.id, customer ) + + # check if list is empty + list = RecentView.list( customer ) + assert( !list[0], 'check if recent view list is empty' ) + + # log entry of not existing object + RecentView.user_log_destroy(agent) + RecentView.log( ticket1.class.to_s, ticket1.id, agent ) + + # check if list is empty + list = RecentView.list( agent ) + assert( !list[0], 'check if recent view list is empty' ) + + + # access for customer via customer id + ticket1 = Ticket.create( + :title => 'RecentViewTest 1 some title äöüß', + :group => Group.lookup( :name => 'WithoutAccess'), + :customer_id => 2, + :state => Ticket::State.lookup( :name => 'new' ), + :priority => Ticket::Priority.lookup( :name => '2 normal' ), + :updated_by_id => 1, + :created_by_id => 1, + ) + assert( ticket1, "ticket created" ) + + # log entry + RecentView.user_log_destroy(customer) + RecentView.log( ticket1.class.to_s, ticket1.id, customer ) + + # check if list is empty + list = RecentView.list( customer ) + assert( list[0]['o_id'], ticket1.id ) + assert( list[0]['object'], 'Ticket' ) + assert( !list[1], 'check if recent view list is empty' ) + + + # log entry + organization = Organization.find(1) + RecentView.user_log_destroy(customer) + RecentView.log( organization.class.to_s, organization.id, customer ) + + # check if list is empty + list = RecentView.list( customer ) + assert( !list[0], 'check if recent view list is empty' ) + + + # log entry + organization = Organization.find(1) + RecentView.user_log_destroy(agent) + RecentView.log( organization.class.to_s, organization.id, agent ) + + # check if list is empty + list = RecentView.list( agent ) + assert( list[0]['o_id'], organization.id ) + assert( list[0]['object'], 'Organization' ) + assert( !list[1], 'check if recent view list is empty' ) + end + +end \ No newline at end of file