Skip to content

Commit

Permalink
Refactoring: Drop Ticket.access_condition in favor of using Pundit sc…
Browse files Browse the repository at this point in the history
…opes.
  • Loading branch information
Ryan Lue authored and mgruner committed Jul 20, 2021
1 parent 9f7bec8 commit 276c45b
Show file tree
Hide file tree
Showing 21 changed files with 428 additions and 160 deletions.
18 changes: 9 additions & 9 deletions app/controllers/concerns/ticket_stats.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def ticket_ids_and_assets(condition, current_user, limit, assets)
assets_of_tickets(tickets, assets)
end

def ticket_stats_last_year(condition, access_condition)
def ticket_stats_last_year(condition)
volume_by_year = []
now = Time.zone.now

Expand All @@ -26,16 +26,16 @@ def ticket_stats_last_year(condition, access_condition)
date_end = "#{date_to_check.year}-#{date_to_check.month}-#{date_to_check.end_of_month.day} 00:00:00"

# created
created = Ticket.where('created_at > ? AND created_at < ?', date_start, date_end)
.where(access_condition)
.where(condition)
.count
created = TicketPolicy::ReadScope.new(current_user).resolve
.where('created_at > ? AND created_at < ?', date_start, date_end)
.where(condition)
.count

# closed
closed = Ticket.where('close_at > ? AND close_at < ?', date_start, date_end)
.where(access_condition)
.where(condition)
.count
closed = TicketPolicy::ReadScope.new(current_user).resolve
.where('close_at > ? AND close_at < ?', date_start, date_end)
.where(condition)
.count

data = {
month: date_to_check.month,
Expand Down
54 changes: 24 additions & 30 deletions app/controllers/tickets_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ def index
per_page = 100
end

access_condition = Ticket.access_condition(current_user, 'read')
tickets = Ticket.where(access_condition).order(id: :asc).offset(offset).limit(per_page)
tickets = TicketPolicy::ReadScope.new(current_user).resolve
.order(id: :asc)
.offset(offset)
.limit(per_page)

if response_expand?
list = []
Expand Down Expand Up @@ -317,36 +319,29 @@ def ticket_related
ticket = Ticket.find(params[:ticket_id])
assets = ticket.assets({})

# open tickets by customer
access_condition = Ticket.access_condition(current_user, 'read')

ticket_lists = Ticket
.where(
customer_id: ticket.customer_id,
state_id: Ticket::State.by_category(:open).pluck(:id), # rubocop:disable Rails/PluckInWhere
)
.where(access_condition)
.where.not(id: [ ticket.id ])
.order(created_at: :desc)
.limit(6)
tickets = TicketPolicy::ReadScope.new(current_user).resolve
.where(
customer_id: ticket.customer_id,
state_id: Ticket::State.by_category(:open).select(:id),
)
.where.not(id: [ ticket.id ])
.order(created_at: :desc)
.limit(6)

# if we do not have open related tickets, search for any tickets
if ticket_lists.blank?
ticket_lists = Ticket
.where(
customer_id: ticket.customer_id,
).where.not(
state_id: Ticket::State.by_category(:merged).pluck(:id),
)
.where(access_condition)
.where.not(id: [ ticket.id ])
.order(created_at: :desc)
.limit(6)
end
tickets ||= TicketPolicy::ReadScope.new(current_user).resolve
.where(
customer_id: ticket.customer_id,
).where.not(
state_id: Ticket::State.by_category(:merged).pluck(:id),
)
.where.not(id: [ ticket.id ])
.order(created_at: :desc)
.limit(6)

# get related assets
ticket_ids_by_customer = []
ticket_lists.each do |ticket_list|
tickets.each do |ticket_list|
ticket_ids_by_customer.push ticket_list.id
assets = ticket_list.assets(assets)
end
Expand Down Expand Up @@ -534,7 +529,6 @@ def stats
# lookup open user tickets
limit = 100
assets = {}
access_condition = Ticket.access_condition(current_user, 'read')

user_tickets = {}
if params[:user_id]
Expand Down Expand Up @@ -573,7 +567,7 @@ def stats
condition = {
'tickets.customer_id' => user.id,
}
user_tickets[:volume_by_year] = ticket_stats_last_year(condition, access_condition)
user_tickets[:volume_by_year] = ticket_stats_last_year(condition)

end

Expand Down Expand Up @@ -615,7 +609,7 @@ def stats
condition = {
'tickets.organization_id' => organization.id,
}
org_tickets[:volume_by_year] = ticket_stats_last_year(condition, access_condition)
org_tickets[:volume_by_year] = ticket_stats_last_year(condition)
end

# return result
Expand Down
52 changes: 12 additions & 40 deletions app/models/ticket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,43 +93,6 @@ class Ticket < ApplicationModel

=begin
get user access conditions
conditions = Ticket.access_condition( User.find(1) , 'full')
returns
result = [user1, user2, ...]
=end

def self.access_condition(user, access)
sql = []
bind = []

if user.permissions?('ticket.agent')
sql.push('group_id IN (?)')
bind.push(user.group_ids_access(access))
end

if user.permissions?('ticket.customer')
if !user.organization || (!user.organization.shared || user.organization.shared == false)
sql.push('tickets.customer_id = ?')
bind.push(user.id)
else
sql.push('(tickets.customer_id = ? OR tickets.organization_id = ?)')
bind.push(user.id)
bind.push(user.organization.id)
end
end

return if sql.blank?

[ sql.join(' OR ') ].concat(bind)
end

=begin
processes tickets which have reached their pending time and sets next state_id
processed_tickets = Ticket.process_pending
Expand Down Expand Up @@ -500,9 +463,18 @@ def self.selectors(selectors, options)
return [ticket_count, tickets]
end

access_condition = Ticket.access_condition(current_user, access)
ticket_count = Ticket.distinct.where(access_condition).where(query, *bind_params).joins(tables).count
tickets = Ticket.distinct.where(access_condition).where(query, *bind_params).joins(tables).limit(limit)
ticket_count = "TicketPolicy::#{access.camelize}Scope".constantize
.new(current_user).resolve
.distinct
.where(query, *bind_params)
.joins(tables)
.count
tickets = "TicketPolicy::#{access.camelize}Scope".constantize
.new(current_user).resolve
.distinct
.where(query, *bind_params)
.joins(tables)
.limit(limit)

return [ticket_count, tickets]
rescue ActiveRecord::StatementInvalid => e
Expand Down
30 changes: 15 additions & 15 deletions app/models/ticket/overviews.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,6 @@ def self.index(user, links = nil)
)
return [] if overviews.blank?

# get only tickets with permissions
access_condition = Ticket.access_condition(user, 'overview')
access_condition_read = Ticket.access_condition(user, 'read')

ticket_attributes = Ticket.new.attributes
list = []
overviews.each do |overview|
Expand Down Expand Up @@ -129,18 +125,17 @@ def self.index(user, links = nil)
end
end

overview_access_condition = access_condition
scope = TicketPolicy::OverviewScope
if overview.condition['ticket.mention_user_ids'].present?
overview_access_condition = access_condition_read
scope = TicketPolicy::ReadScope
end

ticket_result = Ticket.distinct
.where(overview_access_condition)
.where(query_condition, *bind_condition)
.joins(tables)
.order(Arel.sql("#{order_by} #{direction}"))
.limit(2000)
.pluck(:id, :updated_at, Arel.sql(order_by))
ticket_result = scope.new(user).resolve
.distinct
.where(query_condition, *bind_condition)
.joins(tables)
.order(Arel.sql("#{order_by} #{direction}"))
.limit(2000)
.pluck(:id, :updated_at, Arel.sql(order_by))

tickets = ticket_result.map do |ticket|
{
Expand All @@ -149,7 +144,12 @@ def self.index(user, links = nil)
}
end

count = Ticket.distinct.where(overview_access_condition).where(query_condition, *bind_condition).joins(tables).count()
count = TicketPolicy::OverviewScope.new(user).resolve
.distinct
.where(query_condition, *bind_condition)
.joins(tables)
.count()

