Updated rubocop to latest version (0.59.2) and applied required changes.
This commit is contained in:
parent
3d4d5414f1
commit
9af50f2a4e
536 changed files with 1327 additions and 340 deletions
|
@ -1,5 +1,5 @@
|
|||
# Default enabled cops
|
||||
# https://github.com/bbatsov/rubocop/blob/master/config/enabled.yml
|
||||
# https://github.com/rubocop-hq/rubocop/blob/master/config/default.yml
|
||||
|
||||
inherit_from: .rubocop_todo.yml
|
||||
|
||||
|
@ -144,6 +144,10 @@ Style/BracesAroundHashParameters:
|
|||
Description: 'Enforce braces style around hash parameters.'
|
||||
Enabled: false
|
||||
|
||||
Rails/BulkChangeTable:
|
||||
Description: 'Check whether alter queries are combinable.'
|
||||
Enabled: false
|
||||
|
||||
Rails/FindEach:
|
||||
Description: 'Prefer all.find_each over all.find.'
|
||||
Enabled: false
|
||||
|
|
|
@ -40,6 +40,14 @@ Rails/ApplicationRecord:
|
|||
Description: 'Check that models subclass ApplicationRecord.'
|
||||
Enabled: false
|
||||
|
||||
# Browser-Tests inherit from TestCase < Test::Unit::TestCase
|
||||
# which does not provide assert_not
|
||||
Rails/AssertNot:
|
||||
Description: 'Use `assert_not` instead of `assert !`.'
|
||||
Enabled: true
|
||||
Exclude:
|
||||
- "test/browser/*"
|
||||
|
||||
Rails/CreateTableWithTimestamps:
|
||||
Description: >-
|
||||
Checks the migration for which timestamps are not included
|
||||
|
|
14
Gemfile.lock
14
Gemfile.lock
|
@ -203,6 +203,7 @@ GEM
|
|||
ice_cube (0.16.2)
|
||||
inflection (1.0.0)
|
||||
interception (0.5)
|
||||
jaro_winkler (1.5.1)
|
||||
json (2.1.0)
|
||||
jwt (1.5.6)
|
||||
kgio (2.11.0)
|
||||
|
@ -293,12 +294,12 @@ GEM
|
|||
omniauth (~> 1.5)
|
||||
omniauth-oauth2 (>= 1.4.0)
|
||||
parallel (1.12.1)
|
||||
parser (2.5.0.5)
|
||||
parser (2.5.1.2)
|
||||
ast (~> 2.4.0)
|
||||
pg (0.21.0)
|
||||
pluginator (1.5.0)
|
||||
power_assert (1.1.1)
|
||||
powerpack (0.1.1)
|
||||
powerpack (0.1.2)
|
||||
pre-commit (0.37.0)
|
||||
pluginator (~> 1.5)
|
||||
pry (0.11.3)
|
||||
|
@ -377,14 +378,15 @@ GEM
|
|||
rspec-mocks (~> 3.8.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-support (3.8.0)
|
||||
rubocop (0.54.0)
|
||||
rubocop (0.59.2)
|
||||
jaro_winkler (~> 1.5.1)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 2.5)
|
||||
parser (>= 2.5, != 2.5.1.1)
|
||||
powerpack (~> 0.1)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (~> 1.0, >= 1.0.1)
|
||||
ruby-progressbar (1.9.0)
|
||||
ruby-progressbar (1.10.0)
|
||||
ruby_dep (1.5.0)
|
||||
rubyzip (1.2.2)
|
||||
safe_yaml (1.0.4)
|
||||
|
@ -463,7 +465,7 @@ GEM
|
|||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.7.5)
|
||||
unicode-display_width (1.3.0)
|
||||
unicode-display_width (1.4.0)
|
||||
unicorn (5.3.1)
|
||||
kgio (~> 2.6)
|
||||
raindrops (~> 0.7)
|
||||
|
|
|
@ -15,10 +15,12 @@ module ApplicationController::Authenticates
|
|||
permission: key,
|
||||
)
|
||||
return false if user
|
||||
|
||||
raise Exceptions::NotAuthorized, 'Not authorized (token)!'
|
||||
end
|
||||
|
||||
return false if current_user&.permissions?(key)
|
||||
|
||||
raise Exceptions::NotAuthorized, 'Not authorized (user)!'
|
||||
end
|
||||
|
||||
|
@ -68,6 +70,7 @@ module ApplicationController::Authenticates
|
|||
if Setting.get('api_password_access') == false
|
||||
raise Exceptions::NotAuthorized, 'API password access disabled!'
|
||||
end
|
||||
|
||||
user = User.authenticate(username, password)
|
||||
return authentication_check_prerequesits(user, 'basic_auth', auth_param) if user
|
||||
end
|
||||
|
@ -79,6 +82,7 @@ module ApplicationController::Authenticates
|
|||
if Setting.get('api_token_access') == false
|
||||
raise Exceptions::NotAuthorized, 'API token access disabled!'
|
||||
end
|
||||
|
||||
user = Token.check(
|
||||
action: 'api',
|
||||
name: token_string,
|
||||
|
|
|
@ -5,6 +5,7 @@ module ApplicationController::ChecksMaintainance
|
|||
|
||||
def check_maintenance(user)
|
||||
return false if !check_maintenance_only(user)
|
||||
|
||||
raise Exceptions::NotAuthorized, 'Maintenance mode enabled!'
|
||||
end
|
||||
|
||||
|
@ -12,6 +13,7 @@ module ApplicationController::ChecksMaintainance
|
|||
def check_maintenance_only(user)
|
||||
return false if Setting.get('maintenance_mode') != true
|
||||
return false if user.permissions?('admin.maintenance')
|
||||
|
||||
Rails.logger.info "Maintenance mode enabled, denied login for user #{user.login}, it's no admin user."
|
||||
true
|
||||
end
|
||||
|
|
|
@ -7,6 +7,7 @@ module ApplicationController::HandlesDevices
|
|||
|
||||
def user_device_check
|
||||
return false if !user_device_log(current_user, 'session')
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
|
@ -39,6 +40,7 @@ module ApplicationController::HandlesDevices
|
|||
# if ip has not changed and ttl in still valid
|
||||
remote_ip = ENV['TEST_REMOTE_IP'] || request.remote_ip
|
||||
return true if time_to_check == false && session[:user_device_remote_ip] == remote_ip
|
||||
|
||||
session[:user_device_remote_ip] = remote_ip
|
||||
|
||||
# for sessions we need the fingperprint
|
||||
|
@ -46,6 +48,7 @@ module ApplicationController::HandlesDevices
|
|||
if !session[:user_device_updated_at] && !params[:fingerprint] && !session[:user_device_fingerprint]
|
||||
raise Exceptions::UnprocessableEntity, 'Need fingerprint param!'
|
||||
end
|
||||
|
||||
if params[:fingerprint]
|
||||
UserDevice.fingerprint_validation(params[:fingerprint])
|
||||
session[:user_device_fingerprint] = params[:fingerprint]
|
||||
|
|
|
@ -17,6 +17,7 @@ module ApplicationController::HasResponseExtentions
|
|||
return true if params[:full] == 'true'
|
||||
return true if params[:full] == 1
|
||||
return true if params[:full] == '1'
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
|
@ -25,6 +26,7 @@ module ApplicationController::HasResponseExtentions
|
|||
return true if params[:all] == 'true'
|
||||
return true if params[:all] == 1
|
||||
return true if params[:all] == '1'
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ module ApplicationController::HasUser
|
|||
def current_user
|
||||
user_on_behalf = current_user_on_behalf
|
||||
return user_on_behalf if user_on_behalf
|
||||
|
||||
current_user_real
|
||||
end
|
||||
|
||||
|
@ -20,6 +21,7 @@ module ApplicationController::HasUser
|
|||
def current_user_real
|
||||
return @_current_user if @_current_user
|
||||
return if !session[:user_id]
|
||||
|
||||
@_current_user = User.lookup(id: session[:user_id])
|
||||
end
|
||||
|
||||
|
@ -49,6 +51,7 @@ module ApplicationController::HasUser
|
|||
search_attributes[field] = request.headers['X-On-Behalf-Of']
|
||||
@_user_on_behalf = User.find_by(search_attributes)
|
||||
next if !@_user_on_behalf
|
||||
|
||||
return @_user_on_behalf
|
||||
end
|
||||
|
||||
|
@ -89,11 +92,13 @@ module ApplicationController::HasUser
|
|||
|
||||
# fill user agent
|
||||
return if session[:user_agent]
|
||||
|
||||
session[:user_agent] = request.env['HTTP_USER_AGENT']
|
||||
end
|
||||
|
||||
def valid_session_with_user
|
||||
return true if current_user
|
||||
|
||||
raise Exceptions::UnprocessableEntity, 'No session user!'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,6 +24,7 @@ module ApplicationController::LogsHttpAccess
|
|||
}
|
||||
request.headers.each do |key, value|
|
||||
next if key[0, 5] != 'HTTP_'
|
||||
|
||||
request_data[:content] += if key == 'HTTP_COOKIE'
|
||||
"#{key}: xxxxx\n"
|
||||
else
|
||||
|
|
|
@ -10,6 +10,7 @@ module ApplicationController::PreventsCsrf
|
|||
|
||||
def set_csrf_token_headers
|
||||
return true if @_auth_type.present? && @_auth_type != 'session'
|
||||
|
||||
headers['CSRF-TOKEN'] = form_authenticity_token
|
||||
end
|
||||
|
||||
|
@ -19,6 +20,7 @@ module ApplicationController::PreventsCsrf
|
|||
return true if request.head?
|
||||
return true if %w[token_auth basic_auth].include?(@_auth_type)
|
||||
return true if valid_authenticity_token?(session, params[:authenticity_token] || request.headers['X-CSRF-Token'])
|
||||
|
||||
logger.info 'CSRF token verification failed'
|
||||
raise Exceptions::NotAuthorized, 'CSRF token verification failed!'
|
||||
end
|
||||
|
|
|
@ -156,6 +156,7 @@ module ApplicationController::RendersModels
|
|||
generic_object = object.find(params[:id])
|
||||
result = Models.references(object, generic_object.id)
|
||||
return false if result.blank?
|
||||
|
||||
raise Exceptions::UnprocessableEntity, 'Can\'t delete, object has references.'
|
||||
rescue => e
|
||||
raise Exceptions::UnprocessableEntity, e
|
||||
|
|
|
@ -11,6 +11,7 @@ module ApplicationController::SetsHeaders
|
|||
# For all responses in this controller, return the CORS access control headers.
|
||||
def set_access_control_headers
|
||||
return if @_auth_type != 'token_auth' && @_auth_type != 'basic_auth'
|
||||
|
||||
set_access_control_headers_execute
|
||||
end
|
||||
|
||||
|
@ -26,11 +27,13 @@ module ApplicationController::SetsHeaders
|
|||
# text/plain.
|
||||
def cors_preflight_check
|
||||
return true if @_auth_type != 'token_auth' && @_auth_type != 'basic_auth'
|
||||
|
||||
cors_preflight_check_execute
|
||||
end
|
||||
|
||||
def cors_preflight_check_execute
|
||||
return true if request.method != 'OPTIONS'
|
||||
|
||||
headers['Access-Control-Allow-Origin'] = '*'
|
||||
headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, PATCH, OPTIONS'
|
||||
headers['Access-Control-Allow-Headers'] = 'Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control, Accept-Language'
|
||||
|
|
|
@ -29,6 +29,7 @@ class ChannelsEmailController < ApplicationController
|
|||
end
|
||||
EmailAddress.all.each do |email_address|
|
||||
next if system_online_service && email_address.preferences && email_address.preferences['online_service_disable']
|
||||
|
||||
email_address_ids.push email_address.id
|
||||
assets = email_address.assets(assets)
|
||||
if !email_address.channel_id || !email_address.active || !Channel.find_by(id: email_address.channel_id)
|
||||
|
@ -256,6 +257,7 @@ class ChannelsEmailController < ApplicationController
|
|||
next if channel.options[:inbound][:options][:user] != result[:setting][:inbound][:options][:user]
|
||||
next if channel.options[:inbound][:options][:folder].to_s != result[:setting][:inbound][:options][:folder].to_s
|
||||
next if channel.id.to_s == channel_id.to_s
|
||||
|
||||
render json: {
|
||||
result: 'duplicate',
|
||||
message: 'Account already exists!',
|
||||
|
@ -267,6 +269,7 @@ class ChannelsEmailController < ApplicationController
|
|||
|
||||
def check_online_service
|
||||
return true if !Setting.get('system_online_service')
|
||||
|
||||
raise Exceptions::NotAuthorized
|
||||
end
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ module ChecksUserAttributesByCurrentUserPermission
|
|||
return true if params[:id].present?
|
||||
return true if params[:role_ids]
|
||||
return true if params[:roles]
|
||||
|
||||
params[:role_ids] = Role.signup_role_ids
|
||||
true
|
||||
end
|
||||
|
|
|
@ -13,8 +13,10 @@ module ClonesTicketArticleAttachments
|
|||
attachments = []
|
||||
article.attachments.each do |new_attachment|
|
||||
next if new_attachment.preferences['content-alternative'] == true
|
||||
|
||||
if article.content_type.present? && article.content_type =~ %r{text/html}i
|
||||
next if new_attachment.preferences['content_disposition'].present? && new_attachment.preferences['content_disposition'] !~ /inline/
|
||||
|
||||
if new_attachment.preferences['Content-ID'].present? && article.body.present?
|
||||
next if article.body.match?(/#{Regexp.quote(new_attachment.preferences['Content-ID'])}/i)
|
||||
end
|
||||
|
@ -22,10 +24,12 @@ module ClonesTicketArticleAttachments
|
|||
already_added = false
|
||||
existing_attachments.each do |existing_attachment|
|
||||
next if existing_attachment.filename != new_attachment.filename || existing_attachment.size != new_attachment.size
|
||||
|
||||
already_added = true
|
||||
break
|
||||
end
|
||||
next if already_added == true
|
||||
|
||||
file = Store.add(
|
||||
object: 'UploadCache',
|
||||
o_id: params[:form_id],
|
||||
|
|
|
@ -84,12 +84,14 @@ module CreatesTicketArticles
|
|||
# validation
|
||||
['mime-type', 'filename', 'data'].each do |key|
|
||||
next if attachment[key]
|
||||
|
||||
raise Exceptions::UnprocessableEntity, "Attachment needs '#{key}' param for attachment with index '#{index}'"
|
||||
end
|
||||
|
||||
preferences = {}
|
||||
['charset', 'mime-type'].each do |key|
|
||||
next if !attachment[key]
|
||||
|
||||
store_key = key.tr('-', '_').camelize.gsub(/(.+)([A-Z])/, '\1_\2').tr('_', '-')
|
||||
preferences[store_key] = attachment[key]
|
||||
end
|
||||
|
|
|
@ -58,6 +58,7 @@ class ExternalCredentialsController < ApplicationController
|
|||
if params[:id].present? && ExternalCredential.exists?(params[:id])
|
||||
external_credential = ExternalCredential.find(params[:id])
|
||||
raise 'No such ExternalCredential!' if !external_credential
|
||||
|
||||
authentication_check(permission: ["admin.channel_#{external_credential.name}"])
|
||||
return
|
||||
end
|
||||
|
|
|
@ -223,6 +223,7 @@ class FirstStepsController < ApplicationController
|
|||
|
||||
def access?
|
||||
return true if current_user.permissions?(['admin', 'ticket.agent'])
|
||||
|
||||
render json: []
|
||||
false
|
||||
end
|
||||
|
@ -243,10 +244,12 @@ class FirstStepsController < ApplicationController
|
|||
test_ticket_active = false
|
||||
end
|
||||
return result if test_ticket_active
|
||||
|
||||
result.each do |item|
|
||||
items = []
|
||||
item[:items].each do |local_item|
|
||||
next if local_item[:name] == 'Create a Test Ticket'
|
||||
|
||||
items.push local_item
|
||||
end
|
||||
item[:items] = items
|
||||
|
|
|
@ -230,6 +230,7 @@ class FormController < ApplicationController
|
|||
|
||||
def fingerprint_exists?
|
||||
return true if params[:fingerprint].present? && params[:fingerprint].length > 30
|
||||
|
||||
Rails.logger.info 'No fingerprint given!'
|
||||
response_access_deny
|
||||
false
|
||||
|
@ -238,6 +239,7 @@ class FormController < ApplicationController
|
|||
def enabled?
|
||||
return true if params[:test] && current_user && current_user.permissions?('admin.channel_formular')
|
||||
return true if Setting.get('form_ticket_create')
|
||||
|
||||
response_access_deny
|
||||
false
|
||||
end
|
||||
|
|
|
@ -103,6 +103,7 @@ class ImportOtrsController < ApplicationController
|
|||
|
||||
def import_start
|
||||
return if setup_done_response
|
||||
|
||||
Setting.set('import_mode', true)
|
||||
welcome = Import::OTRS.connection_test
|
||||
if !welcome
|
||||
|
@ -130,6 +131,7 @@ class ImportOtrsController < ApplicationController
|
|||
dynamic_fields = Import::OTRS::Requester.load('DynamicField')
|
||||
dynamic_fields.each do |dynamic_field|
|
||||
next if dynamic_field['ValidID'].to_i != 1
|
||||
|
||||
dynamic_field_count += 1
|
||||
end
|
||||
if dynamic_field_count > 20
|
||||
|
@ -140,6 +142,7 @@ class ImportOtrsController < ApplicationController
|
|||
sys_configs = Import::OTRS::Requester.load('SysConfig')
|
||||
sys_configs.each do |sys_config|
|
||||
next if sys_config['Key'] != 'Process'
|
||||
|
||||
issues.push 'otrsProcesses'
|
||||
end
|
||||
|
||||
|
@ -176,6 +179,7 @@ class ImportOtrsController < ApplicationController
|
|||
if !setup_done
|
||||
return false
|
||||
end
|
||||
|
||||
render json: {
|
||||
setup_done: true,
|
||||
}
|
||||
|
|
|
@ -93,6 +93,7 @@ class ImportZendeskController < ApplicationController
|
|||
|
||||
def import_start
|
||||
return if setup_done_response
|
||||
|
||||
Setting.set('import_mode', true)
|
||||
Setting.set('import_backend', 'zendesk')
|
||||
|
||||
|
@ -129,6 +130,7 @@ class ImportZendeskController < ApplicationController
|
|||
if !setup_done
|
||||
return false
|
||||
end
|
||||
|
||||
render json: {
|
||||
setup_done: true,
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ UserAgent: #{request.env['HTTP_USER_AGENT']}
|
|||
ticket_ids_found.each do |ticket_id|
|
||||
ticket = Ticket.find_by(id: ticket_id)
|
||||
next if !ticket
|
||||
|
||||
article = Ticket::Article.create!(
|
||||
ticket_id: ticket_id,
|
||||
type_id: Ticket::Article::Type.find_by(name: 'web').id,
|
||||
|
@ -84,6 +85,7 @@ UserAgent: #{request.env['HTTP_USER_AGENT']}
|
|||
ticket_ids_found.each do |ticket_id|
|
||||
ticket = Ticket.find_by(id: ticket_id)
|
||||
next if !ticket
|
||||
|
||||
ticket.state_id = auto_close_state_id
|
||||
ticket.save!
|
||||
end
|
||||
|
|
|
@ -48,6 +48,7 @@ class Integration::CtiController < ApplicationController
|
|||
routing_table.each do |row|
|
||||
dest = row[:dest].gsub(/\*/, '.+?')
|
||||
next if to !~ /^#{dest}$/
|
||||
|
||||
from = row[:caller_id]
|
||||
data = {
|
||||
action: 'dial',
|
||||
|
|
|
@ -19,6 +19,7 @@ class Integration::LdapController < ApplicationController
|
|||
rescue => e
|
||||
# workaround for issue #1114
|
||||
raise if !e.message.end_with?(', 48, Inappropriate Authentication')
|
||||
|
||||
# return empty result
|
||||
{}
|
||||
end
|
||||
|
|
|
@ -14,6 +14,7 @@ class Integration::SipgateController < ApplicationController
|
|||
# check if call need to be blocked
|
||||
block_caller_ids.each do |item|
|
||||
next if item[:caller_id] != params['from']
|
||||
|
||||
xml = Builder::XmlMarkup.new(indent: 2)
|
||||
xml.instruct!
|
||||
content = xml.Response(onHangup: url, onAnswer: url) do
|
||||
|
@ -61,6 +62,7 @@ class Integration::SipgateController < ApplicationController
|
|||
routing_table.each do |row|
|
||||
dest = row[:dest].gsub(/\*/, '.+?')
|
||||
next if to !~ /^#{dest}$/
|
||||
|
||||
from = row[:caller_id]
|
||||
content = xml.Response(onHangup: url, onAnswer: url) do
|
||||
xml.Dial(callerId: from) { xml.Number(params[:to]) }
|
||||
|
|
|
@ -103,8 +103,10 @@ class LongPollingController < ApplicationController
|
|||
|
||||
def client_id_verify
|
||||
return if !params[:client_id]
|
||||
|
||||
sessions = Sessions.sessions
|
||||
return if !sessions.include?(params[:client_id].to_s)
|
||||
|
||||
params[:client_id].to_s
|
||||
end
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ curl http://localhost/api/v1/monitoring/health_check?token=XXX
|
|||
message = "Channel: #{channel.area} in "
|
||||
%w[host user uid].each do |key|
|
||||
next if channel.options[key].blank?
|
||||
|
||||
message += "key:#{channel.options[key]};"
|
||||
end
|
||||
issues.push "#{message} #{channel.last_log_in}"
|
||||
|
@ -52,9 +53,11 @@ curl http://localhost/api/v1/monitoring/health_check?token=XXX
|
|||
|
||||
# outbound channel
|
||||
next if channel.status_out != 'error'
|
||||
|
||||
message = "Channel: #{channel.area} out "
|
||||
%w[host user uid].each do |key|
|
||||
next if channel.options[key].blank?
|
||||
|
||||
message += "key:#{channel.options[key]};"
|
||||
end
|
||||
issues.push "#{message} #{channel.last_log_out}"
|
||||
|
@ -76,6 +79,7 @@ curl http://localhost/api/v1/monitoring/health_check?token=XXX
|
|||
Scheduler.where('active = ? AND period > 300', true).where.not(last_run: nil).order(last_run: :asc, period: :asc).each do |scheduler|
|
||||
diff = Time.zone.now - (scheduler.last_run + scheduler.period.seconds)
|
||||
next if diff < 8.minutes
|
||||
|
||||
issues.push "scheduler may not run (last execution of #{scheduler.method} #{helpers.time_ago_in_words(Time.zone.now - diff.seconds)} over) - please contact your system administrator"
|
||||
break
|
||||
end
|
||||
|
@ -259,11 +263,13 @@ curl http://localhost/api/v1/monitoring/status?token=XXX
|
|||
user = authentication_check_only(permission: 'admin.monitoring')
|
||||
return if user
|
||||
return if Setting.get('monitoring_token') == params[:token]
|
||||
|
||||
raise Exceptions::NotAuthorized
|
||||
end
|
||||
|
||||
def access_check
|
||||
return if Permission.find_by(name: 'admin.monitoring', active: true)
|
||||
|
||||
raise Exceptions::NotAuthorized
|
||||
end
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ curl http://localhost/api/v1/online_notifications/#{id} -v -u #{login}:#{passwor
|
|||
|
||||
def show
|
||||
return if !access?
|
||||
|
||||
model_show_render(OnlineNotification, params)
|
||||
end
|
||||
|
||||
|
@ -131,6 +132,7 @@ curl http://localhost/api/v1/online_notifications -v -u #{login}:#{password} -H
|
|||
|
||||
def update
|
||||
return if !access?
|
||||
|
||||
model_update_render(OnlineNotification, params)
|
||||
end
|
||||
|
||||
|
@ -149,6 +151,7 @@ curl http://localhost/api/v1/online_notifications/{id}.json -v -u #{login}:#{pas
|
|||
|
||||
def destroy
|
||||
return if !access?
|
||||
|
||||
model_destroy_render(OnlineNotification, params)
|
||||
end
|
||||
|
||||
|
|
|
@ -190,6 +190,7 @@ curl http://localhost/api/v1/overviews_prio -v -u #{login}:#{password} -H "Conte
|
|||
params[:prios].each do |overview_prio|
|
||||
overview = Overview.find(overview_prio[0])
|
||||
next if overview.prio == overview_prio[1]
|
||||
|
||||
overview.prio = overview_prio[1]
|
||||
overview.save!
|
||||
end
|
||||
|
|
|
@ -30,6 +30,7 @@ class ReportsController < ApplicationController
|
|||
backend[:condition] = condition
|
||||
end
|
||||
next if !backend[:adapter]
|
||||
|
||||
result[backend[:name]] = backend[:adapter].aggs(
|
||||
range_start: get_params[:start],
|
||||
range_end: get_params[:stop],
|
||||
|
@ -75,6 +76,7 @@ class ReportsController < ApplicationController
|
|||
result = {}
|
||||
get_params[:metric][:backend].each do |backend|
|
||||
next if params[:downloadBackendSelected] != backend[:name]
|
||||
|
||||
condition = get_params[:profile].condition
|
||||
if backend[:condition]
|
||||
backend[:condition].merge(condition)
|
||||
|
@ -82,6 +84,7 @@ class ReportsController < ApplicationController
|
|||
backend[:condition] = condition
|
||||
end
|
||||
next if !backend[:adapter]
|
||||
|
||||
result = backend[:adapter].items(
|
||||
range_start: get_params[:start],
|
||||
range_end: get_params[:stop],
|
||||
|
@ -95,6 +98,7 @@ class ReportsController < ApplicationController
|
|||
|
||||
# generate sheet
|
||||
next if !params[:sheet]
|
||||
|
||||
content = sheet(get_params[:profile], backend[:display], result)
|
||||
send_data(
|
||||
content,
|
||||
|
@ -113,11 +117,13 @@ class ReportsController < ApplicationController
|
|||
if !params[:profiles] && !params[:profile_id]
|
||||
raise Exceptions::UnprocessableEntity, 'No such profiles param'
|
||||
end
|
||||
|
||||
if params[:profile_id]
|
||||
profile = Report::Profile.find(params[:profile_id])
|
||||
else
|
||||
params[:profiles].each do |profile_id, active|
|
||||
next if !active
|
||||
|
||||
profile = Report::Profile.find(profile_id)
|
||||
end
|
||||
end
|
||||
|
@ -129,6 +135,7 @@ class ReportsController < ApplicationController
|
|||
if !local_config || !local_config[:metric] || !local_config[:metric][params[:metric].to_sym]
|
||||
raise Exceptions::UnprocessableEntity, "No such metric #{params[:metric]}"
|
||||
end
|
||||
|
||||
metric = local_config[:metric][params[:metric].to_sym]
|
||||
|
||||
#{"metric"=>"count", "year"=>2015, "month"=>10, "week"=>43, "day"=>20, "timeSlot"=>"year", "report"=>{"metric"=>"count", "year"=>2015, "month"=>10, "week"=>43, "day"=>20, "timeSlot"=>"year"}}
|
||||
|
|
|
@ -36,6 +36,7 @@ class SearchController < ApplicationController
|
|||
local_class = object.constantize
|
||||
preferences = local_class.search_preferences(current_user)
|
||||
next if !preferences
|
||||
|
||||
objects_in_order_hash[preferences[:prio]] = local_class
|
||||
end
|
||||
objects_in_order_hash.keys.sort.reverse_each do |prio|
|
||||
|
@ -53,6 +54,7 @@ class SearchController < ApplicationController
|
|||
objects.each do |object|
|
||||
preferences = object.constantize.search_preferences(current_user)
|
||||
next if !preferences
|
||||
|
||||
if preferences[:direct_search_index]
|
||||
objects_with_direct_search_index.push object
|
||||
else
|
||||
|
@ -68,6 +70,7 @@ class SearchController < ApplicationController
|
|||
local_class = Kernel.const_get(item[:type])
|
||||
record = local_class.lookup(id: item[:id])
|
||||
next if !record
|
||||
|
||||
assets = record.assets(assets)
|
||||
item[:type] = local_class.to_app_model.to_s
|
||||
result.push item
|
||||
|
@ -87,6 +90,7 @@ class SearchController < ApplicationController
|
|||
objects_in_order.each do |object|
|
||||
result.each do |item|
|
||||
next if item[:type] != object.to_app_model.to_s
|
||||
|
||||
item[:id] = item[:id].to_i
|
||||
result_in_order.push item
|
||||
end
|
||||
|
|
|
@ -45,5 +45,5 @@ module ExtraCollection
|
|||
|
||||
[collections, assets]
|
||||
end
|
||||
module_function :session
|
||||
module_function :session # rubocop:disable Style/AccessModifierDeclarations
|
||||
end
|
||||
|
|
|
@ -10,9 +10,10 @@ module ExtraCollection
|
|||
key: 'dashboard',
|
||||
)
|
||||
return [collections, assets] if !item
|
||||
|
||||
collections['StatsStore'] = [item]
|
||||
|
||||
[collections, assets]
|
||||
end
|
||||
module_function :session
|
||||
module_function :session # rubocop:disable Style/AccessModifierDeclarations
|
||||
end
|
||||
|
|
|
@ -44,5 +44,5 @@ module ExtraCollection
|
|||
end
|
||||
[collections, assets]
|
||||
end
|
||||
module_function :session
|
||||
module_function :session # rubocop:disable Style/AccessModifierDeclarations
|
||||
end
|
||||
|
|
|
@ -288,10 +288,13 @@ class SessionsController < ApplicationController
|
|||
sessions_clean = []
|
||||
SessionHelper.list.each do |session|
|
||||
next if session.data['user_id'].blank?
|
||||
|
||||
sessions_clean.push session
|
||||
next if session.data['user_id']
|
||||
|
||||
user = User.lookup(id: session.data['user_id'])
|
||||
next if !user
|
||||
|
||||
assets = user.assets(assets)
|
||||
end
|
||||
render json: {
|
||||
|
@ -314,8 +317,10 @@ class SessionsController < ApplicationController
|
|||
config = {}
|
||||
Setting.select('name, preferences').where(frontend: true).each do |setting|
|
||||
next if setting.preferences[:authentication] == true && !current_user
|
||||
|
||||
value = Setting.get(setting.name)
|
||||
next if !current_user && (value == false || value.nil?)
|
||||
|
||||
config[setting.name] = value
|
||||
end
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ class SettingsController < ApplicationController
|
|||
list = []
|
||||
Setting.all.each do |setting|
|
||||
next if setting.preferences[:permission] && !current_user.permissions?(setting.preferences[:permission])
|
||||
|
||||
list.push setting
|
||||
end
|
||||
render json: list, status: :ok
|
||||
|
|
|
@ -44,6 +44,7 @@ class TicketArticlesController < ApplicationController
|
|||
|
||||
# ignore internal article if customer is requesting
|
||||
next if article.internal == true && current_user.permissions?('ticket.customer')
|
||||
|
||||
result = article.attributes_with_association_names
|
||||
articles.push result
|
||||
end
|
||||
|
@ -74,6 +75,7 @@ class TicketArticlesController < ApplicationController
|
|||
|
||||
# ignore internal article if customer is requesting
|
||||
next if article.internal == true && current_user.permissions?('ticket.customer')
|
||||
|
||||
articles.push article.attributes_with_association_names
|
||||
end
|
||||
render json: articles, status: :ok
|
||||
|
@ -315,6 +317,7 @@ class TicketArticlesController < ApplicationController
|
|||
if Setting.get('import_mode') != true
|
||||
raise 'Only can import tickets if system is in import mode.'
|
||||
end
|
||||
|
||||
result = Ticket::Article.csv_import(
|
||||
string: params[:file].read.force_encoding('utf-8'),
|
||||
parse_params: {
|
||||
|
@ -331,6 +334,7 @@ class TicketArticlesController < ApplicationController
|
|||
disposition = params.fetch(:disposition, 'inline')
|
||||
valid_disposition = %w[inline attachment]
|
||||
return disposition if valid_disposition.include?(disposition)
|
||||
|
||||
raise Exceptions::NotAuthorized, "Invalid disposition #{disposition} requested. Only #{valid_disposition.join(', ')} are valid."
|
||||
end
|
||||
end
|
||||
|
|
|
@ -31,6 +31,7 @@ class TicketStatesController < ApplicationController
|
|||
def destroy
|
||||
permission_check('admin.object')
|
||||
return if model_references_check(Ticket::State, params)
|
||||
|
||||
model_destroy_render(Ticket::State, params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -177,10 +177,13 @@ class TicketsController < ApplicationController
|
|||
if params[:links].present?
|
||||
link = params[:links].permit!.to_h
|
||||
raise Exceptions::UnprocessableEntity, 'Invalid link structure' if !link.is_a? Hash
|
||||
|
||||
link.each do |target_object, link_types_with_object_ids|
|
||||
raise Exceptions::UnprocessableEntity, 'Invalid link structure (Object)' if !link_types_with_object_ids.is_a? Hash
|
||||
|
||||
link_types_with_object_ids.each do |link_type, object_ids|
|
||||
raise Exceptions::UnprocessableEntity, 'Invalid link structure (Object->LinkType)' if !object_ids.is_a? Array
|
||||
|
||||
object_ids.each do |local_object_id|
|
||||
link = Link.add(
|
||||
link_type: link_type,
|
||||
|
@ -342,6 +345,7 @@ class TicketsController < ApplicationController
|
|||
recent_views.each do |recent_view|
|
||||
next if recent_view.object.name != 'Ticket'
|
||||
next if recent_view.o_id == ticket.id
|
||||
|
||||
ticket_ids_recent_viewed.push recent_view.o_id
|
||||
recent_view_ticket = Ticket.find(recent_view.o_id)
|
||||
assets = recent_view_ticket.assets(assets)
|
||||
|
@ -516,6 +520,7 @@ class TicketsController < ApplicationController
|
|||
if !user
|
||||
raise "No such user with id #{params[:user_id]}"
|
||||
end
|
||||
|
||||
conditions = {
|
||||
closed_ids: {
|
||||
'ticket.state_id' => {
|
||||
|
@ -557,6 +562,7 @@ class TicketsController < ApplicationController
|
|||
if !organization
|
||||
raise "No such organization with id #{params[:organization_id]}"
|
||||
end
|
||||
|
||||
conditions = {
|
||||
closed_ids: {
|
||||
'ticket.state_id' => {
|
||||
|
@ -634,6 +640,7 @@ class TicketsController < ApplicationController
|
|||
if Setting.get('import_mode') != true
|
||||
raise 'Only can import tickets if system is in import mode.'
|
||||
end
|
||||
|
||||
string = params[:data] || params[:file].read.force_encoding('utf-8')
|
||||
result = Ticket.csv_import(
|
||||
string: string,
|
||||
|
@ -652,6 +659,7 @@ class TicketsController < ApplicationController
|
|||
|
||||
return true if ticket.group.follow_up_possible != 'new_ticket' # check if the setting for follow_up_possible is disabled
|
||||
return true if ticket.state.name != 'closed' # check if the ticket state is already closed
|
||||
|
||||
raise Exceptions::UnprocessableEntity, 'Cannot follow up on a closed ticket. Please create a new ticket.'
|
||||
end
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ class TimeAccountingsController < ApplicationController
|
|||
time_unit.each do |ticket_id, local_time_unit|
|
||||
ticket = Ticket.lookup(id: ticket_id)
|
||||
next if !ticket
|
||||
|
||||
if !customers[ticket.customer_id]
|
||||
customers[ticket.customer_id] = '-'
|
||||
if ticket.customer_id
|
||||
|
@ -264,6 +265,7 @@ class TimeAccountingsController < ApplicationController
|
|||
time_unit.each do |ticket_id, local_time_unit|
|
||||
ticket = Ticket.lookup(id: ticket_id)
|
||||
next if !ticket
|
||||
|
||||
if !customers[ticket.customer_id]
|
||||
organization = nil
|
||||
if ticket.organization_id
|
||||
|
@ -345,6 +347,7 @@ class TimeAccountingsController < ApplicationController
|
|||
ticket = Ticket.lookup(id: ticket_id)
|
||||
next if !ticket
|
||||
next if !ticket.organization_id
|
||||
|
||||
if !organizations[ticket.organization_id]
|
||||
organizations[ticket.organization_id] = {
|
||||
organization: Organization.lookup(id: ticket.organization_id).attributes,
|
||||
|
|
|
@ -41,6 +41,7 @@ curl http://localhost/api/v1/user_access_token -v -u #{login}:#{password}
|
|||
keys = Object.const_get('Permission').with_parents(key)
|
||||
keys.each do |local_key|
|
||||
next if local_permissions_new.key?([local_key])
|
||||
|
||||
if local_permissions[local_key] == true
|
||||
local_permissions_new[local_key] = true
|
||||
next
|
||||
|
@ -51,6 +52,7 @@ curl http://localhost/api/v1/user_access_token -v -u #{login}:#{password}
|
|||
permissions = []
|
||||
Permission.all.where(active: true).order(:name).each do |permission|
|
||||
next if !local_permissions_new.key?(permission.name) && !current_user.permissions?(permission.name)
|
||||
|
||||
permission_attributes = permission.attributes
|
||||
if local_permissions_new[permission.name] == false
|
||||
permission_attributes['preferences']['disabled'] = true
|
||||
|
@ -93,6 +95,7 @@ curl http://localhost/api/v1/user_access_token -v -u #{login}:#{password} -H "Co
|
|||
if params[:label].blank?
|
||||
raise Exceptions::UnprocessableEntity, 'Need label!'
|
||||
end
|
||||
|
||||
token = Token.create!(
|
||||
action: 'api',
|
||||
label: params[:label],
|
||||
|
@ -124,6 +127,7 @@ curl http://localhost/api/v1/user_access_token/{id} -v -u #{login}:#{password} -
|
|||
def destroy
|
||||
token = Token.find_by(action: 'api', user_id: current_user.id, id: params[:id])
|
||||
raise Exceptions::UnprocessableEntity, 'Unable to find api token!' if !token
|
||||
|
||||
token.destroy!
|
||||
render json: {}, status: :ok
|
||||
end
|
||||
|
|
|
@ -36,6 +36,7 @@ class UserDevicesController < ApplicationController
|
|||
next if !session.data['user_id']
|
||||
next if !session.data['user_device_id']
|
||||
next if session.data['user_device_id'] != user_device.id
|
||||
|
||||
SessionHelper.destroy( session.id )
|
||||
end
|
||||
user_device.destroy
|
||||
|
|
|
@ -411,6 +411,7 @@ class UsersController < ApplicationController
|
|||
}
|
||||
%i[role_ids permissions].each do |key|
|
||||
next if params[key].blank?
|
||||
|
||||
query_params[key] = params[key]
|
||||
end
|
||||
|
||||
|
@ -827,6 +828,7 @@ curl http://localhost/api/v1/users/out_of_office -v -u #{login}:#{password} -H "
|
|||
|
||||
def out_of_office
|
||||
raise Exceptions::UnprocessableEntity, 'No current user!' if !current_user
|
||||
|
||||
user = User.find(current_user.id)
|
||||
user.with_lock do
|
||||
user.assign_attributes(
|
||||
|
@ -1065,6 +1067,7 @@ curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content
|
|||
if Setting.get('password_min_2_lower_2_upper_characters').to_i == 1 && ( password !~ /[A-Z].*[A-Z]/ || password !~ /[a-z].*[a-z]/ )
|
||||
return ["Can't update password, it must contain at least 2 lowercase and 2 uppercase characters!"]
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
end
|
||||
|
|
|
@ -45,6 +45,7 @@ add a new activity entry for an object
|
|||
if !permission
|
||||
raise "No such Permission #{data[:permission]}"
|
||||
end
|
||||
|
||||
permission_id = permission.id
|
||||
end
|
||||
|
||||
|
|
|
@ -43,12 +43,15 @@ returns
|
|||
end
|
||||
|
||||
return data if !self['created_by_id']
|
||||
|
||||
app_model_user = User.to_app_model
|
||||
%w[created_by_id].each do |local_user_id|
|
||||
next if !self[ local_user_id ]
|
||||
next if data[ app_model_user ] && data[ app_model_user ][ self[ local_user_id ] ]
|
||||
|
||||
user = User.lookup(id: self[ local_user_id ])
|
||||
next if !user
|
||||
|
||||
data = user.assets(data)
|
||||
end
|
||||
data
|
||||
|
|
|
@ -32,12 +32,15 @@ returns
|
|||
end
|
||||
|
||||
return data if !self['created_by_id'] && !self['updated_by_id']
|
||||
|
||||
app_model_user = User.to_app_model
|
||||
%w[created_by_id updated_by_id].each do |local_user_id|
|
||||
next if !self[ local_user_id ]
|
||||
next if data[ app_model_user ] && data[ app_model_user ][ self[ local_user_id ] ]
|
||||
|
||||
user = User.lookup(id: self[ local_user_id ])
|
||||
next if !user
|
||||
|
||||
data = user.assets(data)
|
||||
end
|
||||
data
|
||||
|
@ -60,10 +63,12 @@ get assets and record_ids of selector
|
|||
send(selector).each do |item, content|
|
||||
attribute = item.split(/\./)
|
||||
next if !attribute[1]
|
||||
|
||||
begin
|
||||
attribute_class = attribute[0].to_classname.constantize
|
||||
rescue => e
|
||||
next if attribute[0] == 'article'
|
||||
|
||||
logger.error "Unable to get asset for '#{attribute[0]}': #{e.inspect}"
|
||||
next
|
||||
end
|
||||
|
@ -73,12 +78,15 @@ get assets and record_ids of selector
|
|||
next if !models[attribute_class][:reflections]
|
||||
next if !models[attribute_class][:reflections][reflection]
|
||||
next if !models[attribute_class][:reflections][reflection].klass
|
||||
|
||||
attribute_ref_class = models[attribute_class][:reflections][reflection].klass
|
||||
if content['value'].instance_of?(Array)
|
||||
content['value'].each do |item_id|
|
||||
next if item_id.blank?
|
||||
|
||||
attribute_object = attribute_ref_class.lookup(id: item_id)
|
||||
next if !attribute_object
|
||||
|
||||
assets = attribute_object.assets(assets)
|
||||
end
|
||||
elsif content['value'].present?
|
||||
|
|
|
@ -23,8 +23,10 @@ returns
|
|||
group_ids: :group_ids_access_map=
|
||||
}.each do |param, setter|
|
||||
next if !params.key?(param)
|
||||
|
||||
map = params[param]
|
||||
next if !respond_to?(setter)
|
||||
|
||||
send(setter, map)
|
||||
end
|
||||
|
||||
|
@ -32,9 +34,11 @@ returns
|
|||
self.class.reflect_on_all_associations.map do |assoc|
|
||||
assoc_name = assoc.name
|
||||
next if association_attributes_ignored.include?(assoc_name)
|
||||
|
||||
real_ids = assoc_name[0, assoc_name.length - 1] + '_ids'
|
||||
real_ids = real_ids.to_sym
|
||||
next if !params.key?(real_ids)
|
||||
|
||||
list_of_items = params[real_ids]
|
||||
if !params[real_ids].instance_of?(Array)
|
||||
list_of_items = [ params[real_ids] ]
|
||||
|
@ -42,12 +46,14 @@ returns
|
|||
list = []
|
||||
list_of_items.each do |item_id|
|
||||
next if !item_id
|
||||
|
||||
lookup = assoc.klass.lookup(id: item_id)
|
||||
|
||||
# complain if we found no reference
|
||||
if !lookup
|
||||
raise ArgumentError, "No value found for '#{assoc_name}' with id #{item_id.inspect}"
|
||||
end
|
||||
|
||||
list.push item_id
|
||||
end
|
||||
send("#{real_ids}=", list)
|
||||
|
@ -57,16 +63,20 @@ returns
|
|||
self.class.reflect_on_all_associations.map do |assoc|
|
||||
assoc_name = assoc.name
|
||||
next if association_attributes_ignored.include?(assoc_name)
|
||||
|
||||
real_ids = assoc_name[0, assoc_name.length - 1] + '_ids'
|
||||
next if !respond_to?(real_ids)
|
||||
|
||||
real_values = assoc_name[0, assoc_name.length - 1] + 's'
|
||||
real_values = real_values.to_sym
|
||||
next if !respond_to?(real_values)
|
||||
next if !params[real_values]
|
||||
|
||||
if params[real_values].instance_of?(String) || params[real_values].instance_of?(Integer) || params[real_values].instance_of?(Float)
|
||||
params[real_values] = [params[real_values]]
|
||||
end
|
||||
next if !params[real_values].instance_of?(Array)
|
||||
|
||||
list = []
|
||||
class_object = assoc.klass
|
||||
params[real_values].each do |value|
|
||||
|
@ -86,6 +96,7 @@ returns
|
|||
if !lookup
|
||||
raise ArgumentError, "No lookup value found for '#{assoc_name}': #{value.inspect}"
|
||||
end
|
||||
|
||||
list.push lookup.id
|
||||
end
|
||||
send("#{real_ids}=", list)
|
||||
|
@ -171,8 +182,10 @@ returns
|
|||
self.class.reflect_on_all_associations.map do |assoc|
|
||||
next if !respond_to?(assoc.name)
|
||||
next if association_attributes_ignored.include?(assoc.name)
|
||||
|
||||
ref = send(assoc.name)
|
||||
next if !ref
|
||||
|
||||
if ref.respond_to?(:first)
|
||||
attributes[assoc.name.to_s] = []
|
||||
ref.each do |item|
|
||||
|
@ -181,6 +194,7 @@ returns
|
|||
next
|
||||
end
|
||||
next if !item[:name]
|
||||
|
||||
attributes[assoc.name.to_s].push item[:name]
|
||||
end
|
||||
if ref.count.positive? && attributes[assoc.name.to_s].blank?
|
||||
|
@ -193,6 +207,7 @@ returns
|
|||
next
|
||||
end
|
||||
next if !ref[:name]
|
||||
|
||||
attributes[assoc.name.to_s] = ref[:name]
|
||||
end
|
||||
|
||||
|
@ -207,8 +222,10 @@ returns
|
|||
'updated_by_id' => 'updated_by',
|
||||
}.each do |source, destination|
|
||||
next if !attributes[source]
|
||||
|
||||
user = User.lookup(id: attributes[source])
|
||||
next if !user
|
||||
|
||||
attributes[destination] = user.login
|
||||
end
|
||||
|
||||
|
@ -245,14 +262,18 @@ returns
|
|||
|
||||
# check if id is assigned
|
||||
next if !key.end_with?('_id')
|
||||
|
||||
key_short = key.chomp('_id')
|
||||
|
||||
self.class.reflect_on_all_associations.map do |assoc|
|
||||
next if assoc.name.to_s != key_short
|
||||
|
||||
item = assoc.class_name.constantize
|
||||
return false if !item.respond_to?(:find_by)
|
||||
|
||||
ref_object = item.find_by(id: value)
|
||||
return false if !ref_object
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
@ -332,6 +353,7 @@ returns
|
|||
assoc_name = assoc.name
|
||||
value = data[assoc_name]
|
||||
next if !value # next if we do not have a value
|
||||
|
||||
ref_name = "#{assoc_name}_id"
|
||||
|
||||
# handle _id values
|
||||
|
@ -345,6 +367,7 @@ returns
|
|||
if !value.instance_of?(String)
|
||||
raise ArgumentError, "String is needed as ref value #{value.inspect} for '#{assoc_name}'"
|
||||
end
|
||||
|
||||
if !lookup
|
||||
lookup = class_object.lookup(login: value)
|
||||
end
|
||||
|
@ -374,6 +397,7 @@ returns
|
|||
|
||||
# handle _ids values
|
||||
next if !assoc_name.to_s.end_with?('s')
|
||||
|
||||
ref_names = "#{assoc_name.to_s.chomp('s')}_ids"
|
||||
generic_object_tmp = new
|
||||
next if !generic_object_tmp.respond_to?(ref_names) # if we do have an _ids attribute
|
||||
|
@ -388,6 +412,7 @@ returns
|
|||
if !item.instance_of?(String)
|
||||
raise ArgumentError, "String is needed in array ref as ref value #{value.inspect} for '#{assoc_name}'"
|
||||
end
|
||||
|
||||
if !lookup
|
||||
lookup = class_object.lookup(login: item)
|
||||
end
|
||||
|
@ -402,6 +427,7 @@ returns
|
|||
if !lookup
|
||||
raise ArgumentError, "No lookup value found for '#{assoc_name}': #{item.inspect}"
|
||||
end
|
||||
|
||||
lookup_ids.push lookup.id
|
||||
end
|
||||
|
||||
|
|
|
@ -50,10 +50,12 @@ returns
|
|||
reflect_on_all_associations.map do |assoc|
|
||||
class_name = assoc.options[:class_name]
|
||||
next if !class_name
|
||||
|
||||
name = "#{assoc.name}_id"
|
||||
next if !data.key?(name)
|
||||
next if data[name].blank?
|
||||
next if assoc.klass.lookup(id: data[name])
|
||||
|
||||
raise ArgumentError, "Invalid value for param '#{name}': #{data[name].inspect}"
|
||||
end
|
||||
clean_params[attribute] = data[attribute]
|
||||
|
@ -105,6 +107,7 @@ merge preferences param
|
|||
def param_preferences_merge(new_params)
|
||||
return new_params if new_params.blank?
|
||||
return new_params if preferences.blank?
|
||||
|
||||
new_params[:preferences] = preferences.merge(new_params[:preferences] || {})
|
||||
new_params
|
||||
end
|
||||
|
|
|
@ -27,6 +27,7 @@ returns
|
|||
updated_at = order(updated_at: :desc, id: :desc).limit(1).pluck(:updated_at).first
|
||||
|
||||
return if !updated_at
|
||||
|
||||
latest_change_set(updated_at)
|
||||
updated_at
|
||||
end
|
||||
|
|
|
@ -25,6 +25,7 @@ returns
|
|||
attribute_name_with_id = key.to_s
|
||||
attribute_name = key.to_s
|
||||
next if attribute_name[-3, 3] != '_id'
|
||||
|
||||
attribute_name = attribute_name[ 0, attribute_name.length - 3 ]
|
||||
|
||||
# check if attribute method exists
|
||||
|
|
|
@ -21,6 +21,7 @@ touch references by params
|
|||
object_class = Kernel.const_get(data[:object])
|
||||
object = object_class.lookup(id: data[:o_id])
|
||||
return if !object
|
||||
|
||||
object.touch # rubocop:disable Rails/SkipsModelValidations
|
||||
rescue => e
|
||||
logger.error e
|
||||
|
|
|
@ -19,6 +19,7 @@ module ApplicationModel::ChecksAttributeValuesAndLength
|
|||
columns = self.class.columns_hash
|
||||
attributes.each do |name, value|
|
||||
next if !value.instance_of?(String)
|
||||
|
||||
column = columns[name]
|
||||
next if !column
|
||||
|
||||
|
@ -52,6 +53,7 @@ module ApplicationModel::ChecksAttributeValuesAndLength
|
|||
|
||||
# strip 4 bytes utf8 chars if needed (mysql/mariadb will complain it)
|
||||
next if self[name].blank?
|
||||
|
||||
self[name] = self[name].utf8_to_3bytesutf8
|
||||
end
|
||||
true
|
||||
|
|
|
@ -14,6 +14,7 @@ module ApplicationModel::ChecksImport
|
|||
return if !Setting.get('system_init_done')
|
||||
return if Setting.get('import_mode') && import_class_list.include?(self.class.to_s)
|
||||
return if !has_attribute?(:id)
|
||||
|
||||
self[:id] = nil
|
||||
true
|
||||
end
|
||||
|
|
|
@ -96,6 +96,7 @@ class Authorization < ApplicationModel
|
|||
|
||||
def delete_user_cache
|
||||
return if !user
|
||||
|
||||
user.touch # rubocop:disable Rails/SkipsModelValidations
|
||||
end
|
||||
|
||||
|
|
|
@ -179,6 +179,7 @@ add avatar by url
|
|||
# fetch image
|
||||
image = Service::Image.user(url)
|
||||
return if !image
|
||||
|
||||
data[:resize] = image
|
||||
data[:full] = image
|
||||
end
|
||||
|
@ -358,6 +359,7 @@ returns:
|
|||
store_hash: hash,
|
||||
)
|
||||
return if !avatar
|
||||
|
||||
Store.find(avatar.store_resize_id)
|
||||
end
|
||||
|
||||
|
@ -389,6 +391,7 @@ returns:
|
|||
).order('created_at ASC, id DESC')
|
||||
avatars.each do |avatar|
|
||||
next if avatar.id == avatar_id
|
||||
|
||||
avatar.default = false
|
||||
avatar.save!
|
||||
end
|
||||
|
|
|
@ -33,6 +33,7 @@ returns calendar object
|
|||
# prevent multible setups for same ip
|
||||
cache = Cache.get('Calendar.init_setup.done')
|
||||
return if cache && cache[:ip] == ip
|
||||
|
||||
Cache.write('Calendar.init_setup.done', { ip: ip }, { expires_in: 1.hour })
|
||||
|
||||
# call for calendar suggestion
|
||||
|
@ -171,6 +172,7 @@ returns
|
|||
public_holidays.each do |day, meta|
|
||||
next if !public_holidays[day]['feed']
|
||||
next if meta['feed'] == Digest::MD5.hexdigest(ical_url)
|
||||
|
||||
public_holidays.delete(day)
|
||||
end
|
||||
|
||||
|
@ -215,6 +217,7 @@ returns
|
|||
if !result.success?
|
||||
raise result.error
|
||||
end
|
||||
|
||||
cal_file = result.body
|
||||
else
|
||||
cal_file = File.open(location)
|
||||
|
@ -234,14 +237,17 @@ returns
|
|||
occurrences.each do |occurrence|
|
||||
result = Calendar.day_and_comment_by_event(event, occurrence.start_time)
|
||||
next if !result
|
||||
|
||||
events[result[0]] = result[1]
|
||||
end
|
||||
end
|
||||
end
|
||||
next if event.dtstart < Time.zone.now - 1.year
|
||||
next if event.dtstart > Time.zone.now + 3.years
|
||||
|
||||
result = Calendar.day_and_comment_by_event(event, event.dtstart)
|
||||
next if !result
|
||||
|
||||
events[result[0]] = result[1]
|
||||
end
|
||||
events.sort.to_h
|
||||
|
@ -255,6 +261,7 @@ returns
|
|||
|
||||
# ignore daylight saving time entries
|
||||
return if comment.match?(/(daylight saving|sommerzeit|summertime)/i)
|
||||
|
||||
[day, comment]
|
||||
end
|
||||
|
||||
|
@ -263,9 +270,11 @@ returns
|
|||
# if changed calendar is default, set all others default to false
|
||||
def sync_default
|
||||
return true if !default
|
||||
|
||||
Calendar.find_each do |calendar|
|
||||
next if calendar.id == id
|
||||
next if !calendar.default
|
||||
|
||||
calendar.default = false
|
||||
calendar.save
|
||||
end
|
||||
|
@ -277,6 +286,7 @@ returns
|
|||
if !Calendar.find_by(default: true)
|
||||
first = Calendar.order(:created_at, :id).limit(1).first
|
||||
return true if !first
|
||||
|
||||
first.default = true
|
||||
first.save
|
||||
end
|
||||
|
|
|
@ -58,6 +58,7 @@ fetch one account
|
|||
driver_class = Object.const_get("Channel::Driver::#{adapter.to_classname}")
|
||||
driver_instance = driver_class.new
|
||||
return if !force && !driver_instance.fetchable?(self)
|
||||
|
||||
result = driver_instance.fetch(adapter_options, self)
|
||||
self.status_in = result[:result]
|
||||
self.last_log_in = result[:notice]
|
||||
|
@ -103,6 +104,7 @@ stream instance of account
|
|||
|
||||
# check is stream exists
|
||||
return if !driver_instance.respond_to?(:stream_instance)
|
||||
|
||||
driver_instance.stream_instance(self)
|
||||
|
||||
# set scheduler job to active
|
||||
|
@ -142,9 +144,11 @@ stream all accounts
|
|||
channels.each do |channel|
|
||||
adapter = channel.options[:adapter]
|
||||
next if adapter.blank?
|
||||
|
||||
driver_class = Object.const_get("Channel::Driver::#{adapter.to_classname}")
|
||||
next if !driver_class.respond_to?(:streamable?)
|
||||
next if !driver_class.streamable?
|
||||
|
||||
channel_id = channel.id.to_s
|
||||
|
||||
current_channels.push channel_id
|
||||
|
@ -225,6 +229,7 @@ stream all accounts
|
|||
last_channels.each do |channel_id|
|
||||
next if @@channel_stream[channel_id].blank?
|
||||
next if current_channels.include?(channel_id)
|
||||
|
||||
logger.info "channel (#{channel_id}) not longer active, stop stream thread"
|
||||
@@channel_stream[channel_id][:thread].exit
|
||||
@@channel_stream[channel_id][:thread].join
|
||||
|
|
|
@ -52,11 +52,14 @@ returns
|
|||
end
|
||||
|
||||
return data if !self['created_by_id'] && !self['updated_by_id']
|
||||
|
||||
%w[created_by_id updated_by_id].each do |local_user_id|
|
||||
next if !self[ local_user_id ]
|
||||
next if data[ User.to_app_model ] && data[ User.to_app_model ][ self[ local_user_id ] ]
|
||||
|
||||
user = User.lookup(id: self[ local_user_id ])
|
||||
next if !user
|
||||
|
||||
data = user.assets(data)
|
||||
end
|
||||
data
|
||||
|
|
|
@ -30,11 +30,13 @@ class Channel::Driver::Facebook
|
|||
access_token = nil
|
||||
options['pages'].each do |page|
|
||||
next if page['id'].to_s != fb_object_id.to_s
|
||||
|
||||
access_token = page['access_token']
|
||||
end
|
||||
if !access_token
|
||||
raise "No access_token found for fb_object_id: #{fb_object_id}"
|
||||
end
|
||||
|
||||
client = ::Facebook.new(access_token)
|
||||
client.from_article(article)
|
||||
end
|
||||
|
@ -54,6 +56,7 @@ class Channel::Driver::Facebook
|
|||
return true if !channel.preferences
|
||||
return true if !channel.preferences[:last_fetch]
|
||||
return false if channel.preferences[:last_fetch] > Time.zone.now - 5.minutes
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
|
@ -93,6 +96,7 @@ returns
|
|||
page = get_page(page_to_sync_id)
|
||||
next if !page
|
||||
next if page_to_sync_params['group_id'].blank?
|
||||
|
||||
page_client = ::Facebook.new(page['access_token'])
|
||||
|
||||
posts = page_client.client.get_connection('me', 'feed', fields: 'id,from,to,message,created_time,permalink_url,comments{id,from,to,message,created_time}')
|
||||
|
|
|
@ -164,6 +164,7 @@ example
|
|||
subject = message_meta['ENVELOPE'].subject
|
||||
next if !subject
|
||||
next if subject !~ /#{verify_string}/
|
||||
|
||||
Rails.logger.info " - verify email #{verify_string} found"
|
||||
@imap.store(message_id, '+FLAGS', [:Deleted])
|
||||
@imap.expunge()
|
||||
|
@ -206,6 +207,7 @@ example
|
|||
# delete email from server after article was created
|
||||
msg = @imap.fetch(message_id, 'RFC822')[0].attr['RFC822']
|
||||
next if !msg
|
||||
|
||||
process(channel, msg, false)
|
||||
if !keep_on_server
|
||||
@imap.store(message_id, '+FLAGS', [:Deleted])
|
||||
|
@ -231,6 +233,7 @@ example
|
|||
|
||||
def disconnect
|
||||
return if !@imap
|
||||
|
||||
@imap.disconnect()
|
||||
end
|
||||
|
||||
|
@ -256,8 +259,10 @@ returns
|
|||
return false if !keep_on_server
|
||||
return false if !message_meta.attr
|
||||
return false if !message_meta.attr['ENVELOPE']
|
||||
|
||||
local_message_id = message_meta.attr['ENVELOPE'].message_id
|
||||
return false if local_message_id.blank?
|
||||
|
||||
local_message_id_md5 = Digest::MD5.hexdigest(local_message_id)
|
||||
article = Ticket::Article.where(message_id_md5: local_message_id_md5).order('created_at DESC, id DESC').limit(1).first
|
||||
return false if !article
|
||||
|
@ -275,6 +280,7 @@ returns
|
|||
|
||||
def deleted?(message_meta, count, count_all)
|
||||
return false if !message_meta.attr['FLAGS'].include?(:Deleted)
|
||||
|
||||
Rails.logger.info " - ignore message #{count}/#{count_all} - because message has already delete flag"
|
||||
true
|
||||
end
|
||||
|
|
|
@ -118,6 +118,7 @@ returns
|
|||
|
||||
# check if verify message exists
|
||||
next if mail !~ /#{verify_string}/
|
||||
|
||||
Rails.logger.info " - verify email #{verify_string} found"
|
||||
m.delete
|
||||
disconnect
|
||||
|
@ -196,6 +197,7 @@ returns
|
|||
|
||||
def disconnect
|
||||
return if !@pop
|
||||
|
||||
@pop.finish
|
||||
end
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ class Channel::Driver::Sendmail
|
|||
|
||||
def delivery_method
|
||||
return :test if Rails.env.test?
|
||||
|
||||
:sendmail
|
||||
end
|
||||
end
|
||||
|
|
|
@ -50,6 +50,7 @@ returns
|
|||
if options[:auth] && options[:auth][:external_credential_id]
|
||||
external_credential = ExternalCredential.find_by(id: options[:auth][:external_credential_id])
|
||||
raise "No such ExternalCredential.find(#{options[:auth][:external_credential_id]})" if !external_credential
|
||||
|
||||
options[:auth][:api_key] = external_credential.credentials['api_key']
|
||||
end
|
||||
options
|
||||
|
|
|
@ -83,6 +83,7 @@ returns
|
|||
return true if !channel.preferences
|
||||
return true if !channel.preferences[:last_fetch]
|
||||
return false if channel.preferences[:last_fetch] > Time.zone.now - 20.minutes
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
|
@ -206,6 +207,7 @@ returns
|
|||
if loop_count >= 2
|
||||
raise "Unable to stream, try #{loop_count}, error #{e.inspect}"
|
||||
end
|
||||
|
||||
Rails.logger.info "wait for #{sleep_on_unauthorized} sec. and try it again"
|
||||
sleep sleep_on_unauthorized
|
||||
end
|
||||
|
@ -224,6 +226,7 @@ returns
|
|||
next if item['term'].blank?
|
||||
next if item['term'] == '#'
|
||||
next if item['group_id'].blank?
|
||||
|
||||
hashtags.push item['term']
|
||||
end
|
||||
filter[:track] = hashtags.join(',')
|
||||
|
@ -246,6 +249,7 @@ returns
|
|||
if tweet.class == Twitter::DirectMessage
|
||||
if sync['direct_messages'] && sync['direct_messages']['group_id'] != ''
|
||||
next if @stream_client.direct_message_limit_reached(tweet, 2)
|
||||
|
||||
@stream_client.to_group(tweet, sync['direct_messages']['group_id'], @channel)
|
||||
end
|
||||
next
|
||||
|
@ -275,8 +279,10 @@ returns
|
|||
next if item['term'].blank?
|
||||
next if item['term'] == '#'
|
||||
next if item['group_id'].blank?
|
||||
|
||||
tweet.hashtags.each do |hashtag|
|
||||
next if item['term'] !~ /^#/
|
||||
|
||||
if item['term'].sub(/^#/, '') == hashtag.text
|
||||
hit = item
|
||||
end
|
||||
|
@ -296,6 +302,7 @@ returns
|
|||
next if item['term'].blank?
|
||||
next if item['term'] == '#'
|
||||
next if item['group_id'].blank?
|
||||
|
||||
if body.match?(/#{item['term']}/)
|
||||
hit = item
|
||||
end
|
||||
|
@ -312,10 +319,12 @@ returns
|
|||
|
||||
def fetch_search
|
||||
return if @sync[:search].blank?
|
||||
|
||||
@sync[:search].each do |search|
|
||||
next if search[:term].blank?
|
||||
next if search[:term] == '#'
|
||||
next if search[:group_id].blank?
|
||||
|
||||
result_type = search[:type] || 'mixed'
|
||||
Rails.logger.debug { " - searching for '#{search[:term]}'" }
|
||||
older_import = 0
|
||||
|
@ -333,6 +342,7 @@ returns
|
|||
next if @rest_client.locale_sender?(tweet) && own_tweet_already_imported?(tweet)
|
||||
next if Ticket::Article.find_by(message_id: tweet.id)
|
||||
break if @rest_client.tweet_limit_reached(tweet)
|
||||
|
||||
@rest_client.to_group(tweet, search[:group_id], @channel)
|
||||
end
|
||||
end
|
||||
|
@ -341,6 +351,7 @@ returns
|
|||
def fetch_mentions
|
||||
return if @sync[:mentions].blank?
|
||||
return if @sync[:mentions][:group_id].blank?
|
||||
|
||||
Rails.logger.debug { ' - searching for mentions' }
|
||||
older_import = 0
|
||||
older_import_max = 20
|
||||
|
@ -355,6 +366,7 @@ returns
|
|||
end
|
||||
next if Ticket::Article.find_by(message_id: tweet.id)
|
||||
break if @rest_client.tweet_limit_reached(tweet)
|
||||
|
||||
@rest_client.to_group(tweet, @sync[:mentions][:group_id], @channel)
|
||||
end
|
||||
end
|
||||
|
@ -362,6 +374,7 @@ returns
|
|||
def fetch_direct_messages
|
||||
return if @sync[:direct_messages].blank?
|
||||
return if @sync[:direct_messages][:group_id].blank?
|
||||
|
||||
Rails.logger.debug { ' - searching for direct_messages' }
|
||||
older_import = 0
|
||||
older_import_max = 20
|
||||
|
@ -375,6 +388,7 @@ returns
|
|||
end
|
||||
next if Ticket::Article.find_by(message_id: tweet.id)
|
||||
break if @rest_client.direct_message_limit_reached(tweet)
|
||||
|
||||
@rest_client.to_group(tweet, @sync[:direct_messages][:group_id], @channel)
|
||||
end
|
||||
end
|
||||
|
@ -383,6 +397,7 @@ returns
|
|||
if options[:auth] && options[:auth][:external_credential_id]
|
||||
external_credential = ExternalCredential.find_by(id: options[:auth][:external_credential_id])
|
||||
raise "No such ExternalCredential.find(#{options[:auth][:external_credential_id]})" if !external_credential
|
||||
|
||||
options[:auth][:consumer_key] = external_credential.credentials['consumer_key']
|
||||
options[:auth][:consumer_secret] = external_credential.credentials['consumer_secret']
|
||||
end
|
||||
|
@ -403,6 +418,7 @@ returns
|
|||
end
|
||||
count = Delayed::Job.where('created_at < ?', event_time).count
|
||||
break if count.zero?
|
||||
|
||||
sleep_time = 2 * count
|
||||
sleep_time = 5 if sleep_time > 5
|
||||
Rails.logger.debug { "Delay importing own tweets - sleep #{sleep_time} (loop #{loop_count})" }
|
||||
|
|
|
@ -37,6 +37,7 @@ module Channel::EmailBuild
|
|||
next if key.to_s == 'attachments'
|
||||
next if key.to_s == 'body'
|
||||
next if key.to_s == 'content_type'
|
||||
|
||||
mail[key.to_s] = if value && value.class != Array
|
||||
value.to_s
|
||||
else
|
||||
|
@ -84,6 +85,7 @@ module Channel::EmailBuild
|
|||
attr[:attachments]&.each do |attachment|
|
||||
next if attachment.class == Hash
|
||||
next if attachment.preferences['Content-ID'].blank?
|
||||
|
||||
attachment = Mail::Part.new do
|
||||
content_type attachment.preferences['Content-Type']
|
||||
content_id "<#{attachment.preferences['Content-ID']}>"
|
||||
|
@ -105,6 +107,7 @@ module Channel::EmailBuild
|
|||
mail.attachments[attachment[:filename]] = attachment
|
||||
else
|
||||
next if attachment.preferences['Content-ID'].present?
|
||||
|
||||
filename = attachment.filename
|
||||
encoded_filename = Mail::Encodings.decode_encode filename, :encode
|
||||
disposition = attachment.preferences['Content-Disposition'] || 'attachment'
|
||||
|
@ -131,6 +134,7 @@ returns
|
|||
|
||||
def self.recipient_line(realname, email)
|
||||
return "#{realname} <#{email}>" if realname.match?(/^[A-z]+$/i)
|
||||
|
||||
"\"#{realname.gsub('"', '\"')}\" <#{email}>"
|
||||
end
|
||||
|
||||
|
|
|
@ -121,6 +121,7 @@ returns
|
|||
file.write msg
|
||||
end
|
||||
return false if exception == false
|
||||
|
||||
raise e.inspect + "\n" + e.backtrace.join("\n")
|
||||
end
|
||||
|
||||
|
@ -169,6 +170,7 @@ returns
|
|||
if !session_user_id
|
||||
raise 'No x-zammad-session-user-id, no sender set!'
|
||||
end
|
||||
|
||||
session_user = User.lookup(id: session_user_id)
|
||||
if !session_user
|
||||
raise "No user found for x-zammad-session-user-id: #{session_user_id}!"
|
||||
|
@ -320,23 +322,28 @@ returns
|
|||
attribute = nil
|
||||
# skip check attributes if it is tags
|
||||
return true if header_name == 'x-zammad-ticket-tags'
|
||||
|
||||
if header_name =~ /^x-zammad-(.+?)-(followup-|)(.*)$/i
|
||||
class_name = $1
|
||||
attribute = $3
|
||||
end
|
||||
return true if !class_name
|
||||
|
||||
if class_name.downcase == 'article'
|
||||
class_name = 'Ticket::Article'
|
||||
end
|
||||
return true if !attribute
|
||||
|
||||
key_short = attribute[ attribute.length - 3, attribute.length ]
|
||||
return true if key_short != '_id'
|
||||
|
||||
class_object = Object.const_get(class_name.to_classname)
|
||||
return if !class_object
|
||||
|
||||
class_instance = class_object.new
|
||||
|
||||
return false if !class_instance.association_id_validation(attribute, value)
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
|
@ -467,6 +474,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
|
|||
Dir.glob("#{path}/*.eml") do |entry|
|
||||
ticket, article, user, mail = Channel::EmailParser.new.process(params, IO.binread(entry))
|
||||
next if ticket.blank?
|
||||
|
||||
files.push entry
|
||||
File.delete(entry)
|
||||
end
|
||||
|
@ -535,6 +543,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
|
|||
body_text = Mail::Utilities.to_lf(body_text)
|
||||
|
||||
return body_text.html2html_strict if options[:strict_html]
|
||||
|
||||
body_text
|
||||
end
|
||||
|
||||
|
@ -567,6 +576,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
|
|||
attachments.push(*new_attachments)
|
||||
rescue => e # Protect process to work with spam emails (see test/fixtures/mail15.box)
|
||||
raise e if (fail_count ||= 0).positive?
|
||||
|
||||
(fail_count += 1) && retry
|
||||
end
|
||||
end
|
||||
|
@ -694,6 +704,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
|
|||
}
|
||||
map.each do |type, ext|
|
||||
next if headers_store['Content-Type'] !~ /^#{Regexp.quote(type)}/i
|
||||
|
||||
filename = if headers_store['Content-Description'].present?
|
||||
"#{headers_store['Content-Description']}.#{ext[0]}".to_s.force_encoding('utf-8')
|
||||
else
|
||||
|
@ -723,6 +734,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
|
|||
end
|
||||
end
|
||||
break if filename_exists == false
|
||||
|
||||
filename = if local_extention.present?
|
||||
"#{local_filename}#{i}.#{local_extention}"
|
||||
else
|
||||
|
@ -769,6 +781,7 @@ module Mail
|
|||
value = @raw_value.utf8_encode(fallback: :read_as_sanitized_binary)
|
||||
end
|
||||
return value if value.blank?
|
||||
|
||||
value.sub(/^.+?:(\s|)/, '')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,6 +16,7 @@ module Channel::Filter::BounceDeliveryPermanentFailed
|
|||
|
||||
result = Channel::EmailParser.new.parse(attachment[:data])
|
||||
next if !result[:message_id]
|
||||
|
||||
message_id_md5 = Digest::MD5.hexdigest(result[:message_id])
|
||||
article = Ticket::Article.where(message_id_md5: message_id_md5).order('created_at DESC, id DESC').limit(1).first
|
||||
next if !article
|
||||
|
@ -30,11 +31,13 @@ module Channel::Filter::BounceDeliveryPermanentFailed
|
|||
if article.sender.name == 'System' || article.sender.name == 'Agent'
|
||||
%w[to cc].each do |line|
|
||||
next if article[line].blank?
|
||||
|
||||
recipients = []
|
||||
begin
|
||||
list = Mail::AddressList.new(article[line])
|
||||
list.addresses.each do |address|
|
||||
next if address.address.blank?
|
||||
|
||||
recipients.push address.address.downcase
|
||||
end
|
||||
rescue
|
||||
|
@ -60,6 +63,7 @@ module Channel::Filter::BounceDeliveryPermanentFailed
|
|||
users = User.where(email: recipient)
|
||||
users.each do |user|
|
||||
next if !user
|
||||
|
||||
user.preferences[:mail_delivery_failed] = true
|
||||
user.preferences[:mail_delivery_failed_data] = Time.zone.now
|
||||
user.save!
|
||||
|
|
|
@ -16,6 +16,7 @@ module Channel::Filter::BounceFollowUpCheck
|
|||
|
||||
result = Channel::EmailParser.new.parse(attachment[:data])
|
||||
next if !result[:message_id]
|
||||
|
||||
message_id_md5 = Digest::MD5.hexdigest(result[:message_id])
|
||||
article = Ticket::Article.where(message_id_md5: message_id_md5).order('created_at DESC, id DESC').limit(1).first
|
||||
next if !article
|
||||
|
|
|
@ -14,6 +14,7 @@ module Channel::Filter::Database
|
|||
filter[:match].each do |key, meta|
|
||||
begin
|
||||
next if meta.blank? || meta['value'].blank?
|
||||
|
||||
value = mail[ key.downcase.to_sym ]
|
||||
match_rule = meta['value']
|
||||
min_one_rule_exists = true
|
||||
|
@ -44,6 +45,7 @@ module Channel::Filter::Database
|
|||
|
||||
filter[:perform].each do |key, meta|
|
||||
next if !Channel::EmailParser.check_attributes_by_x_headers(key, meta['value'])
|
||||
|
||||
Rails.logger.info " perform '#{key.downcase}' = '#{meta.inspect}'"
|
||||
|
||||
if key.downcase == 'x-zammad-ticket-tags' && meta['value'].present? && meta['operator'].present?
|
||||
|
@ -54,13 +56,16 @@ module Channel::Filter::Database
|
|||
when 'add'
|
||||
tags.each do |tag|
|
||||
next if tag.blank?
|
||||
|
||||
tag.strip!
|
||||
next if mail[ 'x-zammad-ticket-tags'.downcase.to_sym ].include?(tag)
|
||||
|
||||
mail[ 'x-zammad-ticket-tags'.downcase.to_sym ].push tag
|
||||
end
|
||||
when 'remove'
|
||||
tags.each do |tag|
|
||||
next if tag.blank?
|
||||
|
||||
tag.strip!
|
||||
mail[ 'x-zammad-ticket-tags'.downcase.to_sym ] -= [tag]
|
||||
end
|
||||
|
|
|
@ -30,8 +30,10 @@ module Channel::Filter::FollowUpCheck
|
|||
if setting.include?('attachment') && mail[:attachments]
|
||||
mail[:attachments].each do |attachment|
|
||||
next if !attachment[:data]
|
||||
|
||||
ticket = Ticket::Number.check(attachment[:data].html2text)
|
||||
next if !ticket
|
||||
|
||||
Rails.logger.debug { "Follow up for '##{ticket.number}' in attachment." }
|
||||
mail['x-zammad-ticket-id'.to_sym] = ticket.id
|
||||
return true
|
||||
|
@ -58,6 +60,7 @@ module Channel::Filter::FollowUpCheck
|
|||
message_id_md5 = Digest::MD5.hexdigest(message_id)
|
||||
article = Ticket::Article.where(message_id_md5: message_id_md5).order('created_at DESC, id DESC').limit(1).first
|
||||
next if !article
|
||||
|
||||
Rails.logger.debug { "Follow up for '##{article.ticket.number}' in references." }
|
||||
mail['x-zammad-ticket-id'.to_sym] = article.ticket_id
|
||||
return true
|
||||
|
@ -85,8 +88,10 @@ module Channel::Filter::FollowUpCheck
|
|||
message_id_md5 = Digest::MD5.hexdigest(message_id)
|
||||
article = Ticket::Article.where(message_id_md5: message_id_md5).order('created_at DESC, id DESC').limit(1).first
|
||||
next if !article
|
||||
|
||||
ticket = article.ticket
|
||||
next if !ticket
|
||||
|
||||
article_first = ticket.articles.first
|
||||
next if !article_first
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ module Channel::Filter::FollowUpPossibleCheck
|
|||
def self.run(_channel, mail)
|
||||
ticket_id = mail['x-zammad-ticket-id'.to_sym]
|
||||
return true if !ticket_id
|
||||
|
||||
ticket = Ticket.lookup(id: ticket_id)
|
||||
return true if !ticket
|
||||
return true if ticket.state.state_type.name !~ /^(closed|merged|removed)/i
|
||||
|
|
|
@ -96,14 +96,17 @@ module Channel::Filter::IdentifySender
|
|||
current_count = 0
|
||||
['raw-to', 'raw-cc'].each do |item|
|
||||
next if mail[item.to_sym].blank?
|
||||
|
||||
begin
|
||||
items = mail[item.to_sym].addrs
|
||||
next if items.blank?
|
||||
|
||||
items.each do |address_data|
|
||||
email_address = address_data.address
|
||||
next if email_address.blank?
|
||||
next if email_address !~ /@/
|
||||
next if email_address.match?(/\s/)
|
||||
|
||||
user_create(
|
||||
firstname: address_data.display_name,
|
||||
lastname: '',
|
||||
|
@ -131,6 +134,7 @@ module Channel::Filter::IdentifySender
|
|||
next if address.blank?
|
||||
next if address !~ /@/
|
||||
next if address.match?(/\s/)
|
||||
|
||||
user_create(
|
||||
firstname: display_name,
|
||||
lastname: '',
|
||||
|
|
|
@ -10,11 +10,13 @@ module Channel::Filter::Match::EmailRegex
|
|||
if regexp == false
|
||||
match_rule_quoted = Regexp.quote(match_rule).gsub(/\\\*/, '.*')
|
||||
return true if value.match?(/#{match_rule_quoted}/i)
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
begin
|
||||
return true if value.match?(/#{match_rule}/i)
|
||||
|
||||
return false
|
||||
rescue => e
|
||||
message = "Can't use regex '#{match_rule}' on '#{value}': #{e.message}"
|
||||
|
|
|
@ -14,6 +14,7 @@ class Channel::Filter::MonitoringBase
|
|||
def self.run(_channel, mail)
|
||||
integration = integration_name
|
||||
return if !Setting.get("#{integration}_integration")
|
||||
|
||||
sender = Setting.get("#{integration}_sender")
|
||||
auto_close = Setting.get("#{integration}_auto_close")
|
||||
auto_close_state_id = Setting.get("#{integration}_auto_close_state_id")
|
||||
|
@ -22,6 +23,7 @@ class Channel::Filter::MonitoringBase
|
|||
|
||||
return if mail[:from].blank?
|
||||
return if mail[:body].blank?
|
||||
|
||||
session_user_id = mail[ 'x-zammad-session-user-id'.to_sym ]
|
||||
return if !session_user_id
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ module Channel::Filter::OwnNotificationLoopDetection
|
|||
|
||||
message_id = mail['message-id'.to_sym]
|
||||
return if !message_id
|
||||
|
||||
recedence = mail['precedence'.to_sym]
|
||||
return if !recedence
|
||||
return if recedence !~ /bulk/i
|
||||
|
|
|
@ -16,9 +16,11 @@ module Channel::Filter::SenderIsSystemAddress
|
|||
# in case, set sender
|
||||
begin
|
||||
return if !mail[form].addrs
|
||||
|
||||
items = mail[form].addrs
|
||||
items.each do |item|
|
||||
next if !EmailAddress.find_by(email: item.address.downcase)
|
||||
|
||||
mail['x-zammad-ticket-create-article-sender'.to_sym] = 'Agent'
|
||||
mail['x-zammad-article-sender'.to_sym] = 'Agent'
|
||||
return true
|
||||
|
@ -29,10 +31,12 @@ module Channel::Filter::SenderIsSystemAddress
|
|||
|
||||
# check if sender is agent
|
||||
return if mail[:from_email].blank?
|
||||
|
||||
begin
|
||||
user = User.find_by(email: mail[:from_email].downcase)
|
||||
return if !user
|
||||
return if !user.permissions?('ticket.agent')
|
||||
|
||||
mail['x-zammad-ticket-create-article-sender'.to_sym] = 'Agent'
|
||||
mail['x-zammad-article-sender'.to_sym] = 'Agent'
|
||||
return true
|
||||
|
|
|
@ -9,6 +9,7 @@ module Channel::Filter::Trusted
|
|||
if !channel[:trusted]
|
||||
mail.each_key do |key|
|
||||
next if key !~ /^x-zammad/i
|
||||
|
||||
mail.delete(key)
|
||||
end
|
||||
return
|
||||
|
@ -20,6 +21,7 @@ module Channel::Filter::Trusted
|
|||
|
||||
# no assoc exists, remove header
|
||||
next if Channel::EmailParser.check_attributes_by_x_headers(key, value)
|
||||
|
||||
mail.delete(key.to_sym)
|
||||
end
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ class Chat < ApplicationModel
|
|||
|
||||
def self.agent_state(user_id)
|
||||
return { state: 'chat_disabled' } if !Setting.get('chat')
|
||||
|
||||
assets = {}
|
||||
Chat.where(active: true).each do |chat|
|
||||
assets = chat.assets(assets)
|
||||
|
@ -76,8 +77,10 @@ class Chat < ApplicationModel
|
|||
runningchat_session_list_local = running_chat_session_list
|
||||
runningchat_session_list_local.each do |session|
|
||||
next if !session['user_id']
|
||||
|
||||
user = User.lookup(id: session['user_id'])
|
||||
next if !user
|
||||
|
||||
assets = user.assets(assets)
|
||||
end
|
||||
{
|
||||
|
@ -96,6 +99,7 @@ class Chat < ApplicationModel
|
|||
|
||||
def self.agent_state_with_sessions(user_id)
|
||||
return { state: 'chat_disabled' } if !Setting.get('chat')
|
||||
|
||||
result = agent_state(user_id)
|
||||
result[:active_sessions] = Chat::Session.active_chats_by_user_id(user_id)
|
||||
result
|
||||
|
@ -146,6 +150,7 @@ class Chat < ApplicationModel
|
|||
Chat::Agent.where(active: true).where('updated_at > ?', Time.zone.now - diff).each do |record|
|
||||
user = User.lookup(id: record.updated_by_id)
|
||||
next if !user
|
||||
|
||||
users.push user
|
||||
end
|
||||
users
|
||||
|
@ -180,6 +185,7 @@ optional you can ignore it for dedecated user
|
|||
# send broadcast to agents
|
||||
Chat::Agent.where('active = ? OR updated_at > ?', true, Time.zone.now - 8.hours).each do |item|
|
||||
next if item.updated_by_id == ignore_user_id
|
||||
|
||||
data = {
|
||||
event: 'chat_status_agent',
|
||||
data: Chat.agent_state(item.updated_by_id),
|
||||
|
@ -250,6 +256,7 @@ optional you can put the max oldest chat sessions as argument
|
|||
def self.cleanup_close(diff = 5.minutes)
|
||||
Chat::Session.where.not(state: 'closed').where('updated_at < ?', Time.zone.now - diff).each do |chat_session|
|
||||
next if chat_session.recipients_active?
|
||||
|
||||
chat_session.state = 'closed'
|
||||
chat_session.save
|
||||
message = {
|
||||
|
@ -276,6 +283,7 @@ check if ip address is blocked for chat
|
|||
def blocked_ip?(ip)
|
||||
return false if ip.blank?
|
||||
return false if block_ip.blank?
|
||||
|
||||
ips = block_ip.split(';')
|
||||
ips.each do |local_ip|
|
||||
return true if ip == local_ip.strip
|
||||
|
@ -296,9 +304,11 @@ check if country is blocked for chat
|
|||
def blocked_country?(ip)
|
||||
return false if ip.blank?
|
||||
return false if block_country.blank?
|
||||
|
||||
geo_ip = Service::GeoIp.location(ip)
|
||||
return false if geo_ip.blank?
|
||||
return false if geo_ip['country_code'].blank?
|
||||
|
||||
countries = block_country.split(';')
|
||||
countries.each do |local_country|
|
||||
return true if geo_ip['country_code'] == local_country
|
||||
|
|
|
@ -14,6 +14,7 @@ class Chat::Agent < ApplicationModel
|
|||
)
|
||||
if state.nil?
|
||||
return false if !chat_agent
|
||||
|
||||
return chat_agent.active
|
||||
end
|
||||
if chat_agent
|
||||
|
|
|
@ -23,6 +23,7 @@ class Chat::Session < ApplicationModel
|
|||
preferences[:participants] = []
|
||||
end
|
||||
return preferences[:participants] if preferences[:participants].include?(client_id)
|
||||
|
||||
preferences[:participants].push client_id
|
||||
if store
|
||||
save
|
||||
|
@ -33,18 +34,22 @@ class Chat::Session < ApplicationModel
|
|||
def recipients_active?
|
||||
return true if !preferences
|
||||
return true if !preferences[:participants]
|
||||
|
||||
count = 0
|
||||
preferences[:participants].each do |client_id|
|
||||
next if !Sessions.session_exists?(client_id)
|
||||
|
||||
count += 1
|
||||
end
|
||||
return true if count >= 2
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
def send_to_recipients(message, ignore_client_id = nil)
|
||||
preferences[:participants].each do |local_client_id|
|
||||
next if local_client_id == ignore_client_id
|
||||
|
||||
Sessions.send(local_client_id, message)
|
||||
end
|
||||
true
|
||||
|
@ -52,6 +57,7 @@ class Chat::Session < ApplicationModel
|
|||
|
||||
def position
|
||||
return if state != 'waiting'
|
||||
|
||||
position = 0
|
||||
Chat::Session.where(state: 'waiting').order(created_at: :asc).each do |chat_session|
|
||||
position += 1
|
||||
|
@ -63,6 +69,7 @@ class Chat::Session < ApplicationModel
|
|||
def self.messages_by_session_id(session_id)
|
||||
chat_session = Chat::Session.find_by(session_id: session_id)
|
||||
return if !chat_session
|
||||
|
||||
session_attributes = []
|
||||
Chat::Message.where(chat_session_id: chat_session.id).order(created_at: :asc).each do |message|
|
||||
session_attributes.push message.attributes
|
||||
|
|
|
@ -48,8 +48,10 @@ returns
|
|||
%w[created_by_id updated_by_id].each do |local_user_id|
|
||||
next if !self[ local_user_id ]
|
||||
next if data[ app_model_user ] && data[ app_model_user ][ self[ local_user_id ] ]
|
||||
|
||||
user = User.lookup(id: self[ local_user_id ])
|
||||
next if !user
|
||||
|
||||
data = user.assets(data)
|
||||
end
|
||||
data
|
||||
|
|
|
@ -27,6 +27,7 @@ returns if user has no permissions to search
|
|||
|
||||
def search_preferences(current_user)
|
||||
return false if Setting.get('chat') != true || !current_user.permissions?('chat.agent')
|
||||
|
||||
{
|
||||
prio: 900,
|
||||
direct_search_index: true,
|
||||
|
@ -68,6 +69,7 @@ returns
|
|||
items.each do |item|
|
||||
chat_session = Chat::Session.lookup(id: item[:id])
|
||||
next if !chat_session
|
||||
|
||||
chat_sessions.push chat_session
|
||||
end
|
||||
return chat_sessions
|
||||
|
|
|
@ -70,6 +70,7 @@ returns
|
|||
|
||||
if data[:file].present?
|
||||
raise Exceptions::UnprocessableEntity, "No such file '#{data[:file]}'" if !File.exist?(data[:file])
|
||||
|
||||
begin
|
||||
file = File.open(data[:file], 'r:UTF-8')
|
||||
data[:string] = file.read
|
||||
|
@ -103,6 +104,7 @@ returns
|
|||
item.strip!
|
||||
end
|
||||
next if !item.respond_to?(:downcase!)
|
||||
|
||||
item.downcase!
|
||||
end
|
||||
|
||||
|
@ -124,6 +126,7 @@ returns
|
|||
row.each_with_index do |item, count|
|
||||
next if item.blank?
|
||||
next if header[count].nil?
|
||||
|
||||
if payload_last[header[count].to_sym].class != Array
|
||||
payload_last[header[count].to_sym] = [payload_last[header[count].to_sym]]
|
||||
end
|
||||
|
@ -136,6 +139,7 @@ returns
|
|||
next if !item
|
||||
next if header[count].blank?
|
||||
next if @csv_attributes_ignored&.include?(header[count].to_sym)
|
||||
|
||||
attributes[header[count].to_sym] = if item.respond_to?(:strip)
|
||||
item.strip
|
||||
else
|
||||
|
@ -170,6 +174,7 @@ returns
|
|||
record = nil
|
||||
%i[id number name login email].each do |lookup_by|
|
||||
next if !attributes[lookup_by]
|
||||
|
||||
params = {}
|
||||
params[lookup_by] = attributes[lookup_by]
|
||||
record = lookup(params)
|
||||
|
@ -208,6 +213,7 @@ returns
|
|||
end
|
||||
record = new(clean_params)
|
||||
next if try == true
|
||||
|
||||
record.associations_from_param(attributes)
|
||||
record.save!
|
||||
rescue => e
|
||||
|
@ -217,6 +223,7 @@ returns
|
|||
else
|
||||
stats[:updated] += 1
|
||||
next if try == true
|
||||
|
||||
begin
|
||||
csv_verify_attributes(clean_params)
|
||||
clean_params = param_cleanup(clean_params)
|
||||
|
@ -278,6 +285,7 @@ verify if attributes are valid, will raise an ArgumentError with "unknown attrib
|
|||
end
|
||||
clean_params.each_key do |key|
|
||||
next if all_clean_attributes.key?(key.to_sym)
|
||||
|
||||
raise ArgumentError, "unknown attribute '#{key}' for #{new.class}."
|
||||
end
|
||||
true
|
||||
|
@ -319,6 +327,7 @@ returns
|
|||
next if key == 'created_at'
|
||||
next if key == 'updated_at'
|
||||
next if header.include?(key)
|
||||
|
||||
header.push key
|
||||
end
|
||||
end
|
||||
|
@ -339,6 +348,7 @@ returns
|
|||
record[key].each do |entry|
|
||||
entry_count += 1
|
||||
next if entry_count == -1
|
||||
|
||||
if !rows_to_add[entry_count]
|
||||
rows_to_add[entry_count] = Array.new(header.count + 1) { '' }
|
||||
end
|
||||
|
@ -350,6 +360,7 @@ returns
|
|||
end
|
||||
rows.push row
|
||||
next if rows_to_add.count.zero?
|
||||
|
||||
rows_to_add.each do |item|
|
||||
rows.push item
|
||||
end
|
||||
|
|
|
@ -21,6 +21,7 @@ returns
|
|||
|
||||
def generate_uniq_name(name)
|
||||
return name if !exists?(name: name)
|
||||
|
||||
(1..100).each do |counter|
|
||||
name = "#{name}_#{counter}"
|
||||
break if !exists?(name: name)
|
||||
|
|
|
@ -29,6 +29,7 @@ class OwnModel < ApplicationModel
|
|||
|
||||
# return if we run import mode
|
||||
return if Setting.get('import_mode')
|
||||
|
||||
logger.debug { "#{self.class.name}.find(#{id}) notify created #{created_at}" }
|
||||
class_name = self.class.name
|
||||
class_name.gsub!(/::/, '')
|
||||
|
@ -61,6 +62,7 @@ class OwnModel < ApplicationModel
|
|||
|
||||
# return if we run import mode
|
||||
return if Setting.get('import_mode')
|
||||
|
||||
logger.debug { "#{self.class.name}.find(#{id}) notify UPDATED #{updated_at}" }
|
||||
class_name = self.class.name
|
||||
class_name.gsub!(/::/, '')
|
||||
|
@ -93,6 +95,7 @@ class OwnModel < ApplicationModel
|
|||
|
||||
# return if we run import mode
|
||||
return if Setting.get('import_mode')
|
||||
|
||||
logger.debug { "#{self.class.name}.find(#{id}) notify TOUCH #{updated_at}" }
|
||||
class_name = self.class.name
|
||||
class_name.gsub!(/::/, '')
|
||||
|
@ -124,6 +127,7 @@ class OwnModel < ApplicationModel
|
|||
|
||||
# return if we run import mode
|
||||
return if Setting.get('import_mode')
|
||||
|
||||
logger.debug { "#{self.class.name}.find(#{id}) notify DESTOY #{updated_at}" }
|
||||
class_name = self.class.name
|
||||
class_name.gsub!(/::/, '')
|
||||
|
|
|
@ -28,6 +28,7 @@ module ChecksConditionValidation
|
|||
|
||||
ticket_count, tickets = Ticket.selectors(validate_condition, 1, User.find(1))
|
||||
return true if ticket_count.present?
|
||||
|
||||
raise Exceptions::UnprocessableEntity, 'Invalid ticket selector conditions'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -40,9 +40,11 @@ log object update activity stream, if configured - will be executed automaticall
|
|||
log = false
|
||||
saved_changes.each_key do |key|
|
||||
next if ignored_attributes.include?(key.to_sym)
|
||||
|
||||
log = true
|
||||
end
|
||||
return true if !log
|
||||
|
||||
activity_stream_log('update', self['updated_by_id'])
|
||||
true
|
||||
end
|
||||
|
|
|
@ -47,6 +47,7 @@ module HasGroupRelationDefinition
|
|||
end
|
||||
|
||||
return if !query.exists?
|
||||
|
||||
errors.add(:access, "#{group_relation_model_identifier.to_s.capitalize} can have full or granular access to group")
|
||||
end
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ module HasGroups
|
|||
|
||||
# check indirect access through Roles if possible
|
||||
return false if !respond_to?(:role_access?)
|
||||
|
||||
role_access?(group_id, access)
|
||||
end
|
||||
|
||||
|
@ -197,6 +198,7 @@ module HasGroups
|
|||
# @return [Boolean]
|
||||
def groups_access_permission?
|
||||
return true if !respond_to?(:permissions?)
|
||||
|
||||
permissions?('ticket.agent')
|
||||
end
|
||||
|
||||
|
@ -244,6 +246,7 @@ module HasGroups
|
|||
# if changes to the map were performed
|
||||
# otherwise it's just an update of other attributes
|
||||
return if group_access_buffer.nil?
|
||||
|
||||
yield
|
||||
group_access_buffer = nil
|
||||
cache_delete
|
||||
|
@ -356,6 +359,7 @@ module HasGroups
|
|||
|
||||
def ensure_group_id_parameter(group_or_id)
|
||||
return group_or_id if group_or_id.is_a?(Integer)
|
||||
|
||||
group_or_id.id
|
||||
end
|
||||
|
||||
|
|
|
@ -84,6 +84,7 @@ module HasRoles
|
|||
|
||||
def ensure_group_id_parameter(group_or_id)
|
||||
return group_or_id if group_or_id.is_a?(Integer)
|
||||
|
||||
group_or_id.id
|
||||
end
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ update search index, if configured - will be executed automatically
|
|||
|
||||
# start background job to transfer data to search index
|
||||
return true if !SearchIndexBackend.enabled?
|
||||
|
||||
Delayed::Job.enqueue(BackgroundJobSearchIndex.new(self.class.to_s, id))
|
||||
true
|
||||
end
|
||||
|
@ -38,6 +39,7 @@ delete search index object, will be executed automatically
|
|||
|
||||
def search_index_destroy
|
||||
return true if ignore_search_indexing?(:destroy)
|
||||
|
||||
SearchIndexBackend.remove(self.class.to_s, id)
|
||||
true
|
||||
end
|
||||
|
@ -87,9 +89,11 @@ returns
|
|||
%w[name note].each do |key|
|
||||
next if !self[key]
|
||||
next if self[key].respond_to?('blank?') && self[key].blank?
|
||||
|
||||
attributes[key] = self[key]
|
||||
end
|
||||
return true if attributes.blank?
|
||||
|
||||
attributes
|
||||
end
|
||||
|
||||
|
@ -130,6 +134,7 @@ reload search index with full data
|
|||
ids.each do |item_id|
|
||||
item = find(item_id)
|
||||
next if item.ignore_search_indexing?(:destroy)
|
||||
|
||||
begin
|
||||
item.search_index_update_backend
|
||||
rescue => e
|
||||
|
|
|
@ -72,6 +72,7 @@ returns
|
|||
# check order
|
||||
params[:order_by].each do |value|
|
||||
raise "Found invalid order by value #{value}. Please use 'asc' or 'desc'." if value !~ /\A(asc|desc)\z/i
|
||||
|
||||
order_by.push(value.downcase)
|
||||
end
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ module Cti
|
|||
)
|
||||
|
||||
return record if !record.new_record?
|
||||
|
||||
record.comment = data[:comment]
|
||||
record.save!
|
||||
end
|
||||
|
@ -72,10 +73,12 @@ returns
|
|||
model = nil
|
||||
map.each do |item|
|
||||
next if item[:model] != record.class
|
||||
|
||||
level = item[:level]
|
||||
model = item[:model]
|
||||
end
|
||||
return if !level || !model
|
||||
|
||||
build_item(record, model, level)
|
||||
end
|
||||
|
||||
|
@ -92,6 +95,7 @@ returns
|
|||
article = record.articles.first
|
||||
return if !article
|
||||
return if article.sender.name != 'Customer'
|
||||
|
||||
record = article
|
||||
end
|
||||
|
||||
|
@ -112,8 +116,10 @@ returns
|
|||
attributes.each_value do |value|
|
||||
next if value.class != String
|
||||
next if value.blank?
|
||||
|
||||
local_caller_ids = Cti::CallerId.extract_numbers(value)
|
||||
next if local_caller_ids.blank?
|
||||
|
||||
caller_ids = caller_ids.concat(local_caller_ids)
|
||||
end
|
||||
|
||||
|
@ -217,6 +223,7 @@ returns
|
|||
def self.extract_numbers(text)
|
||||
# see specs for example
|
||||
return [] if !text.is_a?(String)
|
||||
|
||||
text.scan(/([\d|\s|\-|\(|\)]{6,26})/).map do |match|
|
||||
normalize_number(match[0])
|
||||
end
|
||||
|
@ -273,17 +280,20 @@ returns
|
|||
end
|
||||
return [from_comment_known, preferences_known] if from_comment_known.present?
|
||||
return ["maybe #{from_comment_maybe}", preferences_maybe] if from_comment_maybe.present?
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
def update_cti_logs
|
||||
return if object != 'User'
|
||||
|
||||
UpdateCtiLogsByCallerJob.perform_later(caller_id)
|
||||
end
|
||||
|
||||
def update_cti_logs_with_fg_optimization
|
||||
return if object != 'User'
|
||||
return if level != 'known'
|
||||
|
||||
UpdateCtiLogsByCallerJob.perform_now(caller_id, limit: 20)
|
||||
UpdateCtiLogsByCallerJob.perform_later(caller_id, limit: 40, offset: 20)
|
||||
end
|
||||
|
|
|
@ -320,6 +320,7 @@ Cti::Log.process(
|
|||
done = false
|
||||
end
|
||||
raise "call_id #{call_id} already exists!" if log
|
||||
|
||||
create(
|
||||
direction: params['direction'],
|
||||
from: params['from'],
|
||||
|
@ -336,6 +337,7 @@ Cti::Log.process(
|
|||
when 'answer'
|
||||
raise "No such call_id #{call_id}" if !log
|
||||
return if log.state == 'hangup' # call is already hangup, ignore answer
|
||||
|
||||
log.with_lock do
|
||||
log.state = 'answer'
|
||||
log.start_at = Time.zone.now
|
||||
|
@ -349,6 +351,7 @@ Cti::Log.process(
|
|||
end
|
||||
when 'hangup'
|
||||
raise "No such call_id #{call_id}" if !log
|
||||
|
||||
log.with_lock do
|
||||
log.done = done
|
||||
if params['direction'] == 'in'
|
||||
|
@ -395,6 +398,7 @@ Cti::Log.process(
|
|||
def self.push_caller_list_update?(record)
|
||||
list_ids = Cti::Log.log_records.pluck(:id)
|
||||
return true if list_ids.include?(record.id)
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ check and if channel not exists reset configured channels for email addresses
|
|||
|
||||
# set in inactive if channel not longer exists
|
||||
next if !email_address.active
|
||||
|
||||
email_address.save!
|
||||
end
|
||||
end
|
||||
|
@ -45,9 +46,11 @@ check and if channel not exists reset configured channels for email addresses
|
|||
def check_email
|
||||
return true if Setting.get('import_mode')
|
||||
return true if email.blank?
|
||||
|
||||
self.email = email.downcase.strip
|
||||
raise Exceptions::UnprocessableEntity, 'Invalid email' if email !~ /@/
|
||||
raise Exceptions::UnprocessableEntity, 'Invalid email' if email.match?(/\s/)
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
|
@ -79,6 +82,7 @@ check and if channel not exists reset configured channels for email addresses
|
|||
total = Group.count
|
||||
return if not_configured.zero?
|
||||
return if total != 1
|
||||
|
||||
group = Group.find_by(email_address_id: nil)
|
||||
group.email_address_id = id
|
||||
group.updated_by_id = updated_by_id
|
||||
|
|
|
@ -37,8 +37,10 @@ class ExternalSync < ApplicationModel
|
|||
local_key_sym = local_key.to_sym
|
||||
|
||||
next if result[local_key_sym].present?
|
||||
|
||||
value = extract(remote_key, information_source)
|
||||
next if value.blank?
|
||||
|
||||
result[local_key_sym] = value
|
||||
end
|
||||
result
|
||||
|
|
|
@ -5,11 +5,9 @@ class History < ApplicationModel
|
|||
|
||||
self.table_name = 'histories'
|
||||
|
||||
# rubocop:disable Rails/InverseOf
|
||||
belongs_to :history_type, class_name: 'History::Type'
|
||||
belongs_to :history_object, class_name: 'History::Object'
|
||||
belongs_to :history_attribute, class_name: 'History::Attribute'
|
||||
# rubocop:enable Rails/InverseOf
|
||||
|
||||
# the noop is needed since Layout/EmptyLines detects
|
||||
# the block commend below wrongly as the measurement of
|
||||
|
@ -101,6 +99,7 @@ remove whole history entries of an object
|
|||
def self.remove(requested_object, requested_object_id)
|
||||
history_object = History::Object.find_by(name: requested_object)
|
||||
return if !history_object
|
||||
|
||||
History.where(
|
||||
history_object_id: history_object.id,
|
||||
o_id: requested_object_id,
|
||||
|
|
|
@ -51,8 +51,10 @@ class ImportJob < ApplicationModel
|
|||
# return [Boolean] whether the ImportJob should get rescheduled (true) or destroyed (false)
|
||||
def reschedule?(delayed_job)
|
||||
return false if finished_at.present?
|
||||
|
||||
instance = name.constantize.new(self)
|
||||
return false if !instance.respond_to?(:reschedule?)
|
||||
|
||||
instance.reschedule?(delayed_job)
|
||||
end
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ Job.run
|
|||
jobs = Job.where(active: true)
|
||||
jobs.each do |job|
|
||||
next if !job.executable?
|
||||
|
||||
job.run(false, start_at)
|
||||
end
|
||||
true
|
||||
|
@ -199,10 +200,12 @@ job.run(true)
|
|||
(0..5).each do |minute_counter|
|
||||
if minute_counter.nonzero?
|
||||
break if day_to_check.min.zero?
|
||||
|
||||
day_to_check = day_to_check + 10.minutes
|
||||
end
|
||||
next if !timeplan['hours'][day_to_check.hour] && !timeplan['hours'][day_to_check.hour.to_s]
|
||||
next if !timeplan['minutes'][match_minutes(day_to_check.min)] && !timeplan['minutes'][match_minutes(day_to_check.min).to_s]
|
||||
|
||||
return day_to_check
|
||||
end
|
||||
end
|
||||
|
@ -227,10 +230,12 @@ job.run(true)
|
|||
(0..5).each do |minute_counter|
|
||||
minute_to_check = hour_to_check + minute_counter.minutes * 10
|
||||
next if !timeplan['minutes'][match_minutes(minute_to_check.min)] && !timeplan['minutes'][match_minutes(minute_to_check.min).to_s]
|
||||
|
||||
time_to_check = minute_to_check
|
||||
break
|
||||
end
|
||||
next if !minute_to_check
|
||||
|
||||
return time_to_check
|
||||
end
|
||||
|
||||
|
@ -252,6 +257,7 @@ job.run(true)
|
|||
|
||||
def match_minutes(minutes)
|
||||
return 0 if minutes < 10
|
||||
|
||||
"#{minutes.to_s.gsub(/(\d)\d/, '\\1')}0".to_i
|
||||
end
|
||||
|
||||
|
|
|
@ -40,8 +40,10 @@ returns
|
|||
%w[created_by_id updated_by_id].each do |local_user_id|
|
||||
next if !self[ local_user_id ]
|
||||
next if data[ User.to_app_model ][ self[ local_user_id ] ]
|
||||
|
||||
user = User.lookup(id: self[ local_user_id ])
|
||||
next if !user
|
||||
|
||||
data = user.assets(data)
|
||||
end
|
||||
data
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue