diff --git a/HTTPSock.cpp b/HTTPSock.cpp index 5f8f86f8..e0d92cdd 100644 --- a/HTTPSock.cpp +++ b/HTTPSock.cpp @@ -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"); } diff --git a/HTTPSock.h b/HTTPSock.h index dfb8fc0f..5f73c41e 100644 --- a/HTTPSock.h +++ b/HTTPSock.h @@ -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 diff --git a/WebModules.cpp b/WebModules.cpp index b7d9b933..e20ed67c 100644 --- a/WebModules.cpp +++ b/WebModules.cpp @@ -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 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 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 CWebSock::GetSession() const { + if (!m_spSession.IsNull()) { + return m_spSession; + } - Row["Message"] = sMessage; - return m_Template.GetLoop("ErrorLoop")->size(); -} + static map > mspSessions; + map >::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 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 spSession = GetSession(); + + if (spSession->IsLoggedIn() && !spSession->GetUser()->GetSkinName().empty()) { + return spSession->GetUser()->GetSkinName(); } return CZNC::Get().GetSkinName(); diff --git a/WebModules.h b/WebModules.h index 3e2deb92..fbde6a43 100644 --- a/WebModules.h +++ b/WebModules.h @@ -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 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& 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 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 > m_mspSessions; + CSmartPtr m_spSession; }; #endif // !_WEBMODULES_H diff --git a/modules/webadmin.cpp b/modules/webadmin.cpp index d37ed764..d7e49def 100644 --- a/modules/webadmin.cpp +++ b/modules/webadmin.cpp @@ -70,6 +70,7 @@ public: } CUser* GetNewUser(CWebSock& WebSock, CUser* pUser) { + CSmartPtr 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 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 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 spSession = WebSock.GetSession(); const map& 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"; } diff --git a/webskins/_default_/pub/main.css b/webskins/_default_/pub/main.css index 108bd2ad..f7d80016 100644 --- a/webskins/_default_/pub/main.css +++ b/webskins/_default_/pub/main.css @@ -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; } diff --git a/webskins/_default_/tmpl/LoginBar.tmpl b/webskins/_default_/tmpl/LoginBar.tmpl index 0d1bb876..298dc6db 100644 --- a/webskins/_default_/tmpl/LoginBar.tmpl +++ b/webskins/_default_/tmpl/LoginBar.tmpl @@ -1,5 +1,14 @@ - Logout + Logout + +   - Login + +
+ + User: + Pass: + +
+
diff --git a/webskins/_default_/tmpl/login.tmpl b/webskins/_default_/tmpl/login.tmpl new file mode 100644 index 00000000..1791267a --- /dev/null +++ b/webskins/_default_/tmpl/login.tmpl @@ -0,0 +1,17 @@ + +
+ + + + + + + + + + + + +
User:Password: 
   
+
+