Commit 9bb81b0c authored by Henning Leutz's avatar Henning Leutz 🥋

refactor: fix: Neues Benutzer Flag -> Muss Passwort ändern; user.xml in das...

refactor: fix: Neues Benutzer Flag -> Muss Passwort ändern; user.xml in das root Verzeichnis gelegt; events.xml und EventHandler für event.xml quiqqer eingeführt
parent ceb68a64
......@@ -26,5 +26,6 @@ QUI::$Ajax->registerFunction(
$User->setPassword($pw1);
},
array('uid', 'pw1', 'pw2', 'params')
array('uid', 'pw1', 'pw2', 'params'),
'Permission::checkSU'
);
<?php
/**
* Set a password for the user
*
* @param {string|integer} $uid
* @param {string} $pw1
* @param {string} $pw2
*
* @throws QUI\Exception
*/
QUI::$Ajax->registerFunction(
'ajax_users_set_passwordChange',
function ($uid, $newPassword, $passwordRepeat, $oldPassword) {
$Users = QUI::getUsers();
$User = $Users->get((int)$uid);
if ($newPassword != $passwordRepeat) {
throw new QUI\Exception(
QUI::getLocale()->get(
'quiqqer/system',
'exception.lib.user.wrong.passwords'
)
);
}
$User->changePassword($newPassword, $oldPassword);
},
array('uid', 'newPassword', 'passwordRepeat', 'oldPassword')
);
<table class="data-table">
<table class="data-table data-table-flexbox">
<thead>
<tr>
<th colspan="2">
{title text="Benutzer Passwort"}
</th>
</tr>
<tr>
<th>
{locale group="quiqqer/quiqqer" var="user.panel.password"}
</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="width: 150px">Neues Passwort setzen</td>
<td><input type="password" name="password" value="" autocomplete="off" /></td>
</tr>
<tr class="even">
<td style="width: 150px">Passwort wiederhohlen</td>
<td><input type="password" name="password2" value="" autocomplete="off" /></td>
</tr>
<tr class="even">
<td style="width: 150px"></td>
<td>
<label>
<input type="checkbox" name="showPasswords" /> Passwörter anzeigen
</label>
</td>
</tr>
<tr>
<td>
<label class="field-container">
<span class="field-container-item">
{locale group="quiqqer/quiqqer" var="user.panel.password.new"}
</span>
<input type="password" name="password"
value=""
autocomplete="off"
class="field-container-field"
/>
</label>
</td>
</tr>
<tr>
<td>
<label class="field-container">
<span class="field-container-item">
{locale group="quiqqer/quiqqer" var="user.panel.password.repeat"}
</span>
<input type="password" name="password2"
value=""
autocomplete="off"
class="field-container-field"
/>
</label>
</td>
</tr>
<tr class="even">
<td>
<label class="field-container">
<span class="field-container-item">
{locale group="quiqqer/quiqqer" var="user.panel.password.show"}
</span>
<span class="field-container-field">
<input type="checkbox" name="showPasswords"/>
</span>
</label>
</td>
</tr>
<tr>
<td>
<label class="field-container">
<span class="field-container-item">
{locale group="quiqqer/quiqqer" var="user.settings.setNewPassword"}
</span>
<span class="field-container-field">
<input type="checkbox"
name="quiqqer.set.new.password"
/>
{locale group="quiqqer/quiqqer" var="user.settings.setNewPassword.text"}
</span>
</label>
</td>
</tr>
</tbody>
</table>
<table class="data-table">
<table class="data-table data-table-flexbox">
<thead>
<tr>
<th colspan="2">
{title text="Gültig bis"}
</th>
</tr>
<tr>
<th>
{title text="Gültig bis"}
</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="width: 20px;"><input type="radio" name="expire" value="never" class="noborder" /></td>
<td>Immer</td>
</tr>
<tr class="even">
<td><input type="radio" name="expire" value="date" class="noborder" /></td>
<td>Datum / Uhrzeit</td>
</tr>
<tr class="even">
<td></td>
<td>
<div class="expire-container">
<input name="expire_date" value="" type="date" />
</div>
</td>
</tr>
<tr><td style="font-size: 5px">&nbsp;</td></tr>
<tr>
<td>
<label class="field-container">
<span class="field-container-item">
Immer
</span>
<span class="field-container-field">
<input type="radio" name="expire" value="never" class="noborder"/>
</span>
</label>
</td>
</tr>
<tr>
<td>
<label class="field-container">
<span class="field-container-item">
Datum / Uhrzeit
</span>
<span class="field-container-field">
<input type="radio"
name="expire"
value="date"
class="noborder"
style="float: left;"
/>
<span class="expire-container" style="float: left;clear: both; margin-top: 20px;">
<input name="expire_date" value="" type="date"/>
</span>
</span>
</label>
</td>
</tr>
</tbody>
</table>
\ No newline at end of file
</table>
<user>
<attributes>
<attribute>qui-bookmarks</attribute>
</attributes>
</user>
......@@ -282,8 +282,8 @@ define('controls/users/User', [
var attributes = User.getAttributes();
var extras = JSON.decode(attributes.extra);
FormUtils.setDataToForm(attributes, Body.getElement('form'));
FormUtils.setDataToForm(extras, Body.getElement('form'));
FormUtils.setDataToForm(attributes, Body.getElement('form'));
// parse all the controls
QUI.parse(Body).then(function () {
......
......@@ -7,6 +7,10 @@
* @require Ajax
* @require Locale
* @require css!controls/users/password/Password.css
*
* @event onSaveBegin [self]
* @event onSaveEnd [self]
* @event onSave [self]
*/
define('controls/users/password/Password', [
......@@ -31,7 +35,8 @@ define('controls/users/password/Password', [
],
options: {
uid: false
uid : false,
mustChange: false
},
initialize: function (options) {
......@@ -42,6 +47,8 @@ define('controls/users/password/Password', [
}
this.$Password = null;
this.$Password2 = null;
this.$OldPassword = null;
this.$ShowPassCheckbox = null;
this.addEvents({
......@@ -61,13 +68,19 @@ define('controls/users/password/Password', [
' <span class="qui-controle-user-password-title">' +
QUILocale.get(lg, 'user.panel.password.new') +
' </span>' +
' <input type="password" name="password" autocomplete="off" />' +
' <input type="password" name="password" required autocomplete="off" />' +
'</label>' +
'<label>' +
' <span class="qui-controle-user-password-title">' +
QUILocale.get(lg, 'user.panel.password.repeat') +
' </span>' +
' <input type="password" name="password2"autocomplete="off" />' +
' <input type="password" name="password2" required autocomplete="off" />' +
'</label>' +
'<label>' +
' <span class="qui-controle-user-password-title">' +
QUILocale.get(lg, 'user.panel.password.old') +
' </span>' +
' <input type="password" name="oldPassword" required autocomplete="off" />' +
'</label>' +
'<label>' +
' <input type="checkbox" name="show" />' +
......@@ -82,15 +95,18 @@ define('controls/users/password/Password', [
this.$Password = this.$Elm.getElement('[name="password"]');
this.$Password2 = this.$Elm.getElement('[name="password2"]');
this.$OldPassword = this.$Elm.getElement('[name="oldPassword"]');
this.$ShowPassCheckbox = this.$Elm.getElement('[name="show"]');
this.$ShowPassCheckbox.addEvent('change', function () {
if (this.$ShowPassCheckbox.checked) {
this.$Password.type = 'text';
this.$Password2.type = 'text';
this.$Password.type = 'text';
this.$Password2.type = 'text';
this.$OldPassword.type = 'text';
} else {
this.$Password.type = 'password';
this.$Password2.type = 'password';
this.$Password.type = 'password';
this.$Password2.type = 'password';
this.$OldPassword.type = 'password';
}
}.bind(this));
......@@ -114,15 +130,19 @@ define('controls/users/password/Password', [
return Promise.resolve();
}
this.fireEvent('saveBegin', [this]);
return new Promise(function (resolve, reject) {
QUIAjax.post('ajax_users_set_password', function () {
QUIAjax.post('ajax_users_set_passwordChange', function () {
resolve();
this.fireEvent('save', [this]);
this.fireEvent('saveEnd', [this]);
}.bind(this), {
uid : this.getAttribute('uid'),
pw1 : this.$Password.value,
pw2 : this.$Password2.value,
onError: reject
uid : this.getAttribute('uid'),
newPassword : this.$Password.value,
passwordRepeat: this.$Password2.value,
oldPassword : this.$OldPassword.value,
onError : reject
});
}.bind(this));
}
......
......@@ -28,13 +28,18 @@ define('controls/users/password/Window', [
],
options: {
icon : 'fa fa-icon',
title : QUILocale.get('quiqqer/quiqqer', 'menu.profile.userPassword.text'),
maxHeight: 400,
maxWidth : 400,
uid : false,
autoclose: false,
message : false
icon : 'fa fa-key',
title : QUILocale.get('quiqqer/system', 'menu.profile.userPassword.text'),
maxHeight : 470,
maxWidth : 340,
uid : false,
autoclose : false,
message : false,
mustChange: false,
ok_button : {
text : QUILocale.get('quiqqer/system', 'accept'),
textimage: 'fa fa-check'
}
},
initialize: function (options) {
......@@ -70,8 +75,26 @@ define('controls/users/password/Window', [
}
this.$Password = new Password({
uid: this.getAttribute('uid')
uid : this.getAttribute('uid'),
mustChange: false,
events : {
onSaveBegin: function () {
Win.Loader.show();
},
onSave : function () {
Win.Loader.hide();
}
}
}).inject(Win.getContent());
if (this.getAttribute('mustChange')) {
this.setAttribute('autoclose', false);
this.setAttribute('backgroundClosable', false);
this.Background.getElm().removeEvents('click');
this.$Title.getElements('.qui-window-popup-title-close').destroy();
this.getButton('cancel').destroy();
}
},
/**
......
......@@ -26,7 +26,6 @@ Slick.definePseudo('display', function (value) {
// IE Flickering Bug
try {
document.execCommand("BackgroundImageCache", false, true);
} catch (err) {
// Nothing to do
}
......
......@@ -168,6 +168,7 @@ label.field-container-field {
color: #666666;
font: inherit;
font-weight: normal;
width: 200px;
}
.field-container-field,
......
<?xml version="1.0" encoding="UTF-8"?>
<events>
<event on="onAdminLoadFooter" fire="\QUI\EventHandler::onAdminLoadFooter"/>
<event on="onUserSetPassword" fire="\QUI\EventHandler::onUserSetPassword"/>
</events>
\ No newline at end of file
<?php
/**
* This file contains \QUI\Intranet\EventHandler
*/
namespace QUI;
use QUI;
/**
* Intranet
*
* @author www.pcsg.de
*/
class EventHandler
{
/**
* event on onAdminLoadFooter
*/
public static function onAdminLoadFooter()
{
$User = QUI::getUserBySession();
if (!$User->getAttribute('quiqqer.set.new.password')) {
return;
}
echo "<script>
var openChangePasswordWindow = function() {
require([
'controls/users/password/Window',
'Locale'
], function(Password, QUILocale) {
new Password({
mustChange: true,
message: QUILocale.get('quiqqer/quiqqer', 'message.set.new.password')
}).open();
});
}
require(['Locale'], function(QUILocale) {
if (!QUILocale.exists('quiqqer/quiqqer', 'message.set.new.password')) {
(function() {
openChangePasswordWindow();
}).delay(2000);
return;
}
openChangePasswordWindow();
});
</script>";
}
/**
* @param QUI\Interfaces\Users\User $User
*/
public static function onUserSetPassword(QUI\Interfaces\Users\User $User)
{
$User->setAttribute('quiqqer.set.new.password', 0);
$User->save(QUI::getUsers()->getSystemUser());
}
}
......@@ -19,13 +19,13 @@ class Auth implements QUI\Interfaces\Users\Auth
* User object
* @var false|QUI\Users\User
*/
protected $User;
protected $User = null;
/**
* Name of the user
* @var string
*/
protected $username;
protected $username = null;
/**
* @param string $username
......@@ -76,7 +76,7 @@ class Auth implements QUI\Interfaces\Users\Auth
*/
public function getUserId()
{
if ($this->User) {
if (!is_null($this->User)) {
return $this->User->getId();
}
......
......@@ -733,6 +733,52 @@ class Manager
return $result;
}
/**
* Return the users authenticator
*
* @param string $username - username
* @return QUI\Interfaces\Users\Auth
*
* @throws Exception
*/
public function getAuthenticator($username)
{
// Authentifizierung
$authType = QUI::conf('auth', 'type');
$authClass = $authType;
if ($authType == 'standard') {
$authClass = Auth::class;
}
if (!class_exists($authClass)) {
QUI\System\Log::addError(
'Authentication Type not found. Please check your config settings'
);
throw new QUI\Users\Exception(
array('quiqqer/system', 'exception.login.fail'),
401
);
}
$Auth = new $authClass($username);
$implements = class_implements($Auth);
if (!isset($implements['QUI\Interfaces\Users\Auth'])) {
QUI\System\Log::addError(
'Authentication Type is not from Interface QUI\Interfaces\Users\Auth'
);
throw new QUI\Users\Exception(
array('quiqqer/system', 'exception.login.fail'),
401
);
}
return $Auth;
}
/**
* Returns all userids
*
......@@ -852,19 +898,7 @@ class Manager
);
}
$Auth = new $authClass($username);
$implements = class_implements($Auth);
if (!isset($implements['QUI\Interfaces\Users\Auth'])) {
QUI\System\Log::addError(
'Authentication Type is not from Interface QUI\Interfaces\Users\Auth'
);
throw new QUI\Users\Exception(
array('quiqqer/system', 'exception.login.fail'),
401
);
}
$Auth = $this->getAuthenticator($username);
/* @var $Auth QUI\Interfaces\Users\Auth */
if ($Auth->auth($pass) === false) {
......@@ -874,7 +908,6 @@ class Manager
);
}
$userId = $Auth->getUserId();
// check user data
......
......@@ -878,6 +878,44 @@ class User implements QUI\Interfaces\Users\User
}
}
/**
* This method can be used, for change the user password by himself
*
* @param string $newPassword
* @param string $oldPassword
* @param bool|QUI\Interfaces\Users\User $ParentUser
* @throws QUI\Users\Exception
*/
public function changePassword($newPassword, $oldPassword, $ParentUser = false)
{
$this->checkRights($ParentUser);
if (empty($newPassword) || empty($oldPassword)) {
throw new QUI\Users\Exception(
QUI::getLocale()->get(
'quiqqer/system',
'exception.lib.user.empty.password'
)
);
}
if (!$this->checkPassword($oldPassword)) {
throw new QUI\Users\Exception(
QUI::getLocale()->get(
'quiqqer/quiqqer',
'exception.user.oldPassword.is.wrong'
)
);
}
$this->setPassword($newPassword, $ParentUser);
QUI::getEvents()->fireEvent(
'userChangePassword',
array($this, $newPassword, $oldPassword)
);
}
/**
* (non-PHPdoc)
*
......@@ -933,13 +971,18 @@ class User implements QUI\Interfaces\Users\User
*/
public function checkPassword($pass, $encrypted = false)
{
if (!$encrypted) {
$_pw = $this->Users->genHash($pass);
} else {
$_pw = $pass;
if ($encrypted) {
return $pass == $this->password ? true : false;
}
try {
$Auth = QUI::getUsers()->getAuthenticator($this->getUsername());
} catch (QUI\Exception $Exception) {
QUI\System\Log::addWarning($Exception->getMessage());
return false;
}
return $_pw == $this->password ? true : false;
return $Auth->auth($pass);
}
/**
......@@ -1364,11 +1407,6 @@ class User implements QUI\Interfaces\Users\User
);
}
$attributes = array_merge(
$attributes,
$this->readAttributesFromUserXML(SYS_DIR . 'user.xml')
);
QUI\Cache\Manager::set('user/plugin-attribute-list', $attributes);
return $attributes;
......
......@@ -65,18 +65,8 @@ class Utils
);
}
/*
$Plugin = \QUI::getPlugins();
$plugins = $Plugin->get();
// user.xml auslesen
foreach ( $plugins as $Plugin ) {
$Plugin->loadUserTabs( $Tabbar, $User );
}
*/
/**
* user extention from projects
* user extension from projects
*/
$projects = QUI\Projects\Manager::getProjects();
......@@ -99,6 +89,7 @@ class Utils
* @param string $tab
*
* @return string
* @deprecated
*/
public static function getTab($uid, $plugin, $tab)
{
......@@ -116,7 +107,7 @@ class Utils
);
}
// ürpject
// project
if (strpos($plugin, 'project.') !== false) {
$project = explode('project.', $plugin);
......
......@@ -358,7 +358,11 @@
</locale>
<locale name="user.panel.password.show">
<de><![CDATA[Passwörter anzeigen]]></de>
<en><![CDATA[how passwords]]></en>
<en><![CDATA[Show passwords]]></en>
</locale>
<locale name="user.panel.password.old">
<de><![CDATA[Altes Password]]></de>
<en><![CDATA[Old password]]></en>
</locale>
<locale name="user.panel.personalData">
<de><![CDATA[Persönliche Daten / Adressen]]></de>
......@@ -404,6 +408,23 @@
<de><![CDATA[Die Gruppen <b>[groups]</b> wurde erfolgreich gespeichert.]]></de>
<en><![CDATA[The groups <b>[groups]</b> successfully deleted.]]></en>
</locale>
<locale name="message.set.new.password">
<de><![CDATA[Du musst dein Passwort ändern. Bitte gebe ein neues Passwort ein.]]></de>
<en><![CDATA[You must change your password. Please enter a new password.]]></en>
</locale>
<locale name="exception.user.oldPassword.is.wrong">
<de><![CDATA[Das alte Passwort ist nicht korrekt.]]></de>
<en><![CDATA[The old password is incorrect]]></en>
</locale>
<locale name="user.settings.setNewPassword">
<de><![CDATA[Passwort erneuern]]></de>
<en><![CDATA[Renew password]]></en>
</locale>
<locale name="user.settings.setNewPassword.text">
<de><![CDATA[Beim nächsten Login muss der Benutzer ein neues Passwort setzen.]]></de>
<en><![CDATA[At the next login, the user must set a new password.]]></en>
</locale>
</groups>
<groups name="quiqqer/quiqqer" datatype="php">
......@@ -1030,6 +1051,10 @@ Folgende Zeichen sind erlaubt: 0-9 a-z A-Z _ -</p>]]></de>
<de><![CDATA[Keine Ergebnisse gefunden]]></de>
<en><![CDATA[No results found]]></en>
</locale>
<locale name="menu.profile.userPassword.text">
<de><![CDATA[Passwort ändern]]></de>
<en><![CDATA[Change password]]></en>
</locale>
</groups>
<groups name="quiqqer/system" datatype="js">
<locale name="welcome.message">
......@@ -4840,10 +4865,6 @@ Folgende Zeichen sind erlaubt: 0-9 a-z A-Z _ -</p>]]></de>
<de><![CDATA[Profil]]></de>
<en><![CDATA[Profile]]></en>
</locale>
<locale name="menu.profile.userPassword.text">
<de><![CDATA[Passwort ändern]]></de>