summaryrefslogtreecommitdiff
path: root/modules/commands/ns_access.cpp
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2014-11-24 14:27:23 -0500
committerAdam <Adam@anope.org>2014-11-24 14:27:23 -0500
commit42238034490fb5479d787bd1695750387d508200 (patch)
treec93c62e0e1c936e656ae5b9ee1b62380ce2a194c /modules/commands/ns_access.cpp
parentd492923610d9c9146b2a2b63de38deab2cfd4ca7 (diff)
Rewrite serializable to have field level granularity
Represent serializable objects in a digraph, and as a result made most object relationships implicitly defined, and use the graph to trace references between objects to determine relationships. Edges may also be marked as having a dependency of the object they point to, which allows for automatic cleanup and deletion of most objects when no longer needed. Additionally, this allows not having to require in-memory copies of everything when using external databases. db_sql has been rewritten for this and now always requires a database to function. db_sql with MySQL now requires InnoDB to make use of transactions and foreign key constraints.
Diffstat (limited to 'modules/commands/ns_access.cpp')
-rw-r--r--modules/commands/ns_access.cpp126
1 files changed, 94 insertions, 32 deletions
diff --git a/modules/commands/ns_access.cpp b/modules/commands/ns_access.cpp
index 443686bca..d944c8736 100644
--- a/modules/commands/ns_access.cpp
+++ b/modules/commands/ns_access.cpp
@@ -11,6 +11,53 @@
#include "module.h"
#include "modules/nickserv.h"
+#include "modules/ns_access.h"
+
+class NickAccessImpl : public NickAccess
+{
+ public:
+ NickAccessImpl(Serialize::TypeBase *type) : NickAccess(type) { }
+ NickAccessImpl(Serialize::TypeBase *type, Serialize::ID id) : NickAccess(type, id) { }
+
+ NickServ::Account *GetAccount() override;
+ void SetAccount(NickServ::Account *) override;
+
+ Anope::string GetMask() override;
+ void SetMask(const Anope::string &) override;
+};
+
+class NickAccessType : public Serialize::Type<NickAccessImpl>
+{
+ public:
+ Serialize::ObjectField<NickAccessImpl, NickServ::Account *> account;
+ Serialize::Field<NickAccessImpl, Anope::string> mask;
+
+ NickAccessType(Module *creator) : Serialize::Type<NickAccessImpl>(creator, "NSAccess")
+ , account(this, "account", true)
+ , mask(this, "mask")
+ {
+ }
+};
+
+NickServ::Account *NickAccessImpl::GetAccount()
+{
+ return Get(&NickAccessType::account);
+}
+
+void NickAccessImpl::SetAccount(NickServ::Account *acc)
+{
+ Set(&NickAccessType::account, acc);
+}
+
+Anope::string NickAccessImpl::GetMask()
+{
+ return Get(&NickAccessType::mask);
+}
+
+void NickAccessImpl::SetMask(const Anope::string &m)
+{
+ Set(&NickAccessType::mask, m);
+}
class CommandNSAccess : public Command
{
@@ -29,21 +76,27 @@ class CommandNSAccess : public Command
return;
}
- if (nc->access.size() >= Config->GetModule(this->owner)->Get<unsigned>("accessmax", "32"))
+ std::vector<NickAccess *> access = nc->GetRefs<NickAccess *>(nsaccess);
+
+ if (access.size() >= Config->GetModule(this->owner)->Get<unsigned>("accessmax", "32"))
{
source.Reply(_("Sorry, the maximum of \002{0}\002 access entries has been reached."), Config->GetModule(this->owner)->Get<unsigned>("accessmax"));
return;
}
- if (nc->FindAccess(mask))
- {
- source.Reply(_("Mask \002{0}\002 already present on the access list of \002{1}\002."), mask, nc->display);
- return;
- }
+ for (NickAccess *a : access)
+ if (a->GetMask().equals_ci(mask))
+ {
+ source.Reply(_("Mask \002{0}\002 already present on the access list of \002{1}\002."), mask, nc->GetDisplay());
+ return;
+ }
- nc->AddAccess(mask);
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to ADD mask " << mask << " to " << nc->display;
- source.Reply(_("\002{0}\002 added to the access list of \002{1}\002."), mask, nc->display);
+ NickAccess *a = nsaccess.Create();
+ a->SetAccount(nc);
+ a->SetMask(mask);
+
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to ADD mask " << mask << " to " << nc->GetDisplay();
+ source.Reply(_("\002{0}\002 added to the access list of \002{1}\002."), mask, nc->GetDisplay());
}
void DoDel(CommandSource &source, NickServ::Account *nc, const Anope::string &mask)
@@ -60,34 +113,35 @@ class CommandNSAccess : public Command
return;
}
- if (!nc->FindAccess(mask))
- {
- source.Reply(_("\002{0}\002 not found on the access list of \002{1}\002."), mask, nc->display);
- return;
- }
+ for (NickAccess *a : nc->GetRefs<NickAccess *>(nsaccess))
+ if (a->GetMask().equals_ci(mask))
+ {
+ a->Delete();
+ Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to DELETE mask " << mask << " from " << nc->GetDisplay();
+ source.Reply(_("\002{0}\002 deleted from the access list of \002{1}\002."), mask, nc->GetDisplay());
+ return;
+ }
- nc->EraseAccess(mask);
- Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to DELETE mask " << mask << " from " << nc->display;
- source.Reply(_("\002{0}\002 deleted from the access list of \002{1}\002."), mask, nc->display);
+
+ source.Reply(_("\002{0}\002 not found on the access list of \002{1}\002."), mask, nc->GetDisplay());
}
void DoList(CommandSource &source, NickServ::Account *nc, const Anope::string &mask)
{
- unsigned i, end;
-
- if (nc->access.empty())
+ std::vector<NickAccess *> access = nc->GetRefs<NickAccess *>(nsaccess);
+ if (access.empty())
{
- source.Reply(_("The access list of \002{0}\002 is empty."), nc->display);
+ source.Reply(_("The access list of \002{0}\002 is empty."), nc->GetDisplay());
return;
}
- source.Reply(_("Access list for \002{0}\002:"), nc->display);
- for (i = 0, end = nc->access.size(); i < end; ++i)
+ source.Reply(_("Access list for \002{0}\002:"), nc->GetDisplay());
+ for (NickAccess *a : access)
{
- Anope::string access = nc->GetAccess(i);
- if (!mask.empty() && !Anope::Match(access, mask))
+ if (!mask.empty() && !Anope::Match(a->GetMask(), mask))
continue;
- source.Reply(" {0}", access);
+
+ source.Reply(" {0}", a->GetMask());
}
}
public:
@@ -115,20 +169,20 @@ class CommandNSAccess : public Command
NickServ::Account *nc;
if (!nick.empty() && source.HasPriv("nickserv/access"))
{
- const NickServ::Nick *na = NickServ::FindNick(nick);
+ NickServ::Nick *na = NickServ::FindNick(nick);
if (na == NULL)
{
source.Reply(_("\002{0}\002 isn't registered."), nick);
return;
}
- if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.GetAccount() != na->nc && na->nc->IsServicesOper() && !cmd.equals_ci("LIST"))
+ if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.GetAccount() != na->GetAccount() && na->GetAccount()->IsServicesOper() && !cmd.equals_ci("LIST"))
{
source.Reply(_("You may view but not modify the access list of other Services Operators."));
return;
}
- nc = na->nc;
+ nc = na->GetAccount();
}
else
nc = source.nc;
@@ -140,8 +194,8 @@ class CommandNSAccess : public Command
}
else if (cmd.equals_ci("LIST"))
return this->DoList(source, nc, mask);
- else if (nc->HasExt("NS_SUSPENDED"))
- source.Reply(_("\002{0}\002 is suspended."), nc->display);
+ else if (nc->HasFieldS("NS_SUSPENDED"))
+ source.Reply(_("\002{0}\002 is suspended."), nc->GetDisplay());
else if (cmd.equals_ci("ADD"))
return this->DoAdd(source, nc, mask);
else if (cmd.equals_ci("DEL"))
@@ -178,18 +232,26 @@ class NSAccess : public Module
, public EventHook<NickServ::Event::NickRegister>
{
CommandNSAccess commandnsaccess;
+ NickAccessType nick_type;
public:
NSAccess(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
, EventHook<NickServ::Event::NickRegister>("OnNickRegister")
, commandnsaccess(this)
+ , nick_type(this)
{
}
void OnNickRegister(User *u, NickServ::Nick *na, const Anope::string &) override
{
if (u && Config->GetModule(this)->Get<bool>("addaccessonreg"))
- na->nc->AddAccess(u->Mask());
+ {
+ NickAccess *a = nsaccess.Create();
+ a->SetAccount(na->GetAccount());
+ a->SetMask(u->Mask());
+ //XXX?
+// source.Reply(_("\002{0}\002 has been registered under your hostmask: \002{1}\002"), u_nick, na->GetAccount()->GetAccess(0));
+ }
}
};