added cmd_clvl and moved all the database request functions to DBHelper.c
authorpk910 <philipp@zoelle1.de>
Sat, 20 Aug 2011 06:12:23 +0000 (08:12 +0200)
committerpk910 <philipp@zoelle1.de>
Sat, 20 Aug 2011 06:12:23 +0000 (08:12 +0200)
13 files changed:
ChanNode.c
ChanNode.h
ChanUser.h
DBHelper.c [new file with mode: 0644]
DBHelper.h [new file with mode: 0644]
Makefile
UserNode.c
UserNode.h
bot_NeonServ.c
cmd_neonserv_adduser.c
cmd_neonserv_clvl.c [new file with mode: 0644]
cmd_neonserv_deluser.c
modcmd.c

index 482c54ce112ea463a6bf49da2cf879e285efe022..14ab084d43378595a7014712b653b8c80c739157 100644 (file)
@@ -2,7 +2,6 @@
 #include "ChanUser.h"
 #include "UserNode.h"
 #include "modcmd.h"
-#include "mysqlConn.h"
 
 static struct ChanNode **chanList;
 static int modes_with_strarg, modes_with_intarg;
@@ -375,19 +374,3 @@ void getModeString(struct ChanNode* chan, char *modesStr) {
     #undef MODE_VALUE
     #undef MODE_VALUE_INDEX
 }
-
-
-void load_channel_settings(struct ChanNode *chan) {
-    if(!(chan->flags & CHANFLAG_REQUESTED_CHANINFO)) {
-        check_mysql();
-        MYSQL_RES *res;
-        MYSQL_ROW row;
-        printf_mysql_query("SELECT `channel_id` FROM `channels` WHERE `channel_name` = '%s'", escape_string(chan->name));
-        res = mysql_use();
-        if ((row = mysql_fetch_row(res)) != NULL) {
-            chan->flags |= CHANFLAG_CHAN_REGISTERED;
-            chan->channel_id = atoi(row[0]);
-        }
-        chan->flags |= CHANFLAG_REQUESTED_CHANINFO;
-    }
-}
index 88cf2ac00a86be41606cd22596110f472fa1cdf5..c93625c3b1072b997d8a36d4fb875f841d2c785e 100644 (file)
@@ -38,6 +38,4 @@ void* getModeValue(struct ChanNode* chan, char modeChar);
 void parseModes(struct ChanNode* chan, char *modeStr, char **argv, int argc);
 void getModeString(struct ChanNode* chan, char *modesStr);
 
-void load_channel_settings(struct ChanNode *chan);
-
 #endif
\ No newline at end of file
index c12de4a362b453836060624d5a72df0708ee88cf..d803adab8a212f3859ae0b116cbd1becbc05f273 100644 (file)
@@ -5,6 +5,10 @@
 #define CHANUSERFLAG_VOICED 0x02
 
 
+#define DB_CHANUSER_SUSPENDED = 0x01
+#define DB_CHANUSER_AUTOINVITE = 0x02
+#define DB_CHANUSER_NOAUTOOP = 0x04
+
 #define CHANUSERFLAG_OPPED_OR_VOICED (CHANUSERFLAG_OPPED | CHANUSERFLAG_VOICED)
 
 struct ChanNode;
