app/models/foreman_tasks/task.rb in foreman-tasks-0.15.11 vs app/models/foreman_tasks/task.rb in foreman-tasks-0.16.0

- old
+ new

@@ -1,10 +1,11 @@ require 'securerandom' module ForemanTasks class Task < ApplicationRecord include Authorizable + extend Search def check_permissions_after_save # there's no create_tasks permission, tasks are created as a result of internal actions, in such case we # don't do authorization, that should have been performed on wrapping action level # the same applies for updating @@ -27,14 +28,11 @@ has_many :task_group_members, :dependent => :destroy has_many :task_groups, :through => :task_group_members has_many :recurring_logic_task_groups, -> { where :type => 'ForemanTasks::TaskGroups::RecurringLogicTaskGroup' }, :through => :task_group_members, :source => :task_group - # in fact, the task has only one owner but Rails don't let you to - # specify has_one relation though has_many relation - has_many :owners, -> { where(['foreman_tasks_locks.name = ?', Lock::OWNER_LOCK_NAME]) }, - :through => :locks, :source => :resource, :source_type => 'User' + belongs_to :user scoped_search :on => :id, :complete_value => false scoped_search :on => :action, :complete_value => false scoped_search :on => :label, :complete_value => true scoped_search :on => :state, :complete_value => true @@ -44,21 +42,19 @@ scoped_search :on => :start_at, :complete_value => false scoped_search :on => :ended_at, :complete_value => false scoped_search :on => :parent_task_id, :complete_value => true scoped_search :relation => :locks, :on => :resource_id, :complete_value => false, :rename => 'location_id', :ext_method => :search_by_taxonomy, :only_explicit => true scoped_search :relation => :locks, :on => :resource_id, :complete_value => false, :rename => 'organization_id', :ext_method => :search_by_taxonomy, :only_explicit => true - scoped_search :relation => :locks, :on => :resource_type, :complete_value => true, :rename => 'resource_type', :ext_method => :search_by_generic_resource - scoped_search :relation => :locks, :on => :resource_id, :complete_value => false, :rename => 'resource_id', :ext_method => :search_by_generic_resource - scoped_search :relation => :owners, - :on => :id, + scoped_search :relation => :locks, :on => :resource_type, :complete_value => true, :rename => 'resource_type', :ext_method => :search_by_generic_resource, :only_explicit => true + scoped_search :relation => :locks, :on => :resource_id, :complete_value => false, :rename => 'resource_id', :ext_method => :search_by_generic_resource, :only_explicit => true + scoped_search :on => :user_id, :complete_value => true, - :rename => 'owner.id', - :ext_method => :search_by_owner, + :rename => 'user.id', :validator => ->(value) { ScopedSearch::Validators::INTEGER.call(value) || value == 'current_user' }, - :aliases => ['user.id'] - scoped_search :relation => :owners, :on => :login, :complete_value => true, :rename => 'owner.login', :ext_method => :search_by_owner, :aliases => [:user] - scoped_search :relation => :owners, :on => :firstname, :complete_value => true, :rename => 'owner.firstname', :ext_method => :search_by_owner + :aliases => ['owner.id'], :ext_method => :search_by_owner, :only_explicit => true + scoped_search :relation => :user, :on => :login, :rename => 'user.login', :complete_value => true, :aliases => ['owner.login', 'user'], :ext_method => :search_by_owner, :only_explicit => true + scoped_search :relation => :user, :on => :firstname, :rename => 'user.firstname', :complete_value => true, :aliases => ['owner.firstname'], :ext_method => :search_by_owner, :only_explicit => true scoped_search :relation => :task_groups, :on => :id, :complete_value => true, :rename => 'task_group.id', :validator => ScopedSearch::Validators::INTEGER scope :active, -> { where('foreman_tasks_tasks.state != ?', :stopped) } scope :running, -> { where("foreman_tasks_tasks.state NOT IN ('stopped', 'paused')") } scope :for_resource, @@ -75,15 +71,15 @@ def output {} end def owner - owners.first + user end def username - owner.try(:login) + owner end def execution_type delayed? ? N_('Delayed') : N_('Immediate') end @@ -148,11 +144,11 @@ end end # used by Foreman notifications framework def notification_recipients_ids - owner_ids + [owner.id] end def build_notifications notifications = [] if paused? @@ -161,67 +157,9 @@ notifications << UINotifications::Tasks::TaskPausedOwner.new(self) end notifications << UINotifications::Tasks::TaskPausedAdmin.new(self) end notifications - end - - def self.search_by_generic_resource(key, operator, value) - key = 'resource_type' if key.blank? - key_name = connection.quote_column_name(key.sub(/^.*\./, '')) - condition = sanitize_sql_for_conditions(["foreman_tasks_locks.#{key_name} #{operator} ?", value]) - - { :conditions => condition, :joins => :locks } - end - - def self.search_by_taxonomy(key, operator, value) - uniq_suffix = SecureRandom.hex(3) - resource_type = key == 'location_id' ? 'Location' : 'Organization' - - joins = <<-SQL - LEFT JOIN foreman_tasks_locks AS foreman_tasks_locks_taxonomy#{uniq_suffix} - ON (foreman_tasks_locks_taxonomy#{uniq_suffix}.task_id = foreman_tasks_tasks.id AND - foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_type = '#{resource_type}') - SQL - # Select only those tasks which either have the correct taxonomy or are not related to any - sql = "foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_id #{operator} ? OR foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_id IS NULL" - { :conditions => sanitize_sql_for_conditions([sql, value]), :joins => joins } - end - - def self.search_by_owner(key, operator, value) - return { :conditions => '0 = 1' } if value == 'current_user' && User.current.nil? - - key = 'owners.login' if key == 'user' - # using uniq suffix to avoid colisions when searching by two different owners via ScopedSearch - uniq_suffix = SecureRandom.hex(3) - key_name = connection.quote_column_name(key.sub(/^.*\./, '')) - value.sub!('*', '%%') - condition = if key.blank? - sanitize_sql_for_conditions(["users#{uniq_suffix}.login #{operator} ? or users#{uniq_suffix}.firstname #{operator} ? ", value, value]) - elsif key =~ /\.id\Z/ - value = User.current.id if value == 'current_user' - sanitize_sql_for_conditions(["foreman_tasks_locks_owner#{uniq_suffix}.resource_id #{operator} ?", value]) - else - placeholder, value = operator == 'IN' ? ['(?)', value.split(',').map(&:strip)] : ['?', value] - sanitize_sql_for_conditions(["users#{uniq_suffix}.#{key_name} #{operator} #{placeholder}", value]) - end - { :conditions => condition, :joins => joins_for_user_search(key, uniq_suffix) } - end - - def self.joins_for_user_search(key, uniq_suffix) - joins = <<-SQL - INNER JOIN foreman_tasks_locks AS foreman_tasks_locks_owner#{uniq_suffix} - ON (foreman_tasks_locks_owner#{uniq_suffix}.task_id = foreman_tasks_tasks.id AND - foreman_tasks_locks_owner#{uniq_suffix}.resource_type = 'User' AND - foreman_tasks_locks_owner#{uniq_suffix}.name = '#{Lock::OWNER_LOCK_NAME}') - SQL - if key !~ /\.id\Z/ - joins << <<-SQL - INNER JOIN users as users#{uniq_suffix} - ON (users#{uniq_suffix}.id = foreman_tasks_locks_owner#{uniq_suffix}.resource_id) - SQL - end - joins end def progress case state.to_s when 'running', 'paused'