Browse Source

Refactoring: Drop Ticket.access_condition in favor of using Pundit scopes.

Ryan Lue 3 years ago
parent
commit
276c45b2e9

+ 9 - 9
app/controllers/concerns/ticket_stats.rb

@@ -16,7 +16,7 @@ module TicketStats
     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
 
@@ -26,16 +26,16 @@ module TicketStats
       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,

+ 24 - 30
app/controllers/tickets_controller.rb

@@ -23,8 +23,10 @@ class TicketsController < ApplicationController
       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 = []
@@ -317,36 +319,29 @@ class TicketsController < ApplicationController
     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
@@ -534,7 +529,6 @@ class TicketsController < ApplicationController
     # lookup open user tickets
     limit            = 100
     assets           = {}
-    access_condition = Ticket.access_condition(current_user, 'read')
 
     user_tickets = {}
     if params[:user_id]
@@ -573,7 +567,7 @@ class TicketsController < ApplicationController
       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
 
@@ -615,7 +609,7 @@ class TicketsController < ApplicationController
       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

+ 12 - 40
app/models/ticket.rb

@@ -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
@@ -500,9 +463,18 @@ get count of tickets and tickets which match on selector
         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

+ 15 - 15
app/models/ticket/overviews.rb

@@ -92,10 +92,6 @@ returns
     )
     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|
@@ -129,18 +125,17 @@ returns
         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|
         {
@@ -149,7 +144,12 @@ returns
         }
       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,

+ 14 - 15
app/models/ticket/screen_options.rb

@@ -177,16 +177,14 @@ returns
     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|
@@ -194,12 +192,13 @@ returns
       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

+ 14 - 17
app/models/ticket/search.rb

@@ -190,9 +190,6 @@ returns
         return tickets
       end
 
-      # fallback do sql query
-      access_condition = Ticket.access_condition(current_user, 'read')
-
       # do query
       # - stip out * we already search for *query* -
 
@@ -200,22 +197,22 @@ returns
       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

+ 0 - 10
app/policies/application_policy.rb

@@ -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 - 0
app/policies/application_policy/scope.rb

@@ -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

+ 0 - 13
app/policies/organization_policy.rb

@@ -14,17 +14,4 @@ class OrganizationPolicy < ApplicationPolicy
 
     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

+ 16 - 0
app/policies/organization_policy/scope.rb

@@ -0,0 +1,16 @@
+# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
+
+class OrganizationPolicy < ApplicationPolicy
+  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

Some files were not shown because too many files changed in this diff