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 9package Kernel::Output::HTML::Preferences::Password; 10 11use strict; 12use warnings; 13 14use Kernel::Language qw(Translatable); 15 16our $ObjectManagerDisabled = 1; 17 18sub new { 19 my ( $Type, %Param ) = @_; 20 21 # allocate new hash for object 22 my $Self = {%Param}; 23 bless( $Self, $Type ); 24 25 for my $Needed (qw(UserID UserObject ConfigItem)) { 26 die "Got no $Needed!" if !$Self->{$Needed}; 27 } 28 29 return $Self; 30} 31 32sub Param { 33 my ( $Self, %Param ) = @_; 34 35 # check if we need to show password change option 36 37 # define AuthModule for frontend 38 my $AuthModule = $Self->{ConfigItem}->{Area} eq 'Agent' 39 ? 'AuthModule' 40 : 'Customer::AuthModule'; 41 42 # get config object 43 my $ConfigObject = $Kernel::OM->Get('Kernel::Config'); 44 45 # get auth module 46 my $Module = $ConfigObject->Get($AuthModule); 47 my $AuthBackend = $Param{UserData}->{UserAuthBackend}; 48 if ($AuthBackend) { 49 $Module = $ConfigObject->Get( $AuthModule . $AuthBackend ); 50 } 51 52 # return on no pw reset backends 53 return if $Module =~ /(LDAP|HTTPBasicAuth|Radius)/i; 54 55 my @Params; 56 push( 57 @Params, 58 { 59 %Param, 60 Key => Translatable('Current password'), 61 Name => 'CurPw', 62 Raw => 1, 63 Block => 'Password', 64 Autocomplete => 'current-password', 65 }, 66 { 67 %Param, 68 Key => Translatable('New password'), 69 Name => 'NewPw', 70 Raw => 1, 71 Block => 'Password', 72 Autocomplete => 'new-password', 73 }, 74 { 75 %Param, 76 Key => Translatable('Verify password'), 77 Name => 'NewPw1', 78 Raw => 1, 79 Block => 'Password', 80 Autocomplete => 'current-password', 81 }, 82 ); 83 84 # set the TwoFactorModue setting name depending on the interface 85 my $AuthTwoFactorModule = $Self->{ConfigItem}->{Area} eq 'Agent' 86 ? 'AuthTwoFactorModule' 87 : 'Customer::AuthTwoFactorModule'; 88 89 # show 2 factor password input if we have at least one backend enabled 90 COUNT: 91 for my $Count ( '', 1 .. 10 ) { 92 next COUNT if !$ConfigObject->Get( $AuthTwoFactorModule . $Count ); 93 94 push @Params, { 95 %Param, 96 Key => '2 Factor Token', 97 Name => 'TwoFactorToken', 98 Raw => 1, 99 Block => 'Input', 100 }; 101 102 last COUNT; 103 } 104 105 return @Params; 106} 107 108sub Run { 109 my ( $Self, %Param ) = @_; 110 111 my $ConfigObject = $Kernel::OM->Get('Kernel::Config'); 112 my $LanguageObject = $Kernel::OM->Get('Kernel::Language'); 113 114 # pref update db 115 return 1 if $ConfigObject->Get('DemoSystem'); 116 117 # get password from form 118 my $CurPw; 119 if ( $Param{GetParam}->{CurPw} && $Param{GetParam}->{CurPw}->[0] ) { 120 $CurPw = $Param{GetParam}->{CurPw}->[0]; 121 } 122 my $Pw; 123 if ( $Param{GetParam}->{NewPw} && $Param{GetParam}->{NewPw}->[0] ) { 124 $Pw = $Param{GetParam}->{NewPw}->[0]; 125 } 126 my $Pw1; 127 if ( $Param{GetParam}->{NewPw1} && $Param{GetParam}->{NewPw1}->[0] ) { 128 $Pw1 = $Param{GetParam}->{NewPw1}->[0]; 129 } 130 131 # get the two factor token from form 132 my $TwoFactorToken; 133 if ( $Param{GetParam}->{TwoFactorToken} && $Param{GetParam}->{TwoFactorToken}->[0] ) { 134 $TwoFactorToken = $Param{GetParam}->{TwoFactorToken}->[0]; 135 } 136 137 # define AuthModule for frontend 138 my $AuthModule = $Self->{ConfigItem}->{Area} eq 'Agent' 139 ? 'Auth' 140 : 'CustomerAuth'; 141 142 my $AuthObject = $Kernel::OM->Get( 'Kernel::System::' . $AuthModule ); 143 return 1 if !$AuthObject; 144 145 # validate current password 146 if ( 147 !$AuthObject->Auth( 148 User => $Param{UserData}->{UserLogin}, 149 Pw => $CurPw, 150 TwoFactorToken => $TwoFactorToken || '', 151 ) 152 ) 153 { 154 $Self->{Error} = $LanguageObject->Translate('The current password is not correct. Please try again!'); 155 return; 156 } 157 158 # check if pw is true 159 if ( !$Pw || !$Pw1 ) { 160 $Self->{Error} = $LanguageObject->Translate('Please supply your new password!'); 161 return; 162 } 163 164 # compare pws 165 if ( $Pw ne $Pw1 ) { 166 $Self->{Error} 167 = $LanguageObject->Translate('Can\'t update password, your new passwords do not match. Please try again!'); 168 return; 169 } 170 171 # check pw 172 my $Config = $Self->{ConfigItem}; 173 174 # check if password is not matching PasswordRegExp 175 if ( $Config->{PasswordRegExp} && $Pw !~ /$Config->{PasswordRegExp}/ ) { 176 $Self->{Error} = $LanguageObject->Translate( 177 'This password is forbidden by the current system configuration. Please contact the administrator if you have additional questions.' 178 ); 179 return; 180 } 181 182 # check min size of password 183 if ( $Config->{PasswordMinSize} && length $Pw < $Config->{PasswordMinSize} ) { 184 $Self->{Error} = $LanguageObject->Translate( 185 'Can\'t update password, it must be at least %s characters long!', 186 $Config->{PasswordMinSize} 187 ); 188 return; 189 } 190 191 # check min 2 lower and 2 upper char 192 if ( 193 $Config->{PasswordMin2Lower2UpperCharacters} 194 && ( $Pw !~ /[A-Z].*[A-Z]/ || $Pw !~ /[a-z].*[a-z]/ ) 195 ) 196 { 197 $Self->{Error} = $LanguageObject->Translate( 198 'Can\'t update password, it must contain at least 2 lowercase and 2 uppercase letter characters!' 199 ); 200 return; 201 } 202 203 # check min 1 digit password 204 if ( $Config->{PasswordNeedDigit} && $Pw !~ /\d/ ) { 205 $Self->{Error} = $LanguageObject->Translate('Can\'t update password, it must contain at least 1 digit!'); 206 return; 207 } 208 209 # check min 2 char password 210 if ( $Config->{PasswordMin2Characters} && $Pw !~ /[A-z][A-z]/ ) { 211 $Self->{Error} 212 = $LanguageObject->Translate('Can\'t update password, it must contain at least 2 letter characters!'); 213 return; 214 } 215 216 # set new password 217 my $Success = $Self->{UserObject}->SetPassword( 218 UserLogin => $Param{UserData}->{UserLogin}, 219 PW => $Pw, 220 ); 221 return if !$Success; 222 223 $Self->{Message} = $LanguageObject->Translate('Preferences updated successfully!'); 224 return 1; 225} 226 227sub Error { 228 my ( $Self, %Param ) = @_; 229 230 return $Self->{Error} || ''; 231} 232 233sub Message { 234 my ( $Self, %Param ) = @_; 235 236 return $Self->{Message} || ''; 237} 238 2391; 240