Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Interfaces/API/intfPureModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ using namespace TAPI;
\**********************************************************************/
//used by Api call methods
//USER
#define USER_DELETE_METHOD_ARGS_DECL_APICALL APICALLBOOM_TYPE_JWT_USER_DECL &APICALLBOOM_PARAM, TAPI::PKsByPath_t _pksByPath = {}
#define USER_DELETE_METHOD_ARGS_DECL_APICALL APICALLBOOM_TYPE_JWT_USER_DECL &APICALLBOOM_PARAM, TAPI::PKsByPath_t _pksByPath //= {}
#define USER_DELETE_METHOD_ARGS_IMPL_APICALL APICALLBOOM_TYPE_JWT_USER_IMPL &APICALLBOOM_PARAM, TAPI::PKsByPath_t _pksByPath

#define ORMDELETE_USER(_doc, ...) apiDELETE(USER_DELETE_METHOD_ARGS_DECL_APICALL) __VA_ARGS__; \
Expand All @@ -195,7 +195,7 @@ using namespace TAPI;
#define IMPL_ORMDELETE_USER(_module) _module::apiDELETE(USER_DELETE_METHOD_ARGS_IMPL_APICALL)

//API
#define API_DELETE_METHOD_ARGS_DECL_APICALL APICALLBOOM_TYPE_JWT_API_DECL &APICALLBOOM_PARAM, TAPI::PKsByPath_t _pksByPath = {}
#define API_DELETE_METHOD_ARGS_DECL_APICALL APICALLBOOM_TYPE_JWT_API_DECL &APICALLBOOM_PARAM, TAPI::PKsByPath_t _pksByPath //= {}
#define API_DELETE_METHOD_ARGS_IMPL_APICALL APICALLBOOM_TYPE_JWT_API_IMPL &APICALLBOOM_PARAM, TAPI::PKsByPath_t _pksByPath

#define ORMDELETE_API(_doc, ...) apiDELETE(API_DELETE_METHOD_ARGS_DECL_APICALL) __VA_ARGS__; \
Expand All @@ -205,7 +205,7 @@ using namespace TAPI;
#define IMPL_ORMDELETE_API(_module) _module::apiDELETE(API_DELETE_METHOD_ARGS_IMPL_APICALL)

//used by internal methods
#define DELETE_METHOD_ARGS_DECL_INTERNAL INTFAPICALLBOOM_DECL &APICALLBOOM_PARAM, TAPI::PKsByPath_t _pksByPath = {}
#define DELETE_METHOD_ARGS_DECL_INTERNAL INTFAPICALLBOOM_DECL &APICALLBOOM_PARAM, TAPI::PKsByPath_t _pksByPath //= {}
#define DELETE_METHOD_ARGS_IMPL_INTERNAL INTFAPICALLBOOM_IMPL &APICALLBOOM_PARAM, TAPI::PKsByPath_t _pksByPath

#define DELETE_METHOD_ARGS_CALL_VALUES APICALLBOOM_PARAM, _pksByPath
Expand Down
18 changes: 13 additions & 5 deletions Interfaces/DBM/QueryBuilders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2538,12 +2538,20 @@ ORMSelectQuery& ORMSelectQuery::addColsFromInlineJoinCols(Q_DECL_UNUSED const QL
ORMSelectQuery& ORMSelectQuery::addCol(const clsColSpecs& _colSpecs) {

//check duplicates
QString ColSpecToCompare;
if (_colSpecs.renameAs().isEmpty())
ColSpecToCompare = _colSpecs.name();
else
ColSpecToCompare = _colSpecs.renameAs();

foreach (auto Col, this->Data->RequiredCols) {
if ((Col.name().isEmpty() == false)
&& (_colSpecs.name().isEmpty() == false)
&& (Col.name() == _colSpecs.name())
&& (Col.renameAs() == _colSpecs.renameAs())
)
QString ColToCompare;
if (Col.renameAs().isEmpty())
ColToCompare = Col.name();
else
ColToCompare = Col.renameAs();

if (ColSpecToCompare == ColToCompare)
return *this;
}

Expand Down
21 changes: 21 additions & 0 deletions Modules/Account/functionalTest/testAccount.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1732,6 +1732,27 @@ private slots:
}
}

void apitoken_edit_name_and_expiry() {
QT_TRY {
QVariant Result = this->callUserAPI(
RESTClientHelper::enuHTTPMethod::PATCH,
"Account/APITokens",
{},
{
{ "token", this->TokenJWT },
{ "name", "new name aa" },
{ "expireDate", "2345/06/07 12:34:56" },
});

QVERIFY(Result.isValid());

this->TokenJWT = Result.toMap().value("token").toString();

} QT_CATCH (const std::exception &exp) {
QTest::qFail(exp.what(), __FILE__, __LINE__);
}
}

void apitoken_new_resume() {
QT_TRY {
QVariant Result = this->callUserAPI(
Expand Down
101 changes: 101 additions & 0 deletions Modules/Account/moduleSrc/ORM/APITokens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,92 @@ QVariant IMPL_ORMGET_USER(APITokens) {
return this->Select(GET_METHOD_ARGS_CALL_VALUES);
}

QVariantMap IMPL_REST_UPDATE(APITokens, , (
APICALLBOOM_TYPE_JWT_USER_DECL &APICALLBOOM_PARAM,
QString _token,
QString _name,
NULLABLE_TYPE(TAPI::DateTime_t) _expireDate
)) {
QVariantMap MethodResult;

quint64 CurrentUserID = APICALLBOOM_PARAM.getActorID();

TAPI::JWT_t TokenJWTPayload;
QJWT::extractAndDecryptPayload(_token, TokenJWTPayload);

if (CurrentUserID != TokenJWTPayload["own"].toDouble())
throw exAuthorization("This API Token is not yours");

//----------------------------------------
enuTokenActorType::Type TokenType = enuTokenActorType::USER;
if (TokenJWTPayload.contains("typ"))
TokenType = enuTokenActorType::toEnum(TokenJWTPayload["typ"].toString());
if (TokenType != enuTokenActorType::API)
throw exHTTPForbidden("Only API Token allowed");

//----------------------------------------
auto UpdateQuery = this->makeUpdateQuery(APICALLBOOM_PARAM)
.where({ tblAPITokens::Fields::aptToken, enuConditionOperator::Equal, _token });

int ToUpdateCount = 0;

if (_name.isNull() == false) {
++ToUpdateCount;
UpdateQuery.set(tblAPITokens::Fields::aptName, _name);
}

QString NewToken;

if (NULLABLE_HAS_VALUE(_expireDate)) {
TokenJWTPayload["exp"] = (NULLABLE_VALUE(_expireDate)).toSecsSinceEpoch();
NewToken = QJWT::encryptAndSigned(TokenJWTPayload);
MethodResult.insert("token", NewToken);

++ToUpdateCount;
UpdateQuery
.set(tblAPITokens::Fields::aptToken, NewToken)
.set(tblAPITokens::Fields::aptExpiryDate, NULLABLE_VALUE(_expireDate))
;
}

if (ToUpdateCount == 0)
throw exHTTPInternalServerError("Nothing to do");

try {
if (UpdateQuery.execute(CurrentUserID) == 0)
throw exHTTPInternalServerError("Error in updating");
} catch (const std::exception &_exp) {
QString ExpStr = _exp.what();
if (ExpStr.contains("Duplicate entry", Qt::CaseInsensitive))
throw /*exHTTPConflict*/exHTTPBadRequest("This name has already been used");

throw;
}

if (NewToken.isEmpty() == false) {
QString OldTokenMD5 = QCryptographicHash::hash(_token.toLatin1(), QCryptographicHash::Md5).toHex().constData();
QString NewTokenMD5 = QCryptographicHash::hash(NewToken.toLatin1(), QCryptographicHash::Md5).toHex().constData();

QString qry = QString()
+ "UPDATE " + tblTokenBin::Name
+ " SET tkbTokenMD5=?"
+ " WHERE tkbTokenMD5=?"
;

clsDACResult Result = TokenBin::instance().execQuery(APICALLBOOM_PARAM,
qry,
QVariantList({
NewTokenMD5,
OldTokenMD5
})
);
}

MethodResult.insert("result", true);

return MethodResult;
}

QVariant IMPL_REST_GET(APITokens, byService, (
APICALLBOOM_TYPE_JWT_USER_IMPL &APICALLBOOM_PARAM,
QStringList _services,
Expand Down Expand Up @@ -283,9 +369,14 @@ Targoman::API::AccountModule::stuRequestTokenResult IMPL_REST_POST(APITokens, re
)) {
// QString TokenMD5 = QCryptographicHash::hash(_token.toLatin1(), QCryptographicHash::Md5).toHex().constData();

quint64 CurrentUserID = APICALLBOOM_PARAM.getActorID();

TAPI::JWT_t TokenJWTPayload;
QJWT::extractAndDecryptPayload(_token, TokenJWTPayload);

if (CurrentUserID != TokenJWTPayload["own"].toDouble())
throw exAuthorization("This API Token is not yours");

//----------------------------------------
enuTokenActorType::Type TokenType = enuTokenActorType::USER;
if (TokenJWTPayload.contains("typ"))
Expand Down Expand Up @@ -342,9 +433,14 @@ bool IMPL_REST_POST(APITokens, pause, (
APICALLBOOM_TYPE_JWT_USER_IMPL &APICALLBOOM_PARAM,
const QString &_token
)) {
quint64 CurrentUserID = APICALLBOOM_PARAM.getActorID();

TAPI::JWT_t TokenJWTPayload;
QJWT::extractAndDecryptPayload(_token, TokenJWTPayload);

if (CurrentUserID != TokenJWTPayload["own"].toDouble())
throw exAuthorization("This API Token is not yours");

//----------------------------------------
enuTokenActorType::Type TokenType = enuTokenActorType::USER;
if (TokenJWTPayload.contains("typ"))
Expand All @@ -369,9 +465,14 @@ bool IMPL_REST_POST(APITokens, resume, (
APICALLBOOM_TYPE_JWT_USER_IMPL &APICALLBOOM_PARAM,
const QString &_token
)) {
quint64 CurrentUserID = APICALLBOOM_PARAM.getActorID();

TAPI::JWT_t TokenJWTPayload;
QJWT::extractAndDecryptPayload(_token, TokenJWTPayload);

if (CurrentUserID != TokenJWTPayload["own"].toDouble())
throw exAuthorization("This API Token is not yours");

//----------------------------------------
enuTokenActorType::Type TokenType = enuTokenActorType::USER;
if (TokenJWTPayload.contains("typ"))
Expand Down
17 changes: 14 additions & 3 deletions Modules/Account/moduleSrc/ORM/APITokens.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,14 @@ namespace tblAPITokens {
const QList<clsORMField> ORMFields = {
//ColName Type validation Default UpBy Sort Filter Self Virt PK
{ Fields::aptID, ORM_PRIMARYKEY_64 },
{ Fields::aptToken, S(QString), QFV, QRequired, UPAdmin, true, true },
{ Fields::aptToken, S(QString), QFV, QRequired, UPOwner, true, true },
//aptTokenMD5
{ Fields::aptName, S(QString), QFV.asciiAlNum().maxLenght(250), QRequired, UPOwner, true, true },
{ Fields::apt_usrID, S(quint64), QFV.integer().minValue(1), QRequired, UPNone },
{ Fields::aptLang, S(TAPI::ISO639_2_t), QFV, "en", UPOwner },
{ Fields::aptValidateIP, S(bool), QFV, false, UPOwner },
{ Fields::aptExtraPrivileges, S(TAPI::PrivObject_t), QFV, QNull, UPAdmin, false, false },
{ Fields::aptExpiryDate, S(TAPI::DateTime_t), QFV, QNull, UPAdmin },
{ Fields::aptExtraPrivileges, S(TAPI::PrivObject_t), QFV, QNull, UPOwner, false, false },
{ Fields::aptExpiryDate, S(TAPI::DateTime_t), QFV, QNull, UPOwner },
{ Fields::aptLastActivity, S(TAPI::DateTime_t), QFV, QInvalid, UPNone },
{ Fields::aptAccessCount, S(quint32), QFV.integer().minValue(1), QInvalid, UPNone },
{ Fields::aptPaused, S(bool), QFV, false, UPOwner },
Expand Down Expand Up @@ -301,6 +301,17 @@ private slots:
// bool ORMUPDATE_USER("Update an APIToken")
// bool ORMDELETE_USER("Delete an APIToken")

QVariantMap REST_UPDATE(
,
(
APICALLBOOM_TYPE_JWT_USER_DECL &APICALLBOOM_PARAM,
QString _token,
QString _name = {},
NULLABLE_TYPE(TAPI::DateTime_t) _expireDate = NULLABLE_NULL_VALUE
),
"Update token name and expire date. Returns new token and other info"
)

QVariant REST_GET(
byService,
(
Expand Down
24 changes: 22 additions & 2 deletions Modules/Account/moduleSrc/ORM/User.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,28 @@ bool IMPL_ORMUPDATE_USER(User) {
return this->Update(UPDATE_METHOD_ARGS_CALL_VALUES);
}

bool IMPL_ORMDELETE_USER(User) {
if (APICALLBOOM_PARAM.getActorID() != _pksByPath.toULongLong())
//bool IMPL_ORMDELETE_USER(User) {
// if (APICALLBOOM_PARAM.getActorID() != _pksByPath.toULongLong())
// Authorization::checkPriv(APICALLBOOM_PARAM, this->privOn(EHTTP_DELETE, this->moduleBaseName()));

// return this->DeleteByPks(DELETE_METHOD_ARGS_CALL_VALUES);
//}

bool IMPL_REST_DELETE(User, , (
USER_DELETE_METHOD_ARGS_IMPL_APICALL,
TAPI::MD5_t _pass,
QString _salt
)) {
if (APICALLBOOM_PARAM.getActorID() == _pksByPath.toULongLong()) {
//check password if is set
this->callSP(APICALLBOOM_PARAM,
"spUser_CheckPassword", {
{ "iUserID", APICALLBOOM_PARAM.getActorID() },
{ "iPass", _pass },
{ "iSalt", _salt },
{ "iThrowIfPassNotSet", 0 },
});
} else
Authorization::checkPriv(APICALLBOOM_PARAM, this->privOn(EHTTP_DELETE, this->moduleBaseName()));

return this->DeleteByPks(DELETE_METHOD_ARGS_CALL_VALUES);
Expand Down
12 changes: 11 additions & 1 deletion Modules/Account/moduleSrc/ORM/User.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,17 @@ private slots:
QVariant ORMGET_USER("Get user information")
quint64 ORMCREATE_USER("Create a new user by an authorized user. Email or Mobile is required")
bool ORMUPDATE_USER("Update User info by an authorized user")
bool ORMDELETE_USER("Delete a User by an authorized user")
// bool ORMDELETE_USER("Delete a User by an authorized user")

bool REST_DELETE(
,
(
USER_DELETE_METHOD_ARGS_DECL_APICALL,
TAPI::MD5_t _pass = {},
QString _salt = {}
),
"Delete an user"
)

TAPI::Base64Image_t REST_GET(
photo,
Expand Down