Merge some work by Jens-Andre Koch

Only his changes to the core are presented here.
Unfortunately, the skin itself looks ugly on Opera,
and simply doesn't work on Firefox...

Merge branch 'master' into znc-ation

Conflicts:
	modules/data/lastseen/tmpl/lastseen_WebadminUser.tmpl
	modules/data/webadmin/tmpl/settings.tmpl
This commit is contained in:
Alexey Sokolov
2012-04-10 23:10:36 +07:00
38 changed files with 272 additions and 1542 deletions
+1 -1
View File
@@ -25,7 +25,7 @@
<table class="data">
<thead>
<tr>
<td style="width: 10px;"></td>
<td></td>
<td>Key</td>
</tr>
</thead>
@@ -1,9 +1,8 @@
<div class="sectionbg">
<div class="sectionbody">
<div class="subsection">
<div class="inputlabel">Last login time:</div>
<p><? VAR LastSeen DEFAULT="- unknown -" ?></p>
<label id="last_login">Last login time:</label>
<span id="lastseen"><? VAR LastSeen DEFAULT="- unknown -" ?></span>
</div>
<div style="clear:both;"></div>
</div>
</div>
+13
View File
@@ -0,0 +1,13 @@
function floodprotection_change() {
var protection = document.getElementById('floodprotection_checkbox');
var rate = document.getElementById('floodrate');
var burst = document.getElementById('floodburst');
if (protection.checked) {
rate.removeAttribute('disabled');
burst.removeAttribute('disabled');
} else {
rate.disabled = 'disabled';
burst.disabled = 'disabled';
}
}
@@ -1,3 +1,4 @@
<? AddRow JSLoop HREF=/modfiles/global/webadmin/webadmin.js ?>
<? INC Header.tmpl ?>
<? IF Edit ?>
@@ -61,20 +62,6 @@
<br /><span class="info">One server per line, host [[+]port] [password]</span>
</div>
<script type="text/javascript">
function floodprotection_change() {
var protection = document.getElementById('floodprotection_checkbox');
var rate = document.getElementById('floodrate');
var burst = document.getElementById('floodburst');
if (protection.checked) {
rate.removeAttribute('disabled');
burst.removeAttribute('disabled');
} else {
rate.disabled = 'disabled';
burst.disabled = 'disabled';
}
}
</script>
<div class="subsection">
<div class="inputlabel">Flood protection:</div>
<div class="checkbox">
@@ -126,7 +113,7 @@
<td>BufferCount</td>
<td>Options</td>
<? ELSE ?>
<td>&nbsp;&nbsp;&lt;- Add a channel (opens in same page)&nbsp;&nbsp;</td>
<td>&lt;- Add a channel (opens in same page)</td>
<? ENDIF ?>
</tr>
</thead>
@@ -173,7 +160,13 @@
<input type="checkbox" name="loadmod" id="lm_<? VAR Name ?>" value="<? VAR Name ?>"<? IF Checked ?> checked="checked"<? ENDIF ?><? IF Disabled ?> disabled="disabled"<? ENDIF ?> /><label for="lm_<? VAR Name ?>"> <? IF Wiki ?><a href="http://wiki.znc.in/<? VAR Wiki ?>"><? VAR Name ?></a> <? ELSE ?> <? VAR Name ?> <? ENDIF ?></label>
</td>
<td class="mod_args">
<? IF Disabled ?><? VAR Args ?><? ELSE ?><input class="third" type="text" name="modargs_<? VAR Name ?>" value="<? VAR Args ?>" /><? ENDIF ?>
<? IF Disabled ?>
<? VAR Args ?>
<? ELSE ?>
<input class="third" type="text" name="modargs_<? VAR Name ?>" value="<? VAR Args ?>"
<? IF !HasArgs ?> disabled="disabled"<? ENDIF ?>
<? IF ArgsHelpText ?> title="<? VAR ArgsHelpText ?>"<? ENDIF ?> />
<? ENDIF ?>
</td>
<td class="mod_descr"><? VAR Description ?></td>
</tr>
+19 -13
View File
@@ -82,27 +82,33 @@
</div>
<div style="clear: both;"></div>
<? IF BindHostLoop ?>
<? IF BindHostEdit ?>
<div class="subsection">
<div class="inputlabel">BindHost:</div>
<select name="bindhost">
<option value="">- Default -</option>
<? LOOP BindHostLoop ?><option value="<? VAR BindHost ?>"<? IF Checked ?> selected="selected"<? ENDIF ?>><? VAR BindHost ?></option><? ENDLOOP ?>
</select>
<? IF BindHostLoop ?>
<select name="bindhost">
<option value="">- Default -</option>
<? LOOP BindHostLoop ?><option value="<? VAR BindHost ?>"<? IF Checked ?> selected="selected"<? ENDIF ?>><? VAR BindHost ?></option><? ENDLOOP ?>
</select>
<? ELSE ?>
<input type="text" name="bindhost" value="<? VAR BindHost ?>"/>
<? ENDIF ?>
</div>
<div style="clear: both;"></div>
<? ENDIF ?>
<? IF DCCBindHostLoop ?>
<div class="subsection">
<div class="inputlabel">DCCBindHost:</div>
<select name="dccbindhost">
<option value="">- Default -</option>
<? LOOP DCCBindHostLoop ?><option value="<? VAR BindHost ?>"<? IF Checked ?> selected="selected"<? ENDIF ?>><? VAR BindHost ?></option><? ENDLOOP ?>
</select>
<? IF DCCBindHostLoop ?>
<select name="dccbindhost">
<option value="">- Default -</option>
<? LOOP DCCBindHostLoop ?><option value="<? VAR BindHost ?>"<? IF Checked ?> selected="selected"<? ENDIF ?>><? VAR BindHost ?></option><? ENDLOOP ?>
</select>
<? ELSE ?>
<input type="text" name="dccbindhost" value="<? VAR DCCBindHost ?>"/>
<? ENDIF ?>
</div>
<div style="clear: both;"></div>
<? ENDIF ?>
<? ENDIF ?>
<div class="subsection">
<div class="inputlabel">Quit Message:</div>
@@ -126,7 +132,7 @@
<? IF NetworkLoop ?>
<td>Name</td>
<? ELSE ?>
<td>&nbsp;&nbsp;&lt;- Add a network (opens in same page)&nbsp;&nbsp;</td>
<td>&lt;- Add a network (opens in same page)</td>
<? ENDIF ?>
</tr>
</thead>
+55 -30
View File
@@ -9,36 +9,61 @@
<div class="sectionbg">
<div class="sectionbody">
<div class="subsection">
<table>
<thead>
<tr>
<td>Port</td>
<td>BindHost</td>
<td>SSL</td>
<td>IPv4</td>
<td>IPv6</td>
<td>IRC</td>
<td>Web</td>
</tr>
</thead>
<tbody>
<? LOOP ListenLoop ?>
<tr class="<? IF __EVEN__ ?>evenrow<? ELSE ?>oddrow<? ENDIF ?>">
<td><? VAR Port ?></td>
<td><? VAR BindHost DEFAULT=** ?></td>
<td><? IF IsSSL ?>Yes<? ELSE ?>No<? ENDIF ?></td>
<td><? IF IsIPV4 ?>Yes<? ELSE ?>No<? ENDIF ?></td>
<td><? IF IsIPV6 ?>Yes<? ELSE ?>No<? ENDIF ?></td>
<td><? IF IsIRC ?>Yes<? ELSE ?>No<? ENDIF ?></td>
<td><? IF IsWeb ?>Yes<? ELSE ?>No<? ENDIF ?></td>
</tr>
<? ENDLOOP ?>
</tbody>
</table>
<div>
<form action="add_listener" method="post">
<table>
<thead>
<tr>
<td>Port</td>
<td>BindHost</td>
<td>SSL</td>
<td>IPv4</td>
<td>IPv6</td>
<td>IRC</td>
<td>Web</td>
<td/>
</tr>
</thead>
<tbody>
<? LOOP ListenLoop ?>
<tr class="<? IF __EVEN__ ?>evenrow<? ELSE ?>oddrow<? ENDIF ?>">
<td><? VAR Port ?></td>
<td><? VAR BindHost DEFAULT=** ?></td>
<td><div class="checkbox"><input type="checkbox" disabled="disabled" <? IF IsSSL ?>checked="checked"<? ENDIF ?>/></div></td>
<td><div class="checkbox"><input type="checkbox" disabled="disabled" <? IF IsIPV4 ?>checked="checked"<? ENDIF ?>/></div></td>
<td><div class="checkbox"><input type="checkbox" disabled="disabled" <? IF IsIPV6 ?>checked="checked"<? ENDIF ?>/></div></td>
<td><div class="checkbox"><input type="checkbox" disabled="disabled" <? IF IsIRC ?>checked="checked"<? ENDIF ?>/></div></td>
<td><div class="checkbox"><input type="checkbox" disabled="disabled" <? IF IsWeb ?>checked="checked"<? ENDIF ?>/></div></td>
<td>
<? IF SuggestDeletion ?>
<form action="del_listener" method="post">
<? INC _csrf_check.tmpl ?>
<input name="host" type="hidden" value="<? VAR BindHost ?>"/>
<input name="port" type="hidden" value="<? VAR Port ?>"/>
<input name="ipv4" type="hidden" value="<? VAR IsIPV4 ?>"/>
<input name="ipv6" type="hidden" value="<? VAR IsIPV6 ?>"/>
<input type="submit" value="Del"/>
</form>
<? ENDIF ?>
</td>
</tr>
<? ENDLOOP ?>
<tr>
<? INC _csrf_check.tmpl ?>
<td><input name="port" type="number" min="1" max="65535" class="number"/></td>
<td><input name="host" type="text" value="*" class="third"/></td>
<td><div class="checkbox"><input name="ssl" type="checkbox"/></div></td>
<td><div class="checkbox"><input name="ipv4" type="checkbox" checked="checked"/></div></td>
<td><div class="checkbox"><input name="ipv6" type="checkbox" checked="checked"/></div></td>
<td><div class="checkbox"><input name="irc" type="checkbox" checked="checked"/></div></td>
<td><div class="checkbox"><input name="web" type="checkbox" checked="checked"/></div></td>
<td><input type="submit" value="Add"/></td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
</div>
</div>
</div>
@@ -167,4 +192,4 @@
</div>
</form>
<? INC Footer.tmpl ?>
<? INC Footer.tmpl ?>
+1 -1
View File
@@ -134,7 +134,7 @@ void CIMAPSock::ReadLine(const CString& sLine) {
}
Write("AUTH LOGIN " + sUsername + " " + m_spAuth->GetPassword() + "\r\n");
} else {
} else if (sLine.Left(5) == "AUTH ") {
CUser* pUser = CZNC::Get().FindUser(m_spAuth->GetUsername());
if (pUser && sLine.Equals("AUTH OK", false, 7)) {
+147 -27
View File
@@ -513,6 +513,20 @@ public:
return TrafficPage(WebSock, Tmpl);
} else if (sPageName == "index") {
return true;
} else if (sPageName == "add_listener") {
// Admin Check
if (!spSession->IsAdmin()) {
return false;
}
return AddListener(WebSock, Tmpl);
} else if (sPageName == "del_listener") {
// Admin Check
if (!spSession->IsAdmin()) {
return false;
}
return DelListener(WebSock, Tmpl);
}
return false;
@@ -955,41 +969,49 @@ public:
// To change BindHosts be admin or don't have DenySetBindHost
if (spSession->IsAdmin() || !spSession->GetUser()->DenySetBindHost()) {
Tmpl["BindHostEdit"] = "true";
const VCString& vsBindHosts = CZNC::Get().GetBindHosts();
bool bFoundBindHost = false;
bool bFoundDCCBindHost = false;
for (unsigned int b = 0; b < vsBindHosts.size(); b++) {
const CString& sBindHost = vsBindHosts[b];
CTemplate& l = Tmpl.AddRow("BindHostLoop");
CTemplate& k = Tmpl.AddRow("DCCBindHostLoop");
if (vsBindHosts.empty()) {
if (pUser) {
Tmpl["BindHost"] = pUser->GetBindHost();
Tmpl["DCCBindHost"] = pUser->GetDCCBindHost();
}
} else {
bool bFoundBindHost = false;
bool bFoundDCCBindHost = false;
for (unsigned int b = 0; b < vsBindHosts.size(); b++) {
const CString& sBindHost = vsBindHosts[b];
CTemplate& l = Tmpl.AddRow("BindHostLoop");
CTemplate& k = Tmpl.AddRow("DCCBindHostLoop");
l["BindHost"] = sBindHost;
k["BindHost"] = sBindHost;
l["BindHost"] = sBindHost;
k["BindHost"] = sBindHost;
if (pUser && pUser->GetBindHost() == sBindHost) {
if (pUser && pUser->GetBindHost() == sBindHost) {
l["Checked"] = "true";
bFoundBindHost = true;
}
if (pUser && pUser->GetDCCBindHost() == sBindHost) {
k["Checked"] = "true";
bFoundDCCBindHost = true;
}
}
// If our current bindhost is not in the global list...
if (pUser && !bFoundBindHost && !pUser->GetBindHost().empty()) {
CTemplate& l = Tmpl.AddRow("BindHostLoop");
l["BindHost"] = pUser->GetBindHost();
l["Checked"] = "true";
bFoundBindHost = true;
}
if (pUser && !bFoundDCCBindHost && !pUser->GetDCCBindHost().empty()) {
CTemplate& l = Tmpl.AddRow("DCCBindHostLoop");
if (pUser && pUser->GetDCCBindHost() == sBindHost) {
k["Checked"] = "true";
bFoundDCCBindHost = true;
l["BindHost"] = pUser->GetDCCBindHost();
l["Checked"] = "true";
}
}
// If our current bindhost is not in the global list...
if (pUser && !bFoundBindHost && !pUser->GetBindHost().empty()) {
CTemplate& l = Tmpl.AddRow("BindHostLoop");
l["BindHost"] = pUser->GetBindHost();
l["Checked"] = "true";
}
if (pUser && !bFoundDCCBindHost && !pUser->GetDCCBindHost().empty()) {
CTemplate& l = Tmpl.AddRow("DCCBindHostLoop");
l["BindHost"] = pUser->GetDCCBindHost();
l["Checked"] = "true";
}
}
vector<CString> vDirs;
@@ -1237,7 +1259,100 @@ public:
return true;
}
bool AddListener(CWebSock& WebSock, CTemplate& Tmpl) {
unsigned int uPort = WebSock.GetParam("port").ToUInt();
CString sHost = WebSock.GetParam("host");
if (sHost == "*") sHost = "";
bool bSSL = WebSock.GetParam("ssl").ToBool();
bool bIPv4 = WebSock.GetParam("ipv4").ToBool();
bool bIPv6 = WebSock.GetParam("ipv6").ToBool();
bool bIRC = WebSock.GetParam("irc").ToBool();
bool bWeb = WebSock.GetParam("web").ToBool();
EAddrType eAddr = ADDR_ALL;
if (bIPv4) {
if (bIPv6) {
eAddr = ADDR_ALL;
} else {
eAddr = ADDR_IPV4ONLY;
}
} else {
if (bIPv6) {
eAddr = ADDR_IPV6ONLY;
} else {
WebSock.GetSession()->AddError("Choose either IPv4 or IPv6 or both.");
return SettingsPage(WebSock, Tmpl);
}
}
CListener::EAcceptType eAccept;
if (bIRC) {
if (bWeb) {
eAccept = CListener::ACCEPT_ALL;
} else {
eAccept = CListener::ACCEPT_IRC;
}
} else {
if (bWeb) {
eAccept = CListener::ACCEPT_HTTP;
} else {
WebSock.GetSession()->AddError("Choose either IRC or Web or both.");
return SettingsPage(WebSock, Tmpl);
}
}
CString sMessage;
if (CZNC::Get().AddListener(uPort, sHost, bSSL, eAddr, eAccept, sMessage)) {
if (!sMessage.empty()) {
WebSock.GetSession()->AddSuccess(sMessage);
}
if (!CZNC::Get().WriteConfig()) {
WebSock.GetSession()->AddError("Port changed, but config was not written");
}
} else {
WebSock.GetSession()->AddError(sMessage);
}
return SettingsPage(WebSock, Tmpl);
}
bool DelListener(CWebSock& WebSock, CTemplate& Tmpl) {
unsigned int uPort = WebSock.GetParam("port").ToUInt();
CString sHost = WebSock.GetParam("host");
bool bIPv4 = WebSock.GetParam("ipv4").ToBool();
bool bIPv6 = WebSock.GetParam("ipv6").ToBool();
EAddrType eAddr = ADDR_ALL;
if (bIPv4) {
if (bIPv6) {
eAddr = ADDR_ALL;
} else {
eAddr = ADDR_IPV4ONLY;
}
} else {
if (bIPv6) {
eAddr = ADDR_IPV6ONLY;
} else {
WebSock.GetSession()->AddError("Invalid request.");
return SettingsPage(WebSock, Tmpl);
}
}
CListener* pListener = CZNC::Get().FindListener(uPort, sHost, eAddr);
if (pListener) {
CZNC::Get().DelListener(pListener);
if (!CZNC::Get().WriteConfig()) {
WebSock.GetSession()->AddError("Port changed, but config was not written");
}
} else {
WebSock.GetSession()->AddError("The specified listener was not found.");
}
return SettingsPage(WebSock, Tmpl);
}
bool SettingsPage(CWebSock& WebSock, CTemplate& Tmpl) {
Tmpl.SetFile("settings.tmpl");
if (!WebSock.GetParam("submitted").ToUInt()) {
CString sBindHosts, sMotd;
Tmpl["Action"] = "settings";
@@ -1272,6 +1387,11 @@ public:
l["IsWeb"] = CString(pListener->GetAcceptType() != CListener::ACCEPT_IRC);
l["IsIRC"] = CString(pListener->GetAcceptType() != CListener::ACCEPT_HTTP);
// simple protection for user from shooting his own foot
// TODO check also for hosts/families
// such check is only here, user still can forge HTTP request to delete web port
l["SuggestDeletion"] = CString(pListener->GetPort() != WebSock.GetLocalPort());
#ifdef HAVE_LIBSSL
if (pListener->IsSSL()) {
l["IsSSL"] = "true";