refs #497 value objects role/user

* created value objects for role/role list and authenticated user
* removed old roles class
This commit is contained in:
Klaus Basan
2015-10-21 18:45:12 +02:00
committed by Mathew Sutcliffe
parent bcf1bed1d0
commit 134a725002
13 changed files with 588 additions and 120 deletions

View File

@@ -1,45 +0,0 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "roles.h"
namespace BlackGui
{
CRoles::CRoles() { }
bool CRoles::hasRole(const QString &role) const
{
return m_roles.contains(role);
}
bool CRoles::isAdmin() const
{
return m_roles.contains("ADMIN");
}
void CRoles::setAdmin(bool admin)
{
if (admin)
{
if (isAdmin()) { return; }
m_roles.append("ADMIN");
}
else
{
m_roles.removeAll("ADMIN");
}
}
CRoles &CRoles::roles()
{
static CRoles roles;
return roles;
}
} // roles

View File

@@ -1,47 +0,0 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKGUI_ROLES_H
#define BLACKGUI_ROLES_H
#include "blackgui/blackguiexport.h"
#include <QStringList>
namespace BlackGui
{
/*!
* Roles
*/
class BLACKGUI_EXPORT CRoles
{
public:
//! Has role?
bool hasRole(const QString &role) const;
//! Admin?
bool isAdmin() const;
//! Set admin
void setAdmin(bool admin);
//! Roles
static CRoles &roles();
private:
//! Constructor
CRoles();
QStringList m_roles;
};
} // ns
#endif // guard

View File

@@ -21,6 +21,9 @@ void BlackMisc::Network::registerMetadata()
{
CUser::registerMetadata();
CUserList::registerMetadata();
CAuthenticatedUser::registerMetadata();
CRole::registerMetadata();
CRoleList::registerMetadata();
CServer::registerMetadata();
CServerList::registerMetadata();
CTextMessage::registerMetadata();

View File

@@ -0,0 +1,140 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "blackmisc/network/authenticateduser.h"
#include "blackmisc/iconlist.h"
#include "blackmisc/blackmiscfreefunctions.h"
#include "blackmisc/propertyindex.h"
#include "blackmisc/variant.h"
#include <tuple>
namespace BlackMisc
{
namespace Network
{
CAuthenticatedUser::CAuthenticatedUser(int id, const QString &realname)
: IDatastoreObjectWithIntegerKey(id), m_realname(realname.trimmed())
{ }
CAuthenticatedUser::CAuthenticatedUser(int id, const QString &realname, const QString &email, const QString &password)
: IDatastoreObjectWithIntegerKey(id), m_realname(realname.trimmed()), m_email(email.trimmed()), m_password(password.trimmed())
{ }
QString CAuthenticatedUser::getRealNameAndId() const
{
if (hasValidRealName())
{
return m_realname + " " + getDbKeyAsStringInParentheses();
}
else
{
return getDbKeyAsString();
}
}
QString CAuthenticatedUser::convertToQString(bool i18n) const
{
Q_UNUSED(i18n);
if (this->m_realname.isEmpty()) return "<no realname>";
QString s = this->m_realname;
if (this->hasValidDbKey())
{
s.append(" ").append(this->getDbKeyAsStringInParentheses());
}
return s;
}
CAuthenticatedUser CAuthenticatedUser::fromDatabaseJson(const QJsonObject &json)
{
CAuthenticatedUser user;
user.setDbKey(json.value("id").toInt(-1));
user.setVatsimId(json.value("vatsimId").toInt(-1));
user.setRealName(json.value("name").toString());
user.setEmail(json.value("email").toString(""));
user.setCountry(CCountry(json.value("country").toString(), json.value("countryname").toString()));
user.setEnabled(json.value("enabled").toBool());
user.setAuthenticated(json.value("authenticated").toBool());
CRoleList roles(CRoleList::fromDatabaseJson(json.value("roles").toArray()));
user.setRoles(roles);
return user;
}
void CAuthenticatedUser::setRealName(const QString &realname)
{
QString rn(realname.trimmed().simplified());
this->m_realname = rn;
}
CStatusMessageList CAuthenticatedUser::validate() const
{
static const CLogCategoryList cats(CLogCategoryList(this).join({ CLogCategory::validation()}));
CStatusMessageList msgs;
// callsign optional
if (!this->hasValidDbKey()) { msgs.push_back(CStatusMessage(cats, CStatusMessage::SeverityWarning, "Invalid id"));}
if (!this->hasValidRealName()) { msgs.push_back(CStatusMessage(cats, CStatusMessage::SeverityWarning, "Invalid real name"));}
if (!this->hasValidCredentials()) { msgs.push_back(CStatusMessage(cats, CStatusMessage::SeverityWarning, "Invalid credentials"));}
return msgs;
}
bool CAuthenticatedUser::isAdmin() const
{
return this->hasRole("ADMIN");
}
CIcon CAuthenticatedUser::toIcon() const
{
return CIconList::iconByIndex(CIcons::StandardIconUser16);
}
CVariant CAuthenticatedUser::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
{
if (index.isMyself()) { return CVariant::from(*this); }
if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { return IDatastoreObjectWithIntegerKey::propertyByIndex(index); }
ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
case IndexVatsimId:
return CVariant::fromValue(this->m_vatsimId);
case IndexEmail:
return CVariant::fromValue(this->m_email);
case IndexPassword:
return CVariant::fromValue(this->m_password);
case IndexRealName:
return CVariant::fromValue(this->m_realname);
default:
return CValueObject::propertyByIndex(index);
}
}
void CAuthenticatedUser::setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index)
{
if (index.isMyself()) { (*this) = variant.to<CAuthenticatedUser>(); return; }
if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { IDatastoreObjectWithIntegerKey::setPropertyByIndex(variant, index); return; }
ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
case IndexVatsimId:
this->setVatsimId(variant.toInt());
break;
case IndexEmail:
this->setEmail(variant.value<QString>());
break;
case IndexPassword:
this->setPassword(variant.value<QString>());
break;
case IndexRealName:
this->setRealName(variant.value<QString>());
break;
default:
CValueObject::setPropertyByIndex(variant, index);
break;
}
}
} // namespace
} // namespace