diff --git a/DBHelper.c b/DBHelper.c
new file mode 100644 (file)
index 0000000..eb89536
--- /dev/null
@@ -0,0 +1,98 @@
+
+#include "DBHelper.h"
+#include "UserNode.h"
+#include "ChanNode.h"
+#include "ChanUser.h"
+#include "mysqlConn.h"
+#include "lang.h"
+
+
+void _loadUserSettings(struct UserNode *user) {
+    check_mysql();
+    MYSQL_RES *res;
+    MYSQL_ROW row;
+    printf_mysql_query("SELECT `user_lang`, `user_reply_privmsg`, `user_god` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+    res = mysql_use();
+    if ((row = mysql_fetch_row(res)) != NULL) {
+        user->language = get_language_by_tag(row[0]);
+        if(user->language == NULL) user->language = get_default_language();
+        if(strcmp(row[1], "0"))
+            user->flags |= USERFLAG_REPLY_PRIVMSG;
+        if(strcmp(row[2], "0"))
+            user->flags |= USERFLAG_GOD_MODE;
+    } else
+        user->language = get_default_language();
+    user->flags |= USERFLAG_LOADED_SETTINGS;
+}
+
+int isGodMode(struct UserNode *user) {
+    loadUserSettings(user);
+    return (user->flags & USERFLAG_GOD_MODE);
+}
+
+int getChannelAccess(struct UserNode *user, struct ChanNode *chan, int override) {
+    if(!(user->flags & USERFLAG_ISAUTHED)) return 0;
+    loadChannelSettings(chan);
+    if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return 0;
+    MYSQL_RES *res;
+    MYSQL_ROW row;
+    check_mysql();
+    int caccess = 0;
+    printf_mysql_query("SELECT `user_id`, `user_access`, `user_god` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+    res = mysql_use();
+    if ((row = mysql_fetch_row(res)) != NULL) {
+        if(strcmp(row[2], "0") && override) 
+            caccess = atoi(row[1]);
+        printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` WHERE `chanuser_uid` = '%s' AND `chanuser_cid` = '%d'", row[0], chan->channel_id);
+        //
+        res = mysql_use();
+        if ((row = mysql_fetch_row(res)) != NULL) {
+            if(!(atoi(row[1]) & DB_CHANUSER_SUSPENDED) && atoi(row[0]) > caccess)
+                caccess = atoi(row[0]);
+        }
+        return caccess;
+    }
+    return 0;
+}
+
+int checkChannelAccess(struct UserNode *user, struct ChanNode *chan, char *channel_setting, int allow_override, int allow_501) {
+    loadChannelSettings(chan);
+    if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return 0;
+    MYSQL_RES *res;
+    MYSQL_ROW row;
+    printf_mysql_query("SELECT `%s` FROM `channels` WHERE `channel_id` = '%d'", channel_setting, chan->channel_id);
+    res = mysql_use();
+    if ((row = mysql_fetch_row(res)) == NULL) return 0;
+    int require_access = atoi(row[0]);
+    if(require_access == 0) return 1;
+    if(!(user->flags & USERFLAG_ISAUTHED)) return 0;
+    int caccess = 0;
+    printf_mysql_query("SELECT `user_id`, `user_access`, `user_god` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+    res = mysql_use();
+    if ((row = mysql_fetch_row(res)) != NULL) {
+        printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` WHERE `chanuser_uid` = '%s' AND `chanuser_cid` = '%d'", row[0], chan->channel_id);
+        res = mysql_use();
+        if ((row = mysql_fetch_row(res)) != NULL) {
+            if(!(atoi(row[1]) & DB_CHANUSER_SUSPENDED))
+                caccess = atoi(row[0]);
+        }
+    }
+    if(caccess >= require_access) return 1;
+    if(caccess == 500 && require_access == 501 && allow_501) return 1;
+    return 0;
+}
+
+void _loadChannelSettings(struct ChanNode *chan) {
+    check_mysql();
+    MYSQL_RES *res;
+    MYSQL_ROW row;
+    printf_mysql_query("SELECT `channel_id` FROM `channels` WHERE `channel_name` = '%s'", escape_string(chan->name));
+    res = mysql_use();
+    if ((row = mysql_fetch_row(res)) != NULL) {
+        chan->flags |= CHANFLAG_CHAN_REGISTERED;
+        chan->channel_id = atoi(row[0]);
+    }
+    chan->flags |= CHANFLAG_REQUESTED_CHANINFO;
+}
+
+
diff --git a/DBHelper.h b/DBHelper.h
new file mode 100644 (file)
index 0000000..a618541
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _DBHelper_h
+#define _DBHelper_h
+
+#include "main.h"
+
+void _loadUserSettings(struct UserNode* user);
+#define loadUserSettings(USER) if((USER->flags & USERFLAG_ISAUTHED) && !(USER->flags & USERFLAG_LOADED_SETTINGS)) _loadUserSettings(USER)
+int isGodMode(struct UserNode *user);
+int getChannelAccess(struct UserNode *user, struct ChanNode *chan, int override);
+int checkChannelAccess(struct UserNode *user, struct ChanNode *chan, char *channel_setting, int allow_override, int allow_501);
+void _loadChannelSettings(struct ChanNode *chan);
+#define loadChannelSettings(CHAN) if(!(CHAN->flags & CHANFLAG_REQUESTED_CHANINFO)) _loadChannelSettings(CHAN)
+
+#endif
\ No newline at end of file
index 6d4053ed82c47c0f4032921ea594a941480c9274..8d40c2b69eab568943a14d3db8ffbc693f195a7e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,6 +16,7 @@ all:
        gcc -g -O2 ${LIBS} -c lang.c -o lang.o ${CFLAGS}
        gcc -g -O2 ${LIBS} -c HandleInfoHandler.c -o HandleInfoHandler.o ${CFLAGS}
        gcc -g -O2 ${LIBS} -c tools.c -o tools.o ${CFLAGS}
+       gcc -g -O2 ${LIBS} -c DBHelper.c -o DBHelper.o ${CFLAGS}
        gcc -g -O2 ${LIBS} -c bots.c -o bots.o ${CFLAGS}
        gcc -g -O2 ${LIBS} -c bot_NeonServ.c -o bot_NeonServ.o ${CFLAGS}
 
index d85cceb9a4fc4e7ee0e86c0ecdeab18668e45d47..5b6c9c11259c79019d5e7d7a562f656be786ab33 100644 (file)
@@ -1,7 +1,5 @@
 #include "UserNode.h"
 #include "ChanUser.h"
-#include "mysqlConn.h"
-#include "lang.h"
 
 static struct UserNode **userList;
 
@@ -278,29 +276,3 @@ void clearTempUsers() {
             last_user = cuser;
     }
 }
-
-
-void load_user_settings(struct UserNode *user) {
-    if(!(user->flags & USERFLAG_ISAUTHED) || (user->flags & USERFLAG_LOADED_SETTINGS))
-        return;
-    check_mysql();
-    MYSQL_RES *res;
-    MYSQL_ROW row;
-    printf_mysql_query("SELECT `user_lang`, `user_reply_privmsg`, `user_god` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
-    res = mysql_use();
-    if ((row = mysql_fetch_row(res)) != NULL) {
-        user->language = get_language_by_tag(row[0]);
-        if(user->language == NULL) user->language = get_default_language();
-        if(strcmp(row[1], "0"))
-            user->flags |= USERFLAG_REPLY_PRIVMSG;
-        if(strcmp(row[2], "0"))
-            user->flags |= USERFLAG_GOD_MODE;
-    } else
-        user->language = get_default_language();
-    user->flags |= USERFLAG_LOADED_SETTINGS;
-}
-
-int isGodMode(struct UserNode *user) {
-    load_user_settings(user);
-    return (user->flags & USERFLAG_GOD_MODE);
-}
index 9a0c5381fe2dc0c215caad87fbefe70d7198d439..b475c754af20850128867c3bdf975c7ff910993a 100644 (file)
@@ -42,7 +42,4 @@ int renameUser(struct UserNode* user, const char *new_nick);
 void delUser(struct UserNode* user, int freeUser);
 void clearTempUsers();
 
-void load_user_settings(struct UserNode* user);
-int isGodMode(struct UserNode *user);
-
 #endif
index 5d4d9772b5fd2dd543e9c1f041b0a3e9f4eb39c8..8daa67815b17c87259e48c7c5fab6ee1c2c4d52a 100644 (file)
@@ -23,6 +23,10 @@ static const struct default_language_entry msgtab[] = {
     {"NS_ADDUSER_DONE", "Added %s to the %s user list with access %d."},
     {"NS_NOT_ON_USERLIST", "%s lacks access to \002%s\002."},
     {"NS_DELUSER_DONE", "Deleted %s (with access %d) from the %s user list."},
+    {"NS_ACCESS_OUTRANKED", "You cannot give users access greater than or equal to your own."},
+    {"NS_USER_OUTRANKED", "\002%s\002 outranks you (command has no effect)."},
+    {"NS_ACCESS_DENIED", "Access denied."},
+    {"NS_CLVL_DONE", "%s now has access \002%d\002 in %s."},
     {NULL, NULL}
 };
 
index 6d1716ee99153dc9bc64e104bd59c99bd33d8cce..f68f0418668d179721d2feb6c04a8da57fbb32b6 100644 (file)
@@ -20,12 +20,16 @@ static CMD_BIND(neonserv_cmd_adduser) {
     MYSQL_RES *res;
     MYSQL_ROW row;
     check_mysql();
-    //check acccess
+    checkChannelAccess(user, chan, "channel_canadd", 1, 0);
     caccess = atoi(argv[1]);
     if(caccess <= 0 || caccess > 500) {
         reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess);
         return;
     }
+    if(caccess >= getChannelAccess(user, chan, 1)) {
+        reply(getTextBot(), user, "NS_ACCESS_OUTRANKED");
+        return;
+    }
     //check own access
     if(argv[0][0] == '*') {
         //we've got an auth
diff --git a/cmd_neonserv_clvl.c b/cmd_neonserv_clvl.c
new file mode 100644 (file)
index 0000000..386a73b
--- /dev/null
@@ -0,0 +1,101 @@
+
+/*
+* argv[0] - nick / *auth
+* argv[1] - access
+*/
+static USERAUTH_CALLBACK(neonserv_cmd_clvl_nick_lookup);
+static void neonserv_cmd_clvl_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nick, char *auth, int caccess);
+
+struct neonserv_cmd_clvl_cache {
+    struct ClientSocket *client, *textclient;
+    struct UserNode *user;
+    struct ChanNode *chan;
+    char *nick;
+    int access;
+};
+
+static CMD_BIND(neonserv_cmd_clvl) {
+    int caccess;
+    MYSQL_RES *res;
+    MYSQL_ROW row;
+    check_mysql();
+    checkChannelAccess(user, chan, "channel_canclvl", 1, 0);
+    caccess = atoi(argv[1]);
+    if(caccess <= 0 || caccess > 500) {
+        reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess);
+        return;
+    }
+    if(caccess >= getChannelAccess(user, chan, 1)) {
+        reply(getTextBot(), user, "NS_ACCESS_OUTRANKED");
+        return;
+    }
+    if(argv[0][0] == '*') {
+        //we've got an auth
+        argv[0]++;
+        neonserv_cmd_clvl_async1(client, getTextBot(), user, chan, argv[0], argv[0], caccess);
+    } else {
+        struct UserNode *cuser = getUserByNick(argv[0]);
+        if(!cuser) {
+            cuser = createTempUser(argv[0]);
+            cuser->flags |= USERFLAG_ISTMPUSER;
+        }
+        if(cuser->flags & USERFLAG_ISAUTHED) {
+            neonserv_cmd_clvl_async1(client, getTextBot(), user, chan, argv[0], cuser->auth, caccess);
+        } else {
+            struct neonserv_cmd_clvl_cache *cache = malloc(sizeof(*cache));
+            if (!cache) {
+                perror("malloc() failed");
+                return;
+            }
+            cache->client = client;
+            cache->textclient = getTextBot();
+            cache->user = user;
+            cache->chan = chan;
+            cache->nick = strdup(argv[0]);
+            cache->access = caccess;
+            get_userauth(cuser, neonserv_cmd_clvl_nick_lookup, cache);
+        }
+    }
+}
+
+static USERAUTH_CALLBACK(neonserv_cmd_clvl_nick_lookup) {
+    struct neonserv_cmd_clvl_cache *cache = data;
+    if(!user) {
+        //USER_DOES_NOT_EXIST
+        reply(cache->textclient, cache->user, "NS_USER_UNKNOWN", cache->nick);
+    }
+    else if(!(user->flags & USERFLAG_ISAUTHED)) {
+        //USER_NOT_AUTHED
+        reply(cache->textclient, cache->user, "NS_USER_NEED_AUTH", cache->nick);
+    }
+    else
+        neonserv_cmd_clvl_async1(cache->client, cache->textclient, cache->user, cache->chan, user->nick, user->auth, cache->access);
+    free(cache->nick);
+    free(cache);
+}
+
+static void neonserv_cmd_clvl_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nick, char *auth, int caccess) {
+    //we've got a valid auth now...
+    MYSQL_RES *res;
+    MYSQL_ROW row;
+    int userid;
+    printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(auth));
+    res = mysql_use();
+    if ((row = mysql_fetch_row(res)) != NULL) {
+        userid = atoi(row[0]);
+        //check if the user is already added
+        printf_mysql_query("SELECT `chanuser_access`, `chanuser_id` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
+        res = mysql_use();
+        if ((row = mysql_fetch_row(res)) != NULL) {
+            //clvl
+            if(atoi(row[0]) >= getChannelAccess(user, chan, 1)) {
+                reply(cache->textclient, cache->user, "NS_USER_OUTRANKED", nick);
+                return;
+            }
+            printf_mysql_query("UPDATE `chanusers` SET `chanuser_access` = '%d' WHERE `chanuser_id` = '%s'", caccess, row[1]);
+            reply(textclient, user, "NS_CLVL_DONE", nick, caccess, chan->name);
+            return;
+        }
+    }
+    reply(textclient, user, "NS_NOT_ON_USERLIST", nick, chan->name);
+}
index b98e7f32dc2b8bca25c10d2eb72eb76aedcae1d5..acd271790c407f2f5a7707eda83fc08e0e34e869 100644 (file)
@@ -2,7 +2,6 @@
 /*
 * argv[0] - nick / *auth
 */
