summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAttila Molnar <attilamolnar@hush.com>2015-12-05 16:16:49 +0100
committerAttila Molnar <attilamolnar@hush.com>2015-12-05 16:16:49 +0100
commit425d54073a0ae61c68de1b339177bb7c0db116f1 (patch)
tree8a0e4e91f0a5deeaa3e50ef5f42c983400e0c393
parentddc6999a1db1aa1e9bf9df2f1ab444c387bcd5b1 (diff)
m_cap Specialize extension item
-rw-r--r--include/modules/cap.h9
-rw-r--r--src/modules/m_cap.cpp55
2 files changed, 62 insertions, 2 deletions
diff --git a/include/modules/cap.h b/include/modules/cap.h
index 6f91f5aee..9ff5faca9 100644
--- a/include/modules/cap.h
+++ b/include/modules/cap.h
@@ -28,7 +28,14 @@ namespace Cap
static const unsigned int MAX_VALUE_LENGTH = 100;
typedef intptr_t Ext;
- typedef LocalIntExt ExtItem;
+ class ExtItem : public LocalIntExt
+ {
+ public:
+ ExtItem(Module* mod);
+ std::string serialize(SerializeFormat format, const Extensible* container, void* item) const;
+ void unserialize(SerializeFormat format, Extensible* container, const std::string& value);
+ };
+
class Capability;
enum Protocol
diff --git a/src/modules/m_cap.cpp b/src/modules/m_cap.cpp
index e1593e33f..bfce2e68c 100644
--- a/src/modules/m_cap.cpp
+++ b/src/modules/m_cap.cpp
@@ -25,6 +25,8 @@ namespace Cap
class ManagerImpl;
}
+static Cap::ManagerImpl* managerimpl;
+
class Cap::ManagerImpl : public Cap::Manager
{
typedef insp::flat_map<std::string, Capability*, irc::insensitive_swo> CapMap;
@@ -62,9 +64,10 @@ class Cap::ManagerImpl : public Cap::Manager
public:
ManagerImpl(Module* mod, Events::ModuleEventProvider& evprovref)
: Cap::Manager(mod)
- , capext("caps", ExtensionItem::EXT_USER, mod)
+ , capext(mod)
, evprov(evprovref)
{
+ managerimpl = this;
}
~ManagerImpl()
@@ -199,6 +202,56 @@ class Cap::ManagerImpl : public Cap::Manager
}
};
+Cap::ExtItem::ExtItem(Module* mod)
+ : LocalIntExt("caps", ExtensionItem::EXT_USER, mod)
+{
+}
+
+std::string Cap::ExtItem::serialize(SerializeFormat format, const Extensible* container, void* item) const
+{
+ std::string ret;
+ // XXX: Cast away the const because IS_LOCAL() doesn't handle it
+ LocalUser* user = IS_LOCAL(const_cast<User*>(static_cast<const User*>(container)));
+ if ((format == FORMAT_NETWORK) || (!user))
+ return ret;
+
+ // List requested caps
+ managerimpl->HandleList(ret, user, false, false);
+
+ // Serialize cap protocol version. If building a human-readable string append a new token, otherwise append only a single character indicating the version.
+ Protocol protocol = managerimpl->GetProtocol(user);
+ if (format == FORMAT_USER)
+ ret.append("capversion=3.");
+ else if (!ret.empty())
+ ret.erase(ret.length()-1);
+
+ if (protocol == CAP_302)
+ ret.push_back('2');
+ else
+ ret.push_back('1');
+
+ return ret;
+}
+
+void Cap::ExtItem::unserialize(SerializeFormat format, Extensible* container, const std::string& value)
+{
+ if (format == FORMAT_NETWORK)
+ return;
+
+ LocalUser* user = IS_LOCAL(static_cast<User*>(container));
+ if (!user)
+ return; // Can't happen
+
+ // Process the cap protocol version which is a single character at the end of the serialized string
+ const char verchar = *value.rbegin();
+ if (verchar == '2')
+ managerimpl->Set302Protocol(user);
+
+ // Remove the version indicator from the string passed to HandleReq
+ std::string caplist(value, 0, value.size()-1);
+ managerimpl->HandleReq(user, caplist);
+}
+
class CommandCap : public SplitCommand
{
Events::ModuleEventProvider evprov;