diff --git a/.rubocop.yml b/.rubocop.yml index 292590f30..a0cee4e67 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -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 diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 9ead11a0b..8581fe0a4 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -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 diff --git a/Gemfile.lock b/Gemfile.lock index ae7e92cf7..b0941b974 100644 --- a/Gemfile.lock +++ b/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) diff --git a/app/controllers/application_controller/authenticates.rb b/app/controllers/application_controller/authenticates.rb index fbf2a764d..81fe62db6 100644 --- a/app/controllers/application_controller/authenticates.rb +++ b/app/controllers/application_controller/authenticates.rb @@ -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, diff --git a/app/controllers/application_controller/checks_maintainance.rb b/app/controllers/application_controller/checks_maintainance.rb index 591a1f30e..7d1ef0ae5 100644 --- a/app/controllers/application_controller/checks_maintainance.rb +++ b/app/controllers/application_controller/checks_maintainance.rb @@ -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 diff --git a/app/controllers/application_controller/handles_devices.rb b/app/controllers/application_controller/handles_devices.rb index abef7ebff..8428b4b9a 100644 --- a/app/controllers/application_controller/handles_devices.rb +++ b/app/controllers/application_controller/handles_devices.rb @@ -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] diff --git a/app/controllers/application_controller/has_response_extentions.rb b/app/controllers/application_controller/has_response_extentions.rb index 284573cb6..56d02cc0d 100644 --- a/app/controllers/application_controller/has_response_extentions.rb +++ b/app/controllers/application_controller/has_response_extentions.rb @@ -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 diff --git a/app/controllers/application_controller/has_user.rb b/app/controllers/application_controller/has_user.rb index 86ed5bb73..3003d6847 100644 --- a/app/controllers/application_controller/has_user.rb +++ b/app/controllers/application_controller/has_user.rb @@ -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 diff --git a/app/controllers/application_controller/logs_http_access.rb b/app/controllers/application_controller/logs_http_access.rb index fe783693c..3aed2fc65 100644 --- a/app/controllers/application_controller/logs_http_access.rb +++ b/app/controllers/application_controller/logs_http_access.rb @@ -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 diff --git a/app/controllers/application_controller/prevents_csrf.rb b/app/controllers/application_controller/prevents_csrf.rb index 240daa874..2182ac07a 100644 --- a/app/controllers/application_controller/prevents_csrf.rb +++ b/app/controllers/application_controller/prevents_csrf.rb @@ -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 diff --git a/app/controllers/application_controller/renders_models.rb b/app/controllers/application_controller/renders_models.rb index 6c008d4c2..1643ddb56 100644 --- a/app/controllers/application_controller/renders_models.rb +++ b/app/controllers/application_controller/renders_models.rb @@ -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 diff --git a/app/controllers/application_controller/sets_headers.rb b/app/controllers/application_controller/sets_headers.rb index d99c9edc9..97391904b 100644 --- a/app/controllers/application_controller/sets_headers.rb +++ b/app/controllers/application_controller/sets_headers.rb @@ -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' diff --git a/app/controllers/channels_email_controller.rb b/app/controllers/channels_email_controller.rb index 0dc1ac72a..b7743b38e 100644 --- a/app/controllers/channels_email_controller.rb +++ b/app/controllers/channels_email_controller.rb @@ -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 diff --git a/app/controllers/concerns/checks_user_attributes_by_current_user_permission.rb b/app/controllers/concerns/checks_user_attributes_by_current_user_permission.rb index 1f01f5ce2..5d6308f4d 100644 --- a/app/controllers/concerns/checks_user_attributes_by_current_user_permission.rb +++ b/app/controllers/concerns/checks_user_attributes_by_current_user_permission.rb @@ -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 diff --git a/app/controllers/concerns/clones_ticket_article_attachments.rb b/app/controllers/concerns/clones_ticket_article_attachments.rb index 211d6f29f..d521f85b2 100644 --- a/app/controllers/concerns/clones_ticket_article_attachments.rb +++ b/app/controllers/concerns/clones_ticket_article_attachments.rb @@ -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], diff --git a/app/controllers/concerns/creates_ticket_articles.rb b/app/controllers/concerns/creates_ticket_articles.rb index df7741c3a..1502ad75c 100644 --- a/app/controllers/concerns/creates_ticket_articles.rb +++ b/app/controllers/concerns/creates_ticket_articles.rb @@ -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 diff --git a/app/controllers/external_credentials_controller.rb b/app/controllers/external_credentials_controller.rb index af387cae3..f8064f0b4 100644 --- a/app/controllers/external_credentials_controller.rb +++ b/app/controllers/external_credentials_controller.rb @@ -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 diff --git a/app/controllers/first_steps_controller.rb b/app/controllers/first_steps_controller.rb index 0dd392be3..b41746f88 100644 --- a/app/controllers/first_steps_controller.rb +++ b/app/controllers/first_steps_controller.rb @@ -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 diff --git a/app/controllers/form_controller.rb b/app/controllers/form_controller.rb index e30eec739..2c2778711 100644 --- a/app/controllers/form_controller.rb +++ b/app/controllers/form_controller.rb @@ -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 diff --git a/app/controllers/import_otrs_controller.rb b/app/controllers/import_otrs_controller.rb index 289d9e7ca..60cdcb371 100644 --- a/app/controllers/import_otrs_controller.rb +++ b/app/controllers/import_otrs_controller.rb @@ -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, } diff --git a/app/controllers/import_zendesk_controller.rb b/app/controllers/import_zendesk_controller.rb index b3418b322..8537fdd93 100644 --- a/app/controllers/import_zendesk_controller.rb +++ b/app/controllers/import_zendesk_controller.rb @@ -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, } diff --git a/app/controllers/integration/check_mk_controller.rb b/app/controllers/integration/check_mk_controller.rb index 2c62c7fe3..db8a562f7 100644 --- a/app/controllers/integration/check_mk_controller.rb +++ b/app/controllers/integration/check_mk_controller.rb @@ -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 diff --git a/app/controllers/integration/cti_controller.rb b/app/controllers/integration/cti_controller.rb index 33a1bd9ea..2091475fe 100644 --- a/app/controllers/integration/cti_controller.rb +++ b/app/controllers/integration/cti_controller.rb @@ -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', diff --git a/app/controllers/integration/ldap_controller.rb b/app/controllers/integration/ldap_controller.rb index 5f916f6df..92ce57f22 100644 --- a/app/controllers/integration/ldap_controller.rb +++ b/app/controllers/integration/ldap_controller.rb @@ -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 diff --git a/app/controllers/integration/sipgate_controller.rb b/app/controllers/integration/sipgate_controller.rb index 9c27ae1ed..5fa0eb2b8 100644 --- a/app/controllers/integration/sipgate_controller.rb +++ b/app/controllers/integration/sipgate_controller.rb @@ -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]) } diff --git a/app/controllers/long_polling_controller.rb b/app/controllers/long_polling_controller.rb index 294617ec6..0c8e198c5 100644 --- a/app/controllers/long_polling_controller.rb +++ b/app/controllers/long_polling_controller.rb @@ -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 diff --git a/app/controllers/monitoring_controller.rb b/app/controllers/monitoring_controller.rb index e477cd3b3..ac7787a7e 100644 --- a/app/controllers/monitoring_controller.rb +++ b/app/controllers/monitoring_controller.rb @@ -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 diff --git a/app/controllers/online_notifications_controller.rb b/app/controllers/online_notifications_controller.rb index efa36016e..632127b9e 100644 --- a/app/controllers/online_notifications_controller.rb +++ b/app/controllers/online_notifications_controller.rb @@ -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 diff --git a/app/controllers/overviews_controller.rb b/app/controllers/overviews_controller.rb index ee7d835ca..2a717bf5b 100644 --- a/app/controllers/overviews_controller.rb +++ b/app/controllers/overviews_controller.rb @@ -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 diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index 08ff8fe45..be1ae6a4c 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -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"}} diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index fad61f23c..aac7a750f 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -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 diff --git a/app/controllers/sessions/collection_base.rb b/app/controllers/sessions/collection_base.rb index 87464301a..f0773f53c 100644 --- a/app/controllers/sessions/collection_base.rb +++ b/app/controllers/sessions/collection_base.rb @@ -45,5 +45,5 @@ module ExtraCollection [collections, assets] end - module_function :session + module_function :session # rubocop:disable Style/AccessModifierDeclarations end diff --git a/app/controllers/sessions/collection_dashboard.rb b/app/controllers/sessions/collection_dashboard.rb index c36836cac..7ed34c4a6 100644 --- a/app/controllers/sessions/collection_dashboard.rb +++ b/app/controllers/sessions/collection_dashboard.rb @@ -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 diff --git a/app/controllers/sessions/collection_ticket.rb b/app/controllers/sessions/collection_ticket.rb index e7c74d1a4..12db49ef1 100644 --- a/app/controllers/sessions/collection_ticket.rb +++ b/app/controllers/sessions/collection_ticket.rb @@ -44,5 +44,5 @@ module ExtraCollection end [collections, assets] end - module_function :session + module_function :session # rubocop:disable Style/AccessModifierDeclarations end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index e7e34d000..7f394a64c 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -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 diff --git a/app/controllers/settings_controller.rb b/app/controllers/settings_controller.rb index f41ecedff..07c87f57a 100644 --- a/app/controllers/settings_controller.rb +++ b/app/controllers/settings_controller.rb @@ -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 diff --git a/app/controllers/ticket_articles_controller.rb b/app/controllers/ticket_articles_controller.rb index 110321e63..54357bb76 100644 --- a/app/controllers/ticket_articles_controller.rb +++ b/app/controllers/ticket_articles_controller.rb @@ -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 diff --git a/app/controllers/ticket_states_controller.rb b/app/controllers/ticket_states_controller.rb index ca56750ba..4db94415b 100644 --- a/app/controllers/ticket_states_controller.rb +++ b/app/controllers/ticket_states_controller.rb @@ -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 diff --git a/app/controllers/tickets_controller.rb b/app/controllers/tickets_controller.rb index 5d10c945c..217afadf5 100644 --- a/app/controllers/tickets_controller.rb +++ b/app/controllers/tickets_controller.rb @@ -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 diff --git a/app/controllers/time_accountings_controller.rb b/app/controllers/time_accountings_controller.rb index 1ff3b7d82..1d71789e3 100644 --- a/app/controllers/time_accountings_controller.rb +++ b/app/controllers/time_accountings_controller.rb @@ -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, diff --git a/app/controllers/user_access_token_controller.rb b/app/controllers/user_access_token_controller.rb index 576a373bb..2efce83c3 100644 --- a/app/controllers/user_access_token_controller.rb +++ b/app/controllers/user_access_token_controller.rb @@ -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 diff --git a/app/controllers/user_devices_controller.rb b/app/controllers/user_devices_controller.rb index 4b9efccc3..37b1cac4f 100644 --- a/app/controllers/user_devices_controller.rb +++ b/app/controllers/user_devices_controller.rb @@ -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 diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index e7c03202b..b40d47e4c 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -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 diff --git a/app/models/activity_stream.rb b/app/models/activity_stream.rb index ddbb536bf..26b57f853 100644 --- a/app/models/activity_stream.rb +++ b/app/models/activity_stream.rb @@ -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 diff --git a/app/models/activity_stream/assets.rb b/app/models/activity_stream/assets.rb index a8a8aab3b..1fd7a4fcd 100644 --- a/app/models/activity_stream/assets.rb +++ b/app/models/activity_stream/assets.rb @@ -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 diff --git a/app/models/application_model/can_assets.rb b/app/models/application_model/can_assets.rb index efb5fdf52..fe1307257 100644 --- a/app/models/application_model/can_assets.rb +++ b/app/models/application_model/can_assets.rb @@ -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? diff --git a/app/models/application_model/can_associations.rb b/app/models/application_model/can_associations.rb index 3e737422b..feadc3d05 100644 --- a/app/models/application_model/can_associations.rb +++ b/app/models/application_model/can_associations.rb @@ -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 diff --git a/app/models/application_model/can_cleanup_param.rb b/app/models/application_model/can_cleanup_param.rb index e9ded1977..6deb02ef8 100644 --- a/app/models/application_model/can_cleanup_param.rb +++ b/app/models/application_model/can_cleanup_param.rb @@ -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 diff --git a/app/models/application_model/can_latest_change.rb b/app/models/application_model/can_latest_change.rb index def47cb03..39f0c2fe2 100644 --- a/app/models/application_model/can_latest_change.rb +++ b/app/models/application_model/can_latest_change.rb @@ -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 diff --git a/app/models/application_model/can_lookup_search_index_attributes.rb b/app/models/application_model/can_lookup_search_index_attributes.rb index 5607bb005..a38ebe7f0 100644 --- a/app/models/application_model/can_lookup_search_index_attributes.rb +++ b/app/models/application_model/can_lookup_search_index_attributes.rb @@ -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 diff --git a/app/models/application_model/can_touch_references.rb b/app/models/application_model/can_touch_references.rb index 23eba980a..18037f927 100644 --- a/app/models/application_model/can_touch_references.rb +++ b/app/models/application_model/can_touch_references.rb @@ -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 diff --git a/app/models/application_model/checks_attribute_values_and_length.rb b/app/models/application_model/checks_attribute_values_and_length.rb index 2cc92eeda..2f37dff5d 100644 --- a/app/models/application_model/checks_attribute_values_and_length.rb +++ b/app/models/application_model/checks_attribute_values_and_length.rb @@ -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 diff --git a/app/models/application_model/checks_import.rb b/app/models/application_model/checks_import.rb index feb1def4f..dd37714db 100644 --- a/app/models/application_model/checks_import.rb +++ b/app/models/application_model/checks_import.rb @@ -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 diff --git a/app/models/authorization.rb b/app/models/authorization.rb index 4b8075f0b..2d70ca492 100644 --- a/app/models/authorization.rb +++ b/app/models/authorization.rb @@ -96,6 +96,7 @@ class Authorization < ApplicationModel def delete_user_cache return if !user + user.touch # rubocop:disable Rails/SkipsModelValidations end diff --git a/app/models/avatar.rb b/app/models/avatar.rb index dc7fd832d..7f6ccb62c 100644 --- a/app/models/avatar.rb +++ b/app/models/avatar.rb @@ -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 diff --git a/app/models/calendar.rb b/app/models/calendar.rb index 1fcf20bdb..9a660e22d 100644 --- a/app/models/calendar.rb +++ b/app/models/calendar.rb @@ -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 diff --git a/app/models/channel.rb b/app/models/channel.rb index 0ecd2953e..401e61502 100644 --- a/app/models/channel.rb +++ b/app/models/channel.rb @@ -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 diff --git a/app/models/channel/assets.rb b/app/models/channel/assets.rb index c181cbb2c..316fa4c3e 100644 --- a/app/models/channel/assets.rb +++ b/app/models/channel/assets.rb @@ -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 diff --git a/app/models/channel/driver/facebook.rb b/app/models/channel/driver/facebook.rb index b56b39a66..a7de9857c 100644 --- a/app/models/channel/driver/facebook.rb +++ b/app/models/channel/driver/facebook.rb @@ -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}') diff --git a/app/models/channel/driver/imap.rb b/app/models/channel/driver/imap.rb index 68b42da9f..5231fbc2b 100644 --- a/app/models/channel/driver/imap.rb +++ b/app/models/channel/driver/imap.rb @@ -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 diff --git a/app/models/channel/driver/pop3.rb b/app/models/channel/driver/pop3.rb index 050a7e400..474cd3a10 100644 --- a/app/models/channel/driver/pop3.rb +++ b/app/models/channel/driver/pop3.rb @@ -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 diff --git a/app/models/channel/driver/sendmail.rb b/app/models/channel/driver/sendmail.rb index 46cf13c8f..17f507247 100644 --- a/app/models/channel/driver/sendmail.rb +++ b/app/models/channel/driver/sendmail.rb @@ -23,6 +23,7 @@ class Channel::Driver::Sendmail def delivery_method return :test if Rails.env.test? + :sendmail end end diff --git a/app/models/channel/driver/telegram.rb b/app/models/channel/driver/telegram.rb index 66f1eb5b5..ba5811af8 100644 --- a/app/models/channel/driver/telegram.rb +++ b/app/models/channel/driver/telegram.rb @@ -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 diff --git a/app/models/channel/driver/twitter.rb b/app/models/channel/driver/twitter.rb index 33ecf4c1d..fa26525ec 100644 --- a/app/models/channel/driver/twitter.rb +++ b/app/models/channel/driver/twitter.rb @@ -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})" } diff --git a/app/models/channel/email_build.rb b/app/models/channel/email_build.rb index 7e6a4aad5..d9d8082fd 100644 --- a/app/models/channel/email_build.rb +++ b/app/models/channel/email_build.rb @@ -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 diff --git a/app/models/channel/email_parser.rb b/app/models/channel/email_parser.rb index 049f5fb02..e3cda61f4 100644 --- a/app/models/channel/email_parser.rb +++ b/app/models/channel/email_parser.rb @@ -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 diff --git a/app/models/channel/filter/bounce_delivery_permanent_failed.rb b/app/models/channel/filter/bounce_delivery_permanent_failed.rb index 7def43640..59e7b5895 100644 --- a/app/models/channel/filter/bounce_delivery_permanent_failed.rb +++ b/app/models/channel/filter/bounce_delivery_permanent_failed.rb @@ -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! diff --git a/app/models/channel/filter/bounce_follow_up_check.rb b/app/models/channel/filter/bounce_follow_up_check.rb index bb0891d58..62819acc5 100644 --- a/app/models/channel/filter/bounce_follow_up_check.rb +++ b/app/models/channel/filter/bounce_follow_up_check.rb @@ -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 diff --git a/app/models/channel/filter/database.rb b/app/models/channel/filter/database.rb index 3dba8f2c3..bfec06464 100644 --- a/app/models/channel/filter/database.rb +++ b/app/models/channel/filter/database.rb @@ -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 diff --git a/app/models/channel/filter/follow_up_check.rb b/app/models/channel/filter/follow_up_check.rb index d41d32ff0..3f8d2469e 100644 --- a/app/models/channel/filter/follow_up_check.rb +++ b/app/models/channel/filter/follow_up_check.rb @@ -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 diff --git a/app/models/channel/filter/follow_up_possible_check.rb b/app/models/channel/filter/follow_up_possible_check.rb index 8e5ab4e85..959c882ee 100644 --- a/app/models/channel/filter/follow_up_possible_check.rb +++ b/app/models/channel/filter/follow_up_possible_check.rb @@ -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 diff --git a/app/models/channel/filter/identify_sender.rb b/app/models/channel/filter/identify_sender.rb index ddc72bedf..315acaedc 100644 --- a/app/models/channel/filter/identify_sender.rb +++ b/app/models/channel/filter/identify_sender.rb @@ -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: '', diff --git a/app/models/channel/filter/match/email_regex.rb b/app/models/channel/filter/match/email_regex.rb index cf5dead02..846257211 100644 --- a/app/models/channel/filter/match/email_regex.rb +++ b/app/models/channel/filter/match/email_regex.rb @@ -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}" diff --git a/app/models/channel/filter/monitoring_base.rb b/app/models/channel/filter/monitoring_base.rb index 17c8db226..a1d86a0e3 100644 --- a/app/models/channel/filter/monitoring_base.rb +++ b/app/models/channel/filter/monitoring_base.rb @@ -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 diff --git a/app/models/channel/filter/own_notification_loop_detection.rb b/app/models/channel/filter/own_notification_loop_detection.rb index b64129c9e..4c7629a93 100644 --- a/app/models/channel/filter/own_notification_loop_detection.rb +++ b/app/models/channel/filter/own_notification_loop_detection.rb @@ -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 diff --git a/app/models/channel/filter/sender_is_system_address.rb b/app/models/channel/filter/sender_is_system_address.rb index 07efc2806..b21629fd1 100644 --- a/app/models/channel/filter/sender_is_system_address.rb +++ b/app/models/channel/filter/sender_is_system_address.rb @@ -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 diff --git a/app/models/channel/filter/trusted.rb b/app/models/channel/filter/trusted.rb index e118dc3da..238d885d6 100644 --- a/app/models/channel/filter/trusted.rb +++ b/app/models/channel/filter/trusted.rb @@ -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 diff --git a/app/models/chat.rb b/app/models/chat.rb index e5bedd1c8..612050856 100644 --- a/app/models/chat.rb +++ b/app/models/chat.rb @@ -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 diff --git a/app/models/chat/agent.rb b/app/models/chat/agent.rb index fdcd1ff12..42ef218bf 100644 --- a/app/models/chat/agent.rb +++ b/app/models/chat/agent.rb @@ -14,6 +14,7 @@ class Chat::Agent < ApplicationModel ) if state.nil? return false if !chat_agent + return chat_agent.active end if chat_agent diff --git a/app/models/chat/session.rb b/app/models/chat/session.rb index 789665634..9640458d3 100644 --- a/app/models/chat/session.rb +++ b/app/models/chat/session.rb @@ -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 diff --git a/app/models/chat/session/assets.rb b/app/models/chat/session/assets.rb index 492bb355c..acb08409b 100644 --- a/app/models/chat/session/assets.rb +++ b/app/models/chat/session/assets.rb @@ -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 diff --git a/app/models/chat/session/search.rb b/app/models/chat/session/search.rb index ef77f7050..13eda294a 100644 --- a/app/models/chat/session/search.rb +++ b/app/models/chat/session/search.rb @@ -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 diff --git a/app/models/concerns/can_csv_import.rb b/app/models/concerns/can_csv_import.rb index 4e227b561..cde7a5ed0 100644 --- a/app/models/concerns/can_csv_import.rb +++ b/app/models/concerns/can_csv_import.rb @@ -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 diff --git a/app/models/concerns/can_uniq_name.rb b/app/models/concerns/can_uniq_name.rb index e3cd8cee8..d3669feb2 100644 --- a/app/models/concerns/can_uniq_name.rb +++ b/app/models/concerns/can_uniq_name.rb @@ -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) diff --git a/app/models/concerns/checks_client_notification.rb b/app/models/concerns/checks_client_notification.rb index fc35db039..0d44dcb43 100644 --- a/app/models/concerns/checks_client_notification.rb +++ b/app/models/concerns/checks_client_notification.rb @@ -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!(/::/, '') diff --git a/app/models/concerns/checks_condition_validation.rb b/app/models/concerns/checks_condition_validation.rb index 7bdee3770..4f24d8ee2 100644 --- a/app/models/concerns/checks_condition_validation.rb +++ b/app/models/concerns/checks_condition_validation.rb @@ -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 diff --git a/app/models/concerns/has_activity_stream_log.rb b/app/models/concerns/has_activity_stream_log.rb index f07b872d0..6092e3b7b 100644 --- a/app/models/concerns/has_activity_stream_log.rb +++ b/app/models/concerns/has_activity_stream_log.rb @@ -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 diff --git a/app/models/concerns/has_group_relation_definition.rb b/app/models/concerns/has_group_relation_definition.rb index 1323c167a..b8282993a 100644 --- a/app/models/concerns/has_group_relation_definition.rb +++ b/app/models/concerns/has_group_relation_definition.rb @@ -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 diff --git a/app/models/concerns/has_groups.rb b/app/models/concerns/has_groups.rb index da43a7140..0d8074de3 100644 --- a/app/models/concerns/has_groups.rb +++ b/app/models/concerns/has_groups.rb @@ -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 diff --git a/app/models/concerns/has_roles.rb b/app/models/concerns/has_roles.rb index 42377e6a2..652431ac3 100644 --- a/app/models/concerns/has_roles.rb +++ b/app/models/concerns/has_roles.rb @@ -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 diff --git a/app/models/concerns/has_search_index_backend.rb b/app/models/concerns/has_search_index_backend.rb index 283928e9b..09622f472 100644 --- a/app/models/concerns/has_search_index_backend.rb +++ b/app/models/concerns/has_search_index_backend.rb @@ -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 diff --git a/app/models/concerns/has_search_sortable.rb b/app/models/concerns/has_search_sortable.rb index a1e60be6d..a859125d9 100644 --- a/app/models/concerns/has_search_sortable.rb +++ b/app/models/concerns/has_search_sortable.rb @@ -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 diff --git a/app/models/cti/caller_id.rb b/app/models/cti/caller_id.rb index f531f83af..c9dd3e353 100644 --- a/app/models/cti/caller_id.rb +++ b/app/models/cti/caller_id.rb @@ -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 diff --git a/app/models/cti/log.rb b/app/models/cti/log.rb index 1b39766a2..4a77b5aa2 100644 --- a/app/models/cti/log.rb +++ b/app/models/cti/log.rb @@ -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 diff --git a/app/models/email_address.rb b/app/models/email_address.rb index 0441f4431..5dcd2c9ed 100644 --- a/app/models/email_address.rb +++ b/app/models/email_address.rb @@ -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 diff --git a/app/models/external_sync.rb b/app/models/external_sync.rb index 1eff33857..f63240eed 100644 --- a/app/models/external_sync.rb +++ b/app/models/external_sync.rb @@ -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 diff --git a/app/models/history.rb b/app/models/history.rb index 15fae7bc8..9b82e54e4 100644 --- a/app/models/history.rb +++ b/app/models/history.rb @@ -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, diff --git a/app/models/import_job.rb b/app/models/import_job.rb index 4623aba5c..273893a22 100644 --- a/app/models/import_job.rb +++ b/app/models/import_job.rb @@ -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 diff --git a/app/models/job.rb b/app/models/job.rb index 10a8778a7..e0c4dac9e 100644 --- a/app/models/job.rb +++ b/app/models/job.rb @@ -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 diff --git a/app/models/job/assets.rb b/app/models/job/assets.rb index 7593594f2..8d8ce0423 100644 --- a/app/models/job/assets.rb +++ b/app/models/job/assets.rb @@ -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 diff --git a/app/models/karma.rb b/app/models/karma.rb index f9f1f9cba..b08f16fab 100644 --- a/app/models/karma.rb +++ b/app/models/karma.rb @@ -5,6 +5,7 @@ class Karma def self.score_by_user(user) last_activity_log = Karma::ActivityLog.where(user_id: user.id).order(id: :desc).first return 0 if !last_activity_log + last_activity_log.score_total end diff --git a/app/models/karma/activity_log.rb b/app/models/karma/activity_log.rb index bfdfd611b..ac3b5b9c9 100644 --- a/app/models/karma/activity_log.rb +++ b/app/models/karma/activity_log.rb @@ -29,6 +29,7 @@ add karma activity log of an object activity_id: activity.id, ).find_by('created_at >= ?', Time.zone.now - activity.once_ttl.seconds) return false if !force && latest_activity + score_total = 0 if last_activity score_total = last_activity.score_total diff --git a/app/models/karma/user.rb b/app/models/karma/user.rb index b276f45e3..ca5e1dd9b 100644 --- a/app/models/karma/user.rb +++ b/app/models/karma/user.rb @@ -9,6 +9,7 @@ class Karma::User < ApplicationModel record = Karma::User.find_by(user_id: user.id) if record return record if record.score == score && record.level == level + record.score = score record.level = level record.save @@ -24,6 +25,7 @@ class Karma::User < ApplicationModel def self.by_user(user) record = Karma::User.find_by(user_id: user.id) return record if record + sync(user) end @@ -36,6 +38,7 @@ class Karma::User < ApplicationModel end next if local_level[:start] && score < local_level[:start] next if local_level[:end] && score > local_level[:end] + level = local_level[:name] end level diff --git a/app/models/link.rb b/app/models/link.rb index 0361ce474..e96730d60 100644 --- a/app/models/link.rb +++ b/app/models/link.rb @@ -2,10 +2,8 @@ class Link < ApplicationModel - # rubocop:disable Rails/InverseOf belongs_to :link_type, class_name: 'Link::Type' belongs_to :link_object, class_name: 'Link::Object' - # rubocop:enable Rails/InverseOf after_destroy :touch_link_references @@ -27,6 +25,7 @@ class Link < ApplicationModel def self.list(data) linkobject = link_object_get( name: data[:link_object] ) return if !linkobject + items = [] # get links for one site diff --git a/app/models/locale.rb b/app/models/locale.rb index e183cd904..8ae95f0d9 100644 --- a/app/models/locale.rb +++ b/app/models/locale.rb @@ -41,6 +41,7 @@ all: def self.sync return true if load_from_file + load end @@ -73,6 +74,7 @@ all: version = Version.get file = Rails.root.join('config', "locales-#{version}.yml") return false if !File.exist?(file) + data = YAML.load_file(file) to_database(data) true diff --git a/app/models/object_lookup.rb b/app/models/object_lookup.rb index 5ada6c174..ddc76234f 100644 --- a/app/models/object_lookup.rb +++ b/app/models/object_lookup.rb @@ -6,6 +6,7 @@ class ObjectLookup < ApplicationModel # lookup lookup = self.lookup(id: id) return if !lookup + lookup.name end diff --git a/app/models/object_manager/attribute.rb b/app/models/object_manager/attribute.rb index d5ba71558..10042bdc8 100644 --- a/app/models/object_manager/attribute.rb +++ b/app/models/object_manager/attribute.rb @@ -319,6 +319,7 @@ possible types if !force %i[name display data_type position active].each do |key| next if record[key] == data[key] + record[:data_option_new] = data[:data_option] if data[:data_option] # bring the data options over as well, when there are changes to the fields above data[:to_config] = true break @@ -491,9 +492,11 @@ returns: } if item.data_option[:permission]&.any? next if !user + hint = false item.data_option[:permission].each do |permission| next if !user.permissions?(permission) + hint = true break end @@ -584,6 +587,7 @@ returns def self.pending_migration? return false if migrations.blank? + true end @@ -802,6 +806,7 @@ where attributes are used by triggers, overviews or schedulers attribute_list[condition_key] ||= {} attribute_list[condition_key][item.class.name] ||= [] next if attribute_list[condition_key][item.class.name].include?(item.name) + attribute_list[condition_key][item.class.name].push item.name end end @@ -821,6 +826,7 @@ is certain attribute used by triggers, overviews or schedulers local_object, local_attribute = reference_key.split('.') next if local_object != object_name.downcase next if local_attribute != attribute_name + return true end false @@ -845,6 +851,7 @@ is certain attribute used by triggers, overviews or schedulers local_object, local_attribute = reference_key.split('.') next if local_object != object_name.downcase next if local_attribute != attribute_name + relations.each do |relation, relation_names| result[relation] ||= [] result[relation].push relation_names.sort @@ -909,11 +916,13 @@ is certain attribute used by triggers, overviews or schedulers return true if !record.respond_to?(name.to_sym) raise "#{name} already exists!" if record.attributes.key?(name) && new_record? return true if record.attributes.key?(name) + raise "#{name} is a reserved word, please choose a different one" end def check_editable return if editable + raise 'Attribute not editable!' end diff --git a/app/models/observer/chat/leave/background_job.rb b/app/models/observer/chat/leave/background_job.rb index 1a681eb38..666bb8ddd 100644 --- a/app/models/observer/chat/leave/background_job.rb +++ b/app/models/observer/chat/leave/background_job.rb @@ -11,6 +11,7 @@ class Observer::Chat::Leave::BackgroundJob chat_session = Chat::Session.find_by(id: @chat_session_id) return if !chat_session return if chat_session.recipients_active? + chat_session.state = 'closed' chat_session.save diff --git a/app/models/observer/sla/ticket_rebuild_escalation.rb b/app/models/observer/sla/ticket_rebuild_escalation.rb index 6c27cc206..eac8a6fea 100644 --- a/app/models/observer/sla/ticket_rebuild_escalation.rb +++ b/app/models/observer/sla/ticket_rebuild_escalation.rb @@ -32,6 +32,7 @@ class Observer::Sla::TicketRebuildEscalation < ActiveRecord::Observer fields_to_check.each do |item| next if !record.saved_change_to_attribute(item) next if record.saved_change_to_attribute(item)[0] == record.saved_change_to_attribute(item)[1] + changed = true end return true if !changed diff --git a/app/models/observer/ticket/article/communicate_email.rb b/app/models/observer/ticket/article/communicate_email.rb index a369706d7..7c5247c21 100644 --- a/app/models/observer/ticket/article/communicate_email.rb +++ b/app/models/observer/ticket/article/communicate_email.rb @@ -14,12 +14,14 @@ class Observer::Ticket::Article::CommunicateEmail < ActiveRecord::Observer # if sender is customer, do not communicate return if !record.sender_id + sender = Ticket::Article::Sender.lookup(id: record.sender_id) return 1 if sender.nil? return 1 if sender['name'] == 'Customer' # only apply on emails return if !record.type_id + type = Ticket::Article::Type.lookup(id: record.type_id) return if type['name'] != 'email' diff --git a/app/models/observer/ticket/article/communicate_email/background_job.rb b/app/models/observer/ticket/article/communicate_email/background_job.rb index 54114744c..1bd150eb4 100644 --- a/app/models/observer/ticket/article/communicate_email/background_job.rb +++ b/app/models/observer/ticket/article/communicate_email/background_job.rb @@ -174,6 +174,7 @@ class Observer::Ticket::Article::CommunicateEmail::BackgroundJob if Rails.env.production? return current_time + attempts * 25.seconds end + current_time + 5.seconds end end diff --git a/app/models/observer/ticket/article/communicate_facebook.rb b/app/models/observer/ticket/article/communicate_facebook.rb index 0eb4d60d4..6b1148c62 100644 --- a/app/models/observer/ticket/article/communicate_facebook.rb +++ b/app/models/observer/ticket/article/communicate_facebook.rb @@ -13,12 +13,14 @@ class Observer::Ticket::Article::CommunicateFacebook < ActiveRecord::Observer # if sender is customer, do not communicate return if !record.sender_id + sender = Ticket::Article::Sender.lookup(id: record.sender_id) return 1 if sender.nil? return 1 if sender['name'] == 'Customer' # only apply for facebook return if !record.type_id + type = Ticket::Article::Type.lookup(id: record.type_id) return if type['name'] !~ /\Afacebook/ diff --git a/app/models/observer/ticket/article/communicate_facebook/background_job.rb b/app/models/observer/ticket/article/communicate_facebook/background_job.rb index b3a268f86..598ca7348 100644 --- a/app/models/observer/ticket/article/communicate_facebook/background_job.rb +++ b/app/models/observer/ticket/article/communicate_facebook/background_job.rb @@ -99,6 +99,7 @@ class Observer::Ticket::Article::CommunicateFacebook::BackgroundJob if Rails.env.production? return current_time + attempts * 120.seconds end + current_time + 5.seconds end end diff --git a/app/models/observer/ticket/article/communicate_telegram.rb b/app/models/observer/ticket/article/communicate_telegram.rb index 9995763fb..5e43ab0fe 100644 --- a/app/models/observer/ticket/article/communicate_telegram.rb +++ b/app/models/observer/ticket/article/communicate_telegram.rb @@ -10,12 +10,14 @@ class Observer::Ticket::Article::CommunicateTelegram < ActiveRecord::Observer # if sender is customer, do not communicate return if !record.sender_id + sender = Ticket::Article::Sender.lookup(id: record.sender_id) return if sender.nil? return if sender['name'] == 'Customer' # only apply on telegram messages return if !record.type_id + type = Ticket::Article::Type.lookup(id: record.type_id) return if type['name'] !~ /\Atelegram/i diff --git a/app/models/observer/ticket/article/communicate_telegram/background_job.rb b/app/models/observer/ticket/article/communicate_telegram/background_job.rb index 9e1543cde..18e65bf06 100644 --- a/app/models/observer/ticket/article/communicate_telegram/background_job.rb +++ b/app/models/observer/ticket/article/communicate_telegram/background_job.rb @@ -120,6 +120,7 @@ class Observer::Ticket::Article::CommunicateTelegram::BackgroundJob if Rails.env.production? return current_time + attempts * 120.seconds end + current_time + 5.seconds end end diff --git a/app/models/observer/ticket/article/communicate_twitter.rb b/app/models/observer/ticket/article/communicate_twitter.rb index 311f48e04..d391993fd 100644 --- a/app/models/observer/ticket/article/communicate_twitter.rb +++ b/app/models/observer/ticket/article/communicate_twitter.rb @@ -14,16 +14,19 @@ class Observer::Ticket::Article::CommunicateTwitter < ActiveRecord::Observer # if sender is customer, do not communicate return if !record.sender_id + sender = Ticket::Article::Sender.lookup(id: record.sender_id) return if sender.nil? return if sender['name'] == 'Customer' # only apply on tweets return if !record.type_id + type = Ticket::Article::Type.lookup(id: record.type_id) return if type['name'] !~ /\Atwitter/i raise Exceptions::UnprocessableEntity, 'twitter to: parameter is missing' if record.to.blank? && type['name'] == 'twitter direct-message' + Delayed::Job.enqueue(Observer::Ticket::Article::CommunicateTwitter::BackgroundJob.new(record.id)) end diff --git a/app/models/observer/ticket/article/communicate_twitter/background_job.rb b/app/models/observer/ticket/article/communicate_twitter/background_job.rb index b7f3257b4..ee7b4b9d6 100644 --- a/app/models/observer/ticket/article/communicate_twitter/background_job.rb +++ b/app/models/observer/ticket/article/communicate_twitter/background_job.rb @@ -138,6 +138,7 @@ class Observer::Ticket::Article::CommunicateTwitter::BackgroundJob if Rails.env.production? return current_time + attempts * 120.seconds end + current_time + 5.seconds end end diff --git a/app/models/observer/ticket/article/fillup_from_email.rb b/app/models/observer/ticket/article/fillup_from_email.rb index 1a59bb69d..59d8095f0 100644 --- a/app/models/observer/ticket/article/fillup_from_email.rb +++ b/app/models/observer/ticket/article/fillup_from_email.rb @@ -14,12 +14,14 @@ class Observer::Ticket::Article::FillupFromEmail < ActiveRecord::Observer # if sender is customer, do not change anything return true if !record.sender_id + sender = Ticket::Article::Sender.lookup(id: record.sender_id) return true if sender.nil? return true if sender['name'] == 'Customer' # set email attributes return true if !record.type_id + type = Ticket::Article::Type.lookup(id: record.type_id) return true if type['name'] != 'email' diff --git a/app/models/observer/ticket/article/fillup_from_general.rb b/app/models/observer/ticket/article/fillup_from_general.rb index 7bd037fe4..fca6080ea 100644 --- a/app/models/observer/ticket/article/fillup_from_general.rb +++ b/app/models/observer/ticket/article/fillup_from_general.rb @@ -14,6 +14,7 @@ class Observer::Ticket::Article::FillupFromGeneral < ActiveRecord::Observer # set from on all article types excluding email|twitter status|twitter direct-message|facebook feed post|facebook feed comment return true if record.type_id.blank? + type = Ticket::Article::Type.lookup(id: record.type_id) return true if type['name'] == 'email' @@ -41,6 +42,7 @@ class Observer::Ticket::Article::FillupFromGeneral < ActiveRecord::Observer end end return true if user_id.blank? + user = User.find(user_id) if type.name == 'web' || type.name == 'phone' record.from = "#{user.firstname} #{user.lastname} <#{user.email}>" diff --git a/app/models/observer/ticket/article/fillup_from_origin_by_id.rb b/app/models/observer/ticket/article/fillup_from_origin_by_id.rb index 2e0690f9f..07ebd3fdd 100644 --- a/app/models/observer/ticket/article/fillup_from_origin_by_id.rb +++ b/app/models/observer/ticket/article/fillup_from_origin_by_id.rb @@ -16,6 +16,7 @@ class Observer::Ticket::Article::FillupFromOriginById < ActiveRecord::Observer return if record.origin_by_id.present? return if record.ticket.customer_id.blank? return if record.sender.name != 'Customer' + type_name = record.type.name return if type_name != 'phone' && type_name != 'note' && type_name != 'web' diff --git a/app/models/observer/ticket/article_changes.rb b/app/models/observer/ticket/article_changes.rb index 337611fbf..7fa1e1356 100644 --- a/app/models/observer/ticket/article_changes.rb +++ b/app/models/observer/ticket/article_changes.rb @@ -50,6 +50,7 @@ class Observer::Ticket::ArticleChanges < ActiveRecord::Observer sender = Ticket::Article::Sender.lookup(name: 'System') count = Ticket::Article.where(ticket_id: record.ticket_id).where('sender_id NOT IN (?)', sender.id).count return false if current_count == count + record.ticket.article_count = count true end diff --git a/app/models/observer/ticket/close_time.rb b/app/models/observer/ticket/close_time.rb index afb1ce845..2d884cfcb 100644 --- a/app/models/observer/ticket/close_time.rb +++ b/app/models/observer/ticket/close_time.rb @@ -23,6 +23,7 @@ class Observer::Ticket::CloseTime < ActiveRecord::Observer # check if ticket is closed now return true if !record.state_id + state = Ticket::State.lookup(id: record.state_id) state_type = Ticket::StateType.lookup(id: state.state_type_id) return true if state_type.name != 'closed' diff --git a/app/models/observer/ticket/escalation_update.rb b/app/models/observer/ticket/escalation_update.rb index 9de4d5877..b8bc039c3 100644 --- a/app/models/observer/ticket/escalation_update.rb +++ b/app/models/observer/ticket/escalation_update.rb @@ -15,6 +15,7 @@ class Observer::Ticket::EscalationUpdate < ActiveRecord::Observer return true if Setting.get('import_mode') return true if !Ticket.exists?(record.id) + record.reload record.escalation_calculation end diff --git a/app/models/observer/ticket/last_owner_update.rb b/app/models/observer/ticket/last_owner_update.rb index 4d081b05b..867adc0b5 100644 --- a/app/models/observer/ticket/last_owner_update.rb +++ b/app/models/observer/ticket/last_owner_update.rb @@ -31,6 +31,7 @@ class Observer::Ticket::LastOwnerUpdate < ActiveRecord::Observer if record.changes_to_save['group_id'].present? group = Group.lookup(id: record.changes_to_save['group_id'][1]) return true if !group + if group.assignment_timeout.blank? || group.assignment_timeout.zero? record.last_owner_update_at = nil return true diff --git a/app/models/observer/ticket/online_notification_seen/background_job.rb b/app/models/observer/ticket/online_notification_seen/background_job.rb index 43e3542b8..d79bda580 100644 --- a/app/models/observer/ticket/online_notification_seen/background_job.rb +++ b/app/models/observer/ticket/online_notification_seen/background_job.rb @@ -11,9 +11,11 @@ class Observer::Ticket::OnlineNotificationSeen::BackgroundJob ticket = Ticket.lookup(id: @ticket_id) OnlineNotification.list_by_object('Ticket', @ticket_id).each do |notification| next if notification.seen + seen = ticket.online_notification_seen_state(notification.user_id) next if !seen next if seen == notification.seen + notification.seen = true notification.updated_by_id = @user_id notification.save! diff --git a/app/models/observer/ticket/reset_new_state.rb b/app/models/observer/ticket/reset_new_state.rb index 8caa211cc..37ea9315b 100644 --- a/app/models/observer/ticket/reset_new_state.rb +++ b/app/models/observer/ticket/reset_new_state.rb @@ -23,6 +23,7 @@ class Observer::Ticket::ResetNewState < ActiveRecord::Observer # if current ticket state is still new ticket = Ticket.find_by(id: record.ticket_id) return true if !ticket + new_state = Ticket::State.find_by(default_create: true) return true if ticket.state_id != new_state.id diff --git a/app/models/observer/ticket/stats_reopen.rb b/app/models/observer/ticket/stats_reopen.rb index cead581d3..45e441400 100644 --- a/app/models/observer/ticket/stats_reopen.rb +++ b/app/models/observer/ticket/stats_reopen.rb @@ -20,6 +20,7 @@ class Observer::Ticket::StatsReopen < ActiveRecord::Observer # return if we run import mode return if Setting.get('import_mode') + Stats::TicketReopen.log('Ticket', record.id, record.saved_changes, record.updated_by_id) end end diff --git a/app/models/observer/ticket/user_ticket_counter/background_job.rb b/app/models/observer/ticket/user_ticket_counter/background_job.rb index de2ffadf1..b24f88398 100644 --- a/app/models/observer/ticket/user_ticket_counter/background_job.rb +++ b/app/models/observer/ticket/user_ticket_counter/background_job.rb @@ -27,6 +27,7 @@ class Observer::Ticket::UserTicketCounter::BackgroundJob # check if update is needed customer = User.lookup(id: @customer_id) return true if !customer + need_update = false if customer[:preferences][:tickets_open] != tickets_open need_update = true @@ -38,6 +39,7 @@ class Observer::Ticket::UserTicketCounter::BackgroundJob end return true if !need_update + customer.updated_by_id = @updated_by_id customer.save end diff --git a/app/models/observer/transaction.rb b/app/models/observer/transaction.rb index 648e1ee7d..d1ab877b7 100644 --- a/app/models/observer/transaction.rb +++ b/app/models/observer/transaction.rb @@ -34,6 +34,7 @@ class Observer::Transaction < ActiveRecord::Observer Setting.where(area: 'Transaction::Backend::Sync').order(:name).each do |setting| backend = Setting.get(setting.name) next if params[:disable]&.include?(backend) + sync_backends.push Kernel.const_get(backend) end @@ -211,6 +212,7 @@ class Observer::Transaction < ActiveRecord::Observer next if key == 'article_count' next if key == 'create_article_type_id' next if key == 'create_article_sender_id' + real_changes[key] = value end diff --git a/app/models/observer/user/geo.rb b/app/models/observer/user/geo.rb index 8cb6b9a68..24f210e72 100644 --- a/app/models/observer/user/geo.rb +++ b/app/models/observer/user/geo.rb @@ -48,6 +48,7 @@ class Observer::User::Geo < ActiveRecord::Observer location = %w[address street zip city country] location.each do |item| next if record[item].blank? + if address.present? address += ', ' end diff --git a/app/models/observer/user/ref_object_touch.rb b/app/models/observer/user/ref_object_touch.rb index 07a380ec7..68f323f11 100644 --- a/app/models/observer/user/ref_object_touch.rb +++ b/app/models/observer/user/ref_object_touch.rb @@ -48,6 +48,7 @@ class Observer::User::RefObjectTouch < ActiveRecord::Observer # touch old/current customer member_ids.uniq.each do |user_id| next if user_id == record.id + User.find(user_id).touch # rubocop:disable Rails/SkipsModelValidations end true diff --git a/app/models/online_notification.rb b/app/models/online_notification.rb index 56c5eeaf7..0192ebfaf 100644 --- a/app/models/online_notification.rb +++ b/app/models/online_notification.rb @@ -216,6 +216,7 @@ returns: next if notification.type_lookup_id != type_id next if notification.created_by_id != created_by_user.id next if notification.seen != seen + return true end false diff --git a/app/models/online_notification/assets.rb b/app/models/online_notification/assets.rb index b803ca668..797bd04b8 100644 --- a/app/models/online_notification/assets.rb +++ b/app/models/online_notification/assets.rb @@ -43,12 +43,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 diff --git a/app/models/organization.rb b/app/models/organization.rb index 3c2f8c45a..d772fea1b 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -13,9 +13,7 @@ class Organization < ApplicationModel include Organization::Search include Organization::SearchIndex - # rubocop:disable Rails/InverseOf has_many :members, class_name: 'User' - # rubocop:enable Rails/InverseOf before_create :domain_cleanup before_update :domain_cleanup @@ -28,6 +26,7 @@ class Organization < ApplicationModel def domain_cleanup return true if domain.blank? + domain.gsub!(/@/, '') domain.gsub!(/\s*/, '') domain.strip! diff --git a/app/models/organization/assets.rb b/app/models/organization/assets.rb index 71b438387..51dc06afb 100644 --- a/app/models/organization/assets.rb +++ b/app/models/organization/assets.rb @@ -48,8 +48,10 @@ returns end local_attributes['member_ids'].each do |local_user_id| next if data[ app_model_user ] && data[ app_model_user ][ local_user_id ] + user = User.lookup(id: local_user_id) next if !user + data = user.assets(data) end end @@ -59,8 +61,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 ][ self[ local_user_id ] ] + user = User.lookup(id: self[ local_user_id ]) next if !user + data = user.assets(data) end data diff --git a/app/models/organization/checks_access.rb b/app/models/organization/checks_access.rb index 33c17d489..b1b9e30c7 100644 --- a/app/models/organization/checks_access.rb +++ b/app/models/organization/checks_access.rb @@ -21,12 +21,14 @@ class Organization # access ok if its own organization return false if access != 'read' return false if !user.organization_id + return id == user.organization_id end # check agent return true if user.permissions?('admin') return true if user.permissions?('ticket.agent') + false end @@ -42,6 +44,7 @@ class Organization # @return [nil] def access!(user, access) return if access?(user, access) + raise Exceptions::NotAuthorized end end diff --git a/app/models/organization/search.rb b/app/models/organization/search.rb index dd117492b..c266993f8 100644 --- a/app/models/organization/search.rb +++ b/app/models/organization/search.rb @@ -32,6 +32,7 @@ returns if user has no permissions to search def search_preferences(current_user) return false if !current_user.permissions?('ticket.agent') && !current_user.permissions?('admin.organization') + { prio: 1000, direct_search_index: true, @@ -87,6 +88,7 @@ returns items.each do |item| organization = Organization.lookup(id: item[:id]) next if !organization + organizations.push organization end return organizations @@ -121,12 +123,14 @@ returns organization_exists = false organizations.each do |organization| next if organization.id != organization_by_user.id + organization_exists = true break end # get model with full data next if organization_exists + organizations.push Organization.find(organization_by_user.id) end organizations diff --git a/app/models/overview.rb b/app/models/overview.rb index 8740f7b87..7e4d285bb 100644 --- a/app/models/overview.rb +++ b/app/models/overview.rb @@ -62,6 +62,7 @@ class Overview < ApplicationModel def fill_prio return true if prio.present? + self.prio = Overview.count + 1 true end @@ -77,6 +78,7 @@ class Overview < ApplicationModel def fill_link_on_update return true if !changes['name'] && !changes['link'] + self.link = if link.present? link_name(link) else diff --git a/app/models/overview/assets.rb b/app/models/overview/assets.rb index f18830140..ef8826cc2 100644 --- a/app/models/overview/assets.rb +++ b/app/models/overview/assets.rb @@ -37,8 +37,10 @@ returns data[ app_model_overview ][ id ] = attributes_with_association_ids user_ids&.each do |local_user_id| next if data[ app_model_user ][ local_user_id ] + user = User.lookup(id: local_user_id) next if !user + data = user.assets(data) end data = assets_of_selector('condition', data) @@ -46,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 ][ self[ local_user_id ] ] + user = User.lookup(id: self[ local_user_id ]) next if !user + data = user.assets(data) end data diff --git a/app/models/package.rb b/app/models/package.rb index 57952f111..6735cdab3 100644 --- a/app/models/package.rb +++ b/app/models/package.rb @@ -41,10 +41,12 @@ returns: content_package = Base64.decode64(file['content']) content_fs = self.class._read_file(file['location']) next if content_package == content_fs + logger.error "File #{file['location']} is different" issues[file['location']] = 'changed' end return nil if issues.blank? + issues end @@ -59,6 +61,7 @@ install all packages located under auto_install/*.zpm def self.auto_install path = "#{@@root}/auto_install/" return if !File.exist?(path) + data = [] Dir.foreach(path) do |entry| if entry =~ /\.zpm/ && entry !~ /^\./ @@ -105,6 +108,7 @@ note: will not take down package migrations, use Package.unlink instead if package == false raise "Can't link package, '#{package_base_dir}' is no package source directory!" end + logger.debug { package.inspect } package end @@ -186,6 +190,7 @@ link files + execute migration up if File.exist?(backup_file) raise "Can't link #{entry} -> #{dest}, destination and .link_backup already exists!" end + logger.info "Create backup file of #{dest} -> #{backup_file}." File.rename(dest.to_s, backup_file) end @@ -307,6 +312,7 @@ returns if !package raise "No such package '#{package_name}'" end + file = _get_bin(package.name, package.version) install(string: file, reinstall: true) package @@ -384,6 +390,7 @@ execute all pending package migrations at once if !package raise "No such package '#{name}' version '#{version}'" end + list = Store.list( object: 'Package', o_id: package.id, @@ -396,6 +403,7 @@ execute all pending package migrations at once if !list.first.content raise "No such file in storage #{name} #{version}" end + list.first.content end @@ -496,6 +504,7 @@ execute all pending package migrations at once location = "#{root}/db/addon/#{package.underscore}" return true if !File.exist?(location) + migrations_done = Package::Migration.where(name: package.underscore) # get existing migrations @@ -503,6 +512,7 @@ execute all pending package migrations at once Dir.foreach(location) do |entry| next if entry == '.' next if entry == '..' + migrations_existing.push entry end @@ -516,6 +526,7 @@ execute all pending package migrations at once migrations_existing.each do |migration| next if migration !~ /\.rb$/ + version = nil name = nil if migration =~ /^(.+?)_(.*)\.rb$/ @@ -530,6 +541,7 @@ execute all pending package migrations at once done = Package::Migration.find_by(name: package.underscore, version: version) if direction == 'reverse' next if !done + logger.info "NOTICE: down package migration '#{migration}'" load "#{location}/#{migration}" classname = name.camelcase @@ -540,6 +552,7 @@ execute all pending package migrations at once # up else next if done + logger.info "NOTICE: up package migration '#{migration}'" load "#{location}/#{migration}" classname = name.camelcase diff --git a/app/models/postmaster_filter.rb b/app/models/postmaster_filter.rb index 172cb32f0..da110f1a4 100644 --- a/app/models/postmaster_filter.rb +++ b/app/models/postmaster_filter.rb @@ -10,9 +10,11 @@ class PostmasterFilter < ApplicationModel def validate_condition raise Exceptions::UnprocessableEntity, 'Min. one match rule needed!' if match.blank? + match.each_value do |meta| raise Exceptions::UnprocessableEntity, 'operator invalid, ony "contains" and "contains not" is supported' if meta['operator'].blank? || meta['operator'] !~ /^(contains|contains not)$/ raise Exceptions::UnprocessableEntity, 'value invalid/empty' if meta['value'].blank? + begin Channel::Filter::Match::EmailRegex.match(value: 'test content', match_rule: meta['value'], check_mode: true) rescue => e diff --git a/app/models/recent_view/assets.rb b/app/models/recent_view/assets.rb index 7e1cca223..7cb120708 100644 --- a/app/models/recent_view/assets.rb +++ b/app/models/recent_view/assets.rb @@ -42,12 +42,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 diff --git a/app/models/role.rb b/app/models/role.rb index 48b18bcba..013060c81 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -34,6 +34,7 @@ grant permission to role permission = Permission.lookup(name: key) raise "Invalid permission #{key}" if !permission return true if permission_ids.include?(permission.id) + self.permission_ids = permission_ids.push permission.id true end @@ -50,6 +51,7 @@ revoke permission of role permission = Permission.lookup(name: key) raise "Invalid permission #{key}" if !permission return true if !permission_ids.include?(permission.id) + self.permission_ids = self.permission_ids -= [permission.id] true end @@ -131,16 +133,16 @@ returns return true if Role.joins(:roles_permissions).joins(:permissions).where( 'roles.id = ? AND permissions_roles.permission_id IN (?) AND permissions.active = ?', id, permission_ids, true ).distinct().count.nonzero? + false end - private_class_method - def self.permission_ids_by_name(keys) Array(keys).each_with_object([]) do |key, result| ::Permission.with_parents(key).each do |local_key| permission = ::Permission.lookup(name: local_key) next if !permission + result.push permission.id end end @@ -151,11 +153,13 @@ returns def validate_permissions Rails.logger.debug { "self permission: #{self.permission_ids}" } return true if !self.permission_ids + permission_ids.each do |permission_id| permission = Permission.lookup(id: permission_id) raise "Unable to find permission for id #{permission_id}" if !permission raise "Permission #{permission.name} is disabled" if permission.preferences[:disabled] == true next if !permission.preferences[:not] + permission.preferences[:not].each do |local_permission_name| local_permission = Permission.lookup(name: local_permission_name) next if !local_permission @@ -170,6 +174,7 @@ returns return true if active != false return true if !with_permission?(['admin', 'admin.user']) raise Exceptions::UnprocessableEntity, 'Minimum one user needs to have admin permissions.' if last_admin_check_admin_count < 1 + true end @@ -177,6 +182,7 @@ returns return true if Setting.get('import_mode') return true if permission.name != 'admin' && permission.name != 'admin.user' raise Exceptions::UnprocessableEntity, 'Minimum one user needs to have admin permissions.' if last_admin_check_admin_count < 1 + true end @@ -190,11 +196,13 @@ returns return true if !will_save_change_to_attribute?('active') return true if active != true return true if !with_permission?('ticket.agent') + ticket_agent_role_ids = Role.joins(:permissions).where(permissions: { name: 'ticket.agent', active: true }, roles: { active: true }).pluck(:id) currents = User.joins(:roles).where(roles: { id: ticket_agent_role_ids }, users: { active: true }).distinct().pluck(:id) news = User.joins(:roles).where(roles: { id: id }, users: { active: true }).distinct().pluck(:id) count = currents.concat(news).uniq.count raise Exceptions::UnprocessableEntity, 'Agent limit exceeded, please check your account settings.' if count > Setting.get('system_agent_limit').to_i + true end @@ -203,10 +211,12 @@ returns return true if active != true return true if permission.active != true return true if permission.name != 'ticket.agent' + ticket_agent_role_ids = Role.joins(:permissions).where(permissions: { name: 'ticket.agent' }, roles: { active: true }).pluck(:id) ticket_agent_role_ids.push(id) count = User.joins(:roles).where(roles: { id: ticket_agent_role_ids }, users: { active: true }).distinct().count raise Exceptions::UnprocessableEntity, 'Agent limit exceeded, please check your account settings.' if count > Setting.get('system_agent_limit').to_i + true end @@ -216,6 +226,7 @@ returns normal_permissions = (all_permissions - admin_permissions) | (admin_permissions - all_permissions) # all other permissions besides admin.*/ticket.agent return true if default_at_signup != true # means if default_at_signup = false, no need further checks return true if self.permission_ids.all? { |i| normal_permissions.include? i } # allow user to choose only normal permissions + raise Exceptions::UnprocessableEntity, 'Cannot set default at signup when role has admin or ticket.agent permissions.' end diff --git a/app/models/role/assets.rb b/app/models/role/assets.rb index c7634ca06..ad4ef97e4 100644 --- a/app/models/role/assets.rb +++ b/app/models/role/assets.rb @@ -38,19 +38,24 @@ returns local_attributes['group_ids'].each_key do |group_id| next if data[:Group] && data[:Group][group_id] + group = Group.lookup(id: group_id) next if !group + data = group.assets(data) end 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 diff --git a/app/models/setting.rb b/app/models/setting.rb index cf06b283e..ec5853707 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -36,6 +36,7 @@ set config setting if !setting raise "Can't find config setting '#{name}'" end + setting.state_current = { value: value } setting.save! logger.info "Setting.set('#{name}', #{value.inspect})" @@ -70,6 +71,7 @@ reset config setting to default raise "Can't find config setting '#{name}'" end return true if !force && setting.state_current == setting.state_initial + setting.state_current = setting.state_initial setting.save! logger.info "Setting.reset('#{name}', #{setting.state_current.inspect})" @@ -149,6 +151,7 @@ reload config settings #logger.debug "Setting.cache_valid?: cache_id has been set within last #{@@lookup_timeout} seconds" return true end + change_id = Cache.get('Setting::ChangeId') if @@change_id && change_id == @@change_id @@lookup_at = Time.zone.now # rubocop:disable Style/ClassVars @@ -164,6 +167,7 @@ reload config settings def state_check return true if !state return true if state.try(:key?, :value) + self.state_current = { value: state } true end @@ -171,6 +175,7 @@ reload config settings # notify clients about public config changes def check_broadcast return true if frontend != true + value = state_current if state_current.key?(:value) value = state_current[:value] diff --git a/app/models/sla/assets.rb b/app/models/sla/assets.rb index c0185bf19..341451074 100644 --- a/app/models/sla/assets.rb +++ b/app/models/sla/assets.rb @@ -46,8 +46,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 ][ self[ local_user_id ] ] + user = User.lookup(id: self[ local_user_id ]) next if !user + data = user.assets(data) end data diff --git a/app/models/stats_store/search_index.rb b/app/models/stats_store/search_index.rb index 34a9faa90..73600834f 100644 --- a/app/models/stats_store/search_index.rb +++ b/app/models/stats_store/search_index.rb @@ -7,8 +7,10 @@ module StatsStore::SearchIndex begin return if !Kernel.const_get(attributes['stats_store_object']) + record = Kernel.const_get(attributes['stats_store_object']).lookup(id: o_id) return if !record + attributes['stats_store_object_ref'] = record.search_index_attribute_lookup rescue return diff --git a/app/models/store.rb b/app/models/store.rb index 516f06588..5a79c1966 100644 --- a/app/models/store.rb +++ b/app/models/store.rb @@ -5,10 +5,8 @@ require_dependency 'store/file' class Store < ApplicationModel - # rubocop:disable Rails/InverseOf belongs_to :store_object, class_name: 'Store::Object' belongs_to :store_file, class_name: 'Store::File' - # rubocop:enable Rails/InverseOf validates :filename, presence: true @@ -161,6 +159,7 @@ returns if !file raise "No such file #{store_file_id}!" end + file.content end @@ -183,6 +182,7 @@ returns if !file raise "No such file #{store_file_id}!" end + if !path path = Rails.root.join('tmp', filename) end @@ -201,6 +201,7 @@ returns if !file raise "No such file #{store_file_id}!" end + file.provider end end diff --git a/app/models/store/file.rb b/app/models/store/file.rb index a9f0eb234..db8bbfaf6 100644 --- a/app/models/store/file.rb +++ b/app/models/store/file.rb @@ -28,6 +28,7 @@ do also verify of written data if !adapter_name raise 'Missing storage_provider setting option' end + adapter = load_adapter("Store::Provider::#{adapter_name}") adapter.add(data, sha) file = Store::File.create( @@ -85,6 +86,7 @@ in case of fixing sha hash use: sha = Digest::SHA256.hexdigest(content) logger.info "CHECK: Store::File.find(#{item.id})" next if sha == item.sha + success = false logger.error "DIFF: sha diff of Store::File.find(#{item.id}) current:#{sha}/db:#{item.sha}/provider:#{item.provider}" store = Store.find_by(store_file_id: item.id) @@ -122,6 +124,7 @@ nice move to keep system responsive file_ids.each do |item_id| item = Store::File.find(item_id) next if item.provider == target + content = item.content # add to new provider diff --git a/app/models/store/provider/db.rb b/app/models/store/provider/db.rb index c532b75e3..a47db5b52 100644 --- a/app/models/store/provider/db.rb +++ b/app/models/store/provider/db.rb @@ -16,6 +16,7 @@ class Store def self.get(sha) file = Store::Provider::DB.find_by(sha: sha) return if !file + file.data end diff --git a/app/models/store/provider/file.rb b/app/models/store/provider/file.rb index 153872441..6e3866394 100644 --- a/app/models/store/provider/file.rb +++ b/app/models/store/provider/file.rb @@ -42,6 +42,7 @@ class Store::Provider::File if !File.exist?(location) raise "ERROR: No such file #{location}" end + data = File.open(location, 'rb') content = data.read @@ -50,6 +51,7 @@ class Store::Provider::File if local_sha != sha raise "ERROR: Corrupt file in fs #{location}, sha should be #{sha} but is #{local_sha}" end + content end @@ -67,6 +69,7 @@ class Store::Provider::File local_location = locations[0, count].join('/') break if local_location.match?(%r{storage/fs/{0,4}$}) break if Dir["#{local_location}/*"].present? + FileUtils.rmdir(local_location) end end diff --git a/app/models/tag.rb b/app/models/tag.rb index b885763ab..7805c747a 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -2,10 +2,8 @@ class Tag < ApplicationModel - # rubocop:disable Rails/InverseOf belongs_to :tag_object, class_name: 'Tag::Object' belongs_to :tag_item, class_name: 'Tag::Item' - # rubocop:enable Rails/InverseOf # the noop is needed since Layout/EmptyLines detects # the block commend below wrongly as the measurement of @@ -158,6 +156,7 @@ returns tag_search.each_with_object([]) do |tag, result| tag_item = Tag::Item.lookup(id: tag.tag_item_id) next if !tag_item + result.push tag_item.name end end @@ -338,6 +337,7 @@ remove tag item (destroy with reverences) hash.each do |key, condition| next if %w[ticket.tags x-zammad-ticket-tags].exclude? key next if condition[:value].split(', ').exclude? old_name + condition[:value] = update_name(condition[:value], old_name, new_name) changed = true end @@ -347,6 +347,7 @@ remove tag item (destroy with reverences) def self.update_name(condition, old_name, new_name) tags = condition.split(', ') return new_name if tags.size == 1 + tags = tags.map { |t| t == old_name ? new_name : t } tags.join(', ') end diff --git a/app/models/taskbar.rb b/app/models/taskbar.rb index b96f2d441..0826c8b7a 100644 --- a/app/models/taskbar.rb +++ b/app/models/taskbar.rb @@ -14,15 +14,18 @@ class Taskbar < ApplicationModel def state_changed? return false if state.blank? + state.each_value do |value| if value.is_a? Hash value.each do |key1, value1| next if value1.blank? next if key1 == 'form_id' + return true end else next if value.blank? + return true end end @@ -63,11 +66,13 @@ class Taskbar < ApplicationModel def update_last_contact return true if local_update return true if changes.blank? + if changes['notify'] count = 0 changes.each_key do |attribute| next if attribute == 'updated_at' next if attribute == 'created_at' + count += 1 end return true if count <= 1 @@ -78,6 +83,7 @@ class Taskbar < ApplicationModel def set_user return true if local_update return true if !UserInfo.current_user_id + self.user_id = UserInfo.current_user_id end @@ -118,6 +124,7 @@ class Taskbar < ApplicationModel # update other taskbars Taskbar.where(key: key).order(:created_at, :id).each do |taskbar| next if taskbar.id == id + taskbar.with_lock do taskbar.preferences = preferences taskbar.local_update = true @@ -135,6 +142,7 @@ class Taskbar < ApplicationModel def notify_clients return true if !saved_change_to_attribute?('preferences') + data = { event: 'taskbar:preferences', data: { diff --git a/app/models/text_module.rb b/app/models/text_module.rb index 1e4d69d7a..06c80c4b4 100644 --- a/app/models/text_module.rb +++ b/app/models/text_module.rb @@ -25,6 +25,7 @@ load text modules from online def self.load(locale, overwrite_existing_item = false) raise 'Got no locale' if locale.blank? + locale = locale.split(',').first.downcase # in case of accept_language header is given url = "https://i18n.zammad.com/api/v1/text_modules/#{locale}" @@ -44,6 +45,7 @@ load text modules from online exists = TextModule.find_by(foreign_id: text_module['foreign_id']) if exists next if !overwrite_existing_item + exists.update!(text_module.symbolize_keys!) else text_module[:updated_by_id] = 1 @@ -70,6 +72,7 @@ push text_modules to online text_modules_to_push = [] text_modules.each do |text_module| next if !text_module.active + text_modules_to_push.push text_module end @@ -108,6 +111,7 @@ push text_modules to online def validate_content return true if content.blank? return true if content.match?(/<.+?>/) + content.gsub!(/(\r\n|\n\r|\r)/, "\n") self.content = content.text2html true diff --git a/app/models/ticket.rb b/app/models/ticket.rb index 3fb95b8ae..b88198ddd 100644 --- a/app/models/ticket.rb +++ b/app/models/ticket.rb @@ -57,17 +57,14 @@ class Ticket < ApplicationModel belongs_to :organization has_many :articles, class_name: 'Ticket::Article', after_add: :cache_update, after_remove: :cache_update, dependent: :destroy, inverse_of: :ticket has_many :ticket_time_accounting, class_name: 'Ticket::TimeAccounting', dependent: :destroy, inverse_of: :ticket - - # rubocop:disable Rails/InverseOf - belongs_to :state, class_name: 'Ticket::State' - belongs_to :priority, class_name: 'Ticket::Priority' - belongs_to :owner, class_name: 'User' - belongs_to :customer, class_name: 'User' - belongs_to :created_by, class_name: 'User' - belongs_to :updated_by, class_name: 'User' - belongs_to :create_article_type, class_name: 'Ticket::Article::Type' - belongs_to :create_article_sender, class_name: 'Ticket::Article::Sender' - # rubocop:enable Rails/InverseOf + belongs_to :state, class_name: 'Ticket::State' + belongs_to :priority, class_name: 'Ticket::Priority' + belongs_to :owner, class_name: 'User' + belongs_to :customer, class_name: 'User' + belongs_to :created_by, class_name: 'User' + belongs_to :updated_by, class_name: 'User' + belongs_to :create_article_type, class_name: 'Ticket::Article::Type' + belongs_to :create_article_sender, class_name: 'Ticket::Article::Sender' self.inheritance_column = nil @@ -244,17 +241,22 @@ returns # process pending action tickets state_ids = Ticket::State.by_category(:work_on).pluck(:id) return [] if state_ids.blank? + result = [] groups = Group.where(active: true).where('assignment_timeout IS NOT NULL AND groups.assignment_timeout != 0') return [] if groups.blank? + groups.each do |group| next if group.assignment_timeout.blank? + ticket_ids = Ticket.where('state_id IN (?) AND owner_id != 1 AND group_id = ? AND last_owner_update_at IS NOT NULL', state_ids, group.id).limit(600).pluck(:id) ticket_ids.each do |ticket_id| ticket = Ticket.find_by(id: ticket_id) next if !ticket + minutes_since_last_assignment = Time.zone.now - ticket.last_owner_update_at next if (minutes_since_last_assignment / 60) <= group.assignment_timeout + Transaction.execute do ticket.owner_id = 1 ticket.updated_at = Time.zone.now @@ -397,6 +399,7 @@ returns if user_id_check return false if owner_id == 1 return false if updated_by_id != owner_id && user_id_check == owner_id + return true end return true @@ -405,6 +408,7 @@ returns # set all to seen if new state is a closed or merged state return true if state_type.name == 'closed' return true if state_type.name == 'merged' + false end @@ -418,6 +422,7 @@ get count of tickets and tickets which match on selector def self.selectors(selectors, limit = 10, current_user = nil, access = 'full') raise 'no selectors given' if !selectors + query, bind_params, tables = selector2sql(selectors, current_user) return [] if !query @@ -513,6 +518,7 @@ condition example next if !selector[1] next if selector[0] == 'ticket' next if tables.include?(selector[0]) + if query != '' query += ' AND ' end @@ -542,6 +548,7 @@ condition example # validation raise "Invalid selector #{selector_raw.inspect}" if !selector_raw raise "Invalid selector #{selector_raw.inspect}" if !selector_raw.respond_to?(:key?) + selector = selector_raw.stringify_keys raise "Invalid selector, operator missing #{selector.inspect}" if !selector['operator'] raise "Invalid selector, operator #{selector['operator']} is invalid #{selector.inspect}" if selector['operator'] !~ /^(is|is\snot|contains|contains\s(not|all|one|all\snot|one\snot)|(after|before)\s\(absolute\)|(within\snext|within\slast|after|before)\s\(relative\))$/ @@ -585,6 +592,7 @@ condition example end elsif selector['pre_condition'] == 'current_user.id' raise "Use current_user.id in selector, but no current_user is set #{selector.inspect}" if !current_user_id + query += "#{attribute} IN (?)" if attributes[1] == 'out_of_office_replacement_id' bind_params.push User.find(current_user_id).out_of_office_agent_of.pluck(:id) @@ -593,6 +601,7 @@ condition example end elsif selector['pre_condition'] == 'current_user.organization_id' raise "Use current_user.id in selector, but no current_user is set #{selector.inspect}" if !current_user_id + query += "#{attribute} IN (?)" user = User.find_by(id: current_user_id) bind_params.push user.organization_id @@ -858,6 +867,7 @@ perform changes on ticket # update tags if key == 'ticket.tags' next if value['value'].blank? + tags = value['value'].split(/,/) if value['operator'] == 'add' tags.each do |tag| @@ -877,6 +887,7 @@ perform changes on ticket if key == 'ticket.action' next if value['value'].blank? next if value['value'] != 'delete' + logger.debug { "Deleted ticket from #{perform_origin} #{perform.inspect} Ticket.find(#{id})" } destroy! next @@ -888,12 +899,14 @@ perform changes on ticket value['value'] = 1 elsif value['pre_condition'].match?(/^current_user\./) raise 'Unable to use current_user, got no current_user_id for ticket.perform_changes' if !current_user_id + value['value'] = current_user_id end end # update ticket next if self[attribute].to_s == value['value'].to_s + changed = true self[attribute] = value['value'] @@ -959,8 +972,10 @@ perform changes on ticket users.each do |user| next if user.preferences[:mail_delivery_failed] != true next if !user.preferences[:mail_delivery_failed_data] + till_blocked = ((user.preferences[:mail_delivery_failed_data] - Time.zone.now - 60.days) / 60 / 60 / 24).round next if till_blocked.positive? + logger.info "Send no trigger based notification to #{recipient_email} because email is marked as mail_delivery_failed for #{till_blocked} days" skip_user = true break @@ -982,6 +997,7 @@ perform changes on ticket if recipient_email !~ /^(.+?)<(.+?)@(.+?)>$/ next # no usable format found end + recipient_email = "#{$2}@#{$3}" end next if recipient_email.blank? @@ -1021,11 +1037,13 @@ perform changes on ticket type: Ticket::Article::Type.find_by(name: 'email'), ).where('ticket_articles.created_at > ? AND ticket_articles.to LIKE ?', Time.zone.now - minutes.minutes, "%#{recipient_email.strip}%").count next if already_sent < count + logger.info "Send no trigger based notification to #{recipient_email} because already sent #{count} for this ticket within last #{minutes} minutes (loop protection)" skip = true break end next if skip + map = { 10 => 30, 30 => 60, @@ -1040,6 +1058,7 @@ perform changes on ticket type: Ticket::Article::Type.find_by(name: 'email'), ).where('ticket_articles.created_at > ? AND ticket_articles.to LIKE ?', Time.zone.now - minutes.minutes, "%#{recipient_email.strip}%").count next if already_sent < count + logger.info "Send no trigger based notification to #{recipient_email} because already sent #{count} in total within last #{minutes} minutes (loop protection)" skip = true break @@ -1048,14 +1067,17 @@ perform changes on ticket email = recipient_email.downcase.strip next if recipients_checked.include?(email) + recipients_checked.push(email) end return if recipients_checked.blank? + recipient_string = recipients_checked.join(', ') group_id = self.group_id return if !group_id + email_address = Group.find(group_id).email_address if !email_address logger.info "Unable to send trigger based notification to #{recipient_string} because no email address is set for group '#{group.name}'" @@ -1180,6 +1202,7 @@ perform active triggers on ticket (object_name, attribute) = key.split('.', 2) next if object_name != 'article' next if attribute == 'id' + article_selector = true end if article && article_selector @@ -1201,6 +1224,7 @@ perform active triggers on ticket next if object_name != 'ticket' next if item[:changes].blank? next if !item[:changes].key?(attribute) + condition.delete(key) one_has_changed_done = true end @@ -1210,6 +1234,7 @@ perform active triggers on ticket next if value.blank? next if value['operator'].blank? next if !value['operator']['has changed'] + has_changed_done = false break end @@ -1218,6 +1243,7 @@ perform active triggers on ticket if condition['ticket.action'] next if condition['ticket.action']['operator'] == 'is' && condition['ticket.action']['value'] != type next if condition['ticket.action']['operator'] != 'is' && condition['ticket.action']['value'] == type + condition.delete('ticket.action') end next if !has_changed_done @@ -1230,9 +1256,11 @@ perform active triggers on ticket condition.each_key do |key| (object_name, attribute) = key.split('.', 2) next if object_name != 'ticket' + one_has_changed_condition = true next if item[:changes].blank? next if !item[:changes].key?(attribute) + one_has_changed_done = true break end @@ -1260,6 +1288,7 @@ perform active triggers on ticket next if ticket_count.blank? next if ticket_count.zero? next if tickets.first.id != ticket.id + user_id = ticket.updated_by_id if article user_id = article.updated_by_id @@ -1326,6 +1355,7 @@ result references.push article.in_reply_to end next if article.message_id.blank? + references.push article.message_id end ignore.each do |item| @@ -1375,12 +1405,14 @@ result def check_generate return true if number + self.number = Ticket::Number.generate true end def check_title return true if !title + title.gsub!(/\s|\t|\r/, ' ') true end @@ -1390,9 +1422,11 @@ result self.owner_id = 1 end return true if !customer_id + customer = User.find_by(id: customer_id) return true if !customer return true if organization_id == customer.organization_id + self.organization_id = customer.organization_id true end @@ -1412,22 +1446,27 @@ result # in case, set pending_time to nil return true if current_state_type.name.match?(/^pending/i) + self.pending_time = nil true end def set_default_state return true if state_id + default_ticket_state = Ticket::State.find_by(default_create: true) return true if !default_ticket_state + self.state_id = default_ticket_state.id true end def set_default_priority return true if priority_id + default_ticket_priority = Ticket::Priority.find_by(default_create: true) return true if !default_ticket_priority + self.priority_id = default_ticket_priority.id true end diff --git a/app/models/ticket/article.rb b/app/models/ticket/article.rb index 4e5a14494..53e5407d1 100644 --- a/app/models/ticket/article.rb +++ b/app/models/ticket/article.rb @@ -11,14 +11,11 @@ class Ticket::Article < ApplicationModel belongs_to :ticket has_one :ticket_time_accounting, class_name: 'Ticket::TimeAccounting', foreign_key: :ticket_article_id, dependent: :destroy, inverse_of: :ticket_article - - # rubocop:disable Rails/InverseOf belongs_to :type, class_name: 'Ticket::Article::Type' belongs_to :sender, class_name: 'Ticket::Article::Sender' belongs_to :created_by, class_name: 'User' belongs_to :updated_by, class_name: 'User' belongs_to :origin_by, class_name: 'User' - # rubocop:enable Rails/InverseOf before_create :check_subject, :check_body, :check_message_id_md5 before_update :check_subject, :check_body, :check_message_id_md5 @@ -45,6 +42,7 @@ class Ticket::Article < ApplicationModel # fillup md5 of message id to search easier on very long message ids def check_message_id_md5 return true if message_id.blank? + self.message_id_md5 = Digest::MD5.hexdigest(message_id.to_s) end @@ -75,6 +73,7 @@ returns # look for attachment article['attachments'].each do |file| next if !file[:preferences] || !file[:preferences]['Content-ID'] || (file[:preferences]['Content-ID'] != cid && file[:preferences]['Content-ID'] != "<#{cid}>" ) + replace = "#{tag_start}/api/v1/ticket_attachment/#{article['ticket_id']}/#{article['id']}/#{file[:id]}\"#{tag_end}>" inline_attachments[file[:id]] = true break @@ -84,6 +83,7 @@ returns new_attachments = [] article['attachments'].each do |file| next if inline_attachments[file[:id]] + new_attachments.push file end article['attachments'] = new_attachments @@ -111,6 +111,7 @@ returns # look for attachment attachments.each do |file| next if !file.preferences['Content-ID'] || (file.preferences['Content-ID'] != cid && file.preferences['Content-ID'] != "<#{cid}>" ) + inline_attachments[file.id] = true break end @@ -118,6 +119,7 @@ returns new_attachments = [] attachments.each do |file| next if !inline_attachments[file.id] + new_attachments.push file end new_attachments @@ -140,6 +142,7 @@ get body as html def body_as_html return '' if !body return body if content_type && content_type =~ %r{text/html}i + body.text2html end @@ -155,6 +158,7 @@ get body as text def body_as_text return '' if !body return body if content_type.blank? || content_type =~ %r{text/plain}i + body.html2text end @@ -190,6 +194,7 @@ returns: o_id: id, ) return if list.blank? + list[0] end @@ -220,6 +225,7 @@ returns: def sanitizeable?(attribute, _value) return true if attribute != :body return false if content_type.blank? + content_type =~ /html/i end @@ -274,6 +280,7 @@ returns # strip not wanted chars def check_subject return true if subject.blank? + subject.gsub!(/\s|\t|\r/, ' ') true end @@ -281,6 +288,7 @@ returns # strip body length or raise exception def check_body return true if body.blank? + limit = 1_500_000 current_length = body.length return true if body.length <= limit diff --git a/app/models/ticket/article/assets.rb b/app/models/ticket/article/assets.rb index d88f85b9d..78848ef28 100644 --- a/app/models/ticket/article/assets.rb +++ b/app/models/ticket/article/assets.rb @@ -46,8 +46,10 @@ returns %w[created_by_id updated_by_id origin_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 diff --git a/app/models/ticket/article/checks_access.rb b/app/models/ticket/article/checks_access.rb index 5bf3eac12..ac2bb2c30 100644 --- a/app/models/ticket/article/checks_access.rb +++ b/app/models/ticket/article/checks_access.rb @@ -35,6 +35,7 @@ class Ticket # @return [nil] def access!(user, access) return if access?(user, access) + raise Exceptions::NotAuthorized end end diff --git a/app/models/ticket/assets.rb b/app/models/ticket/assets.rb index c202e5d4b..618f9c976 100644 --- a/app/models/ticket/assets.rb +++ b/app/models/ticket/assets.rb @@ -35,8 +35,10 @@ returns %w[created_by_id updated_by_id owner_id customer_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 diff --git a/app/models/ticket/checks_access.rb b/app/models/ticket/checks_access.rb index 8aa9c61cd..45eadf1e1 100644 --- a/app/models/ticket/checks_access.rb +++ b/app/models/ticket/checks_access.rb @@ -25,6 +25,7 @@ class Ticket return false if organization_id.blank? return false if user.organization_id.blank? return false if organization_id != user.organization_id + return organization.shared? end @@ -49,6 +50,7 @@ class Ticket # @return [nil] def access!(user, access) return if access?(user, access) + raise Exceptions::NotAuthorized end end diff --git a/app/models/ticket/escalation.rb b/app/models/ticket/escalation.rb index 816d2fde0..132b6ec1a 100644 --- a/app/models/ticket/escalation.rb +++ b/app/models/ticket/escalation.rb @@ -37,6 +37,7 @@ returns def escalation_calculation(force = false) return if !escalation_calculation_int(force) + self.callback_loop = true save! self.callback_loop = false @@ -51,6 +52,7 @@ returns # set escalation off if current state is not escalation relativ (e. g. ticket is closed) return if !state_id + state = Ticket::State.lookup(id: state_id) escalation_disabled = false if state.ignore_escalation? @@ -59,6 +61,7 @@ returns # early exit if nothing current state is not escalation relativ if !force return false if escalation_at.nil? + self.escalation_at = nil if preferences['escalation_calculation'] preferences['escalation_calculation']['escalation_disabled'] = escalation_disabled @@ -79,6 +82,7 @@ returns # nothing to change return false if !escalation_at && !first_response_escalation_at && !update_escalation_at && !close_escalation_at + preferences['escalation_calculation'] = {} self.escalation_at = nil self.first_response_escalation_at = nil @@ -155,10 +159,12 @@ returns calendar.business_hours.each do |day, meta| next if !meta[:active] next if !meta[:timeframes] + hours[day.to_sym] = {} meta[:timeframes].each do |frame| next if !frame[0] next if !frame[1] + hours[day.to_sym][frame[0]] = frame[1] end end @@ -173,6 +179,7 @@ returns next if !meta next if !meta['active'] next if meta['removed'] + holidays.push Date.parse(day) end config.holidays = holidays @@ -298,6 +305,7 @@ returns query_condition, bind_condition, tables = Ticket.selector2sql(sla.condition) ticket = Ticket.where(query_condition, *bind_condition).joins(tables).find_by(id: id) next if !ticket + sla_selected = sla break end @@ -356,6 +364,7 @@ returns next if !history_item['attribute'] next if history_item['attribute'] != 'state' next if history_item['id'] + last_history_state = history_item end local_updated_at = updated_at diff --git a/app/models/ticket/number.rb b/app/models/ticket/number.rb index e751c7b0c..58fee6bc5 100644 --- a/app/models/ticket/number.rb +++ b/app/models/ticket/number.rb @@ -49,10 +49,12 @@ returns if !adapter_name raise 'Missing ticket_number setting option' end + adapter = load_adapter(adapter_name) if !adapter raise "Can't load ticket_number adapter '#{adapter_name}'" end + adapter end end diff --git a/app/models/ticket/overviews.rb b/app/models/ticket/overviews.rb index 1ea3e41f4..1edfb5928 100644 --- a/app/models/ticket/overviews.rb +++ b/app/models/ticket/overviews.rb @@ -29,6 +29,7 @@ returns # get agent overviews return [] if !current_user.permissions?('ticket.agent') + overview_filter = { active: true } overview_filter_not = { out_of_office: true } if User.where('out_of_office = ? AND out_of_office_start_at <= ? AND out_of_office_end_at >= ? AND out_of_office_replacement_id = ? AND active = ?', true, Time.zone.today, Time.zone.today, current_user.id, true).count.positive? diff --git a/app/models/ticket/priority.rb b/app/models/ticket/priority.rb index 5481e226c..d2a75fd71 100644 --- a/app/models/ticket/priority.rb +++ b/app/models/ticket/priority.rb @@ -11,6 +11,7 @@ class Ticket::Priority < ApplicationModel def ensure_defaults return true if callback_loop + priorities_with_default = Ticket::Priority.where(default_create: true) return true if priorities_with_default.count == 1 @@ -25,6 +26,7 @@ class Ticket::Priority < ApplicationModel if priorities_with_default.count > 1 Ticket::Priority.all.each do |local_priority| next if local_priority.id == id + local_priority.default_create = false local_priority.callback_loop = true local_priority.save! diff --git a/app/models/ticket/screen_options.rb b/app/models/ticket/screen_options.rb index 4e7782516..4eba8c727 100644 --- a/app/models/ticket/screen_options.rb +++ b/app/models/ticket/screen_options.rb @@ -64,6 +64,7 @@ returns state_types.each do |type| state_type = Ticket::StateType.find_by(name: type) next if !state_type + state_type.states.each do |state| assets = state.assets(assets) state_ids.push state.id @@ -88,6 +89,7 @@ returns types.each do |type_name| type = Ticket::Article::Type.lookup(name: type_name) next if type.blank? + type_ids.push type.id end end @@ -118,10 +120,13 @@ returns User.where(id: group_agent_user_ids.concat(group_agent_role_user_ids).uniq, active: true).pluck(:id).each do |user_id| dependencies[:group_id][group.id][:owner_id].push user_id next if agents[user_id] + agents[user_id] = true next if assets[:User] && assets[:User][user_id] + user = User.lookup(id: user_id) next if !user + assets = user.assets(assets) end diff --git a/app/models/ticket/search.rb b/app/models/ticket/search.rb index 7de4ad7d7..bf6d6925c 100644 --- a/app/models/ticket/search.rb +++ b/app/models/ticket/search.rb @@ -166,6 +166,7 @@ returns items.each do |item| ticket = Ticket.lookup(id: item[:id]) next if !ticket + tickets.push ticket end return tickets diff --git a/app/models/ticket/state.rb b/app/models/ticket/state.rb index 98f1597e1..34a7e670b 100644 --- a/app/models/ticket/state.rb +++ b/app/models/ticket/state.rb @@ -2,10 +2,8 @@ class Ticket::State < ApplicationModel include ChecksLatestChangeObserved - # rubocop:disable Rails/InverseOf belongs_to :state_type, class_name: 'Ticket::StateType', inverse_of: :states belongs_to :next_state, class_name: 'Ticket::State' - # rubocop:enable Rails/InverseOf after_create :ensure_defaults after_update :ensure_defaults @@ -81,6 +79,7 @@ returns: def ignore_escalation? return true if ignore_escalation + false end @@ -102,6 +101,7 @@ returns: Ticket::State.all.each do |local_state| next if local_state.id == id next if local_state[default_field] == false + local_state[default_field] = false local_state.callback_loop = true local_state.save! diff --git a/app/models/ticket/time_accounting.rb b/app/models/ticket/time_accounting.rb index 599606642..0db8bc6cf 100644 --- a/app/models/ticket/time_accounting.rb +++ b/app/models/ticket/time_accounting.rb @@ -15,9 +15,11 @@ class Ticket::TimeAccounting < ApplicationModel exists = true end return false if exists == false + ticket = Ticket.lookup(id: ticket_id) return false if !ticket return false if ticket.time_unit == time_units + ticket.time_unit = time_units ticket.save! true diff --git a/app/models/token.rb b/app/models/token.rb index d9d12accc..1ec3187f0 100644 --- a/app/models/token.rb +++ b/app/models/token.rb @@ -81,6 +81,7 @@ returns if data[:permission] return if !user.permissions?(data[:permission]) return if !token.preferences[:permission] + local_permissions = data[:permission] if data[:permission].class != Array local_permissions = [data[:permission]] @@ -90,10 +91,12 @@ returns local_permissions = Permission.with_parents(local_permission) local_permissions.each do |local_permission_name| next if !token.preferences[:permission].include?(local_permission_name) + match = true break end next if !match + break end return if !match diff --git a/app/models/transaction/background_job.rb b/app/models/transaction/background_job.rb index 4d92c6017..f0f4a57ec 100644 --- a/app/models/transaction/background_job.rb +++ b/app/models/transaction/background_job.rb @@ -26,6 +26,7 @@ class Transaction::BackgroundJob Setting.where(area: 'Transaction::Backend::Async').order(:name).each do |setting| backend = Setting.get(setting.name) next if @params[:disable]&.include?(backend) + backend = Kernel.const_get(backend) Observer::Transaction.execute_singel_backend(backend, @item, @params) end diff --git a/app/models/transaction/cti_caller_id_detection.rb b/app/models/transaction/cti_caller_id_detection.rb index 8a1ee55db..44020b1b0 100644 --- a/app/models/transaction/cti_caller_id_detection.rb +++ b/app/models/transaction/cti_caller_id_detection.rb @@ -37,12 +37,14 @@ class Transaction::CtiCallerIdDetection if @item[:object] == 'Ticket' && @item[:type] == 'create' ticket = Ticket.lookup(id: @item[:object_id]) return if !ticket + Cti::CallerId.build(ticket) end if @item[:object] == 'User' user = User.lookup(id: @item[:object_id]) return if !user + Cti::CallerId.build(user) end diff --git a/app/models/transaction/karma.rb b/app/models/transaction/karma.rb index c5fa1d082..da41aacf2 100644 --- a/app/models/transaction/karma.rb +++ b/app/models/transaction/karma.rb @@ -55,12 +55,14 @@ class Transaction::Karma if @item[:type] == 'reminder_reached' return if ticket.owner_id == 1 return if ticket.pending_time && ticket.pending_time > Time.zone.now - 2.days + Karma::ActivityLog.add('ticket reminder overdue (+2 days)', ticket.owner, 'Ticket', ticket.id) return end if @item[:type] == 'escalation' return if ticket.owner_id == 1 + Karma::ActivityLog.add('ticket escalated', ticket.owner, 'Ticket', ticket.id) return end @@ -68,6 +70,7 @@ class Transaction::Karma return if @item[:type] != 'update' return if !@item[:changes] return if !@item[:changes]['state_id'] + state_before = Ticket::State.lookup(id: @item[:changes]['state_id'][0]) state_now = Ticket::State.lookup(id: @item[:changes]['state_id'][1]) @@ -76,7 +79,7 @@ class Transaction::Karma # did user send a response to customer before? current_time = @item[:created_at] - ticket.articles.reverse.each do |local_article| + ticket.articles.reverse_each do |local_article| next if local_article.created_at > current_time next if local_article.created_by_id != @item[:user_id] next if local_article.internal @@ -103,6 +106,7 @@ class Transaction::Karma def ticket_article_karma(user) return if !@item[:article_id] + article = Ticket::Article.lookup(id: @item[:article_id]) return if !article @@ -136,6 +140,7 @@ class Transaction::Karma last_sender_customer = local_sender.name == 'Customer' next if local_sender.name != 'Customer' + last_customer_contact = local_article.created_at end if last_sender_customer && last_customer_contact @@ -164,8 +169,10 @@ class Transaction::Karma def tagging(user) return if @item[:type] != 'create' + tag = Tag.lookup(id: @item[:object_id]) return if !tag + Karma::ActivityLog.add('tagging', user, tag.tag_object.name, tag.o_id) end diff --git a/app/models/transaction/notification.rb b/app/models/transaction/notification.rb index 4d9bff765..a1a5313e7 100644 --- a/app/models/transaction/notification.rb +++ b/app/models/transaction/notification.rb @@ -31,6 +31,7 @@ class Transaction::Notification ticket = Ticket.find_by(id: @item[:object_id]) return if !ticket + if @item[:article_id] article = Ticket::Article.find(@item[:article_id]) @@ -38,6 +39,7 @@ class Transaction::Notification sender = Ticket::Article::Sender.lookup(id: article.sender_id) if sender&.name == 'System' return if @item[:changes].blank? && article.preferences[:notification] != true + if article.preferences[:notification] != true article = nil end @@ -77,9 +79,11 @@ class Transaction::Notification result = NotificationFactory::Mailer.notification_settings(user, ticket, @item[:type]) next if !result next if already_checked_recipient_ids[user.id] + already_checked_recipient_ids[user.id] = true recipients_and_channels.push result next if recipients_reason[user.id] + recipients_reason[user.id] = 'are in group' end @@ -114,6 +118,7 @@ class Transaction::Notification next if history['value_to'] !~ /\(#{Regexp.escape(@item[:type])}:/ next if history['value_to'] !~ /#{Regexp.escape(identifier)}\(/ next if !history['created_at'].today? + already_notified = true end next if already_notified @@ -214,6 +219,7 @@ class Transaction::Notification def add_recipient_list(ticket, user, channels, type) return if channels.blank? + identifier = user.email if !identifier || identifier == '' identifier = user.login @@ -231,6 +237,7 @@ class Transaction::Notification def human_changes(user, record) return {} if !@item[:changes] + locale = user.preferences[:locale] || Setting.get('locale_default') || 'en-us' # only show allowed attributes @@ -330,6 +337,7 @@ class Transaction::Notification # return for already found, added and checked users # to prevent re-doing complete lookup paths return if !replacements.add?(replacement) + reasons[replacement.id] = 'are the out-of-office replacement of the owner' recursive_ooo_replacements( diff --git a/app/models/transaction/signature_detection.rb b/app/models/transaction/signature_detection.rb index d3443a2fe..3648fbbaf 100644 --- a/app/models/transaction/signature_detection.rb +++ b/app/models/transaction/signature_detection.rb @@ -31,6 +31,7 @@ class Transaction::SignatureDetection ticket = Ticket.lookup(id: @item[:object_id]) return if !ticket + article = ticket.articles.first return if !article @@ -51,6 +52,7 @@ class Transaction::SignatureDetection return if !user return if !user.preferences return if !user.preferences[:signature_detection] + line = ::SignatureDetection.find_signature_line_by_article( user, article diff --git a/app/models/transaction/slack.rb b/app/models/transaction/slack.rb index 300ba2d2d..7f631230c 100644 --- a/app/models/transaction/slack.rb +++ b/app/models/transaction/slack.rb @@ -45,6 +45,7 @@ class Transaction::Slack sender = Ticket::Article::Sender.lookup(id: article.sender_id) if sender&.name == 'System' return if @item[:changes].blank? + article = nil end end @@ -133,6 +134,7 @@ class Transaction::Slack hit = false local_config['types'].each do |type| next if type.to_s != @item[:type].to_s + hit = true break end @@ -146,6 +148,7 @@ class Transaction::Slack hit = false local_config['group_ids'].each do |group_id| next if group_id.to_s != ticket.group_id.to_s + hit = true break end @@ -196,6 +199,7 @@ class Transaction::Slack def human_changes(record) return {} if !@item[:changes] + user = User.find(1) locale = user.preferences[:locale] || Setting.get('locale_default') || 'en-us' diff --git a/app/models/transaction/trigger.rb b/app/models/transaction/trigger.rb index 5faab763d..c16f70067 100644 --- a/app/models/transaction/trigger.rb +++ b/app/models/transaction/trigger.rb @@ -31,6 +31,7 @@ class Transaction::Trigger ticket = Ticket.find_by(id: @item[:object_id]) return if !ticket + if @item[:article_id] article = Ticket::Article.find_by(id: @item[:article_id]) end diff --git a/app/models/translation.rb b/app/models/translation.rb index afd70a7ad..5baf74ecf 100644 --- a/app/models/translation.rb +++ b/app/models/translation.rb @@ -21,6 +21,7 @@ all: def self.sync(dedicated_locale = nil) return true if load_from_file(dedicated_locale) + load end @@ -171,6 +172,7 @@ get list of translations %w[yes no or Year Years Month Months Day Days Hour Hours Minute Minutes Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec January February March April May June July August September October November December Mon Tue Wed Thu Fri Sat Sun Monday Tuesday Wednesday Thursday Friday Saturday Sunday].each do |presort| list.each do |item| next if item[1] != presort + presorted_list.push item list.delete item #list.unshift presort @@ -231,6 +233,7 @@ all: locals_to_sync(dedicated_locale).each do |locale| file = Rails.root.join(directory, "#{locale}-#{version}.yml") return false if !File.exist?(file) + data = YAML.load_file(file) to_database(locale, data) end @@ -323,12 +326,14 @@ Get source file at https://i18n.zammad.com/api/v1/translations_empty_translation translation_raw = [] rows.each do |row| raise "Can't import translation, source is missing" if row[0].blank? + if row[1].blank? warn "Skipped #{row[0]}, because translation is blank" next end raise "Can't import translation, format is missing" if row[2].blank? raise "Can't import translation, format is invalid (#{row[2]})" if row[2] !~ /^(time|string)$/ + item = { 'locale' => locale.locale, 'source' => row[0], @@ -349,6 +354,7 @@ Get source file at https://i18n.zammad.com/api/v1/translations_empty_translation next if row[3] != raw['format'] return false if row[4] == raw['target'] # no update if target is still the same return false if row[4] != row[5] # no update if translation has already changed + return [true, Translation.find(row[0])] end [true, nil] @@ -362,6 +368,7 @@ Get source file at https://i18n.zammad.com/api/v1/translations_empty_translation result = Translation.remote_translation_need_update?(translation_raw, translations) next if result == false next if result.class != Array + if result[1] result[1].update!(translation_raw.symbolize_keys!) result[1].save @@ -395,6 +402,7 @@ Get source file at https://i18n.zammad.com/api/v1/translations_empty_translation def set_initial return true if target_initial.present? return true if target_initial == '' + self.target_initial = target true end diff --git a/app/models/trigger/assets.rb b/app/models/trigger/assets.rb index fd37d3145..695cbfc14 100644 --- a/app/models/trigger/assets.rb +++ b/app/models/trigger/assets.rb @@ -41,8 +41,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 ][ self[ local_user_id ] ] + user = User.lookup(id: self[ local_user_id ]) next if !user + data = user.assets(data) end data diff --git a/app/models/type_lookup.rb b/app/models/type_lookup.rb index 5934498d6..b4e68a1e4 100644 --- a/app/models/type_lookup.rb +++ b/app/models/type_lookup.rb @@ -5,6 +5,7 @@ class TypeLookup < ApplicationModel def self.by_id( id ) lookup = self.lookup( id: id ) return if !lookup + lookup.name end diff --git a/app/models/user.rb b/app/models/user.rb index b0c85ee09..c7febd6c8 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -65,6 +65,7 @@ class User < ApplicationModel def ignore_search_indexing?(_action) # ignore internal user return true if id == 1 + false end @@ -162,6 +163,7 @@ returns return false if out_of_office != true return false if out_of_office_start_at.blank? return false if out_of_office_end_at.blank? + Time.zone.today.between?(out_of_office_start_at, out_of_office_end_at) end @@ -181,6 +183,7 @@ returns def out_of_office_agent return if !out_of_office? return if out_of_office_replacement_id.blank? + User.find_by(id: out_of_office_replacement_id) end @@ -360,6 +363,7 @@ returns url = '' hash['info']['urls']&.each_value do |local_url| next if local_url.blank? + url = local_url end begin @@ -402,6 +406,7 @@ returns list = {} ::Permission.select('permissions.name, permissions.preferences').joins(:roles).where('roles.id IN (?) AND permissions.active = ?', role_ids, true).pluck(:name, :preferences).each do |permission| next if permission[1]['selectable'] == false + list[permission[0]] = true end list @@ -440,6 +445,7 @@ returns else permission = ::Permission.lookup(name: local_key) break if permission&.active == false + permissions = ::Permission.with_parents(local_key) list = ::Permission.select('preferences').joins(:roles).where('roles.id IN (?) AND roles.active = ? AND permissions.name IN (?) AND permissions.active = ?', role_ids, true, permissions, true).pluck(:preferences) end @@ -471,6 +477,7 @@ returns where_bind.push "#{permission_name}.%" end return [] if where == '' + ::Permission.where("permissions.active = ? AND (#{where})", *where_bind).pluck(:id) end @@ -501,15 +508,18 @@ returns ::Permission.with_parents(key).each do |local_key| permission = ::Permission.lookup(name: local_key) next if !permission + permission_ids.push permission.id end next if permission_ids.blank? + Role.joins(:roles_permissions).joins(:permissions).where('permissions_roles.permission_id IN (?) AND roles.active = ? AND permissions.active = ?', permission_ids, true, true).distinct().pluck(:id).each do |role_id| role_ids.push role_id end total_role_ids.push role_ids end return [] if total_role_ids.blank? + condition = '' total_role_ids.each do |_role_ids| if condition != '' @@ -721,6 +731,7 @@ returns if !group_ids return User.where(active: true).joins(:users_roles).where('roles_users.role_id IN (?)', roles_ids).order('users.updated_at DESC') end + User.where(active: true) .joins(:users_roles) .joins(:users_groups) @@ -742,14 +753,18 @@ returns def self.update_default_preferences_by_permission(permission_name, force = false) permission = ::Permission.lookup(name: permission_name) return if !permission + default = Rails.configuration.preferences_default_by_permission return false if !default + default.deep_stringify_keys! User.with_permissions(permission.name).each do |user| next if !default[permission.name] + has_changed = false default[permission.name].each do |key, value| next if !force && user.preferences[key] + has_changed = true user.preferences[key] = value end @@ -775,8 +790,10 @@ returns def self.update_default_preferences_by_role(role_name, force = false) role = Role.lookup(name: role_name) return if !role + default = Rails.configuration.preferences_default_by_permission return false if !default + default.deep_stringify_keys! role.permissions.each do |permission| User.update_default_preferences_by_permission(permission.name, force) @@ -787,12 +804,15 @@ returns def check_notifications(other, should_save = true) default = Rails.configuration.preferences_default_by_permission return if !default + default.deep_stringify_keys! has_changed = false other.permissions.each do |permission| next if !default[permission.name] + default[permission.name].each do |key, value| next if preferences[key] + preferences[key] = value has_changed = true end @@ -818,6 +838,7 @@ returns end end return if @preferences_default.blank? + preferences_tmp = @preferences_default.merge(preferences) self.preferences = preferences_tmp @preferences_default = nil @@ -846,6 +867,7 @@ try to find correct name def self.name_guess(string, email = nil) return if string.blank? && email.blank? + string.strip! firstname = '' lastname = '' @@ -931,10 +953,12 @@ try to find correct name def check_email return true if Setting.get('import_mode') return true if email.blank? + self.email = email.downcase.strip return true if id == 1 raise Exceptions::UnprocessableEntity, 'Invalid email' if email !~ /@/ raise Exceptions::UnprocessableEntity, 'Invalid email' if email.match?(/\s/) + true end @@ -973,17 +997,20 @@ try to find correct name def check_mail_delivery_failed return if email_change.blank? + preferences.delete(:mail_delivery_failed) end def ensure_roles return true if role_ids.present? + self.role_ids = Role.signup_role_ids end def ensure_identifier return true if email.present? || firstname.present? || lastname.present? || phone.present? return true if login.present? && !login.start_with?('auto-') + raise Exceptions::UnprocessableEntity, 'Minimum one identifier (login, firstname, lastname, phone or email) for user is required.' end @@ -994,16 +1021,19 @@ try to find correct name return true if !changes return true if !changes['email'] return true if !User.find_by(email: email.downcase.strip) + raise Exceptions::UnprocessableEntity, 'Email address is already used for other user.' end def validate_roles(role) return true if !role_ids # we need role_ids for checking in role_ids below, in this method return true if role.preferences[:not].blank? + role.preferences[:not].each do |local_role_name| local_role = Role.lookup(name: local_role_name) next if !local_role next if role_ids.exclude?(local_role.id) + raise "Role #{role.name} conflicts with #{local_role.name}" end true @@ -1016,6 +1046,7 @@ try to find correct name raise Exceptions::UnprocessableEntity, 'out of office end is before start' if out_of_office_start_at > out_of_office_end_at raise Exceptions::UnprocessableEntity, 'out of office replacement user is required' if out_of_office_replacement_id.blank? raise Exceptions::UnprocessableEntity, 'out of office no such replacement user' if !User.find_by(id: out_of_office_replacement_id) + true end @@ -1025,6 +1056,7 @@ try to find correct name return true if preferences.blank? return true if !preferences[:notification_sound] return true if !preferences[:notification_sound][:enabled] + if preferences[:notification_sound][:enabled] == 'true' preferences[:notification_sound][:enabled] = true elsif preferences[:notification_sound][:enabled] == 'false' @@ -1032,6 +1064,7 @@ try to find correct name end class_name = preferences[:notification_sound][:enabled].class.to_s raise Exceptions::UnprocessableEntity, "preferences.notification_sound.enabled need to be an boolean, but it was a #{class_name}" if class_name != 'TrueClass' && class_name != 'FalseClass' + true end @@ -1050,6 +1083,7 @@ raise 'Minimum one user need to have admin permissions' return true if active != false return true if !permissions?(['admin', 'admin.user']) raise Exceptions::UnprocessableEntity, 'Minimum one user needs to have admin permissions.' if last_admin_check_admin_count < 1 + true end @@ -1057,6 +1091,7 @@ raise 'Minimum one user need to have admin permissions' return true if Setting.get('import_mode') return true if !role.with_permission?(['admin', 'admin.user']) raise Exceptions::UnprocessableEntity, 'Minimum one user needs to have admin permissions.' if last_admin_check_admin_count < 1 + true end @@ -1070,9 +1105,11 @@ raise 'Minimum one user need to have admin permissions' return true if !will_save_change_to_attribute?('active') return true if active != true return true if !permissions?('ticket.agent') + ticket_agent_role_ids = Role.joins(:permissions).where(permissions: { name: 'ticket.agent', active: true }, roles: { active: true }).pluck(:id) count = User.joins(:roles).where(roles: { id: ticket_agent_role_ids }, users: { active: true }).distinct().count + 1 raise Exceptions::UnprocessableEntity, 'Agent limit exceeded, please check your account settings.' if count > Setting.get('system_agent_limit').to_i + true end @@ -1081,6 +1118,7 @@ raise 'Minimum one user need to have admin permissions' return true if active != true return true if role.active != true return true if !role.with_permission?('ticket.agent') + ticket_agent_role_ids = Role.joins(:permissions).where(permissions: { name: 'ticket.agent', active: true }, roles: { active: true }).pluck(:id) count = User.joins(:roles).where(roles: { id: ticket_agent_role_ids }, users: { active: true }).distinct().count @@ -1091,6 +1129,7 @@ raise 'Minimum one user need to have admin permissions' hint = false role_ids.each do |locale_role_id| next if !ticket_agent_role_ids.include?(locale_role_id) + hint = true break end @@ -1101,17 +1140,21 @@ raise 'Minimum one user need to have admin permissions' end end raise Exceptions::UnprocessableEntity, 'Agent limit exceeded, please check your account settings.' if count > Setting.get('system_agent_limit').to_i + true end def domain_based_assignment return true if !email return true if organization_id + begin domain = Mail::Address.new(email).domain return true if !domain + organization = Organization.find_by(domain: domain.downcase, domain_assignment: true) return true if !organization + self.organization_id = organization.id rescue return true @@ -1124,6 +1167,7 @@ raise 'Minimum one user need to have admin permissions' # set the user's locale to the one of the "executing" user return true if !UserInfo.current_user_id + user = User.find_by(id: UserInfo.current_user_id) return true if !user return true if !user.preferences[:locale] @@ -1177,6 +1221,7 @@ raise 'Minimum one user need to have admin permissions' def ensure_password return true if password_empty? return true if PasswordHash.crypted?(password) + self.password = PasswordHash.crypt(password) true end @@ -1198,6 +1243,7 @@ raise 'Minimum one user need to have admin permissions' # reset login_failed if password is changed def reset_login_failed return true if !will_save_change_to_attribute?('password') + self.login_failed = 0 true end diff --git a/app/models/user/assets.rb b/app/models/user/assets.rb index 7b5e63d94..0ae1f264e 100644 --- a/app/models/user/assets.rb +++ b/app/models/user/assets.rb @@ -59,6 +59,7 @@ returns # get roles local_attributes['role_ids']&.each do |role_id| next if data[:Role] && data[:Role][role_id] + role = Role.lookup(id: role_id) data = role.assets(data) end @@ -66,16 +67,20 @@ returns # get groups local_attributes['group_ids']&.each do |group_id, _access| next if data[:Group] && data[:Group][group_id] + group = Group.lookup(id: group_id) next if !group + data = group.assets(data) end # get organizations local_attributes['organization_ids']&.each do |organization_id| next if data[:Organization] && data[:Organization][organization_id] + organization = Organization.lookup(id: organization_id) next if !organization + data = organization.assets(data) end @@ -94,8 +99,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 ][ self[ local_user_id ] ] + user = User.lookup(id: self[ local_user_id ]) next if !user + data = user.assets(data) end data diff --git a/app/models/user/checks_access.rb b/app/models/user/checks_access.rb index b62f0bb9a..c0d111452 100644 --- a/app/models/user/checks_access.rb +++ b/app/models/user/checks_access.rb @@ -16,6 +16,7 @@ class User def access?(requester, access) # full admins can do whatever they want return true if requester.permissions?('admin') + send("#{access}able_by?".to_sym, requester) end @@ -31,6 +32,7 @@ class User # @return [nil] def access!(user, access) return if access?(user, access) + raise Exceptions::NotAuthorized end @@ -42,6 +44,7 @@ class User return true if requester.permissions?('ticket.agent') # check same organization for customers return false if !requester.permissions?('ticket.customer') + same_organization?(requester) end @@ -49,6 +52,7 @@ class User return true if requester.permissions?('admin.user') # allow agents to change customers return false if !requester.permissions?('ticket.agent') + permissions?('ticket.customer') end @@ -63,6 +67,7 @@ class User def same_organization?(requester) return false if organization_id.blank? return false if requester.organization_id.blank? + organization_id == requester.organization_id end end diff --git a/app/models/user/search.rb b/app/models/user/search.rb index f8f126367..63daa5ded 100644 --- a/app/models/user/search.rb +++ b/app/models/user/search.rb @@ -32,6 +32,7 @@ returns if user has no permissions to search def search_preferences(current_user) return false if !current_user.permissions?('ticket.agent') && !current_user.permissions?('admin.user') + { prio: 2000, direct_search_index: true, @@ -117,6 +118,7 @@ returns items.each do |item| user = User.lookup(id: item[:id]) next if !user + users.push user end return users diff --git a/app/models/user/search_index.rb b/app/models/user/search_index.rb index cab464500..26b1c87a6 100644 --- a/app/models/user/search_index.rb +++ b/app/models/user/search_index.rb @@ -24,6 +24,7 @@ returns permissions_with_child_ids.each do |permission_id| permission = ::Permission.lookup(id: permission_id) next if !permission + attributes['permissions'].push permission.name end attributes['role_ids'] = role_ids @@ -54,6 +55,7 @@ returns next if key == 'password' next if !value next if value.respond_to?('blank?') && value.blank? + attributes[key] = value end return if attributes.blank? diff --git a/app/models/user_device.rb b/app/models/user_device.rb index 8fccaf44f..d9718bab0 100644 --- a/app/models/user_device.rb +++ b/app/models/user_device.rb @@ -237,6 +237,7 @@ check fingerprint string def self.fingerprint_validation(fingerprint) return true if fingerprint.blank? raise Exceptions::UnprocessableEntity, "fingerprint is #{fingerprint.to_s.length} chars but can only be 160 chars!" if fingerprint.to_s.length > 160 + true end diff --git a/config/initializers/db_preferences_mysql.rb b/config/initializers/db_preferences_mysql.rb index 2958bb6a4..e4de98227 100644 --- a/config/initializers/db_preferences_mysql.rb +++ b/config/initializers/db_preferences_mysql.rb @@ -13,6 +13,7 @@ connection = ActiveRecord::Base.connection # mariadb example: "10.1.17-MariaDB" server_version = connection.execute('SELECT @@version;').first.first raise 'Unable to retrive database version' if server_version.blank? + version_number = Gem::Version.new(server_version.split('-').first) vendor = server_version.split('-').second || 'MySQL' diff --git a/config/initializers/html_sanitizer.rb b/config/initializers/html_sanitizer.rb index 5e8b708b6..021996387 100644 --- a/config/initializers/html_sanitizer.rb +++ b/config/initializers/html_sanitizer.rb @@ -1,4 +1,3 @@ - # content of this tags will also be removed Rails.application.config.html_sanitizer_tags_remove_content = %w[ style diff --git a/db/migrate/20150979000001_update_timestamps.rb b/db/migrate/20150979000001_update_timestamps.rb index 3f476ac0c..39f9b2df6 100644 --- a/db/migrate/20150979000001_update_timestamps.rb +++ b/db/migrate/20150979000001_update_timestamps.rb @@ -4,6 +4,7 @@ class UpdateTimestamps < ActiveRecord::Migration[4.2] Models.all.each_value do |value| next if !value next if !value[:attributes] + if value[:attributes].include?('changed_at') ActiveRecord::Migration.change_column value[:table].to_sym, :changed_at, :datetime, null: false end diff --git a/db/migrate/20161117000003_store_config_name_update_issue_428.rb b/db/migrate/20161117000003_store_config_name_update_issue_428.rb index 84697a0b2..e68c6e184 100644 --- a/db/migrate/20161117000003_store_config_name_update_issue_428.rb +++ b/db/migrate/20161117000003_store_config_name_update_issue_428.rb @@ -2,8 +2,10 @@ class StoreConfigNameUpdateIssue428 < ActiveRecord::Migration[4.2] def up # return if it's a new setup return if !Setting.find_by(name: 'system_init_done') + setting = Setting.find_by(name: 'storage') return if !setting + setting.name = 'storage_provider' setting.options = { form: [ diff --git a/db/migrate/20170113000001_object_manager_attribute_create_middle.rb b/db/migrate/20170113000001_object_manager_attribute_create_middle.rb index ede9e01dd..7088bc2e7 100644 --- a/db/migrate/20170113000001_object_manager_attribute_create_middle.rb +++ b/db/migrate/20170113000001_object_manager_attribute_create_middle.rb @@ -7,6 +7,7 @@ class ObjectManagerAttributeCreateMiddle < ActiveRecord::Migration[4.2] next if attribute.name == 'tags' next if !attribute.screens next if !attribute.screens['create_bottom'] + attribute.screens['create_middle'] = attribute.screens['create_bottom'] attribute.screens.delete('create_bottom') attribute.save! diff --git a/db/migrate/20170113000002_slack_group_config_issue_587.rb b/db/migrate/20170113000002_slack_group_config_issue_587.rb index b3f541447..23938fe93 100644 --- a/db/migrate/20170113000002_slack_group_config_issue_587.rb +++ b/db/migrate/20170113000002_slack_group_config_issue_587.rb @@ -9,10 +9,12 @@ class SlackGroupConfigIssue587 < ActiveRecord::Migration[4.2] return if !setting.state_current['value'] return if !setting.state_current['value']['items'] + config_item = setting.state_current['value']['items'].first return if !config_item return if !config_item.key?('group_id') + config_item['group_ids'] = config_item.delete('group_id') setting.save! diff --git a/db/migrate/20170116000002_fixed_typos_622.rb b/db/migrate/20170116000002_fixed_typos_622.rb index 57425f858..7bbad1284 100644 --- a/db/migrate/20170116000002_fixed_typos_622.rb +++ b/db/migrate/20170116000002_fixed_typos_622.rb @@ -6,6 +6,7 @@ class FixedTypos622 < ActiveRecord::Migration[4.2] setting = Setting.find_by(name: 'ticket_define_email_from_seperator') return if !setting + setting.name = 'ticket_define_email_from_separator' setting.options[:form][0][:name] = 'ticket_define_email_from_separator' setting.save! @@ -21,6 +22,7 @@ class FixedTypos622 < ActiveRecord::Migration[4.2] setting_map.each do |key, description| local_setting = Setting.find_by(name: key) next if !local_setting + local_setting.description = description local_setting.save! end diff --git a/db/migrate/20170203000001_remove_last_login_from_history_722.rb b/db/migrate/20170203000001_remove_last_login_from_history_722.rb index 08e050edb..152d74cb6 100644 --- a/db/migrate/20170203000001_remove_last_login_from_history_722.rb +++ b/db/migrate/20170203000001_remove_last_login_from_history_722.rb @@ -6,8 +6,10 @@ class RemoveLastLoginFromHistory722 < ActiveRecord::Migration[4.2] history_object = History.object_lookup('User') return if !history_object + history_attribute = History.attribute_lookup('last_login') return if !history_attribute + History.where(history_object_id: history_object.id, history_attribute_id: history_attribute.id).delete_all end end diff --git a/db/migrate/20170214000001_reload_online_browser_after_cors_csrf_changes.rb b/db/migrate/20170214000001_reload_online_browser_after_cors_csrf_changes.rb index 9b996c0af..f082be45b 100644 --- a/db/migrate/20170214000001_reload_online_browser_after_cors_csrf_changes.rb +++ b/db/migrate/20170214000001_reload_online_browser_after_cors_csrf_changes.rb @@ -3,6 +3,7 @@ class ReloadOnlineBrowserAfterCorsCsrfChanges < ActiveRecord::Migration[4.2] # return if it's a new setup return if !Setting.find_by(name: 'system_init_done') + AppVersion.set(true, 'app_version') end end diff --git a/db/migrate/20170403000001_fixed_admin_user_permission_920.rb b/db/migrate/20170403000001_fixed_admin_user_permission_920.rb index a0b3199a8..a80073b67 100644 --- a/db/migrate/20170403000001_fixed_admin_user_permission_920.rb +++ b/db/migrate/20170403000001_fixed_admin_user_permission_920.rb @@ -752,6 +752,7 @@ class FixedAdminUserPermission920 < ActiveRecord::Migration[4.2] } ObjectManager::Attribute.all.each do |attribute| next if attribute.screens.blank? + screens = {} attribute.screens.each do |screen, role_value| if role_value.blank? diff --git a/db/migrate/20170419000002_overview_role_ids.rb b/db/migrate/20170419000002_overview_role_ids.rb index 5c2a2cd4c..124f8c019 100644 --- a/db/migrate/20170419000002_overview_role_ids.rb +++ b/db/migrate/20170419000002_overview_role_ids.rb @@ -14,6 +14,7 @@ class OverviewRoleIds < ActiveRecord::Migration[4.2] Overview.reset_column_information Overview.all.each do |overview| next if overview.role_id.blank? + overview.role_ids = [overview.role_id] overview.save! end diff --git a/db/migrate/20170516000001_trigger_recipient_update.rb b/db/migrate/20170516000001_trigger_recipient_update.rb index e35bd4ad5..4c3eb8c07 100644 --- a/db/migrate/20170516000001_trigger_recipient_update.rb +++ b/db/migrate/20170516000001_trigger_recipient_update.rb @@ -12,6 +12,7 @@ class TriggerRecipientUpdate < ActiveRecord::Migration[4.2] next if trigger.perform['notification.email'].blank? next if trigger.perform['notification.email']['recipient'].blank? next if trigger.perform['notification.email']['recipient'] != 'ticket_customer' + trigger.perform['notification.email']['recipient'] = 'article_last_sender' trigger.save! rescue => e diff --git a/db/migrate/20170529132120_ldap_multi_group_mapping.rb b/db/migrate/20170529132120_ldap_multi_group_mapping.rb index 25d450d51..ae745dbee 100644 --- a/db/migrate/20170529132120_ldap_multi_group_mapping.rb +++ b/db/migrate/20170529132120_ldap_multi_group_mapping.rb @@ -15,6 +15,7 @@ class LdapMultiGroupMapping < ActiveRecord::Migration[4.2] # if we need to migrate to new array structure ldap_config['group_role_map'].each do |source, dest| next if dest.is_a?(Array) + ldap_config['group_role_map'][source] = [dest] end diff --git a/db/migrate/20170713000001_omniauth_office365_setting.rb b/db/migrate/20170713000001_omniauth_office365_setting.rb index 59b2f1c17..f7a3c85b6 100644 --- a/db/migrate/20170713000001_omniauth_office365_setting.rb +++ b/db/migrate/20170713000001_omniauth_office365_setting.rb @@ -3,6 +3,7 @@ class OmniauthOffice365Setting < ActiveRecord::Migration[4.2] # return if it's a new setup return if !Setting.find_by(name: 'system_init_done') + Setting.create_if_not_exists( title: 'Authentication via %s', name: 'auth_microsoft_office365', diff --git a/db/migrate/20170822000001_agend_based_sender_issue_1351.rb b/db/migrate/20170822000001_agend_based_sender_issue_1351.rb index 12d9fc743..fc9dd1db7 100644 --- a/db/migrate/20170822000001_agend_based_sender_issue_1351.rb +++ b/db/migrate/20170822000001_agend_based_sender_issue_1351.rb @@ -3,6 +3,7 @@ class AgendBasedSenderIssue1351 < ActiveRecord::Migration[4.2] # return if it's a new setup return if !Setting.find_by(name: 'system_init_done') + EmailAddress.all.each do |email_address| begin email_address.save! diff --git a/db/migrate/20170905140038_cti_log_preferences_migration.rb b/db/migrate/20170905140038_cti_log_preferences_migration.rb index 513473a5f..478ed41d0 100644 --- a/db/migrate/20170905140038_cti_log_preferences_migration.rb +++ b/db/migrate/20170905140038_cti_log_preferences_migration.rb @@ -49,6 +49,7 @@ class CtiLogPreferencesMigration < ActiveRecord::Migration[5.0] # to an Hash via .attributes updated = item.preferences[direction].each_with_object([]) do |caller_id, new_direction| next if !caller_id.respond_to?(:attributes) + new_direction.push(caller_id.attributes) end diff --git a/db/migrate/20170908000001_fixed_twitter_ticket_article_preferences4.rb b/db/migrate/20170908000001_fixed_twitter_ticket_article_preferences4.rb index 77979d462..e39216dfe 100644 --- a/db/migrate/20170908000001_fixed_twitter_ticket_article_preferences4.rb +++ b/db/migrate/20170908000001_fixed_twitter_ticket_article_preferences4.rb @@ -10,9 +10,11 @@ class FixedTwitterTicketArticlePreferences4 < ActiveRecord::Migration[5.0] article_ids.each do |article_id| article = Ticket::Article.find(article_id) next if !article.preferences + changed = false article.preferences.each_value do |value| next if value.class != ActiveSupport::HashWithIndifferentAccess + value.each do |sub_key, sub_level| if sub_level.class == NilClass value[sub_key] = nil @@ -24,11 +26,13 @@ class FixedTwitterTicketArticlePreferences4 < ActiveRecord::Migration[5.0] next end next if sub_level.class != Twitter::NullObject + value[sub_key] = nil changed = true end end next if !changed + article.save! end diff --git a/db/migrate/20170924054554_weibo_oauth2.rb b/db/migrate/20170924054554_weibo_oauth2.rb index 0ad4ba7bd..39df6a38f 100644 --- a/db/migrate/20170924054554_weibo_oauth2.rb +++ b/db/migrate/20170924054554_weibo_oauth2.rb @@ -3,6 +3,7 @@ class WeiboOauth2 < ActiveRecord::Migration[4.2] # return if it's a new setup return if !Setting.find_by(name: 'system_init_done') + Setting.create_if_not_exists( title: 'Authentication via %s', name: 'auth_weibo', diff --git a/db/migrate/20170927000001_setting_send_no_auto_response_reg_exp.rb b/db/migrate/20170927000001_setting_send_no_auto_response_reg_exp.rb index 781165172..a4d280ca9 100644 --- a/db/migrate/20170927000001_setting_send_no_auto_response_reg_exp.rb +++ b/db/migrate/20170927000001_setting_send_no_auto_response_reg_exp.rb @@ -6,6 +6,7 @@ class SettingSendNoAutoResponseRegExp < ActiveRecord::Migration[5.0] # improved domain name matching return if !Setting.find_by(name: 'send_no_auto_response_reg_exp') + Setting.set('send_no_auto_response_reg_exp', '(mailer-daemon|postmaster|abuse|root|noreply|noreply.+?|no-reply|no-reply.+?)@.+?') end diff --git a/db/migrate/20171023000001_fixed_store_upgrade_ror_45.rb b/db/migrate/20171023000001_fixed_store_upgrade_ror_45.rb index d66888068..4db8b86a9 100644 --- a/db/migrate/20171023000001_fixed_store_upgrade_ror_45.rb +++ b/db/migrate/20171023000001_fixed_store_upgrade_ror_45.rb @@ -3,6 +3,7 @@ class FixedStoreUpgradeRor45 < ActiveRecord::Migration[5.0] # return if it's a new setup return if !Setting.find_by(name: 'system_init_done') + Cache.clear [Macro, Taskbar, Calendar, Trigger, Channel, Job, PostmasterFilter, Report::Profile, Setting, Sla, Template].each do |class_name| class_name.all.each do |record| @@ -16,6 +17,7 @@ class FixedStoreUpgradeRor45 < ActiveRecord::Migration[5.0] Channel.all.each do |channel| next if channel.options.blank? + channel.options.each do |key, value| channel.options[key] = cleanup(value) end @@ -23,6 +25,7 @@ class FixedStoreUpgradeRor45 < ActiveRecord::Migration[5.0] end User.with_permissions('ticket.agent').each do |user| next if user.preferences.blank? + user.preferences.each do |key, value| user.preferences[key] = cleanup(value) end @@ -35,6 +38,7 @@ class FixedStoreUpgradeRor45 < ActiveRecord::Migration[5.0] value = value.permit!.to_h end return value if value.class != ActiveSupport::HashWithIndifferentAccess && value.class != Hash + value.each do |local_key, local_value| value[local_key] = cleanup(local_value) end diff --git a/db/migrate/20171203000001_setting_es_pipeline.rb b/db/migrate/20171203000001_setting_es_pipeline.rb index 2d7b9b667..81988acc1 100644 --- a/db/migrate/20171203000001_setting_es_pipeline.rb +++ b/db/migrate/20171203000001_setting_es_pipeline.rb @@ -3,6 +3,7 @@ class SettingEsPipeline < ActiveRecord::Migration[5.1] # return if it's a new setup return if !Setting.find_by(name: 'system_init_done') + Setting.create_if_not_exists( title: 'Elasticsearch Pipeline Name', name: 'es_pipeline', diff --git a/db/migrate/20171207000001_permission_user_preferences_out_of_office.rb b/db/migrate/20171207000001_permission_user_preferences_out_of_office.rb index 9d631b77b..b4191afd6 100644 --- a/db/migrate/20171207000001_permission_user_preferences_out_of_office.rb +++ b/db/migrate/20171207000001_permission_user_preferences_out_of_office.rb @@ -1,4 +1,3 @@ - class PermissionUserPreferencesOutOfOffice < ActiveRecord::Migration[5.1] def up diff --git a/db/migrate/20180202000002_custom_ldap_login_attribute.rb b/db/migrate/20180202000002_custom_ldap_login_attribute.rb index 60297d258..94017431e 100644 --- a/db/migrate/20180202000002_custom_ldap_login_attribute.rb +++ b/db/migrate/20180202000002_custom_ldap_login_attribute.rb @@ -39,6 +39,7 @@ class CustomLdapLoginAttribute < ActiveRecord::Migration[5.1] def no_change_needed? return true if ldap_config.blank? return true if ldap_config[:user_attributes].blank? + ldap_config[:user_attributes].values.count('login') < 2 end diff --git a/db/migrate/20180220000001_setting_attachment_preview.rb b/db/migrate/20180220000001_setting_attachment_preview.rb index a3ab60ac1..ef2357438 100644 --- a/db/migrate/20180220000001_setting_attachment_preview.rb +++ b/db/migrate/20180220000001_setting_attachment_preview.rb @@ -3,6 +3,7 @@ class SettingAttachmentPreview < ActiveRecord::Migration[5.1] # return if it's a new setup return if !Setting.find_by(name: 'system_init_done') + Setting.create_if_not_exists( title: 'Sidebar Attachments', name: 'ui_ticket_zoom_attachments_preview', diff --git a/db/migrate/20180220000002_setting_user_organization_selector_with_email.rb b/db/migrate/20180220000002_setting_user_organization_selector_with_email.rb index a55edcd63..156ffedf2 100644 --- a/db/migrate/20180220000002_setting_user_organization_selector_with_email.rb +++ b/db/migrate/20180220000002_setting_user_organization_selector_with_email.rb @@ -3,6 +3,7 @@ class SettingUserOrganizationSelectorWithEmail < ActiveRecord::Migration[5.1] # return if it's a new setup return if !Setting.find_by(name: 'system_init_done') + Setting.create_if_not_exists( title: 'User Organization Selector - email', name: 'ui_user_organization_selector_with_email', diff --git a/db/migrate/20180220171219_check_for_object_attributes.rb b/db/migrate/20180220171219_check_for_object_attributes.rb index d5988b903..27b5a9b36 100644 --- a/db/migrate/20180220171219_check_for_object_attributes.rb +++ b/db/migrate/20180220171219_check_for_object_attributes.rb @@ -22,17 +22,20 @@ class CheckForObjectAttributes < ActiveRecord::Migration[5.1] def fix_nil_data_option(attribute) return if attribute[:data_option].is_a?(Hash) || attribute[:data_option][:options].is_a?(Array) + attribute[:data_option] = {} end def fix_options(attribute) return if attribute[:data_option][:options].is_a?(Hash) return if attribute[:data_option][:options].is_a?(Array) + attribute[:data_option][:options] = {} end def fix_relation(attribute) return if attribute[:data_option][:relation].is_a?(String) + attribute[:data_option][:relation] = '' end end diff --git a/db/migrate/20180226085743_issue_1660_fix_tree_select_configurations.rb b/db/migrate/20180226085743_issue_1660_fix_tree_select_configurations.rb index 8ba55b99a..0b1d42e92 100644 --- a/db/migrate/20180226085743_issue_1660_fix_tree_select_configurations.rb +++ b/db/migrate/20180226085743_issue_1660_fix_tree_select_configurations.rb @@ -5,6 +5,7 @@ class Issue1660FixTreeSelectConfigurations < ActiveRecord::Migration[5.1] return if !Setting.find_by(name: 'system_init_done') return if attributes.blank? + attributes.each do |attribute| next if attribute.data_option.blank? diff --git a/db/migrate/20180410000001_cleanup_user_preferences_notification_sound2.rb b/db/migrate/20180410000001_cleanup_user_preferences_notification_sound2.rb index c1f3ff976..f71b3fe2b 100644 --- a/db/migrate/20180410000001_cleanup_user_preferences_notification_sound2.rb +++ b/db/migrate/20180410000001_cleanup_user_preferences_notification_sound2.rb @@ -17,12 +17,14 @@ class CleanupUserPreferencesNotificationSound2 < ActiveRecord::Migration[5.1] return false if !user.preferences return false if !user.preferences[:notification_sound] return false if !user.preferences[:notification_sound][:enabled] + if user.preferences[:notification_sound][:enabled] == 'true' user.preferences[:notification_sound][:enabled] = true user.save! return true end return false if user.preferences[:notification_sound][:enabled] != 'false' + user.preferences[:notification_sound][:enabled] = false user.save! true @@ -37,6 +39,7 @@ class CleanupUserPreferencesNotificationSound2 < ActiveRecord::Migration[5.1] items = SearchIndexBackend.search('preferences.notification_sound.enabled:*', 3000, 'User') || [] items.each do |item| next if !item[:id] + user = User.find_by(id: item[:id]) local_to_h!(user.preferences) local_clear_preferences(user) diff --git a/db/migrate/20180611070839_add_ux_flow_next_up_to_macros.rb b/db/migrate/20180611070839_add_ux_flow_next_up_to_macros.rb index e956fda35..655895966 100644 --- a/db/migrate/20180611070839_add_ux_flow_next_up_to_macros.rb +++ b/db/migrate/20180611070839_add_ux_flow_next_up_to_macros.rb @@ -11,6 +11,7 @@ class AddUxFlowNextUpToMacros < ActiveRecord::Migration[5.1] macro = Macro.find_by(name: 'Close & Tag as Spam') return if !macro + macro.ux_flow_next_up = 'next_task' macro.save! end diff --git a/db/migrate/20180628000001_fixed_twitter_ticket_article_preferences5.rb b/db/migrate/20180628000001_fixed_twitter_ticket_article_preferences5.rb index 59634974b..b36f6a860 100644 --- a/db/migrate/20180628000001_fixed_twitter_ticket_article_preferences5.rb +++ b/db/migrate/20180628000001_fixed_twitter_ticket_article_preferences5.rb @@ -10,9 +10,11 @@ class FixedTwitterTicketArticlePreferences5 < ActiveRecord::Migration[5.0] article_ids.each do |article_id| article = Ticket::Article.find(article_id) next if !article.preferences + changed = false article.preferences.each_value do |value| next if value.class != ActiveSupport::HashWithIndifferentAccess + value.each do |sub_key, sub_level| if sub_level.class == NilClass value[sub_key] = nil @@ -24,11 +26,13 @@ class FixedTwitterTicketArticlePreferences5 < ActiveRecord::Migration[5.0] next end next if sub_level.class != Twitter::NullObject + value[sub_key] = nil changed = true end end next if !changed + article.save! end diff --git a/db/migrate/20180719033247_add_confidential_to_doorkeeper_application.rb b/db/migrate/20180719033247_add_confidential_to_doorkeeper_application.rb index 4e209428e..f563a9669 100644 --- a/db/migrate/20180719033247_add_confidential_to_doorkeeper_application.rb +++ b/db/migrate/20180719033247_add_confidential_to_doorkeeper_application.rb @@ -1,6 +1,7 @@ class AddConfidentialToDoorkeeperApplication < ActiveRecord::Migration[5.1] def change return if ActiveRecord::Base.connection.column_exists?(:oauth_applications, :confidential) + add_column( :oauth_applications, :confidential, diff --git a/db/migrate/20180919000000_setting_update_pretty_date_format.rb b/db/migrate/20180919000000_setting_update_pretty_date_format.rb index c89703f12..85b80c4d6 100644 --- a/db/migrate/20180919000000_setting_update_pretty_date_format.rb +++ b/db/migrate/20180919000000_setting_update_pretty_date_format.rb @@ -6,6 +6,7 @@ class SettingUpdatePrettyDateFormat < ActiveRecord::Migration[5.1] setting = Setting.find_by(name: 'pretty_date_format') return if !setting + setting.options[:form][0][:options][:timestamp] = 'timestamp - e. g. "2018-08-30 14:30"' setting.save! end diff --git a/lib/app_version.rb b/lib/app_version.rb index 2c8fd0d69..4668aeea0 100644 --- a/lib/app_version.rb +++ b/lib/app_version.rb @@ -35,6 +35,7 @@ send also reload type to clients def self.set(reload_required = false, type = 'app_version') return false if !Setting.find_by(name: 'app_version') + version = "#{Time.zone.now.strftime('%Y%m%d%H%M%S')}:#{reload_required}" Setting.set('app_version', version) diff --git a/lib/application_handle_info.rb b/lib/application_handle_info.rb index 78d4586c1..c63c8627e 100644 --- a/lib/application_handle_info.rb +++ b/lib/application_handle_info.rb @@ -9,6 +9,7 @@ module ApplicationHandleInfo def self.postmaster? return false if current.blank? + current.split('.')[1] == 'postmaster' end end diff --git a/lib/auth.rb b/lib/auth.rb index 6ade62a6a..ad9dda285 100644 --- a/lib/auth.rb +++ b/lib/auth.rb @@ -23,6 +23,7 @@ returns return false if !user.active? return true if !user.max_login_failed? + Rails.logger.info "Max login failed reached for user #{user.login}." false @@ -96,6 +97,7 @@ returns # added configured backends Setting.where(area: 'Security::Authentication').each do |setting| next if setting.state_current[:value].blank? + config.push setting.state_current[:value] end diff --git a/lib/auth/developer.rb b/lib/auth/developer.rb index 99476113d..dbbf970fd 100644 --- a/lib/auth/developer.rb +++ b/lib/auth/developer.rb @@ -7,6 +7,7 @@ class Auth return false if user.blank? return false if Setting.get('developer_mode') != true return false if password != 'test' + Rails.logger.info "System in developer mode, authentication for user #{user.login} ok." true end diff --git a/lib/auth/ldap.rb b/lib/auth/ldap.rb index f72ab6fe0..09e9f8a06 100644 --- a/lib/auth/ldap.rb +++ b/lib/auth/ldap.rb @@ -8,6 +8,7 @@ class Auth def valid?(user, password) return false if !Setting.get('ldap_integration') + ldap_user = ::Ldap::User.new() # get from config or fallback to login diff --git a/lib/auto_wizard.rb b/lib/auto_wizard.rb index 362a0819d..f05522ab4 100644 --- a/lib/auto_wizard.rb +++ b/lib/auto_wizard.rb @@ -15,6 +15,7 @@ returns def self.enabled? auto_wizard_file_location = file_location return false if !File.file?(auto_wizard_file_location) + true end @@ -33,6 +34,7 @@ returns def self.data auto_wizard_file_location = file_location raise "So such file #{auto_wizard_file_location}" if !File.file?(auto_wizard_file_location) + JSON.parse(File.read(auto_wizard_file_location)) end @@ -93,6 +95,7 @@ returns } model_map.each do |map_name, model| next if !auto_wizard_hash[map_name] + auto_wizard_hash[map_name].each do |data| generic_object = Kernel.const_get(model) data.symbolize_keys! @@ -136,6 +139,7 @@ returns } model_map.each do |map_name, model| next if !auto_wizard_hash[map_name] + auto_wizard_hash[map_name].each do |data| generic_object = Kernel.const_get(model) data.symbolize_keys! diff --git a/lib/background_job_search_index.rb b/lib/background_job_search_index.rb index e05833cba..8550bead9 100644 --- a/lib/background_job_search_index.rb +++ b/lib/background_job_search_index.rb @@ -8,6 +8,7 @@ class BackgroundJobSearchIndex def perform record = @object.constantize.lookup(id: @o_id) return if !exists?(record) + record.search_index_update_backend end @@ -15,6 +16,7 @@ class BackgroundJobSearchIndex def exists?(record) return true if record + Rails.logger.info "Can't index #{@object}.lookup(id: #{@o_id}), no such record found" false end diff --git a/lib/calendar_subscriptions.rb b/lib/calendar_subscriptions.rb index 143e1130f..47d9effbc 100644 --- a/lib/calendar_subscriptions.rb +++ b/lib/calendar_subscriptions.rb @@ -16,6 +16,7 @@ class CalendarSubscriptions end return if @user.preferences[:calendar_subscriptions].blank? + @preferences = @preferences.merge(@user.preferences[:calendar_subscriptions]) end diff --git a/lib/core_ext/open-uri.rb b/lib/core_ext/open-uri.rb index 9d9db6602..592c96cb9 100644 --- a/lib/core_ext/open-uri.rb +++ b/lib/core_ext/open-uri.rb @@ -1,4 +1,5 @@ -if Kernel.respond_to?(:open_uri_original_open) # rubocop:disable Naming/FileName +# rubocop:disable Naming/FileName +if Kernel.respond_to?(:open_uri_original_open) module Kernel private @@ -14,6 +15,7 @@ if Kernel.respond_to?(:open_uri_original_open) # rubocop:disable Naming/FileName open_uri_original_open(name, *rest, &block) end end - module_function :open + module_function :open # rubocop:disable Style/AccessModifierDeclarations end end +# rubocop:enable Naming/FileName diff --git a/lib/core_ext/string.rb b/lib/core_ext/string.rb index 3b11bce6a..e658eaca3 100644 --- a/lib/core_ext/string.rb +++ b/lib/core_ext/string.rb @@ -87,6 +87,7 @@ class String # More details: http://pjambet.github.io/blog/emojis-and-mysql/ def utf8_to_3bytesutf8 return self if Rails.application.config.db_4bytes_utf8 + each_char.select do |c| if c.bytes.count > 3 Rails.logger.warn "strip out 4 bytes utf8 chars '#{c}' of '#{self}'" diff --git a/lib/enrichment/clearbit/organization.rb b/lib/enrichment/clearbit/organization.rb index 2477acd80..245d349f9 100644 --- a/lib/enrichment/clearbit/organization.rb +++ b/lib/enrichment/clearbit/organization.rb @@ -35,6 +35,7 @@ module Enrichment def mapping? @mapping = @config['organization_sync'].dup return false if @mapping.blank? + # TODO: Refactoring: # Currently all target keys are prefixed with # organization. @@ -54,11 +55,13 @@ module Enrichment def remote_id? return if !@payload['company'] + @remote_id = @payload['company']['id'] end def external_found? return true if @external_organization + @external_organization = ExternalSync.find_by( source: @source, source_id: @remote_id, @@ -94,6 +97,7 @@ module Enrichment object: organization, current_changes: @current_changes, ) + organization.save! ExternalSync.create( @@ -109,6 +113,7 @@ module Enrichment def load_previous_changes last_payload = @external_organization.last_payload return if !last_payload + @previous_changes = ExternalSync.map( mapping: @mapping, source: last_payload diff --git a/lib/enrichment/clearbit/user.rb b/lib/enrichment/clearbit/user.rb index e885f62d4..ab44f6544 100644 --- a/lib/enrichment/clearbit/user.rb +++ b/lib/enrichment/clearbit/user.rb @@ -31,6 +31,7 @@ module Enrichment end return false if !attributes_changed && !organization_synced + @local_user.save if attributes_changed || organization_synced true end @@ -40,6 +41,7 @@ module Enrichment def mapping? @mapping = @config['user_sync'].dup return false if @mapping.blank? + # TODO: Refactoring: # Currently all target keys are prefixed with # user. @@ -52,17 +54,20 @@ module Enrichment def load_remote(data) return if !remote_id?(data) return if !external_found? + load_previous_changes end def remote_id?(data) return if !data return if !data['person'] + @remote_id = data['person']['id'] end def external_found? return true if @external_user + @external_user = ExternalSync.find_by( source: @source, source_id: @remote_id, @@ -75,6 +80,7 @@ module Enrichment def load_previous_changes last_payload = @external_user.last_payload return if !last_payload + @previous_changes = ExternalSync.map( mapping: @mapping, source: last_payload diff --git a/lib/event_buffer.rb b/lib/event_buffer.rb index 95dc34095..7af1de9f7 100644 --- a/lib/event_buffer.rb +++ b/lib/event_buffer.rb @@ -20,6 +20,7 @@ module EventBuffer def self.reset(key) return if !Thread.current[:event_buffer] return if !Thread.current[:event_buffer][key] + Thread.current[:event_buffer][key] = [] end diff --git a/lib/external_credential/facebook.rb b/lib/external_credential/facebook.rb index 89546082f..ab18fe34d 100644 --- a/lib/external_credential/facebook.rb +++ b/lib/external_credential/facebook.rb @@ -8,6 +8,7 @@ class ExternalCredential::Facebook def self.request_account_to_link(credentials = {}) external_credential = ExternalCredential.find_by(name: 'facebook') raise Exceptions::UnprocessableEntity, 'No facebook app configured!' if !external_credential + if !credentials[:application_id] credentials[:application_id] = external_credential.credentials['application_id'] end @@ -32,6 +33,7 @@ class ExternalCredential::Facebook # fail if request_token.params[:oauth_token] != params[:state] external_credential = ExternalCredential.find_by(name: 'facebook') raise 'No such account' if !external_credential + oauth = Koala::Facebook::OAuth.new( external_credential.credentials['application_id'], external_credential.credentials['application_secret'], @@ -58,6 +60,7 @@ class ExternalCredential::Facebook next if !channel.options['user'] next if !channel.options['user']['id'] next if channel.options['user']['id'] != user['id'] + channel.options['auth']['access_token'] = access_token channel.options['pages'] = pages channel.save diff --git a/lib/external_credential/twitter.rb b/lib/external_credential/twitter.rb index 41b6165e3..adb792c33 100644 --- a/lib/external_credential/twitter.rb +++ b/lib/external_credential/twitter.rb @@ -8,6 +8,7 @@ class ExternalCredential::Twitter def self.request_account_to_link(credentials = {}) external_credential = ExternalCredential.find_by(name: 'twitter') raise Exceptions::UnprocessableEntity, 'No twitter app configured!' if !external_credential + if !credentials[:consumer_key] credentials[:consumer_key] = external_credential.credentials['consumer_key'] end @@ -29,6 +30,7 @@ class ExternalCredential::Twitter def self.link_account(request_token, params) raise if request_token.params[:oauth_token] != params[:oauth_token] + external_credential = ExternalCredential.find_by(name: 'twitter') access_token = request_token.get_access_token(oauth_verifier: params[:oauth_verifier]) client = Twitter::REST::Client.new( diff --git a/lib/facebook.rb b/lib/facebook.rb index 4d90f405b..32f697d41 100644 --- a/lib/facebook.rb +++ b/lib/facebook.rb @@ -36,6 +36,7 @@ disconnect client def disconnect return if !@client + @client = nil end @@ -104,9 +105,11 @@ result def user(item) return if !item['from'] return if !item['from']['id'] + cache_key = "FB:User:Lookup:#{item['from']['id']}" cache = Cache.get(cache_key) return cache if cache + begin result = @client.get_object(item['from']['id'], fields: 'first_name,last_name,email') rescue @@ -141,8 +144,10 @@ result # ignore if value is already set map.each do |target, source| next if user[target].present? + new_value = tweet_user.send(source).to_s next if new_value.blank? + user_data[target] = new_value end user.update!(user_data) @@ -309,6 +314,7 @@ result def to_group(post, group_id, channel, page) Rails.logger.debug { 'import post' } return if !post['message'] + ticket = nil # use transaction @@ -330,6 +336,7 @@ result if article[:type] != 'facebook feed comment' raise "Can't handle unknown facebook article type '#{article[:type]}'." end + Rails.logger.debug { 'Create feed comment from article...' } post = @client.put_comment(article[:in_reply_to], article[:body]) Rails.logger.debug { post.inspect } @@ -352,6 +359,7 @@ result return state if !ticket return ticket.state if ticket.state_id == state.id + Ticket::State.find_by(default_follow_up: true) end @@ -361,6 +369,7 @@ result next if !lookup[:page_id] && !lookup[:page] next if lookup[:page_id] && lookup[:page_id].to_s != page[:id] next if lookup[:page] && lookup[:page] != page[:name] + access_token = page[:access_token] break end @@ -378,6 +387,7 @@ result comments.each do |comment| user = to_user(comment) next if !user + article_data = { from: "#{user.firstname} #{user.lastname}", body: comment['message'], diff --git a/lib/fill_db.rb b/lib/fill_db.rb index fb3fa7fdf..5328184a3 100644 --- a/lib/fill_db.rb +++ b/lib/fill_db.rb @@ -170,6 +170,7 @@ or if you only want to create 100 tickets state_pool = Ticket::State.all return if !tickets || tickets.zero? + (1..tickets).each do ActiveRecord::Base.transaction do customer = customer_pool[ rand(customer_pool.length - 1) ] diff --git a/lib/html_sanitizer.rb b/lib/html_sanitizer.rb index e72173785..8077e81a6 100644 --- a/lib/html_sanitizer.rb +++ b/lib/html_sanitizer.rb @@ -36,6 +36,7 @@ satinize html string based on whiltelist .reject { |u| u.match?(/^[^:]+:$/) } # URI::extract will match, e.g., 'tel:' next if urls.blank? + add_link(node.content, urls, node) end @@ -50,6 +51,7 @@ satinize html string based on whiltelist end next if !href_without_spaces.downcase.start_with?('http', 'ftp', '//') + node.set_attribute('href', href) node.set_attribute('rel', 'nofollow noreferrer noopener') node.set_attribute('target', '_blank') @@ -106,6 +108,7 @@ satinize html string based on whiltelist class_new = '' classes.each do |local_class| next if !classes_whitelist.include?(local_class.to_s.strip) + if class_new != '' class_new += ' ' end @@ -121,6 +124,7 @@ satinize html string based on whiltelist # move style attributes to css attributes attributes_2_css.each do |key| next if !node[key] + if node['style'].blank? node['style'] = '' else @@ -129,6 +133,7 @@ satinize html string based on whiltelist value = node[key] node.delete(key) next if value.blank? + value += 'px' if !value.match?(/%|px|em/i) node['style'] += "#{key}:#{value}" end @@ -140,10 +145,12 @@ satinize html string based on whiltelist pears.each do |local_pear| prop = local_pear.split(':') next if !prop[0] + key = prop[0].strip next if !css_properties_whitelist.include?(node.name) next if !css_properties_whitelist[node.name].include?(key) next if css_values_blacklist[node.name]&.include?(local_pear.gsub(/[[:space:]]/, '').strip) + style += "#{local_pear};" end node['style'] = style @@ -155,8 +162,10 @@ satinize html string based on whiltelist # scan for invalid link content %w[href style].each do |attribute_name| next if !node[attribute_name] + href = cleanup_target(node[attribute_name]) next if href !~ /(javascript|livescript|vbscript):/i + node.delete(attribute_name) end @@ -164,6 +173,7 @@ satinize html string based on whiltelist node.each do |attribute, _value| attribute_name = attribute.downcase next if attributes_whitelist[:all].include?(attribute_name) || (attributes_whitelist[node.name]&.include?(attribute_name)) + node.delete(attribute) end @@ -225,6 +235,7 @@ cleanup html string: tags_backlist = %w[span center] scrubber = Loofah::Scrubber.new do |node| next if !tags_backlist.include?(node.name) + hit = false local_node = nil (1..5).each do |_count| @@ -235,9 +246,11 @@ cleanup html string: end break if !local_node next if local_node.name != 'td' + hit = true end next if hit && node.keys.count.positive? + node.replace cleanup_replace_tags(node.children.to_s) Loofah::Scrubber::STOP end @@ -352,12 +365,14 @@ cleanup html string: text = Nokogiri::XML::Text.new(pre, node.document) node.add_next_sibling(text).add_next_sibling(a) return if post.blank? + add_link(post, urls, a) return end node.content = pre node.add_next_sibling(a) return if post.blank? + add_link(post, urls, a) end @@ -404,6 +419,7 @@ cleanup html string: return true if url_new == "http://#{url_old}" return true if url_old == "https://#{url_new}" return true if url_new == "https://#{url_old}" + false end @@ -465,6 +481,7 @@ satinize style of img tags pears.each do |local_pear| prop = local_pear.split(':') next if !prop[0] + key = prop[0].strip if key == 'height' key = 'max-height' diff --git a/lib/idoit.rb b/lib/idoit.rb index cf487c6fc..4fda0c006 100644 --- a/lib/idoit.rb +++ b/lib/idoit.rb @@ -127,6 +127,7 @@ or with filter: if result.data['result'].class == Array result.data['result'].each do |item| next if !item['id'] + item['link'] = "#{_url_cleanup_baseurl(url)}/?objID=#{item['id']}" item['link'].gsub!(%r{([^:])//+}, '\\1/') end @@ -137,6 +138,7 @@ or with filter: def self._url_cleanup(url) url.strip! raise "Invalid endpoint '#{url}', need to start with http:// or https://" if url !~ %r{^http(s|)://}i + url = _url_cleanup_baseurl(url) url = "#{url}/src/jsonrpc.php" url.gsub(%r{([^:])//+}, '\\1/') @@ -145,6 +147,7 @@ or with filter: def self._url_cleanup_baseurl(url) url.strip! raise "Invalid endpoint '#{url}', need to start with http:// or https://" if url !~ %r{^http(s|)://}i + url.gsub!(%r{src/jsonrpc.php}, '') url.gsub(%r{([^:])//+}, '\\1/') end diff --git a/lib/import/base_factory.rb b/lib/import/base_factory.rb index 26d52ef43..0b77ce75c 100644 --- a/lib/import/base_factory.rb +++ b/lib/import/base_factory.rb @@ -8,6 +8,7 @@ module Import pre_import_hook(records, *args) import_loop(records, *args) do |record| next if skip?(record, *args) + backend_instance = create_instance(record, *args) post_import_hook(record, backend_instance, *args) end diff --git a/lib/import/exchange/item_attributes.rb b/lib/import/exchange/item_attributes.rb index 4eb111bfa..1ed7a33dc 100644 --- a/lib/import/exchange/item_attributes.rb +++ b/lib/import/exchange/item_attributes.rb @@ -25,6 +25,7 @@ module Import properties.each do |key, value| if value.is_a?(String) next if !%w[true false].include?(value) + properties[key] = value == 'true' elsif value.is_a?(Hash) properties[key] = booleanize_values(value) diff --git a/lib/import/helper.rb b/lib/import/helper.rb index e0b1d1a66..abc999571 100644 --- a/lib/import/helper.rb +++ b/lib/import/helper.rb @@ -6,11 +6,13 @@ module Import def check_import_mode # check if system is in import mode return true if Setting.get('import_mode') + raise 'System is not in import mode!' end def check_system_init_done return true if !Setting.get('system_init_done') + raise 'System is already system_init_done!' end @@ -23,6 +25,7 @@ module Import data.each do |key, value| next if !value next if !value.respond_to?(:utf8_encode) + data[key] = value.utf8_encode end end diff --git a/lib/import/helper/attributes_examples.rb b/lib/import/helper/attributes_examples.rb index ef2e9ba4d..fcdf4c94e 100644 --- a/lib/import/helper/attributes_examples.rb +++ b/lib/import/helper/attributes_examples.rb @@ -21,6 +21,7 @@ module Import # extractor.extract(attributes) # end return if !block_given? + if block.arity.zero? instance_eval(&block) else diff --git a/lib/import/integration_base.rb b/lib/import/integration_base.rb index 40380f5ec..eeac68182 100644 --- a/lib/import/integration_base.rb +++ b/lib/import/integration_base.rb @@ -95,6 +95,7 @@ module Import # return [nil] def start return if !requirements_completed? + start_import end @@ -130,6 +131,7 @@ module Import end return true if !message + inform(message) false end diff --git a/lib/import/otrs.rb b/lib/import/otrs.rb index 147a2d5f3..d058e3ea6 100644 --- a/lib/import/otrs.rb +++ b/lib/import/otrs.rb @@ -135,6 +135,7 @@ module Import def imported?(args) log "loading #{args[:limit]} #{args[:remote_object]} starting at #{args[:offset]}..." return false if !import_action(args[:remote_object], limit: args[:limit], offset: args[:offset], diff: args[:diff]) + true end diff --git a/lib/import/otrs/article.rb b/lib/import/otrs/article.rb index bd8db5c03..3931f4de1 100644 --- a/lib/import/otrs/article.rb +++ b/lib/import/otrs/article.rb @@ -46,12 +46,14 @@ module Import def create_or_update(article) return if updated?(article) + create(article) end def updated?(article) @local_article = ::Ticket::Article.find_by(id: article[:id]) return false if !@local_article + log "update Ticket::Article.find_by(id: #{article[:id]})" @local_article.update!(article) true @@ -89,6 +91,7 @@ module Import # so Zammad can set the default content type mapped.delete(:content_type) if mapped[:content_type].blank? return mapped if !mapped[:content_type] + mapped[:content_type].sub!(/[;,]\s?.+?$/, '') mapped end diff --git a/lib/import/otrs/article/attachment_factory.rb b/lib/import/otrs/article/attachment_factory.rb index 45e987486..e7f799913 100644 --- a/lib/import/otrs/article/attachment_factory.rb +++ b/lib/import/otrs/article/attachment_factory.rb @@ -12,6 +12,7 @@ module Import local_article = args[:local_article] return if skip_import?(attachments, local_article) + perform_import(attachments, local_article) end @@ -65,9 +66,11 @@ module Import def skip_import?(attachments, local_article) local_attachments = local_article.attachments return true if local_attachments.count == attachments.count + # get a common ground local_attachments.each(&:delete) return true if attachments.blank? + false end @@ -79,6 +82,7 @@ module Import @sha_queue[sha] ||= [] return if !queueing_active? + @sha_queue[sha].push(queue_id) while @sha_queue[sha].first != queue_id @@ -90,11 +94,13 @@ module Import def queue_cleanup(sha) return if !queueing_active? + @sha_queue[sha].shift end def queueing_active? return if !queue_id + true end diff --git a/lib/import/otrs/article_customer.rb b/lib/import/otrs/article_customer.rb index d4f478730..31f3c5cdc 100644 --- a/lib/import/otrs/article_customer.rb +++ b/lib/import/otrs/article_customer.rb @@ -14,6 +14,7 @@ module Import def find(article) email = local_email(article['From']) return if !email + user = ::User.find_by(email: email) user ||= ::User.find_by(login: email) user @@ -23,6 +24,7 @@ module Import # TODO: should get unified with User#check_email email = extract_email(from) return if !email + email.downcase end @@ -32,6 +34,7 @@ module Import Mail::Address.new(from).address rescue return from if from !~ /<\s*([^>]+)/ + $1.strip end end @@ -44,6 +47,7 @@ module Import def find_or_create(article) return if self.class.find(article) + create(article) end @@ -85,6 +89,7 @@ module Import parsed_address = Mail::Address.new(from) return parsed_address.display_name if parsed_address.display_name return from if parsed_address.comments.blank? + parsed_address.comments[0] rescue from diff --git a/lib/import/otrs/article_customer_factory.rb b/lib/import/otrs/article_customer_factory.rb index e2db53431..1db84192b 100644 --- a/lib/import/otrs/article_customer_factory.rb +++ b/lib/import/otrs/article_customer_factory.rb @@ -7,6 +7,7 @@ module Import return true if record['SenderType'] != 'customer' return true if record['CreatedBy'].to_i != 1 return true if record['From'].blank? + false end end diff --git a/lib/import/otrs/async.rb b/lib/import/otrs/async.rb index 5b74a6e91..d5a7b0625 100644 --- a/lib/import/otrs/async.rb +++ b/lib/import/otrs/async.rb @@ -52,6 +52,7 @@ module Import def status_bg state = Cache.get('import:state') return state if state + { message: 'not running', } diff --git a/lib/import/otrs/customer.rb b/lib/import/otrs/customer.rb index ef4c4d8c6..b2cdafdd6 100644 --- a/lib/import/otrs/customer.rb +++ b/lib/import/otrs/customer.rb @@ -23,6 +23,7 @@ module Import result = nil organizations.each do |organization| next if customer_id != organization['CustomerID'] + result = Organization.find_by(name: organization['CustomerCompanyName']) break end @@ -37,12 +38,14 @@ module Import def create_or_update(customer) return if updated?(customer) + create(customer) end def updated?(customer) @local_customer = Organization.find_by(name: customer[:name]) return false if !@local_customer + log "update Organization.find_by(name: #{customer[:name]})" @local_customer.update!(customer) true diff --git a/lib/import/otrs/customer_user.rb b/lib/import/otrs/customer_user.rb index 0d42816dd..1170f7161 100644 --- a/lib/import/otrs/customer_user.rb +++ b/lib/import/otrs/customer_user.rb @@ -36,6 +36,7 @@ module Import def create_or_update(customer) return if updated?(customer) + create(customer) end @@ -92,8 +93,10 @@ module Import def organization_id(customer) return if !customer['UserCustomerID'] + organization = Import::OTRS::Customer.by_customer_id(customer['UserCustomerID']) return if !organization + organization.id end end diff --git a/lib/import/otrs/diff.rb b/lib/import/otrs/diff.rb index 40104614b..882d91ac1 100644 --- a/lib/import/otrs/diff.rb +++ b/lib/import/otrs/diff.rb @@ -6,11 +6,13 @@ module Import def diff_worker return if !diff_import_possible? + diff end def diff? return true if @diff + false end @@ -19,6 +21,7 @@ module Import def diff_import_possible? return if !Setting.get('import_mode') return if Setting.get('import_otrs_endpoint') == 'http://otrs_host/otrs' + true end diff --git a/lib/import/otrs/dynamic_field_factory.rb b/lib/import/otrs/dynamic_field_factory.rb index 549853c22..b4df8bdc5 100644 --- a/lib/import/otrs/dynamic_field_factory.rb +++ b/lib/import/otrs/dynamic_field_factory.rb @@ -10,6 +10,7 @@ module Import def skip?(record, *_args) return true if skip_field?(record['Name']) return false if importable?(record) + @skip_fields.push(record['Name']) true end @@ -26,17 +27,20 @@ module Import def importable?(dynamic_field) return false if !supported_object_type?(dynamic_field) + supported_field_type?(dynamic_field) end def supported_object_type?(dynamic_field) return true if dynamic_field['ObjectType'] == 'Ticket' + log "ERROR: Unsupported dynamic field object type '#{dynamic_field['ObjectType']}' for dynamic field '#{dynamic_field['Name']}'" false end def supported_field_type?(dynamic_field) return true if supported_field_types.include?(dynamic_field['FieldType']) + log "ERROR: Unsupported dynamic field field type '#{dynamic_field['FieldType']}' for dynamic field '#{dynamic_field['Name']}'" false end @@ -47,6 +51,7 @@ module Import def skip_fields return @skip_fields if @skip_fields + @skip_fields = %w[ProcessManagementProcessID ProcessManagementActivityID ZammadMigratorChanged ZammadMigratorChangedOld] end end diff --git a/lib/import/otrs/helper.rb b/lib/import/otrs/helper.rb index 784e7b247..cf53ffff2 100644 --- a/lib/import/otrs/helper.rb +++ b/lib/import/otrs/helper.rb @@ -13,6 +13,7 @@ module Import self.class::MAPPING.each do |key_sym, value| key = key_sym.to_s next if !record.key?(key) + result[value] = record[key] end result diff --git a/lib/import/otrs/history.rb b/lib/import/otrs/history.rb index 19e2b24e1..a95712925 100644 --- a/lib/import/otrs/history.rb +++ b/lib/import/otrs/history.rb @@ -28,6 +28,7 @@ module Import history_attribute = @history_attributes[:history_attribute] return if !history_attribute return if history_attribute_exists?(history_attribute) + @@created_history_attributes[history_attribute] = true ::History.attribute_lookup(history_attribute) end diff --git a/lib/import/otrs/history_factory.rb b/lib/import/otrs/history_factory.rb index 03d0604dc..f75c22b26 100644 --- a/lib/import/otrs/history_factory.rb +++ b/lib/import/otrs/history_factory.rb @@ -8,6 +8,7 @@ module Import def skip?(record, *_args) return true if !determine_class(record) + false end @@ -27,12 +28,14 @@ module Import def check_supported(history) return if !supported_types.include?(history['HistoryType']) + history['HistoryType'] end def check_article(history) return if !history['ArticleID'] return if history['ArticleID'].to_i.zero? + 'Article' end end diff --git a/lib/import/otrs/priority.rb b/lib/import/otrs/priority.rb index 784964003..be693b409 100644 --- a/lib/import/otrs/priority.rb +++ b/lib/import/otrs/priority.rb @@ -26,12 +26,14 @@ module Import def create_or_update(priority) return if updated?(priority) + create(priority) end def updated?(priority) @local_priority = ::Ticket::Priority.find_by(id: priority[:id]) return false if !@local_priority + log "update Ticket::Priority.find_by(id: #{priority[:id]})" @local_priority.update!(priority) true diff --git a/lib/import/otrs/priority_factory.rb b/lib/import/otrs/priority_factory.rb index 7122dfa8f..353c4a005 100644 --- a/lib/import/otrs/priority_factory.rb +++ b/lib/import/otrs/priority_factory.rb @@ -13,6 +13,7 @@ module Import def update_attribute_settings return if Import::OTRS.diff? + update_attribute end diff --git a/lib/import/otrs/queue.rb b/lib/import/otrs/queue.rb index 2ccfe99ce..a50e0f21d 100644 --- a/lib/import/otrs/queue.rb +++ b/lib/import/otrs/queue.rb @@ -26,12 +26,14 @@ module Import def create_or_update(queue) return if updated?(queue) + create(queue) end def updated?(queue) @local_queue = Group.find_by(id: queue[:id]) return false if !@local_queue + log "update Group.find_by(id: #{queue[:id]})" @local_queue.update!(queue) true diff --git a/lib/import/otrs/requester.rb b/lib/import/otrs/requester.rb index 2e27c6f7f..d9564cd3e 100644 --- a/lib/import/otrs/requester.rb +++ b/lib/import/otrs/requester.rb @@ -40,6 +40,7 @@ module Import ) return result if opts.present? + @cache[object] = result @cache[object] end @@ -67,6 +68,7 @@ module Import def connection_test result = request_json({}) raise 'API key not valid!' if !result['Success'] + true end @@ -90,6 +92,7 @@ module Import response = post(params) result = handle_response(response) raise 'Invalid response' if !result + result end diff --git a/lib/import/otrs/state.rb b/lib/import/otrs/state.rb index 416654b3f..946d5bdc6 100644 --- a/lib/import/otrs/state.rb +++ b/lib/import/otrs/state.rb @@ -27,12 +27,14 @@ module Import def create_or_update(state) return if updated?(state) + create(state) end def updated?(state) @local_state = ::Ticket::State.find_by(id: state[:id]) return false if !@local_state + log "update Ticket::State.find_by(id: #{state[:id]})" @local_state.update!(state) true @@ -63,6 +65,7 @@ module Import def map_type(state) return if state['TypeName'] != 'pending auto' + state['TypeName'] = 'pending action' end end diff --git a/lib/import/otrs/ticket.rb b/lib/import/otrs/ticket.rb index 38cc934f5..ba430f93b 100644 --- a/lib/import/otrs/ticket.rb +++ b/lib/import/otrs/ticket.rb @@ -43,12 +43,14 @@ module Import def create_or_update(ticket) return if updated?(ticket) + create(ticket) end def updated?(ticket) @local_ticket = ::Ticket.find_by(id: ticket[:id]) return false if !@local_ticket + log "update Ticket.find_by(id: #{ticket[:id]})" @local_ticket.update!(ticket) true @@ -70,6 +72,7 @@ module Import def ensure_map(mapped) return mapped if mapped[:title] + mapped[:title] = '**EMPTY**' mapped end @@ -92,9 +95,11 @@ module Import key_string = key.to_s next if !key_string.start_with?('DynamicField_') + dynamic_field_name = key_string[13, key_string.length] next if Import::OTRS::DynamicFieldFactory.skip_field?( dynamic_field_name ) + dynamic_field_name = Import::OTRS::DynamicField.convert_name(dynamic_field_name) result[dynamic_field_name.to_sym] = ticket[key_string] @@ -107,9 +112,11 @@ module Import owner = ticket['Owner'] return default if !owner + user = user_lookup(owner) return user.id if user + default end @@ -133,6 +140,7 @@ module Import return ticket['CreateBy'] if ticket['CreateBy'].to_i != default return default if ticket['Articles'].blank? return default if ticket['Articles'].first['SenderType'] != 'customer' + customer_id(ticket) end @@ -145,8 +153,10 @@ module Import articles.each do |article| next if article['SenderType'] != 'customer' next if article['From'].blank? + user = Import::OTRS::ArticleCustomer.find(article) break if !user + user_id = user.id break end @@ -163,6 +173,7 @@ module Import def fix_timestamps(ticket) ticket.each do |key, value| next if value != '0000-00-00 00:00:00' + ticket[key] = nil end end @@ -172,6 +183,7 @@ module Import return if ticket['StateType'] != 'closed' return if ticket['Closed'] return if ticket['Closed'].present? + ticket['Closed'] = ticket['Created'] end end diff --git a/lib/import/otrs/user.rb b/lib/import/otrs/user.rb index be086603c..b2040c67f 100644 --- a/lib/import/otrs/user.rb +++ b/lib/import/otrs/user.rb @@ -30,6 +30,7 @@ module Import def create_or_update(user) ensure_unique_login(user) return if updated?(user) + create(user) end @@ -62,6 +63,7 @@ module Import def unique_login(user) login = user[:login] return login if ::User.where('login = ? AND id != ?', login.downcase, user[:id]).count.zero? + "#{login}_#{user[:id]}" end @@ -87,6 +89,7 @@ module Import def password(user) return if !user['UserPw'] + "{sha2}#{user['UserPw']}" end @@ -118,6 +121,7 @@ module Import roles(user).each do |role| role_lookup = Role.lookup(name: role) next if !role_lookup + local_role_ids.push role_lookup.id end local_role_ids @@ -147,6 +151,7 @@ module Import result = [] return result if role_object.blank? return result if role_object['GroupIDs'].blank? + permissions = role_object['GroupIDs'][ group['ID'] ] return result if !permissions @@ -167,6 +172,7 @@ module Import roles = Import::OTRS::Requester.load('Role') roles.each do |role| next if !user['RoleIDs'].include?(role['ID']) + result += groups_from_otrs_groups(role) end result diff --git a/lib/ldap.rb b/lib/ldap.rb index 2e732b8ac..4599f7203 100644 --- a/lib/ldap.rb +++ b/lib/ldap.rb @@ -183,6 +183,7 @@ class Ldap @host_url = @config[:host_url] return if @host_url.blank? raise "Invalid host url '#{@host_url}'" if @host_url !~ %r{\A([^:]+)://(.+?)/?\z} + @protocol = $1.to_sym @host = $2 @ssl = @protocol == :ldaps @@ -190,18 +191,21 @@ class Ldap def parse_host return if @host !~ /\A([^:]+):(.+?)\z/ + @host = $1 @port = $2.to_i end def handle_ssl_config return if !@ssl + @port ||= @config.fetch(:port, 636) @encryption = { method: :simple_tls, } return if @config[:ssl_verify] + @encryption[:tls_options] = { verify_mode: OpenSSL::SSL::VERIFY_NONE } diff --git a/lib/ldap/filter_lookup.rb b/lib/ldap/filter_lookup.rb index ee0680758..c39c92b55 100644 --- a/lib/ldap/filter_lookup.rb +++ b/lib/ldap/filter_lookup.rb @@ -12,6 +12,7 @@ class Ldap result = nil possible_filters.each do |possible_filter| next if !@ldap.entries?(possible_filter) + result = possible_filter break end diff --git a/lib/ldap/group.rb b/lib/ldap/group.rb index 2ce254d2a..046c5e57a 100644 --- a/lib/ldap/group.rb +++ b/lib/ldap/group.rb @@ -96,6 +96,7 @@ class Ldap result[user_dn_key] ||= [] next if result[user_dn_key].include?(role) + result[user_dn_key].push(role) end end @@ -130,6 +131,7 @@ class Ldap def handle_config(config) return if config.blank? + @uid_attribute = config[:uid_attribute] @filter = config[:filter] end diff --git a/lib/ldap/guid.rb b/lib/ldap/guid.rb index 562aceb2a..ecb168283 100644 --- a/lib/ldap/guid.rb +++ b/lib/ldap/guid.rb @@ -96,6 +96,7 @@ class Ldap # add dashes if requested return result if !dashify + [ result[0..7], result[8..11], diff --git a/lib/ldap/user.rb b/lib/ldap/user.rb index 0d39bb00a..bb9689dfc 100644 --- a/lib/ldap/user.rb +++ b/lib/ldap/user.rb @@ -62,6 +62,7 @@ class Ldap result = nil %i[objectguid entryuuid samaccountname userprincipalname uid dn].each do |attribute| next if attributes[attribute].blank? + result = attribute.to_s break end @@ -182,6 +183,7 @@ class Ldap def handle_config return if config.blank? + @uid_attribute = config[:uid_attribute] @filter = config[:filter] end diff --git a/lib/models.rb b/lib/models.rb index e613f20b8..5b470bd89 100644 --- a/lib/models.rb +++ b/lib/models.rb @@ -42,10 +42,13 @@ returns next if !model_class next if !model_class.respond_to? :new next if !model_class.respond_to? :table_name + table_name = model_class.table_name # handle models where not table exists, pending migrations next if !tables.include?(table_name) + model_object = model_class.new next if !model_object.respond_to? :attributes + all[model_class] = {} all[model_class][:attributes] = model_class.attribute_names all[model_class][:reflections] = model_class.reflections @@ -136,11 +139,13 @@ returns end next if !model_attributes[:attributes] + ref_attributes.each do |item| next if !model_attributes[:attributes].include?(item) count = model_class.where("#{item} = ?", object_id).count next if count.zero? + if !references[model_class.to_s][item] references[model_class.to_s][item] = 0 end @@ -152,15 +157,18 @@ returns # find relations via reflections list.each do |model_class, model_attributes| next if !model_attributes[:reflections] + model_attributes[:reflections].each_value do |reflection_value| next if reflection_value.macro != :belongs_to + col_name = "#{reflection_value.name}_id" next if ref_attributes.include?(col_name) if reflection_value.options[:class_name] == object_name count = model_class.where("#{col_name} = ?", object_id).count next if count.zero? + if !references[model_class.to_s][col_name] references[model_class.to_s][col_name] = 0 end @@ -173,6 +181,7 @@ returns count = model_class.where("#{col_name} = ?", object_id).count next if count.zero? + if !references[model_class.to_s][col_name] references[model_class.to_s][col_name] = 0 end @@ -184,6 +193,7 @@ returns # cleanup, remove models with empty references references.each do |k, v| next if v.present? + references.delete(k) end diff --git a/lib/notification_factory/mailer.rb b/lib/notification_factory/mailer.rb index 352d4083c..7841d6513 100644 --- a/lib/notification_factory/mailer.rb +++ b/lib/notification_factory/mailer.rb @@ -32,6 +32,7 @@ returns return if !user.preferences return if !user.preferences['notification_config'] + matrix = user.preferences['notification_config']['matrix'] return if !matrix @@ -79,11 +80,14 @@ returns end end return if !matrix[type] + data = matrix[type] return if !data return if !data['criteria'] + channels = data['channel'] return if !channels + if data['criteria']['owned_by_me'] && owned_by_me return { user: user, @@ -97,6 +101,7 @@ returns } end return if !data['criteria']['no'] + { user: user, channels: channels @@ -212,6 +217,7 @@ retunes next if item['object'] != 'Ticket' next if item['value_to'] !~ /#{recipient.email}/i next if item['value_to'] !~ /#{type}/i + count += 1 end count diff --git a/lib/notification_factory/renderer.rb b/lib/notification_factory/renderer.rb index 0a55064cf..01e9b371e 100644 --- a/lib/notification_factory/renderer.rb +++ b/lib/notification_factory/renderer.rb @@ -66,6 +66,7 @@ examples how to use # if no object is given, just return return '#{no such object}' if object_name.blank? # rubocop:disable Lint/InterpolationCheck + object_refs = @objects[object_name] || @objects[object_name.to_sym] # if object is not in avalable objects, just return @@ -75,6 +76,7 @@ examples how to use if object_methods.blank? && object_refs.class != String && object_refs.class != Float && object_refs.class != Integer return "\#{#{key} / no such method}" end + object_methods_s = '' object_methods.each do |method_raw| @@ -127,6 +129,7 @@ examples how to use # h('fqdn', htmlEscape) def h(key) return key if !key + CGI.escapeHTML(key.to_s) end @@ -135,11 +138,13 @@ examples how to use def escaping(key, escape) return key if escape == false return key if escape.nil? && !@escape + h key end def data_key_valid?(key) return false if key =~ /`|\.(|\s*)(save|destroy|delete|remove|drop|update|create|new|all|where|find|raise|dump|rollback|freeze)/i && key !~ /(update|create)d_(at|by)/i + true end diff --git a/lib/password_hash.rb b/lib/password_hash.rb index b65017065..4c94a08c6 100644 --- a/lib/password_hash.rb +++ b/lib/password_hash.rb @@ -19,12 +19,14 @@ module PasswordHash return false if !pw_hash return true if hashed_argon2?(pw_hash) return true if hashed_sha2?(pw_hash) + false end def legacy?(pw_hash, password) return false if pw_hash.blank? return false if !password + sha2?(pw_hash, password) end @@ -46,6 +48,7 @@ module PasswordHash def sha2?(pw_hash, password) return false if !hashed_sha2?(pw_hash) + pw_hash == sha2(password) end diff --git a/lib/push_messages.rb b/lib/push_messages.rb index b1b2a8ff1..fcb9d9ab1 100644 --- a/lib/push_messages.rb +++ b/lib/push_messages.rb @@ -2,11 +2,13 @@ module PushMessages def self.enabled? return true if Thread.current[:push_messages].class == Array + false end def self.init return true if enabled? + Thread.current[:push_messages] = [] end @@ -34,6 +36,7 @@ module PushMessages def self.finish return false if !enabled? + Thread.current[:push_messages].each do |message| if message[:type] == 'send_to' Sessions.send_to(message[:user_id], message[:data]) diff --git a/lib/report/base.rb b/lib/report/base.rb index b43801452..9856e2878 100644 --- a/lib/report/base.rb +++ b/lib/report/base.rb @@ -236,6 +236,7 @@ class Report::Base ticket_list.each do |ticket| timestamp = ticket[ data[:type].to_sym ] next if !timestamp + # puts 'FR:' + first_response.to_s # puts 'CT:' + ticket.created_at.to_s diff = timestamp - ticket.created_at @@ -268,6 +269,7 @@ class Report::Base ticket_list.each do |ticket| timestamp = ticket[ data[:type].to_sym ] next if !timestamp + ticket_ids.push ticket.id # puts 'FR:' + first_response.to_s # puts 'CT:' + ticket.created_at.to_s @@ -305,6 +307,7 @@ class Report::Base ticket_list.each do |ticket| timestamp = ticket[ data[:type].to_sym ] next if !timestamp + ticket_ids.push ticket.id # puts "#{data[:type].to_s} - #{timestamp} - #{ticket.inspect}" # puts 'FR:' + ticket.first_response.to_s diff --git a/lib/report/ticket_generic_time.rb b/lib/report/ticket_generic_time.rb index c1c0657db..cd0a0bc59 100644 --- a/lib/report/ticket_generic_time.rb +++ b/lib/report/ticket_generic_time.rb @@ -75,6 +75,7 @@ returns if !result_es['aggregations']['time_buckets']['buckets'] raise "Invalid es result, no buckets #{result_es.inspect}" end + result_es['aggregations']['time_buckets']['buckets'].each do |item| if params[:interval] == 'minute' item['key_as_string'] = item['key_as_string'].sub(/:\d\d.\d\d\dZ$/, '') @@ -85,6 +86,7 @@ returns next if !item['doc_count'] next if item['key_as_string'] !~ /#{start_string}/ next if match + match = true result.push item['doc_count'] if params[:interval] == 'month' @@ -100,6 +102,7 @@ returns end end next if match + result.push 0 if params[:interval] == 'month' start = start.next_month @@ -163,6 +166,7 @@ returns result = SearchIndexBackend.selectors(['Ticket'], selector, limit, nil, aggs_interval) return result if params[:sheet].present? + assets = {} result[:ticket_ids].each do |ticket_id| ticket_full = Ticket.find(ticket_id) diff --git a/lib/report/ticket_moved.rb b/lib/report/ticket_moved.rb index 8ed7dccc5..76f1ded24 100644 --- a/lib/report/ticket_moved.rb +++ b/lib/report/ticket_moved.rb @@ -138,6 +138,7 @@ returns local_params = defaults.merge(local_params) result = history(local_params) return result if params[:sheet].present? + assets = {} result[:ticket_ids].each do |ticket_id| ticket_full = Ticket.find(ticket_id) diff --git a/lib/report/ticket_reopened.rb b/lib/report/ticket_reopened.rb index 405848482..a8f21eeb2 100644 --- a/lib/report/ticket_reopened.rb +++ b/lib/report/ticket_reopened.rb @@ -107,6 +107,7 @@ returns selector: params[:selector] ) return result if params[:sheet].present? + assets = {} result[:ticket_ids].each do |ticket_id| ticket_full = Ticket.find(ticket_id) @@ -120,6 +121,7 @@ returns key = 'Report::TicketReopened::StateList' ticket_state_ids = Cache.get( key ) return ticket_state_ids if ticket_state_ids + ticket_state_types = Ticket::StateType.where( name: %w[closed merged removed] ) ticket_state_ids = [] ticket_state_types.each do |ticket_state_type| diff --git a/lib/search_index_backend.rb b/lib/search_index_backend.rb index 7bea80d09..f1735c172 100644 --- a/lib/search_index_backend.rb +++ b/lib/search_index_backend.rb @@ -13,6 +13,7 @@ info about used search index machine def self.info url = Setting.get('es_url').to_s return if url.blank? + Rails.logger.info "# curl -X GET \"#{url}\"" response = UserAgent.get( url, @@ -29,8 +30,10 @@ info about used search index machine if response.success? installed_version = response.data.dig('version', 'number') raise "Unable to get elasticsearch version from response: #{response.inspect}" if installed_version.blank? + version_supported = Gem::Version.new(installed_version) < Gem::Version.new('5.7') raise "Version #{installed_version} of configured elasticsearch is not supported" if !version_supported + return response.data end @@ -300,6 +303,7 @@ return search result def self.search(query, limit = 10, index = nil, query_extention = {}, from = 0, sort_by = [], order_by = []) # rubocop:enable Metrics/ParameterLists return [] if query.blank? + if index.class == Array ids = [] index.each do |local_index| @@ -318,6 +322,7 @@ return search result url = build_url return if url.blank? + url += if index if index.class == Array "/#{index.join(',')}/_search" @@ -377,6 +382,7 @@ return search result return ids if !data return ids if !data['hits'] return ids if !data['hits']['hits'] + data['hits']['hits'].each do |item| Rails.logger.info "... #{item['_type']} #{item['_id']}" data = { @@ -471,6 +477,7 @@ get count of tickets and tickets which match on selector url = build_url return if url.blank? + url += if index if index.class == Array "/#{index.join(',')}/_search" @@ -574,6 +581,7 @@ get count of tickets and tickets which match on selector if range.blank? raise "Invalid relative_map for range '#{data['range']}'." end + t[:range] = {} t[:range][key_tmp] = {} if data['operator'] == 'within last (relative)' @@ -589,6 +597,7 @@ get count of tickets and tickets which match on selector if range.blank? raise "Invalid relative_map for range '#{data['range']}'." end + t[:range] = {} t[:range][key_tmp] = {} if data['operator'] == 'before (relative)' @@ -673,11 +682,13 @@ return true if backend is configured def self.enabled? return false if Setting.get('es_url').blank? + true end def self.build_url(type = nil, o_id = nil) return if !SearchIndexBackend.enabled? + index = "#{Setting.get('es_index')}_#{Rails.env}" url = Setting.get('es_url') url = if type diff --git a/lib/sequencer.rb b/lib/sequencer.rb index 05059257e..825bfe4eb 100644 --- a/lib/sequencer.rb +++ b/lib/sequencer.rb @@ -56,6 +56,7 @@ class Sequencer # fall back to sequence default expecting if no explicit # expecting was given for this sequence return if !@expecting.nil? + @expecting = @sequence.expecting end diff --git a/lib/sequencer/mixin/prefixed_constantize.rb b/lib/sequencer/mixin/prefixed_constantize.rb index 243bee274..f0d07bc46 100644 --- a/lib/sequencer/mixin/prefixed_constantize.rb +++ b/lib/sequencer/mixin/prefixed_constantize.rb @@ -36,6 +36,7 @@ class Sequencer def namespace(name_string) prefix = const_get(:PREFIX) return name_string if name_string.start_with?(prefix) + "#{prefix}#{name_string}" end end diff --git a/lib/sequencer/state.rb b/lib/sequencer/state.rb index 5f8915dcc..431ddd792 100644 --- a/lib/sequencer/state.rb +++ b/lib/sequencer/state.rb @@ -88,6 +88,7 @@ class Sequencer # @return [Object, nil] def optional(attribute) return get(attribute) if @attributes.known?(attribute) + logger.public_send(log_level[:optional]) { "Access to unknown optional attribute '#{attribute}'." } nil end diff --git a/lib/sequencer/unit/base.rb b/lib/sequencer/unit/base.rb index 1876c4099..b8cd57953 100644 --- a/lib/sequencer/unit/base.rb +++ b/lib/sequencer/unit/base.rb @@ -171,6 +171,7 @@ class Sequencer # for independent usage. Otherwise it creates a new one. def self.declarations_initial(key) return Set.new([]) if !superclass.respond_to?(:declarations) + superclass.send(:declarations, key).dup end @@ -183,6 +184,7 @@ class Sequencer cache = "@#{key}" value = scope.instance_variable_get(cache) return value if value + value = yield scope.instance_variable_set(cache, value) end diff --git a/lib/sequencer/unit/common/mixin/dynamic_attribute.rb b/lib/sequencer/unit/common/mixin/dynamic_attribute.rb index 12e410d7c..4481129c0 100644 --- a/lib/sequencer/unit/common/mixin/dynamic_attribute.rb +++ b/lib/sequencer/unit/common/mixin/dynamic_attribute.rb @@ -18,6 +18,7 @@ class Sequencer if uses.size != 1 raise "DynamicAttribute classes can use exactly one attribute. Found #{uses.size}." end + uses.first end end diff --git a/lib/sequencer/unit/common/provider/attribute.rb b/lib/sequencer/unit/common/provider/attribute.rb index 115af7466..7ac967aa9 100644 --- a/lib/sequencer/unit/common/provider/attribute.rb +++ b/lib/sequencer/unit/common/provider/attribute.rb @@ -6,6 +6,7 @@ class Sequencer def process return if ignore? + state.provide(attribute, value) end @@ -18,6 +19,7 @@ class Sequencer def provides provides_list = self.class.provides raise "Only single provide attribute possible for class #{self.class.name}" if provides_list.size != 1 + provides_list.first end diff --git a/lib/sequencer/unit/exchange/connection.rb b/lib/sequencer/unit/exchange/connection.rb index da71593b8..6c726dfa4 100644 --- a/lib/sequencer/unit/exchange/connection.rb +++ b/lib/sequencer/unit/exchange/connection.rb @@ -31,6 +31,7 @@ class Sequencer def http_opts return {} if config[:disable_ssl_verify].blank? + { http_opts: { ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE diff --git a/lib/sequencer/unit/import/common/import_job/statistics/store.rb b/lib/sequencer/unit/import/common/import_job/statistics/store.rb index 78207a631..ea836dbc4 100644 --- a/lib/sequencer/unit/import/common/import_job/statistics/store.rb +++ b/lib/sequencer/unit/import/common/import_job/statistics/store.rb @@ -16,6 +16,7 @@ class Sequencer import_job.result = statistics return if !store? + import_job.save! end @@ -23,6 +24,7 @@ class Sequencer def store? return true if import_job.updated_at.blank? + next_update_at < Time.zone.now end diff --git a/lib/sequencer/unit/import/common/import_job/statistics/update.rb b/lib/sequencer/unit/import/common/import_job/statistics/update.rb index 57af16340..8a4beddfc 100644 --- a/lib/sequencer/unit/import/common/import_job/statistics/update.rb +++ b/lib/sequencer/unit/import/common/import_job/statistics/update.rb @@ -26,6 +26,7 @@ class Sequencer def statistics import_job = state.optional(:import_job) return {} if import_job.nil? + import_job.result end diff --git a/lib/sequencer/unit/import/common/import_mode/check.rb b/lib/sequencer/unit/import/common/import_mode/check.rb index 288a14bf3..9680a2dd4 100644 --- a/lib/sequencer/unit/import/common/import_mode/check.rb +++ b/lib/sequencer/unit/import/common/import_mode/check.rb @@ -8,6 +8,7 @@ class Sequencer def process # check if system is in import mode return if Setting.get('import_mode') + raise 'System is not in import mode!' end end diff --git a/lib/sequencer/unit/import/common/model/associations/assign.rb b/lib/sequencer/unit/import/common/model/associations/assign.rb index 9e1fcc202..b55fdc833 100644 --- a/lib/sequencer/unit/import/common/model/associations/assign.rb +++ b/lib/sequencer/unit/import/common/model/associations/assign.rb @@ -28,12 +28,14 @@ class Sequencer # always returns true def log_associations_error return true if %i[failed deactivated].include?(action) + logger.error { 'associations cannot be nil' } if associations.nil? true end def register_changes return if !(action == :unchanged && changes.any?) + logger.debug { "Changed instance associations: #{changes.inspect}" } state.provide(:action, :updated) end diff --git a/lib/sequencer/unit/import/common/model/attributes/check_mandatory.rb b/lib/sequencer/unit/import/common/model/attributes/check_mandatory.rb index 3bc83e71d..7d7b24b5a 100644 --- a/lib/sequencer/unit/import/common/model/attributes/check_mandatory.rb +++ b/lib/sequencer/unit/import/common/model/attributes/check_mandatory.rb @@ -15,6 +15,7 @@ class Sequencer def process mandatory.each do |mapped_attribute| next if mapped[mapped_attribute].present? + state.provide(:action, :skipped) break end diff --git a/lib/sequencer/unit/import/common/model/external_sync/integrity.rb b/lib/sequencer/unit/import/common/model/external_sync/integrity.rb index ffc7535b7..4a749f4c1 100644 --- a/lib/sequencer/unit/import/common/model/external_sync/integrity.rb +++ b/lib/sequencer/unit/import/common/model/external_sync/integrity.rb @@ -12,6 +12,7 @@ class Sequencer return if instance.blank? return if instance.id.blank? return if up_to_date? + create end @@ -20,6 +21,7 @@ class Sequencer def up_to_date? return false if entry.blank? return true if entry.source_id == remote_id + entry.update!(source_id: remote_id) true end diff --git a/lib/sequencer/unit/import/common/model/http_log.rb b/lib/sequencer/unit/import/common/model/http_log.rb index 0cec9c26d..9ee037138 100644 --- a/lib/sequencer/unit/import/common/model/http_log.rb +++ b/lib/sequencer/unit/import/common/model/http_log.rb @@ -9,6 +9,7 @@ class Sequencer def process return if dry_run + ::HttpLog.create( direction: 'out', facility: facility, diff --git a/lib/sequencer/unit/import/common/model/lookup/attributes.rb b/lib/sequencer/unit/import/common/model/lookup/attributes.rb index 8a097b010..a8e956790 100644 --- a/lib/sequencer/unit/import/common/model/lookup/attributes.rb +++ b/lib/sequencer/unit/import/common/model/lookup/attributes.rb @@ -54,6 +54,7 @@ class Sequencer def lookup(attribute:, value:) return model_class.identify(value) if model_class.respond_to?(:identify) + model_class.find_by(attribute => value) end end diff --git a/lib/sequencer/unit/import/common/model/mixin/skip/action.rb b/lib/sequencer/unit/import/common/model/mixin/skip/action.rb index 0c7a32f17..bccf8911b 100644 --- a/lib/sequencer/unit/import/common/model/mixin/skip/action.rb +++ b/lib/sequencer/unit/import/common/model/mixin/skip/action.rb @@ -24,10 +24,12 @@ class Sequencer def skip_action?(action) logger.debug { "Checking if skip is necessary for action #{action.inspect}." } return false if action.blank? + logger.debug { "Checking if skip is necessary for skip_actions #{skip_actions.inspect}." } return false if skip_actions.blank? return true if skip_actions.include?(action) return true if skip_actions.include?(:any) + false end end diff --git a/lib/sequencer/unit/import/common/model/save.rb b/lib/sequencer/unit/import/common/model/save.rb index ea8d12646..94e4d0388 100644 --- a/lib/sequencer/unit/import/common/model/save.rb +++ b/lib/sequencer/unit/import/common/model/save.rb @@ -17,6 +17,7 @@ class Sequencer def process return if dry_run return if instance.blank? + instance.save! rescue => e handle_failure(e) diff --git a/lib/sequencer/unit/import/common/model/skip/blank/base.rb b/lib/sequencer/unit/import/common/model/skip/blank/base.rb index 7399b117e..fad5248e6 100644 --- a/lib/sequencer/unit/import/common/model/skip/blank/base.rb +++ b/lib/sequencer/unit/import/common/model/skip/blank/base.rb @@ -17,6 +17,7 @@ class Sequencer def process return if !skip? + logger.debug { "Skipping. Blank #{attribute} found: #{attribute_value.inspect}" } state.provide(:action, :skipped) end @@ -29,6 +30,7 @@ class Sequencer def skip? return true if attribute_value.blank? + relevant_blank? end diff --git a/lib/sequencer/unit/import/common/model/skip/missing_mandatory/base.rb b/lib/sequencer/unit/import/common/model/skip/missing_mandatory/base.rb index 6aee4846b..08ade7afd 100644 --- a/lib/sequencer/unit/import/common/model/skip/missing_mandatory/base.rb +++ b/lib/sequencer/unit/import/common/model/skip/missing_mandatory/base.rb @@ -17,6 +17,7 @@ class Sequencer def process return if !skip? + logger.debug { "Skipping. Missing mandatory attributes for #{attribute}: #{attribute_value.inspect}" } state.provide(:action, :skipped) end @@ -29,6 +30,7 @@ class Sequencer def skip? return true if attribute_value.blank? + mandatory_missing? end diff --git a/lib/sequencer/unit/import/common/model/statistics/mixin/action_diff.rb b/lib/sequencer/unit/import/common/model/statistics/mixin/action_diff.rb index 59df5dcbb..8ec3baa61 100644 --- a/lib/sequencer/unit/import/common/model/statistics/mixin/action_diff.rb +++ b/lib/sequencer/unit/import/common/model/statistics/mixin/action_diff.rb @@ -19,6 +19,7 @@ class Sequencer def diff raise "Unknown action '#{action}'" if !possible? + empty_diff.merge( action => 1, sum: 1, diff --git a/lib/sequencer/unit/import/common/sub_sequence/mixin/resources.rb b/lib/sequencer/unit/import/common/sub_sequence/mixin/resources.rb index b617b7549..a793b3fcb 100644 --- a/lib/sequencer/unit/import/common/sub_sequence/mixin/resources.rb +++ b/lib/sequencer/unit/import/common/sub_sequence/mixin/resources.rb @@ -9,6 +9,7 @@ class Sequencer def process return if resources.blank? + sequence_resources(resources) end diff --git a/lib/sequencer/unit/import/common/system_init_done/check.rb b/lib/sequencer/unit/import/common/system_init_done/check.rb index a3dac83c7..87a5ef395 100644 --- a/lib/sequencer/unit/import/common/system_init_done/check.rb +++ b/lib/sequencer/unit/import/common/system_init_done/check.rb @@ -7,6 +7,7 @@ class Sequencer def process return if !Setting.get('system_init_done') + raise 'System is already system_init_done!' end end diff --git a/lib/sequencer/unit/import/common/user/attributes/downcase.rb b/lib/sequencer/unit/import/common/user/attributes/downcase.rb index 22dfa5625..2f31fd96c 100644 --- a/lib/sequencer/unit/import/common/user/attributes/downcase.rb +++ b/lib/sequencer/unit/import/common/user/attributes/downcase.rb @@ -14,6 +14,7 @@ class Sequencer def process %i[login email].each do |attribute| next if mapped[attribute].blank? + mapped[attribute].downcase! end end diff --git a/lib/sequencer/unit/import/common/user/email/check_validity.rb b/lib/sequencer/unit/import/common/user/email/check_validity.rb index e99de6c27..6331eebb3 100644 --- a/lib/sequencer/unit/import/common/user/email/check_validity.rb +++ b/lib/sequencer/unit/import/common/user/email/check_validity.rb @@ -24,6 +24,7 @@ class Sequencer # TODO: should get unified with User#check_email email = extract_email(source) return if !email + email.downcase end @@ -36,6 +37,7 @@ class Sequencer Mail::Address.new(source).address rescue return source if source !~ /<\s*([^>]+)/ + $1.strip end end diff --git a/lib/sequencer/unit/import/exchange/folder_contact/mapping/from_config.rb b/lib/sequencer/unit/import/exchange/folder_contact/mapping/from_config.rb index 7cdc37de9..c1b4c949c 100644 --- a/lib/sequencer/unit/import/exchange/folder_contact/mapping/from_config.rb +++ b/lib/sequencer/unit/import/exchange/folder_contact/mapping/from_config.rb @@ -16,8 +16,10 @@ class Sequencer def from_import_job return if !state.provided?(:import_job) + payload = import_job.payload return if payload.blank? + payload[:ews_attributes] end end diff --git a/lib/sequencer/unit/import/ldap/user/lookup/attributes.rb b/lib/sequencer/unit/import/ldap/user/lookup/attributes.rb index c97b93e9e..0edef07ac 100644 --- a/lib/sequencer/unit/import/ldap/user/lookup/attributes.rb +++ b/lib/sequencer/unit/import/ldap/user/lookup/attributes.rb @@ -13,6 +13,7 @@ class Sequencer def lookup(attribute:, value:) entries = model_class.where(attribute => value).to_a return if entries.blank? + not_synced(entries) end diff --git a/lib/sequencer/unit/import/ldap/user/remote_id/unhex.rb b/lib/sequencer/unit/import/ldap/user/remote_id/unhex.rb index 3fcd7a04e..a703343cf 100644 --- a/lib/sequencer/unit/import/ldap/user/remote_id/unhex.rb +++ b/lib/sequencer/unit/import/ldap/user/remote_id/unhex.rb @@ -18,6 +18,7 @@ class Sequencer # the HEX values cause errors otherwise return if remote_id.nil? return if remote_id.ascii_only? + state.provide(:remote_id, unhexed) end diff --git a/lib/sequencer/unit/import/ldap/users/sub_sequence.rb b/lib/sequencer/unit/import/ldap/users/sub_sequence.rb index a8a9c8537..513e81a71 100644 --- a/lib/sequencer/unit/import/ldap/users/sub_sequence.rb +++ b/lib/sequencer/unit/import/ldap/users/sub_sequence.rb @@ -17,6 +17,7 @@ class Sequencer result = sequence_resource(entry) next if result[:instance].blank? + found_ids.push(result[:instance].id) end diff --git a/lib/sequencer/unit/import/zendesk/common/article_sender_id.rb b/lib/sequencer/unit/import/zendesk/common/article_sender_id.rb index d6e9f9b3f..d4617b1e7 100644 --- a/lib/sequencer/unit/import/zendesk/common/article_sender_id.rb +++ b/lib/sequencer/unit/import/zendesk/common/article_sender_id.rb @@ -12,6 +12,7 @@ class Sequencer def article_sender_id return article_sender('Customer') if author.role?('Customer') return article_sender('Agent') if author.role?('Agent') + article_sender('System') end diff --git a/lib/sequencer/unit/import/zendesk/common/article_type_id.rb b/lib/sequencer/unit/import/zendesk/common/article_type_id.rb index 918a2d623..1b28f34f0 100644 --- a/lib/sequencer/unit/import/zendesk/common/article_type_id.rb +++ b/lib/sequencer/unit/import/zendesk/common/article_type_id.rb @@ -29,11 +29,13 @@ class Sequencer def remote_name_facebook return 'facebook feed post' if resource.via.source.rel == 'post' + 'facebook feed comment' end def remote_name_twitter return 'twitter status' if resource.via.source.rel == 'mention' + 'twitter direct message' end diff --git a/lib/sequencer/unit/import/zendesk/common/custom_fields.rb b/lib/sequencer/unit/import/zendesk/common/custom_fields.rb index beec7436c..8d4957b45 100644 --- a/lib/sequencer/unit/import/zendesk/common/custom_fields.rb +++ b/lib/sequencer/unit/import/zendesk/common/custom_fields.rb @@ -26,8 +26,10 @@ class Sequencer def attributes_hash return {} if fields.blank? + fields.each_with_object({}) do |(key, value), result| next if value.nil? + result[key] = value end end diff --git a/lib/sequencer/unit/import/zendesk/objects_total_count.rb b/lib/sequencer/unit/import/zendesk/objects_total_count.rb index 44294c24e..ebbd68824 100644 --- a/lib/sequencer/unit/import/zendesk/objects_total_count.rb +++ b/lib/sequencer/unit/import/zendesk/objects_total_count.rb @@ -19,6 +19,7 @@ class Sequencer def request(object) return tickets if object == 'Tickets' + generic(object) end diff --git a/lib/sequencer/unit/import/zendesk/ticket/comment/attachment/request.rb b/lib/sequencer/unit/import/zendesk/ticket/comment/attachment/request.rb index b7322ca69..d1e5b84f9 100644 --- a/lib/sequencer/unit/import/zendesk/ticket/comment/attachment/request.rb +++ b/lib/sequencer/unit/import/zendesk/ticket/comment/attachment/request.rb @@ -25,6 +25,7 @@ class Sequencer def failed? return false if response.success? + logger.error response.error true end diff --git a/lib/sequencer/unit/import/zendesk/ticket/comment/attachments.rb b/lib/sequencer/unit/import/zendesk/ticket/comment/attachments.rb index f3d318476..098514e50 100644 --- a/lib/sequencer/unit/import/zendesk/ticket/comment/attachments.rb +++ b/lib/sequencer/unit/import/zendesk/ticket/comment/attachments.rb @@ -9,6 +9,7 @@ class Sequencer def process # check if we need to import the attachments return if skip? + # if so call the original .process from SubObject class super end @@ -30,11 +31,13 @@ class Sequencer def ensure_common_ground return if common_ground? + local_attachments.each(&:delete) end def common_ground? return false if remote_attachments.blank? + attachments_equal? end diff --git a/lib/sequencer/unit/import/zendesk/ticket/comment/source_based.rb b/lib/sequencer/unit/import/zendesk/ticket/comment/source_based.rb index 5932ff3a8..effbda1e8 100644 --- a/lib/sequencer/unit/import/zendesk/ticket/comment/source_based.rb +++ b/lib/sequencer/unit/import/zendesk/ticket/comment/source_based.rb @@ -10,6 +10,7 @@ class Sequencer def value return if private_methods(false).exclude?(value_method_name) + send(value_method_name) end diff --git a/lib/sequencer/unit/import/zendesk/ticket_field/check_custom.rb b/lib/sequencer/unit/import/zendesk/ticket_field/check_custom.rb index 2a5e03a74..848ab1f6a 100644 --- a/lib/sequencer/unit/import/zendesk/ticket_field/check_custom.rb +++ b/lib/sequencer/unit/import/zendesk/ticket_field/check_custom.rb @@ -10,6 +10,7 @@ class Sequencer def process return if custom? + state.provide(:action, :skipped) end diff --git a/lib/sequencer/unit/import/zendesk/tickets.rb b/lib/sequencer/unit/import/zendesk/tickets.rb index 075ee4772..70fd46c4f 100644 --- a/lib/sequencer/unit/import/zendesk/tickets.rb +++ b/lib/sequencer/unit/import/zendesk/tickets.rb @@ -42,6 +42,7 @@ class Sequencer def update_import_job return if !update_required? + state.provide(import_job, updated_import_job) end @@ -54,6 +55,7 @@ class Sequencer def update_required? return false if previous_page.blank? return false if previous_page == next_page + current_request_count.present? end diff --git a/lib/sequencer/unit/import/zendesk/user/groups.rb b/lib/sequencer/unit/import/zendesk/user/groups.rb index a3a5d9f50..f1a69f31e 100644 --- a/lib/sequencer/unit/import/zendesk/user/groups.rb +++ b/lib/sequencer/unit/import/zendesk/user/groups.rb @@ -17,6 +17,7 @@ class Sequencer def remote_ids return [] if user_group_map.blank? + user_group_map.fetch(resource.id, []) end end diff --git a/lib/sequencer/unit/import/zendesk/user/initiator.rb b/lib/sequencer/unit/import/zendesk/user/initiator.rb index 8f91258b8..43f8d5dc6 100644 --- a/lib/sequencer/unit/import/zendesk/user/initiator.rb +++ b/lib/sequencer/unit/import/zendesk/user/initiator.rb @@ -16,6 +16,7 @@ class Sequencer def initiator? return false if resource.email.blank? + resource.email == Setting.get('import_zendesk_endpoint_username') end end diff --git a/lib/sequencer/unit/import/zendesk/user/organization_id.rb b/lib/sequencer/unit/import/zendesk/user/organization_id.rb index 5fd7708f4..645b93ce6 100644 --- a/lib/sequencer/unit/import/zendesk/user/organization_id.rb +++ b/lib/sequencer/unit/import/zendesk/user/organization_id.rb @@ -12,6 +12,7 @@ class Sequencer def organization_id remote_id = resource.organization_id return if remote_id.blank? + organization_map[remote_id] end end diff --git a/lib/sequencer/unit/import/zendesk/user/password.rb b/lib/sequencer/unit/import/zendesk/user/password.rb index cb2b6a6ff..d816feb1e 100644 --- a/lib/sequencer/unit/import/zendesk/user/password.rb +++ b/lib/sequencer/unit/import/zendesk/user/password.rb @@ -14,6 +14,7 @@ class Sequencer # since we have no other confidential value # that is known to Zammad and the User return Setting.get('import_zendesk_endpoint_key') if initiator + # otherwise set an empty password so the user # has to re-set a new password for Zammad '' diff --git a/lib/sequencer/unit/import/zendesk/user/roles.rb b/lib/sequencer/unit/import/zendesk/user/roles.rb index ed9cdb6db..05433dd3d 100644 --- a/lib/sequencer/unit/import/zendesk/user/roles.rb +++ b/lib/sequencer/unit/import/zendesk/user/roles.rb @@ -11,11 +11,13 @@ class Sequencer def roles return admin if initiator + map_roles end def map_roles return send(zendesk_role) if respond_to?(zendesk_role, true) + logger.error "Unknown mapping for role '#{resource.role.name}' (method: #{zendesk_role})" end_user end @@ -30,6 +32,7 @@ class Sequencer def agent return [role_agent] if resource.restricted_agent + admin end diff --git a/lib/sequencer/units/attributes.rb b/lib/sequencer/units/attributes.rb index a649d8f84..6660fa4d1 100644 --- a/lib/sequencer/units/attributes.rb +++ b/lib/sequencer/units/attributes.rb @@ -68,6 +68,7 @@ class Sequencer unit[:provides].try(:each) do |attribute| next if result[attribute].will_be_provided? + result[attribute].from = index end end diff --git a/lib/session_helper.rb b/lib/session_helper.rb index 3beea0f80..878af387e 100644 --- a/lib/session_helper.rb +++ b/lib/session_helper.rb @@ -46,6 +46,7 @@ module SessionHelper def self.destroy(id) session = ActiveRecord::SessionStore::Session.find_by(id: id) return if !session + session.destroy end end diff --git a/lib/sessions.rb b/lib/sessions.rb index 8e2e0169a..6df4549bd 100644 --- a/lib/sessions.rb +++ b/lib/sessions.rb @@ -53,6 +53,7 @@ returns # send update to browser return if !session || session['id'].blank? + send( client_id, { @@ -88,6 +89,7 @@ returns next if entry == '..' next if entry == 'tmp' next if entry == 'spool' + data.push entry.to_s end data @@ -108,8 +110,10 @@ returns def self.session_exists?(client_id) session_dir = "#{@path}/#{client_id}" return false if !File.exist?(session_dir) + session_file = "#{session_dir}/session" return false if !File.exist?(session_file) + true end @@ -150,6 +154,7 @@ returns client_ids.each do |client_id| data = get(client_id) next if !data + session_list[client_id] = data end session_list @@ -211,6 +216,7 @@ returns def self.touch(client_id) data = get(client_id) return false if !data + path = "#{@path}/#{client_id}" data[:meta][:last_ping] = Time.now.utc.to_i File.open("#{path}/session", 'wb' ) do |file| @@ -306,6 +312,7 @@ returns end end return false if !File.directory? path + begin File.open(location, 'wb') do |file| file.flock(File::LOCK_EX) @@ -343,6 +350,7 @@ returns next if !session[:user] next if !session[:user]['id'] next if session[:user]['id'].to_i != user_id.to_i + Sessions.send(client_id, data) end true @@ -419,13 +427,16 @@ returns Dir.foreach(path) do |entry| next if entry == '.' next if entry == '..' + files.push entry end files.sort.each do |entry| filename = "#{path}/#{entry}" next if entry !~ /^send/ + message = Sessions.queue_file_read(path, entry) next if !message + data.push message end data @@ -441,6 +452,7 @@ returns end File.delete(location) return if message.blank? + begin return JSON.parse(message) rescue => e @@ -459,6 +471,7 @@ remove all session and spool messages def self.cleanup return true if !File.exist?(@path) + FileUtils.rm_rf @path true end @@ -488,11 +501,13 @@ remove all session and spool messages Dir.foreach(path) do |entry| next if entry == '.' next if entry == '..' + files.push entry end files.sort.each do |entry| filename = "#{path}/#{entry}" next if !File.exist?(filename) + File.open(filename, 'rb') do |file| file.flock(File::LOCK_SH) message = file.read @@ -610,6 +625,7 @@ remove all session and spool messages next if session_data.blank? next if session_data[:user].blank? next if session_data[:user]['id'].blank? + user = User.lookup(id: session_data[:user]['id']) next if user.blank? diff --git a/lib/sessions/backend/base.rb b/lib/sessions/backend/base.rb index f84b156e1..ae7a9dccb 100644 --- a/lib/sessions/backend/base.rb +++ b/lib/sessions/backend/base.rb @@ -25,6 +25,7 @@ class Sessions::Backend::Base def asset_needed?(record) return false if !asset_needed_by_updated_at?(record.class.to_s, record.id, record.updated_at) + true end @@ -35,6 +36,7 @@ class Sessions::Backend::Base return true if @asset_lookup[class_name][record_id][:updated_at] < updated_at return true if @asset_lookup[class_name][record_id][:pushed_at].blank? return true if @asset_lookup[class_name][record_id][:pushed_at] < @time_now - 7200 + false end diff --git a/lib/sessions/backend/collections.rb b/lib/sessions/backend/collections.rb index 06ccf631d..f18f66201 100644 --- a/lib/sessions/backend/collections.rb +++ b/lib/sessions/backend/collections.rb @@ -44,6 +44,7 @@ class Sessions::Backend::Collections < Sessions::Backend::Base file.gsub!("#{dir}/lib/", '') file.gsub!(/\.rb$/, '') next if file.classify == 'Sessions::Backend::Collections::Base' + #puts "LOAD #{file.classify}---" #next if file == '' backend = file.classify.constantize.new(@user, @asset_lookup, @client, @client_id, @ttl) diff --git a/lib/sessions/backend/collections/base.rb b/lib/sessions/backend/collections/base.rb index c965d8a92..66bf33877 100644 --- a/lib/sessions/backend/collections/base.rb +++ b/lib/sessions/backend/collections/base.rb @@ -41,6 +41,7 @@ class Sessions::Backend::Collections::Base < Sessions::Backend::Base # check if update has been done last_change = self.class.model.constantize.latest_change return if last_change.to_s == @last_change + @last_change = last_change.to_s # load current data @@ -59,6 +60,7 @@ class Sessions::Backend::Collections::Base < Sessions::Backend::Base assets = {} items.each do |item| next if !asset_needed?(item) + assets = asset_push(item, assets) end if !@client diff --git a/lib/sessions/backend/ticket_overview_list.rb b/lib/sessions/backend/ticket_overview_list.rb index ac645ff51..01e12ccbe 100644 --- a/lib/sessions/backend/ticket_overview_list.rb +++ b/lib/sessions/backend/ticket_overview_list.rb @@ -46,6 +46,7 @@ class Sessions::Backend::TicketOverviewList < Sessions::Backend::Base return true end return false if Sessions::CacheIn.get(client_key) + true end @@ -60,6 +61,7 @@ class Sessions::Backend::TicketOverviewList < Sessions::Backend::Base last_overview_change = Overview.latest_change last_ticket_change = Ticket.latest_change return if last_ticket_change == @last_ticket_change && last_overview_change == @last_overview_change + @last_overview_change = last_overview_change @last_ticket_change = last_ticket_change @@ -96,6 +98,7 @@ class Sessions::Backend::TicketOverviewList < Sessions::Backend::Base # do not deliver unchanged lists next if @last_overview[data[:overview][:id]] == data + @last_overview[data[:overview][:id]] = data assets = {} @@ -105,6 +108,7 @@ class Sessions::Backend::TicketOverviewList < Sessions::Backend::Base end data[:tickets].each do |ticket_meta| next if !asset_needed_by_updated_at?('Ticket', ticket_meta[:id], ticket_meta[:updated_at]) + ticket = Ticket.lookup(id: ticket_meta[:id]) assets = asset_push(ticket, assets) end @@ -127,6 +131,7 @@ class Sessions::Backend::TicketOverviewList < Sessions::Backend::Base end end return results if !@client + nil end diff --git a/lib/sessions/cache_in.rb b/lib/sessions/cache_in.rb index 82080aff9..f6046a663 100644 --- a/lib/sessions/cache_in.rb +++ b/lib/sessions/cache_in.rb @@ -40,6 +40,7 @@ module Sessions::CacheIn # check if expired if @@expires_in[key] return true if @@expires_in[key] < Time.zone.now + return false end @@ -49,6 +50,7 @@ module Sessions::CacheIn def self.get(key, params = {}) return if expired( key, params) + @@data[ key ] end end diff --git a/lib/sessions/client.rb b/lib/sessions/client.rb index 4a111abe5..efa201384 100644 --- a/lib/sessions/client.rb +++ b/lib/sessions/client.rb @@ -32,6 +32,7 @@ class Sessions::Client return if !session_data return if !session_data[:user] return if !session_data[:user]['id'] + user = User.lookup(id: session_data[:user]['id']) return if !user diff --git a/lib/sessions/event/base.rb b/lib/sessions/event/base.rb index 1b02e6bfe..3c42ee38f 100644 --- a/lib/sessions/event/base.rb +++ b/lib/sessions/event/base.rb @@ -7,6 +7,7 @@ class Sessions::Event::Base @is_web_socket = false return if !@clients[@client_id] + @is_web_socket = true end @@ -76,6 +77,7 @@ class Sessions::Event::Base def current_user user_id = current_user_id return if !user_id + user = User.find_by(id: user_id) if !user error = { @@ -93,6 +95,7 @@ class Sessions::Event::Base def permission_check(key, event) user = current_user return if !user + if !user.permissions?(key) error = { event: "#{event}_error", diff --git a/lib/sessions/event/chat_base.rb b/lib/sessions/event/chat_base.rb index 680f55236..5bd3f150e 100644 --- a/lib/sessions/event/chat_base.rb +++ b/lib/sessions/event/chat_base.rb @@ -3,11 +3,13 @@ class Sessions::Event::ChatBase < Sessions::Event::Base def initialize(params) super(params) return if !@is_web_socket + ActiveRecord::Base.establish_connection end def destroy return if !@is_web_socket + ActiveRecord::Base.remove_connection end @@ -15,6 +17,7 @@ class Sessions::Event::ChatBase < Sessions::Event::Base # check if feature is enabled return if Setting.get('chat') + { event: 'chat_error', data: { @@ -39,6 +42,7 @@ class Sessions::Event::ChatBase < Sessions::Event::Base return end return true if current_chat_session + error = { event: 'chat_error', data: { @@ -56,6 +60,7 @@ class Sessions::Event::ChatBase < Sessions::Event::Base def check_chat_exists chat = current_chat return true if chat + error = { event: 'chat_error', data: { diff --git a/lib/sessions/event/chat_session_leave_temporary.rb b/lib/sessions/event/chat_session_leave_temporary.rb index dbc7d614d..4d9620295 100644 --- a/lib/sessions/event/chat_session_leave_temporary.rb +++ b/lib/sessions/event/chat_session_leave_temporary.rb @@ -3,6 +3,7 @@ class Sessions::Event::ChatSessionLeaveTemporary < Sessions::Event::ChatBase def run return super if super return if !check_chat_session_exists + chat_session = current_chat_session Delayed::Job.enqueue( diff --git a/lib/sessions/event/chat_session_message.rb b/lib/sessions/event/chat_session_message.rb index eb446992d..b2d199242 100644 --- a/lib/sessions/event/chat_session_message.rb +++ b/lib/sessions/event/chat_session_message.rb @@ -3,6 +3,7 @@ class Sessions::Event::ChatSessionMessage < Sessions::Event::ChatBase def run return super if super return if !check_chat_session_exists + chat_session = current_chat_session user_id = nil diff --git a/lib/sessions/event/chat_session_notice.rb b/lib/sessions/event/chat_session_notice.rb index d3e04fc93..a02d29f5e 100644 --- a/lib/sessions/event/chat_session_notice.rb +++ b/lib/sessions/event/chat_session_notice.rb @@ -3,6 +3,7 @@ class Sessions::Event::ChatSessionNotice < Sessions::Event::ChatBase def run return super if super return if !check_chat_session_exists + chat_session = current_chat_session return if !chat_session return if !@payload['data']['message'] diff --git a/lib/sessions/event/chat_session_typing.rb b/lib/sessions/event/chat_session_typing.rb index e87463748..c084ee882 100644 --- a/lib/sessions/event/chat_session_typing.rb +++ b/lib/sessions/event/chat_session_typing.rb @@ -3,6 +3,7 @@ class Sessions::Event::ChatSessionTyping < Sessions::Event::ChatBase def run return super if super return if !check_chat_session_exists + chat_session = current_chat_session user_id = nil diff --git a/lib/sessions/event/chat_session_update.rb b/lib/sessions/event/chat_session_update.rb index 0f93dfc31..bd77197d6 100644 --- a/lib/sessions/event/chat_session_update.rb +++ b/lib/sessions/event/chat_session_update.rb @@ -4,6 +4,7 @@ class Sessions::Event::ChatSessionUpdate < Sessions::Event::ChatBase return super if super return if !check_chat_session_exists return if !permission_check('chat.agent', 'chat') + chat_session = current_chat_session if @payload['data']['name'] != chat_session.name @@ -20,11 +21,13 @@ class Sessions::Event::ChatSessionUpdate < Sessions::Event::ChatBase new_tags.each do |new_tag| next if new_tag.blank? next if tags.include?(new_tag) + chat_session.tag_add(new_tag, current_user_id) end tags.each do |tag| next if new_tags.include?(tag) + chat_session.tag_remove(tag, current_user_id) end end diff --git a/lib/sessions/event/chat_status_customer.rb b/lib/sessions/event/chat_status_customer.rb index dbb5e8431..dea2a5475 100644 --- a/lib/sessions/event/chat_status_customer.rb +++ b/lib/sessions/event/chat_status_customer.rb @@ -39,6 +39,7 @@ class Sessions::Event::ChatStatusCustomer < Sessions::Event::ChatBase def check_chat_block_by_ip chat = current_chat return true if !chat.blocked_ip?(@remote_ip) + error = { event: 'chat_error', data: { @@ -52,6 +53,7 @@ class Sessions::Event::ChatStatusCustomer < Sessions::Event::ChatBase def check_chat_block_by_country chat = current_chat return true if !chat.blocked_country?(@remote_ip) + error = { event: 'chat_error', data: { diff --git a/lib/sessions/event/maintenance.rb b/lib/sessions/event/maintenance.rb index 732346b1d..46a5317aa 100644 --- a/lib/sessions/event/maintenance.rb +++ b/lib/sessions/event/maintenance.rb @@ -3,11 +3,13 @@ class Sessions::Event::Maintenance < Sessions::Event::Base def initialize(params) super(params) return if !@is_web_socket + ActiveRecord::Base.establish_connection end def destroy return if !@is_web_socket + ActiveRecord::Base.remove_connection end @@ -15,6 +17,7 @@ class Sessions::Event::Maintenance < Sessions::Event::Base # check if sender is admin return if !permission_check('admin.maintenance', 'maintenance') + Sessions.broadcast(@payload, 'public', @session['id']) false end diff --git a/lib/sessions/event/ticket_overview_index.rb b/lib/sessions/event/ticket_overview_index.rb index 2c8dd191f..e952fddf4 100644 --- a/lib/sessions/event/ticket_overview_index.rb +++ b/lib/sessions/event/ticket_overview_index.rb @@ -2,6 +2,7 @@ class Sessions::Event::TicketOverviewIndex < Sessions::Event::Base def run return if !valid_session? + Sessions::Backend::TicketOverviewList.reset(@session['id']) end diff --git a/lib/sessions/event/ticket_overview_list.rb b/lib/sessions/event/ticket_overview_list.rb index b2f945fb0..a5102d172 100644 --- a/lib/sessions/event/ticket_overview_list.rb +++ b/lib/sessions/event/ticket_overview_list.rb @@ -2,6 +2,7 @@ class Sessions::Event::TicketOverviewList < Sessions::Event::Base def run return if !valid_session? + Sessions::Backend::TicketOverviewList.reset(@session['id']) end diff --git a/lib/sessions/node.rb b/lib/sessions/node.rb index f023e95c1..e80f7c469 100644 --- a/lib/sessions/node.rb +++ b/lib/sessions/node.rb @@ -25,6 +25,7 @@ module Sessions::Node node_count = nil session_count.each do |local_node_id, count| next if !node_count.nil? && count > node_count + node_count = count node_id = local_node_id end @@ -99,9 +100,11 @@ module Sessions::Node file.flock(File::LOCK_UN) begin next if content.blank? + data = JSON.parse(content) next if data.blank? next if data['client_id'].blank? + sessions[data['client_id']] = data['node_id'] rescue => e Rails.logger.error "can't parse session file #{filename}, #{e.inspect}" @@ -151,10 +154,12 @@ module Sessions::Node file.flock(File::LOCK_UN) begin next if content.blank? + data = JSON.parse(content) next if data.blank? next if data['client_id'].blank? next if !Sessions.session_exists?(data['client_id']) && force == false + sessions.push data['client_id'] rescue => e Rails.logger.error "can't parse session file #{filename}, #{e.inspect}" diff --git a/lib/signature_detection.rb b/lib/signature_detection.rb index 8361a62ae..d0da4b5d5 100644 --- a/lib/signature_detection.rb +++ b/lib/signature_detection.rb @@ -85,6 +85,7 @@ returns match_content = '' ( match_block..match_block_total ).each do |match_block_index| break if match_max_content == 10 + match_max_content += 1 match_content += "#{diff_result_array[match_block_index][1..-1]}\n" end @@ -159,6 +160,7 @@ returns def self.find_signature_line_by_article(user, article) return if !user.preferences[:signature_detection] + SignatureDetection.find_signature_line( user.preferences[:signature_detection], article.body, @@ -190,6 +192,7 @@ returns tickets.each do |ticket| article = ticket.articles.first next if !article + data = { content: article.body, content_type: article.content_type, diff --git a/lib/static_assets.rb b/lib/static_assets.rb index a6ccb2c38..27fcfcdcf 100644 --- a/lib/static_assets.rb +++ b/lib/static_assets.rb @@ -71,6 +71,7 @@ returns if list && list[0] return Store.find( list[0] ) end + raise 'No such raw logo!' end @@ -167,6 +168,7 @@ sync image to fs (public/assets/images/hash.png) def self.sync file = read return if !file + path = Rails.root.join('public', 'assets', 'images', filename(file)) File.open(path, 'wb') do |f| f.puts file.content diff --git a/lib/stats.rb b/lib/stats.rb index a25d40aad..d1f6fa9ee 100644 --- a/lib/stats.rb +++ b/lib/stats.rb @@ -31,6 +31,7 @@ returns users.each do |user| next if user.id == 1 next if !user.active + agent_count += 1 data = {} backends.each do |backend| @@ -44,6 +45,7 @@ returns user_result.each_value do |data| data.each do |backend_model, backend_result| next if !backend_result.key?(:used_for_average) + if !backend_average_sum[backend_model] backend_average_sum[backend_model] = 0 end @@ -57,6 +59,7 @@ returns user_result.each do |user_id, data| next if !data[backend_model_average] next if !data[backend_model_average].key?(:used_for_average) + data[backend_model_average][:average_per_agent] = average # generate icon state diff --git a/lib/stats/ticket_channel_distribution.rb b/lib/stats/ticket_channel_distribution.rb index 34e06d788..d94d390b7 100644 --- a/lib/stats/ticket_channel_distribution.rb +++ b/lib/stats/ticket_channel_distribution.rb @@ -41,6 +41,7 @@ class Stats::TicketChannelDistribution type_ids = [] Ticket::Article::Type.all.each do |type| next if type.name !~ /^#{channel[:sender]}/i + type_ids.push type.id end diff --git a/lib/stats/ticket_reopen.rb b/lib/stats/ticket_reopen.rb index 360d549d4..b5b8d80ef 100644 --- a/lib/stats/ticket_reopen.rb +++ b/lib/stats/ticket_reopen.rb @@ -65,6 +65,7 @@ class Stats::TicketReopen def self.log(object, o_id, changes, updated_by_id) return if object != 'Ticket' + ticket = Ticket.lookup(id: o_id) return if !ticket diff --git a/lib/tasks/search_index_es.rake b/lib/tasks/search_index_es.rake index 7771fd055..2f8da0d07 100644 --- a/lib/tasks/search_index_es.rake +++ b/lib/tasks/search_index_es.rake @@ -111,6 +111,7 @@ namespace :searchindex do # update processors pipeline = Setting.get('es_pipeline') next if pipeline.blank? + print 'delete pipeline (pipeline)... ' SearchIndexBackend.processors( "_ingest/pipeline/#{pipeline}": [ diff --git a/lib/tasks/zammad/setup/db_config.rake b/lib/tasks/zammad/setup/db_config.rake index aa64b0d63..881c143bd 100644 --- a/lib/tasks/zammad/setup/db_config.rake +++ b/lib/tasks/zammad/setup/db_config.rake @@ -13,6 +13,7 @@ namespace :zammad do if File.exist?(destination) next if FileUtils.identical?(template, destination) + printf 'config/database.yml: File exists. Overwrite? [y/N] ' next if STDIN.gets.chomp.downcase != 'y' end diff --git a/lib/telegram.rb b/lib/telegram.rb index de822a067..833e248b2 100644 --- a/lib/telegram.rb +++ b/lib/telegram.rb @@ -38,6 +38,7 @@ returns if callback_url.match?(%r{^http://}i) raise 'webhook url need to start with https://, you use http://' end + api = TelegramAPI.new(token) begin api.setWebhook(callback_url) @@ -73,6 +74,7 @@ returns if params[:group_id].blank? raise 'Group needed!' end + group = Group.find_by(id: params[:group_id]) if !group raise 'Group invalid!' @@ -133,6 +135,7 @@ returns next if !channel.options[:bot][:id] next if channel.options[:bot][:id] != bot_id next if channel.id.to_s == channel_id.to_s + return true end false @@ -177,6 +180,7 @@ returns %i[message edited_message].each do |key| next if !params[key] next if !params[key][:message_id] + message_id = params[key][:message_id] break end @@ -185,6 +189,7 @@ returns next if !params[key] next if !params[key][:chat] next if !params[key][:chat][:id] + message_id = "#{message_id}.#{params[key][:chat][:id]}" end end @@ -213,6 +218,7 @@ returns def message(chat_id, message) return if Rails.env.test? + @api.sendMessage(chat_id, message) end @@ -282,6 +288,7 @@ returns %i[text caption].each do |area| next if !params[:message] next if !params[:message][area] + title = params[:message][area] break end @@ -291,6 +298,7 @@ returns next if !params[:message] next if !params[:message][area] next if !params[:message][area][:emoji] + title = params[:message][area][:emoji] break rescue @@ -395,6 +403,7 @@ returns last_height = file['height'].to_i end next if file['width'].to_i >= max_width || file['width'].to_i <= last_width + photo = file last_width = file['width'].to_i last_height = file['height'].to_i @@ -409,6 +418,7 @@ returns if !result.success? || !result.body raise "Unable for download image from telegram: #{result.code}" end + body = "" if params[:message][:caption] body += "
#{params[:message][:caption].text2html}" @@ -430,6 +440,7 @@ returns if !result.success? || !result.body raise "Unable for download image from telegram: #{result.code}" end + body = "" end document_result = download_file(params[:message][:document][:file_id]) @@ -489,6 +500,7 @@ returns if !result.success? || !result.body raise "Unable for download image from telegram: #{result.code}" end + body = "" article.content_type = 'text/html' elsif emoji @@ -534,6 +546,7 @@ returns # map channel_post params to message if params[:channel_post] return if params[:channel_post][:new_chat_title] # happens when channel title is renamed, we use [:chat][:title] already, safely ignore this. + # note: used .blank? which is a rails method. empty? does not work on integers (values like date, width, height) to check. # need delete_if to remove any empty hashes, .compact only removes keys with nil values. params[:message] = { @@ -582,7 +595,7 @@ returns last_name: 'Channel', username: "channel#{params.dig(:channel_post, :chat, :id)}" }, - caption: (params.dig(:channel_post, :caption) ? params.dig(:channel_post, :caption) : {}), + caption: (params.dig(:channel_post, :caption) || {}), date: params.dig(:channel_post, :date), message_id: params.dig(:channel_post, :message_id), text: params.dig(:channel_post, :text), @@ -624,6 +637,7 @@ returns if params[:edited_message] article = Ticket::Article.find_by(message_id: Telegram.message_id(params)) return if !article + params[:message] = params[:edited_message] user = to_user(params) to_article(params, user, article.ticket, channel, article) @@ -684,6 +698,7 @@ returns state = Ticket::State.find_by(default_create: true) return state if !ticket return ticket.state if ticket.state.id == state.id + Ticket::State.find_by(default_follow_up: true) end diff --git a/lib/tweet_base.rb b/lib/tweet_base.rb index c40a5b839..d6910cb36 100644 --- a/lib/tweet_base.rb +++ b/lib/tweet_base.rb @@ -47,8 +47,10 @@ class TweetBase # ignore if value is already set map.each do |target, source| next if user[target].present? + new_value = tweet_user.send(source).to_s next if new_value.blank? + user_data[target] = new_value end user.update!(user_data) @@ -328,6 +330,7 @@ class TweetBase state = Ticket::State.find_by(default_create: true) return state if !ticket return ticket.state if ticket.state_id == state.id + Ticket::State.find_by(default_follow_up: true) end @@ -368,6 +371,7 @@ class TweetBase # replace Twitter::NullObject with nill to prevent elasticsearch index issue preferences.each_value do |value| next if !value.is_a?(Hash) + value.each do |sub_key, sub_level| if sub_level.class == NilClass value[sub_key] = nil @@ -378,6 +382,7 @@ class TweetBase next end next if sub_level.class != Twitter::NullObject + value[sub_key] = nil end end @@ -391,6 +396,7 @@ class TweetBase next if !local_channel.options[:user] next if !local_channel.options[:user][:id] next if local_channel.options[:user][:id].to_s != tweet_user.id.to_s + Rails.logger.debug { "Tweet is sent by local account with user id #{tweet_user.id} and tweet.id #{tweet.id}" } return true end diff --git a/lib/tweet_rest.rb b/lib/tweet_rest.rb index d38d95bfd..f7ced80d9 100644 --- a/lib/tweet_rest.rb +++ b/lib/tweet_rest.rb @@ -17,6 +17,7 @@ class TweetRest < TweetBase def disconnect return if !@client + @client = nil end diff --git a/lib/tweet_stream.rb b/lib/tweet_stream.rb index 925d1cfa7..eb8222703 100644 --- a/lib/tweet_stream.rb +++ b/lib/tweet_stream.rb @@ -22,6 +22,7 @@ class TweetStream < TweetBase end return if !@client + @client = nil end diff --git a/lib/user_agent.rb b/lib/user_agent.rb index b6354a422..256c8a43f 100644 --- a/lib/user_agent.rb +++ b/lib/user_agent.rb @@ -411,6 +411,7 @@ returns ) when Net::HTTPRedirection raise 'Too many redirections for the original URL, halting.' if count <= 0 + url = response['location'] return get(url, params, options, count - 1) when Net::HTTPOK @@ -506,6 +507,7 @@ returns def success? return true if @success + false end end diff --git a/lib/user_info.rb b/lib/user_info.rb index 604e9e964..1361996dd 100644 --- a/lib/user_info.rb +++ b/lib/user_info.rb @@ -16,6 +16,7 @@ module UserInfo yield return if !reset_current_user_id + UserInfo.current_user_id = nil end end diff --git a/script/websocket-server.rb b/script/websocket-server.rb index 94f8d7fcb..a4a425a45 100755 --- a/script/websocket-server.rb +++ b/script/websocket-server.rb @@ -228,11 +228,13 @@ EventMachine.run do clients = 0 client_list.each_value do |client| next if client[:meta][:type] == 'websocket' + clients = clients + 1 end log 'notice', "Status: ajax clients: #{clients}" client_list.each do |client_id, client| next if client[:meta][:type] == 'websocket' + log 'notice', 'working...', client_id end @@ -240,13 +242,16 @@ EventMachine.run do EventMachine.add_periodic_timer(0.4) do next if @clients.size.zero? + #log 'debug', 'checking for data to send...' @clients.each do |client_id, client| next if client[:disconnect] + log 'debug', 'checking for data...', client_id begin queue = Sessions.queue(client_id) next if queue.blank? + log 'notice', 'send data to client', client_id websocket_send(client_id, queue) rescue => e @@ -265,6 +270,7 @@ EventMachine.run do def get_remote_ip(headers) return headers['X-Forwarded-For'] if headers && headers['X-Forwarded-For'] + nil end diff --git a/spec/lib/import/otrs/article/attachment_factory_spec.rb b/spec/lib/import/otrs/article/attachment_factory_spec.rb index 1350f9c65..11d5cb3de 100644 --- a/spec/lib/import/otrs/article/attachment_factory_spec.rb +++ b/spec/lib/import/otrs/article/attachment_factory_spec.rb @@ -27,7 +27,7 @@ RSpec.describe Import::OTRS::Article::AttachmentFactory do expect(Store).to receive(:add).exactly(3).times.with(hash_including( object: 'Ticket::Article', o_id: local_article.id, - )) + )) end def article_attachment_expectations(article_attachments) diff --git a/spec/requests/api_auth_on_behalf_of_spec.rb b/spec/requests/api_auth_on_behalf_of_spec.rb index 97227678e..b56289876 100644 --- a/spec/requests/api_auth_on_behalf_of_spec.rb +++ b/spec/requests/api_auth_on_behalf_of_spec.rb @@ -63,6 +63,7 @@ RSpec.describe 'Api Auth On Behalf Of', type: :request do activity_stream = ActivityStream.find(record_id) next if activity_stream.object.name != 'Ticket' next if activity_stream.o_id != json_response_ticket['id'].to_i + ticket_created = activity_stream end @@ -79,6 +80,7 @@ RSpec.describe 'Api Auth On Behalf Of', type: :request do activity_stream = ActivityStream.find(record['id']) next if activity_stream.object.name != 'Ticket' next if activity_stream.o_id != json_response_ticket['id'] + ticket_created = activity_stream end diff --git a/spec/support/db_migration.rb b/spec/support/db_migration.rb index 49f9e87af..4ef73c015 100644 --- a/spec/support/db_migration.rb +++ b/spec/support/db_migration.rb @@ -48,6 +48,7 @@ module DbMigrationHelper def witout_foreign_key(from_table, column:) suppress_messages do break if !foreign_key_exists?(from_table, column: column) + remove_foreign_key(from_table, column: column) end end diff --git a/spec/support/searchindex_backend.rb b/spec/support/searchindex_backend.rb index 10dfbefd0..481030749 100644 --- a/spec/support/searchindex_backend.rb +++ b/spec/support/searchindex_backend.rb @@ -3,6 +3,7 @@ module SearchindexBackendHelper def configure_elasticsearch(required: false) if ENV['ES_URL'].blank? return if !required + raise "ERROR: Need ES_URL - hint ES_URL='http://127.0.0.1:9200'" end @@ -21,6 +22,7 @@ module SearchindexBackendHelper if ENV['ES_INDEX'].blank? raise "ERROR: Need ES_INDEX - hint ES_INDEX='estest.local_zammad'" end + Setting.set('es_index', ENV['ES_INDEX']) # set max attachment size in mb diff --git a/test/browser/aaa_getting_started_test.rb b/test/browser/aaa_getting_started_test.rb index 252caa6ab..e912b73a5 100644 --- a/test/browser/aaa_getting_started_test.rb +++ b/test/browser/aaa_getting_started_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AaaGettingStartedTest < TestCase @@ -194,6 +193,7 @@ class AaaGettingStartedTest < TestCase fqdn = $1 end raise "Unable to get fqdn based on #{browser_url}" if !fqdn + match( css: '.content.active input[name="fqdn"]', value: fqdn, @@ -205,6 +205,7 @@ class AaaGettingStartedTest < TestCase accounts = [] (1..10).each do |count| next if !ENV["MAILBOX_AUTO#{count}"] + mailbox_user = ENV["MAILBOX_AUTO#{count}"].split(':')[0] mailbox_password = ENV["MAILBOX_AUTO#{count}"].split(':')[1] account = { @@ -268,6 +269,7 @@ class AaaGettingStartedTest < TestCase accounts = [] (1..10).each do |count| next if !ENV["MAILBOX_MANUAL#{count}"] + mailbox_user = ENV["MAILBOX_MANUAL#{count}"].split(':')[0] mailbox_password = ENV["MAILBOX_MANUAL#{count}"].split(':')[1] mailbox_inbound = ENV["MAILBOX_MANUAL#{count}"].split(':')[2] diff --git a/test/browser/aab_basic_urls_test.rb b/test/browser/aab_basic_urls_test.rb index 5bd5838cf..8259242c8 100644 --- a/test/browser/aab_basic_urls_test.rb +++ b/test/browser/aab_basic_urls_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AABBasicUrlsTest < TestCase diff --git a/test/browser/aab_unit_test.rb b/test/browser/aab_unit_test.rb index 86d7bee2c..5ddd104e8 100644 --- a/test/browser/aab_unit_test.rb +++ b/test/browser/aab_unit_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AAbUnitTest < TestCase diff --git a/test/browser/aac_basic_richtext_test.rb b/test/browser/aac_basic_richtext_test.rb index c3e026954..9dc4a2441 100644 --- a/test/browser/aac_basic_richtext_test.rb +++ b/test/browser/aac_basic_richtext_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AACBasicRichtextTest < TestCase diff --git a/test/browser/abb_one_group_test.rb b/test/browser/abb_one_group_test.rb index 70a58a0e9..35a4c9034 100644 --- a/test/browser/abb_one_group_test.rb +++ b/test/browser/abb_one_group_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketActionLevel0Test < TestCase diff --git a/test/browser/admin_calendar_sla_test.rb b/test/browser/admin_calendar_sla_test.rb index 067bb5010..bf86a050e 100644 --- a/test/browser/admin_calendar_sla_test.rb +++ b/test/browser/admin_calendar_sla_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AdminCalendarSlaTest < TestCase diff --git a/test/browser/admin_channel_email_test.rb b/test/browser/admin_channel_email_test.rb index 5b62f1ec2..b19a013d0 100644 --- a/test/browser/admin_channel_email_test.rb +++ b/test/browser/admin_channel_email_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AdminChannelEmailTest < TestCase @@ -70,6 +69,7 @@ class AdminChannelEmailTest < TestCase # delete all channels loop do break if !@browser.find_elements(css: '.content.active .js-channelDelete')[0] + click(css: '.content.active .js-channelDelete') sleep 2 click(css: '.modal .js-submit') diff --git a/test/browser/admin_object_manager_test.rb b/test/browser/admin_object_manager_test.rb index 9a8fb4800..d2e9e23ff 100644 --- a/test/browser/admin_object_manager_test.rb +++ b/test/browser/admin_object_manager_test.rb @@ -565,6 +565,7 @@ class AdminObjectManagerTest < TestCase 30.times do deletable_attribute = instance.find_elements(xpath: '//td[text()="deletable_attribute"]/following-sibling::*[2]')[0] break if deletable_attribute + sleep 1 end diff --git a/test/browser/admin_overview_test.rb b/test/browser/admin_overview_test.rb index 68de128fe..9f2c8d584 100644 --- a/test/browser/admin_overview_test.rb +++ b/test/browser/admin_overview_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AdminOverviewTest < TestCase diff --git a/test/browser/admin_role_test.rb b/test/browser/admin_role_test.rb index da4e862b0..8981373f6 100644 --- a/test/browser/admin_role_test.rb +++ b/test/browser/admin_role_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AdminRoleTest < TestCase diff --git a/test/browser/agent_navigation_and_title_test.rb b/test/browser/agent_navigation_and_title_test.rb index 499ca87b0..594cd8ab6 100644 --- a/test/browser/agent_navigation_and_title_test.rb +++ b/test/browser/agent_navigation_and_title_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentNavigationAndTitleTest < TestCase diff --git a/test/browser/agent_organization_profile_test.rb b/test/browser/agent_organization_profile_test.rb index 45d06494d..e12807299 100644 --- a/test/browser/agent_organization_profile_test.rb +++ b/test/browser/agent_organization_profile_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentOrganizationProfileTest < TestCase diff --git a/test/browser/agent_ticket_attachment_test.rb b/test/browser/agent_ticket_attachment_test.rb index abaf83d72..6c2f496f2 100644 --- a/test/browser/agent_ticket_attachment_test.rb +++ b/test/browser/agent_ticket_attachment_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketAttachmentTest < TestCase diff --git a/test/browser/agent_ticket_auto_assignment_test.rb b/test/browser/agent_ticket_auto_assignment_test.rb index 8e3b9c335..b29cd8d84 100644 --- a/test/browser/agent_ticket_auto_assignment_test.rb +++ b/test/browser/agent_ticket_auto_assignment_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketAutoAssignmentTest < TestCase diff --git a/test/browser/agent_ticket_create_available_types_test.rb b/test/browser/agent_ticket_create_available_types_test.rb index 92ae4a877..1d496981c 100644 --- a/test/browser/agent_ticket_create_available_types_test.rb +++ b/test/browser/agent_ticket_create_available_types_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' # Regression test for UI enhancement diff --git a/test/browser/agent_ticket_create_default_type_test.rb b/test/browser/agent_ticket_create_default_type_test.rb index 4bb06798c..1cbad1142 100644 --- a/test/browser/agent_ticket_create_default_type_test.rb +++ b/test/browser/agent_ticket_create_default_type_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' # Regression test for UI enhancement diff --git a/test/browser/agent_ticket_create_reset_customer_selection_test.rb b/test/browser/agent_ticket_create_reset_customer_selection_test.rb index 83cedd3d2..9e95d795a 100644 --- a/test/browser/agent_ticket_create_reset_customer_selection_test.rb +++ b/test/browser/agent_ticket_create_reset_customer_selection_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketCreateResetCustomerSelectionTest < TestCase diff --git a/test/browser/agent_ticket_create_template_test.rb b/test/browser/agent_ticket_create_template_test.rb index 4111f7bf5..b7787eae9 100644 --- a/test/browser/agent_ticket_create_template_test.rb +++ b/test/browser/agent_ticket_create_template_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' # Regression test for UI bugfix diff --git a/test/browser/agent_ticket_email_reply_keep_body_test.rb b/test/browser/agent_ticket_email_reply_keep_body_test.rb index 51a91a6a2..3ea521b87 100644 --- a/test/browser/agent_ticket_email_reply_keep_body_test.rb +++ b/test/browser/agent_ticket_email_reply_keep_body_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketEmailReplyKeepBodyTest < TestCase diff --git a/test/browser/agent_ticket_email_signature_test.rb b/test/browser/agent_ticket_email_signature_test.rb index e5cd13b5f..74b61919a 100644 --- a/test/browser/agent_ticket_email_signature_test.rb +++ b/test/browser/agent_ticket_email_signature_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketEmailSignatureTest < TestCase diff --git a/test/browser/agent_ticket_link_test.rb b/test/browser/agent_ticket_link_test.rb index 19de03399..b19f5a2e0 100644 --- a/test/browser/agent_ticket_link_test.rb +++ b/test/browser/agent_ticket_link_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketLinkTest < TestCase diff --git a/test/browser/agent_ticket_macro_test.rb b/test/browser/agent_ticket_macro_test.rb index da18df919..d646dd123 100644 --- a/test/browser/agent_ticket_macro_test.rb +++ b/test/browser/agent_ticket_macro_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketMacroTest < TestCase diff --git a/test/browser/agent_ticket_merge_test.rb b/test/browser/agent_ticket_merge_test.rb index 99d6c90e9..720f4278b 100644 --- a/test/browser/agent_ticket_merge_test.rb +++ b/test/browser/agent_ticket_merge_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketMergeTest < TestCase diff --git a/test/browser/agent_ticket_online_notification_test.rb b/test/browser/agent_ticket_online_notification_test.rb index db0bd9e0e..6e7e52ae6 100644 --- a/test/browser/agent_ticket_online_notification_test.rb +++ b/test/browser/agent_ticket_online_notification_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketOnlineNotificationTest < TestCase diff --git a/test/browser/agent_ticket_overview_group_by_organization_test.rb b/test/browser/agent_ticket_overview_group_by_organization_test.rb index d49be92ee..069595f68 100644 --- a/test/browser/agent_ticket_overview_group_by_organization_test.rb +++ b/test/browser/agent_ticket_overview_group_by_organization_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketOverviewGroupByOrganizationTest < TestCase diff --git a/test/browser/agent_ticket_overview_level0_test.rb b/test/browser/agent_ticket_overview_level0_test.rb index 74a83ec7b..214fee70f 100644 --- a/test/browser/agent_ticket_overview_level0_test.rb +++ b/test/browser/agent_ticket_overview_level0_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketOverviewLevel0Test < TestCase diff --git a/test/browser/agent_ticket_overview_level1_test.rb b/test/browser/agent_ticket_overview_level1_test.rb index 2f6ebdc7c..05c32d2cc 100644 --- a/test/browser/agent_ticket_overview_level1_test.rb +++ b/test/browser/agent_ticket_overview_level1_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketOverviewLevel1Test < TestCase diff --git a/test/browser/agent_ticket_overview_tab_test.rb b/test/browser/agent_ticket_overview_tab_test.rb index b38a524f5..ca513c6ea 100644 --- a/test/browser/agent_ticket_overview_tab_test.rb +++ b/test/browser/agent_ticket_overview_tab_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketOverviewTabTest < TestCase diff --git a/test/browser/agent_ticket_tag_test.rb b/test/browser/agent_ticket_tag_test.rb index 1013ff8ae..025f3b03e 100644 --- a/test/browser/agent_ticket_tag_test.rb +++ b/test/browser/agent_ticket_tag_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketTagTest < TestCase diff --git a/test/browser/agent_ticket_text_module_test.rb b/test/browser/agent_ticket_text_module_test.rb index ca44ff399..3385a03c1 100644 --- a/test/browser/agent_ticket_text_module_test.rb +++ b/test/browser/agent_ticket_text_module_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketTextModuleTest < TestCase diff --git a/test/browser/agent_ticket_time_accounting_test.rb b/test/browser/agent_ticket_time_accounting_test.rb index 2f047577d..d93ea99c1 100644 --- a/test/browser/agent_ticket_time_accounting_test.rb +++ b/test/browser/agent_ticket_time_accounting_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketTimeAccountingTest < TestCase diff --git a/test/browser/agent_ticket_update1_test.rb b/test/browser/agent_ticket_update1_test.rb index 5f9be5085..b88b89229 100644 --- a/test/browser/agent_ticket_update1_test.rb +++ b/test/browser/agent_ticket_update1_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketUpdate1Test < TestCase diff --git a/test/browser/agent_ticket_update2_test.rb b/test/browser/agent_ticket_update2_test.rb index 6a1c0ace1..672c08c2c 100644 --- a/test/browser/agent_ticket_update2_test.rb +++ b/test/browser/agent_ticket_update2_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketUpdate2Test < TestCase diff --git a/test/browser/agent_ticket_update3_test.rb b/test/browser/agent_ticket_update3_test.rb index 9dc52755b..e096a6971 100644 --- a/test/browser/agent_ticket_update3_test.rb +++ b/test/browser/agent_ticket_update3_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketUpdate3Test < TestCase diff --git a/test/browser/agent_ticket_update5_test.rb b/test/browser/agent_ticket_update5_test.rb index c21ab1327..5a6ebc31b 100644 --- a/test/browser/agent_ticket_update5_test.rb +++ b/test/browser/agent_ticket_update5_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketUpdate5Test < TestCase diff --git a/test/browser/agent_ticket_update_and_reload_test.rb b/test/browser/agent_ticket_update_and_reload_test.rb index 9f8d3083d..b4eef7dbe 100644 --- a/test/browser/agent_ticket_update_and_reload_test.rb +++ b/test/browser/agent_ticket_update_and_reload_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentTicketUpdateAndReloadTest < TestCase diff --git a/test/browser/agent_user_manage_test.rb b/test/browser/agent_user_manage_test.rb index 15555cc80..ed9b5ef06 100644 --- a/test/browser/agent_user_manage_test.rb +++ b/test/browser/agent_user_manage_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentUserManageTest < TestCase diff --git a/test/browser/agent_user_profile_test.rb b/test/browser/agent_user_profile_test.rb index 929502aa4..c2bc46dc8 100644 --- a/test/browser/agent_user_profile_test.rb +++ b/test/browser/agent_user_profile_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AgentUserProfileTest < TestCase diff --git a/test/browser/auth_test.rb b/test/browser/auth_test.rb index 2ea4238c5..d61443bba 100644 --- a/test/browser/auth_test.rb +++ b/test/browser/auth_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AuthTest < TestCase diff --git a/test/browser/chat_test.rb b/test/browser/chat_test.rb index 0d5b0b9d8..ead09eba3 100644 --- a/test/browser/chat_test.rb +++ b/test/browser/chat_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class ChatTest < TestCase diff --git a/test/browser/customer_ticket_create_test.rb b/test/browser/customer_ticket_create_test.rb index a9108aaa6..0c510c626 100644 --- a/test/browser/customer_ticket_create_test.rb +++ b/test/browser/customer_ticket_create_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class CustomerTicketCreateTest < TestCase diff --git a/test/browser/first_steps_test.rb b/test/browser/first_steps_test.rb index bd3f30012..71d05cb3c 100644 --- a/test/browser/first_steps_test.rb +++ b/test/browser/first_steps_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class FirstStepsTest < TestCase @@ -126,6 +125,7 @@ class FirstStepsTest < TestCase hit = false 37.times do next if !@browser.find_elements(css: '.active.content a[href="#channels/form"].todo.is-done')[0] + hit = true break end diff --git a/test/browser/form_test.rb b/test/browser/form_test.rb index 140abdb5c..eb6435859 100644 --- a/test/browser/form_test.rb +++ b/test/browser/form_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class FormTest < TestCase diff --git a/test/browser/integration_test.rb b/test/browser/integration_test.rb index 3154d012d..fd480ff4d 100644 --- a/test/browser/integration_test.rb +++ b/test/browser/integration_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class IntegrationTest < TestCase diff --git a/test/browser/keyboard_shortcuts_test.rb b/test/browser/keyboard_shortcuts_test.rb index 0f971ef49..365a649ea 100644 --- a/test/browser/keyboard_shortcuts_test.rb +++ b/test/browser/keyboard_shortcuts_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class KeyboardShortcutsTest < TestCase @@ -21,6 +20,7 @@ class KeyboardShortcutsTest < TestCase (1..4).each do |_count| sleep 1 next if !@browser.find_elements(css: '.modal')[0] + exists = true end if !exists @@ -30,6 +30,7 @@ class KeyboardShortcutsTest < TestCase (1..4).each do |_count| sleep 1 next if !@browser.find_elements(css: '.modal')[0] + exists = true end end diff --git a/test/browser/maintenance_app_version_test.rb b/test/browser/maintenance_app_version_test.rb index 2370bd88c..1cf5f703d 100644 --- a/test/browser/maintenance_app_version_test.rb +++ b/test/browser/maintenance_app_version_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class MaintenanceAppVersionTest < TestCase diff --git a/test/browser/maintenance_login_message_test.rb b/test/browser/maintenance_login_message_test.rb index 90423b034..45c14df60 100644 --- a/test/browser/maintenance_login_message_test.rb +++ b/test/browser/maintenance_login_message_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class MaintenanceLoginMessageTest < TestCase diff --git a/test/browser/maintenance_mode_test.rb b/test/browser/maintenance_mode_test.rb index b617688ea..597b0a1e7 100644 --- a/test/browser/maintenance_mode_test.rb +++ b/test/browser/maintenance_mode_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class MaintenanceModeTest < TestCase diff --git a/test/browser/maintenance_session_message_test.rb b/test/browser/maintenance_session_message_test.rb index 8c7093a4c..3c31cec86 100644 --- a/test/browser/maintenance_session_message_test.rb +++ b/test/browser/maintenance_session_message_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class MaintenanceSessionMessageTest < TestCase diff --git a/test/browser/manage_test.rb b/test/browser/manage_test.rb index ba89f07bf..75c82f3e5 100644 --- a/test/browser/manage_test.rb +++ b/test/browser/manage_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class ManageTest < TestCase diff --git a/test/browser/monitoring_test.rb b/test/browser/monitoring_test.rb index 695c4a87e..47cf9e80e 100644 --- a/test/browser/monitoring_test.rb +++ b/test/browser/monitoring_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class MonitoringTest < TestCase diff --git a/test/browser/preferences_language_test.rb b/test/browser/preferences_language_test.rb index 59903391a..8f836a8ed 100644 --- a/test/browser/preferences_language_test.rb +++ b/test/browser/preferences_language_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class PreferencesLanguageTest < TestCase diff --git a/test/browser/preferences_permission_check_test.rb b/test/browser/preferences_permission_check_test.rb index a08e69af1..2e141ba4f 100644 --- a/test/browser/preferences_permission_check_test.rb +++ b/test/browser/preferences_permission_check_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class PreferencesPermissionCheckTest < TestCase diff --git a/test/browser/preferences_token_access_test.rb b/test/browser/preferences_token_access_test.rb index 5329221d3..cc8640584 100644 --- a/test/browser/preferences_token_access_test.rb +++ b/test/browser/preferences_token_access_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class PreferencesTokenAccessTest < TestCase diff --git a/test/browser/reporting_test.rb b/test/browser/reporting_test.rb index 834990644..a455718d2 100644 --- a/test/browser/reporting_test.rb +++ b/test/browser/reporting_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class ReportingTest < TestCase diff --git a/test/browser/setting_test.rb b/test/browser/setting_test.rb index 5783bd097..f22aeaa66 100644 --- a/test/browser/setting_test.rb +++ b/test/browser/setting_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class SettingTest < TestCase diff --git a/test/browser/signup_password_change_and_reset_test.rb b/test/browser/signup_password_change_and_reset_test.rb index c807e5fd7..8545d5def 100644 --- a/test/browser/signup_password_change_and_reset_test.rb +++ b/test/browser/signup_password_change_and_reset_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class SignupPasswordChangeAndResetTest < TestCase diff --git a/test/browser/switch_to_user_test.rb b/test/browser/switch_to_user_test.rb index b060c3d4e..9f7e74bf6 100644 --- a/test/browser/switch_to_user_test.rb +++ b/test/browser/switch_to_user_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class SwitchToUserTest < TestCase diff --git a/test/browser/taskbar_session_test.rb b/test/browser/taskbar_session_test.rb index f289d0d37..6a15df149 100644 --- a/test/browser/taskbar_session_test.rb +++ b/test/browser/taskbar_session_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class TaskbarSessionTest < TestCase diff --git a/test/browser/taskbar_task_test.rb b/test/browser/taskbar_task_test.rb index 88d9b2d0f..49da08cd4 100644 --- a/test/browser/taskbar_task_test.rb +++ b/test/browser/taskbar_task_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class TaskbarTaskTest < TestCase diff --git a/test/browser/translation_test.rb b/test/browser/translation_test.rb index b49373866..5a11bd0b2 100644 --- a/test/browser/translation_test.rb +++ b/test/browser/translation_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class TranslationTest < TestCase diff --git a/test/browser/user_switch_cache_test.rb b/test/browser/user_switch_cache_test.rb index fd3cc8fff..6aaad5e37 100644 --- a/test/browser/user_switch_cache_test.rb +++ b/test/browser/user_switch_cache_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class UserSwitchCache < TestCase diff --git a/test/browser_test_helper.rb b/test/browser_test_helper.rb index 5e7a75410..30d828f66 100644 --- a/test/browser_test_helper.rb +++ b/test/browser_test_helper.rb @@ -41,6 +41,7 @@ class TestCase < Test::Unit::TestCase if browser.match?(/(internet_explorer|ie)/i) return false end + true end @@ -111,6 +112,7 @@ class TestCase < Test::Unit::TestCase def browser_instance_close(local_browser) return if !@browsers[local_browser.hash] + @browsers.delete(local_browser.hash) local_browser.quit end @@ -131,6 +133,7 @@ class TestCase < Test::Unit::TestCase def teardown return if !@browsers + @browsers.each_value do |local_browser| screenshot(browser: local_browser, comment: 'teardown') browser_instance_close(local_browser) @@ -275,6 +278,7 @@ class TestCase < Test::Unit::TestCase login = instance.find_elements(css: '#login')[0] next if !login + assert(true, 'logout ok') return end @@ -303,6 +307,7 @@ class TestCase < Test::Unit::TestCase raise 'Unable to closes clues, no clues found!' end return if !clues + instance.execute_script("$('.js-modal--clue .js-close').click()") assert(true, 'clues closed') sleep 1 @@ -329,6 +334,7 @@ class TestCase < Test::Unit::TestCase raise 'Unable to closes notify, no notify found!' end return if !notify + notify.click assert(true, 'notify closed') sleep 1 @@ -449,6 +455,7 @@ class TestCase < Test::Unit::TestCase if elements.empty? return if params[:only_if_exists] == true + raise "No such element '#{params[param_key]}'" end @@ -611,6 +618,7 @@ class TestCase < Test::Unit::TestCase if params[:js] return instance.execute_script(params[:js]) end + raise "Invalid execute params #{params.inspect}" end @@ -722,6 +730,7 @@ class TestCase < Test::Unit::TestCase log('set', { rescure: true }) element = instance.find_elements(css: params[:css])[0] raise "No such element '#{params[:css]}'" if !element + if !params[:slow] element.send_keys(params[:value]) else @@ -1335,6 +1344,7 @@ set type of task (closeTab, closeNextInOverview, stayOnTab) instance.find_elements(css: params[:css])[0].send_keys(Rails.root.join(file)) end return if params[:no_sleep] + sleep 2 * params[:files].count end @@ -1407,6 +1417,7 @@ set type of task (closeTab, closeNextInOverview, stayOnTab) if !params[:attribute] && !params[:value] raise "'#{selector}' not found" end + raise "'#{params[:value]}' not found in '#{text}'" end @@ -1737,6 +1748,7 @@ wait untill text in selector disabppears begin element = instance.find_elements(css: '.modal .js-selected[data-name=role_ids] .js-option:not(.is-hidden)')[0] break if !element + element.click sleep 0.1 end @@ -1868,6 +1880,7 @@ wait untill text in selector disabppears begin element = instance.find_elements(css: '.modal .js-selected[data-name=role_ids] .js-option:not(.is-hidden)')[0] break if !element + element.click sleep 0.1 end @@ -2991,6 +3004,7 @@ wait untill text in selector disabppears search_result = instance.find_elements(css: search_css).map(&:text).map(&:strip) break if search_result.include? search_target raise 'user creation failed' if i >= 19 + log "new user #{search_query} not found on the #{i.ordinalize} try, retrying" end @@ -3034,6 +3048,7 @@ wait untill text in selector disabppears ) instance.find_elements(css: '.content.active .user-list td:first-child').each do |element| next if element.text.strip != data[:login] + element.click break end @@ -4014,6 +4029,7 @@ wait untill text in selector disabppears # make sure that required params are supplied %i[name display data_type].each do |s| next if data.key? s + raise "missing required param #{s} in object_manager_attribute_create()" end @@ -4304,6 +4320,7 @@ wait untill text in selector disabppears logs = instance.manage.logs.get(:browser) logs.each do |log| next if log.level == 'WARNING' && log.message =~ /Declaration\sdropped./ # ignore ff css warnings + time = Time.zone.parse(Time.zone.at(log.timestamp / 1000).to_datetime.to_s) puts "#{time}/#{log.level}: #{log.message}" end @@ -4313,6 +4330,7 @@ wait untill text in selector disabppears end return if !DEBUG return if params[:mute_log] + puts "#{Time.zone.now}/#{method}: #{params.inspect}" end @@ -4423,6 +4441,7 @@ wait untill text in selector disabppears http.request(req) end raise "HTTP error #{res.code} while fetching #{browser_url}/api/v1/settings/" if res.code != '200' + JSON.parse(res.body) end @@ -4514,6 +4533,7 @@ wait untill text in selector disabppears mute_log: true, } break if !instance.find_elements(css: target[:css])[0] + click(target) end sleep 1 @@ -4535,6 +4555,7 @@ wait untill text in selector disabppears %i[default min max diff].each do |key| next if !data[:data_option].key?(key) + element = instance.find_elements(css: ".modal [name=\"data_option::#{key}\"]").first element.clear element.send_keys(data[:data_option][key]) @@ -4542,6 +4563,7 @@ wait untill text in selector disabppears %i[future past].each do |key| next if !data[:data_option].key?(key) + select( browser: instance, css: ".modal select[name=\"data_option::#{key}\"]", @@ -4552,6 +4574,7 @@ wait untill text in selector disabppears %i[maxlength].each do |key| next if !data[:data_option].key?(key) + set( browser: instance, css: ".modal input[name=\"data_option::#{key}\"]", diff --git a/test/fixtures/seeds.rb b/test/fixtures/seeds.rb index 8f21fdf54..92aee72e4 100644 --- a/test/fixtures/seeds.rb +++ b/test/fixtures/seeds.rb @@ -1,4 +1,3 @@ - # inital data set as extention to db/seeds.rb Trigger.destroy_all diff --git a/test/integration/aaa_auto_wizard_base_setup_test.rb b/test/integration/aaa_auto_wizard_base_setup_test.rb index 8f26b5169..44f405db9 100644 --- a/test/integration/aaa_auto_wizard_base_setup_test.rb +++ b/test/integration/aaa_auto_wizard_base_setup_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AaaAutoWizardBaseSetupTest < TestCase diff --git a/test/integration/auto_wizard_browser_test.rb b/test/integration/auto_wizard_browser_test.rb index f3fe539e7..216d6128b 100644 --- a/test/integration/auto_wizard_browser_test.rb +++ b/test/integration/auto_wizard_browser_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class AutoWizardBrowserTest < TestCase diff --git a/test/integration/clearbit_test.rb b/test/integration/clearbit_test.rb index 03f0e54f0..ca1aed55d 100644 --- a/test/integration/clearbit_test.rb +++ b/test/integration/clearbit_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class ClearbitTest < ActiveSupport::TestCase diff --git a/test/integration/elasticsearch_test.rb b/test/integration/elasticsearch_test.rb index 0dff6580e..b045c5724 100644 --- a/test/integration/elasticsearch_test.rb +++ b/test/integration/elasticsearch_test.rb @@ -308,7 +308,7 @@ class ElasticsearchTest < ActiveSupport::TestCase assert(result.present?, 'result exists not') assert(result[0], 'record 1') - assert(!result[1], 'record 2') + assert_not(result[1], 'record 2') assert_equal(result[0].id, ticket2.id) # search for html content @@ -320,7 +320,7 @@ class ElasticsearchTest < ActiveSupport::TestCase assert(result.present?, 'result exists not') assert(result[0], 'record 1') - assert(!result[1], 'record 2') + assert_not(result[1], 'record 2') assert_equal(result[0].id, ticket2.id) # search for indexed attachment @@ -346,14 +346,14 @@ class ElasticsearchTest < ActiveSupport::TestCase query: 'test88', limit: 15, ) - assert(!result[0], 'record 1') + assert_not(result[0], 'record 1') result = Ticket.search( current_user: @agent, query: 'test99', limit: 15, ) - assert(!result[0], 'record 1') + assert_not(result[0], 'record 1') # search for ticket with no permissions result = Ticket.search( @@ -362,7 +362,7 @@ class ElasticsearchTest < ActiveSupport::TestCase limit: 15, ) assert(result.blank?, 'result should be empty') - assert(!result[0], 'record 1') + assert_not(result[0], 'record 1') # search as @customer1 result = Ticket.search( @@ -374,7 +374,7 @@ class ElasticsearchTest < ActiveSupport::TestCase assert(result.present?, 'result exists not') assert(result[0], 'record 1') assert(result[1], 'record 2') - assert(!result[2], 'record 3') + assert_not(result[2], 'record 3') assert_equal(result[0].id, ticket2.id) assert_equal(result[1].id, ticket1.id) @@ -388,7 +388,7 @@ class ElasticsearchTest < ActiveSupport::TestCase assert(result.present?, 'result exists not') assert(result[0], 'record 1') assert(result[1], 'record 2') - assert(!result[2], 'record 3') + assert_not(result[2], 'record 3') assert_equal(result[0].id, ticket2.id) assert_equal(result[1].id, ticket1.id) @@ -401,7 +401,7 @@ class ElasticsearchTest < ActiveSupport::TestCase assert(result.present?, 'result exists not') assert(result[0], 'record 1') - assert(!result[1], 'record 2') + assert_not(result[1], 'record 2') assert_equal(result[0].id, ticket3.id) # search for tags @@ -411,7 +411,7 @@ class ElasticsearchTest < ActiveSupport::TestCase limit: 15, ) assert(result[0], 'record 1') - assert(!result[1], 'record 1') + assert_not(result[1], 'record 1') assert_equal(result[0].id, ticket1.id) result = Ticket.search( @@ -420,7 +420,7 @@ class ElasticsearchTest < ActiveSupport::TestCase limit: 15, ) assert(result[0], 'record 2') - assert(!result[1], 'record 2') + assert_not(result[1], 'record 2') assert_equal(result[0].id, ticket2.id) # rename tag (e. g. via admin interface) @@ -441,8 +441,8 @@ class ElasticsearchTest < ActiveSupport::TestCase query: 'tags:someTagA', limit: 15, ) - assert(!result[0], 'record 1') - assert(!result[1], 'record 1') + assert_not(result[0], 'record 1') + assert_not(result[1], 'record 1') result = Ticket.search( current_user: @agent, @@ -450,7 +450,7 @@ class ElasticsearchTest < ActiveSupport::TestCase limit: 15, ) assert(result[0], 'record 2') - assert(!result[1], 'record 2') + assert_not(result[1], 'record 2') assert_equal(result[0].id, ticket2.id) result = Ticket.search( @@ -459,7 +459,7 @@ class ElasticsearchTest < ActiveSupport::TestCase limit: 15, ) assert(result[0], 'record 1') - assert(!result[1], 'record 2') + assert_not(result[1], 'record 2') assert_equal(result[0].id, ticket1.id) result = Ticket.search( @@ -468,7 +468,7 @@ class ElasticsearchTest < ActiveSupport::TestCase limit: 15, ) assert(result[0], 'record 1') - assert(!result[1], 'record 2') + assert_not(result[1], 'record 2') assert_equal(result[0].id, ticket2.id) result = Ticket.search( @@ -477,7 +477,7 @@ class ElasticsearchTest < ActiveSupport::TestCase limit: 15, ) assert(result[0], 'record 1') - assert(!result[1], 'record 2') + assert_not(result[1], 'record 2') assert_equal(result[0].id, ticket1.id) result = Ticket.search( @@ -486,7 +486,7 @@ class ElasticsearchTest < ActiveSupport::TestCase limit: 15, ) assert(result[0], 'record 1') - assert(!result[1], 'record 2') + assert_not(result[1], 'record 2') assert_equal(result[0].id, ticket1.id) # check users and search it @@ -498,7 +498,7 @@ class ElasticsearchTest < ActiveSupport::TestCase ) assert(result.present?, 'result should not be empty') assert(result[0], 'record 1') - assert(!result[1], 'record 2') + assert_not(result[1], 'record 2') assert_equal(result[0].id, @customer1.id) # search as @customer1 @@ -508,7 +508,7 @@ class ElasticsearchTest < ActiveSupport::TestCase limit: 15, ) assert(result.blank?, 'result should be empty') - assert(!result[0], 'record 1') + assert_not(result[0], 'record 1') # cleanup Rake::Task['searchindex:drop'].execute diff --git a/test/integration/email_deliver_test.rb b/test/integration/email_deliver_test.rb index b7dff2901..d5a684f10 100644 --- a/test/integration/email_deliver_test.rb +++ b/test/integration/email_deliver_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class EmailDeliverTest < ActiveSupport::TestCase @@ -10,6 +9,7 @@ class EmailDeliverTest < ActiveSupport::TestCase if ENV['MAIL_SERVER_ACCOUNT'].blank? raise "Need MAIL_SERVER_ACCOUNT as ENV variable like export MAIL_SERVER_ACCOUNT='user:somepass'" end + server_login = ENV['MAIL_SERVER_ACCOUNT'].split(':')[0] server_password = ENV['MAIL_SERVER_ACCOUNT'].split(':')[1] diff --git a/test/integration/email_helper_test.rb b/test/integration/email_helper_test.rb index f13802872..8265deebe 100644 --- a/test/integration/email_helper_test.rb +++ b/test/integration/email_helper_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class EmailHelperTest < ActiveSupport::TestCase @@ -251,6 +250,7 @@ class EmailHelperTest < ActiveSupport::TestCase if !ENV['EMAILHELPER_MAILBOX_1'] raise "Need EMAILHELPER_MAILBOX_1 as ENV variable like export EMAILHELPER_MAILBOX_1='unittestemailhelper01@znuny.com:somepass'" end + mailbox_user = ENV['EMAILHELPER_MAILBOX_1'].split(':')[0] mailbox_password = ENV['EMAILHELPER_MAILBOX_1'].split(':')[1] user, domain = EmailHelper.parse_email(mailbox_user) @@ -403,6 +403,7 @@ class EmailHelperTest < ActiveSupport::TestCase if !ENV['EMAILHELPER_MAILBOX_1'] raise "Need EMAILHELPER_MAILBOX_1 as ENV variable like export EMAILHELPER_MAILBOX_1='unittestemailhelper01@znuny.com:somepass'" end + mailbox_user = ENV['EMAILHELPER_MAILBOX_1'].split(':')[0] mailbox_password = ENV['EMAILHELPER_MAILBOX_1'].split(':')[1] user, domain = EmailHelper.parse_email(mailbox_user) @@ -435,6 +436,7 @@ class EmailHelperTest < ActiveSupport::TestCase if !ENV['EMAILHELPER_MAILBOX_1'] raise "Need EMAILHELPER_MAILBOX_1 as ENV variable like export EMAILHELPER_MAILBOX_1='unittestemailhelper01@znuny.com:somepass'" end + mailbox_user = ENV['EMAILHELPER_MAILBOX_1'].split(':')[0] mailbox_password = ENV['EMAILHELPER_MAILBOX_1'].split(':')[1] @@ -450,6 +452,7 @@ class EmailHelperTest < ActiveSupport::TestCase if !ENV['EMAILHELPER_MAILBOX_2'] raise "Need EMAILHELPER_MAILBOX_2 as ENV variable like export EMAILHELPER_MAILBOX_2='hansb36621@gmail.com:somepass'" end + mailbox_user = ENV['EMAILHELPER_MAILBOX_2'].split(':')[0] mailbox_password = ENV['EMAILHELPER_MAILBOX_2'].split(':')[1] @@ -470,6 +473,7 @@ class EmailHelperTest < ActiveSupport::TestCase if !ENV['EMAILHELPER_MAILBOX_1'] raise "Need EMAILHELPER_MAILBOX_1 as ENV variable like export EMAILHELPER_MAILBOX_1='unittestemailhelper01@znuny.com:somepass'" end + mailbox_user = ENV['EMAILHELPER_MAILBOX_1'].split(':')[0] mailbox_password = ENV['EMAILHELPER_MAILBOX_1'].split(':')[1] user, domain = EmailHelper.parse_email(mailbox_user) @@ -502,6 +506,7 @@ class EmailHelperTest < ActiveSupport::TestCase if !ENV['EMAILHELPER_MAILBOX_2'] raise "Need EMAILHELPER_MAILBOX_2 as ENV variable like export EMAILHELPER_MAILBOX_2='hansb36621@gmail.com:somepass'" end + mailbox_user = ENV['EMAILHELPER_MAILBOX_2'].split(':')[0] mailbox_password = ENV['EMAILHELPER_MAILBOX_2'].split(':')[1] user, domain = EmailHelper.parse_email(mailbox_user) diff --git a/test/integration/email_keep_on_server_test.rb b/test/integration/email_keep_on_server_test.rb index e3003aad0..7d3fd7ec8 100644 --- a/test/integration/email_keep_on_server_test.rb +++ b/test/integration/email_keep_on_server_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' require 'net/imap' @@ -11,6 +10,7 @@ class EmailKeepOnServerTest < ActiveSupport::TestCase if ENV['KEEP_ON_MAIL_SERVER_ACCOUNT'].blank? raise "Need KEEP_ON_MAIL_SERVER_ACCOUNT as ENV variable like export KEEP_ON_MAIL_SERVER_ACCOUNT='user:somepass'" end + @server_login = ENV['KEEP_ON_MAIL_SERVER_ACCOUNT'].split(':')[0] @server_password = ENV['KEEP_ON_MAIL_SERVER_ACCOUNT'].split(':')[1] diff --git a/test/integration/facebook_browser_test.rb b/test/integration/facebook_browser_test.rb index d2e371e6f..4972f224b 100644 --- a/test/integration/facebook_browser_test.rb +++ b/test/integration/facebook_browser_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class FacebookBrowserTest < TestCase @@ -8,27 +7,33 @@ class FacebookBrowserTest < TestCase if !ENV['FACEBOOK_BT_APP_ID'] raise "ERROR: Need FACEBOOK_BT_APP_ID - hint FACEBOOK_BT_APP_ID='1234'" end + app_id = ENV['FACEBOOK_BT_APP_ID'] if !ENV['FACEBOOK_BT_APP_SECRET'] raise "ERROR: Need FACEBOOK_BT_APP_SECRET - hint FACEBOOK_BT_APP_SECRET='1234'" end + app_secret = ENV['FACEBOOK_BT_APP_SECRET'] if !ENV['FACEBOOK_BT_USER_LOGIN'] raise "ERROR: Need FACEBOOK_BT_USER_LOGIN - hint FACEBOOK_BT_USER_LOGIN='1234'" end + user_login = ENV['FACEBOOK_BT_USER_LOGIN'] if !ENV['FACEBOOK_BT_USER_PW'] raise "ERROR: Need FACEBOOK_BT_USER_PW - hint FACEBOOK_BT_USER_PW='1234'" end + user_pw = ENV['FACEBOOK_BT_USER_PW'] if !ENV['FACEBOOK_BT_PAGE_ID'] raise "ERROR: Need FACEBOOK_BT_PAGE_ID - hint FACEBOOK_BT_PAGE_ID='1234'" end + page_id = ENV['FACEBOOK_BT_PAGE_ID'] if !ENV['FACEBOOK_BT_CUSTOMER'] raise "ERROR: Need FACEBOOK_BT_CUSTOMER - hint FACEBOOK_BT_CUSTOMER='name:1234:access_token'" end + customer_name = ENV['FACEBOOK_BT_CUSTOMER'].split(':')[0] customer_id = ENV['FACEBOOK_BT_CUSTOMER'].split(':')[1] customer_access_token = ENV['FACEBOOK_BT_CUSTOMER'].split(':')[2] diff --git a/test/integration/facebook_test.rb b/test/integration/facebook_test.rb index a9cdc7808..2bf801efe 100644 --- a/test/integration/facebook_test.rb +++ b/test/integration/facebook_test.rb @@ -1,4 +1,3 @@ - require 'integration_test_helper' class FacebookTest < ActiveSupport::TestCase @@ -20,6 +19,7 @@ class FacebookTest < ActiveSupport::TestCase if !ENV['FACEBOOK_USER'] raise "ERROR: Need FACEBOOK_USER - hint FACEBOOK_USER='name:1234:access_token'" end + user_name = ENV['FACEBOOK_USER'].split(':')[0] user_id = ENV['FACEBOOK_USER'].split(':')[1] user_access_token = ENV['FACEBOOK_USER'].split(':')[2] @@ -27,6 +27,7 @@ class FacebookTest < ActiveSupport::TestCase if !ENV['FACEBOOK_PAGE'] raise "ERROR: Need FACEBOOK_PAGE - hint FACEBOOK_PAGE='name:1234:access_token'" end + page_name = ENV['FACEBOOK_PAGE'].split(':')[0] page_id = ENV['FACEBOOK_PAGE'].split(':')[1] page_access_token = ENV['FACEBOOK_PAGE'].split(':')[2] @@ -34,6 +35,7 @@ class FacebookTest < ActiveSupport::TestCase if !ENV['FACEBOOK_CUSTOMER'] raise "ERROR: Need FACEBOOK_CUSTOMER - hint FACEBOOK_CUSTOMER='name:1234:access_token'" end + customer_name = ENV['FACEBOOK_CUSTOMER'].split(':')[0] customer_id = ENV['FACEBOOK_CUSTOMER'].split(':')[1] customer_access_token = ENV['FACEBOOK_CUSTOMER'].split(':')[2] @@ -86,6 +88,7 @@ class FacebookTest < ActiveSupport::TestCase page_found = false client.pages.each do |page| next if page[:name] != page_name + page_found = true assert_equal(page_id, page[:id]) assert_equal(page_name, page[:name]) @@ -100,6 +103,7 @@ class FacebookTest < ActiveSupport::TestCase client = Facebook.new(page['access_token']) current_user = client.current_user next if page['name'] != page_name + page_found = true assert_equal(page_id, current_user['id']) assert_equal(page_name, current_user['name']) diff --git a/test/integration/geo_calendar_test.rb b/test/integration/geo_calendar_test.rb index 8ecd6bcaa..1aed1818c 100644 --- a/test/integration/geo_calendar_test.rb +++ b/test/integration/geo_calendar_test.rb @@ -1,4 +1,3 @@ - require 'integration_test_helper' class GeoIpCalendar < ActiveSupport::TestCase diff --git a/test/integration/geo_ip_test.rb b/test/integration/geo_ip_test.rb index a2537343a..77c5088ad 100644 --- a/test/integration/geo_ip_test.rb +++ b/test/integration/geo_ip_test.rb @@ -1,4 +1,3 @@ - require 'integration_test_helper' class GeoIpTest < ActiveSupport::TestCase diff --git a/test/integration/geo_location_test.rb b/test/integration/geo_location_test.rb index 7fb38f17c..ea4219ec2 100644 --- a/test/integration/geo_location_test.rb +++ b/test/integration/geo_location_test.rb @@ -1,4 +1,3 @@ - require 'integration_test_helper' require 'webmock/minitest' diff --git a/test/integration/idoit_browser_test.rb b/test/integration/idoit_browser_test.rb index 0369b0734..a9c813276 100644 --- a/test/integration/idoit_browser_test.rb +++ b/test/integration/idoit_browser_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class IntegrationIdoitTest < TestCase @@ -8,14 +7,17 @@ class IntegrationIdoitTest < TestCase if !ENV['IDOIT_API_TOKEN'] raise "ERROR: Need IDOIT_API_TOKEN - hint IDOIT_API_TOKEN='1234'" end + api_token = ENV['IDOIT_API_TOKEN'] if !ENV['IDOIT_API_ENDPOINT'] raise "ERROR: Need IDOIT_API_ENDPOINT - hint IDOIT_API_ENDPOINT='1234'" end + api_endpoint = ENV['IDOIT_API_ENDPOINT'] if !ENV['IDOIT_API_CATEGORY'] raise "ERROR: Need IDOIT_API_CATEGORY - hint IDOIT_API_CATEGORY='Building'" end + api_category = ENV['IDOIT_API_CATEGORY'] id = rand(99_999_999) diff --git a/test/integration/idoit_controller_test.rb b/test/integration/idoit_controller_test.rb index abc208c1f..9fda87711 100644 --- a/test/integration/idoit_controller_test.rb +++ b/test/integration/idoit_controller_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' require 'webmock/minitest' diff --git a/test/integration/object_manager_test.rb b/test/integration/object_manager_test.rb index 725f2f56e..8a4302341 100644 --- a/test/integration/object_manager_test.rb +++ b/test/integration/object_manager_test.rb @@ -807,6 +807,7 @@ class ObjectManagerTest < ActiveSupport::TestCase overview = nil result.each do |local_overview| next if local_overview[:overview][:name] != 'Overview1' + overview = local_overview break end diff --git a/test/integration/otrs_import_browser_test.rb b/test/integration/otrs_import_browser_test.rb index 9329089e3..71dbe083b 100644 --- a/test/integration/otrs_import_browser_test.rb +++ b/test/integration/otrs_import_browser_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class OtrsImportBrowserTest < TestCase diff --git a/test/integration/otrs_import_test.rb b/test/integration/otrs_import_test.rb index 87010e203..56c23acdf 100644 --- a/test/integration/otrs_import_test.rb +++ b/test/integration/otrs_import_test.rb @@ -1,4 +1,3 @@ - require 'integration_test_helper' class OtrsImportTest < ActiveSupport::TestCase diff --git a/test/integration/package_test.rb b/test/integration/package_test.rb index 8dfd53361..292f37395 100644 --- a/test/integration/package_test.rb +++ b/test/integration/package_test.rb @@ -1,4 +1,3 @@ - require 'integration_test_helper' class PackageTest < ActiveSupport::TestCase @@ -312,9 +311,9 @@ class PackageTest < ActiveSupport::TestCase if test[:result] assert(package, 'install package not successful') issues = package.verify - assert(!issues, 'package verify not successful') + assert_not(issues, 'package verify not successful') else - assert(!package, 'install package successful but should not') + assert_not(package, 'install package successful but should not') end elsif test[:action] == 'reinstall' begin @@ -325,9 +324,9 @@ class PackageTest < ActiveSupport::TestCase if test[:result] assert(package, 'reinstall package not successful') issues = package.verify - assert(!issues, 'package verify not successful') + assert_not(issues, 'package verify not successful') else - assert(!package, 'reinstall package successful but should not') + assert_not(package, 'reinstall package successful but should not') end elsif test[:action] == 'uninstall' if test[:zpm] @@ -346,7 +345,7 @@ class PackageTest < ActiveSupport::TestCase if test[:result] assert(package, 'uninstall package not successful') else - assert(!package, 'uninstall package successful but should not') + assert_not(package, 'uninstall package successful but should not') end elsif test[:action] == 'auto_install' if test[:zpm] @@ -379,7 +378,7 @@ class PackageTest < ActiveSupport::TestCase if item[:result] assert(exists, "'#{item[:location]}' exists" ) else - assert(!exists, "'#{item[:location]}' doesn't exists" ) + assert_not(exists, "'#{item[:location]}' doesn't exists" ) end end end diff --git a/test/integration/slack_test.rb b/test/integration/slack_test.rb index b57d77367..765a9dad1 100644 --- a/test/integration/slack_test.rb +++ b/test/integration/slack_test.rb @@ -1,4 +1,3 @@ - require 'integration_test_helper' require 'slack' @@ -284,6 +283,7 @@ class SlackTest < ActiveSupport::TestCase channel_id = nil channels.each do |channel| next if channel['name'] != channel_name + channel_id = channel['id'] end if !channel_id @@ -297,9 +297,11 @@ class SlackTest < ActiveSupport::TestCase if !channel_history['messages'] raise "ERROR: No history messages for channel #{channel_name}/#{channel_id}" end + message_count = 0 channel_history['messages'].each do |message| next if !message['text'] + if message['text'].match?(/#{search_for}/i) message_count += 1 p "SUCCESS: message with #{search_for} found #{message_count} time(s)!" diff --git a/test/integration/telegram_controller_test.rb b/test/integration/telegram_controller_test.rb index e9a86cf5e..10c4ab7cc 100644 --- a/test/integration/telegram_controller_test.rb +++ b/test/integration/telegram_controller_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' require 'rexml/document' require 'webmock/minitest' diff --git a/test/integration/twitter_browser_test.rb b/test/integration/twitter_browser_test.rb index 52c2a27a0..45c55885f 100644 --- a/test/integration/twitter_browser_test.rb +++ b/test/integration/twitter_browser_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class TwitterBrowserTest < TestCase @@ -369,30 +368,36 @@ class TwitterBrowserTest < TestCase if !ENV['TWITTER_BT_CONSUMER_KEY'] raise "ERROR: Need TWITTER_BT_CONSUMER_KEY - hint TWITTER_BT_CONSUMER_KEY='1234'" end + consumer_key = ENV['TWITTER_BT_CONSUMER_KEY'] if !ENV['TWITTER_BT_CONSUMER_SECRET'] raise "ERROR: Need TWITTER_BT_CONSUMER_SECRET - hint TWITTER_BT_CONSUMER_SECRET='1234'" end + consumer_secret = ENV['TWITTER_BT_CONSUMER_SECRET'] if !ENV['TWITTER_BT_USER_LOGIN'] raise "ERROR: Need TWITTER_BT_USER_LOGIN - hint TWITTER_BT_USER_LOGIN='1234'" end + twitter_user_login = ENV['TWITTER_BT_USER_LOGIN'] if !ENV['TWITTER_BT_USER_PW'] raise "ERROR: Need TWITTER_BT_USER_PW - hint TWITTER_BT_USER_PW='1234'" end + twitter_user_pw = ENV['TWITTER_BT_USER_PW'] if !ENV['TWITTER_BT_CUSTOMER_TOKEN'] raise "ERROR: Need TWITTER_BT_CUSTOMER_TOKEN - hint TWITTER_BT_CUSTOMER_TOKEN='1234'" end + twitter_customer_token = ENV['TWITTER_BT_CUSTOMER_TOKEN'] if !ENV['TWITTER_BT_CUSTOMER_TOKEN_SECRET'] raise "ERROR: Need TWITTER_BT_CUSTOMER_TOKEN_SECRET - hint TWITTER_BT_CUSTOMER_TOKEN_SECRET='1234'" end + twitter_customer_token_secret = ENV['TWITTER_BT_CUSTOMER_TOKEN_SECRET'] hash = { diff --git a/test/integration/twitter_test.rb b/test/integration/twitter_test.rb index be52789f8..542cd42bb 100644 --- a/test/integration/twitter_test.rb +++ b/test/integration/twitter_test.rb @@ -1,4 +1,3 @@ - require 'integration_test_helper' class TwitterTest < ActiveSupport::TestCase @@ -28,6 +27,7 @@ class TwitterTest < ActiveSupport::TestCase 'TWITTER_CUSTOMER_TOKEN_SECRET' => '1234', }.each do |key, example_value| next if ENV[key] + raise "ERROR: Need ENV #{key} - hint: export #{key}='#{example_value}'" end @@ -142,6 +142,7 @@ class TwitterTest < ActiveSupport::TestCase tweet_found = false client.user_timeline(system_login_without_at).each do |tweet| next if tweet.id.to_s != article.message_id.to_s + tweet_found = true break end @@ -164,6 +165,7 @@ class TwitterTest < ActiveSupport::TestCase # check if follow up article has been created article = Ticket::Article.find_by(message_id: tweet.id) break if article + sleep 10 end @@ -208,6 +210,7 @@ class TwitterTest < ActiveSupport::TestCase # check if ticket and article has been created article = Ticket::Article.find_by(message_id: tweet.id) break if article + sleep 20 end assert(article, "Can't find tweet id #{tweet.id}/#{text}") @@ -240,6 +243,7 @@ class TwitterTest < ActiveSupport::TestCase client.user_timeline(system_login_without_at).each do |local_tweet| sleep 10 next if local_tweet.id.to_s != article.message_id.to_s + tweet_found = true break end @@ -278,6 +282,7 @@ class TwitterTest < ActiveSupport::TestCase # check if ticket and article has been created article = Ticket::Article.find_by(message_id: tweet.id) break if article + sleep 20 end @@ -325,6 +330,7 @@ class TwitterTest < ActiveSupport::TestCase # check if ticket and article has been created article = Ticket::Article.find_by(message_id: dm.id) break if article + sleep 10 end @@ -375,6 +381,7 @@ class TwitterTest < ActiveSupport::TestCase # check if ticket and article has been created article = Ticket::Article.find_by(message_id: dm.id) break if article + sleep 10 end @@ -408,6 +415,7 @@ class TwitterTest < ActiveSupport::TestCase # check if ticket and article has been created article = Ticket::Article.find_by(message_id: dm.id) break if article + sleep 15 end @@ -467,6 +475,7 @@ class TwitterTest < ActiveSupport::TestCase # check if ticket and article has been created article = Ticket::Article.find_by(message_id: dm.id) break if article + sleep 10 end @@ -531,6 +540,7 @@ class TwitterTest < ActiveSupport::TestCase # check if ticket and article has been created article = Ticket::Article.find_by(message_id: retweet.id) break if article + sleep 10 end @@ -572,6 +582,7 @@ class TwitterTest < ActiveSupport::TestCase # check if ticket and article has been created article = Ticket::Article.find_by(message_id: retweet.id) break if article + sleep 10 end @@ -603,6 +614,7 @@ class TwitterTest < ActiveSupport::TestCase Scheduler.worker(true) article = Ticket::Article.find_by(message_id: tweet.id) break if article + ActiveRecord::Base.clear_all_connections! ActiveRecord::Base.connection.query_cache.clear sleep 10 @@ -630,6 +642,7 @@ class TwitterTest < ActiveSupport::TestCase Scheduler.worker(true) article = Ticket::Article.find_by(message_id: tweet.id) break if article + ActiveRecord::Base.clear_all_connections! ActiveRecord::Base.connection.query_cache.clear sleep 10 @@ -662,6 +675,7 @@ class TwitterTest < ActiveSupport::TestCase client.user_timeline(system_login_without_at).each do |local_tweet| sleep 10 next if local_tweet.id.to_s != article.message_id.to_s + tweet_found = true break end @@ -696,6 +710,7 @@ class TwitterTest < ActiveSupport::TestCase Scheduler.worker(true) article = Ticket::Article.find_by(message_id: dm.id) break if article + sleep 10 end assert(article, "inbound article '#{text}' message_id '#{dm.id}' created") @@ -747,6 +762,7 @@ class TwitterTest < ActiveSupport::TestCase # check if ticket and article has been created article = Ticket::Article.find_by(message_id: retweet.id) break if article + ActiveRecord::Base.clear_all_connections! ActiveRecord::Base.connection.query_cache.clear sleep 10 @@ -797,6 +813,7 @@ class TwitterTest < ActiveSupport::TestCase # check if ticket and article has been created article = Ticket::Article.find_by(message_id: retweet.id) break if article + sleep 10 end @@ -842,6 +859,7 @@ class TwitterTest < ActiveSupport::TestCase Scheduler.worker(true) article = Ticket::Article.find_by(message_id: tweet.id) break if article + ActiveRecord::Base.clear_all_connections! ActiveRecord::Base.connection.query_cache.clear sleep 10 diff --git a/test/integration/user_agent_test.rb b/test/integration/user_agent_test.rb index eb99fb5f9..3c23d7c95 100644 --- a/test/integration/user_agent_test.rb +++ b/test/integration/user_agent_test.rb @@ -1,4 +1,3 @@ - require 'integration_test_helper' class UserAgentTest < ActiveSupport::TestCase @@ -493,7 +492,7 @@ class UserAgentTest < ActiveSupport::TestCase assert_equal(false, result.success?) assert_equal('404', result.code) assert_equal(NilClass, result.body.class) - assert(!result.data) + assert_not(result.data) # post / 200 result = UserAgent.post( diff --git a/test/integration/user_device_controller_test.rb b/test/integration/user_device_controller_test.rb index 28bf37394..790ceb08b 100644 --- a/test/integration/user_device_controller_test.rb +++ b/test/integration/user_device_controller_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class UserDeviceControllerTest < ActionDispatch::IntegrationTest diff --git a/test/integration/zendesk_import_browser_test.rb b/test/integration/zendesk_import_browser_test.rb index da26c7f6d..51293395c 100644 --- a/test/integration/zendesk_import_browser_test.rb +++ b/test/integration/zendesk_import_browser_test.rb @@ -1,4 +1,3 @@ - require 'browser_test_helper' class ZendeskImportBrowserTest < TestCase diff --git a/test/integration/zendesk_import_test.rb b/test/integration/zendesk_import_test.rb index b199b380e..63036bfc0 100644 --- a/test/integration/zendesk_import_test.rb +++ b/test/integration/zendesk_import_test.rb @@ -1,4 +1,3 @@ - require 'integration_test_helper' class ZendeskImportTest < ActiveSupport::TestCase diff --git a/test/support/searchindex_helper.rb b/test/support/searchindex_helper.rb index b6874beeb..89d1a3e7e 100644 --- a/test/support/searchindex_helper.rb +++ b/test/support/searchindex_helper.rb @@ -14,6 +14,7 @@ module SearchindexHelper def configure_elasticsearch(required: false) if ENV['ES_URL'].blank? return if !required + raise "ERROR: Need ES_URL - hint ES_URL='http://127.0.0.1:9200'" end @@ -32,6 +33,7 @@ module SearchindexHelper if ENV['ES_INDEX'].blank? raise "ERROR: Need ES_INDEX - hint ES_INDEX='estest.local_zammad'" end + Setting.set('es_index', ENV['ES_INDEX']) # set max attachment size in mb diff --git a/test/test_helper.rb b/test/test_helper.rb index e4d723fa1..b5031eea5 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -25,6 +25,7 @@ class ActiveSupport::TestCase # exit all threads Thread.list.each do |thread| next if thread == Thread.current + thread.exit thread.join end @@ -63,10 +64,11 @@ class ActiveSupport::TestCase lines.push line end count = 0 - lines.reverse.each do |line| + lines.reverse_each do |line| break if line.match?(/\+\+\+\+NEW\+\+\+\+TEST\+\+\+\+/) next if line !~ /Send notification \(#{type}\)/ next if line !~ /to:\s#{recipient}/ + count += 1 end count @@ -81,10 +83,11 @@ class ActiveSupport::TestCase lines.push line end count = 0 - lines.reverse.each do |line| + lines.reverse_each do |line| break if line.match?(/\+\+\+\+NEW\+\+\+\+TEST\+\+\+\+/) next if line !~ /Send email to:/ next if line !~ /to:\s'#{recipient}'/ + count += 1 end count diff --git a/test/unit/activity_stream_test.rb b/test/unit/activity_stream_test.rb index f7a6f71de..fde8f857d 100644 --- a/test/unit/activity_stream_test.rb +++ b/test/unit/activity_stream_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class ActivityStreamTest < ActiveSupport::TestCase diff --git a/test/unit/auth_test.rb b/test/unit/auth_test.rb index 151782666..b5f33a30f 100644 --- a/test/unit/auth_test.rb +++ b/test/unit/auth_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class AuthTest < ActiveSupport::TestCase diff --git a/test/unit/auto_wizard_test.rb b/test/unit/auto_wizard_test.rb index 12b5744aa..00fe67ef7 100644 --- a/test/unit/auto_wizard_test.rb +++ b/test/unit/auto_wizard_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class AutoWizardTest < ActiveSupport::TestCase @@ -56,6 +55,7 @@ class AutoWizardTest < ActiveSupport::TestCase assert_equal(local_user[:email], user.email) assert_equal(local_user[:roles].count, user.role_ids.count) next if !local_user[:roles] + local_user[:roles].each do |local_role_name| local_role = Role.find_by(name: local_role_name) assert(user.role_ids.include?(local_role.id)) @@ -65,6 +65,7 @@ class AutoWizardTest < ActiveSupport::TestCase group = Group.find_by(name: local_group[:name]) assert_equal(local_group[:name], group.name) next if !local_group[:users] + local_group[:users].each do |local_user_login| local_user = User.find_by(login: local_user_login) assert(group.user_ids.include?(local_user.id)) @@ -194,6 +195,7 @@ class AutoWizardTest < ActiveSupport::TestCase assert_equal(local_user[:lastname], user.lastname) assert_equal(local_user[:email], user.email) next if !local_user[:roles] + assert_equal(local_user[:roles].count, user.role_ids.count) local_user[:roles].each do |local_role_name| local_role = Role.find_by(name: local_role_name) @@ -246,6 +248,7 @@ class AutoWizardTest < ActiveSupport::TestCase def auto_wizard_file_exists? location = Rails.root.join('auto_wizard.json') return false if File.exist?(location) + true end diff --git a/test/unit/cache_test.rb b/test/unit/cache_test.rb index 76b8bdc27..d1a0facda 100644 --- a/test/unit/cache_test.rb +++ b/test/unit/cache_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class CacheTest < ActiveSupport::TestCase diff --git a/test/unit/calendar_subscription_test.rb b/test/unit/calendar_subscription_test.rb index f79eadd96..43ed59c99 100644 --- a/test/unit/calendar_subscription_test.rb +++ b/test/unit/calendar_subscription_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class CalendarSubscriptionTest < ActiveSupport::TestCase diff --git a/test/unit/calendar_test.rb b/test/unit/calendar_test.rb index 8405f9435..6d1c29f0b 100644 --- a/test/unit/calendar_test.rb +++ b/test/unit/calendar_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class CalendarTest < ActiveSupport::TestCase diff --git a/test/unit/chat_test.rb b/test/unit/chat_test.rb index 488c56211..5743b7da1 100644 --- a/test/unit/chat_test.rb +++ b/test/unit/chat_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class ChatTest < ActiveSupport::TestCase diff --git a/test/unit/cti_caller_id_test.rb b/test/unit/cti_caller_id_test.rb index 4f0e07ee2..33a1ed926 100644 --- a/test/unit/cti_caller_id_test.rb +++ b/test/unit/cti_caller_id_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class CtiCallerIdTest < ActiveSupport::TestCase diff --git a/test/unit/db_auto_increment_test.rb b/test/unit/db_auto_increment_test.rb index 0f5edcc39..b37740d66 100644 --- a/test/unit/db_auto_increment_test.rb +++ b/test/unit/db_auto_increment_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class DbAutoIncrementTest < ActiveSupport::TestCase diff --git a/test/unit/email_address_test.rb b/test/unit/email_address_test.rb index 4a6ccf588..a50c83b1d 100644 --- a/test/unit/email_address_test.rb +++ b/test/unit/email_address_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class EmailAddressTest < ActiveSupport::TestCase diff --git a/test/unit/email_build_test.rb b/test/unit/email_build_test.rb index 97e30590d..55289bb1d 100644 --- a/test/unit/email_build_test.rb +++ b/test/unit/email_build_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class EmailBuildTest < ActiveSupport::TestCase @@ -41,7 +40,7 @@ class EmailBuildTest < ActiveSupport::TestCase
> Welcome!
>
> Thank you for installing Zammad. äöüß
>
- MSG_HTML + MSG_HTML mail = Channel::EmailBuild.build( from: 'sender@example.com', to: 'recipient@example.com', @@ -61,7 +60,7 @@ class EmailBuildTest < ActiveSupport::TestCase > > Thank you for installing Zammad. äöüß > - MSG_TEXT + MSG_TEXT assert_equal(text_should, mail.text_part.body.to_s) assert_equal(html, mail.html_part.body.to_s) @@ -100,7 +99,7 @@ class EmailBuildTest < ActiveSupport::TestCase > > Thank you for installing Zammad. äöüß > - MSG_TEXT + MSG_TEXT mail = Channel::EmailBuild.build( from: 'sender@example.com', to: 'recipient@example.com', @@ -184,7 +183,7 @@ class EmailBuildTest < ActiveSupport::TestCase > > Thank you for installing Zammad. äöüß > - MSG_TEXT + MSG_TEXT mail = Channel::EmailBuild.build( from: 'sender@example.com', to: 'recipient@example.com', @@ -226,7 +225,7 @@ class EmailBuildTest < ActiveSupport::TestCase > > Thank you for installing Zammad. äöüß > - MSG_TEXT + MSG_TEXT mail = Channel::EmailBuild.build( from: 'sender@example.com', to: 'recipient@example.com', diff --git a/test/unit/email_process_bounce_delivery_temporary_failed_test.rb b/test/unit/email_process_bounce_delivery_temporary_failed_test.rb index 90ffd657f..a4d7c85e2 100644 --- a/test/unit/email_process_bounce_delivery_temporary_failed_test.rb +++ b/test/unit/email_process_bounce_delivery_temporary_failed_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class EmailProcessBounceDeliveryTemporaryFailed < ActiveSupport::TestCase diff --git a/test/unit/email_process_customer_selection_based_on_sender_recipient_test.rb b/test/unit/email_process_customer_selection_based_on_sender_recipient_test.rb index 81fcfa24d..528aec7bb 100644 --- a/test/unit/email_process_customer_selection_based_on_sender_recipient_test.rb +++ b/test/unit/email_process_customer_selection_based_on_sender_recipient_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class EmailProcessCustomerSelectionBasedOnSenderRecipient < ActiveSupport::TestCase diff --git a/test/unit/email_process_follow_up_possible_test.rb b/test/unit/email_process_follow_up_possible_test.rb index 46a81cf8f..e804931b9 100644 --- a/test/unit/email_process_follow_up_possible_test.rb +++ b/test/unit/email_process_follow_up_possible_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class EmailProcessFollowUpPossibleTest < ActiveSupport::TestCase diff --git a/test/unit/email_process_follow_up_test.rb b/test/unit/email_process_follow_up_test.rb index cb73c8381..6fd7b8541 100644 --- a/test/unit/email_process_follow_up_test.rb +++ b/test/unit/email_process_follow_up_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class EmailProcessFollowUpTest < ActiveSupport::TestCase diff --git a/test/unit/email_process_identify_sender_max_test.rb b/test/unit/email_process_identify_sender_max_test.rb index 895623cde..ee7ffe0b0 100644 --- a/test/unit/email_process_identify_sender_max_test.rb +++ b/test/unit/email_process_identify_sender_max_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class EmailProcessIdentifySenderMax < ActiveSupport::TestCase diff --git a/test/unit/email_process_out_of_office_test.rb b/test/unit/email_process_out_of_office_test.rb index 2025a12c1..cce276097 100644 --- a/test/unit/email_process_out_of_office_test.rb +++ b/test/unit/email_process_out_of_office_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class EmailProcessOutOfOfficeTest < ActiveSupport::TestCase diff --git a/test/unit/email_process_reply_to_test.rb b/test/unit/email_process_reply_to_test.rb index 99d72fc1d..6e87dbe61 100644 --- a/test/unit/email_process_reply_to_test.rb +++ b/test/unit/email_process_reply_to_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class EmailProcessReplyToTest < ActiveSupport::TestCase diff --git a/test/unit/email_process_sender_is_system_address_or_agent_test.rb b/test/unit/email_process_sender_is_system_address_or_agent_test.rb index d1e7265c8..2eb3f7e48 100644 --- a/test/unit/email_process_sender_is_system_address_or_agent_test.rb +++ b/test/unit/email_process_sender_is_system_address_or_agent_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class EmailProcessSenderIsSystemAddressOrAgent < ActiveSupport::TestCase diff --git a/test/unit/email_process_sender_name_update_if_needed.rb b/test/unit/email_process_sender_name_update_if_needed.rb index 6c979f315..df35dad6f 100644 --- a/test/unit/email_process_sender_name_update_if_needed.rb +++ b/test/unit/email_process_sender_name_update_if_needed.rb @@ -1,4 +1,3 @@ - require 'test_helper' class EmailProcessSenderNameUpdateIfNeeded < ActiveSupport::TestCase diff --git a/test/unit/email_process_state_open_set.rb b/test/unit/email_process_state_open_set.rb index 0347e14ca..732a1472b 100644 --- a/test/unit/email_process_state_open_set.rb +++ b/test/unit/email_process_state_open_set.rb @@ -1,4 +1,3 @@ - require 'test_helper' class EmailProcessStateOpenSet < ActiveSupport::TestCase diff --git a/test/unit/email_regex_test.rb b/test/unit/email_regex_test.rb index 88832ef76..0389d06e8 100644 --- a/test/unit/email_regex_test.rb +++ b/test/unit/email_regex_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class EmailRegexTest < ActiveSupport::TestCase diff --git a/test/unit/email_signature_detection_test.rb b/test/unit/email_signature_detection_test.rb index 022fc404b..4a5429274 100644 --- a/test/unit/email_signature_detection_test.rb +++ b/test/unit/email_signature_detection_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class EmailSignatureDetectionTest < ActiveSupport::TestCase diff --git a/test/unit/history_test.rb b/test/unit/history_test.rb index 9c58aa4e9..893a2c93f 100644 --- a/test/unit/history_test.rb +++ b/test/unit/history_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class HistoryTest < ActiveSupport::TestCase @@ -345,6 +344,7 @@ class HistoryTest < ActiveSupport::TestCase next if match next if history_item['object'] != check_item[:history_object] next if history_item['type'] != check_item[:history_type] + if check_item[:history_attribute] next if check_item[:history_attribute] != history_item['attribute'] end diff --git a/test/unit/html_sanitizer_test.rb b/test/unit/html_sanitizer_test.rb index 03b040da2..eaf757965 100644 --- a/test/unit/html_sanitizer_test.rb +++ b/test/unit/html_sanitizer_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class HtmlSanitizerTest < ActiveSupport::TestCase diff --git a/test/unit/integration_icinga_test.rb b/test/unit/integration_icinga_test.rb index 0743c8aa6..a18ec2772 100644 --- a/test/unit/integration_icinga_test.rb +++ b/test/unit/integration_icinga_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class IntegrationIcingaTest < ActiveSupport::TestCase diff --git a/test/unit/integration_monit_test.rb b/test/unit/integration_monit_test.rb index a481cc77d..ffcae433c 100644 --- a/test/unit/integration_monit_test.rb +++ b/test/unit/integration_monit_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class IntegrationMonitTest < ActiveSupport::TestCase diff --git a/test/unit/integration_nagios_test.rb b/test/unit/integration_nagios_test.rb index 9248be00e..f086e7029 100644 --- a/test/unit/integration_nagios_test.rb +++ b/test/unit/integration_nagios_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class IntegrationNagiosTest < ActiveSupport::TestCase diff --git a/test/unit/job_assets_test.rb b/test/unit/job_assets_test.rb index aff315032..3dcbe339b 100644 --- a/test/unit/job_assets_test.rb +++ b/test/unit/job_assets_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class JobAssetsTest < ActiveSupport::TestCase diff --git a/test/unit/job_test.rb b/test/unit/job_test.rb index 1d2470d7b..9042c27cb 100644 --- a/test/unit/job_test.rb +++ b/test/unit/job_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class JobTest < ActiveSupport::TestCase diff --git a/test/unit/karma_test.rb b/test/unit/karma_test.rb index b2659a206..eb50cde3d 100644 --- a/test/unit/karma_test.rb +++ b/test/unit/karma_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class KarmaTest < ActiveSupport::TestCase diff --git a/test/unit/migration_ror_42_to50_store_test.rb b/test/unit/migration_ror_42_to50_store_test.rb index 09e1c273b..449c383db 100644 --- a/test/unit/migration_ror_42_to50_store_test.rb +++ b/test/unit/migration_ror_42_to50_store_test.rb @@ -1,4 +1,3 @@ - # Rails 5.0 has changed to only store and read ActiveSupport::HashWithIndifferentAccess from stores # we extended lib/core_ext/active_record/store/indifferent_coder.rb to read also ActionController::Parameters # and convert them to ActiveSupport::HashWithIndifferentAccess for migration in db/migrate/20170910000001_fixed_store_upgrade_45.rb. diff --git a/test/unit/model_test.rb b/test/unit/model_test.rb index 6090e1a7d..3169316ff 100644 --- a/test/unit/model_test.rb +++ b/test/unit/model_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class ModelTest < ActiveSupport::TestCase @@ -154,7 +153,7 @@ class ModelTest < ActiveSupport::TestCase assert_equal(references1['User']['created_by_id'], 1) assert_equal(references1['Organization']['updated_by_id'], 1) assert_equal(references1['UserGroup']['user_id'], 1) - assert(!references1['Group']) + assert_not(references1['Group']) references_total1 = Models.references_total('User', agent1.id) assert_equal(references_total1, 8) @@ -162,9 +161,9 @@ class ModelTest < ActiveSupport::TestCase # verify agent2 references2 = Models.references('User', agent2.id) - assert(!references2['User']) - assert(!references2['Organization']) - assert(!references2['Group']) + assert_not(references2['User']) + assert_not(references2['Organization']) + assert_not(references2['Group']) assert_equal(references2['UserGroup']['user_id'], 1) references_total2 = Models.references_total('User', agent2.id) @@ -175,10 +174,10 @@ class ModelTest < ActiveSupport::TestCase # verify agent1 references1 = Models.references('User', agent1.id) - assert(!references1['User']) - assert(!references1['Organization']) - assert(!references1['Group']) - assert(!references1['UserGroup']) + assert_not(references1['User']) + assert_not(references1['Organization']) + assert_not(references1['Group']) + assert_not(references1['UserGroup']) assert(references1.blank?) references_total1 = Models.references_total('User', agent1.id) @@ -191,7 +190,7 @@ class ModelTest < ActiveSupport::TestCase assert_equal(references2['User']['created_by_id'], 1) assert_equal(references2['Organization']['updated_by_id'], 1) assert_equal(references2['UserGroup']['user_id'], 2) - assert(!references2['Group']) + assert_not(references2['Group']) references_total2 = Models.references_total('User', agent2.id) assert_equal(references_total2, 9) @@ -202,8 +201,8 @@ class ModelTest < ActiveSupport::TestCase references1 = Models.references('Organization', organization1.id) assert_equal(references1['User']['organization_id'], 1) - assert(!references1['Organization']) - assert(!references1['Group']) + assert_not(references1['Organization']) + assert_not(references1['Group']) references_total1 = Models.references_total('Organization', organization1.id) assert_equal(references_total1, 1) @@ -230,8 +229,8 @@ class ModelTest < ActiveSupport::TestCase references2 = Models.references('Organization', organization2.id) assert_equal(references2['User']['organization_id'], 1) - assert(!references2['Organization']) - assert(!references2['Group']) + assert_not(references2['Organization']) + assert_not(references2['Group']) references_total2 = Models.references_total('Organization', organization2.id) assert_equal(references_total2, 1) diff --git a/test/unit/notification_factory_mailer_template_test.rb b/test/unit/notification_factory_mailer_template_test.rb index 558201013..ed0010914 100644 --- a/test/unit/notification_factory_mailer_template_test.rb +++ b/test/unit/notification_factory_mailer_template_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class NotificationFactoryMailerTemplateTest < ActiveSupport::TestCase diff --git a/test/unit/notification_factory_mailer_test.rb b/test/unit/notification_factory_mailer_test.rb index 770911693..6a37ac897 100644 --- a/test/unit/notification_factory_mailer_test.rb +++ b/test/unit/notification_factory_mailer_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class NotificationFactoryMailerTest < ActiveSupport::TestCase diff --git a/test/unit/notification_factory_slack_template_test.rb b/test/unit/notification_factory_slack_template_test.rb index 319198492..58069fe04 100644 --- a/test/unit/notification_factory_slack_template_test.rb +++ b/test/unit/notification_factory_slack_template_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class NotificationFactorySlackTemplateTest < ActiveSupport::TestCase diff --git a/test/unit/object_cache_test.rb b/test/unit/object_cache_test.rb index 086210c9a..8e08dd4d1 100644 --- a/test/unit/object_cache_test.rb +++ b/test/unit/object_cache_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class ObjectCacheTest < ActiveSupport::TestCase diff --git a/test/unit/object_create_update_with_ref_name_test.rb b/test/unit/object_create_update_with_ref_name_test.rb index db2b02d04..d3b8dee7b 100644 --- a/test/unit/object_create_update_with_ref_name_test.rb +++ b/test/unit/object_create_update_with_ref_name_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class ObjectCreateUpdateWithRefNameTest < ActiveSupport::TestCase diff --git a/test/unit/object_type_lookup_test.rb b/test/unit/object_type_lookup_test.rb index f37a9c24a..18f7bd5eb 100644 --- a/test/unit/object_type_lookup_test.rb +++ b/test/unit/object_type_lookup_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class ObjectTypeLookupTest < ActiveSupport::TestCase diff --git a/test/unit/online_notifiaction_test.rb b/test/unit/online_notifiaction_test.rb index d7746236b..3bac011f1 100644 --- a/test/unit/online_notifiaction_test.rb +++ b/test/unit/online_notifiaction_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class OnlineNotificationTest < ActiveSupport::TestCase @@ -124,9 +123,9 @@ class OnlineNotificationTest < ActiveSupport::TestCase # because it's already closed assert(OnlineNotification.all_seen?('Ticket', ticket1.id)) - assert(!OnlineNotification.exists?(@agent_user1, 'Ticket', ticket1.id, 'create', @agent_user1, false)) - assert(!OnlineNotification.exists?(@agent_user1, 'Ticket', ticket1.id, 'create', @agent_user1, true)) - assert(!OnlineNotification.exists?(@agent_user2, 'Ticket', ticket1.id, 'create', @agent_user1, false)) + assert_not(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket1.id, 'create', @agent_user1, false)) + assert_not(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket1.id, 'create', @agent_user1, true)) + assert_not(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket1.id, 'create', @agent_user1, false)) assert(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket1.id, 'create', @agent_user1, true)) ticket1.update!( @@ -141,10 +140,10 @@ class OnlineNotificationTest < ActiveSupport::TestCase Scheduler.worker(true) # because it's already open - assert(!OnlineNotification.all_seen?('Ticket', ticket1.id)) - assert(!OnlineNotification.exists?(@agent_user1, 'Ticket', ticket1.id, 'update', @customer_user, true)) + assert_not(OnlineNotification.all_seen?('Ticket', ticket1.id)) + assert_not(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket1.id, 'update', @customer_user, true)) assert(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket1.id, 'update', @customer_user, false)) - assert(!OnlineNotification.exists?(@agent_user2, 'Ticket', ticket1.id, 'update', @customer_user, true)) + assert_not(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket1.id, 'update', @customer_user, true)) assert(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket1.id, 'update', @customer_user, false)) # case #2 @@ -178,11 +177,11 @@ class OnlineNotificationTest < ActiveSupport::TestCase Scheduler.worker(true) # because it's already closed - assert(!OnlineNotification.all_seen?('Ticket', ticket2.id)) + assert_not(OnlineNotification.all_seen?('Ticket', ticket2.id)) assert(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket2.id, 'create', @customer_user, false)) - assert(!OnlineNotification.exists?(@agent_user1, 'Ticket', ticket2.id, 'create', @customer_user, true)) - assert(!OnlineNotification.exists?(@agent_user2, 'Ticket', ticket2.id, 'create', @customer_user, false)) - assert(!OnlineNotification.exists?(@agent_user2, 'Ticket', ticket2.id, 'create', @customer_user, true)) + assert_not(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket2.id, 'create', @customer_user, true)) + assert_not(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket2.id, 'create', @customer_user, false)) + assert_not(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket2.id, 'create', @customer_user, true)) ticket2.update!( title: 'Unit Test 1 (äöüß) - update!', @@ -196,11 +195,11 @@ class OnlineNotificationTest < ActiveSupport::TestCase Scheduler.worker(true) # because it's already open - assert(!OnlineNotification.all_seen?('Ticket', ticket2.id)) + assert_not(OnlineNotification.all_seen?('Ticket', ticket2.id)) assert(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket2.id, 'update', @customer_user, false)) - assert(!OnlineNotification.exists?(@agent_user1, 'Ticket', ticket2.id, 'update', @customer_user, true)) - assert(!OnlineNotification.exists?(@agent_user2, 'Ticket', ticket2.id, 'update', @customer_user, true)) - assert(!OnlineNotification.exists?(@agent_user2, 'Ticket', ticket2.id, 'update', @customer_user, false)) + assert_not(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket2.id, 'update', @customer_user, true)) + assert_not(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket2.id, 'update', @customer_user, true)) + assert_not(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket2.id, 'update', @customer_user, false)) # case #3 ticket3 = Ticket.create( @@ -232,11 +231,11 @@ class OnlineNotificationTest < ActiveSupport::TestCase Scheduler.worker(true) # because it's already new - assert(!OnlineNotification.all_seen?('Ticket', ticket3.id)) - assert(!OnlineNotification.exists?(@agent_user1, 'Ticket', ticket3.id, 'create', @agent_user1, false)) - assert(!OnlineNotification.exists?(@agent_user1, 'Ticket', ticket3.id, 'create', @agent_user1, true)) + assert_not(OnlineNotification.all_seen?('Ticket', ticket3.id)) + assert_not(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket3.id, 'create', @agent_user1, false)) + assert_not(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket3.id, 'create', @agent_user1, true)) assert(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket3.id, 'create', @agent_user1, false)) - assert(!OnlineNotification.exists?(@agent_user2, 'Ticket', ticket3.id, 'create', @agent_user1, true)) + assert_not(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket3.id, 'create', @agent_user1, true)) ticket3.update!( title: 'Unit Test 2 (äöüß) - update!', @@ -253,9 +252,9 @@ class OnlineNotificationTest < ActiveSupport::TestCase assert(OnlineNotification.all_seen?('Ticket', ticket3.id)) assert_equal(1, NotificationFactory::Mailer.already_sent?(ticket3, @agent_user1, 'update')) assert_equal(1, NotificationFactory::Mailer.already_sent?(ticket3, @agent_user2, 'update')) - assert(!OnlineNotification.exists?(@agent_user1, 'Ticket', ticket3.id, 'update', @customer_user, false)) + assert_not(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket3.id, 'update', @customer_user, false)) assert(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket3.id, 'update', @customer_user, true)) - assert(!OnlineNotification.exists?(@agent_user2, 'Ticket', ticket3.id, 'update', @customer_user, false)) + assert_not(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket3.id, 'update', @customer_user, false)) assert(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket3.id, 'update', @customer_user, true)) article3 = Ticket::Article.create( @@ -274,7 +273,7 @@ class OnlineNotificationTest < ActiveSupport::TestCase Scheduler.worker(true) # because it's already closed but an follow up arrived later - assert(!OnlineNotification.all_seen?('Ticket', ticket3.id)) + assert_not(OnlineNotification.all_seen?('Ticket', ticket3.id)) assert(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket3.id, 'update', @customer_user, false)) assert(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket3.id, 'update', @customer_user, true)) assert(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket3.id, 'update', @customer_user, false)) @@ -312,11 +311,11 @@ class OnlineNotificationTest < ActiveSupport::TestCase Scheduler.worker(true) # because it's already new - assert(!OnlineNotification.all_seen?('Ticket', ticket4.id)) + assert_not(OnlineNotification.all_seen?('Ticket', ticket4.id)) assert(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket4.id, 'create', @customer_user, false)) - assert(!OnlineNotification.exists?(@agent_user1, 'Ticket', ticket4.id, 'create', @customer_user, true)) - assert(!OnlineNotification.exists?(@agent_user2, 'Ticket', ticket4.id, 'create', @customer_user, false)) - assert(!OnlineNotification.exists?(@agent_user2, 'Ticket', ticket4.id, 'create', @customer_user, true)) + assert_not(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket4.id, 'create', @customer_user, true)) + assert_not(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket4.id, 'create', @customer_user, false)) + assert_not(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket4.id, 'create', @customer_user, true)) ticket4.update!( title: 'Unit Test 3 (äöüß) - update!', @@ -330,11 +329,11 @@ class OnlineNotificationTest < ActiveSupport::TestCase Scheduler.worker(true) # because it's already open - assert(!OnlineNotification.all_seen?('Ticket', ticket4.id)) + assert_not(OnlineNotification.all_seen?('Ticket', ticket4.id)) assert(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket4.id, 'update', @customer_user, false)) - assert(!OnlineNotification.exists?(@agent_user1, 'Ticket', ticket4.id, 'update', @customer_user, true)) - assert(!OnlineNotification.exists?(@agent_user2, 'Ticket', ticket4.id, 'update', @customer_user, false)) - assert(!OnlineNotification.exists?(@agent_user2, 'Ticket', ticket4.id, 'update', @customer_user, true)) + assert_not(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket4.id, 'update', @customer_user, true)) + assert_not(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket4.id, 'update', @customer_user, false)) + assert_not(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket4.id, 'update', @customer_user, true)) # case #5 ticket5 = Ticket.create( @@ -366,11 +365,11 @@ class OnlineNotificationTest < ActiveSupport::TestCase Scheduler.worker(true) # because it's already new - assert(!OnlineNotification.all_seen?('Ticket', ticket5.id)) - assert(!OnlineNotification.exists?(@agent_user1, 'Ticket', ticket5.id, 'create', @agent_user1, true)) - assert(!OnlineNotification.exists?(@agent_user1, 'Ticket', ticket5.id, 'create', @agent_user1, false)) + assert_not(OnlineNotification.all_seen?('Ticket', ticket5.id)) + assert_not(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket5.id, 'create', @agent_user1, true)) + assert_not(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket5.id, 'create', @agent_user1, false)) assert(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket5.id, 'create', @agent_user1, false)) - assert(!OnlineNotification.exists?(@agent_user2, 'Ticket', ticket5.id, 'create', @agent_user1, true)) + assert_not(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket5.id, 'create', @agent_user1, true)) ticket5.update!( title: 'Unit Test 4 (äöüß) - update!', @@ -384,11 +383,11 @@ class OnlineNotificationTest < ActiveSupport::TestCase Scheduler.worker(true) # because it's already open - assert(!OnlineNotification.all_seen?('Ticket', ticket5.id)) + assert_not(OnlineNotification.all_seen?('Ticket', ticket5.id)) assert(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket5.id, 'update', @customer_user, false)) - assert(!OnlineNotification.exists?(@agent_user1, 'Ticket', ticket5.id, 'update', @customer_user, true)) + assert_not(OnlineNotification.exists?(@agent_user1, 'Ticket', ticket5.id, 'update', @customer_user, true)) assert(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket5.id, 'update', @customer_user, false)) - assert(!OnlineNotification.exists?(@agent_user2, 'Ticket', ticket5.id, 'update', @customer_user, true)) + assert_not(OnlineNotification.exists?(@agent_user2, 'Ticket', ticket5.id, 'update', @customer_user, true)) # merge tickets - also remove notifications of merged tickets tickets[0].merge_to( @@ -403,14 +402,14 @@ class OnlineNotificationTest < ActiveSupport::TestCase notifications = OnlineNotification.list_by_object('Ticket', tickets[1].id) assert(notifications.present?, 'should have notifications') - assert(!OnlineNotification.all_seen?('Ticket', tickets[1].id), 'no notifications for master ticket available') + assert_not(OnlineNotification.all_seen?('Ticket', tickets[1].id), 'no notifications for master ticket available') # delete tickets tickets.each do |ticket| ticket_id = ticket.id ticket.destroy found = Ticket.find_by(id: ticket_id) - assert(!found, 'Ticket destroyed') + assert_not(found, 'Ticket destroyed') # check if notifications for ticket still exist Scheduler.worker(true) @@ -619,11 +618,11 @@ class OnlineNotificationTest < ActiveSupport::TestCase OnlineNotification.cleanup - assert(!OnlineNotification.find_by(id: online_notification1.id)) - assert(!OnlineNotification.find_by(id: online_notification2.id)) + assert_not(OnlineNotification.find_by(id: online_notification1.id)) + assert_not(OnlineNotification.find_by(id: online_notification2.id)) assert(OnlineNotification.find_by(id: online_notification3.id)) - assert(!OnlineNotification.find_by(id: online_notification4.id)) - assert(!OnlineNotification.find_by(id: online_notification5.id)) + assert_not(OnlineNotification.find_by(id: online_notification4.id)) + assert_not(OnlineNotification.find_by(id: online_notification5.id)) assert(OnlineNotification.find_by(id: online_notification6.id)) assert(OnlineNotification.find_by(id: online_notification7.id)) OnlineNotification.destroy_all diff --git a/test/unit/organization_assets_test.rb b/test/unit/organization_assets_test.rb index 42081cffe..f19cb2678 100644 --- a/test/unit/organization_assets_test.rb +++ b/test/unit/organization_assets_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class OrganizationAssetsTest < ActiveSupport::TestCase @@ -109,7 +108,7 @@ class OrganizationAssetsTest < ActiveSupport::TestCase org_new = Organization.find(org.id) attributes = org_new.attributes_with_association_ids attributes.delete('user_ids') - assert( !diff(attributes, assets[:Organization][org_new.id]), 'check assets' ) + assert_not(diff(attributes, assets[:Organization][org_new.id]), 'check assets' ) attributes = user_new_2.attributes_with_association_ids attributes['accounts'] = {} @@ -141,6 +140,7 @@ class OrganizationAssetsTest < ActiveSupport::TestCase def diff(object1, object2) return true if object1 == object2 + %w[updated_at created_at].each do |item| if object1[item] object1[item] = object1[item].to_s @@ -150,6 +150,7 @@ class OrganizationAssetsTest < ActiveSupport::TestCase end end return true if (object1.to_a - object2.to_a).blank? + #puts "ERROR: difference \n1: #{object1.inspect}\n2: #{object2.inspect}\ndiff: #{(object1.to_a - object2.to_a).inspect}" false end diff --git a/test/unit/organization_csv_import_test.rb b/test/unit/organization_csv_import_test.rb index 07c14537c..20bf508b5 100644 --- a/test/unit/organization_csv_import_test.rb +++ b/test/unit/organization_csv_import_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class OrganizationCsvImportTest < ActiveSupport::TestCase diff --git a/test/unit/organization_domain_based_assignment_test.rb b/test/unit/organization_domain_based_assignment_test.rb index 4b2e04523..11d206a91 100644 --- a/test/unit/organization_domain_based_assignment_test.rb +++ b/test/unit/organization_domain_based_assignment_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class OrganizationDomainBasedAssignmentTest < ActiveSupport::TestCase diff --git a/test/unit/organization_ref_object_touch_test.rb b/test/unit/organization_ref_object_touch_test.rb index f327bee06..59e818a7c 100644 --- a/test/unit/organization_ref_object_touch_test.rb +++ b/test/unit/organization_ref_object_touch_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class OrganizationRefObjectTouchTest < ActiveSupport::TestCase diff --git a/test/unit/overview_assets_test.rb b/test/unit/overview_assets_test.rb index 5c25cc428..3c664cb1b 100644 --- a/test/unit/overview_assets_test.rb +++ b/test/unit/overview_assets_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class OverviewAssetsTest < ActiveSupport::TestCase diff --git a/test/unit/permission_test.rb b/test/unit/permission_test.rb index b8ccc0268..c17554327 100644 --- a/test/unit/permission_test.rb +++ b/test/unit/permission_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class PermissionTest < ActiveSupport::TestCase diff --git a/test/unit/role_test.rb b/test/unit/role_test.rb index 72dac85ab..7d8554b6f 100644 --- a/test/unit/role_test.rb +++ b/test/unit/role_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class RoleTest < ActiveSupport::TestCase diff --git a/test/unit/role_validate_agent_limit_test.rb b/test/unit/role_validate_agent_limit_test.rb index 11bdceab6..f74aedc99 100644 --- a/test/unit/role_validate_agent_limit_test.rb +++ b/test/unit/role_validate_agent_limit_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class RoleValidateAgentLimit < ActiveSupport::TestCase diff --git a/test/unit/search_index_backend_test.rb b/test/unit/search_index_backend_test.rb index 3a6681a80..f1eb8648b 100644 --- a/test/unit/search_index_backend_test.rb +++ b/test/unit/search_index_backend_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class SearchIndexBackendTest < ActiveSupport::TestCase diff --git a/test/unit/session_basic_test.rb b/test/unit/session_basic_test.rb index 072cf492d..a6fc60ddc 100644 --- a/test/unit/session_basic_test.rb +++ b/test/unit/session_basic_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class SessionBasicTest < ActiveSupport::TestCase @@ -95,7 +94,7 @@ class SessionBasicTest < ActiveSupport::TestCase Sessions.destroy(client_id1) # check if session exists - assert(!Sessions.session_exists?(client_id1), 'check if session exists') + assert_not(Sessions.session_exists?(client_id1), 'check if session exists') end @@ -132,10 +131,10 @@ class SessionBasicTest < ActiveSupport::TestCase # next check should be empty result1 = collection_client1.push - assert(!result1, 'check collections - recall') + assert_not(result1, 'check collections - recall') travel 1.second result2 = collection_client2.push - assert(!result2, 'check collections - recall') + assert_not(result2, 'check collections - recall') # change collection group = Group.first @@ -236,12 +235,12 @@ class SessionBasicTest < ActiveSupport::TestCase # next check should be empty result1 = as_client1.push - assert(!result1, 'check as agent1 - recall') + assert_not(result1, 'check as agent1 - recall') # next check should be empty travel 4.seconds result1 = as_client1.push - assert(!result1, 'check as agent1 - recall 2') + assert_not(result1, 'check as agent1 - recall 2') agent1.update!(email: 'activity-stream-agent11@example.com') ticket = Ticket.create!( @@ -290,12 +289,12 @@ class SessionBasicTest < ActiveSupport::TestCase # next check should be empty result1 = ticket_create_client1.push - assert(!result1, 'check ticket_create - recall') + assert_not(result1, 'check ticket_create - recall') # next check should be empty travel 1.second result1 = ticket_create_client1.push - assert(!result1, 'check ticket_create - recall 2') + assert_not(result1, 'check ticket_create - recall 2') Group.create!( name: "SomeTicketCreateGroup::#{rand(999_999)}", diff --git a/test/unit/session_basic_ticket_test.rb b/test/unit/session_basic_ticket_test.rb index ddc9ca4c9..691d31343 100644 --- a/test/unit/session_basic_ticket_test.rb +++ b/test/unit/session_basic_ticket_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class SessionBasicTicketTest < ActiveSupport::TestCase @@ -117,12 +116,12 @@ class SessionBasicTicketTest < ActiveSupport::TestCase # next check should be empty / no changes result1 = client1.push - assert(!result1, 'check ticket_overview_index - recall') + assert_not(result1, 'check ticket_overview_index - recall') # next check should be empty / no changes travel 3.seconds result1 = client1.push - assert(!result1, 'check ticket_overview_index - recall 2') + assert_not(result1, 'check ticket_overview_index - recall 2') # create ticket ticket3 = Ticket.create!(title: '12323', group_id: 1, priority_id: 1, state_id: 1, customer_id: 1) @@ -149,11 +148,11 @@ class SessionBasicTicketTest < ActiveSupport::TestCase assert_not(result1[1][:data][:assets][:Ticket]) result1 = client1.push - assert(!result1, 'check ticket_overview_index - recall 5') + assert_not(result1, 'check ticket_overview_index - recall 5') Sessions::Backend::TicketOverviewList.reset(@agent1.id) result1 = client1.push - assert(!result1, 'check ticket_overview_index - recall 6') + assert_not(result1, 'check ticket_overview_index - recall 6') ticket4 = Ticket.create!(title: '12323 - 2', group_id: 1, priority_id: 1, state_id: 1, customer_id: 1) Sessions::Backend::TicketOverviewList.reset(@agent1.id) diff --git a/test/unit/session_collections_test.rb b/test/unit/session_collections_test.rb index d58b01918..6753cbfc3 100644 --- a/test/unit/session_collections_test.rb +++ b/test/unit/session_collections_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class SessionCollectionsTest < ActiveSupport::TestCase @@ -89,8 +88,8 @@ class SessionCollectionsTest < ActiveSupport::TestCase assert(result3, 'check collections') assert(check_if_collection_exists(result3, :Group), 'check collections - after init') assert(check_if_collection_exists(result3, :Role), 'check collections - after init') - assert(!check_if_collection_exists(result3, :Signature), 'check collections - after init') - assert(!check_if_collection_exists(result3, :EmailAddress), 'check collections - after init') + assert_not(check_if_collection_exists(result3, :Signature), 'check collections - after init') + assert_not(check_if_collection_exists(result3, :EmailAddress), 'check collections - after init') # next check should be empty result1 = collection_client1.push diff --git a/test/unit/session_enhanced_test.rb b/test/unit/session_enhanced_test.rb index 2443adeba..6e986fc99 100644 --- a/test/unit/session_enhanced_test.rb +++ b/test/unit/session_enhanced_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class SessionEnhancedTest < ActiveSupport::TestCase @@ -155,16 +154,16 @@ class SessionEnhancedTest < ActiveSupport::TestCase travel 2.seconds # check client sessions - assert(!Sessions.session_exists?(client_id1), 'check if session is removed') - assert(!Sessions.session_exists?(client_id2), 'check if session is removed') - assert(!Sessions.session_exists?(client_id3), 'check if session is removed') + assert_not(Sessions.session_exists?(client_id1), 'check if session is removed') + assert_not(Sessions.session_exists?(client_id2), 'check if session is removed') + assert_not(Sessions.session_exists?(client_id3), 'check if session is removed') sleep 6 # check client threads - assert(!Sessions.thread_client_exists?(client_id1), 'check if client is running') - assert(!Sessions.thread_client_exists?(client_id2), 'check if client is running') - assert(!Sessions.thread_client_exists?(client_id3), 'check if client is running') + assert_not(Sessions.thread_client_exists?(client_id1), 'check if client is running') + assert_not(Sessions.thread_client_exists?(client_id2), 'check if client is running') + assert_not(Sessions.thread_client_exists?(client_id3), 'check if client is running') # exit jobs jobs.exit @@ -308,10 +307,10 @@ class SessionEnhancedTest < ActiveSupport::TestCase travel 2.seconds # check client sessions - assert(!Sessions.session_exists?(client_id1_0), 'check if session is removed') - assert(!Sessions.session_exists?(client_id1_1), 'check if session is removed') - assert(!Sessions.session_exists?(client_id2), 'check if session is removed') - assert(!Sessions.session_exists?(client_id3), 'check if session is removed') + assert_not(Sessions.session_exists?(client_id1_0), 'check if session is removed') + assert_not(Sessions.session_exists?(client_id1_1), 'check if session is removed') + assert_not(Sessions.session_exists?(client_id2), 'check if session is removed') + assert_not(Sessions.session_exists?(client_id3), 'check if session is removed') # exit jobs jobs.exit diff --git a/test/unit/sla_assets_test.rb b/test/unit/sla_assets_test.rb index 7616cb851..958cc5b92 100644 --- a/test/unit/sla_assets_test.rb +++ b/test/unit/sla_assets_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class SlaAssetsTest < ActiveSupport::TestCase diff --git a/test/unit/stats_ticket_waiting_time_test.rb b/test/unit/stats_ticket_waiting_time_test.rb index b2a8fed44..743a4a0b1 100644 --- a/test/unit/stats_ticket_waiting_time_test.rb +++ b/test/unit/stats_ticket_waiting_time_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' require 'stats/ticket_waiting_time' diff --git a/test/unit/store_test.rb b/test/unit/store_test.rb index c0853df73..9755ec83a 100644 --- a/test/unit/store_test.rb +++ b/test/unit/store_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class StoreTest < ActiveSupport::TestCase @@ -18,11 +17,11 @@ class StoreTest < ActiveSupport::TestCase assert(exists) result = Store::Provider::File.delete(sha) exists = File.exist?(location) - assert(!exists) + assert_not(exists) exists = File.exist?(Rails.root.join('storage', 'fs', 'ed70', '02b4')) - assert(!exists) + assert_not(exists) exists = File.exist?(Rails.root.join('storage', 'fs', 'ed70')) - assert(!exists) + assert_not(exists) exists = File.exist?(Rails.root.join('storage', 'fs')) assert(exists) exists = File.exist?(Rails.root.join('storage')) diff --git a/test/unit/tag_test.rb b/test/unit/tag_test.rb index a1d1809d3..08488dabb 100644 --- a/test/unit/tag_test.rb +++ b/test/unit/tag_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TagTest < ActiveSupport::TestCase @@ -144,7 +143,7 @@ class TagTest < ActiveSupport::TestCase if value == true assert(list.include?(key), "Tag verify - should exists but exists #{key}") else - assert(!list.include?(key), "Tag verify - exists but should not #{key}") + assert_not(list.include?(key), "Tag verify - exists but should not #{key}") end end end @@ -152,15 +151,11 @@ class TagTest < ActiveSupport::TestCase # delete tags tests.each do |test| tags = nil - tags = if test[:tag_add] - test[:tag_add] - else - test[:tag_remove] - end + tags = test[:tag_add] || test[:tag_remove] success = Tag.tag_remove(tags) assert(success, 'Tag.tag_remove successful') list = Tag.tag_list(tags) - assert(!list.include?(tags[:item]), 'Tag entry destroyed') + assert_not(list.include?(tags[:item]), 'Tag entry destroyed') end end diff --git a/test/unit/text_module_csv_import_test.rb b/test/unit/text_module_csv_import_test.rb index 24a7777d1..c0db2e1a9 100644 --- a/test/unit/text_module_csv_import_test.rb +++ b/test/unit/text_module_csv_import_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TextModuleCsvImportTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_article_communicate_test.rb b/test/unit/ticket_article_communicate_test.rb index a4d0618f0..4d7824cb5 100644 --- a/test/unit/ticket_article_communicate_test.rb +++ b/test/unit/ticket_article_communicate_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketArticleCommunicateTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_article_dos_test.rb b/test/unit/ticket_article_dos_test.rb index 180790ec1..0573c9f2a 100644 --- a/test/unit/ticket_article_dos_test.rb +++ b/test/unit/ticket_article_dos_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketArticleDos < ActiveSupport::TestCase diff --git a/test/unit/ticket_article_store_empty.rb b/test/unit/ticket_article_store_empty.rb index 99909058f..a07059015 100644 --- a/test/unit/ticket_article_store_empty.rb +++ b/test/unit/ticket_article_store_empty.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketArticleStoreEmpty < ActiveSupport::TestCase diff --git a/test/unit/ticket_article_time_accouting_test.rb b/test/unit/ticket_article_time_accouting_test.rb index 54adc448c..455fce5d1 100644 --- a/test/unit/ticket_article_time_accouting_test.rb +++ b/test/unit/ticket_article_time_accouting_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketArticleTimeAccoutingTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_article_twitter_test.rb b/test/unit/ticket_article_twitter_test.rb index eeeb85bd1..f17fe2890 100644 --- a/test/unit/ticket_article_twitter_test.rb +++ b/test/unit/ticket_article_twitter_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketArticleTwitter < ActiveSupport::TestCase diff --git a/test/unit/ticket_csv_import_test.rb b/test/unit/ticket_csv_import_test.rb index ef6a5de51..0f6a78ef3 100644 --- a/test/unit/ticket_csv_import_test.rb +++ b/test/unit/ticket_csv_import_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketCsvImportTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_customer_organization_update_test.rb b/test/unit/ticket_customer_organization_update_test.rb index 7d7914d60..5f55764cc 100644 --- a/test/unit/ticket_customer_organization_update_test.rb +++ b/test/unit/ticket_customer_organization_update_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketCustomerOrganizationUpdateTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_escalation_test.rb b/test/unit/ticket_escalation_test.rb index f4f4ebc8a..4899acc26 100644 --- a/test/unit/ticket_escalation_test.rb +++ b/test/unit/ticket_escalation_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketEscalationTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_last_owner_update_test.rb b/test/unit/ticket_last_owner_update_test.rb index e4dc85bb6..39eac16ec 100644 --- a/test/unit/ticket_last_owner_update_test.rb +++ b/test/unit/ticket_last_owner_update_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketLastOwnerUpdateTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_notification_test.rb b/test/unit/ticket_notification_test.rb index dee8ec856..40acc85b7 100644 --- a/test/unit/ticket_notification_test.rb +++ b/test/unit/ticket_notification_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketNotificationTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_null_byte_test.rb b/test/unit/ticket_null_byte_test.rb index 0579112bf..a6a6e78db 100644 --- a/test/unit/ticket_null_byte_test.rb +++ b/test/unit/ticket_null_byte_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketNullByteTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_number_test.rb b/test/unit/ticket_number_test.rb index 6d41f8651..a656a4d67 100644 --- a/test/unit/ticket_number_test.rb +++ b/test/unit/ticket_number_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketNumberTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_overview_out_of_office_test.rb b/test/unit/ticket_overview_out_of_office_test.rb index 9445f944c..a3272e64b 100644 --- a/test/unit/ticket_overview_out_of_office_test.rb +++ b/test/unit/ticket_overview_out_of_office_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketOverviewOutOfOfficeTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_overview_test.rb b/test/unit/ticket_overview_test.rb index b212e5cc7..f45a22935 100644 --- a/test/unit/ticket_overview_test.rb +++ b/test/unit/ticket_overview_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketOverviewTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_priority_test.rb b/test/unit/ticket_priority_test.rb index 92ff51064..f3ab6d052 100644 --- a/test/unit/ticket_priority_test.rb +++ b/test/unit/ticket_priority_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketPriorityTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_ref_object_touch_test.rb b/test/unit/ticket_ref_object_touch_test.rb index d2957c7a5..472880861 100644 --- a/test/unit/ticket_ref_object_touch_test.rb +++ b/test/unit/ticket_ref_object_touch_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketRefObjectTouchTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_screen_options_test.rb b/test/unit/ticket_screen_options_test.rb index b844e25fa..2533439b9 100644 --- a/test/unit/ticket_screen_options_test.rb +++ b/test/unit/ticket_screen_options_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketScreenOptionsTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_selector_test.rb b/test/unit/ticket_selector_test.rb index b0a6787e0..2298f5fa0 100644 --- a/test/unit/ticket_selector_test.rb +++ b/test/unit/ticket_selector_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketSelectorTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_sla_test.rb b/test/unit/ticket_sla_test.rb index 9a7441d8d..825361038 100644 --- a/test/unit/ticket_sla_test.rb +++ b/test/unit/ticket_sla_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketSlaTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_state_change_test.rb b/test/unit/ticket_state_change_test.rb index 066e4bf87..882711951 100644 --- a/test/unit/ticket_state_change_test.rb +++ b/test/unit/ticket_state_change_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketStateChangeTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_state_test.rb b/test/unit/ticket_state_test.rb index 3e3cbf7a2..62170d897 100644 --- a/test/unit/ticket_state_test.rb +++ b/test/unit/ticket_state_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketStateTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_test.rb b/test/unit/ticket_test.rb index d00616237..c880bd1ad 100644 --- a/test/unit/ticket_test.rb +++ b/test/unit/ticket_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketTest < ActiveSupport::TestCase diff --git a/test/unit/ticket_xss_test.rb b/test/unit/ticket_xss_test.rb index 9d0b8f6d6..fa8a0a1ef 100644 --- a/test/unit/ticket_xss_test.rb +++ b/test/unit/ticket_xss_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TicketXssTest < ActiveSupport::TestCase diff --git a/test/unit/token_test.rb b/test/unit/token_test.rb index ec1a2bf5b..36eb6ec31 100644 --- a/test/unit/token_test.rb +++ b/test/unit/token_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TokenTest < ActiveSupport::TestCase diff --git a/test/unit/trigger_assets_test.rb b/test/unit/trigger_assets_test.rb index 69def14fb..68ce45587 100644 --- a/test/unit/trigger_assets_test.rb +++ b/test/unit/trigger_assets_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class TriggerAssetsTest < ActiveSupport::TestCase diff --git a/test/unit/user_assets_test.rb b/test/unit/user_assets_test.rb index 8d79547c3..b4f172790 100644 --- a/test/unit/user_assets_test.rb +++ b/test/unit/user_assets_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class UserAssetsTest < ActiveSupport::TestCase @@ -141,6 +140,7 @@ class UserAssetsTest < ActiveSupport::TestCase def diff(object1, object2) return true if object1 == object2 + %w[updated_at created_at].each do |item| if object1[item] object1[item] = object1[item].to_s @@ -150,6 +150,7 @@ class UserAssetsTest < ActiveSupport::TestCase end end return true if (object1.to_a - object2.to_a).blank? + #puts "ERROR: difference \n1: #{object1.inspect}\n2: #{object2.inspect}\ndiff: #{(object1.to_a - object2.to_a).inspect}" false end diff --git a/test/unit/user_csv_import_test.rb b/test/unit/user_csv_import_test.rb index cc1d146e5..05b5797d9 100644 --- a/test/unit/user_csv_import_test.rb +++ b/test/unit/user_csv_import_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class UserCsvImportTest < ActiveSupport::TestCase diff --git a/test/unit/user_ref_object_touch_test.rb b/test/unit/user_ref_object_touch_test.rb index efa5fa136..d366da5f4 100644 --- a/test/unit/user_ref_object_touch_test.rb +++ b/test/unit/user_ref_object_touch_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class UserRefObjectTouchTest < ActiveSupport::TestCase diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index 79c6c23d3..2ae981c96 100644 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -1,4 +1,3 @@ - require 'test_helper' class UserTest < ActiveSupport::TestCase @@ -270,6 +269,7 @@ class UserTest < ActiveSupport::TestCase test[:create_verify].each do |key, value| next if key == :image_md5 + if user.respond_to?(key) result = user.send(key) if value.nil? @@ -291,6 +291,7 @@ class UserTest < ActiveSupport::TestCase test[:update_verify].each do |key, value| next if key == :image_md5 + if user.respond_to?(key) assert_equal(user.send(key), value, "update check #{key} in (#{test[:name]})") else