View File

@@ -0,0 +1,169 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKMISC_NETWORK_AUTHENTICATEDUSER_H
#define BLACKMISC_NETWORK_AUTHENTICATEDUSER_H
#include "blackmisc/blackmiscexport.h"
#include "blackmisc/country.h"
#include "blackmisc/datastore.h"
#include "blackmisc/propertyindex.h"
#include "blackmisc/network/rolelist.h"
#include "blackmisc/statusmessagelist.h"
namespace BlackMisc
{
namespace Network
{
/*!
* Value object encapsulating information of an authentiated user.
*/
class BLACKMISC_EXPORT CAuthenticatedUser :
public CValueObject<CAuthenticatedUser>,
public BlackMisc::IDatastoreObjectWithIntegerKey
{
public:
//! Properties by index
enum ColumnIndex
{
IndexEmail = BlackMisc::CPropertyIndex::GlobalIndexCAuthenticatedUser,
IndexVatsimId,
IndexPassword,
IndexRealName
};
//! Default constructor.
CAuthenticatedUser() = default;
//! Constructor.
CAuthenticatedUser(int id, const QString &realname);
//! Constructor.
CAuthenticatedUser(int id, const QString &realname, const QString &email = "", const QString &password = "");
//! Get full name.
const QString &getRealName() const { return m_realname; }
//! Full name + id
QString getRealNameAndId() const;
//! setRealName
void setRealName(const QString &realname);
//! Get password
const QString &getPassword() const { return m_password; }
//! Set password
void setPassword(const QString &pw) { m_password = pw.trimmed(); }
//! Valid user object?
bool isValid() const { return !this->m_realname.isEmpty() && this->hasValidDbKey(); }
//! Valid credentials?
bool hasValidCredentials() const { return this->isValid() && !this->m_password.isEmpty(); }
//! Valid real name?
bool hasValidRealName() const { return !this->m_realname.isEmpty(); }
//! Validate, provide details about issues
BlackMisc::CStatusMessageList validate() const;
//! Get email.
const QString &getEmail() const { return m_email; }
//! Set email.
void setEmail(const QString &email) { m_email = email.trimmed(); }
//! Valid email?
bool hasValidEmail() const { return !this->m_email.isEmpty(); }
//! Get id.
int getVatsimId() const { return m_vatsimId; }
//! Set id
void setVatsimId(int id) { m_vatsimId = id; }
//! Roles
const CRoleList &getRoles() const { return m_roles; }
//! Roles
QString getRolesAsString() const { return m_roles.namesAsString(); }
//! Roles
void setRoles(const CRoleList &roles) { m_roles = roles; }
//! Has roles?
bool hasRole(const QString &roleName) const { return m_roles.hasRole(roleName); }
//! Country
const BlackMisc::CCountry &getCountry() const { return m_country; }
//! Country
void setCountry(const BlackMisc::CCountry &country) { m_country = country; }
//! Admin?
bool isAdmin() const;
//! Authenticated
void setAuthenticated(bool authenticated) { m_authenticated = authenticated; }
//! Authenticated
bool isAuthenticated() const { return m_authenticated; }
//! Enabled
void setEnabled(bool enabled) { m_enabled = enabled; }
//! Enabled
bool isEnabled() const { return this->m_enabled; }
//! \copydoc CValueObject::toIcon()
BlackMisc::CIcon toIcon() const;
//! \copydoc CValueObject::propertyByIndex
CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const;
//! \copydoc CValueObject::setPropertyByIndex
void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index);
//! \copydoc CValueObject::convertToQString
QString convertToQString(bool i18n = false) const;
//! From our database JSON format
static CAuthenticatedUser fromDatabaseJson(const QJsonObject &json);
private:
BLACK_ENABLE_TUPLE_CONVERSION(CAuthenticatedUser)
int m_vatsimId;
QString m_realname;
QString m_email;
QString m_password;
BlackMisc::CCountry m_country;
bool m_enabled = false;
bool m_authenticated = false;
CRoleList m_roles;
};
} // namespace
} // namespace
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Network::CAuthenticatedUser, (
o.m_dbKey,
o.m_vatsimId,
o.m_realname,
o.m_email,
o.m_password,
o.m_country,
o.m_enabled,
o.m_authenticated,
o.m_roles))
Q_DECLARE_METATYPE(BlackMisc::Network::CAuthenticatedUser)
#endif // guard