-static AUTHLOOKUP_CALLBACK(neonserv_cmd_deluser_auth_lookup);
 static USERAUTH_CALLBACK(neonserv_cmd_deluser_nick_lookup);
 static void neonserv_cmd_deluser_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nick, char *auth);
 
@@ -18,28 +17,11 @@ static CMD_BIND(neonserv_cmd_deluser) {
     MYSQL_RES *res;
     MYSQL_ROW row;
     check_mysql();
+    checkChannelAccess(user, chan, "channel_candel", 1, 0);
     if(argv[0][0] == '*') {
         //we've got an auth
         argv[0]++;
-        printf_mysql_query("SELECT `user_user` FROM `users` WHERE `user_user` = '%s'", escape_string(argv[0]));
-        res = mysql_use();
-        if ((row = mysql_fetch_row(res)) != NULL) {
-            neonserv_cmd_deluser_async1(client, getTextBot(), user, chan, argv[0], row[0]);
-        } else {
-            //we need to create a new user...
-            //but first lookup the auth to check if it really exists
-            struct neonserv_cmd_deluser_cache *cache = malloc(sizeof(*cache));
-            if (!cache) {
-                perror("malloc() failed");
-                return;
-            }
-            cache->client = client;
-            cache->textclient = getTextBot();
-            cache->user = user;
-            cache->chan = chan;
-            cache->nick = strdup(argv[0]);
-            lookup_authname(argv[0], neonserv_cmd_deluser_auth_lookup, cache);
-        }
+        neonserv_cmd_deluser_async1(client, getTextBot(), user, chan, argv[0], argv[0]);
     } else {
         struct UserNode *cuser = getUserByNick(argv[0]);
         if(!cuser) {
@@ -64,17 +46,6 @@ static CMD_BIND(neonserv_cmd_deluser) {
     }
 }
 
-static AUTHLOOKUP_CALLBACK(neonserv_cmd_deluser_auth_lookup) {
-    struct neonserv_cmd_deluser_cache *cache = data;
-    if(!exists) {
-        //AUTH_DOES_NOT_EXIST
-        reply(cache->textclient, cache->user, "NS_AUTH_UNKNOWN", cache->nick);
-    } else
-        neonserv_cmd_deluser_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->nick, auth);
-    free(cache->nick);
-    free(cache);
-}
-
 static USERAUTH_CALLBACK(neonserv_cmd_deluser_nick_lookup) {
     struct neonserv_cmd_deluser_cache *cache = data;
     if(!user) {
@@ -104,6 +75,10 @@ static void neonserv_cmd_deluser_async1(struct ClientSocket *client, struct Clie
         printf_mysql_query("SELECT `chanuser_access`, `chanuser_id` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
         res = mysql_use();
         if ((row = mysql_fetch_row(res)) != NULL) {
+            if(atoi(row[0]) >= getChannelAccess(user, chan, 1)) {
+                reply(textclient, cache->user, "NS_USER_OUTRANKED", nick);
+                return;
+            }
             //delete
             printf_mysql_query("DELETE FROM `chanusers` WHERE `chanuser_id` = '%s'", row[1]);
             reply(textclient, user, "NS_DELUSER_DONE", nick, atoi(row[0]), chan->name);
index 6079e3dd87d39d63afcb607177035249cfd29679..5c07fb4e4828011040b799d0ec5dd05729ec3a38 100644 (file)
--- a/modcmd.c
+++ b/modcmd.c
@@ -9,6 +9,7 @@
 #include "WHOHandler.h"
 #include "lang.h"
 #include "mysqlConn.h"
+#include "DBHelper.h"
 
 struct trigger_callback {
     int botid;
@@ -200,7 +201,7 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s
                 break;
             }
             if((cbind->func->flags & CMDFLAG_REGISTERED_CHAN)) {
-                load_channel_settings(chan);
+                loadChannelSettings(chan);
                 if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) {
                     reply(tmp_text_client, user, "MODCMD_CHAN_REQUIRED");
                     break;