item = {
overview: {
name: overview.name,
Expand Down
29 changes: 14 additions & 15 deletions app/models/ticket/screen_options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -177,29 +177,28 @@ def self.list_by_customer(data)
state_id_list_open = Ticket::State.by_category(:open).pluck(:id)
state_id_list_closed = Ticket::State.by_category(:closed).pluck(:id)

# open tickets by customer
access_condition = Ticket.access_condition(data[:current_user], 'read')

# get tickets
tickets_open = Ticket.where(
customer_id: data[:customer_id],
state_id: state_id_list_open
)
.where(access_condition)
.limit(data[:limit] || 15).order(created_at: :desc)
tickets_open = TicketPolicy::ReadScope.new(data[:current_user]).resolve
.where(
customer_id: data[:customer_id],
state_id: state_id_list_open
)
.limit(data[:limit] || 15)
.order(created_at: :desc)
assets = {}
ticket_ids_open = []
tickets_open.each do |ticket|
ticket_ids_open.push ticket.id
assets = ticket.assets(assets)
end

tickets_closed = Ticket.where(
customer_id: data[:customer_id],
state_id: state_id_list_closed
)
.where(access_condition)
.limit(data[:limit] || 15).order(created_at: :desc)
tickets_closed = TicketPolicy::ReadScope.new(data[:current_user]).resolve
.where(
customer_id: data[:customer_id],
state_id: state_id_list_closed
)
.limit(data[:limit] || 15)
.order(created_at: :desc)
ticket_ids_closed = []
tickets_closed.each do |ticket|
ticket_ids_closed.push ticket.id
Expand Down
31 changes: 14 additions & 17 deletions app/models/ticket/search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -190,32 +190,29 @@ def search(params)
return tickets
end

# fallback do sql query
access_condition = Ticket.access_condition(current_user, 'read')

# do query
# - stip out * we already search for *query* -

order_select_sql = sql_helper.get_order_select(sort_by, order_by, 'tickets.updated_at')
order_sql = sql_helper.get_order(sort_by, order_by, 'tickets.updated_at DESC')
if query
query.delete! '*'
tickets_all = Ticket.select("DISTINCT(tickets.id), #{order_select_sql}")
.where(access_condition)
.where('(tickets.title LIKE ? OR tickets.number LIKE ? OR ticket_articles.body LIKE ? OR ticket_articles.from LIKE ? OR ticket_articles.to LIKE ? OR ticket_articles.subject LIKE ?)', "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%")
.joins(:articles)
.order(Arel.sql(order_sql))
.offset(offset)
.limit(limit)
tickets_all = TicketPolicy::ReadScope.new(current_user).resolve
.select("DISTINCT(tickets.id), #{order_select_sql}")
.where('(tickets.title LIKE ? OR tickets.number LIKE ? OR ticket_articles.body LIKE ? OR ticket_articles.from LIKE ? OR ticket_articles.to LIKE ? OR ticket_articles.subject LIKE ?)', "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%")
.joins(:articles)
.order(Arel.sql(order_sql))
.offset(offset)
.limit(limit)
else
query_condition, bind_condition, tables = selector2sql(condition)
tickets_all = Ticket.select("DISTINCT(tickets.id), #{order_select_sql}")
.joins(tables)
.where(access_condition)
.where(query_condition, *bind_condition)
.order(Arel.sql(order_sql))
.offset(offset)
.limit(limit)
tickets_all = TicketPolicy::ReadScope.new(current_user).resolve
.select("DISTINCT(tickets.id), #{order_select_sql}")
.joins(tables)
.where(query_condition, *bind_condition)
.order(Arel.sql(order_sql))
.offset(offset)
.limit(limit)
end

# build result list
Expand Down
10 changes: 0 additions & 10 deletions app/policies/application_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,4 @@ class ApplicationPolicy
def initialize_context(record)
@record = record
end

class Scope
include PunditPolicy

attr_reader :scope

def initialize_context(scope)
@scope = scope
end
end
end
13 changes: 13 additions & 0 deletions app/policies/application_policy/scope.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/

class ApplicationPolicy
class Scope
include PunditPolicy

attr_reader :scope

def initialize_context(scope)
@scope = scope
end
end
end
13 changes: 0 additions & 13 deletions app/policies/organization_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,4 @@ def update?

false
end

class Scope < ApplicationPolicy::Scope

def resolve
if user.permissions?(['ticket.agent', 'admin.organization'])
scope.all
elsif user.organization_id
scope.where(id: user.organization_id)
else
scope.none
end
end
end
end
Loading

0 comments on commit 276c45b

Please sign in to comment.