diff options
-rw-r--r-- | docs/Changes | 2 | ||||
-rw-r--r-- | docs/TODO | 9 | ||||
-rw-r--r-- | modules/core/cs_access.cpp | 25 | ||||
-rw-r--r-- | modules/core/cs_xop.cpp | 21 | ||||
-rw-r--r-- | src/language.cpp | 2 |
5 files changed, 41 insertions, 18 deletions
diff --git a/docs/Changes b/docs/Changes index 04976cfd5..6df1c7ecb 100644 --- a/docs/Changes +++ b/docs/Changes @@ -1,6 +1,8 @@ Anope Version 1.9.4 -------------------- A Automatically set channel founder to the user with the highest access if there is no successor +A /chanserv clone command to copy settings from one channel to another. +A Ability for users to delete their own access in channels F Changed the GHOST command to not allow ghosting unidentified users if the RECOVER command exists Anope Version 1.9.3 @@ -6,12 +6,13 @@ Legend: 1.9.4 ----- [x] MS IGNORE. Make it take nick (accounts) or n!u@h masks. Fake success of memo send still, but send to opers? +[x] Allow users to delete their own access +[x] ChanServ CLONE command +[x] XMLRPC to execute commands and get data from Anope Future ------ -[?] Remote identification [+] Method to store listmodes (more generically than AKICK, too) for e.g. +beI and extbans, etc. -[ ] XMLRPC to execute commands and get data from Anope [ ] NS IDENTIFY changes [?] Last failed identify? Maybe more useful for sopers only, so users don't get unnecessarily worried [?] Last successful login time/ip? perhaps both of these should be a new nick setting @@ -19,7 +20,7 @@ Future [ ] NS SUSPEND: show suspender and reason, probably to sopers only (see CS SUSPEND) [ ] Allow channel founders to change the fantasy trigger for their channel. [ ] CIDR Akills, session exceptions, etc -[ ] Language charset stuff, including collation (1.9.1? phoenix?) +[?] Language charset stuff, including collation (1.9.1? phoenix?) [ ] fantasy: allow replies/notifications to fantasy commands to go to the channel via notice [?] a way for a module to queue itself (or even another module) for unloading [ ] Useful/common "third party" modules to core distro @@ -31,7 +32,7 @@ Future [x] Setter [x] Time added [+] Time modified (can they be modified?) - [ ] Time until expiry/expiry time (YES, time until expiry *instead of* expiry time, more human) + [x] Time until expiry/expiry time (YES, time until expiry *instead of* expiry time, more human) [x] Reason [ ] Unique IDs on each AKILL/blah so that networks may use them as ticket IDs [ ] HS ACTIVATE -ALL (rob sez this all needs reviewing) diff --git a/modules/core/cs_access.cpp b/modules/core/cs_access.cpp index 9f77baead..3ca0e59f6 100644 --- a/modules/core/cs_access.cpp +++ b/modules/core/cs_access.cpp @@ -270,12 +270,12 @@ class CommandCSAccess : public Command if (i == end) u->SendMessage(ChanServ, CHAN_ACCESS_NOT_FOUND, nick.c_str(), ci->name.c_str()); - else if (get_access(u, ci) <= access->level && !u->Account()->HasPriv("chanserv/access/modify")) + else if (nc != u->Account() && check_access(u, ci, CA_NOJOIN) && check_access(u, ci, CA_AUTODEOP) && get_access(u, ci) <= access->level && !u->Account()->HasPriv("chanserv/access/modify")) u->SendMessage(ChanServ, ACCESS_DENIED); else { u->SendMessage(ChanServ, CHAN_ACCESS_DELETED, access->nc->display.c_str(), ci->name.c_str()); - bool override = !check_access(u, ci, CA_ACCESS_CHANGE); + bool override = !check_access(u, ci, CA_ACCESS_CHANGE) && nc != u->Account(); Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << na->nick << " (group: " << access->nc->display << ") from level " << access->level; FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, na->nc)); @@ -402,13 +402,28 @@ class CommandCSAccess : public Command bool is_list = cmd.equals_ci("LIST") || cmd.equals_ci("VIEW"); bool is_clear = cmd.equals_ci("CLEAR"); + bool is_del = cmd.equals_ci("DEL"); + + bool has_access = false; + if (is_list && check_access(u, ci, CA_ACCESS_LIST)) + has_access = true; + else if (check_access(u, ci, CA_ACCESS_CHANGE)) + has_access = true; + else if (is_del) + { + NickAlias *na = findnick(nick); + if (na && na->nc == u->Account()) + has_access = true; + } /* If LIST, we don't *require* any parameters, but we can take any. * If DEL, we require a nick and no level. * Else (ADD), we require a level (which implies a nick). */ if (is_list || is_clear ? 0 : (cmd.equals_ci("DEL") ? (nick.empty() || !s.empty()) : s.empty())) this->OnSyntaxError(u, cmd); - /* We still allow LIST in xOP mode, but not others */ + else if (!has_access) + u->SendMessage(ChanServ, ACCESS_DENIED); + /* We still allow LIST and CLEAR in xOP mode, but not others */ else if (ci->HasFlag(CI_XOP) && !is_list && !is_clear) { if (ModeManager::FindChannelModeByName(CMODE_HALFOP)) @@ -416,9 +431,7 @@ class CommandCSAccess : public Command else u->SendMessage(ChanServ, CHAN_ACCESS_XOP, Config->s_ChanServ.c_str()); } - else if ((is_list && !check_access(u, ci, CA_ACCESS_LIST) && !u->Account()->HasCommand("chanserv/access/list")) || (!is_list && !check_access(u, ci, CA_ACCESS_CHANGE) && !u->Account()->HasPriv("chanserv/access/modify"))) - u->SendMessage(ChanServ, ACCESS_DENIED); - else if (readonly && (cmd.equals_ci("ADD") || cmd.equals_ci("DEL") || cmd.equals_ci("CLEAR"))) + else if (readonly && !is_list) u->SendMessage(ChanServ, CHAN_ACCESS_DISABLED); else if (cmd.equals_ci("ADD")) this->DoAdd(u, ci, params); diff --git a/modules/core/cs_xop.cpp b/modules/core/cs_xop.cpp index 4dbd09525..a37ccaf4c 100644 --- a/modules/core/cs_xop.cpp +++ b/modules/core/cs_xop.cpp @@ -305,9 +305,20 @@ class XOPBase : public Command return MOD_CONT; } + NickAlias *na = NULL; + if (!isdigit(nick[0])) + { + na = findnick(nick); + if (!na) + { + u->SendMessage(ChanServ, NICK_X_NOT_REGISTERED, nick.c_str()); + return MOD_CONT; + } + } + short ulev = get_access(u, ci); - if ((level >= ulev || ulev < ACCESS_AOP) && !u->Account()->HasPriv("chanserv/access/modify")) + if ((!na || na->nc != u->Account()) && (level >= ulev || ulev < ACCESS_AOP) && !u->Account()->HasPriv("chanserv/access/modify")) { u->SendMessage(ChanServ, ACCESS_DENIED); return MOD_CONT; @@ -322,12 +333,6 @@ class XOPBase : public Command } else { - NickAlias *na = findnick(nick); - if (!na) - { - u->SendMessage(ChanServ, NICK_X_NOT_REGISTERED, nick.c_str()); - return MOD_CONT; - } NickCore *nc = na->nc; unsigned i, end; for (i = 0, end = ci->GetAccessCount(); i < end; ++i) @@ -344,7 +349,7 @@ class XOPBase : public Command return MOD_CONT; } - if (ulev <= access->level && !u->Account()->HasPriv("chanserv/access/modify")) + if (nc != u->Account() && ulev <= access->level && !u->Account()->HasPriv("chanserv/access/modify")) u->SendMessage(ChanServ, ACCESS_DENIED); else { diff --git a/src/language.cpp b/src/language.cpp index 4a89ac626..c136b02fe 100644 --- a/src/language.cpp +++ b/src/language.cpp @@ -3865,6 +3865,8 @@ const char *const language_strings[LANG_STRING_COUNT] = { "The ACCESS DEL command removes the given nick from the\n" "access list. If a list of entry numbers is given, those\n" "entries are deleted. (See the example for LIST below.)\n" + "You may remove yourself from an access list, even if you\n" + "do not have access to modify that list otherwise.\n" " \n" "The ACCESS LIST command displays the access list. If\n" "a wildcard mask is given, only those entries matching the\n" |