345 lines
9.5 KiB
C
345 lines
9.5 KiB
C
/****************************************************************************
|
|
* This file is part of the project AqHome.
|
|
* AqHome (c) by 2023 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 "./u_rooms.h"
|
|
#include "./aqhomehttp.h"
|
|
#include "aqhome/http/httpservice.h"
|
|
#include "aqhome/http/httpservice_http.h"
|
|
#include "aqhome/http/httpservice_conf.h"
|
|
|
|
#include <gwenhywfar/gwenhywfar.h>
|
|
#include <gwenhywfar/args.h>
|
|
#include <gwenhywfar/debug.h>
|
|
#include <gwenhywfar/endpoint.h>
|
|
#include <gwenhywfar/mdigest.h>
|
|
#include <gwenhywfar/text.h>
|
|
#include <gwenhywfar/timestamp.h>
|
|
|
|
|
|
|
|
static int _handleUrl(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
|
static int _handleGet(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
|
static int _handlePost(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
|
|
|
static void _handleGetList(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_BUFFER *pageBuf);
|
|
|
|
static void _handleGetAdd(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_BUFFER *pageBuf);
|
|
static int _handlePostAdd(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
|
static int _writeAddPage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_BUFFER *pageBuf);
|
|
|
|
|
|
|
|
|
|
AQH_HTTP_URLHANDLER *AQH_RoomsHttpUrlHandler_new(AQH_SERVICE *sv)
|
|
{
|
|
AQH_HTTP_URLHANDLER *uh;
|
|
|
|
uh=AQH_HttpUrlHandler_new(sv);
|
|
AQH_HttpUrlHandler_SetHandleFn(uh, _handleUrl);
|
|
|
|
return uh;
|
|
}
|
|
|
|
|
|
|
|
int _handleUrl(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
|
{
|
|
const char *protocol;
|
|
const char *cmd;
|
|
GWEN_MSG *msgOut=NULL;
|
|
|
|
AQH_HttpService_SetupModuleAndPerms(AQH_HttpUrlHandler_GetHttpService(uh), rq, "aqhome");
|
|
AQH_HttpRequest_SetupUrlPathMembers(rq);
|
|
|
|
protocol=AQH_HttpRequest_GetProtocol(rq);
|
|
cmd=AQH_HttpRequest_GetCommand(rq);
|
|
if (cmd && *cmd) {
|
|
int rv;
|
|
|
|
if (strcasecmp(cmd, "GET")==0) {
|
|
rv=_handleGet(uh, rq);
|
|
if (rv<0) {
|
|
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
return rv;
|
|
}
|
|
}
|
|
else if (strcasecmp(cmd, "POST")==0) {
|
|
rv=_handlePost(uh, rq);
|
|
if (rv<0) {
|
|
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
return rv;
|
|
}
|
|
}
|
|
else {
|
|
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 405, "Method not allowed", protocol, NULL);
|
|
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
}
|
|
return 0;
|
|
}
|
|
else {
|
|
DBG_ERROR(AQH_LOGDOMAIN, "No command in request");
|
|
return GWEN_ERROR_INVALID;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int _handleGet(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
|
{
|
|
GWEN_BUFFER *pageBuf;
|
|
int rv;
|
|
GWEN_MSG *msgOut=NULL;
|
|
const char *protocol;
|
|
const GWEN_STRINGLIST *sl;
|
|
|
|
protocol=AQH_HttpRequest_GetProtocol(rq);
|
|
pageBuf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
rv=AQH_HttpUrlHandler_AddContentHeaders(uh, AQH_HTTP_CONTENT_MODE_DESKTOP, pageBuf);
|
|
if (rv<0) {
|
|
DBG_ERROR(AQH_LOGDOMAIN, "Error adding headers");
|
|
GWEN_Buffer_free(pageBuf);
|
|
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
|
|
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
return 0;
|
|
}
|
|
|
|
/* handle middle part (header - middle - footer) */
|
|
sl=AQH_HttpRequest_GetUrlPathMembers(rq);
|
|
if (sl) {
|
|
const char *s;
|
|
|
|
s=GWEN_StringList_StringAt(sl, 1);
|
|
if (!(s && *s))
|
|
s="list";
|
|
|
|
if (strcasecmp(s, "list")==0)
|
|
_handleGetList(uh, rq, pageBuf);
|
|
else if (strcasecmp(s, "add")==0)
|
|
_handleGetAdd(uh, rq, pageBuf);
|
|
else {
|
|
DBG_ERROR(NULL, "Invalid url (2nd member is [%s])", s);
|
|
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
|
|
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
GWEN_Buffer_free(pageBuf);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
rv=AQH_HttpUrlHandler_AddContentFooters(uh, AQH_HTTP_CONTENT_MODE_DESKTOP, pageBuf);
|
|
if (rv<0) {
|
|
DBG_ERROR(AQH_LOGDOMAIN, "Error adding footers");
|
|
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
|
|
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
GWEN_Buffer_free(pageBuf);
|
|
return rv;
|
|
}
|
|
|
|
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 200, "OK", protocol, GWEN_Buffer_GetStart(pageBuf));
|
|
GWEN_Buffer_free(pageBuf);
|
|
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
int _handlePost(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
|
{
|
|
GWEN_DB_NODE *db;
|
|
const GWEN_STRINGLIST *sl;
|
|
const char *protocol;
|
|
GWEN_MSG *msgOut=NULL;
|
|
int rv;
|
|
|
|
DBG_ERROR(NULL, "POST:");
|
|
db=AQH_HttpRequest_GetDbPostBody(rq);
|
|
GWEN_DB_Dump(db, 2);
|
|
|
|
protocol=AQH_HttpRequest_GetProtocol(rq);
|
|
sl=AQH_HttpRequest_GetUrlPathMembers(rq);
|
|
if (sl) {
|
|
const char *s;
|
|
|
|
s=GWEN_StringList_StringAt(sl, 1);
|
|
if (s && *s) {
|
|
if (strcasecmp(s, "add")==0)
|
|
rv=_handlePostAdd(uh, rq);
|
|
else {
|
|
DBG_ERROR(NULL, "Invalid url (2nd member is [%s])", s);
|
|
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
|
|
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
return 0;
|
|
}
|
|
return rv;
|
|
}
|
|
else {
|
|
DBG_ERROR(NULL, "Invalid url (2nd member missing)");
|
|
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
|
|
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
return 0;
|
|
}
|
|
}
|
|
// TODO
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
void _handleGetList(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_BUFFER *pageBuf)
|
|
{
|
|
AQH_SERVICE *sv;
|
|
uint32_t perms;
|
|
|
|
DBG_ERROR(NULL, "LIST");
|
|
perms=AQH_HttpRequest_GetModulePerms(rq);
|
|
if (perms & AQHOME_HTTP_PERMS_LIST_ROOMS) {
|
|
AQH_STORAGE *sto;
|
|
|
|
sv=AQH_HttpUrlHandler_GetHttpService(uh);
|
|
sto=AqHomeHttpService_GetStorage(sv);
|
|
if (sto) {
|
|
const AQH_ROOM_LIST *rl;
|
|
|
|
GWEN_Buffer_AppendString(pageBuf, "<h2>Rooms</h2>");
|
|
GWEN_Buffer_AppendString(pageBuf, "<table>");
|
|
GWEN_Buffer_AppendString(pageBuf, "<tr><th>Id</th><th>Name</th><th>Description</th></tr>");
|
|
rl=AQH_Storage_GetRoomList(sto);
|
|
if (rl) {
|
|
const AQH_ROOM *r;
|
|
|
|
r=AQH_Room_List_First(rl);
|
|
while(r) {
|
|
long unsigned int id;
|
|
const char *name;
|
|
const char *descr;
|
|
|
|
id=(long unsigned int) AQH_Room_GetId(r);
|
|
name=AQH_Room_GetName(r);
|
|
descr=AQH_Room_GetDescription(r);
|
|
GWEN_Buffer_AppendArgs(pageBuf, "<tr><td>%lu</td><td>%s</td><td>%s</td></tr>", id, name?name:"", descr?descr:"");
|
|
|
|
r=AQH_Room_List_Next(r);
|
|
}
|
|
}
|
|
GWEN_Buffer_AppendString(pageBuf, "</table>");
|
|
GWEN_Buffer_AppendString(pageBuf, "<a href=\"/rooms/add\">Add Room</a><br>");
|
|
}
|
|
else {
|
|
GWEN_Buffer_AppendString(pageBuf, "<p>Internal error.</p>");
|
|
}
|
|
}
|
|
else {
|
|
GWEN_Buffer_AppendString(pageBuf, "<p>No permissions to see list of rooms.</p>");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void _handleGetAdd(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_BUFFER *pageBuf)
|
|
{
|
|
uint32_t perms;
|
|
|
|
DBG_ERROR(NULL, "ADD");
|
|
perms=AQH_HttpRequest_GetModulePerms(rq);
|
|
if (perms & AQHOME_HTTP_PERMS_ADD_ROOM) {
|
|
_writeAddPage(uh, rq, pageBuf);
|
|
}
|
|
else {
|
|
DBG_INFO(NULL, "No permissions to add a room.");
|
|
GWEN_Buffer_AppendString(pageBuf, "<p>No permissions to add a room.</p>");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int _writeAddPage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_BUFFER *pageBuf)
|
|
{
|
|
int rv;
|
|
int pos;
|
|
|
|
pos=GWEN_Buffer_GetPos(pageBuf);
|
|
rv=AQH_HttpService_AddFile(AQH_HttpUrlHandler_GetHttpService(uh), NULL, "roomadd.html", pageBuf);
|
|
if (rv<0) {
|
|
DBG_ERROR(AQH_LOGDOMAIN, "Error reading file \"roomadd.html\"");
|
|
GWEN_Buffer_Crop(pageBuf, 0, pos);
|
|
GWEN_Buffer_AppendString(pageBuf, "<p>Internal error.</p>");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
int _handlePostAdd(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
|
{
|
|
const char *protocol;
|
|
AQH_SERVICE *sv;
|
|
uint32_t perms;
|
|
GWEN_MSG *msgOut=NULL;
|
|
|
|
protocol=AQH_HttpRequest_GetProtocol(rq);
|
|
sv=AQH_HttpUrlHandler_GetHttpService(uh);
|
|
perms=AQH_HttpRequest_GetModulePerms(rq);
|
|
if (perms & AQHOME_HTTP_PERMS_ADD_ROOM) {
|
|
GWEN_DB_NODE *db;
|
|
const char *roomName;
|
|
const char *roomDescr;
|
|
AQH_STORAGE *sto;
|
|
|
|
db=AQH_HttpRequest_GetDbPostBody(rq);
|
|
|
|
roomName=GWEN_DB_GetCharValue(db, "roomname", 0, NULL);
|
|
roomDescr=GWEN_DB_GetCharValue(db, "descr", 0, NULL);
|
|
|
|
if (!(roomName && *roomName)) {
|
|
msgOut=AQH_HttpUrlHandler_CreatePageMessage(uh, rq, "red", "Missing room name", 1, _writeAddPage);
|
|
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
return 0;
|
|
}
|
|
|
|
sto=AqHomeHttpService_GetStorage(sv);
|
|
if (sto) {
|
|
AQH_ROOM *r;
|
|
|
|
r=AQH_Room_new();
|
|
AQH_Room_SetName(r, roomName);
|
|
if (roomDescr && *roomDescr)
|
|
AQH_Room_SetDescription(r, roomDescr);
|
|
if (AQH_Storage_GetRoomByName(sto, roomName)!=NULL) {
|
|
msgOut=AQH_HttpUrlHandler_CreatePageMessage(uh, rq, "red", "Room already exists", 1, _writeAddPage);
|
|
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
return 0;
|
|
}
|
|
AQH_Storage_AddRoom(sto, r);
|
|
msgOut=AQH_HttpService_CreateRedirectingResponseMsg(sv, protocol, "/rooms/list");
|
|
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
return 0;
|
|
}
|
|
else {
|
|
DBG_ERROR(NULL, "No storage");
|
|
msgOut=AQH_HttpService_CreateResponseMsg(sv, 500, "Internal error", protocol, NULL);
|
|
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
return 0;
|
|
}
|
|
}
|
|
else {
|
|
msgOut=AQH_HttpService_CreateResponseMsg(sv, 403, "Forbidden", protocol, NULL);
|
|
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|