View File

@@ -19,6 +19,9 @@
#include "blackmisc/network/user.h"
#include "blackmisc/network/userlist.h"
#include "blackmisc/network/authenticateduser.h"
#include "blackmisc/network/role.h"
#include "blackmisc/network/rolelist.h"
#include "blackmisc/network/serverlist.h"
#include "blackmisc/network/textmessagelist.h"
#include "blackmisc/network/client.h"

View File

@@ -0,0 +1,71 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "role.h"
namespace BlackMisc
{
namespace Network
{
CRole::CRole(const QString &name, const QString &description)
: m_name(name), m_description(description)
{ }
QString CRole::convertToQString(bool i18n) const
{
Q_UNUSED(i18n);
return "Role: " + m_name +
" description: " + m_description +
" " + this->getDbKeyAsStringInParentheses();
}
CVariant CRole::propertyByIndex(const CPropertyIndex &index) const
{
if (index.isMyself()) { return CVariant::from(*this); }
if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { return IDatastoreObjectWithIntegerKey::propertyByIndex(index); }
ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
case IndexName:
return CVariant::fromValue(this->m_name);
case IndexDescription:
return CVariant::fromValue(this->m_description);
default:
return CValueObject::propertyByIndex(index);
}
}
void CRole::setPropertyByIndex(const CVariant &variant, const CPropertyIndex &index)
{
if (index.isMyself()) { (*this) = variant.to<CRole>(); return; }
if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { IDatastoreObjectWithIntegerKey::setPropertyByIndex(variant, index); return; }
ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
case IndexName:
this->setName(variant.value<QString>());
break;
case IndexDescription:
this->setDescription(variant.value<QString>());
default:
CValueObject::setPropertyByIndex(variant, index);
break;
}
}
CRole CRole::fromDatabaseJson(const QJsonObject &json)
{
CRole role;
role.setName(json.value("name").toString());
role.setDescription(json.value("description").toString());
role.setDbKey(json.value("idrole").toInt(-1));
return role;
}
} // ns
} // ns

View File

@@ -0,0 +1,81 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKMISC_NETWORK_ROLE_H
#define BLACKMISC_NETWORK_ROLE_H
#include "blackmisc/blackmiscexport.h"
#include "blackmisc/valueobject.h"
#include "blackmisc/datastore.h"
#include <QString>
namespace BlackMisc
{
namespace Network
{
/*!
* Role
*/
class BLACKMISC_EXPORT CRole :
public CValueObject<CRole>,
public IDatastoreObjectWithIntegerKey
{
public:
//! Properties by index
enum ColumnIndex
{
IndexName = BlackMisc::CPropertyIndex::GlobalIndexCRole,
IndexDescription
};
//! Constructor
CRole() = default;
//! Constructor
CRole(const QString &name, const QString &description);
//! Name
const QString &getName() const { return m_name; }
//! Name
void setName(const QString &name) { m_name = name.trimmed().toUpper(); }
//! Description
const QString &getDescription() const { return m_description; }
//! Description
void setDescription(const QString &description) { m_description = description.trimmed(); }
//! \copydoc CValueObject::convertToQString
QString convertToQString(bool i18n = false) const;
//! \copydoc CValueObject::propertyByIndex
CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const;
//! \copydoc CValueObject::setPropertyByIndex
void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index);
//! Role from DB JSON
static CRole fromDatabaseJson(const QJsonObject &json);
private:
BLACK_ENABLE_TUPLE_CONVERSION(CRole)
QString m_name;
QString m_description;
};
} // ns
} // ns
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Network::CRole, (o.m_dbKey, o.m_name, o.m_description))
Q_DECLARE_METATYPE(BlackMisc::Network::CRole)
#endif // guard

View File

@@ -0,0 +1,53 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "blackmisc/network/rolelist.h"
namespace BlackMisc
{
namespace Network
{
CRoleList::CRoleList() { }
bool CRoleList::hasRole(const QString &roleName) const
{
return this->contains(&CRole::getName, roleName.trimmed().toUpper());
}
bool CRoleList::hasRole(const CRole &role) const
{
return hasRole(role.getName());
}
CRoleList::CRoleList(const CSequence<CRole> &other) :
CSequence<CRole>(other)
{ }
QString CRoleList::namesAsString(const QString &separator) const
{
QStringList rolesString;
for (const CRole &role : (*this))
{
rolesString.append(role.getName());
}
return rolesString.join(separator);
}
CRoleList CRoleList::fromDatabaseJson(const QJsonArray &array)
{
CRoleList roles;
for (const QJsonValue &value : array)
{
roles.push_back(CRole::fromDatabaseJson(value.toObject()));
}
return roles;
}
} // namespace
} // namespace

View File

