Merge branch 'develop' of git.znuny.com:zammad/zammad into develop
This commit is contained in:
commit
0d1d86511f
456 changed files with 3929 additions and 2621 deletions
61
.rubocop.yml
61
.rubocop.yml
|
@ -45,29 +45,29 @@ Style/TrailingCommaInArguments:
|
||||||
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas'
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas'
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Style/SpaceInsideParens:
|
Layout/SpaceInsideParens:
|
||||||
Description: 'No spaces after ( or before ).'
|
Description: 'No spaces after ( or before ).'
|
||||||
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-spaces-braces'
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-spaces-braces'
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Style/SpaceAfterMethodName:
|
Layout/SpaceAfterMethodName:
|
||||||
Description: >-
|
Description: >-
|
||||||
Do not put a space between a method name and the opening
|
Do not put a space between a method name and the opening
|
||||||
parenthesis in a method definition.
|
parenthesis in a method definition.
|
||||||
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#parens-no-spaces'
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#parens-no-spaces'
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Style/LeadingCommentSpace:
|
Layout/LeadingCommentSpace:
|
||||||
Description: 'Comments should start with a space.'
|
Description: 'Comments should start with a space.'
|
||||||
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#hash-space'
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#hash-space'
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Style/MethodCallParentheses:
|
Style/MethodCallWithoutArgsParentheses:
|
||||||
Description: 'Do not use parentheses for method calls with no arguments.'
|
Description: 'Do not use parentheses for method calls with no arguments.'
|
||||||
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-args-no-parens'
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-args-no-parens'
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Style/SpaceInsideBrackets:
|
Layout/SpaceInsideBrackets:
|
||||||
Description: 'No spaces after [ or before ].'
|
Description: 'No spaces after [ or before ].'
|
||||||
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-spaces-braces'
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-spaces-braces'
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
@ -83,19 +83,19 @@ Style/MethodDefParentheses:
|
||||||
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#method-parens'
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#method-parens'
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Style/EmptyLinesAroundClassBody:
|
Layout/EmptyLinesAroundClassBody:
|
||||||
Description: "Keeps track of empty lines around class bodies."
|
Description: "Keeps track of empty lines around class bodies."
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Style/EmptyLinesAroundMethodBody:
|
Layout/EmptyLinesAroundMethodBody:
|
||||||
Description: "Keeps track of empty lines around method bodies."
|
Description: "Keeps track of empty lines around method bodies."
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Style/EmptyLinesAroundBlockBody:
|
Layout/EmptyLinesAroundBlockBody:
|
||||||
Description: "Keeps track of empty lines around block bodies."
|
Description: "Keeps track of empty lines around block bodies."
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Style/EmptyLinesAroundModuleBody:
|
Layout/EmptyLinesAroundModuleBody:
|
||||||
Description: "Keeps track of empty lines around module bodies."
|
Description: "Keeps track of empty lines around module bodies."
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
@ -143,17 +143,29 @@ Rails/HasAndBelongsToMany:
|
||||||
# StyleGuide: 'https://github.com/bbatsov/rails-style-guide#has-many-through'
|
# StyleGuide: 'https://github.com/bbatsov/rails-style-guide#has-many-through'
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
Rails/SkipsModelValidations:
|
||||||
|
Description: >-
|
||||||
|
Use methods that skips model validations with caution.
|
||||||
|
See reference for more information.
|
||||||
|
Reference: 'http://guides.rubyonrails.org/active_record_validations.html#skipping-validations'
|
||||||
|
Enabled: true
|
||||||
|
Exclude:
|
||||||
|
- test/**/*
|
||||||
|
|
||||||
Style/ClassAndModuleChildren:
|
Style/ClassAndModuleChildren:
|
||||||
Description: 'Checks style of children classes and modules.'
|
Description: 'Checks style of children classes and modules.'
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Style/FileName:
|
Naming/FileName:
|
||||||
Description: 'Use snake_case for source file names.'
|
Description: 'Use snake_case for source file names.'
|
||||||
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#snake-case-files'
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#snake-case-files'
|
||||||
Enabled: true
|
Enabled: true
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'script/websocket-server.rb'
|
- 'script/websocket-server.rb'
|
||||||
|
|
||||||
|
Naming/VariableNumber:
|
||||||
|
Description: 'Use the configured style when numbering variables.'
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
# 2.0
|
# 2.0
|
||||||
|
|
||||||
|
@ -184,8 +196,23 @@ Metrics/ModuleLength:
|
||||||
Description: 'Avoid modules longer than 100 lines of code.'
|
Description: 'Avoid modules longer than 100 lines of code.'
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
Metrics/BlockLength:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Lint/RescueWithoutErrorClass:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Rails/ApplicationRecord:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
|
Rails/HasManyOrHasOneDependent:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/DateTime:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
Style/Documentation:
|
Style/Documentation:
|
||||||
Description: 'Document classes and non-namespace modules.'
|
Description: 'Document classes and non-namespace modules.'
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
@ -193,7 +220,7 @@ Style/Documentation:
|
||||||
Lint/UselessAssignment:
|
Lint/UselessAssignment:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Style/ExtraSpacing:
|
Layout/ExtraSpacing:
|
||||||
Description: 'Do not use unnecessary spacing.'
|
Description: 'Do not use unnecessary spacing.'
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
@ -215,4 +242,14 @@ Style/NumericPredicate:
|
||||||
AutoCorrect: false
|
AutoCorrect: false
|
||||||
Enabled: true
|
Enabled: true
|
||||||
Exclude:
|
Exclude:
|
||||||
- "**/*_spec.rb"
|
- "**/*_spec.rb"
|
||||||
|
|
||||||
|
Lint/AmbiguousBlockAssociation:
|
||||||
|
Description: >-
|
||||||
|
Checks for ambiguous block association with method when param passed without
|
||||||
|
parentheses.
|
||||||
|
StyleGuide: '#syntax'
|
||||||
|
Enabled: true
|
||||||
|
Exclude:
|
||||||
|
- "**/*_spec.rb"
|
||||||
|
- "**/*_examples.rb"
|
||||||
|
|
128
Gemfile
128
Gemfile
|
@ -1,112 +1,131 @@
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
|
# core - base
|
||||||
ruby '2.4.1'
|
ruby '2.4.1'
|
||||||
|
|
||||||
gem 'rails', '5.1.4'
|
gem 'rails', '5.1.4'
|
||||||
gem 'rails-observers'
|
|
||||||
|
# core - rails additions
|
||||||
gem 'activerecord-session_store'
|
gem 'activerecord-session_store'
|
||||||
|
gem 'composite_primary_keys'
|
||||||
# Bundle edge Rails instead:
|
|
||||||
#gem 'rails', :git => 'git://github.com/rails/rails.git'
|
|
||||||
|
|
||||||
gem 'json'
|
gem 'json'
|
||||||
|
gem 'rails-observers'
|
||||||
|
|
||||||
# Supported DBs
|
# core - application servers
|
||||||
|
gem 'puma', group: :puma
|
||||||
|
gem 'unicorn', group: :unicorn
|
||||||
|
|
||||||
|
# core - supported ORMs
|
||||||
gem 'activerecord-nulldb-adapter', group: :nulldb
|
gem 'activerecord-nulldb-adapter', group: :nulldb
|
||||||
gem 'mysql2', group: :mysql
|
gem 'mysql2', group: :mysql
|
||||||
gem 'pg', group: :postgres
|
gem 'pg', group: :postgres
|
||||||
|
|
||||||
|
# core - asynchrous task execution
|
||||||
|
gem 'daemons'
|
||||||
|
gem 'delayed_job_active_record'
|
||||||
|
|
||||||
|
# core - websocket
|
||||||
|
gem 'em-websocket'
|
||||||
|
gem 'eventmachine'
|
||||||
|
|
||||||
|
# core - password security
|
||||||
|
gem 'argon2'
|
||||||
|
|
||||||
|
# performance - Memcached
|
||||||
|
gem 'dalli'
|
||||||
|
|
||||||
|
# asset handling
|
||||||
group :assets do
|
group :assets do
|
||||||
gem 'sass-rails' #, github: 'rails/sass-rails'
|
# asset handling - coffee-script
|
||||||
gem 'coffee-rails'
|
gem 'coffee-rails'
|
||||||
gem 'coffee-script-source'
|
gem 'coffee-script-source'
|
||||||
|
|
||||||
gem 'sprockets'
|
# asset handling - frontend templating
|
||||||
|
|
||||||
gem 'uglifier'
|
|
||||||
gem 'eco'
|
gem 'eco'
|
||||||
|
|
||||||
|
# asset handling - SASS
|
||||||
|
gem 'sass-rails'
|
||||||
|
|
||||||
|
# asset handling - pipeline
|
||||||
|
gem 'sprockets'
|
||||||
|
gem 'uglifier'
|
||||||
end
|
end
|
||||||
|
|
||||||
gem 'autoprefixer-rails'
|
gem 'autoprefixer-rails'
|
||||||
|
|
||||||
|
# asset handling - javascript execution for e.g. linux
|
||||||
|
gem 'execjs'
|
||||||
|
gem 'libv8'
|
||||||
|
gem 'therubyracer'
|
||||||
|
|
||||||
|
# authentication - provider
|
||||||
gem 'doorkeeper'
|
gem 'doorkeeper'
|
||||||
gem 'oauth2'
|
gem 'oauth2'
|
||||||
|
|
||||||
|
# authentication - third party
|
||||||
gem 'omniauth'
|
gem 'omniauth'
|
||||||
gem 'omniauth-oauth2'
|
|
||||||
gem 'omniauth-facebook'
|
gem 'omniauth-facebook'
|
||||||
gem 'omniauth-github'
|
gem 'omniauth-github'
|
||||||
gem 'omniauth-gitlab'
|
gem 'omniauth-gitlab'
|
||||||
gem 'omniauth-google-oauth2'
|
gem 'omniauth-google-oauth2'
|
||||||
gem 'omniauth-linkedin-oauth2'
|
gem 'omniauth-linkedin-oauth2'
|
||||||
gem 'omniauth-twitter'
|
|
||||||
gem 'omniauth-microsoft-office365'
|
gem 'omniauth-microsoft-office365'
|
||||||
|
gem 'omniauth-oauth2'
|
||||||
|
gem 'omniauth-twitter'
|
||||||
gem 'omniauth-weibo-oauth2'
|
gem 'omniauth-weibo-oauth2'
|
||||||
|
|
||||||
gem 'twitter'
|
# channels
|
||||||
gem 'telegramAPI'
|
|
||||||
gem 'koala'
|
gem 'koala'
|
||||||
gem 'mail'
|
gem 'telegramAPI'
|
||||||
gem 'valid_email2'
|
gem 'twitter'
|
||||||
|
|
||||||
|
# channels - email additions
|
||||||
gem 'htmlentities'
|
gem 'htmlentities'
|
||||||
|
gem 'mail', '2.6.6'
|
||||||
gem 'mime-types'
|
gem 'mime-types'
|
||||||
|
gem 'valid_email2'
|
||||||
|
|
||||||
|
# feature - business hours
|
||||||
gem 'biz'
|
gem 'biz'
|
||||||
|
|
||||||
gem 'composite_primary_keys'
|
# feature - signature diffing
|
||||||
gem 'delayed_job_active_record'
|
gem 'diffy'
|
||||||
gem 'daemons'
|
|
||||||
|
|
||||||
gem 'simple-rss'
|
|
||||||
|
|
||||||
# e. g. on linux we need a javascript execution
|
|
||||||
gem 'libv8'
|
|
||||||
gem 'execjs'
|
|
||||||
gem 'therubyracer'
|
|
||||||
|
|
||||||
require 'erb'
|
|
||||||
require 'yaml'
|
|
||||||
|
|
||||||
gem 'net-ldap'
|
|
||||||
|
|
||||||
# password security
|
|
||||||
gem 'argon2'
|
|
||||||
|
|
||||||
|
# feature - excel output
|
||||||
gem 'writeexcel'
|
gem 'writeexcel'
|
||||||
gem 'icalendar'
|
|
||||||
gem 'icalendar-recurrence'
|
# feature - device logging
|
||||||
gem 'browser'
|
gem 'browser'
|
||||||
|
|
||||||
|
# feature - iCal export
|
||||||
|
gem 'icalendar'
|
||||||
|
gem 'icalendar-recurrence'
|
||||||
|
|
||||||
# integrations
|
# integrations
|
||||||
gem 'slack-notifier'
|
|
||||||
gem 'clearbit'
|
gem 'clearbit'
|
||||||
|
gem 'net-ldap'
|
||||||
|
gem 'slack-notifier'
|
||||||
gem 'zendesk_api'
|
gem 'zendesk_api'
|
||||||
gem 'viewpoint'
|
|
||||||
gem 'rubyntlm', git: 'https://github.com/wimm/rubyntlm.git'
|
# integrations - exchange
|
||||||
gem 'autodiscover', git: 'https://github.com/thorsteneckel/autodiscover.git'
|
gem 'autodiscover', git: 'https://github.com/thorsteneckel/autodiscover.git'
|
||||||
|
gem 'rubyntlm', git: 'https://github.com/wimm/rubyntlm.git'
|
||||||
# event machine
|
gem 'viewpoint'
|
||||||
gem 'eventmachine'
|
|
||||||
gem 'em-websocket'
|
|
||||||
|
|
||||||
gem 'diffy'
|
|
||||||
gem 'dalli'
|
|
||||||
|
|
||||||
# Gems used only for develop/test and not required
|
# Gems used only for develop/test and not required
|
||||||
# in production environments by default.
|
# in production environments by default.
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
|
|
||||||
|
# test frameworks
|
||||||
gem 'rspec-rails'
|
gem 'rspec-rails'
|
||||||
gem 'test-unit'
|
gem 'test-unit'
|
||||||
gem 'spring'
|
|
||||||
gem 'spring-commands-rspec'
|
# test DB
|
||||||
gem 'sqlite3'
|
gem 'sqlite3'
|
||||||
|
|
||||||
# code coverage
|
# code coverage
|
||||||
|
gem 'coveralls', require: false
|
||||||
gem 'simplecov'
|
gem 'simplecov'
|
||||||
gem 'simplecov-rcov'
|
gem 'simplecov-rcov'
|
||||||
gem 'coveralls', require: false
|
|
||||||
|
|
||||||
# UI tests w/ Selenium
|
# UI tests w/ Selenium
|
||||||
gem 'selenium-webdriver', '2.53.4'
|
gem 'selenium-webdriver', '2.53.4'
|
||||||
|
@ -121,9 +140,9 @@ group :development, :test do
|
||||||
gem 'guard-symlink', require: false
|
gem 'guard-symlink', require: false
|
||||||
|
|
||||||
# code QA
|
# code QA
|
||||||
|
gem 'coffeelint'
|
||||||
gem 'pre-commit'
|
gem 'pre-commit'
|
||||||
gem 'rubocop'
|
gem 'rubocop'
|
||||||
gem 'coffeelint'
|
|
||||||
|
|
||||||
# changelog generation
|
# changelog generation
|
||||||
gem 'github_changelog_generator'
|
gem 'github_changelog_generator'
|
||||||
|
@ -138,10 +157,7 @@ group :development, :test do
|
||||||
gem 'webmock'
|
gem 'webmock'
|
||||||
end
|
end
|
||||||
|
|
||||||
gem 'puma', group: :puma
|
# load onw gems for development and testing purposes
|
||||||
gem 'unicorn', group: :unicorn
|
|
||||||
|
|
||||||
# load onw gem's
|
|
||||||
local_gemfile = File.join(File.dirname(__FILE__), 'Gemfile.local')
|
local_gemfile = File.join(File.dirname(__FILE__), 'Gemfile.local')
|
||||||
if File.exist?(local_gemfile)
|
if File.exist?(local_gemfile)
|
||||||
eval_gemfile local_gemfile
|
eval_gemfile local_gemfile
|
||||||
|
|
15
Gemfile.lock
15
Gemfile.lock
|
@ -217,13 +217,12 @@ GEM
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.5.9)
|
nokogiri (>= 1.5.9)
|
||||||
lumberjack (1.0.12)
|
lumberjack (1.0.12)
|
||||||
mail (2.7.0)
|
mail (2.6.6)
|
||||||
mini_mime (>= 0.1.1)
|
mime-types (>= 1.16, < 4)
|
||||||
memoizable (0.4.2)
|
memoizable (0.4.2)
|
||||||
thread_safe (~> 0.3, >= 0.3.1)
|
thread_safe (~> 0.3, >= 0.3.1)
|
||||||
method_source (0.9.0)
|
method_source (0.9.0)
|
||||||
mime-types (2.99.3)
|
mime-types (2.99.3)
|
||||||
mini_mime (1.0.0)
|
|
||||||
mini_portile2 (2.3.0)
|
mini_portile2 (2.3.0)
|
||||||
minitest (5.10.3)
|
minitest (5.10.3)
|
||||||
multi_json (1.12.2)
|
multi_json (1.12.2)
|
||||||
|
@ -389,7 +388,6 @@ GEM
|
||||||
rubyzip (~> 1.0)
|
rubyzip (~> 1.0)
|
||||||
websocket (~> 1.0)
|
websocket (~> 1.0)
|
||||||
shellany (0.0.1)
|
shellany (0.0.1)
|
||||||
simple-rss (1.3.1)
|
|
||||||
simple_oauth (0.3.1)
|
simple_oauth (0.3.1)
|
||||||
simplecov (0.15.1)
|
simplecov (0.15.1)
|
||||||
docile (~> 1.1.0)
|
docile (~> 1.1.0)
|
||||||
|
@ -399,10 +397,6 @@ GEM
|
||||||
simplecov-rcov (0.2.3)
|
simplecov-rcov (0.2.3)
|
||||||
simplecov (>= 0.4.1)
|
simplecov (>= 0.4.1)
|
||||||
slack-notifier (2.3.1)
|
slack-notifier (2.3.1)
|
||||||
spring (2.0.2)
|
|
||||||
activesupport (>= 4.2)
|
|
||||||
spring-commands-rspec (1.0.4)
|
|
||||||
spring (>= 0.9.1)
|
|
||||||
sprockets (3.7.1)
|
sprockets (3.7.1)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
rack (> 1, < 3)
|
rack (> 1, < 3)
|
||||||
|
@ -508,7 +502,7 @@ DEPENDENCIES
|
||||||
json
|
json
|
||||||
koala
|
koala
|
||||||
libv8
|
libv8
|
||||||
mail
|
mail (= 2.6.6)
|
||||||
mime-types
|
mime-types
|
||||||
mysql2
|
mysql2
|
||||||
net-ldap
|
net-ldap
|
||||||
|
@ -535,12 +529,9 @@ DEPENDENCIES
|
||||||
rubyntlm!
|
rubyntlm!
|
||||||
sass-rails
|
sass-rails
|
||||||
selenium-webdriver (= 2.53.4)
|
selenium-webdriver (= 2.53.4)
|
||||||
simple-rss
|
|
||||||
simplecov
|
simplecov
|
||||||
simplecov-rcov
|
simplecov-rcov
|
||||||
slack-notifier
|
slack-notifier
|
||||||
spring
|
|
||||||
spring-commands-rspec
|
|
||||||
sprockets
|
sprockets
|
||||||
sqlite3
|
sqlite3
|
||||||
telegramAPI
|
telegramAPI
|
||||||
|
|
0
Rakefile
Normal file → Executable file
0
Rakefile
Normal file → Executable file
|
@ -148,24 +148,26 @@ class App.ControllerGenericIndex extends App.Controller
|
||||||
return item
|
return item
|
||||||
)
|
)
|
||||||
|
|
||||||
# show description button, only if content exists
|
if !@table
|
||||||
showDescription = false
|
|
||||||
if App[ @genericObject ].description && !_.isEmpty(objects)
|
|
||||||
showDescription = true
|
|
||||||
|
|
||||||
@html App.view('generic/admin/index')(
|
# show description button, only if content exists
|
||||||
head: @pageData.objects
|
showDescription = false
|
||||||
notes: @pageData.notes
|
if App[ @genericObject ].description && !_.isEmpty(objects)
|
||||||
buttons: @pageData.buttons
|
showDescription = true
|
||||||
menus: @pageData.menus
|
|
||||||
showDescription: showDescription
|
|
||||||
)
|
|
||||||
|
|
||||||
# show description in content if no no content exists
|
@html App.view('generic/admin/index')(
|
||||||
if _.isEmpty(objects) && App[ @genericObject ].description
|
head: @pageData.objects
|
||||||
description = marked(App[ @genericObject ].description)
|
notes: @pageData.notes
|
||||||
@$('.table-overview').html(description)
|
buttons: @pageData.buttons
|
||||||
return
|
menus: @pageData.menus
|
||||||
|
showDescription: showDescription
|
||||||
|
)
|
||||||
|
|
||||||
|
# show description in content if no no content exists
|
||||||
|
if _.isEmpty(objects) && App[ @genericObject ].description
|
||||||
|
description = marked(App[ @genericObject ].description)
|
||||||
|
@$('.table-overview').html(description)
|
||||||
|
return
|
||||||
|
|
||||||
# append content table
|
# append content table
|
||||||
params = _.extend(
|
params = _.extend(
|
||||||
|
@ -184,7 +186,10 @@ class App.ControllerGenericIndex extends App.Controller
|
||||||
},
|
},
|
||||||
@pageData.tableExtend
|
@pageData.tableExtend
|
||||||
)
|
)
|
||||||
new App.ControllerTable(params)
|
if !@table
|
||||||
|
@table = new App.ControllerTable(params)
|
||||||
|
else
|
||||||
|
@table.update(objects: objects)
|
||||||
|
|
||||||
edit: (id, e) =>
|
edit: (id, e) =>
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
@ -1170,7 +1175,6 @@ class App.ObserverController extends App.Controller
|
||||||
if @globalRerender
|
if @globalRerender
|
||||||
@bind('ui:rerender', =>
|
@bind('ui:rerender', =>
|
||||||
@lastAttributres = undefined
|
@lastAttributres = undefined
|
||||||
console.log('aaaa', @model, @template)
|
|
||||||
@maybeRender(App[@model].fullLocal(@object_id))
|
@maybeRender(App[@model].fullLocal(@object_id))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
class SidebarCustomer extends App.Controller
|
class SidebarCustomer extends App.Controller
|
||||||
sidebarItem: =>
|
sidebarItem: =>
|
||||||
return if !@permissionCheck('ticket.agent')
|
return if !@permissionCheck('ticket.agent')
|
||||||
return if !@params.customer_id
|
return if _.isEmpty(@params.customer_id)
|
||||||
{
|
{
|
||||||
head: 'Customer'
|
head: 'Customer'
|
||||||
name: 'customer'
|
name: 'customer'
|
||||||
|
@ -18,6 +18,7 @@ class SidebarCustomer extends App.Controller
|
||||||
|
|
||||||
showCustomer: (el) =>
|
showCustomer: (el) =>
|
||||||
@el = el
|
@el = el
|
||||||
|
return if _.isEmpty(@params.customer_id)
|
||||||
new App.WidgetUser(
|
new App.WidgetUser(
|
||||||
el: @el
|
el: @el
|
||||||
user_id: @params.customer_id
|
user_id: @params.customer_id
|
||||||
|
|
|
@ -44,6 +44,8 @@ class App.IdoitObjectSelector extends App.ControllerModal
|
||||||
''
|
''
|
||||||
|
|
||||||
search: (filter) =>
|
search: (filter) =>
|
||||||
|
if _.isEmpty(filter.type)
|
||||||
|
delete filter.type
|
||||||
if _.isEmpty(filter.title)
|
if _.isEmpty(filter.title)
|
||||||
delete filter.title
|
delete filter.title
|
||||||
else
|
else
|
||||||
|
|
|
@ -23,17 +23,22 @@ class Index extends App.ControllerSubContent
|
||||||
]
|
]
|
||||||
container: @el.closest('.content')
|
container: @el.closest('.content')
|
||||||
large: true
|
large: true
|
||||||
dndCallback: =>
|
dndCallback: (e, item) =>
|
||||||
items = @el.find('table > tbody > tr')
|
items = @el.find('table > tbody > tr')
|
||||||
order = []
|
prios = []
|
||||||
prio = 0
|
prio = 0
|
||||||
for item in items
|
for item in items
|
||||||
prio += 1
|
prio += 1
|
||||||
id = $(item).data('id')
|
id = $(item).data('id')
|
||||||
overview = App.Overview.find(id)
|
prios.push [id, prio]
|
||||||
if overview.prio isnt prio
|
|
||||||
overview.prio = prio
|
@ajax(
|
||||||
overview.save()
|
id: 'overview_prio'
|
||||||
|
type: 'POST'
|
||||||
|
url: "#{@apiPath}/overviews_prio"
|
||||||
|
processData: true
|
||||||
|
data: JSON.stringify(prios: prios)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
App.Config.set('Overview', { prio: 2300, name: 'Overviews', parent: '#manage', target: '#manage/overviews', controller: Index, permission: ['admin.overview'] }, 'NavBarAdmin')
|
App.Config.set('Overview', { prio: 2300, name: 'Overviews', parent: '#manage', target: '#manage/overviews', controller: Index, permission: ['admin.overview'] }, 'NavBarAdmin')
|
||||||
|
|
|
@ -18,8 +18,19 @@ class App.TicketCustomer extends App.ControllerModal
|
||||||
onSubmit: (e) =>
|
onSubmit: (e) =>
|
||||||
params = @formParam(e.target)
|
params = @formParam(e.target)
|
||||||
|
|
||||||
@customer_id = params['customer_id']
|
ticket = App.Ticket.find(@ticket_id)
|
||||||
|
ticket.customer_id = params['customer_id']
|
||||||
|
errors = ticket.validate()
|
||||||
|
|
||||||
|
if !_.isEmpty(errors)
|
||||||
|
@log 'error', errors
|
||||||
|
@formValidate(
|
||||||
|
form: e.target
|
||||||
|
errors: errors
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
@customer_id = params['customer_id']
|
||||||
callback = =>
|
callback = =>
|
||||||
|
|
||||||
# close modal
|
# close modal
|
||||||
|
|
|
@ -71,7 +71,7 @@ class App.ObjectOrganizationAutocompletion extends App.Controller
|
||||||
@open()
|
@open()
|
||||||
|
|
||||||
focusInput: =>
|
focusInput: =>
|
||||||
@objectSelect.focus() if not @formControl.hasClass 'focus'
|
@objectSelect.focus() if not @formControl.hasClass('focus')
|
||||||
|
|
||||||
onBlur: =>
|
onBlur: =>
|
||||||
selectObject = @objectSelect.val()
|
selectObject = @objectSelect.val()
|
||||||
|
@ -85,6 +85,9 @@ class App.ObjectOrganizationAutocompletion extends App.Controller
|
||||||
@objectId.val("guess:#{selectObject}")
|
@objectId.val("guess:#{selectObject}")
|
||||||
@formControl.removeClass 'focus'
|
@formControl.removeClass 'focus'
|
||||||
|
|
||||||
|
resetObjectSelection: =>
|
||||||
|
@objectId.val('').trigger('change')
|
||||||
|
|
||||||
onObjectClick: (e) =>
|
onObjectClick: (e) =>
|
||||||
objectId = $(e.currentTarget).data('object-id')
|
objectId = $(e.currentTarget).data('object-id')
|
||||||
@selectObject(objectId)
|
@selectObject(objectId)
|
||||||
|
@ -103,23 +106,23 @@ class App.ObjectOrganizationAutocompletion extends App.Controller
|
||||||
# Only work with the last one since its the newest one
|
# Only work with the last one since its the newest one
|
||||||
objectId = @objectId.val().split(',').pop()
|
objectId = @objectId.val().split(',').pop()
|
||||||
|
|
||||||
return if !objectId
|
if objectId && App[@objectSingle].exists(objectId)
|
||||||
return if !App[@objectSingle].exists(objectId)
|
object = App[@objectSingle].find(objectId)
|
||||||
object = App[@objectSingle].find(objectId)
|
name = object.displayName()
|
||||||
name = object.displayName()
|
|
||||||
|
|
||||||
if @attribute.multiple
|
if @attribute.multiple
|
||||||
# create token
|
|
||||||
@createToken name, objectId
|
|
||||||
else
|
|
||||||
if object.email
|
|
||||||
|
|
||||||
# quote name for special character
|
# create token
|
||||||
if name.match(/\@|,|;|\^|\+|#|§|\$|%|&|\/|\(|\)|=|\?|!|\*|\[|\]/)
|
@createToken(name, objectId)
|
||||||
name = "\"#{name}\""
|
else
|
||||||
name += " <#{object.email}>"
|
if object.email
|
||||||
|
|
||||||
@objectSelect.val(name)
|
# quote name for special character
|
||||||
|
if name.match(/\@|,|;|\^|\+|#|§|\$|%|&|\/|\(|\)|=|\?|!|\*|\[|\]/)
|
||||||
|
name = "\"#{name}\""
|
||||||
|
name += " <#{object.email}>"
|
||||||
|
|
||||||
|
@objectSelect.val(name)
|
||||||
|
|
||||||
if @callback
|
if @callback
|
||||||
@callback(objectId)
|
@callback(objectId)
|
||||||
|
@ -321,12 +324,16 @@ class App.ObjectOrganizationAutocompletion extends App.Controller
|
||||||
@hideOrganizationMembers()
|
@hideOrganizationMembers()
|
||||||
|
|
||||||
# hide dropdown
|
# hide dropdown
|
||||||
if !query
|
if _.isEmpty(query)
|
||||||
@emptyResultList()
|
@emptyResultList()
|
||||||
|
|
||||||
if !@attribute.disableCreateObject
|
if !@attribute.disableCreateObject
|
||||||
@recipientList.append(@buildObjectNew())
|
@recipientList.append(@buildObjectNew())
|
||||||
|
|
||||||
|
# reset object selection
|
||||||
|
@resetObjectSelection()
|
||||||
|
return
|
||||||
|
|
||||||
# show dropdown
|
# show dropdown
|
||||||
if query && ( !@attribute.minLengt || @attribute.minLengt <= query.length )
|
if query && ( !@attribute.minLengt || @attribute.minLengt <= query.length )
|
||||||
@lazySearch(query)
|
@lazySearch(query)
|
||||||
|
|
|
@ -387,15 +387,17 @@ set new attributes of model (remove already available attributes)
|
||||||
=>
|
=>
|
||||||
return if _.isEmpty(@SUBSCRIPTION_COLLECTION)
|
return if _.isEmpty(@SUBSCRIPTION_COLLECTION)
|
||||||
App.Log.debug('Model', "server notify collection change #{@className}")
|
App.Log.debug('Model', "server notify collection change #{@className}")
|
||||||
@fetchFull(
|
callback = =>
|
||||||
->
|
@fetchFull(
|
||||||
clear: true
|
->
|
||||||
)
|
clear: true
|
||||||
|
)
|
||||||
|
App.Delay.set(callback, 200, "full-#{@className}")
|
||||||
|
|
||||||
"Collection::Subscribe::#{@className}"
|
"Collection::Subscribe::#{@className}"
|
||||||
)
|
)
|
||||||
|
|
||||||
key = @className + '-' + Math.floor( Math.random() * 99999 )
|
key = "#{@className}-#{Math.floor(Math.random() * 99999)}"
|
||||||
@SUBSCRIPTION_COLLECTION[key] = callback
|
@SUBSCRIPTION_COLLECTION[key] = callback
|
||||||
|
|
||||||
# fetch init collection
|
# fetch init collection
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class App.Overview extends App.Model
|
class App.Overview extends App.Model
|
||||||
@configure 'Overview', 'name', 'prio', 'condition', 'order', 'group_by', 'view', 'user_ids', 'organization_shared', 'role_ids', 'order', 'group_by', 'active', 'updated_at'
|
@configure 'Overview', 'name', 'prio', 'condition', 'order', 'group_by', 'view', 'user_ids', 'organization_shared', 'role_ids', 'active'
|
||||||
@extend Spine.Model.Ajax
|
@extend Spine.Model.Ajax
|
||||||
@url: @apiPath + '/overviews'
|
@url: @apiPath + '/overviews'
|
||||||
@configure_attributes = [
|
@configure_attributes = [
|
||||||
|
|
|
@ -200,6 +200,26 @@ class App.Ticket extends App.Model
|
||||||
result = true if objectValue.toString().match(contains_regex)
|
result = true if objectValue.toString().match(contains_regex)
|
||||||
else if condition.operator == 'contains not'
|
else if condition.operator == 'contains not'
|
||||||
result = true if !objectValue.toString().match(contains_regex)
|
result = true if !objectValue.toString().match(contains_regex)
|
||||||
|
else if condition.operator == 'contains all'
|
||||||
|
result = true
|
||||||
|
for loopConditionValue in conditionValue
|
||||||
|
if !_.contains(objectValue, loopConditionValue)
|
||||||
|
result = false
|
||||||
|
else if condition.operator == 'contains one'
|
||||||
|
result = false
|
||||||
|
for loopConditionValue in conditionValue
|
||||||
|
if _.contains(objectValue, loopConditionValue)
|
||||||
|
result = true
|
||||||
|
else if condition.operator == 'contains all not'
|
||||||
|
result = true
|
||||||
|
for loopObjectValue in objectValue
|
||||||
|
if _.contains(conditionValue, loopObjectValue)
|
||||||
|
result = false
|
||||||
|
else if condition.operator == 'contains one not'
|
||||||
|
result = false
|
||||||
|
for loopObjectValue in objectValue
|
||||||
|
if !_.contains(conditionValue, loopObjectValue)
|
||||||
|
result = true
|
||||||
else if condition.operator == 'is'
|
else if condition.operator == 'is'
|
||||||
result = true if objectValue.toString().trim().toLowerCase() is loopConditionValue.toString().trim().toLowerCase()
|
result = true if objectValue.toString().trim().toLowerCase() is loopConditionValue.toString().trim().toLowerCase()
|
||||||
else if condition.operator == 'is not'
|
else if condition.operator == 'is not'
|
||||||
|
|
|
@ -18,7 +18,7 @@ module ApplicationController::Authenticates
|
||||||
raise Exceptions::NotAuthorized, 'Not authorized (token)!'
|
raise Exceptions::NotAuthorized, 'Not authorized (token)!'
|
||||||
end
|
end
|
||||||
|
|
||||||
return false if current_user && current_user.permissions?(key)
|
return false if current_user&.permissions?(key)
|
||||||
raise Exceptions::NotAuthorized, 'Not authorized (user)!'
|
raise Exceptions::NotAuthorized, 'Not authorized (user)!'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,7 @@ module ApplicationController::HandlesDevices
|
||||||
if user_device_updated_at
|
if user_device_updated_at
|
||||||
# check if entry exists / only if write action
|
# check if entry exists / only if write action
|
||||||
diff = Time.zone.now - 10.minutes
|
diff = Time.zone.now - 10.minutes
|
||||||
method = request.method
|
if %w[GET OPTIONS HEAD].include?(request.method)
|
||||||
if method == 'GET' || method == 'OPTIONS' || method == 'HEAD'
|
|
||||||
diff = Time.zone.now - 30.minutes
|
diff = Time.zone.now - 30.minutes
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ module ApplicationController::HandlesErrors
|
||||||
data[:error_human] = data[:error]
|
data[:error_human] = data[:error]
|
||||||
end
|
end
|
||||||
|
|
||||||
if Rails.env.production? && !data[:error_human].empty?
|
if Rails.env.production? && data[:error_human].present?
|
||||||
data[:error] = data.delete(:error_human)
|
data[:error] = data.delete(:error_human)
|
||||||
end
|
end
|
||||||
data
|
data
|
||||||
|
|
|
@ -146,7 +146,7 @@ module ApplicationController::RendersModels
|
||||||
def model_references_check(object, params)
|
def model_references_check(object, params)
|
||||||
generic_object = object.find(params[:id])
|
generic_object = object.find(params[:id])
|
||||||
result = Models.references(object, generic_object.id)
|
result = Models.references(object, generic_object.id)
|
||||||
return false if result.empty?
|
return false if result.blank?
|
||||||
raise Exceptions::UnprocessableEntity, 'Can\'t delete, object has references.'
|
raise Exceptions::UnprocessableEntity, 'Can\'t delete, object has references.'
|
||||||
rescue => e
|
rescue => e
|
||||||
raise Exceptions::UnprocessableEntity, e
|
raise Exceptions::UnprocessableEntity, e
|
||||||
|
|
|
@ -226,7 +226,7 @@ class ChannelsEmailController < ApplicationController
|
||||||
|
|
||||||
Channel.where(area: 'Email::Notification').each do |channel|
|
Channel.where(area: 'Email::Notification').each do |channel|
|
||||||
active = false
|
active = false
|
||||||
if adapter =~ /^#{channel.options[:outbound][:adapter]}$/i
|
if adapter.match?(/^#{channel.options[:outbound][:adapter]}$/i)
|
||||||
active = true
|
active = true
|
||||||
channel.options = {
|
channel.options = {
|
||||||
outbound: {
|
outbound: {
|
||||||
|
|
|
@ -44,7 +44,7 @@ class FormController < ApplicationController
|
||||||
errors['email'] = 'required'
|
errors['email'] = 'required'
|
||||||
elsif params[:email] !~ /@/
|
elsif params[:email] !~ /@/
|
||||||
errors['email'] = 'invalid'
|
errors['email'] = 'invalid'
|
||||||
elsif params[:email] =~ /(>|<|\||\!|"|§|'|\$|%|&|\(|\)|\?|\s|\.\.)/
|
elsif params[:email].match?(/(>|<|\||\!|"|§|'|\$|%|&|\(|\)|\?|\s|\.\.)/)
|
||||||
errors['email'] = 'invalid'
|
errors['email'] = 'invalid'
|
||||||
end
|
end
|
||||||
if params[:title].blank?
|
if params[:title].blank?
|
||||||
|
@ -126,19 +126,16 @@ class FormController < ApplicationController
|
||||||
internal: false,
|
internal: false,
|
||||||
)
|
)
|
||||||
|
|
||||||
if params[:file]
|
params[:file]&.each do |file|
|
||||||
|
Store.add(
|
||||||
params[:file].each do |file|
|
object: 'Ticket::Article',
|
||||||
Store.add(
|
o_id: article.id,
|
||||||
object: 'Ticket::Article',
|
data: file.read,
|
||||||
o_id: article.id,
|
filename: file.original_filename,
|
||||||
data: file.read,
|
preferences: {
|
||||||
filename: file.original_filename,
|
'Mime-Type' => file.content_type,
|
||||||
preferences: {
|
}
|
||||||
'Mime-Type' => file.content_type,
|
)
|
||||||
}
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
UserInfo.current_user_id = 1
|
UserInfo.current_user_id = 1
|
||||||
|
|
|
@ -66,7 +66,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
|
||||||
|
|
||||||
# verify auto wizard file
|
# verify auto wizard file
|
||||||
auto_wizard_data = AutoWizard.data
|
auto_wizard_data = AutoWizard.data
|
||||||
if !auto_wizard_data || auto_wizard_data.empty?
|
if auto_wizard_data.blank?
|
||||||
render json: {
|
render json: {
|
||||||
auto_wizard: true,
|
auto_wizard: true,
|
||||||
auto_wizard_success: false,
|
auto_wizard_success: false,
|
||||||
|
@ -132,7 +132,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
|
||||||
end
|
end
|
||||||
|
|
||||||
# validate organization
|
# validate organization
|
||||||
if !params[:organization] || params[:organization].empty?
|
if params[:organization].blank?
|
||||||
messages[:organization] = 'Invalid!'
|
messages[:organization] = 'Invalid!'
|
||||||
else
|
else
|
||||||
settings[:organization] = params[:organization]
|
settings[:organization] = params[:organization]
|
||||||
|
@ -146,7 +146,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if !messages.empty?
|
if messages.present?
|
||||||
render json: {
|
render json: {
|
||||||
result: 'invalid',
|
result: 'invalid',
|
||||||
messages: messages,
|
messages: messages,
|
||||||
|
|
|
@ -26,7 +26,7 @@ class ImportOtrsController < ApplicationController
|
||||||
if !response.success? && response.code.to_s !~ /^40.$/
|
if !response.success? && response.code.to_s !~ /^40.$/
|
||||||
message_human = ''
|
message_human = ''
|
||||||
translation_map.each do |key, message|
|
translation_map.each do |key, message|
|
||||||
if response.error.to_s =~ /#{Regexp.escape(key)}/i
|
if response.error.to_s.match?(/#{Regexp.escape(key)}/i)
|
||||||
message_human = message
|
message_human = message
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -39,7 +39,7 @@ class ImportOtrsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
result = {}
|
result = {}
|
||||||
if response.body =~ /zammad migrator/
|
if response.body.match?(/zammad migrator/)
|
||||||
|
|
||||||
migrator_response = JSON.parse(response.body)
|
migrator_response = JSON.parse(response.body)
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ class ImportOtrsController < ApplicationController
|
||||||
message_human: migrator_response['Error']
|
message_human: migrator_response['Error']
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
elsif response.body =~ /(otrs\sag|otrs\.com|otrs\.org)/i
|
elsif response.body.match?(/(otrs\sag|otrs\.com|otrs\.org)/i)
|
||||||
result = {
|
result = {
|
||||||
result: 'invalid',
|
result: 'invalid',
|
||||||
message_human: 'Host found, but no OTRS migrator is installed!'
|
message_human: 'Host found, but no OTRS migrator is installed!'
|
||||||
|
@ -144,7 +144,7 @@ class ImportOtrsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
result = 'ok'
|
result = 'ok'
|
||||||
if !issues.empty?
|
if issues.present?
|
||||||
result = 'failed'
|
result = 'failed'
|
||||||
end
|
end
|
||||||
render json: {
|
render json: {
|
||||||
|
|
|
@ -28,7 +28,7 @@ class ImportZendeskController < ApplicationController
|
||||||
if !response.success?
|
if !response.success?
|
||||||
message_human = ''
|
message_human = ''
|
||||||
translation_map.each do |key, message|
|
translation_map.each do |key, message|
|
||||||
if response.error.to_s =~ /#{Regexp.escape(key)}/i
|
if response.error.to_s.match?(/#{Regexp.escape(key)}/i)
|
||||||
message_human = message
|
message_human = message
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -133,6 +133,8 @@ UserAgent: #{request.env['HTTP_USER_AGENT']}
|
||||||
if Setting.get('check_mk_token') != params[:token]
|
if Setting.get('check_mk_token') != params[:token]
|
||||||
raise Exceptions::UnprocessableEntity, 'Invalid token!'
|
raise Exceptions::UnprocessableEntity, 'Invalid token!'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class Integration::IdoitController < ApplicationController
|
class Integration::IdoitController < ApplicationController
|
||||||
prepend_before_action -> { authentication_check(permission: ['agent.integration.idoit', 'admin.integration.idoit']) }, except: [:verify, :query, :update]
|
prepend_before_action -> { authentication_check(permission: ['agent.integration.idoit', 'admin.integration.idoit']) }, except: %i[verify query update]
|
||||||
prepend_before_action -> { authentication_check(permission: ['admin.integration.idoit']) }, only: [:verify]
|
prepend_before_action -> { authentication_check(permission: ['admin.integration.idoit']) }, only: [:verify]
|
||||||
prepend_before_action -> { authentication_check(permission: ['ticket.agent']) }, only: [:query, :update]
|
prepend_before_action -> { authentication_check(permission: ['ticket.agent']) }, only: %i[query update]
|
||||||
|
|
||||||
def verify
|
def verify
|
||||||
response = ::Idoit.verify(params[:api_token], params[:endpoint], params[:client_id])
|
response = ::Idoit.verify(params[:api_token], params[:endpoint], params[:client_id])
|
||||||
|
|
|
@ -93,6 +93,8 @@ class Integration::SipgateController < ApplicationController
|
||||||
xml_error('Feature not configured, please contact your admin!')
|
xml_error('Feature not configured, please contact your admin!')
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def config_integration
|
def config_integration
|
||||||
|
|
|
@ -18,7 +18,7 @@ class LongPollingController < ApplicationController
|
||||||
params['data'] = {}
|
params['data'] = {}
|
||||||
end
|
end
|
||||||
session_data = {}
|
session_data = {}
|
||||||
if current_user && current_user.id
|
if current_user&.id
|
||||||
session_data = { 'id' => current_user.id }
|
session_data = { 'id' => current_user.id }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -61,13 +61,12 @@ class LongPollingController < ApplicationController
|
||||||
|
|
||||||
# check queue to send
|
# check queue to send
|
||||||
begin
|
begin
|
||||||
|
|
||||||
# update last ping
|
# update last ping
|
||||||
4.times do
|
4.times do
|
||||||
sleep 0.25
|
sleep 0.25
|
||||||
end
|
end
|
||||||
#sleep 1
|
#sleep 1
|
||||||
Sessions.touch(client_id)
|
Sessions.touch(client_id) # rubocop:disable Rails/SkipsModelValidations
|
||||||
|
|
||||||
# set max loop time to 24 sec. because of 30 sec. timeout of mod_proxy
|
# set max loop time to 24 sec. because of 30 sec. timeout of mod_proxy
|
||||||
count = 3
|
count = 3
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class MonitoringController < ApplicationController
|
class MonitoringController < ApplicationController
|
||||||
prepend_before_action -> { authentication_check(permission: 'admin.monitoring') }, except: [:health_check, :status]
|
prepend_before_action -> { authentication_check(permission: 'admin.monitoring') }, except: %i[health_check status]
|
||||||
skip_before_action :verify_csrf_token
|
skip_before_action :verify_csrf_token
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
@ -39,7 +39,7 @@ curl http://localhost/api/v1/monitoring/health_check?token=XXX
|
||||||
# inbound channel
|
# inbound channel
|
||||||
if channel.status_in == 'error'
|
if channel.status_in == 'error'
|
||||||
message = "Channel: #{channel.area} in "
|
message = "Channel: #{channel.area} in "
|
||||||
%w(host user uid).each do |key|
|
%w[host user uid].each do |key|
|
||||||
next if channel.options[key].blank?
|
next if channel.options[key].blank?
|
||||||
message += "key:#{channel.options[key]};"
|
message += "key:#{channel.options[key]};"
|
||||||
end
|
end
|
||||||
|
@ -52,7 +52,7 @@ curl http://localhost/api/v1/monitoring/health_check?token=XXX
|
||||||
# outbound channel
|
# outbound channel
|
||||||
next if channel.status_out != 'error'
|
next if channel.status_out != 'error'
|
||||||
message = "Channel: #{channel.area} out "
|
message = "Channel: #{channel.area} out "
|
||||||
%w(host user uid).each do |key|
|
%w[host user uid].each do |key|
|
||||||
next if channel.options[key].blank?
|
next if channel.options[key].blank?
|
||||||
message += "key:#{channel.options[key]};"
|
message += "key:#{channel.options[key]};"
|
||||||
end
|
end
|
||||||
|
@ -60,7 +60,7 @@ curl http://localhost/api/v1/monitoring/health_check?token=XXX
|
||||||
end
|
end
|
||||||
|
|
||||||
# unprocessable mail check
|
# unprocessable mail check
|
||||||
directory = "#{Rails.root}/tmp/unprocessable_mail"
|
directory = Rails.root.join('tmp', 'unprocessable_mail').to_s
|
||||||
if File.exist?(directory)
|
if File.exist?(directory)
|
||||||
count = 0
|
count = 0
|
||||||
Dir.glob("#{directory}/*.eml") do |_entry|
|
Dir.glob("#{directory}/*.eml") do |_entry|
|
||||||
|
@ -161,9 +161,7 @@ curl http://localhost/api/v1/monitoring/status?token=XXX
|
||||||
map.each do |key, class_name|
|
map.each do |key, class_name|
|
||||||
status[:counts][key] = class_name.count
|
status[:counts][key] = class_name.count
|
||||||
last = class_name.last
|
last = class_name.last
|
||||||
status[:last_created_at][key] = if last
|
status[:last_created_at][key] = last&.created_at
|
||||||
last.created_at
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: status
|
render json: status
|
||||||
|
|
|
@ -98,20 +98,20 @@ class ObjectManagerAttributesController < ApplicationController
|
||||||
private
|
private
|
||||||
|
|
||||||
def check_params
|
def check_params
|
||||||
if params[:data_type] =~ /^(boolean)$/
|
if params[:data_type].match?(/^(boolean)$/)
|
||||||
if params[:data_option][:options]
|
if params[:data_option][:options]
|
||||||
|
# rubocop:disable Lint/BooleanSymbol
|
||||||
if params[:data_option][:options][:false]
|
if params[:data_option][:options][:false]
|
||||||
params[:data_option][:options][false] = params[:data_option][:options][:false]
|
params[:data_option][:options][false] = params[:data_option][:options].delete(:false)
|
||||||
params[:data_option][:options].delete(:false)
|
|
||||||
end
|
end
|
||||||
if params[:data_option][:options][:true]
|
if params[:data_option][:options][:true]
|
||||||
params[:data_option][:options][true] = params[:data_option][:options][:true]
|
params[:data_option][:options][true] = params[:data_option][:options].delete(:true)
|
||||||
params[:data_option][:options].delete(:true)
|
|
||||||
end
|
end
|
||||||
|
# rubocop:enable Lint/BooleanSymbol
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if params[:data_option] && !params[:data_option].key?(:default)
|
if params[:data_option] && !params[:data_option].key?(:default)
|
||||||
params[:data_option][:default] = if params[:data_type] =~ /^(input|select|tree_select)$/
|
params[:data_option][:default] = if params[:data_type].match?(/^(input|select|tree_select)$/)
|
||||||
''
|
''
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -237,12 +237,16 @@ curl http://localhost/api/v1/organization/{id} -v -u #{login}:#{password} -H "Co
|
||||||
params[:limit].to_i = 500
|
params[:limit].to_i = 500
|
||||||
end
|
end
|
||||||
|
|
||||||
|
query = params[:query]
|
||||||
|
if query.respond_to?(:permit!)
|
||||||
|
query = query.permit!.to_h
|
||||||
|
end
|
||||||
query_params = {
|
query_params = {
|
||||||
query: params[:query],
|
query: query,
|
||||||
limit: params[:limit],
|
limit: params[:limit],
|
||||||
current_user: current_user,
|
current_user: current_user,
|
||||||
}
|
}
|
||||||
if params[:role_ids] && !params[:role_ids].empty?
|
if params[:role_ids].present?
|
||||||
query_params[:role_ids] = params[:role_ids]
|
query_params[:role_ids] = params[:role_ids]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ Example:
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
Resource:
|
Resource:
|
||||||
GET /api/v1/overviews.json
|
GET /api/v1/overviews
|
||||||
|
|
||||||
Response:
|
Response:
|
||||||
[
|
[
|
||||||
|
@ -47,7 +47,7 @@ Response:
|
||||||
]
|
]
|
||||||
|
|
||||||
Test:
|
Test:
|
||||||
curl http://localhost/api/v1/overviews.json -v -u #{login}:#{password}
|
curl http://localhost/api/v1/overviews -v -u #{login}:#{password}
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ curl http://localhost/api/v1/overviews.json -v -u #{login}:#{password}
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
Resource:
|
Resource:
|
||||||
GET /api/v1/overviews/#{id}.json
|
GET /api/v1/overviews/#{id}
|
||||||
|
|
||||||
Response:
|
Response:
|
||||||
{
|
{
|
||||||
|
@ -68,7 +68,7 @@ Response:
|
||||||
}
|
}
|
||||||
|
|
||||||
Test:
|
Test:
|
||||||
curl http://localhost/api/v1/overviews/#{id}.json -v -u #{login}:#{password}
|
curl http://localhost/api/v1/overviews/#{id} -v -u #{login}:#{password}
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ curl http://localhost/api/v1/overviews/#{id}.json -v -u #{login}:#{password}
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
Resource:
|
Resource:
|
||||||
POST /api/v1/overviews.json
|
POST /api/v1/overviews
|
||||||
|
|
||||||
Payload:
|
Payload:
|
||||||
{
|
{
|
||||||
|
@ -101,7 +101,7 @@ Response:
|
||||||
}
|
}
|
||||||
|
|
||||||
Test:
|
Test:
|
||||||
curl http://localhost/api/v1/overviews.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"name": "some_name","active": true, "note": "some note"}'
|
curl http://localhost/api/v1/overviews -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"name": "some_name","active": true, "note": "some note"}'
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ curl http://localhost/api/v1/overviews.json -v -u #{login}:#{password} -H "Conte
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
Resource:
|
Resource:
|
||||||
PUT /api/v1/overviews/{id}.json
|
PUT /api/v1/overviews/{id}
|
||||||
|
|
||||||
Payload:
|
Payload:
|
||||||
{
|
{
|
||||||
|
@ -134,7 +134,7 @@ Response:
|
||||||
}
|
}
|
||||||
|
|
||||||
Test:
|
Test:
|
||||||
curl http://localhost/api/v1/overviews.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X PUT -d '{"name": "some_name","active": true, "note": "some note"}'
|
curl http://localhost/api/v1/overviews -v -u #{login}:#{password} -H "Content-Type: application/json" -X PUT -d '{"name": "some_name","active": true, "note": "some note"}'
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
||||||
|
@ -145,17 +145,55 @@ curl http://localhost/api/v1/overviews.json -v -u #{login}:#{password} -H "Conte
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
Resource:
|
Resource:
|
||||||
DELETE /api/v1/overviews/{id}.json
|
DELETE /api/v1/overviews/{id}
|
||||||
|
|
||||||
Response:
|
Response:
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Test:
|
Test:
|
||||||
curl http://localhost/api/v1/overviews/#{id}.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X DELETE
|
curl http://localhost/api/v1/overviews/#{id} -v -u #{login}:#{password} -H "Content-Type: application/json" -X DELETE
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
model_destroy_render(Overview, params)
|
model_destroy_render(Overview, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
Resource:
|
||||||
|
POST /api/v1/overviews_prio
|
||||||
|
|
||||||
|
Payload:
|
||||||
|
{
|
||||||
|
"prios": [
|
||||||
|
[overview_id, prio],
|
||||||
|
[overview_id, prio],
|
||||||
|
[overview_id, prio],
|
||||||
|
[overview_id, prio],
|
||||||
|
[overview_id, prio]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Response:
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
}
|
||||||
|
|
||||||
|
Test:
|
||||||
|
curl http://localhost/api/v1/overviews_prio -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"prios": [ [1,1], [44,2] ]}'
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def prio
|
||||||
|
Overview.without_callback(:update, :before, :rearrangement) do
|
||||||
|
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
|
||||||
|
end
|
||||||
|
render json: { success: true }, status: :ok
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,6 +16,9 @@ class SearchController < ApplicationController
|
||||||
|
|
||||||
# get params
|
# get params
|
||||||
query = params[:query]
|
query = params[:query]
|
||||||
|
if query.respond_to?(:permit!)
|
||||||
|
query = query.permit!.to_h
|
||||||
|
end
|
||||||
limit = params[:limit] || 10
|
limit = params[:limit] || 10
|
||||||
|
|
||||||
# convert objects string into array of class names
|
# convert objects string into array of class names
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class SessionsController < ApplicationController
|
class SessionsController < ApplicationController
|
||||||
prepend_before_action :authentication_check, only: [:switch_to_user, :list, :delete]
|
prepend_before_action :authentication_check, only: %i[switch_to_user list delete]
|
||||||
skip_before_action :verify_csrf_token, only: [:create, :show, :destroy, :create_omniauth, :create_sso]
|
skip_before_action :verify_csrf_token, only: %i[create show destroy create_omniauth create_sso]
|
||||||
|
|
||||||
# "Create" a login, aka "log the user in"
|
# "Create" a login, aka "log the user in"
|
||||||
def create
|
def create
|
||||||
|
|
|
@ -93,11 +93,11 @@ class SettingsController < ApplicationController
|
||||||
|
|
||||||
def keep_certain_attributes
|
def keep_certain_attributes
|
||||||
setting = Setting.find(params[:id])
|
setting = Setting.find(params[:id])
|
||||||
[:name, :area, :state_initial, :frontend, :options].each do |key|
|
%i[name area state_initial frontend options].each do |key|
|
||||||
params.delete(key)
|
params.delete(key)
|
||||||
end
|
end
|
||||||
if !params[:preferences].empty?
|
if params[:preferences].present?
|
||||||
[:online_service_disable, :permission, :render].each do |key|
|
%i[online_service_disable permission render].each do |key|
|
||||||
params[:preferences].delete(key)
|
params[:preferences].delete(key)
|
||||||
end
|
end
|
||||||
params[:preferences].merge!(setting.preferences)
|
params[:preferences].merge!(setting.preferences)
|
||||||
|
|
|
@ -266,7 +266,7 @@ class TicketArticlesController < ApplicationController
|
||||||
|
|
||||||
def sanitized_disposition
|
def sanitized_disposition
|
||||||
disposition = params.fetch(:disposition, 'inline')
|
disposition = params.fetch(:disposition, 'inline')
|
||||||
valid_disposition = %w(inline attachment)
|
valid_disposition = %w[inline attachment]
|
||||||
return disposition if valid_disposition.include?(disposition)
|
return disposition if valid_disposition.include?(disposition)
|
||||||
raise Exceptions::NotAuthorized, "Invalid disposition #{disposition} requested. Only #{valid_disposition.join(', ')} are valid."
|
raise Exceptions::NotAuthorized, "Invalid disposition #{disposition} requested. Only #{valid_disposition.join(', ')} are valid."
|
||||||
end
|
end
|
||||||
|
|
|
@ -80,7 +80,7 @@ class TicketsController < ApplicationController
|
||||||
|
|
||||||
# overwrite params
|
# overwrite params
|
||||||
if !current_user.permissions?('ticket.agent')
|
if !current_user.permissions?('ticket.agent')
|
||||||
[:owner, :owner_id, :customer, :customer_id, :organization, :organization_id, :preferences].each do |key|
|
%i[owner owner_id customer customer_id organization organization_id preferences].each do |key|
|
||||||
clean_params.delete(key)
|
clean_params.delete(key)
|
||||||
end
|
end
|
||||||
clean_params[:customer_id] = current_user.id
|
clean_params[:customer_id] = current_user.id
|
||||||
|
@ -186,7 +186,7 @@ class TicketsController < ApplicationController
|
||||||
|
|
||||||
# overwrite params
|
# overwrite params
|
||||||
if !current_user.permissions?('ticket.agent')
|
if !current_user.permissions?('ticket.agent')
|
||||||
[:owner, :owner_id, :customer, :customer_id, :organization, :organization_id, :preferences].each do |key|
|
%i[owner owner_id customer customer_id organization organization_id preferences].each do |key|
|
||||||
clean_params.delete(key)
|
clean_params.delete(key)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -270,7 +270,7 @@ class TicketsController < ApplicationController
|
||||||
.limit(6)
|
.limit(6)
|
||||||
|
|
||||||
# if we do not have open related tickets, search for any tickets
|
# if we do not have open related tickets, search for any tickets
|
||||||
if ticket_lists.empty?
|
if ticket_lists.blank?
|
||||||
ticket_lists = Ticket
|
ticket_lists = Ticket
|
||||||
.where(
|
.where(
|
||||||
customer_id: ticket.customer_id,
|
customer_id: ticket.customer_id,
|
||||||
|
@ -389,11 +389,16 @@ class TicketsController < ApplicationController
|
||||||
params[:limit].to_i = 100
|
params[:limit].to_i = 100
|
||||||
end
|
end
|
||||||
|
|
||||||
|
query = params[:query]
|
||||||
|
if query.respond_to?(:permit!)
|
||||||
|
query = query.permit!.to_h
|
||||||
|
end
|
||||||
|
|
||||||
# build result list
|
# build result list
|
||||||
tickets = Ticket.search(
|
tickets = Ticket.search(
|
||||||
|
query: query,
|
||||||
|
condition: params[:condition].to_h,
|
||||||
limit: params[:limit],
|
limit: params[:limit],
|
||||||
query: params[:query],
|
|
||||||
condition: params[:condition],
|
|
||||||
current_user: current_user,
|
current_user: current_user,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -435,11 +440,9 @@ class TicketsController < ApplicationController
|
||||||
|
|
||||||
assets = {}
|
assets = {}
|
||||||
ticket_ids = []
|
ticket_ids = []
|
||||||
if tickets
|
tickets&.each do |ticket|
|
||||||
tickets.each do |ticket|
|
ticket_ids.push ticket.id
|
||||||
ticket_ids.push ticket.id
|
assets = ticket.assets(assets)
|
||||||
assets = ticket.assets(assets)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# return result
|
# return result
|
||||||
|
@ -504,7 +507,7 @@ class TicketsController < ApplicationController
|
||||||
|
|
||||||
# lookup open org tickets
|
# lookup open org tickets
|
||||||
org_tickets = {}
|
org_tickets = {}
|
||||||
if params[:organization_id] && !params[:organization_id].empty?
|
if params[:organization_id].present?
|
||||||
organization = Organization.lookup(id: params[:organization_id])
|
organization = Organization.lookup(id: params[:organization_id])
|
||||||
if !organization
|
if !organization
|
||||||
raise "No such organization with id #{params[:organization_id]}"
|
raise "No such organization with id #{params[:organization_id]}"
|
||||||
|
|
|
@ -164,7 +164,7 @@ class TimeAccountingsController < ApplicationController
|
||||||
]
|
]
|
||||||
result = []
|
result = []
|
||||||
results.each do |row|
|
results.each do |row|
|
||||||
row[:ticket].keys.each do |field|
|
row[:ticket].each_key do |field|
|
||||||
next if row[:ticket][field].blank?
|
next if row[:ticket][field].blank?
|
||||||
next if !row[:ticket][field].is_a?(ActiveSupport::TimeWithZone)
|
next if !row[:ticket][field].is_a?(ActiveSupport::TimeWithZone)
|
||||||
|
|
||||||
|
@ -250,7 +250,7 @@ class TimeAccountingsController < ApplicationController
|
||||||
customers[ticket.customer_id][:time_unit] += local_time_unit[:time_unit]
|
customers[ticket.customer_id][:time_unit] += local_time_unit[:time_unit]
|
||||||
end
|
end
|
||||||
results = []
|
results = []
|
||||||
customers.each do |_customer_id, content|
|
customers.each_value do |content|
|
||||||
results.push content
|
results.push content
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -326,7 +326,7 @@ class TimeAccountingsController < ApplicationController
|
||||||
organizations[ticket.organization_id][:time_unit] += local_time_unit[:time_unit]
|
organizations[ticket.organization_id][:time_unit] += local_time_unit[:time_unit]
|
||||||
end
|
end
|
||||||
results = []
|
results = []
|
||||||
organizations.each do |_customer_id, content|
|
organizations.each_value do |content|
|
||||||
results.push content
|
results.push content
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ class UserAccessTokenController < ApplicationController
|
||||||
end
|
end
|
||||||
local_permissions = current_user.permissions
|
local_permissions = current_user.permissions
|
||||||
local_permissions_new = {}
|
local_permissions_new = {}
|
||||||
local_permissions.each do |key, _value|
|
local_permissions.each_key do |key|
|
||||||
keys = Object.const_get('Permission').with_parents(key)
|
keys = Object.const_get('Permission').with_parents(key)
|
||||||
keys.each do |local_key|
|
keys.each do |local_key|
|
||||||
next if local_permissions_new.key?([local_key])
|
next if local_permissions_new.key?([local_key])
|
||||||
|
|
|
@ -8,7 +8,7 @@ class UserDevicesController < ApplicationController
|
||||||
devices_full = []
|
devices_full = []
|
||||||
devices.each do |device|
|
devices.each do |device|
|
||||||
attributes = device.attributes
|
attributes = device.attributes
|
||||||
if device.location_details['city_name'] && !device.location_details['city_name'].empty?
|
if device.location_details['city_name'].present?
|
||||||
attributes['location'] += ", #{device.location_details['city_name']}"
|
attributes['location'] += ", #{device.location_details['city_name']}"
|
||||||
end
|
end
|
||||||
attributes.delete('created_at')
|
attributes.delete('created_at')
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class UsersController < ApplicationController
|
class UsersController < ApplicationController
|
||||||
prepend_before_action :authentication_check, except: [:create, :password_reset_send, :password_reset_verify, :image]
|
prepend_before_action :authentication_check, except: %i[create password_reset_send password_reset_verify image]
|
||||||
prepend_before_action :authentication_check_only, only: [:create]
|
prepend_before_action :authentication_check_only, only: [:create]
|
||||||
|
|
||||||
# @path [GET] /users
|
# @path [GET] /users
|
||||||
|
@ -145,7 +145,7 @@ class UsersController < ApplicationController
|
||||||
group_ids = []
|
group_ids = []
|
||||||
role_ids = []
|
role_ids = []
|
||||||
if count <= 2
|
if count <= 2
|
||||||
Role.where(name: %w(Admin Agent)).each do |role|
|
Role.where(name: %w[Admin Agent]).each do |role|
|
||||||
role_ids.push role.id
|
role_ids.push role.id
|
||||||
end
|
end
|
||||||
Group.all().each do |group|
|
Group.all().each do |group|
|
||||||
|
@ -363,12 +363,17 @@ class UsersController < ApplicationController
|
||||||
params[:limit].to_i = 500
|
params[:limit].to_i = 500
|
||||||
end
|
end
|
||||||
|
|
||||||
|
query = params[:query]
|
||||||
|
if query.respond_to?(:permit!)
|
||||||
|
query = query.permit!.to_h
|
||||||
|
end
|
||||||
|
|
||||||
query_params = {
|
query_params = {
|
||||||
query: params[:query],
|
query: query,
|
||||||
limit: params[:limit],
|
limit: params[:limit],
|
||||||
current_user: current_user,
|
current_user: current_user,
|
||||||
}
|
}
|
||||||
[:role_ids, :permissions].each do |key|
|
%i[role_ids permissions].each do |key|
|
||||||
next if params[key].blank?
|
next if params[key].blank?
|
||||||
query_params[key] = params[key]
|
query_params[key] = params[key]
|
||||||
end
|
end
|
||||||
|
@ -1046,7 +1051,7 @@ curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content
|
||||||
def permission_check_by_permission(params)
|
def permission_check_by_permission(params)
|
||||||
return true if current_user.permissions?('admin.user')
|
return true if current_user.permissions?('admin.user')
|
||||||
|
|
||||||
%i(role_ids roles).each do |key|
|
%i[role_ids roles].each do |key|
|
||||||
next if !params[key]
|
next if !params[key]
|
||||||
if current_user.permissions?('ticket.agent')
|
if current_user.permissions?('ticket.agent')
|
||||||
params.delete(key)
|
params.delete(key)
|
||||||
|
@ -1059,7 +1064,7 @@ curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content
|
||||||
params[:role_ids] = Role.signup_role_ids
|
params[:role_ids] = Role.signup_role_ids
|
||||||
end
|
end
|
||||||
|
|
||||||
%i(group_ids groups).each do |key|
|
%i[group_ids groups].each do |key|
|
||||||
next if !params[key]
|
next if !params[key]
|
||||||
if current_user.permissions?('ticket.agent')
|
if current_user.permissions?('ticket.agent')
|
||||||
params.delete(key)
|
params.delete(key)
|
||||||
|
|
|
@ -99,7 +99,7 @@ return all activity entries of an user
|
||||||
permission_ids = user.permissions_with_child_ids
|
permission_ids = user.permissions_with_child_ids
|
||||||
group_ids = user.group_ids_access('read')
|
group_ids = user.group_ids_access('read')
|
||||||
|
|
||||||
stream = if group_ids.empty?
|
stream = if group_ids.blank?
|
||||||
ActivityStream.where('(permission_id IN (?) AND group_id is NULL)', permission_ids)
|
ActivityStream.where('(permission_id IN (?) AND group_id is NULL)', permission_ids)
|
||||||
.order('created_at DESC, id DESC')
|
.order('created_at DESC, id DESC')
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
|
|
|
@ -33,7 +33,7 @@ returns
|
||||||
|
|
||||||
return data if !self['created_by_id'] && !self['updated_by_id']
|
return data if !self['created_by_id'] && !self['updated_by_id']
|
||||||
app_model_user = User.to_app_model
|
app_model_user = User.to_app_model
|
||||||
%w(created_by_id updated_by_id).each do |local_user_id|
|
%w[created_by_id updated_by_id].each do |local_user_id|
|
||||||
next if !self[ local_user_id ]
|
next if !self[ local_user_id ]
|
||||||
next if data[ app_model_user ] && data[ app_model_user ][ 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 ])
|
user = User.lookup(id: self[ local_user_id ])
|
||||||
|
@ -75,12 +75,12 @@ get assets and record_ids of selector
|
||||||
attribute_ref_class = models[attribute_class][:reflections][reflection].klass
|
attribute_ref_class = models[attribute_class][:reflections][reflection].klass
|
||||||
if content['value'].instance_of?(Array)
|
if content['value'].instance_of?(Array)
|
||||||
content['value'].each do |item_id|
|
content['value'].each do |item_id|
|
||||||
attribute_object = attribute_ref_class.find_by(id: item_id)
|
next if item_id.blank?
|
||||||
if attribute_object
|
attribute_object = attribute_ref_class.lookup(id: item_id)
|
||||||
assets = attribute_object.assets(assets)
|
next if !attribute_object
|
||||||
end
|
assets = attribute_object.assets(assets)
|
||||||
end
|
end
|
||||||
else
|
elsif content['value'].present?
|
||||||
attribute_object = attribute_ref_class.find_by(id: content['value'])
|
attribute_object = attribute_ref_class.find_by(id: content['value'])
|
||||||
if attribute_object
|
if attribute_object
|
||||||
assets = attribute_object.assets(assets)
|
assets = attribute_object.assets(assets)
|
||||||
|
@ -138,11 +138,11 @@ get assets of object list
|
||||||
require item['object'].to_filename
|
require item['object'].to_filename
|
||||||
record = Kernel.const_get(item['object']).find(item['o_id'])
|
record = Kernel.const_get(item['object']).find(item['o_id'])
|
||||||
assets = record.assets(assets)
|
assets = record.assets(assets)
|
||||||
if item['created_by_id']
|
if item['created_by_id'].present?
|
||||||
user = User.find(item['created_by_id'])
|
user = User.find(item['created_by_id'])
|
||||||
assets = user.assets(assets)
|
assets = user.assets(assets)
|
||||||
end
|
end
|
||||||
if item['updated_by_id']
|
if item['updated_by_id'].present?
|
||||||
user = User.find(item['updated_by_id'])
|
user = User.find(item['updated_by_id'])
|
||||||
assets = user.assets(assets)
|
assets = user.assets(assets)
|
||||||
end
|
end
|
||||||
|
|
|
@ -109,7 +109,7 @@ returns
|
||||||
return cache if cache
|
return cache if cache
|
||||||
|
|
||||||
attributes = self.attributes
|
attributes = self.attributes
|
||||||
relevant = %i(has_and_belongs_to_many has_many)
|
relevant = %i[has_and_belongs_to_many has_many]
|
||||||
eager_load = []
|
eager_load = []
|
||||||
pluck = []
|
pluck = []
|
||||||
keys = []
|
keys = []
|
||||||
|
@ -180,7 +180,7 @@ returns
|
||||||
next if !item[:name]
|
next if !item[:name]
|
||||||
attributes[assoc.name.to_s].push item[:name]
|
attributes[assoc.name.to_s].push item[:name]
|
||||||
end
|
end
|
||||||
if ref.count.positive? && attributes[assoc.name.to_s].empty?
|
if ref.count.positive? && attributes[assoc.name.to_s].blank?
|
||||||
attributes.delete(assoc.name.to_s)
|
attributes.delete(assoc.name.to_s)
|
||||||
end
|
end
|
||||||
next
|
next
|
||||||
|
@ -216,7 +216,7 @@ returns
|
||||||
|
|
||||||
def filter_attributes(attributes)
|
def filter_attributes(attributes)
|
||||||
# remove forbitten attributes
|
# remove forbitten attributes
|
||||||
%w(password token tokens token_ids).each do |item|
|
%w[password token tokens token_ids].each do |item|
|
||||||
attributes.delete(item)
|
attributes.delete(item)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -237,7 +237,7 @@ returns
|
||||||
def association_id_validation(attribute_id, value)
|
def association_id_validation(attribute_id, value)
|
||||||
return true if value.nil?
|
return true if value.nil?
|
||||||
|
|
||||||
attributes.each do |key, _value|
|
attributes.each_key do |key|
|
||||||
next if key != attribute_id
|
next if key != attribute_id
|
||||||
|
|
||||||
# check if id is assigned
|
# check if id is assigned
|
||||||
|
@ -339,16 +339,15 @@ returns
|
||||||
class_object = assoc.klass
|
class_object = assoc.klass
|
||||||
lookup = nil
|
lookup = nil
|
||||||
if class_object == User
|
if class_object == User
|
||||||
if value.instance_of?(String)
|
if !value.instance_of?(String)
|
||||||
if !lookup
|
|
||||||
lookup = class_object.lookup(login: value)
|
|
||||||
end
|
|
||||||
if !lookup
|
|
||||||
lookup = class_object.lookup(email: value)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
raise ArgumentError, "String is needed as ref value #{value.inspect} for '#{assoc_name}'"
|
raise ArgumentError, "String is needed as ref value #{value.inspect} for '#{assoc_name}'"
|
||||||
end
|
end
|
||||||
|
if !lookup
|
||||||
|
lookup = class_object.lookup(login: value)
|
||||||
|
end
|
||||||
|
if !lookup
|
||||||
|
lookup = class_object.lookup(email: value)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
lookup = class_object.lookup(name: value)
|
lookup = class_object.lookup(name: value)
|
||||||
end
|
end
|
||||||
|
@ -367,7 +366,7 @@ returns
|
||||||
end
|
end
|
||||||
|
|
||||||
next if !value.instance_of?(Array)
|
next if !value.instance_of?(Array)
|
||||||
next if value.empty?
|
next if value.blank?
|
||||||
next if !value[0].instance_of?(String)
|
next if !value[0].instance_of?(String)
|
||||||
|
|
||||||
# handle _ids values
|
# handle _ids values
|
||||||
|
@ -383,16 +382,15 @@ returns
|
||||||
value.each do |item|
|
value.each do |item|
|
||||||
lookup = nil
|
lookup = nil
|
||||||
if class_object == User
|
if class_object == User
|
||||||
if item.instance_of?(String)
|
if !item.instance_of?(String)
|
||||||
if !lookup
|
|
||||||
lookup = class_object.lookup(login: item)
|
|
||||||
end
|
|
||||||
if !lookup
|
|
||||||
lookup = class_object.lookup(email: item)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
raise ArgumentError, "String is needed in array ref as ref value #{value.inspect} for '#{assoc_name}'"
|
raise ArgumentError, "String is needed in array ref as ref value #{value.inspect} for '#{assoc_name}'"
|
||||||
end
|
end
|
||||||
|
if !lookup
|
||||||
|
lookup = class_object.lookup(login: item)
|
||||||
|
end
|
||||||
|
if !lookup
|
||||||
|
lookup = class_object.lookup(email: item)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
lookup = class_object.lookup(name: item)
|
lookup = class_object.lookup(name: item)
|
||||||
end
|
end
|
||||||
|
|
|
@ -43,7 +43,7 @@ returns
|
||||||
|
|
||||||
# only use object attributes
|
# only use object attributes
|
||||||
clean_params = {}
|
clean_params = {}
|
||||||
new.attributes.each do |attribute, _value|
|
new.attributes.each_key do |attribute|
|
||||||
next if !data.key?(attribute.to_sym)
|
next if !data.key?(attribute.to_sym)
|
||||||
|
|
||||||
# check reference records, referenced by _id attributes
|
# check reference records, referenced by _id attributes
|
||||||
|
@ -80,7 +80,7 @@ returns
|
||||||
def filter_unused_params(data)
|
def filter_unused_params(data)
|
||||||
|
|
||||||
# we do want to set this via database
|
# we do want to set this via database
|
||||||
[:action, :controller, :updated_at, :created_at, :updated_by_id, :created_by_id, :updated_by, :created_by].each do |key|
|
%i[action controller updated_at created_at updated_by_id created_by_id updated_by created_by].each do |key|
|
||||||
data.delete(key)
|
data.delete(key)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -123,8 +123,8 @@ returns
|
||||||
return record
|
return record
|
||||||
end
|
end
|
||||||
record = new(data)
|
record = new(data)
|
||||||
record.save
|
record.save!
|
||||||
return record
|
record
|
||||||
elsif data[:name]
|
elsif data[:name]
|
||||||
|
|
||||||
# do lookup with == to handle case insensitive databases
|
# do lookup with == to handle case insensitive databases
|
||||||
|
@ -140,8 +140,8 @@ returns
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
record = new(data)
|
record = new(data)
|
||||||
record.save
|
record.save!
|
||||||
return record
|
record
|
||||||
elsif data[:login]
|
elsif data[:login]
|
||||||
|
|
||||||
# do lookup with == to handle case insensitive databases
|
# do lookup with == to handle case insensitive databases
|
||||||
|
@ -157,8 +157,8 @@ returns
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
record = new(data)
|
record = new(data)
|
||||||
record.save
|
record.save!
|
||||||
return record
|
record
|
||||||
elsif data[:email]
|
elsif data[:email]
|
||||||
|
|
||||||
# do lookup with == to handle case insensitive databases
|
# do lookup with == to handle case insensitive databases
|
||||||
|
@ -174,8 +174,8 @@ returns
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
record = new(data)
|
record = new(data)
|
||||||
record.save
|
record.save!
|
||||||
return record
|
record
|
||||||
elsif data[:locale]
|
elsif data[:locale]
|
||||||
|
|
||||||
# do lookup with == to handle case insensitive databases
|
# do lookup with == to handle case insensitive databases
|
||||||
|
@ -191,8 +191,8 @@ returns
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
record = new(data)
|
record = new(data)
|
||||||
record.save
|
record.save!
|
||||||
return record
|
record
|
||||||
else
|
else
|
||||||
raise ArgumentError, 'Need name, login, email or locale for create_or_update()'
|
raise ArgumentError, 'Need name, login, email or locale for create_or_update()'
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,7 +21,7 @@ touch references by params
|
||||||
object_class = Kernel.const_get(data[:object])
|
object_class = Kernel.const_get(data[:object])
|
||||||
object = object_class.lookup(id: data[:o_id])
|
object = object_class.lookup(id: data[:o_id])
|
||||||
return if !object
|
return if !object
|
||||||
object.touch
|
object.touch # rubocop:disable Rails/SkipsModelValidations
|
||||||
rescue => e
|
rescue => e
|
||||||
logger.error e
|
logger.error e
|
||||||
end
|
end
|
||||||
|
|
|
@ -37,7 +37,7 @@ store attachments for this object
|
||||||
self.attachments_buffer = attachments
|
self.attachments_buffer = attachments
|
||||||
|
|
||||||
# update if object already exists
|
# update if object already exists
|
||||||
return if !(id && id.nonzero?)
|
return if !(id&.nonzero?)
|
||||||
|
|
||||||
attachments_buffer_check
|
attachments_buffer_check
|
||||||
end
|
end
|
||||||
|
|
|
@ -90,7 +90,7 @@ class Authorization < ApplicationModel
|
||||||
|
|
||||||
def delete_user_cache
|
def delete_user_cache
|
||||||
return if !user
|
return if !user
|
||||||
user.touch
|
user.touch # rubocop:disable Rails/SkipsModelValidations
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -105,16 +105,16 @@ add avatar by url
|
||||||
|
|
||||||
# fetch image based on http url
|
# fetch image based on http url
|
||||||
if data[:url].present?
|
if data[:url].present?
|
||||||
if data[:url] =~ /^http/
|
if data[:url].match?(/^http/)
|
||||||
|
|
||||||
# check if source ist already updated within last 2 minutes
|
# check if source ist already updated within last 2 minutes
|
||||||
if avatar_already_exists && avatar_already_exists.source_url == data[:url]
|
if avatar_already_exists&.source_url == data[:url]
|
||||||
return if avatar_already_exists.updated_at > 2.minutes.ago
|
return if avatar_already_exists.updated_at > 2.minutes.ago
|
||||||
end
|
end
|
||||||
|
|
||||||
# twitter workaround to get bigger avatar images
|
# twitter workaround to get bigger avatar images
|
||||||
# see also https://dev.twitter.com/overview/general/user-profile-images-and-banners
|
# see also https://dev.twitter.com/overview/general/user-profile-images-and-banners
|
||||||
if data[:url] =~ %r{//pbs.twimg.com/}i
|
if data[:url].match?(%r{//pbs.twimg.com/}i)
|
||||||
data[:url].sub!(/normal\.(png|jpg|gif)$/, 'bigger.\1')
|
data[:url].sub!(/normal\.(png|jpg|gif)$/, 'bigger.\1')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -134,10 +134,10 @@ add avatar by url
|
||||||
end
|
end
|
||||||
logger.info "Fetchd image '#{data[:url]}', http code: #{response.code}"
|
logger.info "Fetchd image '#{data[:url]}', http code: #{response.code}"
|
||||||
mime_type = 'image'
|
mime_type = 'image'
|
||||||
if data[:url] =~ /\.png/i
|
if data[:url].match?(/\.png/i)
|
||||||
mime_type = 'image/png'
|
mime_type = 'image/png'
|
||||||
end
|
end
|
||||||
if data[:url] =~ /\.(jpg|jpeg)/i
|
if data[:url].match?(/\.(jpg|jpeg)/i)
|
||||||
mime_type = 'image/jpeg'
|
mime_type = 'image/jpeg'
|
||||||
end
|
end
|
||||||
if !data[:resize]
|
if !data[:resize]
|
||||||
|
@ -150,10 +150,10 @@ add avatar by url
|
||||||
data[:full][:mime_type] = mime_type
|
data[:full][:mime_type] = mime_type
|
||||||
|
|
||||||
# try zammad backend to find image based on email
|
# try zammad backend to find image based on email
|
||||||
elsif data[:url] =~ /@/
|
elsif data[:url].match?(/@/)
|
||||||
|
|
||||||
# check if source ist already updated within last 3 minutes
|
# check if source ist already updated within last 3 minutes
|
||||||
if avatar_already_exists && avatar_already_exists.source_url == data[:url]
|
if avatar_already_exists&.source_url == data[:url]
|
||||||
return if avatar_already_exists.updated_at > 2.minutes.ago
|
return if avatar_already_exists.updated_at > 2.minutes.ago
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -170,8 +170,8 @@ add avatar by url
|
||||||
# check if avatar need to be updated
|
# check if avatar need to be updated
|
||||||
if data[:resize].present? && data[:resize][:content].present?
|
if data[:resize].present? && data[:resize][:content].present?
|
||||||
record[:store_hash] = Digest::MD5.hexdigest(data[:resize][:content])
|
record[:store_hash] = Digest::MD5.hexdigest(data[:resize][:content])
|
||||||
if avatar_already_exists && avatar_already_exists.store_hash == record[:store_hash]
|
if avatar_already_exists&.store_hash == record[:store_hash]
|
||||||
avatar_already_exists.touch
|
avatar_already_exists.touch # rubocop:disable Rails/SkipsModelValidations
|
||||||
return avatar_already_exists
|
return avatar_already_exists
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -83,11 +83,11 @@ returns
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def self.ical_feeds
|
def self.ical_feeds
|
||||||
data = YAML.load_file(Rails.root.join('config/holiday_calendars.yml'))
|
data = YAML.load_file(Rails.root.join('config', 'holiday_calendars.yml'))
|
||||||
url = data['url']
|
url = data['url']
|
||||||
|
|
||||||
data['countries'].map do |country, domain|
|
data['countries'].map do |country, domain|
|
||||||
[(url % { domain: domain }), country]
|
[format(url, domain: domain), country]
|
||||||
end.to_h
|
end.to_h
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ returns
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.fetch_parse(location)
|
def self.fetch_parse(location)
|
||||||
if location =~ /^http/i
|
if location.match?(/^http/i)
|
||||||
result = UserAgent.get(location)
|
result = UserAgent.get(location)
|
||||||
if !result.success?
|
if !result.success?
|
||||||
raise result.error
|
raise result.error
|
||||||
|
@ -257,7 +257,7 @@ returns
|
||||||
end
|
end
|
||||||
|
|
||||||
# ignore daylight saving time entries
|
# ignore daylight saving time entries
|
||||||
return if comment =~ /(daylight saving|sommerzeit|summertime)/i
|
return if comment.match?(/(daylight saving|sommerzeit|summertime)/i)
|
||||||
[day, comment]
|
[day, comment]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,6 @@ fetch one account
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
# we need to require each channel backend individually otherwise we get a
|
# we need to require each channel backend individually otherwise we get a
|
||||||
# 'warning: toplevel constant Twitter referenced by Channel::Driver::Twitter' error e.g.
|
# 'warning: toplevel constant Twitter referenced by Channel::Driver::Twitter' error e.g.
|
||||||
# so we have to convert the channel name to the filename via Rails String.underscore
|
# so we have to convert the channel name to the filename via Rails String.underscore
|
||||||
|
@ -94,7 +93,6 @@ stream instance of account
|
||||||
adapter = options[:adapter]
|
adapter = options[:adapter]
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
# we need to require each channel backend individually otherwise we get a
|
# we need to require each channel backend individually otherwise we get a
|
||||||
# 'warning: toplevel constant Twitter referenced by Channel::Driver::Twitter' error e.g.
|
# 'warning: toplevel constant Twitter referenced by Channel::Driver::Twitter' error e.g.
|
||||||
# so we have to convert the channel name to the filename via Rails String.underscore
|
# so we have to convert the channel name to the filename via Rails String.underscore
|
||||||
|
@ -264,7 +262,6 @@ send via account
|
||||||
result = nil
|
result = nil
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
# we need to require each channel backend individually otherwise we get a
|
# we need to require each channel backend individually otherwise we get a
|
||||||
# 'warning: toplevel constant Twitter referenced by Channel::Driver::Twitter' error e.g.
|
# 'warning: toplevel constant Twitter referenced by Channel::Driver::Twitter' error e.g.
|
||||||
# so we have to convert the channel name to the filename via Rails String.underscore
|
# so we have to convert the channel name to the filename via Rails String.underscore
|
||||||
|
|
|
@ -40,7 +40,7 @@ returns
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if !access
|
if !access
|
||||||
%w(inbound outbound).each do |key|
|
%w[inbound outbound].each do |key|
|
||||||
if attributes['options'] && attributes['options'][key] && attributes['options'][key]['options']
|
if attributes['options'] && attributes['options'][key] && attributes['options'][key]['options']
|
||||||
attributes['options'][key]['options'].delete('password')
|
attributes['options'][key]['options'].delete('password')
|
||||||
end
|
end
|
||||||
|
@ -51,7 +51,7 @@ returns
|
||||||
end
|
end
|
||||||
|
|
||||||
return data if !self['created_by_id'] && !self['updated_by_id']
|
return data if !self['created_by_id'] && !self['updated_by_id']
|
||||||
%w(created_by_id updated_by_id).each do |local_user_id|
|
%w[created_by_id updated_by_id].each do |local_user_id|
|
||||||
next if !self[ 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 ] ]
|
next if data[ User.to_app_model ] && data[ User.to_app_model ][ self[ local_user_id ] ]
|
||||||
user = User.lookup(id: self[ local_user_id ])
|
user = User.lookup(id: self[ local_user_id ])
|
||||||
|
|
|
@ -60,8 +60,7 @@ class Channel::Driver::Facebook
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def disconnect
|
def disconnect; end
|
||||||
end
|
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ example
|
||||||
# sort messages by date on server (if not supported), if not fetch messages via search (first in, first out)
|
# sort messages by date on server (if not supported), if not fetch messages via search (first in, first out)
|
||||||
filter = ['ALL']
|
filter = ['ALL']
|
||||||
if keep_on_server && check_type != 'check' && check_type != 'verify'
|
if keep_on_server && check_type != 'check' && check_type != 'verify'
|
||||||
filter = %w(NOT SEEN)
|
filter = %w[NOT SEEN]
|
||||||
end
|
end
|
||||||
begin
|
begin
|
||||||
message_ids = @imap.sort(['DATE'], filter, 'US-ASCII')
|
message_ids = @imap.sort(['DATE'], filter, 'US-ASCII')
|
||||||
|
@ -254,7 +254,7 @@ returns
|
||||||
|
|
||||||
# verify if message is already imported via same channel, if not, import it again
|
# verify if message is already imported via same channel, if not, import it again
|
||||||
ticket = article.ticket
|
ticket = article.ticket
|
||||||
if ticket && ticket.preferences && ticket.preferences[:channel_id].present? && channel.present?
|
if ticket&.preferences && ticket.preferences[:channel_id].present? && channel.present?
|
||||||
return false if ticket.preferences[:channel_id] != channel[:id]
|
return false if ticket.preferences[:channel_id] != channel[:id]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ class Channel::Driver::Smtp
|
||||||
return if Setting.get('import_mode')
|
return if Setting.get('import_mode')
|
||||||
|
|
||||||
# set smtp defaults
|
# set smtp defaults
|
||||||
if !options.key?(:port) || options[:port].empty?
|
if !options.key?(:port) || options[:port].blank?
|
||||||
options[:port] = 25
|
options[:port] = 25
|
||||||
end
|
end
|
||||||
if !options.key?(:ssl)
|
if !options.key?(:ssl)
|
||||||
|
|
|
@ -119,8 +119,8 @@ returns
|
||||||
end
|
end
|
||||||
|
|
||||||
def disconnect
|
def disconnect
|
||||||
@stream_client.disconnect if @stream_client
|
@stream_client&.disconnect
|
||||||
@rest_client.disconnect if @rest_client
|
@rest_client&.disconnect
|
||||||
end
|
end
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
@ -203,12 +203,11 @@ returns
|
||||||
stream_start
|
stream_start
|
||||||
rescue Twitter::Error::Unauthorized => e
|
rescue Twitter::Error::Unauthorized => e
|
||||||
Rails.logger.info "Unable to stream, try #{loop_count}, error #{e.inspect}"
|
Rails.logger.info "Unable to stream, try #{loop_count}, error #{e.inspect}"
|
||||||
if loop_count < 2
|
if loop_count >= 2
|
||||||
Rails.logger.info "wait for #{sleep_on_unauthorized} sec. and try it again"
|
|
||||||
sleep sleep_on_unauthorized
|
|
||||||
else
|
|
||||||
raise "Unable to stream, try #{loop_count}, error #{e.inspect}"
|
raise "Unable to stream, try #{loop_count}, error #{e.inspect}"
|
||||||
end
|
end
|
||||||
|
Rails.logger.info "wait for #{sleep_on_unauthorized} sec. and try it again"
|
||||||
|
sleep sleep_on_unauthorized
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -233,7 +232,7 @@ returns
|
||||||
filter[:replies] = 'all'
|
filter[:replies] = 'all'
|
||||||
end
|
end
|
||||||
|
|
||||||
return if filter.empty?
|
return if filter.blank?
|
||||||
|
|
||||||
@stream_client.client.user(filter) do |tweet|
|
@stream_client.client.user(filter) do |tweet|
|
||||||
next if tweet.class != Twitter::Tweet && tweet.class != Twitter::DirectMessage
|
next if tweet.class != Twitter::Tweet && tweet.class != Twitter::DirectMessage
|
||||||
|
@ -258,11 +257,9 @@ returns
|
||||||
# check if it's mention
|
# check if it's mention
|
||||||
if sync['mentions'] && sync['mentions']['group_id'].present?
|
if sync['mentions'] && sync['mentions']['group_id'].present?
|
||||||
hit = false
|
hit = false
|
||||||
if tweet.user_mentions
|
tweet.user_mentions&.each do |user|
|
||||||
tweet.user_mentions.each do |user|
|
if user.id.to_s == @channel.options['user']['id'].to_s
|
||||||
if user.id.to_s == @channel.options['user']['id'].to_s
|
hit = true
|
||||||
hit = true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if hit
|
if hit
|
||||||
|
@ -299,7 +296,7 @@ returns
|
||||||
next if item['term'].blank?
|
next if item['term'].blank?
|
||||||
next if item['term'] == '#'
|
next if item['term'] == '#'
|
||||||
next if item['group_id'].blank?
|
next if item['group_id'].blank?
|
||||||
if body =~ /#{item['term']}/
|
if body.match?(/#{item['term']}/)
|
||||||
hit = item
|
hit = item
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -69,7 +69,7 @@ module Channel::EmailBuild
|
||||||
end
|
end
|
||||||
|
|
||||||
# build email without any attachments
|
# build email without any attachments
|
||||||
if !html_alternative && ( !attr[:attachments] || attr[:attachments].empty? )
|
if !html_alternative && attr[:attachments].blank?
|
||||||
mail.content_type 'text/plain; charset=UTF-8'
|
mail.content_type 'text/plain; charset=UTF-8'
|
||||||
mail.body attr[:body]
|
mail.body attr[:body]
|
||||||
return mail
|
return mail
|
||||||
|
@ -84,19 +84,17 @@ module Channel::EmailBuild
|
||||||
html_container.add_part html_alternative
|
html_container.add_part html_alternative
|
||||||
|
|
||||||
# place to add inline attachments related to html alternative
|
# place to add inline attachments related to html alternative
|
||||||
if attr[:attachments]
|
attr[:attachments]&.each do |attachment|
|
||||||
attr[:attachments].each do |attachment|
|
next if attachment.class == Hash
|
||||||
next if attachment.class == Hash
|
next if attachment.preferences['Content-ID'].blank?
|
||||||
next if attachment.preferences['Content-ID'].empty?
|
attachment = Mail::Part.new do
|
||||||
attachment = Mail::Part.new do
|
content_type attachment.preferences['Content-Type']
|
||||||
content_type attachment.preferences['Content-Type']
|
content_id "<#{attachment.preferences['Content-ID']}>"
|
||||||
content_id "<#{attachment.preferences['Content-ID']}>"
|
content_disposition attachment.preferences['Content-Disposition'] || 'inline'
|
||||||
content_disposition attachment.preferences['Content-Disposition'] || 'inline'
|
content_transfer_encoding 'binary'
|
||||||
content_transfer_encoding 'binary'
|
body attachment.content.force_encoding('BINARY')
|
||||||
body attachment.content.force_encoding('BINARY')
|
|
||||||
end
|
|
||||||
html_container.add_part attachment
|
|
||||||
end
|
end
|
||||||
|
html_container.add_part attachment
|
||||||
end
|
end
|
||||||
alternative_bodies.add_part html_container
|
alternative_bodies.add_part html_container
|
||||||
end
|
end
|
||||||
|
@ -104,23 +102,21 @@ module Channel::EmailBuild
|
||||||
mail.add_part alternative_bodies
|
mail.add_part alternative_bodies
|
||||||
|
|
||||||
# add attachments
|
# add attachments
|
||||||
if attr[:attachments]
|
attr[:attachments]&.each do |attachment|
|
||||||
attr[:attachments].each do |attachment|
|
if attachment.class == Hash
|
||||||
if attachment.class == Hash
|
attachment['content-id'] = nil
|
||||||
attachment['content-id'] = nil
|
mail.attachments[ attachment[:filename] ] = attachment
|
||||||
mail.attachments[ attachment[:filename] ] = attachment
|
else
|
||||||
else
|
next if attachment.preferences['Content-ID'].present?
|
||||||
next if !attachment.preferences['Content-ID'].empty?
|
filename = attachment.filename
|
||||||
filename = attachment.filename
|
encoded_filename = Mail::Encodings.decode_encode filename, :encode
|
||||||
encoded_filename = Mail::Encodings.decode_encode filename, :encode
|
disposition = attachment.preferences['Content-Disposition'] || 'attachment'
|
||||||
disposition = attachment.preferences['Content-Disposition'] || 'attachment'
|
content_type = attachment.preferences['Content-Type'] || 'application/octet-stream'
|
||||||
content_type = attachment.preferences['Content-Type'] || 'application/octet-stream'
|
mail.attachments[attachment.filename] = {
|
||||||
mail.attachments[attachment.filename] = {
|
content_disposition: "#{disposition}; filename=\"#{encoded_filename}\"",
|
||||||
content_disposition: "#{disposition}; filename=\"#{encoded_filename}\"",
|
content_type: "#{content_type}; filename=\"#{encoded_filename}\"",
|
||||||
content_type: "#{content_type}; filename=\"#{encoded_filename}\"",
|
content: attachment.content
|
||||||
content: attachment.content
|
}
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
mail
|
mail
|
||||||
|
@ -137,7 +133,7 @@ returns
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def self.recipient_line(realname, email)
|
def self.recipient_line(realname, email)
|
||||||
return "#{realname} <#{email}>" if realname =~ /^[A-z]+$/i
|
return "#{realname} <#{email}>" if realname.match?(/^[A-z]+$/i)
|
||||||
"\"#{realname.gsub('"', '\"')}\" <#{email}>"
|
"\"#{realname.gsub('"', '\"')}\" <#{email}>"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -154,7 +150,7 @@ Check if string is a complete html document. If not, add head and css styles.
|
||||||
# apply mail client fixes
|
# apply mail client fixes
|
||||||
html = Channel::EmailBuild.html_mail_client_fixes(html)
|
html = Channel::EmailBuild.html_mail_client_fixes(html)
|
||||||
|
|
||||||
return html if html =~ /<html>/i
|
return html if html.match?(/<html>/i)
|
||||||
|
|
||||||
# use block form because variable html could contain backslashes and e. g. '\1' that
|
# use block form because variable html could contain backslashes and e. g. '\1' that
|
||||||
# must not be handled as back-references for regular expressions
|
# must not be handled as back-references for regular expressions
|
||||||
|
|
|
@ -94,7 +94,7 @@ class Channel::EmailParser
|
||||||
# verify content, ignore recipients with non email address
|
# verify content, ignore recipients with non email address
|
||||||
['to', 'cc', 'delivered-to', 'x-original-to', 'envelope-to'].each do |field|
|
['to', 'cc', 'delivered-to', 'x-original-to', 'envelope-to'].each do |field|
|
||||||
next if data[field.to_sym].blank?
|
next if data[field.to_sym].blank?
|
||||||
next if data[field.to_sym] =~ /@/
|
next if data[field.to_sym].match?(/@/)
|
||||||
data[field.to_sym] = ''
|
data[field.to_sym] = ''
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ class Channel::EmailParser
|
||||||
if mail.multipart?
|
if mail.multipart?
|
||||||
|
|
||||||
# html attachment/body may exists and will be converted to strict html
|
# html attachment/body may exists and will be converted to strict html
|
||||||
if mail.html_part && mail.html_part.body
|
if mail.html_part&.body
|
||||||
data[:body] = mail.html_part.body.to_s
|
data[:body] = mail.html_part.body.to_s
|
||||||
data[:body] = Encode.conv(mail.html_part.charset.to_s, data[:body])
|
data[:body] = Encode.conv(mail.html_part.charset.to_s, data[:body])
|
||||||
data[:body] = data[:body].html2html_strict.to_s.force_encoding('utf-8')
|
data[:body] = data[:body].html2html_strict.to_s.force_encoding('utf-8')
|
||||||
|
@ -196,17 +196,15 @@ class Channel::EmailParser
|
||||||
end
|
end
|
||||||
|
|
||||||
# get attachments
|
# get attachments
|
||||||
if mail.parts
|
mail.parts&.each do |part|
|
||||||
mail.parts.each do |part|
|
|
||||||
|
|
||||||
# protect process to work fine with spam emails, see test/fixtures/mail15.box
|
# protect process to work fine with spam emails, see test/fixtures/mail15.box
|
||||||
begin
|
begin
|
||||||
attachs = _get_attachment(part, data[:attachments], mail)
|
attachs = _get_attachment(part, data[:attachments], mail)
|
||||||
data[:attachments].concat(attachs)
|
data[:attachments].concat(attachs)
|
||||||
rescue
|
rescue
|
||||||
attachs = _get_attachment(part, data[:attachments], mail)
|
attachs = _get_attachment(part, data[:attachments], mail)
|
||||||
data[:attachments].concat(attachs)
|
data[:attachments].concat(attachs)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -306,10 +304,10 @@ class Channel::EmailParser
|
||||||
end
|
end
|
||||||
|
|
||||||
# ignore text/plain attachments - already shown in view
|
# ignore text/plain attachments - already shown in view
|
||||||
return [] if mail.text_part && mail.text_part.body.to_s == file.body.to_s
|
return [] if mail.text_part&.body.to_s == file.body.to_s
|
||||||
|
|
||||||
# ignore text/html - html part, already shown in view
|
# ignore text/html - html part, already shown in view
|
||||||
return [] if mail.html_part && mail.html_part.body.to_s == file.body.to_s
|
return [] if mail.html_part&.body.to_s == file.body.to_s
|
||||||
|
|
||||||
# get file preferences
|
# get file preferences
|
||||||
headers_store = {}
|
headers_store = {}
|
||||||
|
@ -376,7 +374,7 @@ class Channel::EmailParser
|
||||||
|
|
||||||
# generate file name based on content type
|
# generate file name based on content type
|
||||||
if filename.blank? && headers_store['Content-Type'].present?
|
if filename.blank? && headers_store['Content-Type'].present?
|
||||||
if headers_store['Content-Type'] =~ %r{^message/rfc822}i
|
if headers_store['Content-Type'].match?(%r{^message/rfc822}i)
|
||||||
begin
|
begin
|
||||||
parser = Channel::EmailParser.new
|
parser = Channel::EmailParser.new
|
||||||
mail_local = parser.parse(file.body.to_s)
|
mail_local = parser.parse(file.body.to_s)
|
||||||
|
@ -406,13 +404,13 @@ class Channel::EmailParser
|
||||||
if filename.blank?
|
if filename.blank?
|
||||||
map = {
|
map = {
|
||||||
'message/delivery-status': ['txt', 'delivery-status'],
|
'message/delivery-status': ['txt', 'delivery-status'],
|
||||||
'text/plain': %w(txt document),
|
'text/plain': %w[txt document],
|
||||||
'text/html': %w(html document),
|
'text/html': %w[html document],
|
||||||
'video/quicktime': %w(mov video),
|
'video/quicktime': %w[mov video],
|
||||||
'image/jpeg': %w(jpg image),
|
'image/jpeg': %w[jpg image],
|
||||||
'image/jpg': %w(jpg image),
|
'image/jpg': %w[jpg image],
|
||||||
'image/png': %w(png image),
|
'image/png': %w[png image],
|
||||||
'image/gif': %w(gif image),
|
'image/gif': %w[gif image],
|
||||||
}
|
}
|
||||||
map.each do |type, ext|
|
map.each do |type, ext|
|
||||||
next if headers_store['Content-Type'] !~ /^#{Regexp.quote(type)}/i
|
next if headers_store['Content-Type'] !~ /^#{Regexp.quote(type)}/i
|
||||||
|
@ -454,12 +452,12 @@ class Channel::EmailParser
|
||||||
end
|
end
|
||||||
|
|
||||||
# get mime type
|
# get mime type
|
||||||
if file.header[:content_type] && file.header[:content_type].string
|
if file.header[:content_type]&.string
|
||||||
headers_store['Mime-Type'] = file.header[:content_type].string
|
headers_store['Mime-Type'] = file.header[:content_type].string
|
||||||
end
|
end
|
||||||
|
|
||||||
# get charset
|
# get charset
|
||||||
if file.header && file.header.charset
|
if file.header&.charset
|
||||||
headers_store['Charset'] = file.header.charset
|
headers_store['Charset'] = file.header.charset
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -503,9 +501,8 @@ returns
|
||||||
|
|
||||||
_process(channel, msg)
|
_process(channel, msg)
|
||||||
rescue => e
|
rescue => e
|
||||||
|
|
||||||
# store unprocessable email for bug reporting
|
# store unprocessable email for bug reporting
|
||||||
path = "#{Rails.root}/tmp/unprocessable_mail/"
|
path = Rails.root.join('tmp', 'unprocessable_mail')
|
||||||
FileUtils.mkpath path
|
FileUtils.mkpath path
|
||||||
md5 = Digest::MD5.hexdigest(msg)
|
md5 = Digest::MD5.hexdigest(msg)
|
||||||
filename = "#{path}/#{md5}.eml"
|
filename = "#{path}/#{md5}.eml"
|
||||||
|
@ -532,7 +529,7 @@ returns
|
||||||
Setting.where(area: 'Postmaster::PreFilter').order(:name).each do |setting|
|
Setting.where(area: 'Postmaster::PreFilter').order(:name).each do |setting|
|
||||||
filters[setting.name] = Kernel.const_get(Setting.get(setting.name))
|
filters[setting.name] = Kernel.const_get(Setting.get(setting.name))
|
||||||
end
|
end
|
||||||
filters.each do |_prio, backend|
|
filters.each_value do |backend|
|
||||||
Rails.logger.debug "run postmaster pre filter #{backend}"
|
Rails.logger.debug "run postmaster pre filter #{backend}"
|
||||||
begin
|
begin
|
||||||
backend.run(channel, mail)
|
backend.run(channel, mail)
|
||||||
|
@ -663,16 +660,14 @@ returns
|
||||||
article.save_as_raw(msg)
|
article.save_as_raw(msg)
|
||||||
|
|
||||||
# store attachments
|
# store attachments
|
||||||
if mail[:attachments]
|
mail[:attachments]&.each do |attachment|
|
||||||
mail[:attachments].each do |attachment|
|
Store.add(
|
||||||
Store.add(
|
object: 'Ticket::Article',
|
||||||
object: 'Ticket::Article',
|
o_id: article.id,
|
||||||
o_id: article.id,
|
data: attachment[:data],
|
||||||
data: attachment[:data],
|
filename: attachment[:filename],
|
||||||
filename: attachment[:filename],
|
preferences: attachment[:preferences]
|
||||||
preferences: attachment[:preferences]
|
)
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -682,7 +677,7 @@ returns
|
||||||
Setting.where(area: 'Postmaster::PostFilter').order(:name).each do |setting|
|
Setting.where(area: 'Postmaster::PostFilter').order(:name).each do |setting|
|
||||||
filters[setting.name] = Kernel.const_get(Setting.get(setting.name))
|
filters[setting.name] = Kernel.const_get(Setting.get(setting.name))
|
||||||
end
|
end
|
||||||
filters.each do |_prio, backend|
|
filters.each_value do |backend|
|
||||||
Rails.logger.debug "run postmaster post filter #{backend}"
|
Rails.logger.debug "run postmaster post filter #{backend}"
|
||||||
begin
|
begin
|
||||||
backend.run(channel, mail, ticket, article, session_user)
|
backend.run(channel, mail, ticket, article, session_user)
|
||||||
|
@ -765,7 +760,7 @@ returns
|
||||||
def set_attributes_by_x_headers(item_object, header_name, mail, suffix = false)
|
def set_attributes_by_x_headers(item_object, header_name, mail, suffix = false)
|
||||||
|
|
||||||
# loop all x-zammad-header-* headers
|
# loop all x-zammad-header-* headers
|
||||||
item_object.attributes.each do |key, _value|
|
item_object.attributes.each_key do |key|
|
||||||
|
|
||||||
# ignore read only attributes
|
# ignore read only attributes
|
||||||
next if key == 'updated_by_id'
|
next if key == 'updated_by_id'
|
||||||
|
@ -862,9 +857,9 @@ module Mail
|
||||||
.+?(?=\=\?|$) # Plain String
|
.+?(?=\=\?|$) # Plain String
|
||||||
)/xmi).map do |matches|
|
)/xmi).map do |matches|
|
||||||
string, method = *matches
|
string, method = *matches
|
||||||
if method == 'b' || method == 'B'
|
if method == 'b' || method == 'B' # rubocop:disable Style/MultipleComparison
|
||||||
b_value_decode(string)
|
b_value_decode(string)
|
||||||
elsif method == 'q' || method == 'Q'
|
elsif method == 'q' || method == 'Q' # rubocop:disable Style/MultipleComparison
|
||||||
q_value_decode(string)
|
q_value_decode(string)
|
||||||
else
|
else
|
||||||
string
|
string
|
||||||
|
|
|
@ -25,7 +25,7 @@ module Channel::Filter::AutoResponseCheck
|
||||||
message_id = mail[ 'message_id'.to_sym ]
|
message_id = mail[ 'message_id'.to_sym ]
|
||||||
if message_id
|
if message_id
|
||||||
fqdn = Setting.get('fqdn')
|
fqdn = Setting.get('fqdn')
|
||||||
return if message_id =~ /@#{Regexp.quote(fqdn)}/i
|
return if message_id.match?(/@#{Regexp.quote(fqdn)}/i)
|
||||||
end
|
end
|
||||||
|
|
||||||
mail[ 'x-zammad-send-auto-response'.to_sym ] = true
|
mail[ 'x-zammad-send-auto-response'.to_sym ] = true
|
||||||
|
|
|
@ -28,7 +28,7 @@ module Channel::Filter::BounceDeliveryPermanentFailed
|
||||||
# get recipient of origin article, if only one - mark this user to not sent notifications anymore
|
# get recipient of origin article, if only one - mark this user to not sent notifications anymore
|
||||||
recipients = []
|
recipients = []
|
||||||
if article.sender.name == 'System' || article.sender.name == 'Agent'
|
if article.sender.name == 'System' || article.sender.name == 'Agent'
|
||||||
%w(to cc).each do |line|
|
%w[to cc].each do |line|
|
||||||
next if article[line].blank?
|
next if article[line].blank?
|
||||||
recipients = []
|
recipients = []
|
||||||
begin
|
begin
|
||||||
|
|
|
@ -104,5 +104,6 @@ module Channel::Filter::FollowUpCheck
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,15 +22,15 @@ module Channel::Filter::IdentifySender
|
||||||
if !customer_user && mail[ 'x-zammad-customer-email'.to_sym ].present?
|
if !customer_user && mail[ 'x-zammad-customer-email'.to_sym ].present?
|
||||||
customer_user = User.find_by(email: mail[ 'x-zammad-customer-email'.to_sym ])
|
customer_user = User.find_by(email: mail[ 'x-zammad-customer-email'.to_sym ])
|
||||||
end
|
end
|
||||||
if !customer_user
|
|
||||||
|
|
||||||
# get correct customer
|
# get correct customer
|
||||||
|
if !customer_user && Setting.get('postmaster_sender_is_agent_search_for_customer') == true
|
||||||
if mail[ 'x-zammad-ticket-create-article-sender'.to_sym ] == 'Agent'
|
if mail[ 'x-zammad-ticket-create-article-sender'.to_sym ] == 'Agent'
|
||||||
|
|
||||||
# get first recipient and set customer
|
# get first recipient and set customer
|
||||||
begin
|
begin
|
||||||
to = 'raw-to'.to_sym
|
to = 'raw-to'.to_sym
|
||||||
if mail[to] && mail[to].addrs
|
if mail[to]&.addrs
|
||||||
items = mail[to].addrs
|
items = mail[to].addrs
|
||||||
items.each do |item|
|
items.each do |item|
|
||||||
|
|
||||||
|
@ -46,18 +46,21 @@ module Channel::Filter::IdentifySender
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
rescue => e
|
rescue => e
|
||||||
Rails.logger.error 'ERROR: SenderIsSystemAddress: ' + e.inspect
|
Rails.logger.error "SenderIsSystemAddress: ##{e.inspect}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if !customer_user
|
|
||||||
customer_user = user_create(
|
|
||||||
login: mail[ 'x-zammad-customer-login'.to_sym ] || mail[ 'x-zammad-customer-email'.to_sym ] || mail[:from_email],
|
|
||||||
firstname: mail[ 'x-zammad-customer-firstname'.to_sym ] || mail[:from_display_name],
|
|
||||||
lastname: mail[ 'x-zammad-customer-lastname'.to_sym ],
|
|
||||||
email: mail[ 'x-zammad-customer-email'.to_sym ] || mail[:from_email],
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# take regular from as customer
|
||||||
|
if !customer_user
|
||||||
|
customer_user = user_create(
|
||||||
|
login: mail[ 'x-zammad-customer-login'.to_sym ] || mail[ 'x-zammad-customer-email'.to_sym ] || mail[:from_email],
|
||||||
|
firstname: mail[ 'x-zammad-customer-firstname'.to_sym ] || mail[:from_display_name],
|
||||||
|
lastname: mail[ 'x-zammad-customer-lastname'.to_sym ],
|
||||||
|
email: mail[ 'x-zammad-customer-email'.to_sym ] || mail[:from_email],
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
create_recipients(mail)
|
create_recipients(mail)
|
||||||
mail[ 'x-zammad-ticket-customer_id'.to_sym ] = customer_user.id
|
mail[ 'x-zammad-ticket-customer_id'.to_sym ] = customer_user.id
|
||||||
|
|
||||||
|
@ -83,6 +86,8 @@ module Channel::Filter::IdentifySender
|
||||||
if session_user
|
if session_user
|
||||||
mail[ 'x-zammad-session-user-id'.to_sym ] = session_user.id
|
mail[ 'x-zammad-session-user-id'.to_sym ] = session_user.id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
# create to and cc user
|
# create to and cc user
|
||||||
|
@ -159,7 +164,7 @@ module Channel::Filter::IdentifySender
|
||||||
role_ids = Role.signup_role_ids
|
role_ids = Role.signup_role_ids
|
||||||
|
|
||||||
# fillup
|
# fillup
|
||||||
%w(firstname lastname).each do |item|
|
%w[firstname lastname].each do |item|
|
||||||
if data[item.to_sym].nil?
|
if data[item.to_sym].nil?
|
||||||
data[item.to_sym] = ''
|
data[item.to_sym] = ''
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,12 +9,12 @@ module Channel::Filter::Match::EmailRegex
|
||||||
|
|
||||||
if regexp == false
|
if regexp == false
|
||||||
match_rule_quoted = Regexp.quote(match_rule).gsub(/\\\*/, '.*')
|
match_rule_quoted = Regexp.quote(match_rule).gsub(/\\\*/, '.*')
|
||||||
return true if value =~ /#{match_rule_quoted}/i
|
return true if value.match?(/#{match_rule_quoted}/i)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
return true if value =~ /#{match_rule}/i
|
return true if value.match?(/#{match_rule}/i)
|
||||||
return false
|
return false
|
||||||
rescue => e
|
rescue => e
|
||||||
message = "Can't use regex '#{match_rule}' on '#{value}': #{e.message}"
|
message = "Can't use regex '#{match_rule}' on '#{value}': #{e.message}"
|
||||||
|
|
|
@ -36,9 +36,7 @@ class Channel::Filter::MonitoringBase
|
||||||
key = key.downcase
|
key = key.downcase
|
||||||
end
|
end
|
||||||
value = $2
|
value = $2
|
||||||
if value
|
value&.strip!
|
||||||
value.strip!
|
|
||||||
end
|
|
||||||
result[key] = value
|
result[key] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -70,9 +68,9 @@ class Channel::Filter::MonitoringBase
|
||||||
|
|
||||||
# possible event types https://mmonit.com/monit/documentation/#Setting-an-event-filter
|
# possible event types https://mmonit.com/monit/documentation/#Setting-an-event-filter
|
||||||
if result['state'].blank?
|
if result['state'].blank?
|
||||||
result['state'] = if mail[:body] =~ /\s(done|recovery|succeeded|bytes\sok|packets\sok)\s/
|
result['state'] = if mail[:body].match?(/\s(done|recovery|succeeded|bytes\sok|packets\sok)\s/)
|
||||||
'OK'
|
'OK'
|
||||||
elsif mail[:body] =~ /(instance\schanged\snot|Link\sup|Exists|Saturation\sok|Speed\sok)/
|
elsif mail[:body].match?(/(instance\schanged\snot|Link\sup|Exists|Saturation\sok|Speed\sok)/)
|
||||||
'OK'
|
'OK'
|
||||||
else
|
else
|
||||||
'CRITICAL'
|
'CRITICAL'
|
||||||
|
@ -132,5 +130,6 @@ class Channel::Filter::MonitoringBase
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,12 +18,12 @@ module Channel::Filter::OutOfOfficeCheck
|
||||||
if mail[ 'auto-submitted'.to_sym ]
|
if mail[ 'auto-submitted'.to_sym ]
|
||||||
|
|
||||||
# check zimbra out of office characteristics
|
# check zimbra out of office characteristics
|
||||||
if mail[ 'auto-submitted'.to_sym ] =~ /vacation/i
|
if mail[ 'auto-submitted'.to_sym ].match?(/vacation/i)
|
||||||
mail[ 'x-zammad-out-of-office'.to_sym ] = true
|
mail[ 'x-zammad-out-of-office'.to_sym ] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
# check cloud out of office characteristics
|
# check cloud out of office characteristics
|
||||||
if mail[ 'auto-submitted'.to_sym ] =~ /auto-replied;\sowner-email=/i
|
if mail[ 'auto-submitted'.to_sym ].match?(/auto-replied;\sowner-email=/i)
|
||||||
mail[ 'x-zammad-out-of-office'.to_sym ] = true
|
mail[ 'x-zammad-out-of-office'.to_sym ] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ module Channel::Filter::OutOfOfficeCheck
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,7 @@ module Channel::Filter::Trusted
|
||||||
|
|
||||||
# check if trust x-headers
|
# check if trust x-headers
|
||||||
if !channel[:trusted]
|
if !channel[:trusted]
|
||||||
mail.each do |key, _value|
|
mail.each_key do |key|
|
||||||
next if key !~ /^x-zammad/i
|
next if key !~ /^x-zammad/i
|
||||||
mail.delete(key)
|
mail.delete(key)
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,7 +9,7 @@ class Chat < ApplicationModel
|
||||||
|
|
||||||
# reconnect
|
# reconnect
|
||||||
if session_id
|
if session_id
|
||||||
chat_session = Chat::Session.find_by(session_id: session_id, state: %w(waiting running))
|
chat_session = Chat::Session.find_by(session_id: session_id, state: %w[waiting running])
|
||||||
|
|
||||||
if chat_session
|
if chat_session
|
||||||
if chat_session.state == 'running'
|
if chat_session.state == 'running'
|
||||||
|
@ -126,7 +126,7 @@ class Chat < ApplicationModel
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.active_chat_count
|
def self.active_chat_count
|
||||||
Chat::Session.where(state: %w(waiting running)).count
|
Chat::Session.where(state: %w[waiting running]).count
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.available_agents(diff = 2.minutes)
|
def self.available_agents(diff = 2.minutes)
|
||||||
|
@ -153,7 +153,7 @@ class Chat < ApplicationModel
|
||||||
|
|
||||||
def self.seads_total(diff = 2.minutes)
|
def self.seads_total(diff = 2.minutes)
|
||||||
total = 0
|
total = 0
|
||||||
available_agents(diff).each do |_user_id, concurrent|
|
available_agents(diff).each_value do |concurrent|
|
||||||
total += concurrent
|
total += concurrent
|
||||||
end
|
end
|
||||||
total
|
total
|
||||||
|
|
|
@ -5,7 +5,7 @@ class Chat::Agent < ApplicationModel
|
||||||
end
|
end
|
||||||
|
|
||||||
def active_chat_count
|
def active_chat_count
|
||||||
Chat::Session.where(state: %w(waiting running), user_id: updated_by_id).count
|
Chat::Session.where(state: %w[waiting running], user_id: updated_by_id).count
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.state(user_id, state = nil)
|
def self.state(user_id, state = nil)
|
||||||
|
|
|
@ -17,7 +17,7 @@ module CanSeed
|
||||||
end
|
end
|
||||||
|
|
||||||
def seedfile
|
def seedfile
|
||||||
"#{Rails.root}/db/seeds/#{name.pluralize.underscore.tr('/', '_')}.rb"
|
Rails.root.join('db', 'seeds', "#{name.pluralize.underscore.tr('/', '_')}.rb").to_s
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -35,12 +35,11 @@ log object update activity stream, if configured - will be executed automaticall
|
||||||
return true if !saved_changes?
|
return true if !saved_changes?
|
||||||
|
|
||||||
ignored_attributes = self.class.instance_variable_get(:@activity_stream_attributes_ignored) || []
|
ignored_attributes = self.class.instance_variable_get(:@activity_stream_attributes_ignored) || []
|
||||||
ignored_attributes += %i(created_at updated_at created_by_id updated_by_id)
|
ignored_attributes += %i[created_at updated_at created_by_id updated_by_id]
|
||||||
|
|
||||||
log = false
|
log = false
|
||||||
saved_changes.each do |key, _value|
|
saved_changes.each_key do |key|
|
||||||
next if ignored_attributes.include?(key.to_sym)
|
next if ignored_attributes.include?(key.to_sym)
|
||||||
|
|
||||||
log = true
|
log = true
|
||||||
end
|
end
|
||||||
return true if !log
|
return true if !log
|
||||||
|
|
|
@ -40,11 +40,9 @@ log object update history with all updated attributes, if configured - will be e
|
||||||
|
|
||||||
# new record also triggers update, so ignore new records
|
# new record also triggers update, so ignore new records
|
||||||
changes = saved_changes
|
changes = saved_changes
|
||||||
if history_changes_last_done
|
history_changes_last_done&.each do |key, value|
|
||||||
history_changes_last_done.each do |key, value|
|
if changes.key?(key) && changes[key] == value
|
||||||
if changes.key?(key) && changes[key] == value
|
changes.delete(key)
|
||||||
changes.delete(key)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self.history_changes_last_done = changes
|
self.history_changes_last_done = changes
|
||||||
|
@ -53,7 +51,7 @@ log object update history with all updated attributes, if configured - will be e
|
||||||
return if changes['id'] && !changes['id'][0]
|
return if changes['id'] && !changes['id'][0]
|
||||||
|
|
||||||
ignored_attributes = self.class.instance_variable_get(:@history_attributes_ignored) || []
|
ignored_attributes = self.class.instance_variable_get(:@history_attributes_ignored) || []
|
||||||
ignored_attributes += %i(created_at updated_at created_by_id updated_by_id)
|
ignored_attributes += %i[created_at updated_at created_by_id updated_by_id]
|
||||||
|
|
||||||
changes.each do |key, value|
|
changes.each do |key, value|
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ returns
|
||||||
|
|
||||||
def search_index_data
|
def search_index_data
|
||||||
attributes = {}
|
attributes = {}
|
||||||
%w(name note).each do |key|
|
%w[name note].each do |key|
|
||||||
next if !self[key]
|
next if !self[key]
|
||||||
next if self[key].respond_to?('blank?') && self[key].blank?
|
next if self[key].respond_to?('blank?') && self[key].blank?
|
||||||
attributes[key] = self[key]
|
attributes[key] = self[key]
|
||||||
|
|
|
@ -108,11 +108,11 @@ returns
|
||||||
# get caller ids
|
# get caller ids
|
||||||
caller_ids = []
|
caller_ids = []
|
||||||
attributes = record.attributes
|
attributes = record.attributes
|
||||||
attributes.each do |_attribute, value|
|
attributes.each_value do |value|
|
||||||
next if value.class != String
|
next if value.class != String
|
||||||
next if value.empty?
|
next if value.blank?
|
||||||
local_caller_ids = Cti::CallerId.extract_numbers(value)
|
local_caller_ids = Cti::CallerId.extract_numbers(value)
|
||||||
next if local_caller_ids.empty?
|
next if local_caller_ids.blank?
|
||||||
caller_ids = caller_ids.concat(local_caller_ids)
|
caller_ids = caller_ids.concat(local_caller_ids)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -233,23 +233,23 @@ returns
|
||||||
if user
|
if user
|
||||||
comment += user.fullname
|
comment += user.fullname
|
||||||
end
|
end
|
||||||
elsif !record.comment.empty?
|
elsif record.comment.present?
|
||||||
comment += record.comment
|
comment += record.comment
|
||||||
end
|
end
|
||||||
if record.level == 'known'
|
if record.level == 'known'
|
||||||
if !from_comment_known.empty?
|
if from_comment_known.present?
|
||||||
from_comment_known += ','
|
from_comment_known += ','
|
||||||
end
|
end
|
||||||
from_comment_known += comment
|
from_comment_known += comment
|
||||||
else
|
else
|
||||||
if !from_comment_maybe.empty?
|
if from_comment_maybe.present?
|
||||||
from_comment_maybe += ','
|
from_comment_maybe += ','
|
||||||
end
|
end
|
||||||
from_comment_maybe += comment
|
from_comment_maybe += comment
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return [from_comment_known, preferences_known] if !from_comment_known.empty?
|
return [from_comment_known, preferences_known] if from_comment_known.present?
|
||||||
return ["maybe #{from_comment_maybe}", preferences_maybe] if !from_comment_maybe.empty?
|
return ["maybe #{from_comment_maybe}", preferences_maybe] if from_comment_maybe.present?
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,7 @@ returns
|
||||||
assets = {}
|
assets = {}
|
||||||
list.each do |item|
|
list.each do |item|
|
||||||
next if !item.preferences
|
next if !item.preferences
|
||||||
%w(from to).each do |direction|
|
%w[from to].each do |direction|
|
||||||
next if !item.preferences[direction]
|
next if !item.preferences[direction]
|
||||||
item.preferences[direction].each do |caller_id|
|
item.preferences[direction].each do |caller_id|
|
||||||
next if !caller_id['user_id']
|
next if !caller_id['user_id']
|
||||||
|
|
|
@ -47,7 +47,7 @@ check and if channel not exists reset configured channels for email addresses
|
||||||
return true if email.blank?
|
return true if email.blank?
|
||||||
self.email = email.downcase.strip
|
self.email = email.downcase.strip
|
||||||
raise Exceptions::UnprocessableEntity, 'Invalid email' if email !~ /@/
|
raise Exceptions::UnprocessableEntity, 'Invalid email' if email !~ /@/
|
||||||
raise Exceptions::UnprocessableEntity, 'Invalid email' if email =~ /\s/
|
raise Exceptions::UnprocessableEntity, 'Invalid email' if email.match?(/\s/)
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ class ExternalSync < ApplicationModel
|
||||||
break if !value
|
break if !value
|
||||||
|
|
||||||
storable = value.class.ancestors.any? do |ancestor|
|
storable = value.class.ancestors.any? do |ancestor|
|
||||||
%w(String Integer Float Bool Array).include?(ancestor.to_s)
|
%w[String Integer Float Bool Array].include?(ancestor.to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
if storable
|
if storable
|
||||||
|
|
|
@ -78,11 +78,9 @@ job.run(true)
|
||||||
self.running = true
|
self.running = true
|
||||||
save!
|
save!
|
||||||
|
|
||||||
if tickets
|
tickets&.each do |ticket|
|
||||||
tickets.each do |ticket|
|
Transaction.execute(disable_notification: disable_notification, reset_user_id: true) do
|
||||||
Transaction.execute(disable_notification: disable_notification, reset_user_id: true) do
|
ticket.perform_changes(perform, 'job')
|
||||||
ticket.perform_changes(perform, 'job')
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ returns
|
||||||
data = assets_of_selector('condition', data)
|
data = assets_of_selector('condition', data)
|
||||||
data = assets_of_selector('perform', data)
|
data = assets_of_selector('perform', data)
|
||||||
end
|
end
|
||||||
%w(created_by_id updated_by_id).each do |local_user_id|
|
%w[created_by_id updated_by_id].each do |local_user_id|
|
||||||
next if !self[ local_user_id ]
|
next if !self[ local_user_id ]
|
||||||
next if data[ User.to_app_model ][ self[ local_user_id ] ]
|
next if data[ User.to_app_model ][ self[ local_user_id ] ]
|
||||||
user = User.lookup(id: self[ local_user_id ])
|
user = User.lookup(id: self[ local_user_id ])
|
||||||
|
|
|
@ -71,7 +71,7 @@ all:
|
||||||
|
|
||||||
def self.load_from_file
|
def self.load_from_file
|
||||||
version = Version.get
|
version = Version.get
|
||||||
file = Rails.root.join("config/locales-#{version}.yml")
|
file = Rails.root.join('config', "locales-#{version}.yml")
|
||||||
return false if !File.exist?(file)
|
return false if !File.exist?(file)
|
||||||
data = YAML.load_file(file)
|
data = YAML.load_file(file)
|
||||||
to_database(data)
|
to_database(data)
|
||||||
|
@ -107,7 +107,7 @@ all:
|
||||||
raise "Can't load locales from #{url}" if !result
|
raise "Can't load locales from #{url}" if !result
|
||||||
raise "Can't load locales from #{url}: #{result.error}" if !result.success?
|
raise "Can't load locales from #{url}: #{result.error}" if !result.success?
|
||||||
|
|
||||||
file = Rails.root.join("config/locales-#{version}.yml")
|
file = Rails.root.join('config', "locales-#{version}.yml")
|
||||||
File.open(file, 'w') do |out|
|
File.open(file, 'w') do |out|
|
||||||
YAML.dump(result.data, out)
|
YAML.dump(result.data, out)
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,7 +11,7 @@ list all backend managed object
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def self.list_objects
|
def self.list_objects
|
||||||
%w(Ticket TicketArticle User Organization Group)
|
%w[Ticket TicketArticle User Organization Group]
|
||||||
end
|
end
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
@ -23,7 +23,7 @@ list all frontend managed object
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def self.list_frontend_objects
|
def self.list_frontend_objects
|
||||||
%w(Ticket User Organization Group)
|
%w[Ticket User Organization Group]
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -279,7 +279,7 @@ possible types
|
||||||
|
|
||||||
# if data_option has changed, store it for next migration
|
# if data_option has changed, store it for next migration
|
||||||
if !force
|
if !force
|
||||||
[:name, :display, :data_type, :position, :active].each do |key|
|
%i[name display data_type position active].each do |key|
|
||||||
next if record[key] == data[key]
|
next if record[key] == data[key]
|
||||||
data[:to_config] = true
|
data[:to_config] = true
|
||||||
break
|
break
|
||||||
|
@ -441,7 +441,7 @@ returns:
|
||||||
tag: item.data_type,
|
tag: item.data_type,
|
||||||
#:null => item.null,
|
#:null => item.null,
|
||||||
}
|
}
|
||||||
if item.data_option[:permission] && item.data_option[:permission].any?
|
if item.data_option[:permission]&.any?
|
||||||
next if !user
|
next if !user
|
||||||
hint = false
|
hint = false
|
||||||
item.data_option[:permission].each do |permission|
|
item.data_option[:permission].each do |permission|
|
||||||
|
@ -459,7 +459,7 @@ returns:
|
||||||
permission_options.each do |permission, options|
|
permission_options.each do |permission, options|
|
||||||
if permission == '-all-'
|
if permission == '-all-'
|
||||||
data[:screen][screen] = options
|
data[:screen][screen] = options
|
||||||
elsif user && user.permissions?(permission)
|
elsif user&.permissions?(permission)
|
||||||
data[:screen][screen] = options
|
data[:screen][screen] = options
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -535,7 +535,7 @@ returns
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def self.pending_migration?
|
def self.pending_migration?
|
||||||
return false if migrations.empty?
|
return false if migrations.blank?
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -601,21 +601,21 @@ to send no browser reload event, pass false
|
||||||
end
|
end
|
||||||
|
|
||||||
data_type = nil
|
data_type = nil
|
||||||
if attribute.data_type =~ /^input|select|tree_select|richtext|textarea|checkbox$/
|
if attribute.data_type.match?(/^input|select|tree_select|richtext|textarea|checkbox$/)
|
||||||
data_type = :string
|
data_type = :string
|
||||||
elsif attribute.data_type =~ /^integer|user_autocompletion$/
|
elsif attribute.data_type.match?(/^integer|user_autocompletion$/)
|
||||||
data_type = :integer
|
data_type = :integer
|
||||||
elsif attribute.data_type =~ /^boolean|active$/
|
elsif attribute.data_type.match?(/^boolean|active$/)
|
||||||
data_type = :boolean
|
data_type = :boolean
|
||||||
elsif attribute.data_type =~ /^datetime$/
|
elsif attribute.data_type.match?(/^datetime$/)
|
||||||
data_type = :datetime
|
data_type = :datetime
|
||||||
elsif attribute.data_type =~ /^date$/
|
elsif attribute.data_type.match?(/^date$/)
|
||||||
data_type = :date
|
data_type = :date
|
||||||
end
|
end
|
||||||
|
|
||||||
# change field
|
# change field
|
||||||
if model.column_names.include?(attribute.name)
|
if model.column_names.include?(attribute.name)
|
||||||
if attribute.data_type =~ /^input|select|tree_select|richtext|textarea|checkbox$/
|
if attribute.data_type.match?(/^input|select|tree_select|richtext|textarea|checkbox$/)
|
||||||
ActiveRecord::Migration.change_column(
|
ActiveRecord::Migration.change_column(
|
||||||
model.table_name,
|
model.table_name,
|
||||||
attribute.name,
|
attribute.name,
|
||||||
|
@ -623,7 +623,7 @@ to send no browser reload event, pass false
|
||||||
limit: attribute.data_option[:maxlength],
|
limit: attribute.data_option[:maxlength],
|
||||||
null: true
|
null: true
|
||||||
)
|
)
|
||||||
elsif attribute.data_type =~ /^integer|user_autocompletion|datetime|date$/
|
elsif attribute.data_type.match?(/^integer|user_autocompletion|datetime|date$/)
|
||||||
ActiveRecord::Migration.change_column(
|
ActiveRecord::Migration.change_column(
|
||||||
model.table_name,
|
model.table_name,
|
||||||
attribute.name,
|
attribute.name,
|
||||||
|
@ -631,7 +631,7 @@ to send no browser reload event, pass false
|
||||||
default: attribute.data_option[:default],
|
default: attribute.data_option[:default],
|
||||||
null: true
|
null: true
|
||||||
)
|
)
|
||||||
elsif attribute.data_type =~ /^boolean|active$/
|
elsif attribute.data_type.match?(/^boolean|active$/)
|
||||||
ActiveRecord::Migration.change_column(
|
ActiveRecord::Migration.change_column(
|
||||||
model.table_name,
|
model.table_name,
|
||||||
attribute.name,
|
attribute.name,
|
||||||
|
@ -654,7 +654,7 @@ to send no browser reload event, pass false
|
||||||
end
|
end
|
||||||
|
|
||||||
# create field
|
# create field
|
||||||
if attribute.data_type =~ /^input|select|tree_select|richtext|textarea|checkbox$/
|
if attribute.data_type.match?(/^input|select|tree_select|richtext|textarea|checkbox$/)
|
||||||
ActiveRecord::Migration.add_column(
|
ActiveRecord::Migration.add_column(
|
||||||
model.table_name,
|
model.table_name,
|
||||||
attribute.name,
|
attribute.name,
|
||||||
|
@ -662,7 +662,7 @@ to send no browser reload event, pass false
|
||||||
limit: attribute.data_option[:maxlength],
|
limit: attribute.data_option[:maxlength],
|
||||||
null: true
|
null: true
|
||||||
)
|
)
|
||||||
elsif attribute.data_type =~ /^integer|user_autocompletion$/
|
elsif attribute.data_type.match?(/^integer|user_autocompletion$/)
|
||||||
ActiveRecord::Migration.add_column(
|
ActiveRecord::Migration.add_column(
|
||||||
model.table_name,
|
model.table_name,
|
||||||
attribute.name,
|
attribute.name,
|
||||||
|
@ -670,7 +670,7 @@ to send no browser reload event, pass false
|
||||||
default: attribute.data_option[:default],
|
default: attribute.data_option[:default],
|
||||||
null: true
|
null: true
|
||||||
)
|
)
|
||||||
elsif attribute.data_type =~ /^boolean|active$/
|
elsif attribute.data_type.match?(/^boolean|active$/)
|
||||||
ActiveRecord::Migration.add_column(
|
ActiveRecord::Migration.add_column(
|
||||||
model.table_name,
|
model.table_name,
|
||||||
attribute.name,
|
attribute.name,
|
||||||
|
@ -678,7 +678,7 @@ to send no browser reload event, pass false
|
||||||
default: attribute.data_option[:default],
|
default: attribute.data_option[:default],
|
||||||
null: true
|
null: true
|
||||||
)
|
)
|
||||||
elsif attribute.data_type =~ /^datetime|date$/
|
elsif attribute.data_type.match?(/^datetime|date$/)
|
||||||
ActiveRecord::Migration.add_column(
|
ActiveRecord::Migration.add_column(
|
||||||
model.table_name,
|
model.table_name,
|
||||||
attribute.name,
|
attribute.name,
|
||||||
|
@ -727,26 +727,20 @@ to send no browser reload event, pass false
|
||||||
|
|
||||||
def check_name
|
def check_name
|
||||||
return if !name
|
return if !name
|
||||||
if name =~ /_(id|ids)$/i || name =~ /^id$/i
|
|
||||||
raise 'Name can\'t get used, *_id and *_ids are not allowed'
|
raise 'Name can\'t get used, *_id and *_ids are not allowed' if name.match?(/_(id|ids)$/i) || name.match?(/^id$/i)
|
||||||
elsif name =~ /\s/
|
raise 'Spaces in name are not allowed' if name.match?(/\s/)
|
||||||
raise 'Spaces in name are not allowed'
|
raise 'Only letters from a-z, numbers from 0-9, and _ are allowed' if !name.match?(/^[a-z0-9_]+$/)
|
||||||
elsif name !~ /^[a-z0-9_]+$/
|
raise 'At least one letters is needed' if !name.match?(/[a-z]/)
|
||||||
raise 'Only letters from a-z, numbers from 0-9, and _ are allowed'
|
|
||||||
elsif name !~ /[a-z]/
|
|
||||||
raise 'At least one letters is needed'
|
|
||||||
elsif name =~ /^(destroy|true|false|integer|select|drop|create|alter|index|table|varchar|blob|date|datetime|timestamp)$/
|
|
||||||
raise "#{name} is a reserved word, please choose a different one"
|
|
||||||
|
|
||||||
# do not allow model method names as attributes
|
# do not allow model method names as attributes
|
||||||
else
|
reserved_words = %w[destroy true false integer select drop create alter index table varchar blob date datetime timestamp]
|
||||||
model = Kernel.const_get(object_lookup.name)
|
raise "#{name} is a reserved word, please choose a different one" if name.match?(/^(#{reserved_words.join('|')})$/)
|
||||||
record = model.new
|
|
||||||
if record.respond_to?(name.to_sym) && !record.attributes.key?(name)
|
record = object_lookup.name.constantize.new
|
||||||
raise "#{name} is a reserved word, please choose a different one"
|
return true if !record.respond_to?(name.to_sym)
|
||||||
end
|
return true if record.attributes.key?(name)
|
||||||
end
|
raise "#{name} is a reserved word, please choose a different one"
|
||||||
true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_editable
|
def check_editable
|
||||||
|
@ -783,7 +777,7 @@ to send no browser reload event, pass false
|
||||||
end
|
end
|
||||||
|
|
||||||
if data_type == 'integer'
|
if data_type == 'integer'
|
||||||
[:min, :max].each do |item|
|
%i[min max].each do |item|
|
||||||
raise "Need data_option[#{item.inspect}] param" if !data_option[item]
|
raise "Need data_option[#{item.inspect}] param" if !data_option[item]
|
||||||
raise "Invalid data_option[#{item.inspect}] param #{data_option[item]}" if data_option[item].to_s !~ /^\d+?$/
|
raise "Invalid data_option[#{item.inspect}] param #{data_option[item]}" if data_option[item].to_s !~ /^\d+?$/
|
||||||
end
|
end
|
||||||
|
@ -817,6 +811,7 @@ to send no browser reload event, pass false
|
||||||
raise 'Need data_option[:diff] param in days' if data_option[:diff].nil?
|
raise 'Need data_option[:diff] param in days' if data_option[:diff].nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# encoding: utf-8
|
|
||||||
|
|
||||||
class Observer::Chat::Leave::BackgroundJob
|
class Observer::Chat::Leave::BackgroundJob
|
||||||
def initialize(chat_session_id, client_id, session)
|
def initialize(chat_session_id, client_id, session)
|
||||||
@chat_session_id = chat_session_id
|
@chat_session_id = chat_session_id
|
||||||
|
|
|
@ -27,7 +27,7 @@ class Observer::Organization::RefObjectTouch < ActiveRecord::Observer
|
||||||
Ticket.select('id').where(organization_id: record.id).pluck(:id).each do |ticket_id|
|
Ticket.select('id').where(organization_id: record.id).pluck(:id).each do |ticket_id|
|
||||||
ticket = Ticket.find(ticket_id)
|
ticket = Ticket.find(ticket_id)
|
||||||
ticket.with_lock do
|
ticket.with_lock do
|
||||||
ticket.touch
|
ticket.touch # rubocop:disable Rails/SkipsModelValidations
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ class Observer::Organization::RefObjectTouch < ActiveRecord::Observer
|
||||||
User.select('id').where(organization_id: record.id).pluck(:id).each do |user_id|
|
User.select('id').where(organization_id: record.id).pluck(:id).each do |user_id|
|
||||||
user = User.find(user_id)
|
user = User.find(user_id)
|
||||||
user.with_lock do
|
user.with_lock do
|
||||||
user.touch
|
user.touch # rubocop:disable Rails/SkipsModelValidations
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
true
|
true
|
||||||
|
|
|
@ -33,9 +33,9 @@ class Observer::Sla::TicketRebuildEscalation < ActiveRecord::Observer
|
||||||
changed = false
|
changed = false
|
||||||
fields_to_check = nil
|
fields_to_check = nil
|
||||||
fields_to_check = if record.class == Sla
|
fields_to_check = if record.class == Sla
|
||||||
%w(condition calendar_id first_response_time update_time solution_time)
|
%w[condition calendar_id first_response_time update_time solution_time]
|
||||||
else
|
else
|
||||||
%w(timezone business_hours default ical_url public_holidays)
|
%w[timezone business_hours default ical_url public_holidays]
|
||||||
end
|
end
|
||||||
fields_to_check.each do |item|
|
fields_to_check.each do |item|
|
||||||
next if !record.saved_change_to_attribute(item)
|
next if !record.saved_change_to_attribute(item)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
class Observer::Sla::TicketRebuildEscalation::BackgroundJob
|
class Observer::Sla::TicketRebuildEscalation::BackgroundJob
|
||||||
def initialize(_sla_id)
|
def initialize(_sla_id); end
|
||||||
end
|
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
Cache.delete('SLA::List::Active')
|
Cache.delete('SLA::List::Active')
|
||||||
|
|
|
@ -10,7 +10,7 @@ class Observer::Ticket::Article::CommunicateEmail < ActiveRecord::Observer
|
||||||
|
|
||||||
# only do send email if article got created via application_server (e. g. not
|
# only do send email if article got created via application_server (e. g. not
|
||||||
# if article and sender type is set via *.postmaster)
|
# if article and sender type is set via *.postmaster)
|
||||||
return if ApplicationHandleInfo.current.split('.')[1] == 'postmaster'
|
return if ApplicationHandleInfo.postmaster?
|
||||||
|
|
||||||
# if sender is customer, do not communicate
|
# if sender is customer, do not communicate
|
||||||
return if !record.sender_id
|
return if !record.sender_id
|
||||||
|
|
|
@ -90,7 +90,7 @@ class Observer::Ticket::Article::CommunicateEmail::BackgroundJob
|
||||||
|
|
||||||
# add history record
|
# add history record
|
||||||
recipient_list = ''
|
recipient_list = ''
|
||||||
[:to, :cc].each do |key|
|
%i[to cc].each do |key|
|
||||||
|
|
||||||
next if !record[key]
|
next if !record[key]
|
||||||
next if record[key] == ''
|
next if record[key] == ''
|
||||||
|
@ -130,7 +130,7 @@ class Observer::Ticket::Article::CommunicateEmail::BackgroundJob
|
||||||
if local_record.preferences['delivery_retry'] > 3
|
if local_record.preferences['delivery_retry'] > 3
|
||||||
|
|
||||||
recipient_list = ''
|
recipient_list = ''
|
||||||
[:to, :cc].each do |key|
|
%i[to cc].each do |key|
|
||||||
|
|
||||||
next if !local_record[key]
|
next if !local_record[key]
|
||||||
next if local_record[key] == ''
|
next if local_record[key] == ''
|
||||||
|
|
|
@ -12,7 +12,7 @@ class Observer::Ticket::Article::CommunicateFacebook < ActiveRecord::Observer
|
||||||
|
|
||||||
# only do send email if article got created via application_server (e. g. not
|
# only do send email if article got created via application_server (e. g. not
|
||||||
# if article and sender type is set via *.postmaster)
|
# if article and sender type is set via *.postmaster)
|
||||||
return if ApplicationHandleInfo.current.split('.')[1] == 'postmaster'
|
return if ApplicationHandleInfo.postmaster?
|
||||||
|
|
||||||
# if sender is customer, do not communicate
|
# if sender is customer, do not communicate
|
||||||
return if !record.sender_id
|
return if !record.sender_id
|
||||||
|
|
|
@ -10,7 +10,7 @@ class Observer::Ticket::Article::CommunicateTwitter < ActiveRecord::Observer
|
||||||
|
|
||||||
# only do send email if article got created via application_server (e. g. not
|
# only do send email if article got created via application_server (e. g. not
|
||||||
# if article and sender type is set via *.postmaster)
|
# if article and sender type is set via *.postmaster)
|
||||||
return if ApplicationHandleInfo.current.split('.')[1] == 'postmaster'
|
return if ApplicationHandleInfo.postmaster?
|
||||||
|
|
||||||
# if sender is customer, do not communicate
|
# if sender is customer, do not communicate
|
||||||
return if !record.sender_id
|
return if !record.sender_id
|
||||||
|
|
|
@ -10,7 +10,7 @@ class Observer::Ticket::Article::FillupFromEmail < ActiveRecord::Observer
|
||||||
|
|
||||||
# only do fill of email from if article got created via application_server (e. g. not
|
# only do fill of email from if article got created via application_server (e. g. not
|
||||||
# if article and sender type is set via *.postmaster)
|
# if article and sender type is set via *.postmaster)
|
||||||
return true if ApplicationHandleInfo.current.split('.')[1] == 'postmaster'
|
return if ApplicationHandleInfo.postmaster?
|
||||||
|
|
||||||
# if sender is customer, do not change anything
|
# if sender is customer, do not change anything
|
||||||
return true if !record.sender_id
|
return true if !record.sender_id
|
||||||
|
|
|
@ -10,7 +10,7 @@ class Observer::Ticket::Article::FillupFromGeneral < ActiveRecord::Observer
|
||||||
|
|
||||||
# only do fill of from if article got created via application_server (e. g. not
|
# only do fill of from if article got created via application_server (e. g. not
|
||||||
# if article and sender type is set via *.postmaster)
|
# if article and sender type is set via *.postmaster)
|
||||||
return true if ApplicationHandleInfo.current.split('.')[1] == 'postmaster'
|
return if ApplicationHandleInfo.postmaster?
|
||||||
|
|
||||||
# set from on all article types excluding email|twitter status|twitter direct-message|facebook feed post|facebook feed comment
|
# 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
|
return true if !record.type_id
|
||||||
|
|
|
@ -10,7 +10,7 @@ class Observer::Ticket::Article::FillupFromOriginById < ActiveRecord::Observer
|
||||||
|
|
||||||
# only do fill of from if article got created via application_server (e. g. not
|
# only do fill of from if article got created via application_server (e. g. not
|
||||||
# if article and sender type is set via *.postmaster)
|
# if article and sender type is set via *.postmaster)
|
||||||
return if ApplicationHandleInfo.current.split('.')[1] == 'postmaster'
|
return if ApplicationHandleInfo.postmaster?
|
||||||
|
|
||||||
# check if origin_by_id exists
|
# check if origin_by_id exists
|
||||||
return if record.origin_by_id.present?
|
return if record.origin_by_id.present?
|
||||||
|
|
|
@ -24,7 +24,7 @@ class Observer::Ticket::ArticleChanges < ActiveRecord::Observer
|
||||||
|
|
||||||
# save ticket
|
# save ticket
|
||||||
if !changed
|
if !changed
|
||||||
record.ticket.touch
|
record.ticket.touch # rubocop:disable Rails/SkipsModelValidations
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
record.ticket.save
|
record.ticket.save
|
||||||
|
@ -38,7 +38,7 @@ class Observer::Ticket::ArticleChanges < ActiveRecord::Observer
|
||||||
|
|
||||||
# save ticket
|
# save ticket
|
||||||
if !changed
|
if !changed
|
||||||
record.ticket.touch
|
record.ticket.touch # rubocop:disable Rails/SkipsModelValidations
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
record.ticket.save!
|
record.ticket.save!
|
||||||
|
|
|
@ -24,26 +24,24 @@ class Observer::Ticket::RefObjectTouch < ActiveRecord::Observer
|
||||||
cutomer_id_changed = record.saved_changes['customer_id']
|
cutomer_id_changed = record.saved_changes['customer_id']
|
||||||
if cutomer_id_changed && cutomer_id_changed[0] != cutomer_id_changed[1]
|
if cutomer_id_changed && cutomer_id_changed[0] != cutomer_id_changed[1]
|
||||||
if cutomer_id_changed[0]
|
if cutomer_id_changed[0]
|
||||||
User.find(cutomer_id_changed[0]).touch
|
User.find(cutomer_id_changed[0]).touch # rubocop:disable Rails/SkipsModelValidations
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# touch new/current customer
|
# touch new/current customer
|
||||||
if record.customer
|
record.customer&.touch
|
||||||
record.customer.touch
|
|
||||||
end
|
|
||||||
|
|
||||||
# touch old organization if changed
|
# touch old organization if changed
|
||||||
organization_id_changed = record.saved_changes['organization_id']
|
organization_id_changed = record.saved_changes['organization_id']
|
||||||
if organization_id_changed && organization_id_changed[0] != organization_id_changed[1]
|
if organization_id_changed && organization_id_changed[0] != organization_id_changed[1]
|
||||||
if organization_id_changed[0]
|
if organization_id_changed[0]
|
||||||
Organization.find(organization_id_changed[0]).touch
|
Organization.find(organization_id_changed[0]).touch # rubocop:disable Rails/SkipsModelValidations
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# touch new/current organization
|
# touch new/current organization
|
||||||
return true if !record.organization
|
return true if !record.organization
|
||||||
|
|
||||||
record.organization.touch
|
record.organization.touch # rubocop:disable Rails/SkipsModelValidations
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,7 +9,7 @@ class Observer::Ticket::ResetNewState < ActiveRecord::Observer
|
||||||
return if Setting.get('import_mode')
|
return if Setting.get('import_mode')
|
||||||
|
|
||||||
# only change state if not processed via postmaster
|
# only change state if not processed via postmaster
|
||||||
return if ApplicationHandleInfo.current.split('.')[1] == 'postmaster'
|
return if ApplicationHandleInfo.postmaster?
|
||||||
|
|
||||||
# if article in internal
|
# if article in internal
|
||||||
return true if record.internal
|
return true if record.internal
|
||||||
|
|
|
@ -33,14 +33,14 @@ class Observer::Transaction < ActiveRecord::Observer
|
||||||
sync_backends = []
|
sync_backends = []
|
||||||
Setting.where(area: 'Transaction::Backend::Sync').order(:name).each do |setting|
|
Setting.where(area: 'Transaction::Backend::Sync').order(:name).each do |setting|
|
||||||
backend = Setting.get(setting.name)
|
backend = Setting.get(setting.name)
|
||||||
next if params[:disable] && params[:disable].include?(backend)
|
next if params[:disable]&.include?(backend)
|
||||||
sync_backends.push Kernel.const_get(backend)
|
sync_backends.push Kernel.const_get(backend)
|
||||||
end
|
end
|
||||||
|
|
||||||
# get uniq objects
|
# get uniq objects
|
||||||
list_objects = get_uniq_changes(list)
|
list_objects = get_uniq_changes(list)
|
||||||
list_objects.each do |_object, objects|
|
list_objects.each_value do |objects|
|
||||||
objects.each do |_id, item|
|
objects.each_value do |item|
|
||||||
|
|
||||||
# execute sync backends
|
# execute sync backends
|
||||||
sync_backends.each do |backend|
|
sync_backends.each do |backend|
|
||||||
|
@ -215,7 +215,7 @@ class Observer::Transaction < ActiveRecord::Observer
|
||||||
end
|
end
|
||||||
|
|
||||||
# do not send anything if nothing has changed
|
# do not send anything if nothing has changed
|
||||||
return true if real_changes.empty?
|
return true if real_changes.blank?
|
||||||
|
|
||||||
changed_by_id = nil
|
changed_by_id = nil
|
||||||
changed_by_id = if record.respond_to?('updated_by_id')
|
changed_by_id = if record.respond_to?('updated_by_id')
|
||||||
|
|
|
@ -16,7 +16,7 @@ class Observer::User::Geo < ActiveRecord::Observer
|
||||||
# check if geo need to be updated
|
# check if geo need to be updated
|
||||||
def check_geo(record)
|
def check_geo(record)
|
||||||
|
|
||||||
location = %w(address street zip city country)
|
location = %w[address street zip city country]
|
||||||
|
|
||||||
# check if geo update is needed based on old/new location
|
# check if geo update is needed based on old/new location
|
||||||
if record.id
|
if record.id
|
||||||
|
@ -45,7 +45,7 @@ class Observer::User::Geo < ActiveRecord::Observer
|
||||||
# update geo data of user
|
# update geo data of user
|
||||||
def geo_update(record)
|
def geo_update(record)
|
||||||
address = ''
|
address = ''
|
||||||
location = %w(address street zip city country)
|
location = %w[address street zip city country]
|
||||||
location.each do |item|
|
location.each do |item|
|
||||||
next if record[item].blank?
|
next if record[item].blank?
|
||||||
if address.present?
|
if address.present?
|
||||||
|
|
|
@ -29,7 +29,7 @@ class Observer::User::RefObjectTouch < ActiveRecord::Observer
|
||||||
# featrue used for different propose, do not touch references
|
# featrue used for different propose, do not touch references
|
||||||
if User.where(organization_id: organization_id_changed[0]).count < 100
|
if User.where(organization_id: organization_id_changed[0]).count < 100
|
||||||
organization = Organization.find(organization_id_changed[0])
|
organization = Organization.find(organization_id_changed[0])
|
||||||
organization.touch
|
organization.touch # rubocop:disable Rails/SkipsModelValidations
|
||||||
member_ids = organization.member_ids
|
member_ids = organization.member_ids
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -40,7 +40,7 @@ class Observer::User::RefObjectTouch < ActiveRecord::Observer
|
||||||
|
|
||||||
# featrue used for different propose, do not touch references
|
# featrue used for different propose, do not touch references
|
||||||
if User.where(organization_id: record.organization_id).count < 100
|
if User.where(organization_id: record.organization_id).count < 100
|
||||||
record.organization.touch
|
record.organization.touch # rubocop:disable Rails/SkipsModelValidations
|
||||||
member_ids += record.organization.member_ids
|
member_ids += record.organization.member_ids
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -48,7 +48,7 @@ class Observer::User::RefObjectTouch < ActiveRecord::Observer
|
||||||
# touch old/current customer
|
# touch old/current customer
|
||||||
member_ids.uniq.each do |user_id|
|
member_ids.uniq.each do |user_id|
|
||||||
next if user_id == record.id
|
next if user_id == record.id
|
||||||
User.find(user_id).touch
|
User.find(user_id).touch # rubocop:disable Rails/SkipsModelValidations
|
||||||
end
|
end
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
|
@ -55,7 +55,7 @@ returns
|
||||||
|
|
||||||
data[ app_model_organization ][ id ] = local_attributes
|
data[ app_model_organization ][ id ] = local_attributes
|
||||||
end
|
end
|
||||||
%w(created_by_id updated_by_id).each do |local_user_id|
|
%w[created_by_id updated_by_id].each do |local_user_id|
|
||||||
next if !self[ local_user_id ]
|
next if !self[ local_user_id ]
|
||||||
next if data[ app_model_user ][ self[ local_user_id ] ]
|
next if data[ app_model_user ][ self[ local_user_id ] ]
|
||||||
user = User.lookup(id: self[ local_user_id ])
|
user = User.lookup(id: self[ local_user_id ])
|
||||||
|
|
|
@ -17,26 +17,47 @@ class Overview < ApplicationModel
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
|
|
||||||
before_create :fill_link_on_create, :fill_prio
|
before_create :fill_link_on_create, :fill_prio
|
||||||
before_update :fill_link_on_update
|
before_update :fill_link_on_update, :rearrangement
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def rearrangement
|
||||||
|
return true if !changes['prio']
|
||||||
|
prio = 0
|
||||||
|
Overview.all.order(prio: :asc, updated_at: :desc).pluck(:id).each do |overview_id|
|
||||||
|
prio += 1
|
||||||
|
next if id == overview_id
|
||||||
|
Overview.without_callback(:update, :before, :rearrangement) do
|
||||||
|
overview = Overview.find(overview_id)
|
||||||
|
next if overview.prio == prio
|
||||||
|
overview.prio = prio
|
||||||
|
overview.save!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def fill_prio
|
def fill_prio
|
||||||
return true if prio
|
return true if prio.present?
|
||||||
self.prio = 9999
|
self.prio = Overview.count + 1
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def fill_link_on_create
|
def fill_link_on_create
|
||||||
return true if link.present?
|
self.link = if link.present?
|
||||||
self.link = link_name(name)
|
link_name(link)
|
||||||
|
else
|
||||||
|
link_name(name)
|
||||||
|
end
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def fill_link_on_update
|
def fill_link_on_update
|
||||||
return true if !changes['name']
|
return true if !changes['name'] && !changes['link']
|
||||||
return true if changes['link']
|
self.link = if link.present?
|
||||||
self.link = link_name(name)
|
link_name(link)
|
||||||
|
else
|
||||||
|
link_name(name)
|
||||||
|
end
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -45,17 +66,21 @@ class Overview < ApplicationModel
|
||||||
local_link = local_link.parameterize(separator: '_')
|
local_link = local_link.parameterize(separator: '_')
|
||||||
local_link.gsub!(/\s/, '_')
|
local_link.gsub!(/\s/, '_')
|
||||||
local_link.gsub!(/_+/, '_')
|
local_link.gsub!(/_+/, '_')
|
||||||
local_link = URI.escape(local_link)
|
local_link = CGI.escape(local_link)
|
||||||
if local_link.blank?
|
if local_link.blank?
|
||||||
local_link = id || rand(999)
|
local_link = id || rand(999)
|
||||||
end
|
end
|
||||||
check = true
|
check = true
|
||||||
|
count = 0
|
||||||
|
local_lookup_link = local_link
|
||||||
while check
|
while check
|
||||||
exists = Overview.find_by(link: local_link)
|
count += 1
|
||||||
if exists && exists.id != id
|
exists = Overview.find_by(link: local_lookup_link)
|
||||||
local_link = "#{local_link}_#{rand(999)}"
|
if exists && exists.id != id # rubocop:disable Style/SafeNavigation
|
||||||
|
local_lookup_link = "#{local_link}_#{count}"
|
||||||
else
|
else
|
||||||
check = false
|
check = false
|
||||||
|
local_link = local_lookup_link
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local_link
|
local_link
|
||||||
|
|
|
@ -34,19 +34,15 @@ returns
|
||||||
end
|
end
|
||||||
if !data[ app_model_overview ][ id ]
|
if !data[ app_model_overview ][ id ]
|
||||||
data[ app_model_overview ][ id ] = attributes_with_association_ids
|
data[ app_model_overview ][ id ] = attributes_with_association_ids
|
||||||
if user_ids
|
user_ids&.each do |local_user_id|
|
||||||
user_ids.each do |local_user_id|
|
next if data[ app_model_user ][ local_user_id ]
|
||||||
next if data[ app_model_user ][ local_user_id ]
|
user = User.lookup(id: local_user_id)
|
||||||
user = User.lookup(id: local_user_id)
|
next if !user
|
||||||
next if !user
|
data = user.assets(data)
|
||||||
data = user.assets(data)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
data = assets_of_selector('condition', data)
|
data = assets_of_selector('condition', data)
|
||||||
|
|
||||||
end
|
end
|
||||||
%w(created_by_id updated_by_id).each do |local_user_id|
|
%w[created_by_id updated_by_id].each do |local_user_id|
|
||||||
next if !self[ local_user_id ]
|
next if !self[ local_user_id ]
|
||||||
next if data[ app_model_user ][ self[ local_user_id ] ]
|
next if data[ app_model_user ][ self[ local_user_id ] ]
|
||||||
user = User.lookup(id: self[ local_user_id ])
|
user = User.lookup(id: self[ local_user_id ])
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue