Skip to content

Commit

Permalink
Merge pull request #196 from Targoman/mt_create_module
Browse files Browse the repository at this point in the history
Mt create module
  • Loading branch information
kambizzandi authored Sep 3, 2022
2 parents ea59179 + 10dac18 commit 37804aa
Show file tree
Hide file tree
Showing 197 changed files with 8,454 additions and 2,089 deletions.
20 changes: 11 additions & 9 deletions App/Server/OpenAPIGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,19 +509,21 @@ QJsonObject OpenAPIGenerator::retrieveJson(
});
}

if (APIObject->requiresJWT()) {
ResponseModel["401"] = QJsonObject({{"description", "Authorization information is missing or invalid"}});
ResponseModel["403"] = QJsonObject({{"description", "Access forbidden"}});
// if (APIObject->requiresJWT()) {
if (APIObject->tokenActorType() != enuTokenActorType::ANONYMOUSE) {
ResponseModel["401"] = QJsonObject({{ "description", "Authorization information is missing or invalid" }});
ResponseModel["403"] = QJsonObject({{ "description", "Access forbidden" }});
}

PathInfo["responses"] = ResponseModel;

if (APIObject->requiresJWT()) {
PathInfo["security"] = QJsonArray({
QJsonObject({
{"Bearer", QJsonArray()}
})
});
// if (APIObject->requiresJWT()) {
if (APIObject->tokenActorType() != enuTokenActorType::ANONYMOUSE) {
PathInfo["security"] = QJsonArray({
QJsonObject({
{ "Bearer", QJsonArray() },
})
});
}
return PathInfo;
}; // lambda createPathInfo
Expand Down
10 changes: 8 additions & 2 deletions App/Server/RESTAPIRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,8 @@ QMap<QString, QString> RESTAPIRegistry::extractMethods(
clsAPIObject* APIObject = _registry.value(Key);
QStringList Parameters;

if (APIObject->requiresJWT())
// if (APIObject->requiresJWT())
if (APIObject->tokenActorType() != enuTokenActorType::ANONYMOUSE)
Parameters.append(QString(_showTypes ? "TAPI::JWT_t " : "") + "JWT");

for (quint8 i=0; i<APIObject->/*BaseMethod.parameterCount()*/ParamTypesName.count(); ++i) {
Expand Down Expand Up @@ -685,12 +686,17 @@ void RESTAPIRegistry::dumpAPIs()

bool IsLastMethod = (Method == Methods.last());

QString JWTType = "";
// if (API.APIObject->requiresJWT())
if (API.APIObject->tokenActorType() != enuTokenActorType::ANONYMOUSE)
JWTType = QString(" (JWT:%1)").arg(enuTokenActorType::toStr(API.APIObject->tokenActorType()));

TargomanDebug(5).noLabel().noquote().nospace()
<< (IsLastAPI ? " " : "") << " "
<< (IsLastMethod ? "" : "") << "──"
<< "(" << QString::number(MethodsIndex++) << ") "
<< Method.toUpper() // << " " << Name
<< (API.APIObject->requiresJWT() ? " (JWT)" : "")
<< JWTType
;

if (API.APIObject->ParamTypesName.isEmpty() == false) {
Expand Down
4 changes: 2 additions & 2 deletions App/Server/ServerConfigs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,8 @@ gConfigs::Server::stuStatistics::stuStatistics(const QString& _basePath) :
enuConfigSource::ReadOnly
) { ; }
tmplConfigurableMultiMap<gConfigs::Server> gConfigs::TranslationServers(
clsConfigPath("TranslationServers"),
tmplConfigurableMultiMap<gConfigs::Server> gConfigs::Engines(
clsConfigPath("Engines"),
"List of valid translation servers to connect to them separated by their translation engine");
*/

Expand Down
2 changes: 1 addition & 1 deletion App/Server/StaticModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

namespace Targoman::API::Server {

TARGOMAN_IMPL_API_MODULE(StaticModule)
TARGOMAN_API_MODULE_IMPLEMENT(StaticModule)

StaticModule::StaticModule() :
intfPureModule("")
Expand Down
4 changes: 3 additions & 1 deletion App/Server/StaticModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ class StaticModule : public intfPureModule
Q_OBJECT
Q_PLUGIN_METADATA(IID INTFPUREMODULE_IID)
Q_INTERFACES(Targoman::API::API::intfPureModule)
TARGOMAN_DEFINE_API_MODULE(StaticModule);
//---------------------------------------------------------
TARGOMAN_API_MODULE_DEFINE(StaticModule); //, enuTokenActorType::USER);
//---------------------------------------------------------

private slots:
TAPI::RawData_t EXREST_GET_OR_POST(
Expand Down
37 changes: 25 additions & 12 deletions App/Server/appTargomanAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,28 +59,33 @@ void appTargomanAPI::slotExecute() {
ServerCommonConfigs::InstanceID.setFromVariant(QString("TAPI-%1").arg(QSysInfo::machineHostName()));
TargomanDebug(0) << "Instance-ID: " << ServerCommonConfigs::InstanceID.value();

QMap<QString, intfPureModule::stuDBInfo> RequiredDBs;
QMap<QString, stuModuleDBInfo> RequiredDBs;

auto RegisterModule = [&RequiredDBs](intfPureModule *_module) -> bool {
auto RegisterModule = [&RequiredDBs](intfPureModule *_module) {
_module->setInstancePointer();

TargomanDebug(0) << "Loading module <" << _module->moduleFullName() << ">";
TargomanDebug(0) << "Registering module <" << _module->moduleFullName() << ">";

foreach (auto ModuleMethod, _module->listOfMethods())
RESTAPIRegistry::registerRESTAPI(ModuleMethod.Module, ModuleMethod.Method);

auto DBInfo = _module->requiredDB();
QMap<QString, stuModuleDBInfo> DBInfos = _module->requiredDBs();

if (DBInfo.Schema.size())
RequiredDBs.insert(_module->moduleBaseName(), DBInfo);
for (auto it = DBInfos.constBegin();
it != DBInfos.constEnd();
it++
) {
if (it->Schema.size() && (RequiredDBs.contains(it.key()) == false))
RequiredDBs.insert(/*_module->moduleBaseName()*/ it.key(), it.value());
}

return _module->init();
//_module->initializeModule();
};

//-- StaticModule --
static StaticModule *StaticModuleInstance = new StaticModule();
if (RegisterModule(StaticModuleInstance) == false)
throw exAPIModuleInitiailization("Unable to init StaticModule");
RegisterModule(StaticModuleInstance);
// throw exAPIModuleInitiailization("Unable to init StaticModule");

//-- Dynamic Modules --
//#ifndef QT_DEBUG
Expand All @@ -94,8 +99,8 @@ void appTargomanAPI::slotExecute() {
if (!Module)
throw exInvalidAPIModule(QString("Seems that this an incorrect module: %1").arg(Plugin.File));

if (RegisterModule(Module) == false)
throw exAPIModuleInitiailization(QString("Unable to init module: %1").arg(Plugin.File));
RegisterModule(Module);
// throw exAPIModuleInitiailization(QString("Unable to init module: %1").arg(Plugin.File));
}
//#endif

Expand All @@ -106,7 +111,7 @@ void appTargomanAPI::slotExecute() {

if (ServerConfigs::MasterDB::Host.value().size()
&& ServerConfigs::MasterDB::Schema.value().size()) {
intfPureModule::stuDBInfo MasterDBInfo = {
stuModuleDBInfo MasterDBInfo = {
ServerConfigs::MasterDB::Schema.value(),
ServerConfigs::MasterDB::Port.value(),
ServerConfigs::MasterDB::Host.value(),
Expand Down Expand Up @@ -142,6 +147,14 @@ void appTargomanAPI::slotExecute() {
}
}

//-- init modules
StaticModuleInstance->initializeModule();

foreach (auto Plugin, LoadedModules) {
intfPureModule* Module = qobject_cast<intfPureModule*>(Plugin.Instance);
Module->initializeModule();
}

RESTServer::instance().start();

OpenAPIGenerator::retrieveJson();
Expand Down
12 changes: 8 additions & 4 deletions App/Server/clsAPIObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,24 +55,28 @@ clsAPIObject::clsAPIObject(
RequiredParamsCount(static_cast<quint8>(_method.parameterCount())),
HasExtraMethodName(_hasExtraMethodName),
Parent(_module),
RequiresJWT(false)
// RequiresJWT(false)
TokenActorType(enuTokenActorType::ANONYMOUSE)
{
QList<QByteArray> parameterTypes = _method.parameterTypes();
quint8 i = 0;

foreach (const QByteArray &ParamName, _method.parameterNames()) {
QString ParameterTypeName = parameterTypes.at(i);

/*if (ParameterTypeName.startsWith(APICALLBOOM_TYPE_JWT_DECL)) {
/*if (ParameterTypeName.startsWith(APICALLBOOM_TYPE_JWT_USER_DECL)) {
this->ParamNames.append("JWT");
this->ParamTypesName.append(PARAM_JWT);
this->ParamTypesID.append(QMetaType::type(PARAM_JWT));
this->BaseMethod.DefaultValues[0] = {};
} else */if (ParameterTypeName.startsWith(APICALLBOOM_TYPE_BASE_STR)) { //APICALLBOOM_TYPE_NO_JWT_DECL)) {
--this->RequiredParamsCount;
this->BaseMethod.DefaultValues.removeAt(0);
if (ParameterTypeName.startsWith(APICALLBOOM_TYPE_JWT_DECL_STR))
this->RequiresJWT = true;
// this->RequiresJWT = true;
if (ParameterTypeName.startsWith(APICALLBOOM_TYPE_JWT_USER_DECL_STR))
this->TokenActorType = enuTokenActorType::USER;
else if (ParameterTypeName.startsWith(APICALLBOOM_TYPE_JWT_API_DECL_STR))
this->TokenActorType = enuTokenActorType::API;
} else {
QByteArray ParamNameNoUnderScore = (ParamName.startsWith('_') ? ParamName.mid(1) : ParamName);
this->ParamNames.append(ParamNameNoUnderScore);
Expand Down
20 changes: 15 additions & 5 deletions App/Server/clsAPIObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,23 @@ class clsAPIObject : public intfAPIObject, public QObject
return (this->BaseMethod.name() + QJsonValue::fromVariant(_args).toString().toUtf8()).constData();
}

inline bool requiresJWT() const {
return this->RequiresJWT; //ParamTypesName.contains(PARAM_JWT);
}

inline bool isHidden() const {
return this->BaseMethod.Hidden;
}

intfPureModule* parentModule() {
return this->Parent;
}

// inline bool requiresJWT() const {
// return this->RequiresJWT; //ParamTypesName.contains(PARAM_JWT);
// }

// inline enuTokenActorType::Type moduleActorType() const {
// return this->Parent->actorType();
// }
enuTokenActorType::Type tokenActorType() { return this->TokenActorType; }

// inline bool requiresCookies() const {
// return this->ParamTypesName.contains(PARAM_COOKIES);
// }
Expand Down Expand Up @@ -154,7 +163,8 @@ class clsAPIObject : public intfAPIObject, public QObject
quint8 RequiredParamsCount;
bool HasExtraMethodName;
intfPureModule* Parent;
bool RequiresJWT;
// bool RequiresJWT;
enuTokenActorType::Type TokenActorType;

friend class RESTAPIRegistry;
friend class OpenAPIGenerator;
Expand Down
45 changes: 35 additions & 10 deletions App/Server/clsRequestHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ using namespace Targoman::API::Helpers;
#include "Interfaces/AAA/Authentication.h"
using namespace Targoman::API::AAA;

using namespace TAPI;

namespace Targoman::API::Server {

using namespace qhttp::server;
Expand Down Expand Up @@ -129,7 +131,8 @@ void clsRequestHandler::process(const QString& _api) {

for (auto JSONObjectIter = JSONObject.begin();
JSONObjectIter != JSONObject.end();
++JSONObjectIter) {
++JSONObjectIter
) {
if (JSONObjectIter.value().isBool())
this->Request->addUserDefinedData(JSONObjectIter.key(), JSONObjectIter.value().toBool() ? "1" : "0");
else if (JSONObjectIter.value().isNull())
Expand Down Expand Up @@ -339,9 +342,12 @@ clsRequestHandler::stuResult clsRequestHandler::run(
};

QScopedPointer<intfAPICallBoom> APICALLBOOM;
if (_apiObject->requiresJWT())
APICALLBOOM.reset(new APICALLBOOM_TYPE_JWT_DECL(fnTiming));
else
// if (_apiObject->requiresJWT())
if (_apiObject->tokenActorType() == enuTokenActorType::USER)
APICALLBOOM.reset(new APICALLBOOM_TYPE_JWT_USER_DECL(fnTiming));
else if (_apiObject->tokenActorType() == enuTokenActorType::API)
APICALLBOOM.reset(new APICALLBOOM_TYPE_JWT_API_DECL(fnTiming));
else //enuTokenActorType::ANONYMOUSE
APICALLBOOM.reset(new APICALLBOOM_TYPE_NO_JWT_DECL(fnTiming));

try {
Expand All @@ -356,7 +362,10 @@ clsRequestHandler::stuResult clsRequestHandler::run(
qhttp::THeaderHash Cookies;
TAPI::JWT_t JWT;

if (_apiObject->requiresJWT()) {
// enuTokenActorType::Type AcceptableActorType = _apiObject->moduleActorType();
enuTokenActorType::Type TokenActorType = _apiObject->tokenActorType();
// if (_apiObject->requiresJWT()) {
if (TokenActorType != enuTokenActorType::ANONYMOUSE) {
auto ServerTiming = APICALLBOOM->createScopeTiming("jwt");

QString Auth = Headers.value("authorization");
Expand All @@ -368,15 +377,30 @@ clsRequestHandler::stuResult clsRequestHandler::run(
QJWT::verifyJWT(
BearerToken,
RemoteIP,
TokenActorType,
JWT
);

//check svcs just for API tokens
if ((TokenActorType == enuTokenActorType::API)
&& JWT.contains("prv") && JWT["prv"].toObject().contains("svc")) {
QString ModuleBaseName = _apiObject->parentModule()->moduleBaseName().split(":").first();
if (ModuleBaseName.isEmpty() == false) {
QStringList AllowedServices = JWT["prv"].toObject()["svc"].toString().split(",", QString::SkipEmptyParts);
if (AllowedServices.contains(ModuleBaseName) == false)
throw exHTTPForbidden(QString("Service `%1` not allowed by this token").arg(ModuleBaseName));
}
}

} catch (exJWTExpired &exp) {
QString TokenType = "user";
enuTokenActorType::Type TokenType = enuTokenActorType::USER;

if (JWT.contains("typ"))
TokenType = JWT["typ"].toString();
TokenType = enuTokenActorType::toEnum(JWT["typ"].toString());

if (TokenType == "user") {
/*if (TokenType == enuTokenActorType::System) {
//do nothing
} else*/ if (TokenType == enuTokenActorType::USER) {
auto ServerTiming = APICALLBOOM->createScopeTiming("jwt", "renew");

bool IsRenewed = false;
Expand All @@ -395,11 +419,12 @@ clsRequestHandler::stuResult clsRequestHandler::run(
APICALLBOOM->addResponseHeader("x-auth-warning", "replace token");
APICALLBOOM->addResponseHeaderNameToExpose("x-auth-warning");
}
} else if (TokenType == "api")
} else if (TokenType == enuTokenActorType::API)
throw exHTTPForbidden("API token is expired");
else
throw exHTTPForbidden("Unknown token type");
throw exHTTPForbidden(QString("Unknown token type `%1`").arg(TokenType));
}

JWT["encodedJWT"] = BearerToken;
} else
throw exHTTPForbidden("No valid authentication header is present");
Expand Down
Loading

0 comments on commit 37804aa

Please sign in to comment.