From 90f6ce73e4f549b7c110c222b64b79e2b038a7a3 Mon Sep 17 00:00:00 2001 From: Martin Preuss Date: Sat, 13 Sep 2025 02:17:45 +0200 Subject: [PATCH] more work on aqhome-cgi --- apps/aqhome-cgi/modules/0BUILD | 4 + apps/aqhome-cgi/modules/madmin.c | 107 ++++ apps/aqhome-cgi/modules/madmin.h | 25 + apps/aqhome-cgi/modules/mdevices.c | 4 + apps/aqhome-cgi/modules/mmodules.c | 566 ++++++++++++++++++ apps/aqhome-cgi/modules/mmodules.h | 25 + apps/aqhome-cgi/modules/mroot.c | 20 + apps/aqhome-cgi/modules/static/en/header.html | 1 + 8 files changed, 752 insertions(+) create mode 100644 apps/aqhome-cgi/modules/madmin.c create mode 100644 apps/aqhome-cgi/modules/madmin.h create mode 100644 apps/aqhome-cgi/modules/mmodules.c create mode 100644 apps/aqhome-cgi/modules/mmodules.h diff --git a/apps/aqhome-cgi/modules/0BUILD b/apps/aqhome-cgi/modules/0BUILD index ebed6f4..79acadb 100644 --- a/apps/aqhome-cgi/modules/0BUILD +++ b/apps/aqhome-cgi/modules/0BUILD @@ -53,6 +53,8 @@ mroot.h mdataclient.h mdevices.h + madmin.h + mmodules.h @@ -69,6 +71,8 @@ mroot.c mdataclient.c mdevices.c + madmin.c + mmodules.c diff --git a/apps/aqhome-cgi/modules/madmin.c b/apps/aqhome-cgi/modules/madmin.c new file mode 100644 index 0000000..1d7082f --- /dev/null +++ b/apps/aqhome-cgi/modules/madmin.c @@ -0,0 +1,107 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include "./madmin.h" + +#include "aqhome-cgi/service/module.h" +#include "aqhome-cgi/modules/mmodules.h" + +#include +#include + + + +/* ------------------------------------------------------------------------------------------------ + * defs and enums + * ------------------------------------------------------------------------------------------------ + */ + +/* ------------------------------------------------------------------------------------------------ + * global vars + * ------------------------------------------------------------------------------------------------ + */ + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + +static AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName); +static int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem); +static int _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq); + + +/* ------------------------------------------------------------------------------------------------ + * code + * ------------------------------------------------------------------------------------------------ + */ + +void AQH_ModAdmin_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder) +{ + AQH_ModService_Extend(m, sv, baseFolder); + AQH_ModService_SetHandleRequestFn(m, _handleRequest); + AQH_ModService_SetLoadSubModuleFn(m, _loadSubModule); +} + + + +AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName) +{ + AQH_SERVICE *sv; + + sv=AQH_ModService_GetService(m); + if (strcasecmp(sModuleName, "modules")==0) { + AQH_MODULE *mSub; + + mSub=AQH_Service_LoadModule(sv, sModuleName); + if (mSub) { + const char *s; + GWEN_BUFFER *nbuf; + + nbuf=GWEN_Buffer_new(0, 256, 0, 1); + s=AQH_ModService_GetBaseFolder(m); + GWEN_Buffer_AppendArgs(nbuf, "%s/modules", s?s:"."); + + AQH_ModAdmModules_Extend(mSub, AQH_ModService_GetService(m), GWEN_Buffer_GetStart(nbuf)); + AQH_Module_Tree2_AddChild(m, mSub); + GWEN_Buffer_free(nbuf); + return mSub; + } + } + return NULL; +} + + + +int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem) +{ + if (strcasecmp(sLastPathElem, "index.html")==0) + return _handleRqIndex(m, rq); + else { + AQCGI_SendResponseWithStatus(rq, 404, "Not Found"); + return GWEN_ERROR_NOT_IMPLEMENTED; + } +} + + + +int _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq) +{ + if (AQCGI_Request_GetRequestMethod(rq)==AQCGI_REQUEST_METHOD_GET) + return AQH_ModService_RespondWithFile(m, rq, "en", "index.html"); + AQCGI_SendResponseWithStatus(rq, 404, "Not Found"); + return GWEN_ERROR_GENERIC; +} + + + diff --git a/apps/aqhome-cgi/modules/madmin.h b/apps/aqhome-cgi/modules/madmin.h new file mode 100644 index 0000000..488897a --- /dev/null +++ b/apps/aqhome-cgi/modules/madmin.h @@ -0,0 +1,25 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQHOME_CGI_MADMIN_H +#define AQHOME_CGI_MADMIN_H + +#include + +#include + +#include + + +void AQH_ModAdmin_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder); + + + + +#endif + diff --git a/apps/aqhome-cgi/modules/mdevices.c b/apps/aqhome-cgi/modules/mdevices.c index 553c840..e4bddfa 100644 --- a/apps/aqhome-cgi/modules/mdevices.c +++ b/apps/aqhome-cgi/modules/mdevices.c @@ -180,6 +180,7 @@ void _runValues(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATA "" "Name" "Type" + "Modality" "Driver" "Device" "Name for System" @@ -199,6 +200,9 @@ void _runValues(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATA s=AQH_ValueType_toString(AQH_Value_GetValueType(value)); GWEN_Buffer_AppendArgs(dbuf, "%s", s?s:""); + s=AQH_ValueModality_toString(AQH_Value_GetModality(value)); + GWEN_Buffer_AppendArgs(dbuf, "%s", s?s:""); + s=AQH_Value_GetDriver(value); GWEN_Buffer_AppendArgs(dbuf, "%s", s?s:""); diff --git a/apps/aqhome-cgi/modules/mmodules.c b/apps/aqhome-cgi/modules/mmodules.c new file mode 100644 index 0000000..05eaf59 --- /dev/null +++ b/apps/aqhome-cgi/modules/mmodules.c @@ -0,0 +1,566 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include "./madmin.h" + +#include "aqhome-cgi/service/module.h" + +#include +#include + + + +/* ------------------------------------------------------------------------------------------------ + * defs and enums + * ------------------------------------------------------------------------------------------------ + */ + +/* ------------------------------------------------------------------------------------------------ + * global vars + * ------------------------------------------------------------------------------------------------ + */ + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + +static AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName); +static int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem); +static int _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); +static int _handleRqEditMod(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); +static int _handleRqEditModGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); +static int _handleRqEditModPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); +static int _handleRqEditPerm(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); +static int _handleRqEditPermGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); +static int _handleRqEditPermPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); + +static void _writePermissionsToForm(const AQH_PERMDEF_LIST *permDefList, uint32_t perms, GWEN_BUFFER *dbuf); +static uint32_t _readPermissionsFromForm(GWEN_DB_NODE *dbPost, const AQH_PERMDEF_LIST *permDefList); + + + +/* ------------------------------------------------------------------------------------------------ + * code + * ------------------------------------------------------------------------------------------------ + */ + +void AQH_ModAdmModules_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder) +{ + AQH_ModService_Extend(m, sv, baseFolder); + AQH_ModService_SetHandleRequestFn(m, _handleRequest); + AQH_ModService_SetLoadSubModuleFn(m, _loadSubModule); +} + + + +AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName) +{ + /* no sub-modules */ + return NULL; +} + + + +int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem) +{ + GWEN_BUFFER *dbuf; + int rv; + + dbuf=GWEN_Buffer_new(0, 256, 0, 1); + AQH_ModService_AddHeader(m, "en", dbuf); + + if (strcasecmp(sLastPathElem, "index.html")==0) + rv=_handleRqIndex(m, rq, session, dbuf); + else if (strcasecmp(sLastPathElem, "editmodule.html")==0) + rv=_handleRqEditMod(m, rq, session, dbuf); + else if (strcasecmp(sLastPathElem, "editperm.html")==0) + rv=_handleRqEditPerm(m, rq, session, dbuf); + else { + AQH_ModService_AddFooter(m, "en", dbuf); + AQCGI_Request_SetBufferResponseBody(rq, dbuf); + AQCGI_Request_AddResponseHeaderData(rq, "Content-type: text/html"); + AQCGI_SendResponseWithStatus(rq, 404, "Not Found"); + GWEN_Buffer_free(dbuf); + return GWEN_ERROR_NOT_IMPLEMENTED; + } + AQH_ModService_AddFooter(m, "en", dbuf); + AQCGI_Request_SetBufferResponseBody(rq, dbuf); + AQCGI_Request_AddResponseHeaderData(rq, "Content-type: text/html"); + + if (rv==1) + AQCGI_SendResponseWithStatus(rq, 302, "See other"); + else + AQCGI_SendResponseWithStatus(rq, 200, "Ok"); + GWEN_Buffer_free(dbuf); + return 0; +} + + + +int _handleRqIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) +{ + AQH_SERVICE *sv; + GWEN_STRINGLIST *slModules; + + sv=AQH_ModService_GetService(m); + slModules=AQH_Service_ListModules(sv); + if (slModules) { + GWEN_STRINGLISTENTRY *se; + + GWEN_Buffer_AppendString(dbuf, "

Modules

\n"); + GWEN_Buffer_AppendString(dbuf, + "\n" + "" + "" + "" + "" + "" + "" + "" + "\n" + "\n"); + se=GWEN_StringList_FirstEntry(slModules); + while(se) { + const char *sModName; + + sModName=GWEN_StringListEntry_Data(se); + if (sModName && *sModName) { + AQH_MODULE *currentMod; + + currentMod=AQH_Service_LoadModule(sv, sModName); + if (currentMod) { + const char *s; + const char *sName; + + sName=AQH_Module_GetName(currentMod); + + GWEN_Buffer_AppendString(dbuf, ""); + /* id */ + GWEN_Buffer_AppendArgs(dbuf, "", (unsigned long int) AQH_Module_GetId(currentMod)); + + GWEN_Buffer_AppendArgs(dbuf, "", sName?sName:""); + + s=AQH_Module_GetDescr(currentMod); + GWEN_Buffer_AppendArgs(dbuf, "", s?s:""); + + GWEN_Buffer_AppendArgs(dbuf, + "", + sName?sName:""); + GWEN_Buffer_AppendArgs(dbuf, "\n"); + AQH_Module_free(currentMod); + } + } + se=GWEN_StringListEntry_Next(se); + } + GWEN_Buffer_AppendString(dbuf, + "\n" + "
IdNameDescriptionActions
%lu%s%s
\n"); + GWEN_StringList_free(slModules); + } + GWEN_Buffer_AppendString(dbuf, "
Add Module"); + return 0; +} + + + +int _handleRqEditMod(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) +{ + if (AQCGI_Request_GetRequestMethod(rq)==AQCGI_REQUEST_METHOD_GET) + return _handleRqEditModGet(m, rq, session, dbuf); + else if (AQCGI_Request_GetRequestMethod(rq)==AQCGI_REQUEST_METHOD_POST) + return _handleRqEditModPost(m, rq, session, dbuf); + else { + DBG_ERROR(NULL, "Invalid request method %d", AQCGI_Request_GetRequestMethod(rq)); + AQCGI_SendResponseWithStatus(rq, 405, "Method No Allowed"); + return GWEN_ERROR_INVALID; + } + return 0; +} + + + +int _handleRqEditModGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) +{ + AQH_SERVICE *sv; + GWEN_DB_NODE *dbQuery; + + sv=AQH_ModService_GetService(m); + dbQuery=AQCGI_Request_GetDbQuery(rq); + if (dbQuery) { + const char *sModName; + + sModName=GWEN_DB_GetCharValue(dbQuery, "name", 0, NULL); + if (sModName && *sModName) { + AQH_MODULE *currentMod; + + currentMod=AQH_Service_LoadModule(sv, sModName); + if (currentMod) { + const char *sName; + const char *sDescr; + const AQH_PERMDEF_LIST *permDefList; + + permDefList=AQH_Module_GetPermDefList(currentMod); + sName=AQH_Module_GetName(currentMod); + sDescr=AQH_Module_GetDescr(currentMod); + GWEN_Buffer_AppendString(dbuf, "

