mirror of
https://github.com/znc/znc.git
synced 2026-05-08 22:34:45 +02:00
Added support for cookies and sessions. Logging in is now done via cookies.
git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@1799 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
+35
-1
@@ -41,6 +41,24 @@ void CHTTPSock::ReadData(const char* data, size_t len) {
|
||||
}
|
||||
}
|
||||
|
||||
bool CHTTPSock::SetCookie(const CString& sKey, const CString& sValue) {
|
||||
if (!sKey.empty() && !sValue.empty()) {
|
||||
m_msCookies[sKey] = sValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
const MCString& CHTTPSock::GetCookies() const {
|
||||
return m_msCookies;
|
||||
}
|
||||
|
||||
CString CHTTPSock::GetCookie(const CString& sKey) const {
|
||||
MCString::const_iterator it = m_msCookies.find(sKey);
|
||||
|
||||
return it != m_msCookies.end() ? it->second : "";
|
||||
}
|
||||
|
||||
void CHTTPSock::CheckPost() {
|
||||
if (m_sPostData.size() >= m_uPostLen) {
|
||||
ParseParams(m_sPostData.Left(m_uPostLen));
|
||||
@@ -70,6 +88,16 @@ void CHTTPSock::ReadLine(const CString& sData) {
|
||||
m_bPost = true;
|
||||
m_sURI = sLine.Token(1);
|
||||
ParseURI();
|
||||
} else if (sName.Equals("Cookie:")) {
|
||||
VCString vsNV;
|
||||
|
||||
sLine.Token(1, true).Split(";", vsNV, false, "", "", true, true);
|
||||
|
||||
for (unsigned int a = 0; a < vsNV.size(); a++) {
|
||||
CString s(vsNV[a]);
|
||||
|
||||
SetCookie(s.Token(0, false, "=").Escape_n(CString::EURL, CString::EASCII), s.Token(1, true, "=").Escape_n(CString::EURL, CString::EASCII));
|
||||
}
|
||||
} else if (sName.Equals("Authorization:")) {
|
||||
CString sUnhashed;
|
||||
sLine.Token(2).Base64Decode(sUnhashed);
|
||||
@@ -405,7 +433,13 @@ bool CHTTPSock::PrintHeader(off_t uContentLength, const CString& sContentType, u
|
||||
}
|
||||
Write("Content-Type: " + m_sContentType + "\r\n");
|
||||
|
||||
for (MCString::iterator it = m_msHeaders.begin(); it != m_msHeaders.end(); ++it) {
|
||||
MCString::iterator it;
|
||||
|
||||
for (it = m_msCookies.begin(); it != m_msCookies.end(); ++it) {
|
||||
Write("Set-Cookie: " + it->first.Escape_n(CString::EURL) + "=" + it->second.Escape_n(CString::EURL) + "; path=/;\r\n");
|
||||
}
|
||||
|
||||
for (it = m_msHeaders.begin(); it != m_msHeaders.end(); ++it) {
|
||||
Write(it->first + ": " + it->second + "\r\n");
|
||||
}
|
||||
|
||||
|
||||
+10
-3
@@ -29,8 +29,10 @@ public:
|
||||
// !Csocket derived members
|
||||
|
||||
// Hooks
|
||||
virtual bool OnPageRequest(const CString& sURI, CString& sPageRet) = 0;
|
||||
virtual bool ForceLogin();
|
||||
virtual bool OnLogin(const CString& sUser, const CString& sPass);
|
||||
virtual bool OnPageRequest(const CString& sURI, CString& sPageRet) = 0;
|
||||
virtual bool PrintFile(const CString& sFileName, CString sContentType = "");
|
||||
// !Hooks
|
||||
|
||||
void CheckPost();
|
||||
@@ -41,13 +43,17 @@ public:
|
||||
|
||||
bool PrintNotFound();
|
||||
bool Redirect(const CString& sURL);
|
||||
bool ForceLogin();
|
||||
CString GetErrorPage(unsigned int uStatusId, const CString& sStatusMsg, const CString& sMessage);
|
||||
bool PrintErrorPage(unsigned int uStatusId, const CString& sStatusMsg, const CString& sMessage);
|
||||
void ParseParams(const CString& sParams);
|
||||
void ParseURI();
|
||||
void GetPage();
|
||||
virtual bool PrintFile(const CString& sFileName, CString sContentType = "");
|
||||
|
||||
// Cookies
|
||||
bool SetCookie(const CString& sKey, const CString& sValue);
|
||||
const MCString& GetCookies() const;
|
||||
CString GetCookie(const CString& sKey) const;
|
||||
// Cookies
|
||||
|
||||
// Setters
|
||||
void SetDocRoot(const CString& s);
|
||||
@@ -89,6 +95,7 @@ protected:
|
||||
MCString m_msHeaders;
|
||||
bool m_bHTTP10Client;
|
||||
CString m_sIfNoneMatch;
|
||||
MCString m_msCookies;
|
||||
};
|
||||
|
||||
#endif // !_HTTPSOCK_H
|
||||
|
||||
+131
-52
@@ -17,7 +17,6 @@ CZNCTagHandler::CZNCTagHandler(CWebSock& WebSock) : CTemplateTagHandler(), m_Web
|
||||
bool CZNCTagHandler::HandleTag(CTemplate& Tmpl, const CString& sName, const CString& sArgs, CString& sOutput) {
|
||||
if (sName.Equals("URLPARAM")) {
|
||||
//sOutput = CZNC::Get()
|
||||
std::cerr << "========================= URLPARAM !!!!!!!!!!" << std::endl;
|
||||
sOutput = m_WebSock.GetParam(sArgs.Token(0));
|
||||
return true;
|
||||
}
|
||||
@@ -25,30 +24,82 @@ bool CZNCTagHandler::HandleTag(CTemplate& Tmpl, const CString& sName, const CStr
|
||||
return false;
|
||||
}
|
||||
|
||||
CWebSession::CWebSession(const CString& sId) : m_sId(sId) {
|
||||
if (m_sId.empty()) {
|
||||
m_sId = CBlowfish::MD5(CString::RandomString(4096), true);
|
||||
DEBUG("Auto generated session: [" + m_sId + "]");
|
||||
}
|
||||
|
||||
m_bLoggedIn = false;
|
||||
m_pUser = NULL;
|
||||
}
|
||||
|
||||
bool CWebSession::IsAdmin() const { return IsLoggedIn() && m_pUser->IsAdmin(); }
|
||||
|
||||
CWebAuth::CWebAuth(CWebSock* pWebSock, const CString& sUsername, const CString& sPassword)
|
||||
: CAuthBase(sUsername, sPassword, pWebSock) {
|
||||
m_pWebSock = pWebSock;
|
||||
}
|
||||
|
||||
void CWebSession::ClearMessageLoops() {
|
||||
m_vsErrorMsgs.clear();
|
||||
m_vsSuccessMsgs.clear();
|
||||
}
|
||||
|
||||
void CWebSession::FillMessageLoops(CTemplate& Tmpl) {
|
||||
for (unsigned int a = 0; a < m_vsErrorMsgs.size(); a++) {
|
||||
CTemplate& Row = Tmpl.AddRow("ErrorLoop");
|
||||
Row["Message"] = m_vsErrorMsgs[a];
|
||||
}
|
||||
|
||||
for (unsigned int b = 0; b < m_vsSuccessMsgs.size(); b++) {
|
||||
CTemplate& Row = Tmpl.AddRow("SuccessLoop");
|
||||
Row["Message"] = m_vsSuccessMsgs[b];
|
||||
}
|
||||
}
|
||||
|
||||
size_t CWebSession::AddError(const CString& sMessage) {
|
||||
m_vsErrorMsgs.push_back(sMessage);
|
||||
return m_vsErrorMsgs.size();
|
||||
}
|
||||
|
||||
size_t CWebSession::AddSuccess(const CString& sMessage) {
|
||||
m_vsSuccessMsgs.push_back(sMessage);
|
||||
return m_vsSuccessMsgs.size();
|
||||
}
|
||||
|
||||
|
||||
void CWebAuth::AcceptedLogin(CUser& User) {
|
||||
if (m_pWebSock) {
|
||||
m_pWebSock->SetSessionUser(&User);
|
||||
CSmartPtr<CWebSession> spSession = m_pWebSock->GetSession();
|
||||
|
||||
spSession->SetUser(&User);
|
||||
spSession->SetLoggedIn(true);
|
||||
|
||||
m_pWebSock->SetLoggedIn(true);
|
||||
m_pWebSock->UnPauseRead();
|
||||
|
||||
DEBUG("Successful login attempt ==> USER [" + User.GetUserName() + "] ==> SESSION [" + spSession->GetId() + "]");
|
||||
}
|
||||
}
|
||||
|
||||
void CWebAuth::RefusedLogin(const CString& sReason) {
|
||||
if (m_pWebSock) {
|
||||
m_pWebSock->SetSessionUser(NULL);
|
||||
CSmartPtr<CWebSession> spSession = m_pWebSock->GetSession();
|
||||
|
||||
spSession->AddError("Invalid login!");
|
||||
spSession->SetUser(NULL);
|
||||
spSession->SetLoggedIn(false);
|
||||
|
||||
m_pWebSock->SetLoggedIn(false);
|
||||
m_pWebSock->UnPauseRead();
|
||||
|
||||
DEBUG("UNSUCCESSFUL login attempt ==> REASON [" + sReason + "] ==> SESSION [" + spSession->GetId() + "]");
|
||||
}
|
||||
}
|
||||
|
||||
CWebSock::CWebSock(CModule* pModule) : CHTTPSock(pModule) {
|
||||
m_pModule = pModule;
|
||||
m_pSessionUser = NULL;
|
||||
m_bPathsSet = false;
|
||||
|
||||
m_Template.AddTagHandler(new CZNCTagHandler(*this));
|
||||
@@ -57,7 +108,6 @@ CWebSock::CWebSock(CModule* pModule) : CHTTPSock(pModule) {
|
||||
CWebSock::CWebSock(CModule* pModule, const CString& sHostname, unsigned short uPort, int iTimeout)
|
||||
: CHTTPSock(pModule, sHostname, uPort, iTimeout) {
|
||||
m_pModule = pModule;
|
||||
m_pSessionUser = NULL;
|
||||
m_bPathsSet = false;
|
||||
|
||||
m_Template.AddTagHandler(new CZNCTagHandler(*this));
|
||||
@@ -135,7 +185,7 @@ CModule* CWebSock::ResolveModule() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pModRet = m_pSessionUser->GetModules().FindModule(m_sModName);
|
||||
pModRet = m_spSession->GetUser()->GetModules().FindModule(m_sModName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,10 +292,13 @@ void CWebSock::SetVars() {
|
||||
m_Template["Tag"] = CZNC::GetTag();
|
||||
m_Template["SkinName"] = GetSkinName();
|
||||
|
||||
if (IsAdmin()) {
|
||||
if (m_spSession->IsAdmin()) {
|
||||
m_Template["IsAdmin"] = "true";
|
||||
}
|
||||
|
||||
m_spSession->FillMessageLoops(m_Template);
|
||||
m_spSession->ClearMessageLoops();
|
||||
|
||||
// Global Mods
|
||||
CGlobalModules& vgMods = CZNC::Get().GetModules();
|
||||
for (unsigned int a = 0; a < vgMods.size(); a++) {
|
||||
@@ -254,7 +307,7 @@ void CWebSock::SetVars() {
|
||||
|
||||
// User Mods
|
||||
if (IsLoggedIn()) {
|
||||
CModules& vMods = m_pSessionUser->GetModules();
|
||||
CModules& vMods = m_spSession->GetUser()->GetModules();
|
||||
|
||||
for (unsigned int a = 0; a < vMods.size(); a++) {
|
||||
AddModLoop("UserModLoop", *vMods[a]);
|
||||
@@ -271,7 +324,7 @@ bool CWebSock::AddModLoop(const CString& sLoopName, CModule& Module) {
|
||||
|
||||
DEBUG("=== === === === === [" + Module.GetModName() + "] [" + CString(IsLoggedIn()) + "]");
|
||||
|
||||
if (!sTitle.empty() && (IsLoggedIn() || (!Module.WebRequiresLogin() && !Module.WebRequiresAdmin())) && (IsAdmin() || !Module.WebRequiresAdmin())) {
|
||||
if (!sTitle.empty() && (IsLoggedIn() || (!Module.WebRequiresLogin() && !Module.WebRequiresAdmin())) && (m_spSession->IsAdmin() || !Module.WebRequiresAdmin())) {
|
||||
CTemplate& Row = m_Template.AddRow(sLoopName);
|
||||
|
||||
Row["ModName"] = Module.GetModName();
|
||||
@@ -293,7 +346,7 @@ bool CWebSock::AddModLoop(const CString& sLoopName, CModule& Module) {
|
||||
// bActive is whether or not the current url matches this subpage (params will be checked below)
|
||||
bool bActive = (m_sModName == Module.GetModName() && m_sPage == SubPage->GetName());
|
||||
|
||||
if (SubPage->RequiresAdmin() && !IsAdmin()) {
|
||||
if (SubPage->RequiresAdmin() && !m_spSession->IsAdmin()) {
|
||||
continue; // Don't add admin-only subpages to requests from non-admin users
|
||||
}
|
||||
|
||||
@@ -392,8 +445,41 @@ CString CWebSock::GetSkinPath(const CString& sSkinName) const {
|
||||
return sRet + "/";
|
||||
}
|
||||
|
||||
bool CWebSock::ForceLogin() {
|
||||
if (m_spSession->IsLoggedIn()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
m_spSession->AddError("You must login to view that page");
|
||||
Redirect("/");
|
||||
return false;
|
||||
}
|
||||
|
||||
CString CWebSock::GetCookie(const CString& sKey) const {
|
||||
if (!m_sModName.empty()) {
|
||||
return CHTTPSock::GetCookie("Mod::" + m_sModName + "::" + sKey);
|
||||
}
|
||||
|
||||
return CHTTPSock::GetCookie(sKey);
|
||||
}
|
||||
|
||||
bool CWebSock::SetCookie(const CString& sKey, const CString& sValue) {
|
||||
if (!m_sModName.empty()) {
|
||||
return CHTTPSock::SetCookie("Mod::" + m_sModName + "::" + sKey, sValue);
|
||||
}
|
||||
|
||||
return CHTTPSock::SetCookie(sKey, sValue);
|
||||
}
|
||||
|
||||
bool CWebSock::OnPageRequest(const CString& sURI, CString& sPageRet) {
|
||||
DEBUG("CWebSock::OnPageRequest(" + sURI + ")");
|
||||
m_spSession = GetSession();
|
||||
SetCookie("SessionId", m_spSession->GetId());
|
||||
|
||||
if (m_spSession->IsLoggedIn()) {
|
||||
m_sUser = m_spSession->GetUser()->GetUserName();
|
||||
m_bLoggedIn = true;
|
||||
}
|
||||
|
||||
// Handle the static pages that don't require a login
|
||||
if (sURI == "/") {
|
||||
@@ -401,34 +487,22 @@ bool CWebSock::OnPageRequest(const CString& sURI, CString& sPageRet) {
|
||||
} else if (sURI == "/favicon.ico") {
|
||||
return PrintStaticFile("/pub/favicon.ico", sPageRet);
|
||||
} else if (sURI == "/logout") {
|
||||
if (!IsLoggedIn()) {
|
||||
m_spSession->SetLoggedIn(false);
|
||||
SetLoggedIn(false);
|
||||
Redirect("/");
|
||||
|
||||
return true;
|
||||
} else if (sURI == "/login" || sURI.Left(7) == "/login/") {
|
||||
if (GetParam("submitted").ToBool()) {
|
||||
m_sUser = GetParam("user");
|
||||
m_sPass = GetParam("pass");
|
||||
m_bLoggedIn = OnLogin(m_sUser, m_sPass);
|
||||
|
||||
Redirect("/");
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int uCurCnt = GetParam("cnt").ToUInt();
|
||||
unsigned int uCounter = m_pSessionUser->GetWebLogoutCounter(GetRemoteIP());
|
||||
|
||||
if (!uCurCnt) {
|
||||
Redirect("/logout?cnt=" + CString(uCounter));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (uCurCnt >= uCounter) {
|
||||
m_bLoggedIn = false;
|
||||
m_pSessionUser->IncWebLogoutCounter(GetRemoteIP());
|
||||
ForceLogin();
|
||||
} else {
|
||||
Redirect("/");
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (sURI.Left(6) == "/login") {
|
||||
if (ForceLogin()) {
|
||||
Redirect("/");
|
||||
}
|
||||
|
||||
return true;
|
||||
return PrintTemplate("login", sPageRet);
|
||||
} else if (sURI.Left(5) == "/pub/") {
|
||||
return PrintStaticFile(sURI, sPageRet);
|
||||
} else if (sURI.Left(6) == "/mods/" || sURI.Left(10) == "/modfiles/") {
|
||||
@@ -451,17 +525,17 @@ bool CWebSock::OnPageRequest(const CString& sURI, CString& sPageRet) {
|
||||
return true;
|
||||
}
|
||||
|
||||
pModule = CZNC::Get().FindModule(m_sModName, m_pSessionUser);
|
||||
pModule = CZNC::Get().FindModule(m_sModName, m_spSession->GetUser());
|
||||
}
|
||||
|
||||
if (!pModule) {
|
||||
return false;
|
||||
} else if (pModule->WebRequiresLogin() && !ForceLogin()) {
|
||||
return true;
|
||||
} else if (pModule->WebRequiresAdmin() && !IsAdmin()) {
|
||||
} else if (pModule->WebRequiresAdmin() && !m_spSession->IsAdmin()) {
|
||||
sPageRet = GetErrorPage(403, "Forbidden", "You need to be an admin to access this module");
|
||||
return true;
|
||||
} else if (pModule && !pModule->IsGlobal() && pModule->GetUser() != m_pSessionUser) {
|
||||
} else if (pModule && !pModule->IsGlobal() && pModule->GetUser() != m_spSession->GetUser()) {
|
||||
sPageRet = GetErrorPage(403, "Forbidden", "You must login as " + pModule->GetUser()->GetUserName() + " in order to view this page");
|
||||
return true;
|
||||
}
|
||||
@@ -473,13 +547,13 @@ bool CWebSock::OnPageRequest(const CString& sURI, CString& sPageRet) {
|
||||
|
||||
bool bActive = (m_sModName == pModule->GetModName() && m_sPage == SubPage->GetName());
|
||||
|
||||
if (bActive && SubPage->RequiresAdmin() && !IsAdmin()) {
|
||||
if (bActive && SubPage->RequiresAdmin() && !m_spSession->IsAdmin()) {
|
||||
sPageRet = GetErrorPage(403, "Forbidden", "You need to be an admin to access this page");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (pModule && !pModule->IsGlobal() && (!IsLoggedIn() || pModule->GetUser() != GetSessionUser())) {
|
||||
if (pModule && !pModule->IsGlobal() && (!IsLoggedIn() || pModule->GetUser() != m_spSession->GetUser())) {
|
||||
AddModLoop("UserModLoop", *pModule);
|
||||
}
|
||||
|
||||
@@ -525,18 +599,23 @@ void CWebSock::PrintErrorPage(const CString& sMessage) {
|
||||
m_Template["Error"] = sMessage;
|
||||
}
|
||||
|
||||
size_t CWebSock::AddError(const CString& sMessage) {
|
||||
CTemplate& Row = m_Template.AddRow("ErrorLoop");
|
||||
CSmartPtr<CWebSession> CWebSock::GetSession() const {
|
||||
if (!m_spSession.IsNull()) {
|
||||
return m_spSession;
|
||||
}
|
||||
|
||||
Row["Message"] = sMessage;
|
||||
return m_Template.GetLoop("ErrorLoop")->size();
|
||||
}
|
||||
static map<CString, CSmartPtr<CWebSession> > mspSessions;
|
||||
map<CString, CSmartPtr<CWebSession> >::const_iterator it = mspSessions.find(GetCookie("SessionId"));
|
||||
|
||||
size_t CWebSock::AddSuccess(const CString& sMessage) {
|
||||
CTemplate& Row = m_Template.AddRow("SuccessLoop");
|
||||
if (it != mspSessions.end()) {
|
||||
DEBUG("Found existing session from cookie: [" + GetCookie("SessionId") + "] IsLoggedIn(" + CString(it->second->IsLoggedIn() ? "true" : "false") + ")");
|
||||
return it->second;
|
||||
}
|
||||
|
||||
Row["Message"] = sMessage;
|
||||
return m_Template.GetLoop("SuccessLoop")->size();
|
||||
CSmartPtr<CWebSession> spSession(new CWebSession());
|
||||
mspSessions.insert(make_pair(spSession->GetId(), spSession));
|
||||
|
||||
return spSession;
|
||||
}
|
||||
|
||||
bool CWebSock::OnLogin(const CString& sUser, const CString& sPass) {
|
||||
@@ -560,11 +639,11 @@ Csock* CWebSock::GetSockObj(const CString& sHost, unsigned short uPort) {
|
||||
return pSock;
|
||||
}
|
||||
|
||||
bool CWebSock::IsAdmin() const { return m_pSessionUser && m_pSessionUser->IsAdmin(); }
|
||||
CUser* CWebSock::GetSessionUser() const { return m_pSessionUser; }
|
||||
CString CWebSock::GetSkinName() const {
|
||||
if (m_pSessionUser && IsLoggedIn() && !m_pSessionUser->GetSkinName().empty()) {
|
||||
return m_pSessionUser->GetSkinName();
|
||||
CSmartPtr<CWebSession> spSession = GetSession();
|
||||
|
||||
if (spSession->IsLoggedIn() && !spSession->GetUser()->GetSkinName().empty()) {
|
||||
return spSession->GetUser()->GetSkinName();
|
||||
}
|
||||
|
||||
return CZNC::Get().GetSkinName();
|
||||
|
||||
+34
-12
@@ -32,6 +32,32 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class CWebSession {
|
||||
public:
|
||||
CWebSession(const CString& sId = "");
|
||||
virtual ~CWebSession() {}
|
||||
|
||||
const CString& GetId() const { return m_sId; }
|
||||
CUser* GetUser() const { return m_pUser; }
|
||||
bool IsLoggedIn() const { return m_pUser && m_bLoggedIn; }
|
||||
bool IsAdmin() const;
|
||||
|
||||
bool SetLoggedIn(bool b) { m_bLoggedIn = b; return m_bLoggedIn; }
|
||||
CUser* SetUser(CUser* p) { m_pUser = p; return m_pUser; }
|
||||
|
||||
void ClearMessageLoops();
|
||||
void FillMessageLoops(CTemplate& Tmpl);
|
||||
size_t AddError(const CString& sMessage);
|
||||
size_t AddSuccess(const CString& sMessage);
|
||||
private:
|
||||
CString m_sId;
|
||||
CUser* m_pUser;
|
||||
bool m_bLoggedIn;
|
||||
VCString m_vsErrorMsgs;
|
||||
VCString m_vsSuccessMsgs;
|
||||
};
|
||||
|
||||
|
||||
class CWebSubPage {
|
||||
public:
|
||||
CWebSubPage(const CString& sName, const CString& sTitle = "", unsigned int uFlags = 0) : m_sName(sName), m_sTitle(sTitle) {
|
||||
@@ -84,9 +110,9 @@ public:
|
||||
CWebSock(CModule* pModule, const CString& sHostname, unsigned short uPort, int iTimeout = 60);
|
||||
virtual ~CWebSock();
|
||||
|
||||
virtual bool OnPageRequest(const CString& sURI, CString& sPageRet);
|
||||
|
||||
virtual bool ForceLogin();
|
||||
virtual bool OnLogin(const CString& sUser, const CString& sPass);
|
||||
virtual bool OnPageRequest(const CString& sURI, CString& sPageRet);
|
||||
|
||||
void ParsePath(); // This parses the path portion of the url into some member vars
|
||||
CModule* ResolveModule();
|
||||
@@ -108,26 +134,20 @@ public:
|
||||
}
|
||||
|
||||
void PrintErrorPage(const CString& sMessage);
|
||||
size_t AddError(const CString& sMessage);
|
||||
size_t AddSuccess(const CString& sMessage);
|
||||
|
||||
// Setters
|
||||
void SetSessionUser(CUser* p) {
|
||||
m_pSessionUser = p;
|
||||
}
|
||||
// !Setters
|
||||
CSmartPtr<CWebSession> GetSession() const;
|
||||
|
||||
virtual Csock* GetSockObj(const CString& sHost, unsigned short uPort);
|
||||
bool IsAdmin() const;
|
||||
CUser* GetSessionUser() const;
|
||||
CString GetModWebPath(const CString& sModName) const;
|
||||
CString GetSkinPath(const CString& sSkinName) const;
|
||||
CModule* GetModule() const { return (CModule*) m_pModule; }
|
||||
size_t GetAvailSkins(vector<CFile>& vRet);
|
||||
CString GetSkinName() const;
|
||||
|
||||
CString GetCookie(const CString& sKey) const;
|
||||
bool SetCookie(const CString& sKey, const CString& sValue);
|
||||
|
||||
private:
|
||||
CUser* m_pSessionUser;
|
||||
bool m_bPathsSet;
|
||||
CTemplate m_Template;
|
||||
CSmartPtr<CAuthBase> m_spAuth;
|
||||
@@ -135,6 +155,8 @@ private:
|
||||
CString m_sModName; // Gets filled by ResolveModule()
|
||||
CString m_sPath; // Gets filled by ResolveModule()
|
||||
CString m_sPage; // Gets filled by ResolveModule()
|
||||
mutable map<CString, CSmartPtr<CWebSession> > m_mspSessions;
|
||||
CSmartPtr<CWebSession> m_spSession;
|
||||
};
|
||||
|
||||
#endif // !_WEBMODULES_H
|
||||
|
||||
+23
-18
@@ -70,6 +70,7 @@ public:
|
||||
}
|
||||
|
||||
CUser* GetNewUser(CWebSock& WebSock, CUser* pUser) {
|
||||
CSmartPtr<CWebSession> spSession = WebSock.GetSession();
|
||||
CString sUsername = WebSock.GetParam("newuser");
|
||||
|
||||
if (sUsername.empty()) {
|
||||
@@ -136,7 +137,7 @@ public:
|
||||
|
||||
sArg = WebSock.GetParam("vhost");
|
||||
// To change VHosts be admin or don't have DenySetVHost
|
||||
if (WebSock.IsAdmin() || !WebSock.GetSessionUser()->DenySetVHost()) {
|
||||
if (spSession->IsAdmin() || !spSession->GetUser()->DenySetVHost()) {
|
||||
if (!sArg.empty()) {
|
||||
pNewUser->SetVHost(sArg);
|
||||
}
|
||||
@@ -156,7 +157,7 @@ public:
|
||||
pNewUser->SetJoinTries(WebSock.GetParam("jointries").ToUInt());
|
||||
pNewUser->SetMaxJoins(WebSock.GetParam("maxjoins").ToUInt());
|
||||
|
||||
if (WebSock.IsAdmin()) {
|
||||
if (spSession->IsAdmin()) {
|
||||
pNewUser->SetDenyLoadMod(WebSock.GetParam("denyloadmod").ToBool());
|
||||
pNewUser->SetDenySetVHost(WebSock.GetParam("denysetvhost").ToBool());
|
||||
} else if (pUser) {
|
||||
@@ -178,7 +179,7 @@ public:
|
||||
pNewUser->AddChan(sChan.TrimRight_n("\r"), WebSock.GetParam("save_" + sChan).ToBool());
|
||||
}
|
||||
|
||||
if (WebSock.IsAdmin() || (pUser && !pUser->DenyLoadMod())) {
|
||||
if (spSession->IsAdmin() || (pUser && !pUser->DenyLoadMod())) {
|
||||
WebSock.GetParamValues("loadmod", vsArgs);
|
||||
|
||||
for (a = 0; a < vsArgs.size(); a++) {
|
||||
@@ -222,16 +223,18 @@ public:
|
||||
virtual bool WebRequiresAdmin() { return false; }
|
||||
virtual CString GetWebMenuTitle() { return "webadmin"; }
|
||||
virtual bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, CTemplate& Tmpl) {
|
||||
CSmartPtr<CWebSession> spSession = WebSock.GetSession();
|
||||
|
||||
if (sPageName == "settings") {
|
||||
// Admin Check
|
||||
if (!WebSock.IsAdmin()) {
|
||||
if (!spSession->IsAdmin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return SettingsPage(WebSock, Tmpl);
|
||||
} else if (sPageName == "adduser") {
|
||||
// Admin Check
|
||||
if (!WebSock.IsAdmin()) {
|
||||
if (!spSession->IsAdmin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -240,7 +243,7 @@ public:
|
||||
CUser* pUser = CZNC::Get().FindUser(WebSock.GetParam("user"));
|
||||
|
||||
// Admin/Self Check
|
||||
if (!WebSock.IsAdmin() && (!WebSock.GetSessionUser() || WebSock.GetSessionUser() != pUser)) {
|
||||
if (!spSession->IsAdmin() && (!spSession->GetUser() || spSession->GetUser() != pUser)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -260,7 +263,7 @@ public:
|
||||
CUser* pUser = CZNC::Get().FindUser(WebSock.GetParam("user"));
|
||||
|
||||
// Admin/Self Check
|
||||
if (!WebSock.IsAdmin() && (!WebSock.GetSessionUser() || WebSock.GetSessionUser() != pUser)) {
|
||||
if (!spSession->IsAdmin() && (!spSession->GetUser() || spSession->GetUser() != pUser)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -273,7 +276,7 @@ public:
|
||||
CUser* pUser = CZNC::Get().FindUser(WebSock.GetParam("user"));
|
||||
|
||||
// Admin/Self Check
|
||||
if (!WebSock.IsAdmin() && (!WebSock.GetSessionUser() || WebSock.GetSessionUser() != pUser)) {
|
||||
if (!spSession->IsAdmin() && (!spSession->GetUser() || spSession->GetUser() != pUser)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -284,14 +287,14 @@ public:
|
||||
WebSock.PrintErrorPage("No such username");
|
||||
} else if (sPageName == "deluser") {
|
||||
// Admin Check
|
||||
if (!WebSock.IsAdmin()) {
|
||||
if (!spSession->IsAdmin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CString sUser = WebSock.GetParam("user");
|
||||
CUser* pUser = CZNC::Get().FindUser(sUser);
|
||||
|
||||
if (pUser && pUser == WebSock.GetSessionUser()) {
|
||||
if (pUser && pUser == spSession->GetUser()) {
|
||||
WebSock.PrintErrorPage("Please don't delete yourself, suicide is not the answer!");
|
||||
return true;
|
||||
} else if (CZNC::Get().DeleteUser(sUser)) {
|
||||
@@ -302,10 +305,10 @@ public:
|
||||
WebSock.PrintErrorPage("No such username");
|
||||
return true;
|
||||
} else if (sPageName == "edituser") {
|
||||
CUser* pUser = WebSock.HasParam("user") ? CZNC::Get().FindUser(WebSock.GetParam("user")) : WebSock.GetSessionUser();
|
||||
CUser* pUser = WebSock.HasParam("user") ? CZNC::Get().FindUser(WebSock.GetParam("user")) : spSession->GetUser();
|
||||
|
||||
// Admin/Self Check
|
||||
if (!WebSock.IsAdmin() && (!WebSock.GetSessionUser() || WebSock.GetSessionUser() != pUser)) {
|
||||
if (!spSession->IsAdmin() && (!spSession->GetUser() || spSession->GetUser() != pUser)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -316,7 +319,7 @@ public:
|
||||
WebSock.PrintErrorPage("No such username");
|
||||
} else if (sPageName == "listusers") {
|
||||
// Admin Check
|
||||
if (!WebSock.IsAdmin()) {
|
||||
if (!spSession->IsAdmin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -440,6 +443,7 @@ public:
|
||||
}
|
||||
|
||||
bool UserPage(CWebSock& WebSock, CTemplate& Tmpl, CUser* pUser = NULL) {
|
||||
CSmartPtr<CWebSession> spSession = WebSock.GetSession();
|
||||
Tmpl.SetFile("add_edit_user.tmpl");
|
||||
|
||||
if (!WebSock.GetParam("submitted").ToUInt()) {
|
||||
@@ -507,7 +511,7 @@ public:
|
||||
// To change VHosts be admin or don't have DenySetVHost
|
||||
const VCString& vsVHosts = CZNC::Get().GetVHosts();
|
||||
bool bFoundVHost = false;
|
||||
if (WebSock.IsAdmin() || !WebSock.GetSessionUser()->DenySetVHost()) {
|
||||
if (spSession->IsAdmin() || !spSession->GetUser()->DenySetVHost()) {
|
||||
for (unsigned int b = 0; b < vsVHosts.size(); b++) {
|
||||
const CString& sVHost = vsVHosts[b];
|
||||
CTemplate& l = Tmpl.AddRow("VHostLoop");
|
||||
@@ -557,7 +561,7 @@ public:
|
||||
l["Checked"] = "true";
|
||||
}
|
||||
|
||||
if (!WebSock.IsAdmin() && pUser && pUser->DenyLoadMod()) {
|
||||
if (!spSession->IsAdmin() && pUser && pUser->DenyLoadMod()) {
|
||||
l["Disabled"] = "true";
|
||||
}
|
||||
}
|
||||
@@ -594,7 +598,7 @@ public:
|
||||
o8["DisplayName"] = "Prepend Timestamps";
|
||||
if (pUser && pUser->GetTimestampPrepend()) { o8["Checked"] = "true"; }
|
||||
|
||||
if (WebSock.IsAdmin()) {
|
||||
if (spSession->IsAdmin()) {
|
||||
CTemplate& o9 = Tmpl.AddRow("OptionLoop");
|
||||
o9["Name"] = "denyloadmod";
|
||||
o9["DisplayName"] = "Deny LoadMod";
|
||||
@@ -657,7 +661,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if (!WebSock.IsAdmin()) {
|
||||
if (!spSession->IsAdmin()) {
|
||||
WebSock.Redirect("edituser");
|
||||
} else {
|
||||
WebSock.Redirect("listusers");
|
||||
@@ -667,6 +671,7 @@ public:
|
||||
}
|
||||
|
||||
bool ListUsersPage(CWebSock& WebSock, CTemplate& Tmpl) {
|
||||
CSmartPtr<CWebSession> spSession = WebSock.GetSession();
|
||||
const map<CString,CUser*>& msUsers = CZNC::Get().GetUserMap();
|
||||
Tmpl["Title"] = "List Users";
|
||||
Tmpl["Action"] = "listusers";
|
||||
@@ -682,7 +687,7 @@ public:
|
||||
l["Clients"] = CString(User.GetClients().size());
|
||||
l["IRCNick"] = User.GetIRCNick().GetNick();
|
||||
|
||||
if (&User == WebSock.GetSessionUser()) {
|
||||
if (&User == spSession->GetUser()) {
|
||||
l["IsSelf"] = "true";
|
||||
}
|
||||
|
||||
|
||||
@@ -135,19 +135,50 @@ a:hover {
|
||||
border-right: 1px solid #000;
|
||||
}
|
||||
|
||||
.successbar,
|
||||
.errorbar {
|
||||
width: 790px;
|
||||
height: 20px;
|
||||
border-bottom: 1px solid #000;
|
||||
border-right: 1px solid #000;
|
||||
background: #900;
|
||||
padding: 2px 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.successbar {
|
||||
background: #070;
|
||||
}
|
||||
|
||||
|
||||
#infobar span {
|
||||
float: left;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
#infobar span.switchuser {
|
||||
text-align: center;
|
||||
#infobar span.loginbox,
|
||||
#infobar span.logoutbox {
|
||||
text-align: right;
|
||||
padding-right: 5px;
|
||||
border-left: 1px solid #000000;
|
||||
height: 100%;
|
||||
width: 150px;
|
||||
width: 250px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
#infobar span.logoutbox {
|
||||
text-align: center;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
#infobar span.loginbox input {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
#infobar span.loginbox input.submit {
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
#subpage {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
<? IF LoggedIn ?>
|
||||
<span class="switchuser"><a href="/logout">Logout</a></span>
|
||||
<span class="logoutbox"><a href="/logout">Logout</a></span>
|
||||
<? ELSE IF !ModName && PageName == "login" ?>
|
||||
<span class="logoutbox"> </span>
|
||||
<? ELSE ?>
|
||||
<span class="switchuser"><a href="/login">Login</a></span>
|
||||
<span class="loginbox">
|
||||
<form action="/login" method="POST">
|
||||
<input type="hidden" name="submitted" value="1">
|
||||
User:<input type="text" name="user">
|
||||
Pass:<input type="password" name="pass">
|
||||
<input type="submit" class="submit" value="Login">
|
||||
</form>
|
||||
</span>
|
||||
<? ENDIF ?>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<? INC Header.tmpl ?>
|
||||
<form action="/login" method="POST">
|
||||
<input type="hidden" name="submitted" value="1">
|
||||
<table>
|
||||
<tr>
|
||||
<td>User:</td>
|
||||
<td>Password:</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="text" name="user" size="24"> </td>
|
||||
<td><input type="password" name="pass" size="24"></td>
|
||||
<td><input type="submit" class="submit" value="Login"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<? INC Footer.tmpl ?>
|
||||
Reference in New Issue
Block a user