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'