mirror of
https://github.com/anope/anope.git
synced 2026-07-08 07:25:44 +02:00
Rewrite access path system to be simplier and use recursion
Show where access is "from" in chanserv/status
This commit is contained in:
+10
-11
@@ -78,12 +78,7 @@ class CoreExport ChanAccess : public Serializable
|
||||
Serialize::Reference<NickCore> nc;
|
||||
|
||||
public:
|
||||
typedef std::multimap<const ChanAccess *, const ChanAccess *> Set;
|
||||
/* shows the 'path' taken to determine if an access entry matches a user
|
||||
* .first are access entries checked
|
||||
* .second are access entries which match
|
||||
*/
|
||||
typedef std::pair<Set, Set> Path;
|
||||
typedef std::vector<ChanAccess *> Path;
|
||||
|
||||
/* The provider that created this access entry */
|
||||
AccessProvider *provider;
|
||||
@@ -103,12 +98,14 @@ class CoreExport ChanAccess : public Serializable
|
||||
void Serialize(Serialize::Data &data) const anope_override;
|
||||
static Serializable* Unserialize(Serializable *obj, Serialize::Data &);
|
||||
|
||||
static const unsigned int MAX_DEPTH = 4;
|
||||
|
||||
/** Check if this access entry matches the given user or account
|
||||
* @param u The user
|
||||
* @param nc The account
|
||||
* @param p The path to the access object which matches will be put here
|
||||
* @param next Next channel to check if any
|
||||
*/
|
||||
virtual bool Matches(const User *u, const NickCore *nc, Path &p) const;
|
||||
virtual bool Matches(const User *u, const NickCore *nc, ChannelInfo* &next) const;
|
||||
|
||||
/** Check if this access entry has the given privilege.
|
||||
* @param name The privilege name
|
||||
@@ -136,13 +133,13 @@ class CoreExport ChanAccess : public Serializable
|
||||
/* A group of access entries. This is used commonly, for example with ChannelInfo::AccessFor,
|
||||
* to show what access a user has on a channel because users can match multiple access entries.
|
||||
*/
|
||||
class CoreExport AccessGroup : public std::vector<ChanAccess *>
|
||||
class CoreExport AccessGroup
|
||||
{
|
||||
public:
|
||||
/* access entries + paths */
|
||||
std::vector<ChanAccess::Path> paths;
|
||||
/* Channel these access entries are on */
|
||||
const ChannelInfo *ci;
|
||||
/* Path from these entries to other entries that they depend on */
|
||||
ChanAccess::Path path;
|
||||
/* Account these entries affect, if any */
|
||||
const NickCore *nc;
|
||||
/* super_admin always gets all privs. founder is a special case where ci->founder == nc */
|
||||
@@ -170,6 +167,8 @@ class CoreExport AccessGroup : public std::vector<ChanAccess *>
|
||||
bool operator<(const AccessGroup &other) const;
|
||||
bool operator>=(const AccessGroup &other) const;
|
||||
bool operator<=(const AccessGroup &other) const;
|
||||
|
||||
inline bool empty() const { return paths.empty(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -370,7 +370,7 @@ class CommandCSAccess : public Command
|
||||
if (ci->c)
|
||||
for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit)
|
||||
{
|
||||
ChanAccess::Path p;
|
||||
ChannelInfo *p;
|
||||
if (access->Matches(cit->second->user, cit->second->user->Account(), p))
|
||||
timebuf = "Now";
|
||||
}
|
||||
@@ -407,7 +407,7 @@ class CommandCSAccess : public Command
|
||||
if (ci->c)
|
||||
for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit)
|
||||
{
|
||||
ChanAccess::Path p;
|
||||
ChannelInfo *p;
|
||||
if (access->Matches(cit->second->user, cit->second->user->Account(), p))
|
||||
timebuf = "Now";
|
||||
}
|
||||
|
||||
@@ -236,9 +236,14 @@ class CommandSeen : public Command
|
||||
|
||||
AccessGroup ag = source.c->ci->AccessFor(na->nc);
|
||||
time_t last = 0;
|
||||
for (unsigned i = 0; i < ag.size(); ++i)
|
||||
for (unsigned int i = 0; i < ag.paths.size(); ++i)
|
||||
{
|
||||
ChanAccess *a = ag[i];
|
||||
ChanAccess::Path &p = ag.paths[i];
|
||||
|
||||
if (p.empty())
|
||||
continue;
|
||||
|
||||
ChanAccess *a = p[p.size() - 1];
|
||||
|
||||
if (a->GetAccount() == na->nc && a->last_seen > last)
|
||||
last = a->last_seen;
|
||||
|
||||
@@ -57,11 +57,26 @@ public:
|
||||
{
|
||||
source.Reply(_("Access for \002%s\002 on \002%s\002:"), nick.c_str(), ci->name.c_str());
|
||||
|
||||
for (unsigned i = 0; i < ag.size(); ++i)
|
||||
for (unsigned i = 0; i < ag.paths.size(); ++i)
|
||||
{
|
||||
ChanAccess *acc = ag[i];
|
||||
ChanAccess::Path &p = ag.paths[i];
|
||||
|
||||
source.Reply(_("\002%s\002 matches access entry %s, which has privilege %s."), nick.c_str(), acc->Mask().c_str(), acc->AccessSerialize().c_str());
|
||||
if (p.empty())
|
||||
continue;
|
||||
|
||||
if (p.size() == 1)
|
||||
{
|
||||
ChanAccess *acc = p[0];
|
||||
|
||||
source.Reply(_("\002%s\002 matches access entry %s, which has privilege %s."), nick.c_str(), acc->Mask().c_str(), acc->AccessSerialize().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
ChanAccess *first = p[0];
|
||||
ChanAccess *acc = p[p.size() - 1];
|
||||
|
||||
source.Reply(_("\002%s\002 matches access entry %s (from entry %s), which has privilege %s."), nick.c_str(), acc->Mask().c_str(), first->Mask().c_str(), acc->AccessSerialize().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,8 +86,17 @@ class CommandNSAList : public Command
|
||||
|
||||
entry["Number"] = stringify(chan_count);
|
||||
entry["Channel"] = (ci->HasExt("CS_NO_EXPIRE") ? "!" : "") + ci->name;
|
||||
for (unsigned j = 0; j < access.size(); ++j)
|
||||
entry["Access"] = entry["Access"] + ", " + access[j]->AccessSerialize();
|
||||
for (unsigned j = 0; j < access.paths.size(); ++j)
|
||||
{
|
||||
ChanAccess::Path &p = access.paths[i];
|
||||
|
||||
// not interested in indirect access
|
||||
if (p.size() != 1)
|
||||
continue;
|
||||
|
||||
ChanAccess *a = p[0];
|
||||
entry["Access"] = entry["Access"] + ", " + a->AccessSerialize();
|
||||
}
|
||||
entry["Access"] = entry["Access"].substr(2);
|
||||
entry["Description"] = ci->desc;
|
||||
list.AddEntry(entry);
|
||||
|
||||
@@ -23,8 +23,8 @@ class StatusUpdate : public Module
|
||||
{
|
||||
User *user = it->second->user;
|
||||
|
||||
ChanAccess::Path p;
|
||||
if (user->server != Me && access->Matches(user, user->Account(), p))
|
||||
ChannelInfo *next;
|
||||
if (user->server != Me && access->Matches(user, user->Account(), next))
|
||||
{
|
||||
AccessGroup ag = ci->AccessFor(user);
|
||||
|
||||
@@ -46,8 +46,8 @@ class StatusUpdate : public Module
|
||||
{
|
||||
User *user = it->second->user;
|
||||
|
||||
ChanAccess::Path p;
|
||||
if (user->server != Me && access->Matches(user, user->Account(), p))
|
||||
ChannelInfo *next;
|
||||
if (user->server != Me && access->Matches(user, user->Account(), next))
|
||||
{
|
||||
AccessGroup ag = ci->AccessFor(user);
|
||||
|
||||
|
||||
@@ -46,10 +46,9 @@ bool WebCPanel::NickServ::Alist::OnRequest(HTTPProvider *server, const Anope::st
|
||||
|
||||
replacements["NUMBERS"] = stringify(chan_count);
|
||||
replacements["CHANNELS"] = (ci->HasExt("CS_NO_EXPIRE") ? "!" : "") + ci->name;
|
||||
Anope::string access_str;
|
||||
for (unsigned i = 0; i < access.size(); ++i)
|
||||
access_str += ", " + access[i]->AccessSerialize();
|
||||
replacements["ACCESSES"] = access_str.substr(2);
|
||||
|
||||
const ChanAccess *highest = access.Highest();
|
||||
replacements["ACCESSES"] = highest ? highest->AccessSerialize() : "";
|
||||
}
|
||||
|
||||
TemplateFileServer page("nickserv/alist.html");
|
||||
|
||||
+42
-51
File diff suppressed because it is too large
Load Diff
+68
-34
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user