Module Info

\n"); + GWEN_Buffer_AppendArgs(dbuf, + "
\n" + "\n" + "" + "" + "" + "\n" + "" + "" + "" + "\n", + sName?sName:"", sDescr?sDescr:""); + + if (permDefList) { + GWEN_Buffer_AppendArgs(dbuf, + "" + "\n" + "" ""); + } + + GWEN_Buffer_AppendString(dbuf, "
"); + _writePermissionsToForm(permDefList, AQH_Module_GetGuestPerms(currentMod), dbuf); + GWEN_Buffer_AppendArgs(dbuf, "
\n"); + + GWEN_Buffer_AppendArgs(dbuf, "\n", sModName?sModName:""); + GWEN_Buffer_AppendString(dbuf, "\n
\n\n"); + + GWEN_Buffer_AppendString(dbuf, "

Permission Definitions

\n"); + if (permDefList) { + const AQH_PERMDEF *permDef; + + GWEN_Buffer_AppendString(dbuf, + "\n" + "" + "\n" + "\n" + "\n"); + permDef=AQH_PermDef_List_First(permDefList); + while(permDef) { + const char *sId; + const char *s; + + GWEN_Buffer_AppendString(dbuf, ""); + /* id */ + sId=AQH_PermDef_GetId(permDef); + GWEN_Buffer_AppendArgs(dbuf, "", sId?sId:""); + /* mask */ + GWEN_Buffer_AppendArgs(dbuf, "", AQH_PermDef_GetMask(permDef)); + /* description */ + s=AQH_PermDef_GetDescr(permDef); + GWEN_Buffer_AppendArgs(dbuf, "", s?s:""); + /* actions */ + GWEN_Buffer_AppendArgs(dbuf, ""); + + GWEN_Buffer_AppendString(dbuf, "\n"); + + permDef=AQH_PermDef_List_Next(permDef); + } + GWEN_Buffer_AppendString(dbuf, + "\n" + "
IdMaskDescriptionActions
%s0x%x%s"); + GWEN_Buffer_AppendArgs(dbuf, + "" + "", + sModName?sModName:"", sId?sId:""); + GWEN_Buffer_AppendArgs(dbuf, + "" + "", + sModName?sModName:"", sId?sId:""); + GWEN_Buffer_AppendArgs(dbuf, "
\n"); + } + else { + GWEN_Buffer_AppendString(dbuf, "none"); + } + GWEN_Buffer_AppendArgs(dbuf, + "" + "Add Permission\n", + sModName?sModName:""); + + return 0; + } + } + } + + AQCGI_Request_AddResponseHeaderData(rq, "Location: index.html"); + return 1; /* redirect */ +} + + + +int _handleRqEditModPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) +{ + AQH_SERVICE *sv; + GWEN_DB_NODE *dbPost; + + DBG_ERROR(NULL, "Post request received"); + sv=AQH_ModService_GetService(m); + dbPost=AQCGI_Request_GetDbPostBody(rq); + if (dbPost) { + const char *sModName; + + sModName=GWEN_DB_GetCharValue(dbPost, "module", 0, NULL); + if (sModName && *sModName) { + AQH_MODULE *currentMod; + + currentMod=AQH_Service_LoadModule(sv, sModName); + if (currentMod) { + const char *sNewModName; + const char *sDescr; + int rv; + uint32_t perms; + const AQH_PERMDEF_LIST *permDefList; + + permDefList=AQH_Module_GetPermDefList(currentMod); + sNewModName=GWEN_DB_GetCharValue(dbPost, "name", 0, NULL); + sDescr=GWEN_DB_GetCharValue(dbPost, "descr", 0, NULL); + perms=_readPermissionsFromForm(dbPost, permDefList); + if (sNewModName && *sNewModName) + AQH_Module_SetName(currentMod, sNewModName); + AQH_Module_SetDescr(currentMod, sDescr); + AQH_Module_SetGuestPerms(currentMod, perms); + rv=AQH_Service_SaveModule(sv, currentMod); + if (rv<0) { + GWEN_Buffer_AppendString(dbuf, "

Error

Error saving module

"); + DBG_ERROR(NULL, "Could not save module \"%s\"", sModName); + return 0; + } + else { + DBG_ERROR(NULL, "Module \"%s\" saved", sModName); + } + AQH_Module_free(currentMod); + } + else { + DBG_ERROR(NULL, "Could not load module \"%s\"", sModName); + } + } + else { + DBG_ERROR(NULL, "No module name"); + } + } + else { + DBG_ERROR(NULL, "dbPost missing"); + } + AQCGI_Request_AddResponseHeaderData(rq, "Location: index.html"); + return 1; /* redirect! */ +} + + + +int _handleRqEditPerm(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) +{ + if (AQCGI_Request_GetRequestMethod(rq)==AQCGI_REQUEST_METHOD_GET) + return _handleRqEditPermGet(m, rq, session, dbuf); + else if (AQCGI_Request_GetRequestMethod(rq)==AQCGI_REQUEST_METHOD_POST) + return _handleRqEditPermPost(m, rq, session, dbuf); + else { + DBG_ERROR(NULL, "Invalid request method %d", AQCGI_Request_GetRequestMethod(rq)); + AQCGI_SendResponseWithStatus(rq, 405, "Method Not Allowed"); + return GWEN_ERROR_INVALID; + } + return 0; +} + + + +int _handleRqEditPermGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) +{ + AQH_SERVICE *sv; + GWEN_DB_NODE *dbQuery; + const char *sModName; + const char *sId; + const char *sDescr; + uint32_t mask; + AQH_MODULE *currentMod; + const AQH_PERMDEF_LIST *permDefList; + const AQH_PERMDEF *permDef; + + sv=AQH_ModService_GetService(m); + dbQuery=AQCGI_Request_GetDbQuery(rq); + sModName=dbQuery?GWEN_DB_GetCharValue(dbQuery, "mod", 0, NULL):NULL; + sId=dbQuery?GWEN_DB_GetCharValue(dbQuery, "id", 0, NULL):NULL; + currentMod=(sModName && *sModName)?AQH_Service_LoadModule(sv, sModName):NULL; + permDefList=currentMod?AQH_Module_GetPermDefList(currentMod):NULL; + permDef=(permDefList && sId && *sId)?AQH_PermDef_List_GetById(permDefList, sId):NULL; + sDescr=permDef?AQH_PermDef_GetDescr(permDef):NULL; + mask=permDef?AQH_PermDef_GetMask(permDef):0; + + if (permDef) { + GWEN_Buffer_AppendArgs(dbuf, "

Edit Permission Definition for Module %s

\n", sModName?sModName:""); + GWEN_Buffer_AppendArgs(dbuf, + "
\n" + "\n" + "" + "" + "" + "\n" + "\n" + "" + "" + "\n" + "" + "" + "" + "\n", + sId, (unsigned long int) mask, sDescr?sDescr:""); + GWEN_Buffer_AppendString(dbuf, "
\n"); + + GWEN_Buffer_AppendArgs(dbuf, "\n", sModName?sModName:""); + GWEN_Buffer_AppendArgs(dbuf, "\n", sId?sId:""); + GWEN_Buffer_AppendString(dbuf, "\n"); + GWEN_Buffer_AppendString(dbuf, "
\n\n"); + return 0; + } + else { + GWEN_BUFFER *tbuf; + + tbuf=GWEN_Buffer_new(0, 256, 0, 1); + GWEN_Buffer_AppendArgs(tbuf, "Location: editmodule.html?name=%s", sModName?sModName:""); + AQCGI_Request_AddResponseHeaderData(rq, GWEN_Buffer_GetStart(tbuf)); + GWEN_Buffer_free(tbuf); + return 1; /* redirect */ + } +} + + + +int _handleRqEditPermPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) +{ + AQH_SERVICE *sv; + GWEN_DB_NODE *dbPost; + const char *sModName; + AQH_MODULE *currentMod; + const char *sOldId; + const char *sNewId; + const char *sDescr; + const char *sMask; + uint32_t mask=0; + AQH_PERMDEF_LIST *permDefList; + AQH_PERMDEF *permDef; + long int i; + int rv; + GWEN_BUFFER *tbuf; + + /* sample data */ + sv=AQH_ModService_GetService(m); + dbPost=AQCGI_Request_GetDbPostBody(rq); + sModName=dbPost?GWEN_DB_GetCharValue(dbPost, "mod", 0, NULL):NULL; + currentMod=(sModName && *sModName)?AQH_Service_LoadModule(sv, sModName):NULL; + sOldId=dbPost?GWEN_DB_GetCharValue(dbPost, "oldId", 0, NULL):NULL; + sNewId=dbPost?GWEN_DB_GetCharValue(dbPost, "id", 0, NULL):NULL; + sDescr=dbPost?GWEN_DB_GetCharValue(dbPost, "descr", 0, NULL):NULL; + sMask=dbPost?GWEN_DB_GetCharValue(dbPost, "mask", 0, NULL):NULL; + if (sMask && *sMask && 1==sscanf(sMask, "%li", &i)) + mask=i; + permDefList=currentMod?AQH_Module_GetPermDefList(currentMod):NULL; + permDef=(permDefList && sOldId)?AQH_PermDef_List_GetById(permDefList, sOldId):NULL; + + /* validate */ + if (mask==0) { + DBG_ERROR(NULL, "Invalid value for mask"); + } + if (permDef==NULL) { + DBG_ERROR(NULL, "PermDef %s not found", sOldId?sOldId:NULL); + } + + /* set new values */ + AQH_PermDef_SetId(permDef, sNewId); + AQH_PermDef_SetMask(permDef, mask); + AQH_PermDef_SetDescr(permDef, sDescr); + + /* save module */ + rv=AQH_Service_SaveModule(sv, currentMod); + if (rv<0) { + GWEN_Buffer_AppendString(dbuf, "

Error

Error saving module

"); + DBG_ERROR(NULL, "Could not save module \"%s\"", sModName); + return 0; + } + + tbuf=GWEN_Buffer_new(0, 256, 0, 1); + GWEN_Buffer_AppendArgs(tbuf, "Location: editmodule.html?name=%s", sModName?sModName:""); + AQCGI_Request_AddResponseHeaderData(rq, GWEN_Buffer_GetStart(tbuf)); + GWEN_Buffer_free(tbuf); + return 1; /* redirect */ +} + + + + + + + + + + +void _writePermissionsToForm(const AQH_PERMDEF_LIST *permDefList, uint32_t perms, GWEN_BUFFER *dbuf) +{ + if (permDefList) { + const AQH_PERMDEF *permDef; + + permDef=AQH_PermDef_List_First(permDefList); + while(permDef) { + const char *s; + uint32_t mask; + + s=AQH_PermDef_GetId(permDef); + mask=AQH_PermDef_GetMask(permDef); + if (perms & mask) + GWEN_Buffer_AppendArgs(dbuf, "", s?s:""); + else + GWEN_Buffer_AppendArgs(dbuf, "", s?s:""); + GWEN_Buffer_AppendArgs(dbuf, "", s?s:"", s?s:""); + + permDef=AQH_PermDef_List_Next(permDef); + } + } +} + + + +uint32_t _readPermissionsFromForm(GWEN_DB_NODE *dbPost, const AQH_PERMDEF_LIST *permDefList) +{ + uint32_t result=0; + + if (permDefList) { + const AQH_PERMDEF *permDef; + + permDef=AQH_PermDef_List_First(permDefList); + while(permDef) { + const char *id; + uint32_t mask; + const char *s; + + id=AQH_PermDef_GetId(permDef); + mask=AQH_PermDef_GetMask(permDef); + s=GWEN_DB_GetCharValue(dbPost, id, 0, NULL); + if (s && *s) + result|=mask; + permDef=AQH_PermDef_List_Next(permDef); + } + } + + return result; +} + + + + + + + diff --git a/apps/aqhome-cgi/modules/mmodules.h b/apps/aqhome-cgi/modules/mmodules.h new file mode 100644 index 0000000..16f56bb --- /dev/null +++ b/apps/aqhome-cgi/modules/mmodules.h @@ -0,0 +1,25 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQHOME_CGI_MMODULES_H +#define AQHOME_CGI_MMODULES_H + +#include + +#include + +#include + + +void AQH_ModAdmModules_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder); + + + + +#endif + diff --git a/apps/aqhome-cgi/modules/mroot.c b/apps/aqhome-cgi/modules/mroot.c index 5e2352f..57268fa 100644 --- a/apps/aqhome-cgi/modules/mroot.c +++ b/apps/aqhome-cgi/modules/mroot.c @@ -15,6 +15,7 @@ #include "aqhome-cgi/service/module.h" #include "aqhome-cgi/modules/mdevices.h" +#include "aqhome-cgi/modules/madmin.h" #include #include @@ -81,6 +82,25 @@ AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *sessio GWEN_Buffer_AppendArgs(nbuf, "%s/devices", s?s:"."); AQH_ModDevices_Extend(mSub, AQH_ModService_GetService(m), GWEN_Buffer_GetStart(nbuf)); + AQH_Module_Tree2_AddChild(m, mSub); + GWEN_Buffer_free(nbuf); + return mSub; + } + } + else if (strcasecmp(sModuleName, "admin")==0) { + AQH_MODULE *mSub; + + mSub=AQH_Service_LoadModule(sv, sModuleName); + if (mSub) { + const char *s; + GWEN_BUFFER *nbuf; + + nbuf=GWEN_Buffer_new(0, 256, 0, 1); + s=AQH_ModService_GetBaseFolder(m); + GWEN_Buffer_AppendArgs(nbuf, "%s/devices", s?s:"."); + + AQH_ModAdmin_Extend(mSub, AQH_ModService_GetService(m), GWEN_Buffer_GetStart(nbuf)); + AQH_Module_Tree2_AddChild(m, mSub); GWEN_Buffer_free(nbuf); return mSub; } diff --git a/apps/aqhome-cgi/modules/static/en/header.html b/apps/aqhome-cgi/modules/static/en/header.html index be438c3..2eec303 100644 --- a/apps/aqhome-cgi/modules/static/en/header.html +++ b/apps/aqhome-cgi/modules/static/en/header.html @@ -10,6 +10,7 @@ + AqHome