summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/Changes2
-rw-r--r--docs/TODO9
-rw-r--r--modules/core/cs_access.cpp25
-rw-r--r--modules/core/cs_xop.cpp21
-rw-r--r--src/language.cpp2
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
diff --git a/docs/TODO b/docs/TODO
index 2b66a1fa8..94d9df7b5 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -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"