Commit 44dad435 authored by Leander Schulten's avatar Leander Schulten
Browse files

Add Support for Auto-Login. Redesign the permission dialog. Closes #37

parent 9d8db799
Pipeline #171409 passed with stage
in 1 minute and 38 seconds
......@@ -206,6 +206,8 @@ int main(int argc, char *argv[])
file.copy(file.fileName()+"_"+QDateTime::currentDateTime().toString("dd.MM.yyyy HH.mm.ss"));
}
auto after = ApplicationData::loadData(file);
// nachdem die Benutzer geladen wurden, auto login durchführen
UserManagment::get()->autoLoginUser();
//#warning Dont use IDBase<xxxxx>::getAllIDBases() in this file. It will crash the aplication when its closing
......
......@@ -73,6 +73,7 @@ public:
const std::vector<Type>& getVector()const{return model;}
std::vector<Type>& getVector(){return model;}
typename std::vector<Type>::size_type size()const{return model.size();}
int ssize()const{return static_cast<int>(size());}
virtual int rowCount(const QModelIndex &) const override{return static_cast<int>(model.size());}
/**
* @brief data Return always, if the index is valid, a QVarient that contains the data at the vector
......@@ -194,7 +195,7 @@ public:
model.push_back(t);
endPushBack();
if(cap!=model.capacity()){
emit dataChanged(index(0,0),index(model.size()-1,0));
emit QAbstractItemModel::dataChanged(index(0,0),index(model.size()-1,0));
}
}
}
......@@ -213,7 +214,7 @@ public:
model.push_back(std::forward<Type>(t));
endPushBack();
if(cap!=model.capacity()){
emit dataChanged(index(0,0),index(model.size()-1,0));
emit QAbstractItemModel::dataChanged(index(0,0),index(model.size()-1,0));
}
}
}
......@@ -230,7 +231,7 @@ public:
model.emplace_back(std::forward<_Args>(__args)...);
endPushBack();
if(cap!=model.capacity()){
emit dataChanged(index(0,0),index(model.size()-1,0));
emit QAbstractItemModel::dataChanged(index(0,0),index(model.size()-1,0));
}
}
}
......@@ -242,6 +243,10 @@ public:
return model[index];
}
void dataChanged(int index_){
emit QAbstractItemModel::dataChanged(index(index_), index(index_));
}
typename std::vector<Type>::const_reference operator[](int index)const{
return model[index];
}
......
......@@ -72,5 +72,6 @@
<file>icons/sort_order/sort-reverse-alphabetical-order_32px.png</file>
<file>icons/sort_order/sort-reverse-alphabetical-order_64px.png</file>
<file>icons/sort_order/sort-reverse-alphabetical-order_source</file>
<file>qml/UserSettingsPopup.qml</file>
</qresource>
</RCC>
......@@ -72,14 +72,13 @@ Item{
}
Button{
visible: UserManagment.currentUser.havePermission(Permission.Admin);
text:"Change Permissions"
text:"Change Permissions and Auto-Login"
anchors.right: buttonChangePassword.left
anchors.top: buttonChangePassword.top
anchors.bottom: buttonChangePassword.bottom
anchors.rightMargin: 5
onClicked: {
permissionsView.model = modelData.permissionModel;
permissionDialog.visible = true;
userSettingsPopup.show(modelData);
}
}
Button{
......@@ -315,32 +314,8 @@ Item{
onYesClicked: UserManagment.removeUser(_user);
}
Dialog{
modality: Qt.WindowModal
id:permissionDialog
title: "Chnage Permissions."
width:350
height: 400
contentItem: ListView{
id:permissionsView
delegate: SwitchDelegate{
width: permissionsView.width
checked: havePermission
onCheckedChanged: havePermission = checked
text: permissionName
}
anchors.bottomMargin: 40
Layout.bottomMargin: 40
Button{
text:"Ok"
anchors.margins: 5
anchors.left: permissionsView.left
anchors.right: permissionsView.right
anchors.bottom: permissionsView.bottom
onClicked: permissionDialog.visible=false
}
}
UserSettingsPopup{
id: userSettingsPopup
}
}
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtGraphicalEffects 1.0
import "components"
Popup {
property var user: null;
id: popup
bottomPadding: 0
x: 15
y: 15
width: parent.width - 30
height: parent.height - 30
function show(newUser){
user = newUser;
visible = true;
}
Page{
anchors.fill: parent
header: TabBar{
id: tabBar
currentIndex: swipeView.currentIndex
TabButton{
text: "Permissions"
}
TabButton{
text: "Auto Login"
}
}
contentItem: SwipeView{
clip: true
id: swipeView
currentIndex: tabBar.currentIndex
interactive: false
ListView{
clip: true
id: permissionsView
model: user?user.permissionModel:null
delegate: SwitchDelegate{
width: permissionsView.width
checked: havePermission
onCheckedChanged: if(havePermission !== checked) havePermission = checked
text: permissionName
}
}
Item{
ColumnLayout{
anchors.fill: parent
anchors.margins: 5
Label{
Layout.fillWidth: true
text: "A user can be auto logged in in the light control, when a specific OS user is currently logged in. In this case no password is required.\nThe user name of the currently logged in os user is: " + UserManagment.currentOsUserName + "\nHere you can specify the usernames for the account " + (user?user.name:"null") + ":"
wrapMode: "WordWrap"
Layout.margins: 5
}
ListView{
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
id: usernameView
model: user?user.autologinUsernames:null
delegate: ItemDelegate{
width: usernameView.width
text: modelData
onClicked: usernameView.currentIndex = index
}
highlight: Rectangle{
color: "blue"
opacity: 0.7
}
Rectangle{
anchors.fill: parent
border.width: 1
border.color: "gray"
color: "#00000000"
radius: 3
layer.enabled: true;
layer.effect: FastBlur{
radius: 8
}
}
}
RowLayout{
Layout.fillWidth: true
Label{
text: "Username: "
}
TextInputField{
Layout.fillWidth: true
id: username
text: usernameView.currentItem?usernameView.currentItem.text:""
}
Button{
text: "Change"
enabled: usernameView.currentItem && username.text.length > 0
onClicked: user.changeAutologinUsername(usernameView.currentIndex,username.text)
}
Button{
text: "Add"
enabled: username.text.length > 0
onClicked: {
user.addAutologinUsername(username.text);
usernameView.currentIndex = -1;
}
}
Button{
text: "Remove"
enabled: usernameView.currentItem
onClicked: user.removeAutologinUsername(usernameView.currentIndex);
}
}
}
}
}
footer: RowLayout {
layoutDirection: Qt.RightToLeft
Button{
Layout.fillWidth: true
Layout.margins: 4
text: "Close"
onClicked: popup.visible = false;
}
}
}
}
......@@ -9,6 +9,12 @@ UserManagment::UserManagment():readUser(new User("Default","")),currentUser(read
for(int i = 0 ; i< LAST_PERMISSION;++i){
admin->setPermission(static_cast<Permission>(i));
}*/
#ifdef Q_OS_UNIX
currentOsUserName = qgetenv("USER");
#else
// Windows:
currentOsUserName = qgetenv("UserName");
#endif
}
User* UserManagment::getUserById(ID::value_type id){
......@@ -98,6 +104,21 @@ bool UserManagment::login(User *user, const QString &password){
return false;
}
void UserManagment::autoLoginUser(){
if (currentOsUserName.isEmpty()) {
return;
}
for(const auto & user : users){
for(const auto & name : user->getAutoLoginUserNames()){
if(name == currentOsUserName){
currentUser = user.get();
emit currentUserChanged();
return;
}
}
}
}
void UserManagment::logout(User *user){
if(currentUser==user){
currentUser = readUser;
......@@ -132,13 +153,18 @@ bool UserPermissionModel::setData(const QModelIndex &index, const QVariant &valu
if(UserManagment::get()->getCurrentUser()->havePermission(UserManagment::Admin)){
if(index.row()>=0 && index.row()<rowCount(index)){
const UserManagment::Permission p = static_cast<UserManagment::Permission>(index.row());
if(user->havePermission(p)!=value.toBool()){
user->setPermission(p,value.toBool());
emit dataChanged(index,index,{HavePermissionRole});
return true;
// ein admin darf sich nicht selber entmachten:
if(p != UserManagment::Admin || UserManagment::get()->getCurrentUser() != user){
if(user->havePermission(p)!=value.toBool()){
user->setPermission(p,value.toBool());
emit dataChanged(index,index,{HavePermissionRole});
return true;
}
}
}
}
// you cant change the setting, notify all bindings
emit dataChanged(index,index,{HavePermissionRole});
}
return false;
}
......@@ -157,6 +183,10 @@ User::User(const QJsonObject &o):QObject(UserManagment::get()),username(o["usern
for(const auto & i : array){
permissions.insert(static_cast<UserManagment::Permission>(i.toInt()));
}
const auto arrayNames = o["autologinUsernames"].toArray();
for(const auto & i : arrayNames){
autologinUsernames.push_back(i.toString());
}
}
void User::writeJsonObject(QJsonObject &o) const{
......@@ -167,6 +197,11 @@ void User::writeJsonObject(QJsonObject &o) const{
a.push_back(*i);
}
o.insert("permissions",a);
QJsonArray names;
for(const auto & i : autologinUsernames){
names.push_back(i);
}
o.insert("autologinUsernames",names);
}
User * UserManagment::getUserByName(const QString &name) const{
......
......@@ -20,9 +20,11 @@ class UserManagment : public QObject
Q_PROPERTY(User* currentUser READ getCurrentUser NOTIFY currentUserChanged)
Q_PROPERTY(User* defaultUser READ getCurrentUser CONSTANT)
Q_PROPERTY(QAbstractItemModel * users READ getUserModel CONSTANT)
Q_PROPERTY(QString currentOsUserName READ getCurrentOsUserName CONSTANT)
private:
User * readUser;
User * currentUser;
QString currentOsUserName;
ModelVector<std::unique_ptr<User>> users;
UserManagment();
friend class User;
......@@ -101,6 +103,10 @@ public:
* @return true for success, false for failure
*/
Q_INVOKABLE bool login(User * user, const QString &passwort);
/**
* @brief autoLoginUser checks if the autologin user name of one user matches the currentOsUserName and login the user where the name match
*/
void autoLoginUser();
/**
* @brief logout logout the current User
*/
......@@ -121,6 +127,11 @@ public:
* @return The currently logined user
*/
User * getCurrentUser()const{return currentUser;}
/**
* @brief getCurrentOsUserName returns the username of the current os user that is logged in
* @return the username of the currently logged in os user
*/
QString getCurrentOsUserName()const{return currentOsUserName;}
signals:
void currentUserChanged();
};
......@@ -161,12 +172,14 @@ class User : public QObject, public IDBase<User>{
Q_OBJECT
Q_PROPERTY(QString name READ getUsername NOTIFY usernameChanged)
Q_PROPERTY(QAbstractListModel * permissionModel READ getPermissionModel CONSTANT)
Q_PROPERTY(QAbstractListModel * autologinUsernames READ getAutoLoginUserNameModel CONSTANT)
friend class UserManagment;
friend class UserPermissionModel;
private:
QString username;
QByteArray password;
std::set<UserManagment::Permission> permissions;
ModelVector<QString> autologinUsernames;
UserPermissionModel permissionModel;
void setUsername(const QString &u){if(u==username)return;username = u;emit usernameChanged(username);}
void setPermission(UserManagment::Permission p,bool get = true);
......@@ -189,6 +202,22 @@ public:
*/
Q_INVOKABLE bool havePermission(UserManagment::Permission p){return permissions.find(p)!=permissions.cend();}
UserPermissionModel * getPermissionModel(){return &permissionModel;}
QAbstractListModel * getAutoLoginUserNameModel(){return &autologinUsernames;}
const ModelVector<QString>& getAutoLoginUserNames()const{return autologinUsernames;}
Q_INVOKABLE void removeAutologinUsername(int index){
if (index >= 0 && index < autologinUsernames.ssize()) {
autologinUsernames.erase(index);
}
}
Q_INVOKABLE void changeAutologinUsername(int index, const QString &newUserName){
if (index >= 0 && index < autologinUsernames.ssize()) {
autologinUsernames[index] = newUserName;
autologinUsernames.dataChanged(index);
}
}
Q_INVOKABLE void addAutologinUsername(const QString &newUserName){
autologinUsernames.push_back(newUserName);
}
signals:
void usernameChanged(QString);
void permissionChanged(UserManagment::Permission,bool);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment