summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2011-08-01 22:37:27 -0400
committerAdam <Adam@anope.org>2011-08-01 22:37:27 -0400
commitf7adc0b35b50f06706872a161f1c7476e6e6981e (patch)
tree91fbe281f2772136a327fd4fc4c64740d1ab65ab
parent710c02f3bd3581b7c5b3d48e7604756975219fc8 (diff)
Rewrote the access systems and added a flags access system
-rw-r--r--data/commands.example.conf7
-rw-r--r--data/example.conf98
-rw-r--r--data/mysql/tables.sql6
-rw-r--r--include/access.h91
-rw-r--r--include/extern.h10
-rw-r--r--include/modules.h20
-rw-r--r--include/regchannel.h69
-rw-r--r--include/services.h82
-rw-r--r--modules/core/bs_assign.cpp8
-rw-r--r--modules/core/bs_badwords.cpp12
-rw-r--r--modules/core/bs_control.cpp4
-rw-r--r--modules/core/bs_info.cpp2
-rw-r--r--modules/core/bs_kick.cpp8
-rw-r--r--modules/core/bs_main.cpp4
-rw-r--r--modules/core/bs_set.cpp4
-rw-r--r--modules/core/cs_access.cpp408
-rw-r--r--modules/core/cs_akick.cpp31
-rw-r--r--modules/core/cs_ban.cpp9
-rw-r--r--modules/core/cs_clearusers.cpp5
-rw-r--r--modules/core/cs_clone.cpp6
-rw-r--r--modules/core/cs_drop.cpp4
-rw-r--r--modules/core/cs_flags.cpp455
-rw-r--r--modules/core/cs_getkey.cpp4
-rw-r--r--modules/core/cs_info.cpp3
-rw-r--r--modules/core/cs_invite.cpp2
-rw-r--r--modules/core/cs_kick.cpp9
-rw-r--r--modules/core/cs_main.cpp23
-rw-r--r--modules/core/cs_mode.cpp25
-rw-r--r--modules/core/cs_modes.cpp58
-rw-r--r--modules/core/cs_saset_noexpire.cpp2
-rw-r--r--modules/core/cs_set_bantype.cpp2
-rw-r--r--modules/core/cs_set_description.cpp2
-rw-r--r--modules/core/cs_set_founder.cpp4
-rw-r--r--modules/core/cs_set_keeptopic.cpp2
-rw-r--r--modules/core/cs_set_opnotice.cpp2
-rw-r--r--modules/core/cs_set_peace.cpp2
-rw-r--r--modules/core/cs_set_persist.cpp2
-rw-r--r--modules/core/cs_set_private.cpp2
-rw-r--r--modules/core/cs_set_restricted.cpp6
-rw-r--r--modules/core/cs_set_secure.cpp2
-rw-r--r--modules/core/cs_set_securefounder.cpp2
-rw-r--r--modules/core/cs_set_secureops.cpp2
-rw-r--r--modules/core/cs_set_signkick.cpp2
-rw-r--r--modules/core/cs_set_successor.cpp4
-rw-r--r--modules/core/cs_set_topiclock.cpp2
-rw-r--r--modules/core/cs_set_xop.cpp146
-rw-r--r--modules/core/cs_status.cpp75
-rw-r--r--modules/core/cs_topic.cpp4
-rw-r--r--modules/core/cs_unban.cpp2
-rw-r--r--modules/core/cs_xop.cpp417
-rw-r--r--modules/core/db_mysql.cpp51
-rw-r--r--modules/core/db_plain.cpp102
-rw-r--r--modules/core/ms_del.cpp2
-rw-r--r--modules/core/ms_ignore.cpp2
-rw-r--r--modules/core/ms_info.cpp2
-rw-r--r--modules/core/ms_list.cpp2
-rw-r--r--modules/core/ms_main.cpp4
-rw-r--r--modules/core/ms_read.cpp2
-rw-r--r--modules/core/ms_set.cpp2
-rw-r--r--modules/core/ns_ajoin.cpp4
-rw-r--r--modules/core/ns_alist.cpp123
-rw-r--r--modules/extra/cs_appendtopic.cpp4
-rw-r--r--modules/extra/cs_enforce.cpp7
-rw-r--r--modules/extra/cs_tban.cpp2
-rw-r--r--modules/extra/m_helpchan.cpp2
-rw-r--r--modules/extra/m_statusupdate.cpp52
-rw-r--r--src/access.cpp140
-rw-r--r--src/botserv.cpp14
-rw-r--r--src/channels.cpp38
-rw-r--r--src/chanserv.cpp189
-rw-r--r--src/config.cpp2
-rw-r--r--src/regchannel.cpp195
72 files changed, 1773 insertions, 1319 deletions
diff --git a/data/commands.example.conf b/data/commands.example.conf
index 0fd81e49c..ff7cbb581 100644
--- a/data/commands.example.conf
+++ b/data/commands.example.conf
@@ -50,6 +50,8 @@ module { name = "cs_clone" }
command { service = "ChanServ"; name = "CLONE"; command = "chanserv/clone"; }
module { name = "cs_drop" }
command { service = "ChanServ"; name = "DROP"; command = "chanserv/drop"; }
+module { name = "cs_flags" }
+command { service = "ChanServ"; name = "FLAGS"; command = "chanserv/flags"; }
module { name = "cs_getkey" }
command { service = "ChanServ"; name = "GETKEY"; command = "chanserv/getkey"; }
module { name = "cs_info" }
@@ -127,13 +129,8 @@ command { service = "ChanServ"; name = "SASET SUCCESSOR"; command = "chanserv/sa
module { name = "cs_set_topiclock" }
command { service = "ChanServ"; name = "SET TOPICLOCK"; command = "chanserv/set/topiclock"; }
command { service = "ChanServ"; name = "SASET TOPICLOCK"; command = "chanserv/saset/topiclock"; }
-module { name = "cs_set_xop" }
-command { service = "ChanServ"; name = "SET XOP"; command = "chanserv/set/xop"; }
-command { service = "ChanServ"; name = "SASET XOP"; command = "chanserv/saset/xop"; }
module { name = "cs_saset_noexpire" }
command { service = "ChanServ"; name = "SASET NOEXPIRE"; command = "chanserv/saset/noexpire"; }
-module { name = "cs_status" }
-command { service = "ChanServ"; name = "STATUS"; command = "chanserv/status"; }
module { name = "cs_suspend" }
command { service = "ChanServ"; name = "SUSPEND"; command = "chanserv/suspend"; }
command { service = "ChanServ"; name = "UNSUSPEND"; command = "chanserv/unsuspend"; }
diff --git a/data/example.conf b/data/example.conf
index 3479db966..22a5ee201 100644
--- a/data/example.conf
+++ b/data/example.conf
@@ -439,7 +439,7 @@ options
/*
* Modes that will not be allowed to be locked. Oper only modes such as +O
* are always restricted from regular users and are not affected by this.
- * Leave blank for no restrictions.
+ * Comment out for no restrictions.
*/
nomlock = "z"
@@ -646,14 +646,13 @@ chanserv
* - signkicklevel: Same as above, but the kick will not be signed if the user is at the same access
* level or superior to the target
* - topiclock: Disallow the topic to be changed except with ChanServ's TOPIC command
- * - xop: Enable use of the xOP system
* - persist: Keep the channel open at all times
* - none: No defaults
*
* This directive is optional, if left blank, the options will default to keetopic, secure, securefounder,
* and signkick. If you really want no defaults, use "none" by itself as the option.
*/
- defaults="keeptopic peace secure securefounder signkick xop"
+ defaults="keeptopic peace secure securefounder signkick"
/*
* The maximum number of channels which may be registered to a single nickname.
@@ -738,6 +737,95 @@ chanserv
* This directive is optional.
*/
#opersonly = yes
+
+ /*
+ * ChanServ levels configuration, for use with cs_access.
+ *
+ * These levels are used by the chanserv/access access system.
+ * The levels configured below will be used as a default by newly registered channels.
+ *
+ * The level "founder" is a special level that means anyone with the level_founder permission
+ * can use (which of course defaults to "founder"). Anyone with the founder level permission in
+ * a channel can do anything in the channel.
+ */
+ level_change = 10
+ level_list = 1
+ level_akick = 10
+ level_assign = "founder"
+ level_autohalfop = 4
+ level_autoop = 5
+ level_autoowner = 9999
+ level_autoprotect = 10
+ level_autovoice = 3
+ level_badwords = 10
+ level_ban = 4
+ level_fantasia = 3
+ level_founder = "founder"
+ level_getkey = 5
+ level_greet = 5
+ level_halfop = 5
+ level_halfopme = 4
+ level_info = 9999
+ level_invite = 5
+ level_kick = 4
+ level_memo = 10
+ level_mode = 5
+ level_nokick = 1
+ level_opdeop = 5
+ level_opdeopme = 5
+ level_owner = "founder"
+ level_ownerme = 9999
+ level_protect = 9999
+ level_protectme = 10
+ level_say = 5
+ level_signkick = 9999
+ level_set = 9999
+ level_topic = 5
+ level_unban = 4
+ level_voice = 4
+ level_voiceme = 3
+
+ /*
+ * ChanServ flags configuration, for use with cs_flags.
+ *
+ * These flags are used by the chanserv/flags access system.
+ */
+ flag_change = "f"
+ flag_list = "l"
+ flag_akick = "K"
+ flag_assign = "s"
+ flag_autohalfop = "H"
+ flag_autoop = "O"
+ flag_autoowner = "Q"
+ flag_autoprotect = "A"
+ flag_autovoice = "V"
+ flag_badwords = "k"
+ flag_ban = "b"
+ flag_fantasia = "c"
+ flag_founder = "F"
+ flag_getkey = "G"
+ flag_greet = "g"
+ flag_halfop = "h"
+ flag_halfopme = "h"
+ flag_info = "I"
+ flag_invite = "i"
+ flag_kick = "k"
+ flag_memo = "m"
+ flag_mode = "s"
+ flag_nokick = "N"
+ flag_opdeop = "o"
+ flag_opdeopme = "o"
+ flag_owner = "q"
+ flag_ownerme = "q"
+ flag_protect = "a"
+ flag_protectme = "a"
+ flag_say = "B"
+ flag_set = "s"
+ flag_signkick = "K"
+ flag_topic = "t"
+ flag_unban = "u"
+ flag_voice = "v"
+ flag_voiceme = "v"
}
module { name = "gl_main" }
@@ -1065,7 +1153,7 @@ operserv
/*
* If set, this option will make Services send an (SVS)KILL command immediately after SNLINE ADD.
- * This eliminates the need for killingthe user after the SNLINE has been added.
+ * This eliminates the need for killing the user after the SNLINE has been added.
*
*This directive is optional.
*/
@@ -1073,7 +1161,7 @@ operserv
/*
* If set, this option will make Services send an (SVS)KILL command immediately after SQLINE ADD.
- * This eliminates the need for killingthe user after the SQLINE has been added.
+ * This eliminates the need for killing the user after the SQLINE has been added.
*
* This directive is optional.
*/
diff --git a/data/mysql/tables.sql b/data/mysql/tables.sql
index 32bfcde35..4f9665869 100644
--- a/data/mysql/tables.sql
+++ b/data/mysql/tables.sql
@@ -63,11 +63,13 @@ CREATE TABLE IF NOT EXISTS `anope_bs_info_metadata` (
--
CREATE TABLE IF NOT EXISTS `anope_cs_access` (
- `level` int(11) NOT NULL DEFAULT '0',
- `display` varchar(255) NOT NULL DEFAULT '',
+ `provider` varchar(255) NOT NULL DEFAULT '',
+ `data` varchar(255) NOT NULL DEFAULT '',
+ `mask` varchar(255) NOT NULL DEFAULT '',
`channel` varchar(255) NOT NULL DEFAULT '',
`last_seen` int(10) unsigned NOT NULL DEFAULT '0',
`creator` varchar(255) NOT NULL DEFAULT '',
+ `created` int(11) unsigned NOT NULL DEFAULT '0',
UNIQUE KEY `channel` (`channel`,`display`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
diff --git a/include/access.h b/include/access.h
new file mode 100644
index 000000000..69f8f4bc7
--- /dev/null
+++ b/include/access.h
@@ -0,0 +1,91 @@
+#ifndef ACCESS_H
+#define ACCESS_H
+
+enum ChannelAccess
+{
+ CA_ACCESS_LIST,
+ CA_NOKICK,
+ CA_FANTASIA,
+ CA_GREET,
+ CA_AUTOVOICE,
+ CA_VOICEME,
+ CA_VOICE,
+ CA_INFO,
+ CA_SAY,
+ CA_AUTOHALFOP,
+ CA_HALFOPME,
+ CA_HALFOP,
+ CA_KICK,
+ CA_SIGNKICK,
+ CA_BAN,
+ CA_TOPIC,
+ CA_MODE,
+ CA_GETKEY,
+ CA_INVITE,
+ CA_UNBAN,
+ CA_AUTOOP,
+ CA_OPDEOPME,
+ CA_OPDEOP,
+ CA_AUTOPROTECT,
+ CA_AKICK,
+ CA_BADWORDS,
+ CA_ASSIGN,
+ CA_MEMO,
+ CA_ACCESS_CHANGE,
+ CA_PROTECTME,
+ CA_PROTECT,
+ CA_SET,
+ CA_AUTOOWNER,
+ CA_OWNERME,
+ CA_OWNER,
+ CA_FOUNDER,
+ CA_SIZE
+};
+
+class ChanAccess;
+
+class AccessProvider : public Service
+{
+ public:
+ AccessProvider(Module *o, const Anope::string &n);
+ virtual ~AccessProvider();
+ virtual ChanAccess *Create() = 0;
+};
+
+class CoreExport ChanAccess
+{
+ public:
+ AccessProvider *provider;
+ ChannelInfo *ci;
+ Anope::string mask;
+ Anope::string creator;
+ time_t last_seen;
+ time_t created;
+
+ ChanAccess(AccessProvider *p);
+ virtual ~ChanAccess();
+ virtual bool Matches(User *u, NickCore *nc) = 0;
+ virtual bool HasPriv(ChannelAccess priv) = 0;
+ virtual Anope::string Serialize() = 0;
+ virtual void Unserialize(const Anope::string &data) = 0;
+
+ bool operator>(ChanAccess &other);
+ bool operator<(ChanAccess &other);
+ bool operator>=(ChanAccess &other);
+ bool operator<=(ChanAccess &other);
+};
+
+class AccessGroup : public std::vector<ChanAccess *>
+{
+ public:
+ AccessGroup();
+ bool HasPriv(ChannelAccess priv) const;
+ ChanAccess *Highest() const;
+ bool operator>(const AccessGroup &other) const;
+ bool operator<(const AccessGroup &other) const;
+ bool operator>=(const AccessGroup &other) const;
+ bool operator<=(const AccessGroup &other) const;
+};
+
+#endif
+
diff --git a/include/extern.h b/include/extern.h
index 18df923a8..0b90c6e14 100644
--- a/include/extern.h
+++ b/include/extern.h
@@ -42,8 +42,6 @@ E Channel *findchan(const Anope::string &chan);
E User *nc_on_chan(Channel *c, const NickCore *nc);
-E Anope::string get_xop_level(int level);
-
E void do_cmode(const Anope::string &source, const Anope::string &channel, const Anope::string &modes, const Anope::string &ts);
E void do_join(const Anope::string &source, const Anope::string &channels, const Anope::string &ts);
E void do_kick(const Anope::string &source, const Anope::string &channel, const Anope::string &users, const Anope::string &reason);
@@ -53,21 +51,13 @@ E void chan_set_correct_modes(User *user, Channel *c, int give_modes);
/**** chanserv.c ****/
-E LevelInfo levelinfo[];
-
-
-E void reset_levels(ChannelInfo *ci);
-
E void check_modes(Channel *c);
E ChannelInfo *cs_findchan(const Anope::string &chan);
-E int check_access(User *user, ChannelInfo *ci, int what);
E bool IsFounder(User *user, ChannelInfo *ci);
E void update_cs_lastseen(User *user, ChannelInfo *ci);
E int get_idealban(ChannelInfo *ci, User *u, Anope::string &ret);
-E int levelinfo_maxwidth;
-
/**** config.c ****/
E ConfigurationFile services_conf;
diff --git a/include/modules.h b/include/modules.h
index 28627f506..baf437ff8 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -646,13 +646,6 @@ class CoreExport Module : public Extensible
*/
virtual void OnAccessDel(ChannelInfo *ci, User *u, ChanAccess *access) { }
- /** Called when access is changed
- * @param ci The channel
- * @param u The user who changed the access
- * @param u access The access changed
- */
- virtual void OnAccessChange(ChannelInfo *ci, User *u, ChanAccess *access) { }
-
/** Called when access is added
* @param ci The channel
* @param u The user who added the access
@@ -1029,7 +1022,7 @@ enum Implementation
I_OnNickUpdate,
/* ChanServ */
- I_OnChanForbidden, I_OnChanSuspend, I_OnChanDrop, I_OnPreChanExpire, I_OnChanExpire, I_OnAccessAdd, I_OnAccessChange,
+ I_OnChanForbidden, I_OnChanSuspend, I_OnChanDrop, I_OnPreChanExpire, I_OnChanExpire, I_OnAccessAdd,
I_OnAccessDel, I_OnAccessClear, I_OnLevelChange, I_OnChanRegistered, I_OnChanUnsuspend, I_OnDelChan, I_OnChannelCreate,
I_OnChannelDelete, I_OnAkickAdd, I_OnAkickDel, I_OnCheckKick,
I_OnChanInfo, I_OnFindChan,
@@ -1241,17 +1234,6 @@ class CallBack : public Timer
}
};
-class CoreExport Service : public Base
-{
- public:
- Module *owner;
- Anope::string name;
-
- Service(Module *o, const Anope::string &n);
-
- virtual ~Service();
-};
-
template<typename T>
class service_reference : public dynamic_reference<T>
{
diff --git a/include/regchannel.h b/include/regchannel.h
index 9c3d1c9b9..0a4a7827a 100644
--- a/include/regchannel.h
+++ b/include/regchannel.h
@@ -44,8 +44,6 @@ enum ChannelInfoFlag
CI_SIGNKICK,
/* Sign kicks if level is < than the one defined by the SIGNKIGK level */
CI_SIGNKICK_LEVEL,
- /* Uses XOP */
- CI_XOP,
/* Channel is suspended */
CI_SUSPENDED,
/* Channel still exists when emptied, this can be caused by setting a perm
@@ -61,20 +59,7 @@ enum ChannelInfoFlag
const Anope::string ChannelInfoFlagStrings[] = {
"BEGIN", "KEEPTOPIC", "SECUREOPS", "PRIVATE", "TOPICLOCK", "RESTRICTED",
"PEACE", "SECURE", "NO_EXPIRE", "MEMO_HARDMAX", "OPNOTICE", "SECUREFOUNDER",
- "SIGNKICK", "SIGNKICK_LEVEL", "XOP", "SUSPENDED", "PERSIST", ""
-};
-
-class CoreExport ChanAccess
-{
- Anope::string mask; /* Mask of the access entry */
- public:
- int16 level;
- NickCore *nc; /* NC of the entry, if the entry is a valid nickcore */
- time_t last_seen;
- Anope::string creator;
-
- ChanAccess(const Anope::string &umask);
- const Anope::string &GetMask();
+ "SIGNKICK", "SIGNKICK_LEVEL", "SUSPENDED", "PERSIST", ""
};
/** Flags for auto kick
@@ -117,9 +102,9 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
{
private:
typedef std::multimap<ChannelModeName, ModeLock> ModeList;
- private:
+
NickCore *founder; /* Channel founder */
- std::vector<ChanAccess *> access; /* List of authorized users */
+ std::vector<ChanAccess *> access; /* List of authorized users */
std::vector<AutoKick *> akick; /* List of users to kickban */
std::vector<BadWord *> badwords; /* List of badwords */
ModeList mode_locks;
@@ -151,17 +136,16 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
time_t last_topic_time; /* Time */
int16 bantype;
- int16 *levels; /* Access levels for commands */
+ int16 levels[CA_SIZE];
MemoInfo memos;
Channel *c; /* Pointer to channel record (if channel is currently in use) */
/* For BotServ */
-
BotInfo *bi; /* Bot used on this channel */
Flags<BotServFlag> botflags;
- int16 *ttb; /* Times to ban for each kicker */
+ int16 ttb[TTB_SIZE]; /* Times to ban for each kicker */
int16 capsmin, capspercent; /* For CAPS kicker */
int16 floodlines, floodsecs; /* For FLOOD kicker */
@@ -183,16 +167,9 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
BotInfo *WhoSends();
/** Add an entry to the channel access list
- *
- * @param mask The mask of the access entry
- * @param level The channel access level the user has on the channel
- * @param creator The user who added the access
- * @param last_seen When the user was last seen within the channel
- * @return The new access class
- *
- * Creates a new access list entry and inserts it into the access list.
+ * @param access The entry
*/
- ChanAccess *AddAccess(const Anope::string &mask, int16 level, const Anope::string &creator, int32 last_seen = 0);
+ void AddAccess(ChanAccess *access);
/** Get an entry from the channel access list by index
*
@@ -203,36 +180,16 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
*/
ChanAccess *GetAccess(unsigned index);
- /** Get an entry from the channel access list by User
+ /** Check if a user has a privilege on a channel
*
* @param u The User to find within the access list vector
- * @param level Optional channel access level to compare the access entries to
- * @return A ChanAccess struct corresponding to the User, or NULL if not found
- *
- * Retrieves an entry from the access list that matches the given User, optionally also matching a certain level.
+ * @param priv The privilege to check for.
+ * @return true if the user has the privilege
*/
- ChanAccess *GetAccess(User *u, int16 level = 0);
+ bool HasPriv(User *u, ChannelAccess priv);
- /** Get an entry from the channel access list by NickCore
- *
- * @param u The NickCore to find within the access list vector
- * @param level Optional channel access level to compare the access entries to
- * @return A ChanAccess struct corresponding to the NickCore, or NULL if not found
- *
- * Retrieves an entry from the access list that matches the given NickCore, optionally also matching a certain level.
- */
- ChanAccess *GetAccess(NickCore *nc, int16 level = 0);
-
- /** Get an entry from the channel access list by mask
- *
- * @param u The mask to find within the access list vector
- * @param level Optional channel access level to compare the access entries to
- * @param wildcard True to match using wildcards
- * @return A ChanAccess struct corresponding to the mask, or NULL if not found
- *
- * Retrieves an entry from the access list that matches the given mask, optionally also matching a certain level.
- */
- ChanAccess *GetAccess(const Anope::string &mask, int16 level = 0, bool wildcard = true);
+ AccessGroup AccessFor(User *u);
+ AccessGroup AccessFor(NickCore *nc);
/** Get the size of the accss vector for this channel
* @return The access vector size
diff --git a/include/services.h b/include/services.h
index 556e1d715..0eeafc0e9 100644
--- a/include/services.h
+++ b/include/services.h
@@ -345,6 +345,20 @@ template<typename T, size_t Size = 32> class Flags
}
};
+class Module;
+
+class CoreExport Service : public Base
+{
+ public:
+ Module *owner;
+ Anope::string name;
+
+ Service(Module *o, const Anope::string &n);
+
+ virtual