1# --
2# Copyright (C) 2001-2020 OTRS AG, https://otrs.com/
3# --
4# This software comes with ABSOLUTELY NO WARRANTY. For details, see
5# the enclosed file COPYING for license information (GPL). If you
6# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
7# --
8
9# Default configuration for OTRS. All changes to this file will be lost after an
10#   update, please use AdminSystemConfiguration to configure your system.
11
12## nofilter(TidyAll::Plugin::OTRS::Perl::LayoutObject)
13
14package Kernel::Config::Defaults;
15
16use strict;
17use warnings;
18use utf8;
19
20# Perl 5.16.0 is the required minimum version to use OTRS.
21use 5.016_000;
22
23# prepend '../Custom', '../Kernel/cpan-lib' and '../' to the module search path @INC
24use File::Basename;
25use FindBin qw($Bin);
26use lib dirname($Bin);
27use lib dirname($Bin) . '/Kernel/cpan-lib';
28use lib dirname($Bin) . '/Custom';
29
30use File::stat;
31use Digest::MD5;
32
33use Exporter qw(import);
34our @EXPORT = qw(Translatable); ## no critic (allow automatic export)
35
36our @ObjectDependencies = ();
37
38=head1 NAME
39
40Kernel::Config::Defaults - Base class for the ConfigObject.
41
42=head1 DESCRIPTION
43
44This class implements several internal functions that are used internally in
45L<Kernel::Config>. The two externally used functions are documented as part
46of L<Kernel::Config>, even though they are actually implemented here.
47
48=head1 PUBLIC INTERFACE
49
50=head2 LoadDefaults()
51
52loads the default values of settings that are required to run OTRS even
53when it was not fully configured yet.
54
55=cut
56
57sub LoadDefaults {
58    my $Self = shift;
59
60    # Make any created files readable by owner and group, not by others.
61    # Do this on every instantiation to make sure it also works after fork()
62    #   and in long-running mod_perl or similar environments.
63    umask 0007;
64
65    # --------------------------------------------------- #
66    # system data                                         #
67    # --------------------------------------------------- #
68    # SecureMode
69    # Disables the use of web-installer (installer.pl).
70    # GenericAgent, PackageManager and SQL Box can only be used if SecureMode is enabled.
71    $Self->{SecureMode} = 0;
72
73    # SystemID
74    # (The identify of the system. Each ticket number and
75    # each HTTP session id starts with this number)
76    $Self->{SystemID} = 10;
77
78    # NodeID
79    # (The identify of the node. In a clustered environment
80    # each node needs a separate NodeID. On a setup with just
81    # one frontend server, it is not needed to change this setting)
82    $Self->{NodeID} = 1;
83
84    # FQDN
85    # (Full qualified domain name of your system.)
86    $Self->{FQDN} = 'yourhost.example.com';
87
88    # HttpType
89    # In case you use HTTPS instead of plain HTTP specify it here
90    $Self->{HttpType} = 'http';
91
92    # ScriptAlias
93    # Prefix to index.pl used as ScriptAlias in web config
94    # (Used when emailing links to agents).
95    $Self->{ScriptAlias} = 'otrs/';
96
97    # AdminEmail
98    # (Email of the system admin.)
99    $Self->{AdminEmail} = 'support@<OTRS_CONFIG_FQDN>';
100
101    # Organization
102    # (If this is anything other than '', then the email will have an
103    # Organization X-Header)
104    $Self->{Organization} = 'Example Company';
105
106    # ProductName
107    # (Application name displayed in frontend.)
108    $Self->{ProductName} = 'OTRS 6';
109
110    # --------------------------------------------------- #
111    # database settings                                   #
112    # --------------------------------------------------- #
113    # DatabaseHost
114    # (The database host.)
115    $Self->{DatabaseHost} = 'localhost';
116
117    # Database
118    # (The database name.)
119    $Self->{Database} = 'otrs';
120
121    # DatabaseUser
122    # (The database user.)
123    $Self->{DatabaseUser} = 'otrs';
124
125    # DatabasePw
126    # (The password of database user.)
127    $Self->{DatabasePw} = 'some-pass';
128
129    # DatabaseDSN
130    # The database DSN for MySQL ==> more: "perldoc DBD::mysql"
131    $Self->{DatabaseDSN} = "DBI:mysql:database=<OTRS_CONFIG_Database>;host=<OTRS_CONFIG_DatabaseHost>;";
132
133    # The database DSN for PostgreSQL ==> more: "perldoc DBD::Pg"
134#    $Self->{DatabaseDSN} = "DBI:Pg:dbname=<OTRS_CONFIG_Database>;host=<OTRS_CONFIG_DatabaseHost>;";
135
136    # The database DSN for Oracle ==> more: "perldoc DBD::oracle"
137#    $Self->{DatabaseDSN} = "DBI:Oracle://$Self->{DatabaseHost}:1521/$Self->{Database}";
138#
139#    $ENV{ORACLE_HOME}     = '/path/to/your/oracle';
140#    $ENV{NLS_DATE_FORMAT} = 'YYYY-MM-DD HH24:MI:SS';
141#    $ENV{NLS_LANG}        = 'AMERICAN_AMERICA.AL32UTF8';
142#    $ENV{NLS_LANG}        = 'GERMAN_GERMANY.AL32UTF8';
143
144    # If you want to use an init sql after connect, use this here.
145    # (e. g. can be used for mysql encoding between client and server)
146    #    $Self->{'Database::Connect'} = 'SET NAMES utf8';
147
148    # If you want to use the sql slow log feature, enable this here.
149    # (To log every sql query which takes longer the 4 sec.)
150    #    $Self->{'Database::SlowLog'} = 0;
151
152    # --------------------------------------------------- #
153    # default values                                      #
154    # (default values for GUIs)                           #
155    # --------------------------------------------------- #
156    # default valid
157    $Self->{DefaultValid} = 'valid';
158
159    # DEPRECATED. Compatibilty setting for older 3.0 code.
160    # Internal charset must always be utf-8.
161    $Self->{DefaultCharset} = 'utf-8';
162
163    # default language
164    # (the default frontend language) [default: en]
165    $Self->{DefaultLanguage} = 'en';
166
167    # used languages
168    # (short name = long name and file)
169    $Self->{DefaultUsedLanguages} = {
170        'ar_SA'   => 'Arabic (Saudi Arabia)',
171        'bg'      => 'Bulgarian',
172        'ca'      => 'Catalan',
173        'cs'      => 'Czech',
174        'da'      => 'Danish',
175        'de'      => 'German',
176        'en'      => 'English (United States)',
177        'en_CA'   => 'English (Canada)',
178        'en_GB'   => 'English (United Kingdom)',
179        'es'      => 'Spanish',
180        'es_CO'   => 'Spanish (Colombia)',
181        'es_MX'   => 'Spanish (Mexico)',
182        'et'      => 'Estonian',
183        'el'      => 'Greek',
184        'fa'      => 'Persian',
185        'fi'      => 'Finnish',
186        'fr'      => 'French',
187        'fr_CA'   => 'French (Canada)',
188        'gl'      => 'Galician',
189        'he'      => 'Hebrew',
190        'hi'      => 'Hindi',
191        'hr'      => 'Croatian',
192        'hu'      => 'Hungarian',
193        'id'      => 'Indonesian',
194        'it'      => 'Italian',
195        'ja'      => 'Japanese',
196        'ko'      => 'Korean',
197        'lt'      => 'Lithuanian',
198        'lv'      => 'Latvian',
199        'mk'      => 'Macedonian',
200        'ms'      => 'Malay',
201        'nl'      => 'Dutch',
202        'nb_NO'   => 'Norwegian',
203        'pt_BR'   => 'Portuguese (Brasil)',
204        'pt'      => 'Portuguese',
205        'pl'      => 'Polish',
206        'ro'      => 'Romanian',
207        'ru'      => 'Russian',
208        'sl'      => 'Slovenian',
209        'sr_Latn' => 'Serbian Latin',
210        'sr_Cyrl' => 'Serbian Cyrillic',
211        'sk_SK'   => 'Slovak',
212        'sv'      => 'Swedish',
213        'sw'      => 'Swahili',
214        'th_TH'   => 'Thai',
215        'tr'      => 'Turkish',
216        'uk'      => 'Ukrainian',
217        'vi_VN'   => 'Vietnam',
218        'zh_CN'   => 'Chinese (Simplified)',
219        'zh_TW'   => 'Chinese (Traditional)',
220    };
221
222    $Self->{DefaultUsedLanguagesNative} = {
223        'ar_SA'   => 'العَرَبِية‎',
224        'bg'      => 'Български',
225        'ca'      => 'Català',
226        'cs'      => 'Česky',
227        'da'      => 'Dansk',
228        'de'      => 'Deutsch',
229        'en'      => 'English (United States)',
230        'en_CA'   => 'English (Canada)',
231        'en_GB'   => 'English (United Kingdom)',
232        'es'      => 'Español',
233        'es_CO'   => 'Español (Colombia)',
234        'es_MX'   => 'Español (México)',
235        'et'      => 'Eesti',
236        'el'      => 'Ελληνικά',
237        'fa'      => 'فارسى',
238        'fi'      => 'Suomi',
239        'fr'      => 'Français',
240        'fr_CA'   => 'Français (Canada)',
241        'gl'      => 'Galego',
242        'he'      => 'עברית',
243        'hi'      => 'हिन्दी',
244        'hr'      => 'Hrvatski',
245        'hu'      => 'Magyar',
246        'id'      => 'Bahasa Indonesia',
247        'it'      => 'Italiano',
248        'ja'      => '日本語',
249        'ko'      => '한국어',
250        'lt'      => 'Lietuvių kalba',
251        'lv'      => 'Latvijas',
252        'mk'      => 'Mакедонски',
253        'ms'      => 'Melayu',
254        'nl'      => 'Nederlandse',
255        'nb_NO'   => 'Norsk bokmål',
256        'pt_BR'   => 'Português Brasileiro',
257        'pt'      => 'Português',
258        'pl'      => 'Polski',
259        'ro'      => 'Română',
260        'ru'      => 'Русский',
261        'sl'      => 'Slovenščina',
262        'sr_Latn' => 'Srpski',
263        'sr_Cyrl' => 'Српски',
264        'sk_SK'   => 'Slovenčina',
265        'sv'      => 'Svenska',
266        'sw'      => 'Kiswahili',
267        'th_TH'   => 'ภาษาไทย',
268        'tr'      => 'Türkçe',
269        'uk'      => 'Українська',
270        'vi_VN'   => 'ViɆt Nam',
271        'zh_CN'   => '简体中文',
272        'zh_TW'   => '正體中文',
273    };
274
275    # default theme
276    # (the default HTML theme) [default: Standard]
277    $Self->{DefaultTheme} = 'Standard';
278
279    # DefaultTheme::HostBased
280    # (set theme based on host name)
281#    $Self->{'DefaultTheme::HostBased'} = {
282#        'host1\.example\.com' => 'SomeTheme1',
283#        'host2\.example\.com' => 'SomeTheme1',
284#    };
285
286    # Frontend::WebPath
287    # (URL base path of icons, CSS and Java Script.)
288    $Self->{'Frontend::WebPath'} = '/otrs-web/';
289
290    # Frontend::JavaScriptPath
291    # (URL JavaScript path.)
292    $Self->{'Frontend::JavaScriptPath'} = '<OTRS_CONFIG_Frontend::WebPath>js/';
293
294    # Frontend::CSSPath
295    # (URL CSS path.)
296    $Self->{'Frontend::CSSPath'} = '<OTRS_CONFIG_Frontend::WebPath>css/';
297
298    # Frontend::ImagePath
299    # (URL image path of icons for navigation.)
300    $Self->{'Frontend::ImagePath'} = '<OTRS_CONFIG_Frontend::WebPath>skins/Agent/default/img/';
301
302    # DefaultViewNewLine
303    # (insert new line in text messages after max x chars and
304    # the next word)
305    $Self->{DefaultViewNewLine} = 90;
306
307    # DefaultViewLines
308    # (Max viewable lines in text messages (like ticket lines
309    # in QueueZoom)
310    $Self->{DefaultViewLines} = 6000;
311
312    # ShowAlwaysLongTime
313    # (show always time in long /days hours minutes/ or short
314    # /days hours/ format)
315    $Self->{ShowAlwaysLongTime} = 0;
316    $Self->{TimeShowAlwaysLong} = 0;
317
318    # TimeInputFormat
319    # (default date input format) [Option|Input]
320    $Self->{TimeInputFormat} = 'Option';
321
322    # TimeInputMinutesStep
323    # (default minute step in minutes dropdown) [1,2,5,10,15,30]
324    $Self->{TimeInputMinutesStep} = 1;
325
326    # AttachmentDownloadType
327    # (if the tickets attachments will be opened in browser or just to
328    # force the download) [attachment|inline]
329    #    $Self->{'AttachmentDownloadType'} = 'inline';
330    $Self->{AttachmentDownloadType} = 'attachment';
331
332    # --------------------------------------------------- #
333    # Check Settings
334    # --------------------------------------------------- #
335    # CheckEmailAddresses
336    # (Check syntax of used email addresses)
337    $Self->{CheckEmailAddresses} = 1;
338
339    # CheckMXRecord
340    # (Check mx recorde of used email addresses)
341    $Self->{CheckMXRecord} = 1;
342
343    # CheckEmailValidAddress
344    # (regexp of valid email addresses)
345    $Self->{CheckEmailValidAddress} = '^(root@localhost|admin@localhost)$';
346
347    # CheckEmailInvalidAddress
348    # (regexp of invalid email addresses)
349    $Self->{CheckEmailInvalidAddress} = '@(example)\.(..|...)$';
350
351    # --------------------------------------------------- #
352    # LogModule                                           #
353    # --------------------------------------------------- #
354    # (log backend module)
355    $Self->{LogModule} = 'Kernel::System::Log::SysLog';
356
357#    $Self->{'LogModule'} = 'Kernel::System::Log::File';
358
359    # param for LogModule Kernel::System::Log::SysLog
360    $Self->{'LogModule::SysLog::Facility'} = 'user';
361
362    # param for LogModule Kernel::System::Log::SysLog
363    # (if syslog can't work with utf-8, force the log
364    # charset with this option, on other chars will be
365    # replaces with ?)
366    $Self->{'LogModule::SysLog::Charset'} = 'utf-8';
367
368#    $Self->{'LogModule::SysLog::Charset'} = 'utf-8';
369
370    # param for LogModule Kernel::System::Log::File (required!)
371    $Self->{'LogModule::LogFile'} = '/tmp/otrs.log';
372
373    # param if the date (yyyy-mm) should be added as suffix to
374    # logfile [0|1]
375#    $Self->{'LogModule::LogFile::Date'} = 0;
376
377    # system log cache size for admin system log (default 32k)
378    # $Self->{'LogSystemCacheSize'} = 32 * 1024;
379
380    # --------------------------------------------------- #
381    # SendmailModule
382    # --------------------------------------------------- #
383    # (Where is sendmail located and some options.
384    # See 'man sendmail' for details. Or use the SMTP backend.)
385    $Self->{'SendmailModule'}      = 'Kernel::System::Email::Sendmail';
386    $Self->{'SendmailModule::CMD'} = '/usr/sbin/sendmail -i -f';
387
388#    $Self->{'SendmailModule'} = 'Kernel::System::Email::SMTP';
389#    $Self->{'SendmailModule::Host'} = 'mail.example.com';
390#    $Self->{'SendmailModule::Port'} = '25';
391#    $Self->{'SendmailModule::AuthUser'} = '';
392#    $Self->{'SendmailModule::AuthPassword'} = '';
393
394    # SendmailBcc
395    # (Send all outgoing email via bcc to...
396    # Warning: use it only for external archive functions)
397    $Self->{SendmailBcc} = '';
398
399    # SendmailNotificationEnvelopeFrom
400    # Set a email address that is used as envelope from header in outgoing
401    # notifications
402#    $Self->{'SendmailNotificationEnvelopeFrom'} = '';
403
404    # --------------------------------------------------- #
405    # authentication settings                             #
406    # (enable what you need, auth against otrs db,        #
407    # against LDAP directory, against HTTP basic auth     #
408    # or against Radius server)                           #
409    # --------------------------------------------------- #
410    # This is the auth. module against the otrs db
411    $Self->{AuthModule} = 'Kernel::System::Auth::DB';
412
413    # defines AuthSyncBackend (AuthSyncModule) for AuthModule
414    # if this key exists and is empty, there won't be a sync.
415    # example values: AuthSyncBackend, AuthSyncBackend2
416#    $Self->{'AuthModule::UseSyncBackend'} = '';
417
418    # password crypt type (bcrypt|sha2|sha1|md5|apr1|crypt|plain)
419#    $Self->{'AuthModule::DB::CryptType'} = 'sha2';
420
421    # If "bcrypt" was selected for CryptType, use cost specified here for bcrypt hashing.
422    #   Currently max. supported cost value is 31.
423    # $Self->{'AuthModule::DB::bcryptCost'} = 12;
424
425    # This is an example configuration for an LDAP auth. backend.
426    # (take care that Net::LDAP is installed!)
427#    $Self->{AuthModule} = 'Kernel::System::Auth::LDAP';
428#    $Self->{'AuthModule::LDAP::Host'} = 'ldap.example.com';
429#    $Self->{'AuthModule::LDAP::BaseDN'} = 'dc=example,dc=com';
430#    $Self->{'AuthModule::LDAP::UID'} = 'uid';
431
432    # Check if the user is allowed to auth in a posixGroup
433    # (e. g. user needs to be in a group xyz to use otrs)
434#    $Self->{'AuthModule::LDAP::GroupDN'} = 'cn=otrsallow,ou=posixGroups,dc=example,dc=com';
435#    $Self->{'AuthModule::LDAP::AccessAttr'} = 'memberUid';
436    # for ldap posixGroups objectclass (just uid)
437#    $Self->{'AuthModule::LDAP::UserAttr'} = 'UID';
438    # for non ldap posixGroups objectclass (with full user dn)
439#    $Self->{'AuthModule::LDAP::UserAttr'} = 'DN';
440
441    # The following is valid but would only be necessary if the
442    # anonymous user do NOT have permission to read from the LDAP tree
443#    $Self->{'AuthModule::LDAP::SearchUserDN'} = '';
444#    $Self->{'AuthModule::LDAP::SearchUserPw'} = '';
445
446    # in case you want to add always one filter to each ldap query, use
447    # this option. e. g. AlwaysFilter => '(mail=*)' or AlwaysFilter => '(objectclass=user)'
448    # or if you want to filter with a locigal OR-Expression, like AlwaysFilter => '(|(mail=*abc.com)(mail=*xyz.com))'
449#    $Self->{'AuthModule::LDAP::AlwaysFilter'} = '';
450
451    # in case you want to add a suffix to each login name, then
452    # you can use this option. e. g. user just want to use user but
453    # in your ldap directory exists user@domain.
454#    $Self->{'AuthModule::LDAP::UserSuffix'} = '@domain.com';
455
456    # In case you want to convert all given usernames to lower letters you
457    # should activate this option. It might be helpful if databases are
458    # in use that do not distinguish selects for upper and lower case letters
459    # (Oracle, postgresql). User might be synched twice, if this option
460    # is not in use.
461#    $Self->{'AuthModule::LDAP::UserLowerCase'} = 0;
462
463    # In case you need to use OTRS in iso-charset, you can define this
464    # by using this option (converts utf-8 data from LDAP to iso).
465#    $Self->{'AuthModule::LDAP::Charset'} = 'iso-8859-1';
466
467    # Net::LDAP new params (if needed - for more info see perldoc Net::LDAP)
468#    $Self->{'AuthModule::LDAP::Params'} = {
469#        port    => 389,
470#        timeout => 120,
471#        async   => 0,
472#        version => 3,
473#    };
474
475    # Die if backend can't work, e. g. can't connect to server.
476#    $Self->{'AuthModule::LDAP::Die'} = 1;
477
478    # This is an example configuration for an apache ($ENV{REMOTE_USER})
479    # auth. backend. Use it if you want to have a singe login through
480    # apache http-basic-auth.
481#    $Self->{AuthModule} = 'Kernel::System::Auth::HTTPBasicAuth';
482    # In case there is a leading domain in the REMOTE_USER, you can
483    # replace it by the next config option.
484#    $Self->{'AuthModule::HTTPBasicAuth::Replace'} = 'example_domain\\';
485    # In case you need to replace some part of the REMOTE_USER, you can
486    # use the following RegExp ($1 will be new login).
487#    $Self->{'AuthModule::HTTPBasicAuth::ReplaceRegExp'} = '^(.+?)@.+?$';
488    # Note:
489    # If you use this module, you should use as fallback the following
490    # config settings if user isn't login through apache ($ENV{REMOTE_USER}).
491#    $Self->{LoginURL} = 'http://host.example.com/not-authorised-for-otrs.html';
492#    $Self->{LogoutURL} = 'http://host.example.com/thanks-for-using-otrs.html';
493
494    # This is example configuration to auth. agents against a radius server.
495#    $Self->{'AuthModule'} = 'Kernel::System::Auth::Radius';
496#    $Self->{'AuthModule::Radius::Host'} = 'radiushost';
497#    $Self->{'AuthModule::Radius::Password'} = 'radiussecret';
498
499    # Die if backend can't work, e. g. can't connect to server.
500#    $Self->{'AuthModule::Radius::Die'} = 1;
501
502    # --------------------------------------------------- #
503    # 2 factor authentication settings                    #
504    # check a otp (one-time password)                     #
505    # after successful authentication                     #
506    # as an extra security measure                        #
507    # --------------------------------------------------- #
508    # This is the auth module using the google authenticator mechanism
509#    $Self->{'AuthTwoFactorModule'} = 'Kernel::System::Auth::TwoFactor::GoogleAuthenticator';
510
511    # defines user preference where the secret key is stored
512#    $Self->{'AuthTwoFactorModule::SecretPreferencesKey'} = 'UserGoogleAuthenticatorSecretKey';
513
514    # defines if users can login without a 2 factor authentication if they have no stored shared secret
515#    $Self->{'AuthTwoFactorModule::AllowEmptySecret'} = '1';
516
517    # defines if the otp for the previous timespan (30-60sec ago) will also be valid
518    # helpful to account for timing issues (server and entry based)
519#    $Self->{'AuthTwoFactorModule::AllowPreviousToken'} = '1';
520
521    # --------------------------------------------------- #
522    # authentication sync settings                        #
523    # (enable agent data sync. after succsessful          #
524    # authentication)                                     #
525    # --------------------------------------------------- #
526    # This is an example configuration for an LDAP auth sync. backend.
527    # (take care that Net::LDAP is installed!)
528#    $Self->{AuthSyncModule} = 'Kernel::System::Auth::Sync::LDAP';
529#    $Self->{'AuthSyncModule::LDAP::Host'} = 'ldap.example.com';
530#    $Self->{'AuthSyncModule::LDAP::BaseDN'} = 'dc=example,dc=com';
531#    $Self->{'AuthSyncModule::LDAP::UID'} = 'uid';
532
533    # The following is valid but would only be necessary if the
534    # anonymous user do NOT have permission to read from the LDAP tree
535#    $Self->{'AuthSyncModule::LDAP::SearchUserDN'} = '';
536#    $Self->{'AuthSyncModule::LDAP::SearchUserPw'} = '';
537
538    # in case you want to add always one filter to each ldap query, use
539    # this option. e. g. AlwaysFilter => '(mail=*)' or AlwaysFilter => '(objectclass=user)'
540    # or if you want to filter with a logical OR-Expression, like AlwaysFilter => '(|(mail=*abc.com)(mail=*xyz.com))'
541#    $Self->{'AuthSyncModule::LDAP::AlwaysFilter'} = '';
542
543    # AuthSyncModule::LDAP::UserSyncMap
544    # (map if agent should create/synced from LDAP to DB after successful login)
545    # you may specify LDAP-Fields as either
546    #  * list, which will check each field. first existing will be picked ( ["givenName","cn","_empty"] )
547    #  * name of an LDAP-Field (may return empty strings) ("givenName")
548    #  * fixed strings, prefixed with an underscore: "_test", which will always return this fixed string
549#    $Self->{'AuthSyncModule::LDAP::UserSyncMap'} = {
550#        # DB -> LDAP
551#        UserFirstname => 'givenName',
552#        UserLastname  => 'sn',
553#        UserEmail     => 'mail',
554#    };
555
556    # In case you need to use OTRS in iso-charset, you can define this
557    # by using this option (converts utf-8 data from LDAP to iso).
558#    $Self->{'AuthSyncModule::LDAP::Charset'} = 'iso-8859-1';
559
560    # Net::LDAP new params (if needed - for more info see perldoc Net::LDAP)
561#    $Self->{'AuthSyncModule::LDAP::Params'} = {
562#        port    => 389,
563#        timeout => 120,
564#        async   => 0,
565#        version => 3,
566#    };
567
568    # Die if backend can't work, e. g. can't connect to server.
569#    $Self->{'AuthSyncModule::LDAP::Die'} = 1;
570
571    # Attributes needed for group syncs
572    # (attribute name for group value key)
573#    $Self->{'AuthSyncModule::LDAP::AccessAttr'} = 'memberUid';
574    # (attribute for type of group content UID/DN for full ldap name)
575#    $Self->{'AuthSyncModule::LDAP::UserAttr'} = 'UID';
576#    $Self->{'AuthSyncModule::LDAP::UserAttr'} = 'DN';
577
578    # AuthSyncModule::LDAP::UserSyncInitialGroups
579    # (sync following group with rw permission after initial create of first agent
580    # login)
581#    $Self->{'AuthSyncModule::LDAP::UserSyncInitialGroups'} = [
582#        'users',
583#    ];
584
585    # AuthSyncModule::LDAP::UserSyncGroupsDefinition
586    # (If "LDAP" was selected for AuthModule and you want to sync LDAP
587    # groups to otrs groups, define the following.)
588#    $Self->{'AuthSyncModule::LDAP::UserSyncGroupsDefinition'} = {
589#        # ldap group
590#        'cn=agent,o=otrs' => {
591#            # otrs group
592#            'admin' => {
593#                # permission
594#                rw => 1,
595#                ro => 1,
596#            },
597#            'faq' => {
598#                rw => 0,
599#                ro => 1,
600#            },
601#        },
602#        'cn=agent2,o=otrs' => {
603#            'users' => {
604#                rw => 1,
605#                ro => 1,
606#            },
607#        }
608#    };
609
610    # AuthSyncModule::LDAP::UserSyncRolesDefinition
611    # (If "LDAP" was selected for AuthModule and you want to sync LDAP
612    # groups to otrs roles, define the following.)
613#    $Self->{'AuthSyncModule::LDAP::UserSyncRolesDefinition'} = {
614#        # ldap group
615#        'cn=agent,o=otrs' => {
616#            # otrs role
617#            'role1' => 1,
618#            'role2' => 0,
619#        },
620#        'cn=agent2,o=otrs' => {
621#            'role3' => 1,
622#        }
623#    };
624
625    # AuthSyncModule::LDAP::UserSyncAttributeGroupsDefinition
626    # (If "LDAP" was selected for AuthModule and you want to sync LDAP
627    # attributes to otrs groups, define the following.)
628#    $Self->{'AuthSyncModule::LDAP::UserSyncAttributeGroupsDefinition'} = {
629#        # ldap attribute
630#        'LDAPAttribute' => {
631#            # ldap attribute value
632#            'LDAPAttributeValue1' => {
633#                # otrs group
634#                'admin' => {
635#                    # permission
636#                    rw => 1,
637#                    ro => 1,
638#                },
639#                'faq' => {
640#                    rw => 0,
641#                    ro => 1,
642#                },
643#            },
644#        },
645#        'LDAPAttribute2' => {
646#            'LDAPAttributeValue' => {
647#                'users' => {
648#                    rw => 1,
649#                    ro => 1,
650#                },
651#            },
652#         }
653#    };
654
655    # AuthSyncModule::LDAP::UserSyncAttributeRolesDefinition
656    # (If "LDAP" was selected for AuthModule and you want to sync LDAP
657    # attributes to otrs roles, define the following.)
658#    $Self->{'AuthSyncModule::LDAP::UserSyncAttributeRolesDefinition'} = {
659#        # ldap attribute
660#        'LDAPAttribute' => {
661#            # ldap attribute value
662#            'LDAPAttributeValue1' => {
663#                # otrs role
664#                'role1' => 1,
665#                'role2' => 1,
666#            },
667#        },
668#        'LDAPAttribute2' => {
669#            'LDAPAttributeValue1' => {
670#                'role3' => 1,
671#            },
672#        },
673#    };
674
675    # UserTable
676    $Self->{DatabaseUserTable}       = 'users';
677    $Self->{DatabaseUserTableUserID} = 'id';
678    $Self->{DatabaseUserTableUserPW} = 'pw';
679    $Self->{DatabaseUserTableUser}   = 'login';
680
681    # --------------------------------------------------- #
682    # URL login and logout settings                       #
683    # --------------------------------------------------- #
684
685    # LoginURL
686    # (If this is anything other than '', then it is assumed to be the
687    # URL of an alternate login screen which will be used in place of
688    # the default one.)
689#    $Self->{LoginURL} = '';
690#    $Self->{LoginURL} = 'http://host.example.com/cgi-bin/login.pl';
691
692    # LogoutURL
693    # (If this is anything other than '', it is assumed to be the URL
694    # of an alternate logout page which users will be sent to when they
695    # logout.)
696#    $Self->{LogoutURL} = '';
697#    $Self->{LogoutURL} = 'http://host.example.com/cgi-bin/login.pl';
698
699    # PreApplicationModule
700    # (Used for every request, if defined, the PreRun() function of
701    # this module will be used. This interface use useful to check
702    # some user options or to redirect not accept new application
703    # news)
704#    $Self->{PreApplicationModule}->{AgentInfo} = 'Kernel::Modules::AgentInfo';
705    # Kernel::Modules::AgentInfo check key, if this user preferences key
706    # is true, then the message is already accepted
707#    $Self->{InfoKey} = 'wpt22';
708    # shown InfoFile located under Kernel/Output/HTML/Templates/Standard/AgentInfo.tt
709#    $Self->{InfoFile} = 'AgentInfo';
710
711    # --------------------------------------------------- #
712    # Notification Settings
713    # --------------------------------------------------- #
714
715    # agent interface notification module to check the admin user id
716    # (don't work with user id 1 notification)
717    $Self->{'Frontend::NotifyModule'} = {
718        '1000-CloudServicesDisabled' => {
719            Group  => 'admin',
720            Module => 'Kernel::Output::HTML::Notification::AgentCloudServicesDisabled',
721        },
722        '1100-OTRSBusiness' => {
723            Group  => 'admin',
724            Module => 'Kernel::Output::HTML::Notification::AgentOTRSBusiness',
725        },
726        '2000-UID-Check' => {
727            Module => 'Kernel::Output::HTML::Notification::UIDCheck',
728        },
729        '2500-AgentSessionLimit' => {
730          'Module' => 'Kernel::Output::HTML::Notification::AgentSessionLimit',
731        },
732        '5000-SystemConfigurationIsDirty-Check' => {
733            Group  => 'admin',
734            Module => 'Kernel::Output::HTML::Notification::SystemConfigurationIsDirtyCheck',
735        },
736        '5200-SystemConfigurationInvalid-Check' => {
737            Group  => 'admin',
738            Module => 'Kernel::Output::HTML::Notification::SystemConfigurationInvalidCheck',
739        },
740        '5500-OutofOffice-Check' => {
741            Module => 'Kernel::Output::HTML::Notification::OutofOfficeCheck',
742        },
743        '6000-SystemMaintenance-Check' => {
744            Module => 'Kernel::Output::HTML::Notification::SystemMaintenanceCheck',
745        },
746        '6050-SystemConfiguration-OutOfSync-Check' =>  {
747            Module => 'Kernel::Output::HTML::Notification::SystemConfigurationOutOfSyncCheck',
748            AllowedDelayMinutes => '5',
749        },
750        '7000-AgentTimeZone-Check' => {
751            Module => 'Kernel::Output::HTML::Notification::AgentTimeZoneCheck',
752        },
753        '8000-Daemon-Check' => {
754            Module => 'Kernel::Output::HTML::Notification::DaemonCheck',
755        },
756    };
757
758    # Make sure the daemon is able to deploy the configuration to all cluster nodes that have no ZZZAAuto.pm yet.
759    $Self->{DaemonModules}->{SystemConfigurationSyncManager} =  {
760      Module => 'Kernel::System::Daemon::DaemonModules::SystemConfigurationSyncManager'
761    };
762
763    # --------------------------------------------------- #
764    #                                                     #
765    #             Start of config options!!!              #
766    #                   Session stuff                     #
767    #                                                     #
768    # --------------------------------------------------- #
769
770    # --------------------------------------------------- #
771    # SessionModule                                       #
772    # --------------------------------------------------- #
773    # (How should be the session-data stored?
774    # Advantage of DB is that you can split the
775    # Frontendserver from the db-server. fs is faster.)
776    $Self->{SessionModule} = 'Kernel::System::AuthSession::DB';
777
778#    $Self->{SessionModule} = 'Kernel::System::AuthSession::FS';
779
780    # SessionName
781    # (Name of the session key. E. g. Session, SessionID, OTRS)
782    $Self->{SessionName} = 'OTRSAgentInterface';
783
784    # SessionCheckRemoteIP
785    # (If the application is used via a proxy-farm then the
786    # remote ip address is mostly different. In this case,
787    # turn of the CheckRemoteID. ) [1|0]
788    $Self->{SessionCheckRemoteIP} = 1;
789
790    # SessionDeleteIfNotRemoteID
791    # (Delete session if the session id is used with an
792    # invalied remote IP?) [0|1]
793    $Self->{SessionDeleteIfNotRemoteID} = 1;
794
795    # SessionMaxTime
796    # (Max valid time of one session id in second (8h = 28800).)
797    $Self->{SessionMaxTime} = 16 * 60 * 60;
798
799    # SessionMaxIdleTime
800    # (After this time (in seconds) without new http request, then
801    # the user get logged off)
802    $Self->{SessionMaxIdleTime} = 2 * 60 * 60;
803
804    # SessionDeleteIfTimeToOld
805    # (Delete session's witch are requested and to old?) [0|1]
806    $Self->{SessionDeleteIfTimeToOld} = 1;
807
808    # SessionUseCookie
809    # (Should the session management use html cookies?
810    # It's more comfortable to send links -==> if you have a valid
811    # session, you don't have to login again.) [0|1]
812    # Note: If the client browser disabled html cookies, the system
813    # will work as usual, append SessionID to links!
814    $Self->{SessionUseCookie} = 1;
815
816    # SessionUseCookieAfterBrowserClose
817    # (store cookies in browser after closing a browser) [0|1]
818    $Self->{SessionUseCookieAfterBrowserClose} = 0;
819
820    # SessionDir
821    # directory for all sessen id information (just needed if
822    # $Self->{SessionModule}='Kernel::System::AuthSession::FS)
823    $Self->{SessionDir} = '<OTRS_CONFIG_Home>/var/sessions';
824
825    # SessionTable*
826    # (just needed if $Self->{SessionModule}='Kernel::System::AuthSession::DB)
827    # SessionTable
828    $Self->{SessionTable} = 'sessions';
829
830    # --------------------------------------------------- #
831    # Time Settings
832    # --------------------------------------------------- #
833    # TimeZone
834    # (set the OTRS time zone, default is UTC)
835#    $Self->{'OTRSTimeZone'} = 'UTC';
836
837    # Time*
838    # (Used for ticket age, escalation and system unlock calculation)
839
840    # TimeWorkingHours
841    # (counted hours for working time used)
842    $Self->{TimeWorkingHours} = {
843        Mon => [ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ],
844        Tue => [ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ],
845        Wed => [ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ],
846        Thu => [ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ],
847        Fri => [ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ],
848        Sat => [],
849        Sun => [],
850    };
851
852    $Self->{TimeVacationDays} = {
853        1 => {
854            1 => 'New Year\'s Day',
855        },
856        5 => {
857            1 => 'International Workers\' Day',
858        },
859        12 => {
860            24 => 'Christmas Eve',
861            25 => 'First Christmas Day',
862            26 => 'Second Christmas Day',
863            31 => 'New Year\'s Eve',
864        },
865    };
866
867    $Self->{TimeVacationDaysOneTime} = {
868        2004 => {
869            1 => {
870                1 => 'test',
871            },
872        },
873    };
874
875    # --------------------------------------------------- #
876    # Web Settings
877    # --------------------------------------------------- #
878    # WebMaxFileUpload
879    # (Max size for browser file uploads - default ~ 24 MB)
880    $Self->{WebMaxFileUpload} = 24000000;
881
882    # WebUploadCacheModule
883    # (select you WebUploadCacheModule module, default DB [DB|FS])
884    $Self->{WebUploadCacheModule} = 'Kernel::System::Web::UploadCache::DB';
885
886#    $Self->{WebUploadCacheModule} = 'Kernel::System::Web::UploadCache::FS';
887
888    # CGILogPrefix
889    $Self->{CGILogPrefix} = 'OTRS-CGI';
890
891    # --------------------------------------------------- #
892    # Agent Web Interface
893    # --------------------------------------------------- #
894    # LostPassword
895    # (use lost password feature)
896    $Self->{LostPassword} = 1;
897
898    # ShowMotd
899    # (show message of the day in login screen)
900    $Self->{ShowMotd} = 0;
901
902    # DemoSystem
903    # (If this is true, no agent preferences, like language and theme, via agent
904    # frontend can be updated! Just for the current session. Alow no password can
905    # be changed on agent frontend.)
906    $Self->{DemoSystem} = 0;
907
908    # SwitchToUser
909    # (Allow the admin to switch into a selected user session.)
910    $Self->{SwitchToUser} = 0;
911
912    # --------------------------------------------------- #
913    # MIME-Viewer for online to html converter
914    # --------------------------------------------------- #
915    # (e. g. xlhtml (xls2html), http://chicago.sourceforge.net/xlhtml/)
916#    $Self->{'MIME-Viewer'}->{'application/excel'} = 'xlhtml';
917    # MIME-Viewer for online to html converter
918    # (e. g. wv (word2html), http://wvware.sourceforge.net/)
919#    $Self->{'MIME-Viewer'}->{'application/msword'} = 'wvWare';
920    # (e. g. pdftohtml (pdf2html), http://pdftohtml.sourceforge.net/)
921#    $Self->{'MIME-Viewer'}->{'application/pdf'} = 'pdftohtml -stdout -i';
922    # (e. g. xml2html (xml2html))
923#    $Self->{'MIME-Viewer'}->{'text/xml'} = $Self->{Home}.'/scripts/tools/xml2html.pl';
924
925    # --------------------------------------------------- #
926    # directories                                         #
927    # --------------------------------------------------- #
928    # root directory
929    $Self->{Home} = '/opt/otrs';
930
931    # tmp dir
932    $Self->{TempDir} = '<OTRS_CONFIG_Home>/var/tmp';
933
934    # article dir
935    $Self->{'Ticket::Article::Backend::MIMEBase::ArticleDataDir'} = '<OTRS_CONFIG_Home>/var/article';
936
937    # html template dirs
938    $Self->{TemplateDir}       = '<OTRS_CONFIG_Home>/Kernel/Output';
939    $Self->{CustomTemplateDir} = '<OTRS_CONFIG_Home>/Custom/Kernel/Output';
940
941    # --------------------------------------------------- #
942    # CommonCSS                                           #
943    # --------------------------------------------------- #
944
945    # Customer Common CSS
946    $Self->{'Loader::Customer::CommonCSS'}->{'000-Framework'} = [
947        'Core.Reset.css',
948        'Core.Default.css',
949        'Core.Form.css',
950        'Core.Dialog.css',
951        'Core.Tooltip.css',
952        'Core.Login.css',
953        'Core.Control.css',
954        'Core.Table.css',
955        'Core.TicketZoom.css',
956        'Core.InputFields.css',
957        'Core.Print.css',
958        'Core.Animations.css',
959    ];
960
961    # Agent Common CSS
962    $Self->{'Loader::Agent::CommonCSS'}->{'000-Framework'} = [
963        'Core.Reset.css',
964        'Core.Default.css',
965        'Core.Header.css',
966        'Core.OverviewControl.css',
967        'Core.OverviewSmall.css',
968        'Core.OverviewMedium.css',
969        'Core.OverviewLarge.css',
970        'Core.Footer.css',
971        'Core.PageLayout.css',
972        'Core.Form.css',
973        'Core.Table.css',
974        'Core.Login.css',
975        'Core.Widget.css',
976        'Core.WidgetMenu.css',
977        'Core.TicketDetail.css',
978        'Core.Tooltip.css',
979        'Core.Dialog.css',
980        'Core.InputFields.css',
981        'Core.Print.css',
982        'Core.Animations.css',
983    ];
984
985    # --------------------------------------------------- #
986    # CommonJS                                           #
987    # --------------------------------------------------- #
988
989    # Customer Common JS
990    $Self->{'Loader::Customer::CommonJS'}->{'000-Framework'} = [
991        'thirdparty/jquery-3.4.1/jquery.js',
992        'thirdparty/jquery-browser-detection/jquery-browser-detection.js',
993        'thirdparty/jquery-validate-1.16.0/jquery.validate.js',
994        'thirdparty/jquery-ui-1.12.1/jquery-ui.js',
995        'thirdparty/jquery-pubsub/pubsub.js',
996        'thirdparty/jquery-jstree-3.3.7/jquery.jstree.js',
997        'thirdparty/nunjucks-3.0.1/nunjucks.js',
998        'Core.Init.js',
999        'Core.Debug.js',
1000        'Core.Exception.js',
1001        'Core.Data.js',
1002        'Core.JSON.js',
1003        'Core.JavaScriptEnhancements.js',
1004        'Core.Config.js',
1005        'Core.Language.js',
1006        'Core.Template.js',
1007        'Core.App.js',
1008        'Core.App.Responsive.js',
1009        'Core.AJAX.js',
1010        'Core.UI.js',
1011        'Core.UI.InputFields.js',
1012        'Core.UI.Accessibility.js',
1013        'Core.UI.Dialog.js',
1014        'Core.UI.Floater.js',
1015        'Core.UI.RichTextEditor.js',
1016        'Core.UI.Datepicker.js',
1017        'Core.UI.Popup.js',
1018        'Core.UI.TreeSelection.js',
1019        'Core.UI.Autocomplete.js',
1020        'Core.Form.js',
1021        'Core.Form.ErrorTooltips.js',
1022        'Core.Form.Validate.js',
1023        'Core.Customer.js',
1024        'Core.Customer.Responsive.js',
1025    ];
1026
1027    # Agent Common JS
1028    $Self->{'Loader::Agent::CommonJS'}->{'000-Framework'} = [
1029        'thirdparty/jquery-3.4.1/jquery.js',
1030        'thirdparty/jquery-browser-detection/jquery-browser-detection.js',
1031        'thirdparty/jquery-ui-1.12.1/jquery-ui.js',
1032        'thirdparty/jquery-ui-touch-punch-0.2.3/jquery.ui.touch-punch.js',
1033        'thirdparty/jquery-validate-1.16.0/jquery.validate.js',
1034        'thirdparty/jquery-pubsub/pubsub.js',
1035        'thirdparty/jquery-jstree-3.3.7/jquery.jstree.js',
1036        'thirdparty/nunjucks-3.0.1/nunjucks.js',
1037        'Core.Init.js',
1038        'Core.JavaScriptEnhancements.js',
1039        'Core.Debug.js',
1040        'Core.Exception.js',
1041        'Core.Data.js',
1042        'Core.Config.js',
1043        'Core.Language.js',
1044        'Core.Template.js',
1045        'Core.JSON.js',
1046        'Core.App.js',
1047        'Core.App.Responsive.js',
1048        'Core.AJAX.js',
1049        'Core.UI.js',
1050        'Core.UI.InputFields.js',
1051        'Core.UI.Accordion.js',
1052        'Core.UI.Datepicker.js',
1053        'Core.UI.DnD.js',
1054        'Core.UI.Floater.js',
1055        'Core.UI.Resizable.js',
1056        'Core.UI.Table.js',
1057        'Core.UI.Accessibility.js',
1058        'Core.UI.RichTextEditor.js',
1059        'Core.UI.Dialog.js',
1060        'Core.UI.ActionRow.js',
1061        'Core.UI.Popup.js',
1062        'Core.UI.TreeSelection.js',
1063        'Core.UI.Autocomplete.js',
1064        'Core.Form.js',
1065        'Core.Form.ErrorTooltips.js',
1066        'Core.Form.Validate.js',
1067        'Core.Agent.js',
1068        'Core.Agent.Search.js',
1069        'Core.Agent.CustomerInformationCenterSearch.js',
1070        'Core.Agent.CustomerSearch.js',
1071        'Core.Agent.CustomerUserInformationCenterSearch.js',
1072        'Core.Agent.Header.js',
1073        'Core.UI.Notification.js',
1074        'Core.Agent.Responsive.js',
1075    ];
1076
1077    # --------------------------------------------------- #
1078    #                                                     #
1079    #            package management options               #
1080    #                                                     #
1081    # --------------------------------------------------- #
1082
1083    # Package::RepositoryRoot
1084    # (get online repository list, use the fist availabe result)
1085    $Self->{'Package::RepositoryRoot'} = [
1086        'https://ftp.otrs.org/pub/otrs/misc/packages/repository.xml',
1087    ];
1088
1089    # Package::RepositoryList
1090    # (repository list)
1091#    $Self->{'Package::RepositoryList'} = {
1092#        'ftp://ftp.example.com/pub/otrs/misc/packages/' => '[Example] ftp://ftp.example.com/',
1093#    };
1094
1095    # Package::Timeout
1096    # (http/ftp timeout to get packages)
1097    $Self->{'Package::Timeout'} = 120;
1098
1099    # Package::Proxy
1100    # (fetch packages via proxy)
1101#    $Self->{'Package::Proxy'} = 'http://proxy.sn.no:8001/';
1102
1103    # --------------------------------------------------- #
1104    # PGP settings (supports gpg)                         #
1105    # --------------------------------------------------- #
1106    $Self->{PGP}            = 0;
1107    $Self->{'PGP::Bin'}     = '/usr/bin/gpg';
1108    $Self->{'PGP::Options'} = '--homedir /opt/otrs/.gnupg/ --batch --no-tty --yes';
1109
1110#    $Self->{'PGP::Options'} = '--batch --no-tty --yes';
1111#    $Self->{'PGP::Key::Password'}->{'D2DF79FA'} = 1234;
1112#    $Self->{'PGP::Key::Password'}->{'488A0B8F'} = 1234;
1113
1114    # --------------------------------------------------- #
1115    # S/MIME settings (supports smime)                    #
1116    # --------------------------------------------------- #
1117    $Self->{SMIME} = 0;
1118
1119    # maybe openssl need a HOME env!
1120    #$ENV{HOME} = '/var/lib/wwwrun';
1121    $Self->{'SMIME::Bin'} = '/usr/bin/openssl';
1122
1123#    $Self->{'SMIME::CertPath'} = '/etc/ssl/certs';
1124#    $Self->{'SMIME::PrivatePath'} = '/etc/ssl/private';
1125
1126    # --------------------------------------------------- #
1127    # system permissions
1128    # --------------------------------------------------- #
1129    $Self->{'System::Permission'} = [
1130        'ro',
1131        'move_into',
1132        'create',
1133        'note',
1134        'owner',
1135        'priority',
1136        'rw',
1137    ];
1138    $Self->{'System::Customer::Permission'} = [ 'ro', 'rw' ];
1139
1140    # --------------------------------------------------- #
1141    #                                                     #
1142    #             Start of config options!!!              #
1143    #                 Preferences stuff                   #
1144    #                                                     #
1145    # --------------------------------------------------- #
1146
1147    # PreferencesTable*
1148    # (Stored preferences table data.)
1149    $Self->{PreferencesTable}       = 'user_preferences';
1150    $Self->{PreferencesTableKey}    = 'preferences_key';
1151    $Self->{PreferencesTableValue}  = 'preferences_value';
1152    $Self->{PreferencesTableUserID} = 'user_id';
1153
1154    # PreferencesView
1155    # (Order of shown items)
1156    $Self->{PreferencesView} = [ 'User Profile', 'Notification Settings', 'Other Settings' ];
1157
1158    $Self->{PreferencesGroups}->{Password} = {
1159        'Active'                            => '1',
1160        'Area'                              => 'Agent',
1161        'PreferenceGroup'                   => 'UserProfile',
1162        'Label'                             => 'Change password',
1163        'Module'                            => 'Kernel::Output::HTML::Preferences::Password',
1164        'PasswordMaxLoginFailed'            => '0',
1165        'PasswordMin2Characters'            => '0',
1166        'PasswordMin2Lower2UpperCharacters' => '0',
1167        'PasswordMinSize'                   => '0',
1168        'PasswordNeedDigit'                 => '0',
1169        'PasswordRegExp'                    => '',
1170        'Prio'                              => '0500',
1171        'Desc'                              => 'Set a new password by filling in your current password and a new one.',
1172    };
1173    $Self->{PreferencesGroups}->{Comment} = {
1174        'Active'  => '0',
1175        'Block'   => 'Input',
1176        'PreferenceGroup' => 'Miscellaneous',
1177        'Data'    => '[% Env("UserComment") %]',
1178        'Desc'    => 'This is a Description for Comment on Framework.',
1179        'Key'     => 'Comment',
1180        'Label'   => 'Comment',
1181        'Module'  => 'Kernel::Output::HTML::Preferences::Generic',
1182        'PrefKey' => 'UserComment',
1183        'Prio'    => '6000',
1184    };
1185
1186    $Self->{PreferencesGroups}->{Language} = {
1187        'Active'  => '1',
1188        'PreferenceGroup'  => 'UserProfile',
1189        'Key'     => '',
1190        'Label'   => 'Language',
1191        'Desc'    => 'Select the main interface language.',
1192        'Module'  => 'Kernel::Output::HTML::Preferences::Language',
1193        'PrefKey' => 'UserLanguage',
1194        'Prio'    => '1000',
1195        'NeedsReload' => 1,
1196    };
1197    $Self->{PreferencesGroups}->{Theme} = {
1198        'Active'  => '1',
1199        'PreferenceGroup'  => 'Miscellaneous',
1200        'Key'     => '',
1201        'Label'   => 'Theme',
1202        'Desc'    => 'Select your preferred theme for OTRS.',
1203        'Module'  => 'Kernel::Output::HTML::Preferences::Theme',
1204        'PrefKey' => 'UserTheme',
1205        'Prio'    => '3000',
1206        'NeedsReload' => 1,
1207    };
1208
1209    # --------------------------------------------------- #
1210    #                                                     #
1211    #             Start of config options!!!              #
1212    #                 Notification stuff                  #
1213    #                                                     #
1214    # --------------------------------------------------- #
1215
1216    # notification sender
1217    $Self->{NotificationSenderName}  = 'OTRS Notifications';
1218    $Self->{NotificationSenderEmail} = 'otrs@<OTRS_CONFIG_FQDN>';
1219
1220    # notification email for new password
1221    $Self->{NotificationSubjectLostPassword} = 'New OTRS password';
1222    $Self->{NotificationBodyLostPassword}    = 'Hi <OTRS_USERFIRSTNAME>,
1223
1224
1225Here\'s your new OTRS password.
1226
1227New password: <OTRS_NEWPW>
1228
1229You can log in via the following URL:
1230
1231<OTRS_CONFIG_HttpType>://<OTRS_CONFIG_FQDN>/<OTRS_CONFIG_ScriptAlias>index.pl
1232            ';
1233
1234    # --------------------------------------------------- #
1235    #                                                     #
1236    #             Start of config options!!!              #
1237    #                CustomerPanel stuff                  #
1238    #                                                     #
1239    # --------------------------------------------------- #
1240
1241    # SessionName
1242    # (Name of the session key. E. g. Session, SessionID, OTRS)
1243    $Self->{CustomerPanelSessionName} = 'OTRSCustomerInterface';
1244
1245    # CustomerPanelUserID
1246    # (The customer panel db-uid.) [default: 1]
1247    $Self->{CustomerPanelUserID} = 1;
1248
1249    # CustomerGroupSupport (0 = compat. to OTRS 1.1 or lower)
1250    # (if this is 1, the you need to set the group <-> customer user
1251    # relations! http://host/otrs/index.pl?Action=AdminCustomerUserGroup
1252    # otherway, each user is ro/rw in each group!)
1253    $Self->{CustomerGroupSupport} = 0;
1254
1255    # CustomerGroupAlwaysGroups
1256    # (if CustomerGroupSupport is true and you don't want to manage
1257    # each customer user for this groups, then put the groups
1258    # for all customer user in there)
1259    $Self->{CustomerGroupAlwaysGroups} = [ 'users', ];
1260
1261    # show online agents
1262#    $Self->{'CustomerFrontend::NotifyModule'}->{'1-ShowAgentOnline'} = {
1263#        Module      => 'Kernel::Output::HTML::Notification::AgentOnline',
1264#        ShowEmail   => 1,
1265#        IdleMinutes => 60,
1266#    };
1267
1268    # --------------------------------------------------- #
1269    # login and logout settings                           #
1270    # --------------------------------------------------- #
1271    # CustomerPanelLoginURL
1272    # (If this is anything other than '', then it is assumed to be the
1273    # URL of an alternate login screen which will be used in place of
1274    # the default one.)
1275#    $Self->{CustomerPanelLoginURL} = '';
1276#    $Self->{CustomerPanelLoginURL} = 'http://host.example.com/cgi-bin/login.pl';
1277
1278    # CustomerPanelLogoutURL
1279    # (If this is anything other than '', it is assumed to be the URL
1280    # of an alternate logout page which users will be sent to when they
1281    # logout.)
1282#    $Self->{CustomerPanelLogoutURL} = '';
1283#    $Self->{CustomerPanelLogoutURL} = 'http://host.example.com/cgi-bin/login.pl';
1284
1285    # CustomerPanelPreApplicationModule
1286    # (Used for every request, if defined, the PreRun() function of
1287    # this module will be used. This interface use useful to check
1288    # some user options or to redirect not accept new application
1289    # news)
1290#    $Self->{CustomerPanelPreApplicationModule}->{CustomerAccept} = 'Kernel::Modules::CustomerAccept';
1291    # Kernel::Modules::CustomerAccept check key, if this user preferences key
1292    # is true, then the message is already accepted
1293#    $Self->{'CustomerPanel::InfoKey'} = 'CustomerAccept1';
1294    # shown InfoFile located under Kernel/Output/HTML/Templates/Standard/CustomerAccept.tt
1295#    $Self->{'CustomerPanel::InfoFile'} = 'CustomerAccept';
1296
1297    # CustomerPanelLostPassword
1298    # (use lost password feature)
1299    $Self->{CustomerPanelLostPassword} = 1;
1300
1301    # CustomerPanelCreateAccount
1302    # (use create cutomer account self feature)
1303    $Self->{CustomerPanelCreateAccount} = 1;
1304
1305    # --------------------------------------------------- #
1306    # notification email about new password               #
1307    # --------------------------------------------------- #
1308    $Self->{CustomerPanelSubjectLostPassword} = 'New OTRS password';
1309    $Self->{CustomerPanelBodyLostPassword}    = 'Hi <OTRS_USERFIRSTNAME>,
1310
1311
1312New password: <OTRS_NEWPW>
1313
1314<OTRS_CONFIG_HttpType>://<OTRS_CONFIG_FQDN>/<OTRS_CONFIG_ScriptAlias>customer.pl
1315            ';
1316
1317    # --------------------------------------------------- #
1318    # notification email about new account                #
1319    # --------------------------------------------------- #
1320    $Self->{CustomerPanelSubjectNewAccount} = 'New OTRS Account!';
1321    $Self->{CustomerPanelBodyNewAccount}    = 'Hi <OTRS_USERFIRSTNAME>,
1322
1323You or someone impersonating you has created a new OTRS account for
1324you.
1325
1326Full name: <OTRS_USERFIRSTNAME> <OTRS_USERLASTNAME>
1327User name: <OTRS_USERLOGIN>
1328Password : <OTRS_USERPASSWORD>
1329
1330You can log in via the following URL. We encourage you to change your password
1331via the Preferences button after logging in.
1332
1333<OTRS_CONFIG_HttpType>://<OTRS_CONFIG_FQDN>/<OTRS_CONFIG_ScriptAlias>customer.pl
1334            ';
1335
1336    # --------------------------------------------------- #
1337    # customer authentication settings                    #
1338    # (enable what you need, auth against otrs db,        #
1339    # against a LDAP directory, against HTTP basic        #
1340    # authentication and against Radius server)           #
1341    # --------------------------------------------------- #
1342    # This is the auth. module for the otrs db
1343    # you can also configure it using a remote database
1344    $Self->{'Customer::AuthModule'}                       = 'Kernel::System::CustomerAuth::DB';
1345    $Self->{'Customer::AuthModule::DB::Table'}            = 'customer_user';
1346    $Self->{'Customer::AuthModule::DB::CustomerKey'}      = 'login';
1347    $Self->{'Customer::AuthModule::DB::CustomerPassword'} = 'pw';
1348
1349#    $Self->{'Customer::AuthModule::DB::DSN'} = "DBI:mysql:database=customerdb;host=customerdbhost";
1350#    $Self->{'Customer::AuthModule::DB::User'} = "some_user";
1351#    $Self->{'Customer::AuthModule::DB::Password'} = "some_password";
1352
1353    # if you use odbc or you want to define a database type (without autodetection)
1354#    $Self->{'Customer::AuthModule::DB::Type'} = 'mysql';
1355
1356    # password crypt type (bcrypt|sha2|sha1|md5|apr1|crypt|plain)
1357#    $Self->{'Customer::AuthModule::DB::CryptType'} = 'sha2';
1358
1359    # This is an example configuration for an LDAP auth. backend.
1360    # (take care that Net::LDAP is installed!)
1361#    $Self->{'Customer::AuthModule'} = 'Kernel::System::CustomerAuth::LDAP';
1362#    $Self->{'Customer::AuthModule::LDAP::Host'} = 'ldap.example.com';
1363#    $Self->{'Customer::AuthModule::LDAP::BaseDN'} = 'dc=example,dc=com';
1364#    $Self->{'Customer::AuthModule::LDAP::UID'} = 'uid';
1365
1366    # Check if the user is allowed to auth in a posixGroup
1367    # (e. g. user needs to be in a group xyz to use otrs)
1368#    $Self->{'Customer::AuthModule::LDAP::GroupDN'} = 'cn=otrsallow,ou=posixGroups,dc=example,dc=com';
1369#    $Self->{'Customer::AuthModule::LDAP::AccessAttr'} = 'memberUid';
1370    # for ldap posixGroups objectclass (just uid)
1371#    $Self->{'Customer::AuthModule::LDAP::UserAttr'} = 'UID';
1372    # for non ldap posixGroups objectclass (full user dn)
1373#    $Self->{'Customer::AuthModule::LDAP::UserAttr'} = 'DN';
1374
1375    # The following is valid but would only be necessary if the
1376    # anonymous user do NOT have permission to read from the LDAP tree
1377#    $Self->{'Customer::AuthModule::LDAP::SearchUserDN'} = '';
1378#    $Self->{'Customer::AuthModule::LDAP::SearchUserPw'} = '';
1379
1380    # in case you want to add always one filter to each ldap query, use
1381    # this option. e. g. AlwaysFilter => '(mail=*)' or AlwaysFilter => '(objectclass=user)'
1382#   $Self->{'Customer::AuthModule::LDAP::AlwaysFilter'} = '';
1383
1384    # in case you want to add a suffix to each customer login name, then
1385    # you can use this option. e. g. user just want to use user but
1386    # in your ldap directory exists user@domain.
1387#    $Self->{'Customer::AuthModule::LDAP::UserSuffix'} = '@domain.com';
1388
1389    # Net::LDAP new params (if needed - for more info see perldoc Net::LDAP)
1390#    $Self->{'Customer::AuthModule::LDAP::Params'} = {
1391#        port    => 389,
1392#        timeout => 120,
1393#        async   => 0,
1394#        version => 3,
1395#    };
1396
1397    # Die if backend can't work, e. g. can't connect to server.
1398#    $Self->{'Customer::AuthModule::LDAP::Die'} = 1;
1399
1400    # This is an example configuration for an apache ($ENV{REMOTE_USER})
1401    # auth. backend. Use it if you want to have a singe login through
1402    # apache http-basic-auth
1403#   $Self->{'Customer::AuthModule'} = 'Kernel::System::CustomerAuth::HTTPBasicAuth';
1404
1405    # In case there is a leading domain in the REMOTE_USER, you can
1406    # replace it by the next config option.
1407#   $Self->{'Customer::AuthModule::HTTPBasicAuth::Replace'} = 'example_domain\\';
1408    # Note:
1409    # In case you need to replace some part of the REMOTE_USER, you can
1410    # use the following RegExp ($1 will be new login).
1411#    $Self->{'Customer::AuthModule::HTTPBasicAuth::ReplaceRegExp'} = '^(.+?)@.+?$';
1412    # If you use this module, you should use as fallback the following
1413    # config settings if user isn't login through apache ($ENV{REMOTE_USER})
1414#    $Self->{CustomerPanelLoginURL} = 'http://host.example.com/not-authorised-for-otrs.html';
1415#    $Self->{CustomerPanelLogoutURL} = 'http://host.example.com/thanks-for-using-otrs.html';
1416
1417    # This is example configuration to auth. agents against a radius server
1418#    $Self->{'Customer::AuthModule'} = 'Kernel::System::Auth::Radius';
1419#    $Self->{'Customer::AuthModule::Radius::Host'} = 'radiushost';
1420#    $Self->{'Customer::AuthModule::Radius::Password'} = 'radiussecret';
1421
1422    # --------------------------------------------------- #
1423    # 2 factor customer authentication settings           #
1424    # check a otp (one-time password)                     #
1425    # after successful authentication                     #
1426    # as an extra security measure                        #
1427    # --------------------------------------------------- #
1428    # This is the auth module using the google authenticator mechanism
1429#    $Self->{'Customer::AuthTwoFactorModule'} = 'Kernel::System::CustomerAuth::TwoFactor::GoogleAuthenticator';
1430
1431    # defines user preference where the secret key is stored
1432#    $Self->{'Customer::AuthTwoFactorModule::SecretPreferencesKey'} = 'UserGoogleAuthenticatorSecretKey';
1433
1434    # defines if users can login without a 2 factor authentication if they have no stored shared secret
1435#    $Self->{'Customer::AuthTwoFactorModule::AllowEmptySecret'} = '1';
1436
1437    # defines if the otp for the previous timespan (30-60sec ago) will also be valid
1438    # helpful to account for timing issues (server and entry based)
1439#    $Self->{'Customer::AuthTwoFactorModule::AllowPreviousToken'} = '1';
1440
1441    # --------------------------------------------------- #
1442    #                                                     #
1443    #             Start of config options!!!              #
1444    #                 CustomerUser stuff                  #
1445    #                                                     #
1446    # --------------------------------------------------- #
1447
1448    # CustomerUser
1449    # (customer user database backend and settings)
1450    $Self->{CustomerUser} = {
1451        Name   => Translatable('Database Backend'),
1452        Module => 'Kernel::System::CustomerUser::DB',
1453        Params => {
1454
1455            # if you want to use an external database, add the
1456            # required settings
1457#            DSN  => 'DBI:odbc:yourdsn',
1458#            Type => 'mssql', # only for ODBC connections
1459#            DSN => 'DBI:mysql:database=customerdb;host=customerdbhost',
1460#            User => '',
1461#            Password => '',
1462            Table => 'customer_user',
1463#            ForeignDB => 0,    # set this to 1 if your table does not have create_time, create_by, change_time and change_by fields
1464
1465            # CaseSensitive defines if the data storage of your DBMS is case sensitive and will be
1466            # preconfigured within the database driver by default.
1467            # If the collation of your data storage differs from the default settings,
1468            # you can set the current behavior ( either 1 = CaseSensitive or 0 = CaseINSensitive )
1469            # to fit your environment.
1470            #
1471#            CaseSensitive => 0,
1472
1473            # SearchCaseSensitive will control if the searches within the data storage are performed
1474            # case sensitively (if possible) or not. Change this option to 1, if you want to search case sensitive.
1475            # This can improve the performance dramatically on large databases.
1476            SearchCaseSensitive => 0,
1477        },
1478
1479        # customer unique id
1480        CustomerKey => 'login',
1481
1482        # customer #
1483        CustomerID    => 'customer_id',
1484        CustomerValid => 'valid_id',
1485
1486        # The last field must always be the email address so that a valid
1487        #   email address like "John Doe" <john.doe@domain.com> can be constructed from the fields.
1488        CustomerUserListFields => [ 'first_name', 'last_name', 'email' ],
1489
1490#        CustomerUserListFields => ['login', 'first_name', 'last_name', 'customer_id', 'email'],
1491        CustomerUserSearchFields           => [ 'login', 'first_name', 'last_name', 'customer_id' ],
1492        CustomerUserSearchPrefix           => '*',
1493        CustomerUserSearchSuffix           => '*',
1494        CustomerUserSearchListLimit        => 250,
1495        CustomerUserPostMasterSearchFields => ['email'],
1496        CustomerUserNameFields             => [ 'title', 'first_name', 'last_name' ],
1497        CustomerUserEmailUniqCheck         => 1,
1498
1499#        # Configures the character for joining customer user name parts. Join single space if it is not defined.
1500#        # CustomerUserNameFieldsJoin => '',
1501
1502#        # show now own tickets in customer panel, CompanyTickets
1503#        CustomerUserExcludePrimaryCustomerID => 0,
1504#        # generate auto logins
1505#        AutoLoginCreation => 0,
1506#        # generate auto login prefix
1507#        AutoLoginCreationPrefix => 'auto',
1508#        # admin can change customer preferences
1509#        AdminSetPreferences => 1,
1510        # use customer company support (reference to company, See CustomerCompany settings)
1511        CustomerCompanySupport => 1,
1512        # cache time to live in sec. - cache any database queries
1513        CacheTTL => 60 * 60 * 24,
1514#        # Consider this source read only.
1515#        ReadOnly => 1,
1516        Map => [
1517
1518            # Info about dynamic fields:
1519            #
1520            # Dynamic Fields of type CustomerUser can be used within the mapping (see example below).
1521            # The given storage (third column) then can also be used within the following configurations (see above):
1522            # CustomerUserSearchFields, CustomerUserPostMasterSearchFields, CustomerUserListFields, CustomerUserNameFields
1523            #
1524            # Note that the columns 'frontend' and 'readonly' will be ignored for dynamic fields.
1525
1526            # note: Login, Email and CustomerID needed!
1527            # var, frontend, storage, shown (1=always,2=lite), required, storage-type, http-link, readonly, http-link-target, link class(es)
1528            [ 'UserTitle',        Translatable('Title or salutation'), 'title',          1, 0, 'var', '', 0, undef, undef ],
1529            [ 'UserFirstname',    Translatable('Firstname'),           'first_name',     1, 1, 'var', '', 0, undef, undef ],
1530            [ 'UserLastname',     Translatable('Lastname'),            'last_name',      1, 1, 'var', '', 0, undef, undef ],
1531            [ 'UserLogin',        Translatable('Username'),            'login',          1, 1, 'var', '', 0, undef, undef ],
1532            [ 'UserPassword',     Translatable('Password'),            'pw',             0, 0, 'var', '', 0, undef, undef ],
1533            [ 'UserEmail',        Translatable('Email'),               'email',          1, 1, 'var', '', 0, undef, undef ],
1534#            [ 'UserEmail',        Translatable('Email'),               'email',          1, 1, 'var', '[% Env("CGIHandle") %]?Action=AgentTicketCompose;ResponseID=1;TicketID=[% Data.TicketID | uri %];ArticleID=[% Data.ArticleID | uri %]', 0, '', 'AsPopup OTRSPopup_TicketAction' ],
1535            [ 'UserCustomerID',   Translatable('CustomerID'),          'customer_id',    0, 1, 'var', '', 0, undef, undef ],
1536#            [ 'UserCustomerIDs',  Translatable('CustomerIDs'),         'customer_ids',   1, 0, 'var', '', 0, undef, undef ],
1537            [ 'UserPhone',        Translatable('Phone'),               'phone',          1, 0, 'var', '', 0, undef, undef ],
1538            [ 'UserFax',          Translatable('Fax'),                 'fax',            1, 0, 'var', '', 0, undef, undef ],
1539            [ 'UserMobile',       Translatable('Mobile'),              'mobile',         1, 0, 'var', '', 0, undef, undef ],
1540            [ 'UserStreet',       Translatable('Street'),              'street',         1, 0, 'var', '', 0, undef, undef ],
1541            [ 'UserZip',          Translatable('Zip'),                 'zip',            1, 0, 'var', '', 0, undef, undef ],
1542            [ 'UserCity',         Translatable('City'),                'city',           1, 0, 'var', '', 0, undef, undef ],
1543            [ 'UserCountry',      Translatable('Country'),             'country',        1, 0, 'var', '', 0, undef, undef ],
1544            [ 'UserComment',      Translatable('Comment'),             'comments',       1, 0, 'var', '', 0, undef, undef ],
1545            [ 'ValidID',          Translatable('Valid'),               'valid_id',       0, 1, 'int', '', 0, undef, undef ],
1546
1547            # Dynamic field example
1548#            [ 'DynamicField_Name_X', undef, 'Name_X', 0, 0, 'dynamic_field', undef, 0, undef, undef ],
1549        ],
1550
1551        # default selections
1552        Selections => {
1553
1554#            UserTitle => {
1555#                'Mr.' => Translatable('Mr.'),
1556#                'Mrs.' => Translatable('Mrs.'),
1557#            },
1558        },
1559    };
1560
1561# CustomerUser
1562# (customer user ldap backend and settings)
1563#    $Self->{CustomerUser} = {
1564#        Name => 'LDAP Backend',
1565#        Module => 'Kernel::System::CustomerUser::LDAP',
1566#        Params => {
1567#            # ldap host
1568#            Host => 'bay.csuhayward.edu',
1569#            # ldap base dn
1570#            BaseDN => 'ou=seas,o=csuh',
1571#            # search scope (one|sub)
1572#            SSCOPE => 'sub',
1573#            # The following is valid but would only be necessary if the
1574#            # anonymous user does NOT have permission to read from the LDAP tree
1575#            UserDN => '',
1576#            UserPw => '',
1577#            # in case you want to add always one filter to each ldap query, use
1578#            # this option. e. g. AlwaysFilter => '(mail=*)' or AlwaysFilter => '(objectclass=user)'
1579#            AlwaysFilter => '',
1580#            # if the charset of your ldap server is iso-8859-1, use this:
1581#            # SourceCharset => 'iso-8859-1',
1582#            # die if backend can't work, e. g. can't connect to server
1583#            Die => 0,
1584#            # Net::LDAP new params (if needed - for more info see perldoc Net::LDAP)
1585#            Params => {
1586#                port    => 389,
1587#                timeout => 120,
1588#                async   => 0,
1589#                version => 3,
1590#            },
1591#        },
1592#        # customer unique id
1593#        CustomerKey => 'uid',
1594#        # customer #
1595#        CustomerID => 'mail',
1596#        CustomerUserListFields => ['cn', 'mail'],
1597#        CustomerUserSearchFields => ['uid', 'cn', 'mail'],
1598#        CustomerUserSearchPrefix => '',
1599#        CustomerUserSearchSuffix => '*',
1600#        CustomerUserSearchListLimit => 250,
1601#        CustomerUserPostMasterSearchFields => ['mail'],
1602#        CustomerUserNameFields => ['givenname', 'sn'],
1603#        # Configures the character for joining customer user name parts. Join single space if it is not defined.
1604#        CustomerUserNameFieldsJoin => '',
1605#        # show customer user and customer tickets in customer interface
1606#        CustomerUserExcludePrimaryCustomerID => 0,
1607#        # add a ldap filter for valid users (expert setting)
1608#        # CustomerUserValidFilter => '(!(description=gesperrt))',
1609#        # admin can't change customer preferences
1610#        AdminSetPreferences => 0,
1611#        # cache time to live in sec. - cache any ldap queries
1612#        CacheTTL => 0,
1613#        Map => [
1614#            # note: Login, Email and CustomerID needed!
1615#            # var, frontend, storage, shown (1=always,2=lite), required, storage-type, http-link, readonly, http-link-target, link class(es)
1616#            [ 'UserTitle',       Translatable('Title or salutation'), 'title',               1, 0, 'var', '', 1, undef, undef ],
1617#            [ 'UserFirstname',   Translatable('Firstname'),           'givenname',           1, 1, 'var', '', 1, undef, undef ],
1618#            [ 'UserLastname',    Translatable('Lastname'),            'sn',                  1, 1, 'var', '', 1, undef, undef ],
1619#            [ 'UserLogin',       Translatable('Username'),            'uid',                 1, 1, 'var', '', 1, undef, undef ],
1620#            [ 'UserEmail',       Translatable('Email'),               'mail',                1, 1, 'var', '', 1, undef, undef ],
1621#            [ 'UserCustomerID',  Translatable('CustomerID'),          'mail',                0, 1, 'var', '', 1, undef, undef ],
1622#            # [ 'UserCustomerIDs', Translatable('CustomerIDs'),         'second_customer_ids', 1, 0, 'var', '', 1, undef, undef ],
1623#            [ 'UserPhone',       Translatable('Phone'),               'telephonenumber',     1, 0, 'var', '', 1, undef, undef ],
1624#            [ 'UserAddress',     Translatable('Address'),             'postaladdress',       1, 0, 'var', '', 1, undef, undef ],
1625#            [ 'UserComment',     Translatable('Comment'),             'description',         1, 0, 'var', '', 1, undef, undef ],
1626#
1627#            # this is needed, if "SMIME::FetchFromCustomer" is active
1628#            # [ 'UserSMIMECertificate', 'SMIMECertificate', 'userSMIMECertificate', 0, 1, 'var', '', 1, undef, undef ],
1629#
1630#            # Dynamic field example
1631#            # [ 'DynamicField_Name_X', undef, 'Name_X', 0, 0, 'dynamic_field', undef, 0, undef, undef ],
1632#        ],
1633#    };
1634
1635    $Self->{CustomerCompany} = {
1636        Name   => Translatable('Database Backend'),
1637        Module => 'Kernel::System::CustomerCompany::DB',
1638        Params => {
1639            # if you want to use an external database, add the
1640            # required settings
1641#            DSN  => 'DBI:odbc:yourdsn',
1642#            Type => 'mssql', # only for ODBC connections
1643#            DSN => 'DBI:mysql:database=customerdb;host=customerdbhost',
1644#            User => '',
1645#            Password => '',
1646            Table => 'customer_company',
1647#            ForeignDB => 0,    # set this to 1 if your table does not have create_time, create_by, change_time and change_by fields
1648
1649            # CaseSensitive defines if the data storage of your DBMS is case sensitive and will be
1650            # preconfigured within the database driver by default.
1651            # If the collation of your data storage differs from the default settings,
1652            # you can set the current behavior ( either 1 = CaseSensitive or 0 = CaseINSensitive )
1653            # to fit your environment.
1654            #
1655#            CaseSensitive => 0,
1656
1657            # SearchCaseSensitive will control if the searches within the data storage are performed
1658            # case sensitively (if possible) or not. Change this option to 1, if you want to search case sensitive.
1659            # This can improve the performance dramatically on large databases.
1660            SearchCaseSensitive => 0,
1661        },
1662
1663        # company unique id
1664        CustomerCompanyKey             => 'customer_id',
1665        CustomerCompanyValid           => 'valid_id',
1666        CustomerCompanyListFields      => [ 'customer_id', 'name' ],
1667        CustomerCompanySearchFields    => [ 'customer_id', 'name' ],
1668        CustomerCompanySearchPrefix    => '*',
1669        CustomerCompanySearchSuffix    => '*',
1670        CustomerCompanySearchListLimit => 250,
1671        CacheTTL                       => 60 * 60 * 24, # use 0 to turn off cache
1672
1673        Map => [
1674            # Info about dynamic fields:
1675            #
1676            # Dynamic Fields of type CustomerCompany can be used within the mapping (see example below).
1677            # The given storage (third column) then can also be used within the following configurations (see above):
1678            # CustomerCompanySearchFields, CustomerCompanyListFields
1679            #
1680            # Note that the columns 'frontend' and 'readonly' will be ignored for dynamic fields.
1681
1682            # var, frontend, storage, shown (1=always,2=lite), required, storage-type, http-link, readonly
1683            [ 'CustomerID',             'CustomerID', 'customer_id', 0, 1, 'var', '', 0 ],
1684            [ 'CustomerCompanyName',    'Customer',   'name',        1, 1, 'var', '', 0 ],
1685            [ 'CustomerCompanyStreet',  'Street',     'street',      1, 0, 'var', '', 0 ],
1686            [ 'CustomerCompanyZIP',     'Zip',        'zip',         1, 0, 'var', '', 0 ],
1687            [ 'CustomerCompanyCity',    'City',       'city',        1, 0, 'var', '', 0 ],
1688            [ 'CustomerCompanyCountry', 'Country',    'country',     1, 0, 'var', '', 0 ],
1689            [ 'CustomerCompanyURL',     'URL',        'url',         1, 0, 'var', '[% Data.CustomerCompanyURL | html %]', 0 ],
1690            [ 'CustomerCompanyComment', 'Comment',    'comments',    1, 0, 'var', '', 0 ],
1691            [ 'ValidID',                'Valid',      'valid_id',    0, 1, 'int', '', 0 ],
1692
1693            # Dynamic field example
1694#            [ 'DynamicField_Name_Y', undef, 'Name_Y', 0, 0, 'dynamic_field', undef, 0 ],
1695        ],
1696    };
1697
1698    # --------------------------------------------------- #
1699    # misc
1700    # --------------------------------------------------- #
1701    # yes / no options
1702    $Self->{YesNoOptions} = {
1703        1 => 'Yes',
1704        0 => 'No',
1705    };
1706
1707    $Self->{'Frontend::CommonParam'} = {
1708
1709        # param => default value
1710#        SomeParam => 'DefaultValue',
1711        Action => 'AdminInit',
1712    };
1713
1714    $Self->{'CustomerFrontend::CommonParam'} = {
1715
1716        # param => default value
1717#        SomeParam => 'DefaultValue',
1718    };
1719
1720    $Self->{'PublicFrontend::CommonParam'} = {
1721
1722        # param => default value
1723#        SomeParam => 'DefaultValue',
1724    };
1725
1726    # If the public interface is protected with .htaccess
1727    # we can specify the htaccess login data here,
1728    # this is necessary for the support data collector
1729    # $Self->{'PublicFrontend::AuthUser'} = '';
1730    # $Self->{'PublicFrontend::AuthPassword'} = '';
1731
1732    # --------------------------------------------------- #
1733    # Frontend Module Registry (Agent)
1734    # --------------------------------------------------- #
1735    # Module (from Kernel/Modules/*.pm) => Group
1736
1737    # admin interface
1738    $Self->{'Frontend::Module'}->{Admin} = {
1739        Description => 'Admin Area.',
1740        Group       => [
1741            'admin',
1742        ],
1743        GroupRo     => [],
1744        NavBarName => 'Admin',
1745        Title      => '',
1746    };
1747    $Self->{'Loader::Module::Admin'}->{'000-Defaults'} = {
1748        CSS => [
1749            'Core.Agent.Admin.css',
1750        ],
1751        JavaScript => [
1752            'Core.Agent.Admin.js',
1753            'Core.UI.AllocationList.js',
1754            'Core.Agent.TableFilters.js',
1755        ],
1756    };
1757    $Self->{'Frontend::Navigation'}->{Admin}->{'001-Framework'} = [
1758        {
1759            Group       => [
1760                'admin',
1761            ],
1762            GroupRo     => [],
1763            AccessKey   => 'a',
1764            Block       => 'ItemArea',
1765            Description => 'Admin modules overview.',
1766            Link        => 'Action=Admin',
1767            LinkOption  => '',
1768            Name        => 'Admin',
1769            NavBar      => 'Admin',
1770            Prio        => '10000',
1771            Type        => 'Menu',
1772        },
1773    ];
1774    $Self->{'Frontend::NavigationModule'}->{Admin} = {
1775        Group       => [
1776            'admin',
1777        ],
1778        GroupRo     => [],
1779        Module => 'Kernel::Output::HTML::NavBar::ModuleAdmin',
1780        Description => 'Admin modules overview.',
1781        IconBig => '',
1782        IconSmall => '',
1783        Name => '',
1784        Block => '',
1785    };
1786
1787    $Self->{'Frontend::Module'}->{AdminInit} = {
1788        Description => 'Admin',
1789        Group       => [
1790            'admin',
1791        ],
1792        GroupRo     => [],
1793        NavBarName => '',
1794        Title      => 'Init',
1795    };
1796    $Self->{'Frontend::Module'}->{AdminLog} = {
1797        Description => 'Admin',
1798        Group       => [
1799            'admin',
1800        ],
1801        GroupRo     => [],
1802        NavBarName => 'Admin',
1803        Title      => 'System Log',
1804    };
1805    $Self->{'Loader::Module::AdminLog'}->{'000-Defaults'} = {
1806        JavaScript => [
1807          'Core.Agent.Admin.Log.js'
1808        ],
1809    };
1810    $Self->{'Frontend::NavigationModule'}->{AdminLog} = {
1811        GroupRo     => [],
1812        Group       => [
1813            'admin',
1814        ],
1815        Description => Translatable('View system log messages.'),
1816        IconBig     => 'fa-file-text-o',
1817        IconSmall   => '',
1818        Module      => 'Kernel::Output::HTML::NavBar::ModuleAdmin',
1819        Name        => Translatable('System Log'),
1820        Block => 'Administration',
1821    };
1822
1823    $Self->{'Frontend::Module'}->{AdminSystemConfiguration} = {
1824        Group        => ['admin'],
1825        GroupRo     => [],
1826        Description  => 'Admin.',
1827        Title        => 'System Configuration',
1828        NavBarName   => 'Admin',
1829    };
1830    $Self->{'Loader::Module::AdminSystemConfiguration'}->{'000-Defaults'} = {
1831        CSS => [
1832            'Core.Agent.Admin.SystemConfiguration.css',
1833        ],
1834        JavaScript => [
1835            'thirdparty/clipboardjs-1.7.1/clipboard.min.js',
1836            'Core.SystemConfiguration.js',
1837            'Core.SystemConfiguration.Date.js',
1838            'Core.Agent.Admin.SystemConfiguration.js',
1839        ],
1840    };
1841    $Self->{'Frontend::NavigationModule'}->{AdminSystemConfiguration} = {
1842        Group        => ['admin'],
1843        GroupRo      => [],
1844        Module      => 'Kernel::Output::HTML::NavBar::ModuleAdmin',
1845        Name        => Translatable('System Configuration'),
1846        Description => Translatable('Edit the system configuration settings.'),
1847        Block       => 'System',
1848        IconBig     => '',
1849        IconSmall    => '',
1850        Block => 'Administration',
1851    };
1852
1853    $Self->{'Frontend::Module'}->{AdminPackageManager} = {
1854        Description => 'Software Package Manager.',
1855        Group       => [
1856            'admin',
1857        ],
1858        GroupRo     => [],
1859        NavBarName => 'Admin',
1860        Title      => 'Package Manager',
1861    };
1862    $Self->{'Frontend::NavigationModule'}->{AdminPackageManager} = {
1863        Group       => [
1864            'admin',
1865        ],
1866        GroupRo      => [],
1867        IconBig     => 'fa-plug',
1868        IconSmall => '',
1869        Description => Translatable('Update and extend your system with software packages.'),
1870        Module      => 'Kernel::Output::HTML::NavBar::ModuleAdmin',
1871        Name        => Translatable('Package Manager'),
1872        Block => 'Administration',
1873    };
1874
1875    # specify Loader settings for Login screens
1876    $Self->{'Loader::Module::Login'}->{'000-Defaults'} = {
1877        JavaScript => [
1878            'Core.Agent.Login.js',
1879        ],
1880    };
1881
1882    $Self->{'Loader::Module::CustomerLogin'}->{'000-Defaults'} = {
1883        JavaScript => [
1884            'Core.Customer.Login.js',
1885        ],
1886    };
1887
1888    # specify Loader settings for the installer
1889    $Self->{'Loader::Module::Installer'}->{'000-Defaults'} = {
1890        JavaScript => [
1891            'Core.Installer.js',
1892        ],
1893        CSS => [
1894            'Core.Installer.css',
1895        ],
1896    };
1897
1898    return 1;
1899}
1900
1901#
1902# Hereafter the functions should be documented in Kernel::Config (Kernel/Config.pod.dist), not in
1903#   Kernel::Config:Defaults.
1904#
1905
1906# Please see the documentation in Kernel/Config.pod.dist.
1907sub new {
1908    my ( $Type, %Param ) = @_;
1909
1910    # allocate new hash for object
1911    my $Self = {};
1912    bless( $Self, $Type );
1913
1914    # 0=off; 1=log if there exists no entry; 2=log all;
1915    $Self->{Debug} = 0;
1916
1917    # return on clear level
1918    if ( $Param{Level} && $Param{Level} eq 'Clear' ) {
1919
1920        # load config
1921        $Self->Load();
1922        return $Self;
1923    }
1924
1925    # load defaults
1926    $Self->LoadDefaults();
1927
1928    # load config
1929    $Self->Load();
1930
1931    # load extra config files
1932    if ( -e "$Self->{Home}/Kernel/Config/Files/" ) {
1933
1934        my @Files = glob("$Self->{Home}/Kernel/Config/Files/*.pm");
1935
1936        # Resorting the filelist.
1937        my @NewFileOrderPre  = ();
1938        my @NewFileOrderPost = ();
1939
1940        for my $File (@Files) {
1941
1942            if ( $File =~ /Ticket/ ) {
1943                push @NewFileOrderPre, $File;
1944            }
1945            else {
1946                push @NewFileOrderPost, $File;
1947            }
1948        }
1949
1950        @Files = ( @NewFileOrderPre, @NewFileOrderPost );
1951
1952        FILE:
1953        for my $File (@Files) {
1954
1955            # do not use ZZZ files
1956            if ( $Param{Level} && $Param{Level} eq 'Default' && $File =~ /ZZZ/ ) {
1957                next FILE;
1958            }
1959
1960            my $RelativeFile = $File =~ s{\Q$Self->{Home}\E/*}{}gr;
1961
1962            # Extract package name and load it.
1963            my $Package = $RelativeFile;
1964            $Package =~ s/^\///g;
1965            $Package =~ s/\/{2,}/\//g;
1966            $Package =~ s/\//::/g;
1967            $Package =~ s/\.pm$//g;
1968
1969            eval {
1970
1971                # Try to load file.
1972                if ( !require $RelativeFile ) {
1973                    die "ERROR: Could not load $File: $!\n";
1974                }
1975
1976                # Check if package has loaded and has a Load() method.
1977                if (!$Package->can('Load')) {
1978                    die "$Package has no Load() method.";
1979                }
1980
1981                # Call package method but pass $Self as instance.
1982                $Package->Load($Self);
1983            };
1984
1985            if ( $@ ) {
1986                my $ErrorMessage = $@;
1987                print STDERR $@;
1988                next FILE;
1989            }
1990        }
1991    }
1992
1993    # load RELEASE file
1994    if ( -e !"$Self->{Home}/RELEASE" ) {
1995        print STDERR
1996            "ERROR: $Self->{Home}/RELEASE does not exist! This file is needed by central system parts of OTRS, the system will not work without this file.\n";
1997        die;
1998    }
1999
2000    if ( open( my $Product, '<', "$Self->{Home}/RELEASE" ) ) {    ## no critic
2001
2002        while ( my $Line = <$Product> ) {
2003
2004            # filtering of comment lines
2005            if ( $Line !~ /^#/ ) {
2006
2007                if ( $Line =~ /^PRODUCT\s{0,2}=\s{0,2}(.*)\s{0,2}$/i ) {
2008                    $Self->{Product} = $1;
2009                }
2010                elsif ( $Line =~ /^VERSION\s{0,2}=\s{0,2}(.*)\s{0,2}$/i ) {
2011                    $Self->{Version} = $1;
2012                }
2013            }
2014        }
2015
2016        close $Product;
2017    }
2018    else {
2019        print STDERR
2020            "ERROR: Can't read $Self->{Home}/RELEASE: $! This file is needed by central system parts of OTRS, the system will not work without this file.\n";
2021        die;
2022    }
2023
2024    # load config (again)
2025    $Self->Load();
2026
2027    # do not use ZZZ files
2028    if ( !$Param{Level} ) {
2029
2030        # replace config variables in config variables
2031        KEY:
2032        for my $Key ( sort keys %{$Self} ) {
2033
2034            next KEY if !defined $Key;
2035
2036            if ( defined $Self->{$Key} ) {
2037                $Self->{$Key} =~ s/\<OTRS_CONFIG_(.+?)\>/$Self->{$1}/g;
2038            }
2039            else {
2040                print STDERR "ERROR: $Key not defined!\n";
2041            }
2042        }
2043    }
2044
2045    $Self->AutoloadPerlPackages();
2046
2047    return $Self;
2048}
2049
2050# Please see the documentation in Kernel/Config.pod.dist.
2051sub Get {
2052    my ( $Self, $What ) = @_;
2053
2054    # debug
2055    if ( $Self->{Debug} > 1 ) {
2056        my $Value = defined $Self->{$What} ? $Self->{$What} : '<undef>';
2057        print STDERR "Debug: Config.pm ->Get('$What') --> $Value\n";
2058    }
2059
2060    return $Self->{$What};
2061}
2062
2063# Please see the documentation in Kernel/Config.pod.dist.
2064sub Set {
2065    my ( $Self, %Param ) = @_;
2066
2067    for (qw(Key)) {
2068        if ( !defined $Param{$_} ) {
2069            $Param{$_} = '';
2070        }
2071    }
2072
2073    # debug
2074    if ( $Self->{Debug} > 1 ) {
2075        my $Value = defined $Param{Value} ? $Param{Value} : '<undef>';
2076        print STDERR "Debug: Config.pm ->Set(Key => $Param{Key}, Value => $Value)\n";
2077    }
2078
2079    # set runtime config option
2080    if ( $Param{Key} =~ /^(.+?)###(.+?)$/ ) {
2081
2082        if ( !defined $Param{Value} ) {
2083            delete $Self->{$1}->{$2};
2084        }
2085        else {
2086            $Self->{$1}->{$2} = $Param{Value};
2087        }
2088    }
2089    else {
2090
2091        if ( !defined $Param{Value} ) {
2092            delete $Self->{ $Param{Key} };
2093        }
2094        else {
2095            $Self->{ $Param{Key} } = $Param{Value};
2096        }
2097    }
2098
2099    return 1;
2100}
2101
2102## nofilter(TidyAll::Plugin::OTRS::Perl::Translatable)
2103
2104# This is a no-op to mark a text as translatable in the Perl code.
2105#   We use our own version here instead of importing Language::Translatable to not add a dependency.
2106
2107sub Translatable {
2108    return shift;
2109}
2110
2111# Please see the documentation in Kernel/Config.pod.dist.
2112sub ConfigChecksum {
2113    my $Self = shift;
2114
2115    my @Files = glob( $Self->{Home} . "/Kernel/Config/Files/*.pm" );
2116
2117    # Ignore ZZZAAuto.pm, because this is only a cached version of the XML files which
2118    # will be in the checksum. Otherwise the SysConfig cannot use its cache files.
2119    @Files = grep { $_ !~ m/ZZZAAuto\.pm$/smx } @Files;
2120
2121    push @Files, glob( $Self->{Home} . "/Kernel/Config/Files/*.xml" );
2122    push @Files, $Self->{Home} . "/Kernel/Config/Defaults.pm";
2123    push @Files, $Self->{Home} . "/Kernel/Config.pm";
2124
2125    # Create a string with filenames and file mtimes of the config files
2126    my $ConfigString;
2127    for my $File (@Files) {
2128
2129        # get file metadata
2130        my $Stat = stat($File);
2131
2132        if ( !$Stat ) {
2133            print STDERR "Error: cannot stat file '$File': $!";
2134            return;
2135        }
2136
2137        $ConfigString .= $File . $Stat->mtime();
2138    }
2139
2140    return Digest::MD5::md5_hex($ConfigString);
2141}
2142
2143sub AutoloadPerlPackages {
2144    my ($Self) = @_;
2145
2146    return 1 if !$Self->{AutoloadPerlPackages};
2147    return 1 if ref $Self->{AutoloadPerlPackages} ne 'HASH';
2148    my %AutoloadConfiguration = %{ $Self->{AutoloadPerlPackages} };
2149    return 1 if !%AutoloadConfiguration;
2150
2151    CONFIGKEY:
2152    for my $ConfigKey (sort keys %AutoloadConfiguration) {
2153
2154        my $ConfigValue = $AutoloadConfiguration{$ConfigKey};
2155
2156        next CONFIGKEY if ref $ConfigValue ne 'ARRAY';
2157
2158        PACKAGE:
2159        for my $Package ( @{$ConfigValue} ) {
2160
2161            next PACKAGE if !$Package;
2162
2163            if ( substr($Package, 0, 16) ne 'Kernel::Autoload' ) {
2164                print STDERR "Error: Autoload packages must be located in Kernel/Autoload, skipping $Package\n";
2165                next PACKAGE;
2166            }
2167
2168            # Don't use the MainObject here to load the file.
2169            eval {
2170                my $FileName = $Package =~ s{::}{/}smxgr;
2171                require $FileName . '.pm'; ## nofilter(TidyAll::Plugin::OTRS::Perl::Require)
2172            };
2173        }
2174    }
2175
2176    return 1;
2177}
2178
21791;
2180
2181=head1 TERMS AND CONDITIONS
2182
2183This software is part of the OTRS project (L<https://otrs.org/>).
2184
2185This software comes with ABSOLUTELY NO WARRANTY. For details, see
2186the enclosed file COPYING for license information (GPL). If you
2187did not receive this file, see L<https://www.gnu.org/licenses/gpl-3.0.txt>.
2188
2189=cut
2190