From e21ad3a5aa46635db9dc30b3395aa59588074932 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Mon, 27 Jul 2020 21:22:42 +0200 Subject: server: Protocol v2, DB v2: message replies --- command.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'command.c') diff --git a/command.c b/command.c index 8fa343d..ba8727e 100644 --- a/command.c +++ b/command.c @@ -232,8 +232,18 @@ static struct cmd_retval cmd_send(struct conn_data *data,const char *tag,const c return RET_OK; } userdata_mark_active(data->userid,data->fd,true); + const char *roomname=args[0]; - const char *message=args[1]; + + i64 replyid; + if(!parse_i64(args[1],&replyid)){ + debug("Connection fd=%d sent an invalid number for 'send': '%s'", + data->fd,args[1]); + return RET_CLOSE(true); + } + + const char *message=args[2]; + if(strlen(message)>MAX_MESSAGE_LEN){ net_send_error(data->fd,tag,"Message too long"); return RET_OK; @@ -247,17 +257,22 @@ static struct cmd_retval cmd_send(struct conn_data *data,const char *tag,const c net_send_error(data->fd,tag,"Not in that room"); return RET_OK; } + if(replyid>=0&&!db_message_exists(roomid,replyid)){ + net_send_error(data->fd,tag,"Replied-to message not found"); + return RET_OK; + } i64 timestamp=make_timestamp(); - i64 msgid=db_create_message(roomid,data->userid,make_timestamp(),message); + i64 msgid=db_create_message(roomid,data->userid,make_timestamp(),replyid,message); bool closed=net_send_number(data->fd,tag,msgid); char *pushbuf=NULL; char *username=db_get_username(data->userid); - i64 pushbuflen=asprintf(&pushbuf,"_push message %s %s %" PRIi64 " %" PRIi64 " %s\n", - roomname,username,timestamp,msgid,message); + i64 pushbuflen=asprintf(&pushbuf, + "_push message %s %s %" PRIi64 " %" PRIi64 " %" PRIi64 " %s\n", + roomname,username,timestamp,msgid,replyid,message); - event_emit_message(timestamp,message,username,roomname); + event_emit_message(timestamp,message,username,roomname,replyid); firebase_send_message(roomname,roomid,username,message); free(username); @@ -317,9 +332,9 @@ static struct cmd_retval history_cmd_helper( for(i64 i=ml.count-1;i>=0;i--){ char *username=db_get_username(ml.list[i].userid); - len=asprintf(&buf,"%s history_message %" PRIi64 " %s %s %" PRIi64 " %" PRIi64 " %s\n", + len=asprintf(&buf,"%s history_message %" PRIi64 " %s %s %" PRIi64 " %" PRIi64 " %" PRIi64 " %s\n", tag,ml.count-1-i,roomname,username,ml.list[i].timestamp, - ml.list[i].msgid,ml.list[i].message); + ml.list[i].msgid,ml.list[i].replyid,ml.list[i].message); free(username); closed=net_send_raw_text(data->fd,buf,len); free(buf); @@ -421,7 +436,7 @@ static const struct cmd_info commands[COMMAND_HASH_MODULUS] = { COMMAND_ENTRY('l', "list_members", 1, false, cmd_list_members), COMMAND_ENTRY('c', "create_room", 0, false, cmd_create_room), COMMAND_ENTRY('i', "invite", 2, false, cmd_invite), - COMMAND_ENTRY('s', "send", 2, true, cmd_send), + COMMAND_ENTRY('s', "send", 3, true, cmd_send), COMMAND_ENTRY('h', "history", 2, false, cmd_history), COMMAND_ENTRY('h', "history_before", 3, false, cmd_history_before), COMMAND_ENTRY('p', "ping", 0, false, cmd_ping), -- cgit v1.2.3-70-g09d2 From 1d28744e532ac73ddff0c6fa829949497b25d4b6 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Tue, 28 Jul 2020 16:05:47 +0200 Subject: server: Implement get_message --- command.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- db.c | 37 +++++++++++++++++++++++++++++++------ db.h | 3 ++- 3 files changed, 85 insertions(+), 12 deletions(-) (limited to 'command.c') diff --git a/command.c b/command.c index ba8727e..ca70d76 100644 --- a/command.c +++ b/command.c @@ -257,9 +257,13 @@ static struct cmd_retval cmd_send(struct conn_data *data,const char *tag,const c net_send_error(data->fd,tag,"Not in that room"); return RET_OK; } - if(replyid>=0&&!db_message_exists(roomid,replyid)){ - net_send_error(data->fd,tag,"Replied-to message not found"); - return RET_OK; + if(replyid>=0){ + struct db_message msg=db_get_message(replyid); + if(msg.msgid==-1){ + net_send_error(data->fd,tag,"Replied-to message not found"); + return RET_OK; + } + db_nullify_message(msg); } i64 timestamp=make_timestamp(); @@ -361,6 +365,48 @@ static struct cmd_retval cmd_history_before(struct conn_data *data,const char *t return history_cmd_helper(data,tag,args,"history_before",beforeid); } +static struct cmd_retval cmd_get_message(struct conn_data *data, const char *tag, const char **args) { + i64 msgid; + if (!parse_i64(args[0], &msgid)) { + debug("Connection fd=%d sent an invalid number for 'get_message': '%s'", + data->fd, args[0]); + return RET_CLOSE(true); + } + + if (data->userid == -1) { + net_send_error(data->fd, tag, "Not logged in"); + return RET_OK; + } + + struct db_message msg = db_get_message(msgid); + if (msg.msgid == -1) { + net_send_error(data->fd, tag, "Message not found"); + return RET_OK; + } + + if (!db_is_member(msg.roomid, data->userid)) { + db_nullify_message(msg); + // Don't disclose that the message actually exists elsewhere + net_send_error(data->fd, tag, "Message not found"); + return RET_OK; + } + + char *roomname = db_get_roomname(msg.roomid); + char *username = db_get_username(msg.userid); + + char *buf = NULL; + i64 len = asprintf(&buf, "%s message %s %s %" PRIi64 " %" PRIi64 " %" PRIi64 " %s\n", + tag, roomname, username, msg.timestamp, msg.msgid, msg.replyid, msg.message); + free(roomname); + free(username); + + bool closed = net_send_raw_text(data->fd, buf, len); + free(buf); + + db_nullify_message(msg); + return RET_CLOSE(closed); +} + static struct cmd_retval cmd_ping(struct conn_data *data,const char *tag,const char **args){ (void)args; return RET_CLOSE(net_send_pong(data->fd,tag)); @@ -419,8 +465,8 @@ struct cmd_info{ // Use CommandHash.hs to re-generate this perfect hash function for a different // list of commands. -#define COMMAND_HASH_MODULUS 31 -#define COMMAND_HASH(cmd0, len) ((cmd0 + 6 * len) % COMMAND_HASH_MODULUS) +#define COMMAND_HASH_MODULUS 34 +#define COMMAND_HASH(cmd0, len) ((4 * cmd0 + 7 * len) % COMMAND_HASH_MODULUS) #define COMMAND_ENTRY(cmd0, cmd, nargs, longlast, handler) \ [COMMAND_HASH(cmd0, strlen(cmd))] = {cmd, nargs, longlast, handler} @@ -439,6 +485,7 @@ static const struct cmd_info commands[COMMAND_HASH_MODULUS] = { COMMAND_ENTRY('s', "send", 3, true, cmd_send), COMMAND_ENTRY('h', "history", 2, false, cmd_history), COMMAND_ENTRY('h', "history_before", 3, false, cmd_history_before), + COMMAND_ENTRY('g', "get_message", 1, false, cmd_get_message), COMMAND_ENTRY('p', "ping", 0, false, cmd_ping), COMMAND_ENTRY('i', "is_online", 1, false, cmd_is_online), COMMAND_ENTRY('f', "firebase_token", 1, false, cmd_firebase_token), diff --git a/db.c b/db.c index 416b9d3..d94b13c 100644 --- a/db.c +++ b/db.c @@ -460,16 +460,37 @@ struct db_message_list db_get_messages_before(i64 roomid,i64 count,i64 beforeid) return ml; } -bool db_message_exists(i64 roomid, i64 msgid) { +struct db_message db_get_message(i64 msgid) { sqlite3_stmt *stmt; SQLITE(prepare_v2, database, - "select id from Messages where id = ? and room = ?", + "select room, user, time, reply, message " + "from Messages where id = ?", -1, &stmt, NULL); SQLITE(bind_int64, stmt, 1, msgid); - SQLITE(bind_int64, stmt, 2, roomid); - bool success = sqlite3_step(stmt) == SQLITE_ROW; + + struct db_message msg; + if (sqlite3_step(stmt) == SQLITE_ROW) { + msg.msgid = msgid; + msg.roomid = sqlite3_column_int64(stmt,0); + msg.userid = sqlite3_column_int64(stmt,1); + msg.timestamp = sqlite3_column_int64(stmt,2); + if (sqlite3_column_type(stmt, 3) == SQLITE_INTEGER) { + msg.replyid = sqlite3_column_int64(stmt, 3); + } else { + msg.replyid = -1; // NULL, not a reply + } + msg.message = strdup((const char*)sqlite3_column_text(stmt, 4)); + } else { + msg.msgid = -1; + msg.roomid = -1; + msg.userid = -1; + msg.timestamp = -1; + msg.replyid = -1; + msg.message = NULL; + } + SQLITE(finalize, stmt); - return success; + return msg; } @@ -493,9 +514,13 @@ void db_nullify_user_list(struct db_user_list ul){ ul.list=NULL; } +void db_nullify_message(struct db_message msg){ + if(msg.message)free(msg.message); +} + void db_nullify_message_list(struct db_message_list ml){ for(i64 i=0;i