@@ -0,0 +1,58 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKMISC_NETWORK_ROLELIST_H
#define BLACKMISC_NETWORK_ROLELIST_H
#include "blackmisc/blackmiscexport.h"
#include "blackmisc/network/role.h"
#include "blackmisc/collection.h"
#include "blackmisc/sequence.h"
namespace BlackMisc
{
namespace Network
{
//! Value object encapsulating a list of servers.
class BLACKMISC_EXPORT CRoleList :
public CSequence<CRole>,
public BlackMisc::Mixin::MetaType<CRoleList>
{
public:
BLACKMISC_DECLARE_USING_MIXIN_METATYPE(CRoleList)
//! Default constructor.
CRoleList();
//! Has role?
bool hasRole(const QString &roleName) const;
//! Has role?
bool hasRole(const CRole &role) const;
//! Construct from a base class object.
CRoleList(const CSequence<CRole> &other);
//! Roles as string
QString namesAsString(const QString &separator = ", ") const;
//! From our database JSON format
static CRoleList fromDatabaseJson(const QJsonArray &array);
};
} //namespace
} // namespace
Q_DECLARE_METATYPE(BlackMisc::Network::CRoleList)
Q_DECLARE_METATYPE(BlackMisc::CCollection<BlackMisc::Network::CRole>)
Q_DECLARE_METATYPE(BlackMisc::CSequence<BlackMisc::Network::CRole>)
#endif //guard

View File

@@ -20,10 +20,8 @@
namespace BlackMisc
{
namespace Network
{
/*!
* Value object encapsulating information of a user.
*/

View File

@@ -74,14 +74,16 @@ namespace BlackMisc
GlobalIndexCCoordinateGeodetic = 5100,
GlobalIndexCClient = 6000,
GlobalIndexCUser = 6100,
GlobalIndexCServer = 6200,
GlobalIndexCUrl = 6300,
GlobalIndexCAircraftModel = 6400,
GlobalIndexCSimulatedAircraft = 6500,
GlobalIndexCTextMessage = 6600,
GlobalIndexCSimulatorSetup = 6700,
GlobalIndexCAircraftCfgEntries = 6800,
GlobalIndexCDistributor = 6900,
GlobalIndexCAuthenticatedUser = 6200,
GlobalIndexCRole = 6300,
GlobalIndexCServer = 6400,
GlobalIndexCUrl = 6500,
GlobalIndexCAircraftModel = 6600,
GlobalIndexCSimulatedAircraft = 6700,
GlobalIndexCTextMessage = 6800,
GlobalIndexCSimulatorSetup = 6900,
GlobalIndexCAircraftCfgEntries = 7000,
GlobalIndexCDistributor = 7100,
GlobalIndexCVPilotModelRule = 8000,
GlobalIndexCVoiceRoom = 9000,
GlobalIndexCSettingKeyboardHotkey = 10000,

View File

@@ -13,7 +13,6 @@
#include "blackgui/components/datainfoareacomponent.h"
#include "blackgui/components/logcomponent.h"
#include "blackgui/stylesheetutility.h"
#include "blackgui/roles.h"
#include "blackcore/datacache.h"
#include "blackcore/settingscache.h"
#include "blackmisc/statusmessagelist.h"
@@ -118,17 +117,6 @@ void CSwiftData::ps_onMenuClicked()
//! \todo
this->displayConsole();
}
else
{
QAction *a = qobject_cast<QAction *>(sender);
if (a)
{
if (a->data() == "admin")
{
CRoles::roles().setAdmin(true);
}
}
}
}
void CSwiftData::initDynamicMenus()
@@ -148,10 +136,4 @@ void CSwiftData::initDynamicMenus()
this->ui->menu_Mapping->addAction(CIcons::save16(), "Save DB data", this->ui->comp_MainInfoArea->getDataInfoAreaComponent(), SLOT(writeDbDataToResourceDir()));
}
}
if (CProject::isRunningInDeveloperEnvironment() && !CRoles::roles().isAdmin())
{
QAction *a = this->ui->menu_Test->addAction(CIcons::user16(), "Set administrator");
a->setData("admin");
}
}