343 lines
7.8 KiB
C
343 lines
7.8 KiB
C
/****************************************************************************
|
|
* 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 <config.h>
|
|
#endif
|
|
|
|
|
|
#include "./mservice_p.h"
|
|
|
|
#include "aqhome-cgi/service/module.h"
|
|
|
|
#include <gwenhywfar/debug.h>
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* defs and enums
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
#define AQH_MOD_SERVICE_HEADERFILE "header.html"
|
|
#define AQH_MOD_SERVICE_FOOTERFILE "footer.html"
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* global vars
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
GWEN_INHERIT(AQH_MODULE, AQH_MOD_SERVICE)
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* forward declarations
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
static void GWENHYWFAR_CB _freeData(void *bp, void *p);
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* code
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
void AQH_ModService_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder)
|
|
{
|
|
AQH_MOD_SERVICE *xm;
|
|
|
|
GWEN_NEW_OBJECT(AQH_MOD_SERVICE, xm);
|
|
GWEN_INHERIT_SETDATA(AQH_MODULE, AQH_MOD_SERVICE, m, xm, _freeData);
|
|
|
|
xm->service=sv;
|
|
xm->baseFolder=(baseFolder && *baseFolder)?strdup(baseFolder):NULL;
|
|
}
|
|
|
|
|
|
|
|
void _freeData(GWEN_UNUSED void *bp, void *p)
|
|
{
|
|
AQH_MOD_SERVICE *xm;
|
|
|
|
xm=(AQH_MOD_SERVICE*) p;
|
|
free(xm->baseFolder);
|
|
GWEN_FREE_OBJECT(xm);
|
|
}
|
|
|
|
|
|
|
|
AQH_SERVICE *AQH_ModService_GetService(const AQH_MODULE *m)
|
|
{
|
|
if (m) {
|
|
AQH_MOD_SERVICE *xm;
|
|
|
|
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m);
|
|
if (xm) {
|
|
return xm->service;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
const char *AQH_ModService_GetBaseFolder(const AQH_MODULE *m)
|
|
{
|
|
if (m) {
|
|
AQH_MOD_SERVICE *xm;
|
|
|
|
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m);
|
|
if (xm) {
|
|
return xm->baseFolder;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
void AQH_ModService_SetHandleRequestFn(AQH_MODULE *m, AQH_MODSERVICE_HANDLEREQUEST_FN fn)
|
|
{
|
|
if (m) {
|
|
AQH_MOD_SERVICE *xm;
|
|
|
|
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m);
|
|
if (xm) {
|
|
xm->handleRequestFn=fn;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void AQH_ModService_SetLoadSubModuleFn(AQH_MODULE *m, AQH_MODSERVICE_LOADSUBMODULE_FN fn)
|
|
{
|
|
if (m) {
|
|
AQH_MOD_SERVICE *xm;
|
|
|
|
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m);
|
|
if (xm) {
|
|
xm->loadSubModuleFn=fn;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void AQH_ModService_SetAddHeaderFn(AQH_MODULE *m, AQH_MODSERVICE_ADDHEADER_FN fn)
|
|
{
|
|
if (m) {
|
|
AQH_MOD_SERVICE *xm;
|
|
|
|
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m);
|
|
if (xm) {
|
|
xm->addHeaderFn=fn;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void AQH_ModService_SetAddFooterFn(AQH_MODULE *m, AQH_MODSERVICE_ADDFOOTER_FN fn)
|
|
{
|
|
if (m) {
|
|
AQH_MOD_SERVICE *xm;
|
|
|
|
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m);
|
|
if (xm) {
|
|
xm->addFooterFn=fn;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void AQH_ModService_AddHeader(AQH_MODULE *m, const char *lang, GWEN_BUFFER *dbuf)
|
|
{
|
|
if (m && dbuf) {
|
|
AQH_MOD_SERVICE *xm;
|
|
|
|
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m);
|
|
if (xm) {
|
|
if (xm->addHeaderFn)
|
|
xm->addHeaderFn(m, lang, dbuf);
|
|
else {
|
|
AQH_MODULE *mParent;
|
|
|
|
mParent=AQH_Module_Tree2_GetParent(m);
|
|
if (mParent)
|
|
AQH_ModService_AddHeader(mParent, lang, dbuf);
|
|
AQH_ModService_ReadStaticFile(m, lang, AQH_MOD_SERVICE_HEADERFILE, dbuf);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void AQH_ModService_AddFooter(AQH_MODULE *m, const char *lang, GWEN_BUFFER *dbuf)
|
|
{
|
|
if (m && dbuf) {
|
|
AQH_MOD_SERVICE *xm;
|
|
|
|
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m);
|
|
if (xm) {
|
|
if (xm->addFooterFn)
|
|
xm->addFooterFn(m, lang, dbuf);
|
|
else {
|
|
AQH_MODULE *mParent;
|
|
|
|
AQH_ModService_ReadStaticFile(m, lang, AQH_MOD_SERVICE_FOOTERFILE, dbuf);
|
|
|
|
mParent=AQH_Module_Tree2_GetParent(m);
|
|
if (mParent)
|
|
AQH_ModService_AddFooter(mParent, lang, dbuf);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int AQH_ModService_RespondWithFile(AQH_MODULE *m, AQCGI_REQUEST *rq, const char *lang, const char *sFilename)
|
|
{
|
|
GWEN_BUFFER *buf;
|
|
int rv;
|
|
|
|
buf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
AQH_ModService_AddHeader(m, lang, buf);
|
|
rv=AQH_ModService_ReadStaticFile(m, lang, sFilename, buf);
|
|
if (rv<0) {
|
|
AQCGI_SendResponseWithStatus(rq, 500, "Internal error");
|
|
GWEN_Buffer_free(buf);
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
AQH_ModService_AddFooter(m, lang, buf);
|
|
AQCGI_Request_SetBufferResponseBody(rq, buf);
|
|
AQCGI_Request_AddResponseHeaderData(rq, "Content-type: text/html");
|
|
AQCGI_SendResponseWithStatus(rq, 200, "Ok");
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
int AQH_ModService_HandleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem)
|
|
{
|
|
if (m) {
|
|
AQH_MOD_SERVICE *xm;
|
|
|
|
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m);
|
|
if (xm && xm->handleRequestFn)
|
|
return xm->handleRequestFn(m, rq, session, sLastPathElem);
|
|
}
|
|
return GWEN_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
|
|
|
|
AQH_MODULE *AQH_ModService_LoadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName)
|
|
{
|
|
if (m) {
|
|
AQH_MOD_SERVICE *xm;
|
|
|
|
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m);
|
|
if (xm && xm->loadSubModuleFn)
|
|
return xm->loadSubModuleFn(m, rq, session, sModuleName);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
int AQH_ModService_ReadStaticFile(AQH_MODULE *m, const char *lang, const char *filename, GWEN_BUFFER *dbuf)
|
|
{
|
|
if (m && filename && dbuf) {
|
|
AQH_MOD_SERVICE *xm;
|
|
|
|
xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m);
|
|
if (xm) {
|
|
GWEN_BUFFER *fbuf;
|
|
int rv;
|
|
|
|
fbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
GWEN_Buffer_AppendString(fbuf, xm->baseFolder);
|
|
GWEN_Buffer_AppendString(fbuf, GWEN_DIR_SEPARATOR_S);
|
|
GWEN_Buffer_AppendString(fbuf, (lang && *lang)?lang:"en");
|
|
GWEN_Buffer_AppendString(fbuf, GWEN_DIR_SEPARATOR_S);
|
|
GWEN_Buffer_AppendString(fbuf, filename);
|
|
DBG_ERROR(NULL, "Reading file \"%s\"", GWEN_Buffer_GetStart(fbuf));
|
|
rv=GWEN_SyncIo_Helper_ReadFile(GWEN_Buffer_GetStart(fbuf), dbuf);
|
|
if (rv<0) {
|
|
DBG_ERROR(NULL, "Read(%s): %d", GWEN_Buffer_GetStart(fbuf), rv);
|
|
GWEN_Buffer_free(fbuf);
|
|
return rv;
|
|
}
|
|
GWEN_Buffer_free(fbuf);
|
|
return 0;
|
|
}
|
|
}
|
|
DBG_ERROR(NULL, "Any arg is missing (or is not a AQH_MOD_SERVICE object)");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
|
|
|
|
|
|
AQH_SESSION *AQH_ModService_ReadSession(AQH_MODULE *m, AQCGI_REQUEST *rq)
|
|
{
|
|
AQH_SERVICE *sv;
|
|
GWEN_DB_NODE *db;
|
|
const char *s;
|
|
|
|
sv=AQH_ModService_GetService(m);
|
|
db=AQCGI_Request_GetDbRequestHeader(rq);
|
|
s=GWEN_DB_GetCharValue(db, "cookies/session", 0, NULL);
|
|
if (s && *s) {
|
|
AQH_SESSION *session;
|
|
|
|
session=AQH_Service_LoadSession(sv, s);
|
|
if (session==NULL) {
|
|
DBG_ERROR(NULL, "Session \"%s\" not found", s);
|
|
return NULL;
|
|
}
|
|
else {
|
|
const char *sUserName;
|
|
|
|
sUserName=AQH_Session_GetUserAlias(session);
|
|
if (sUserName && *sUserName) {
|
|
AQH_USER *user;
|
|
|
|
user=AQH_Service_LoadUser(sv, sUserName);
|
|
if (user==NULL) {
|
|
DBG_ERROR(NULL, "User \"%s\" not found", sUserName);
|
|
AQH_Session_free(session);
|
|
return NULL;
|
|
}
|
|
AQH_Session_SetUser(session, user);
|
|
}
|
|
return session;
|
|
}
|
|
}
|
|
else {
|
|
DBG_ERROR(NULL, "No session cookie");
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|