Merge pull request #1814 from blendbyte/new-deny-options

New User Options: DenySetIdent, DenySetNetwork, DenySetRealName, DenySetQuitMsg, DenySetCTCPReplies

Close #1796
This commit is contained in:
Alexey Sokolov
2021-11-27 14:18:39 +00:00
committed by GitHub
10 changed files with 552 additions and 99 deletions
+121 -12
View File
@@ -94,6 +94,11 @@ class CAdminMod : public CModule {
{"MultiClients", boolean},
{"DenyLoadMod", boolean},
{"DenySetBindHost", boolean},
{"DenySetIdent", boolean},
{"DenySetNetwork", boolean},
{"DenySetRealName", boolean},
{"DenySetQuitMsg", boolean},
{"DenySetCTCPReplies", boolean},
{"DefaultChanModes", str},
{"QuitMsg", str},
{"ChanBufferSize", integer},
@@ -241,6 +246,16 @@ class CAdminMod : public CModule {
PutModule("DenyLoadMod = " + CString(pUser->DenyLoadMod()));
else if (sVar == "denysetbindhost")
PutModule("DenySetBindHost = " + CString(pUser->DenySetBindHost()));
else if (sVar == "denysetident")
PutModule("DenySetIdent = " + CString(pUser->DenySetIdent()));
else if (sVar == "denysetnetwork")
PutModule("DenySetNetwork = " + CString(pUser->DenySetNetwork()));
else if (sVar == "denysetrealname")
PutModule("DenySetRealName = " + CString(pUser->DenySetRealName()));
else if (sVar == "denysetquitmsg")
PutModule("DenySetQuitMsg = " + CString(pUser->DenySetQuitMsg()));
else if (sVar == "denysetctcpreplies")
PutModule("DenySetCTCPReplies = " + CString(pUser->DenySetCTCPReplies()));
else if (sVar == "defaultchanmodes")
PutModule("DefaultChanModes = " + pUser->GetDefaultChanModes());
else if (sVar == "quitmsg")
@@ -326,11 +341,19 @@ class CAdminMod : public CModule {
pUser->SetAltNick(sValue);
PutModule("AltNick = " + sValue);
} else if (sVar == "ident") {
pUser->SetIdent(sValue);
PutModule("Ident = " + sValue);
if (!pUser->DenySetIdent() || GetUser()->IsAdmin()) {
pUser->SetIdent(sValue);
PutModule("Ident = " + sValue);
} else {
PutModule(t_s("Access denied!"));
}
} else if (sVar == "realname") {
pUser->SetRealName(sValue);
PutModule("RealName = " + sValue);
if (!pUser->DenySetRealName() || GetUser()->IsAdmin()) {
pUser->SetRealName(sValue);
PutModule("RealName = " + sValue);
} else {
PutModule(t_s("Access denied!"));
}
} else if (sVar == "bindhost") {
if (!pUser->DenySetBindHost() || GetUser()->IsAdmin()) {
if (sValue.Equals(pUser->GetBindHost())) {
@@ -363,12 +386,56 @@ class CAdminMod : public CModule {
} else {
PutModule(t_s("Access denied!"));
}
} else if (sVar == "denysetident") {
if (GetUser()->IsAdmin()) {
bool b = sValue.ToBool();
pUser->SetDenySetIdent(b);
PutModule("DenySetIdent = " + CString(b));
} else {
PutModule(t_s("Access denied!"));
}
} else if (sVar == "denysetnetwork") {
if (GetUser()->IsAdmin()) {
bool b = sValue.ToBool();
pUser->SetDenySetNetwork(b);
PutModule("DenySetNetwork = " + CString(b));
} else {
PutModule(t_s("Access denied!"));
}
} else if (sVar == "denysetrealname") {
if (GetUser()->IsAdmin()) {
bool b = sValue.ToBool();
pUser->SetDenySetRealName(b);
PutModule("DenySetRealName = " + CString(b));
} else {
PutModule(t_s("Access denied!"));
}
} else if (sVar == "denysetquitmsg") {
if (GetUser()->IsAdmin()) {
bool b = sValue.ToBool();
pUser->SetDenySetQuitMsg(b);
PutModule("DenySetQuitMsg = " + CString(b));
} else {
PutModule(t_s("Access denied!"));
}
} else if (sVar == "denysetctcpreplies") {
if (GetUser()->IsAdmin()) {
bool b = sValue.ToBool();
pUser->SetDenySetCTCPReplies(b);
PutModule("DenySetCTCPReplies = " + CString(b));
} else {
PutModule(t_s("Access denied!"));
}
} else if (sVar == "defaultchanmodes") {
pUser->SetDefaultChanModes(sValue);
PutModule("DefaultChanModes = " + sValue);
} else if (sVar == "quitmsg") {
pUser->SetQuitMsg(sValue);
PutModule("QuitMsg = " + sValue);
if (!pUser->DenySetQuitMsg() || GetUser()->IsAdmin()) {
pUser->SetQuitMsg(sValue);
PutModule("QuitMsg = " + sValue);
} else {
PutModule(t_s("Access denied!"));
}
} else if (sVar == "chanbuffersize" || sVar == "buffercount") {
unsigned int i = sValue.ToUInt();
// Admins don't have to honour the buffer limit
@@ -614,11 +681,19 @@ class CAdminMod : public CModule {
pNetwork->SetAltNick(sValue);
PutModule("AltNick = " + pNetwork->GetAltNick());
} else if (sVar.Equals("ident")) {
pNetwork->SetIdent(sValue);
PutModule("Ident = " + pNetwork->GetIdent());
if (!pUser->DenySetIdent() || GetUser()->IsAdmin()) {
pNetwork->SetIdent(sValue);
PutModule("Ident = " + pNetwork->GetIdent());
} else {
PutModule(t_s("Access denied!"));
}
} else if (sVar.Equals("realname")) {
pNetwork->SetRealName(sValue);
PutModule("RealName = " + pNetwork->GetRealName());
if (!pUser->DenySetRealName() || GetUser()->IsAdmin()) {
pNetwork->SetRealName(sValue);
PutModule("RealName = " + pNetwork->GetRealName());
} else {
PutModule(t_s("Access denied!"));
}
} else if (sVar.Equals("bindhost")) {
if (!pUser->DenySetBindHost() || GetUser()->IsAdmin()) {
if (sValue.Equals(pNetwork->GetBindHost())) {
@@ -646,8 +721,12 @@ class CAdminMod : public CModule {
PutModule("Encoding = " + pNetwork->GetEncoding());
#endif
} else if (sVar.Equals("quitmsg")) {
pNetwork->SetQuitMsg(sValue);
PutModule("QuitMsg = " + pNetwork->GetQuitMsg());
if (!pUser->DenySetQuitMsg() || GetUser()->IsAdmin()) {
pNetwork->SetQuitMsg(sValue);
PutModule("QuitMsg = " + pNetwork->GetQuitMsg());
} else {
PutModule(t_s("Access denied!"));
}
} else if (sVar.Equals("trustallcerts")) {
bool b = sValue.ToBool();
pNetwork->SetTrustAllCerts(b);
@@ -1043,6 +1122,11 @@ class CAdminMod : public CModule {
return;
}
if (!GetUser()->IsAdmin() && pUser->DenySetNetwork()) {
PutModule(t_s("Access denied!"));
return;
}
if (!GetUser()->IsAdmin() && !pUser->HasSpaceForNewNetwork()) {
PutStatus(
t_s("Network number limit reached. Ask an admin to increase "
@@ -1088,6 +1172,11 @@ class CAdminMod : public CModule {
return;
}
if (!GetUser()->IsAdmin() && pUser->DenySetNetwork()) {
PutModule(t_s("Access denied!"));
return;
}
CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork);
if (!pNetwork) {
return;
@@ -1166,6 +1255,11 @@ class CAdminMod : public CModule {
CUser* pUser = FindUser(sUsername);
if (!pUser) return;
if (!GetUser()->IsAdmin() && pUser->DenySetNetwork()) {
PutModule(t_s("Access denied!"));
return;
}
CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork);
if (!pNetwork) {
return;
@@ -1197,6 +1291,11 @@ class CAdminMod : public CModule {
CUser* pUser = FindUser(sUsername);
if (!pUser) return;
if (!GetUser()->IsAdmin() && pUser->DenySetNetwork()) {
PutModule(t_s("Access denied!"));
return;
}
CIRCNetwork* pNetwork = FindNetwork(pUser, sNetwork);
if (!pNetwork) {
return;
@@ -1325,6 +1424,11 @@ class CAdminMod : public CModule {
CUser* pUser = FindUser(sUsername);
if (!pUser) return;
if (!GetUser()->IsAdmin() && pUser->DenySetCTCPReplies()) {
PutModule(t_s("Access denied!"));
return;
}
pUser->AddCTCPReply(sCTCPRequest, sCTCPReply);
if (sCTCPReply.empty()) {
PutModule(t_f("CTCP requests {1} to user {2} will now be blocked.")(
@@ -1347,6 +1451,11 @@ class CAdminMod : public CModule {
CUser* pUser = FindUser(sUsername);
if (!pUser) return;
if (!GetUser()->IsAdmin() && pUser->DenySetCTCPReplies()) {
PutModule(t_s("Access denied!"));
return;
}
if (sCTCPRequest.empty()) {
PutModule(t_s("Usage: DelCTCP [user] [request]"));
return;
+1
View File
@@ -21,3 +21,4 @@ table .reverse-sorted::after {
width: 400px;
}
table.networks[data-network-edit="0"] .network_delete { display: none; }
+46 -22
View File
@@ -121,18 +121,31 @@ function serverlist_init($) {
row.remove();
serialize();
}
row.append(
$("<td/>").append($("<input/>").attr({"type":"text"})
.addClass("servers_row_host").val(host)),
$("<td/>").append($("<input/>").attr({"type":"number"})
.addClass("servers_row_port").val(port)),
$("<td/>").append($("<input/>").attr({"type":"checkbox"})
.addClass("servers_row_ssl").prop("checked", ssl)),
$("<td/>").append($("<input/>").attr({"type":"text"})
.addClass("servers_row_pass").val(pass)),
$("<td/>").append($("<input/>").attr({"type":"button"})
.val("X").click(delete_row))
);
if (NetworkEdit) {
row.append(
$("<td/>").append($("<input/>").attr({"type":"text"})
.addClass("servers_row_host").val(host)),
$("<td/>").append($("<input/>").attr({"type":"number"})
.addClass("servers_row_port").val(port)),
$("<td/>").append($("<input/>").attr({"type":"checkbox"})
.addClass("servers_row_ssl").prop("checked", ssl)),
$("<td/>").append($("<input/>").attr({"type":"text"})
.addClass("servers_row_pass").val(pass)),
$("<td/>").append($("<input/>").attr({"type":"button"})
.val("X").click(delete_row))
);
} else {
row.append(
$("<td/>").append($("<input/>").attr({"type":"text","disabled":true})
.addClass("servers_row_host").val(host)),
$("<td/>").append($("<input/>").attr({"type":"number","disabled":true})
.addClass("servers_row_port").val(port)),
$("<td/>").append($("<input/>").attr({"type":"checkbox","disabled":true})
.addClass("servers_row_ssl").prop("checked", ssl)),
$("<td/>").append($("<input/>").attr({"type":"text","disabled":true})
.addClass("servers_row_pass").val(pass))
);
}
$("input", row).change(serialize);
$("#servers_tbody").append(row);
}
@@ -210,16 +223,27 @@ function ctcpreplies_init($) {
row.remove();
serialize();
}
row.append(
$("<td/>").append($("<input/>").val(request)
.addClass("ctcpreplies_row_request")
.attr({"type":"text","list":"ctcpreplies_list"})),
$("<td/>").append($("<input/>").val(response)
.addClass("ctcpreplies_row_response")
.attr({"type":"text","placeholder":$("#ctcpreplies_js").data("placeholder")})),
$("<td/>").append($("<input/>").val("X")
.attr({"type":"button"}).click(delete_row))
);
if (CTCPEdit) {
row.append(
$("<td/>").append($("<input/>").val(request)
.addClass("ctcpreplies_row_request")
.attr({"type":"text","list":"ctcpreplies_list"})),
$("<td/>").append($("<input/>").val(response)
.addClass("ctcpreplies_row_response")
.attr({"type":"text","placeholder":$("#ctcpreplies_js").data("placeholder")})),
$("<td/>").append($("<input/>").val("X")
.attr({"type":"button"}).click(delete_row))
);
} else {
row.append(
$("<td/>").append($("<input/>").val(request)
.addClass("ctcpreplies_row_request")
.attr({"type":"text","list":"ctcpreplies_list","disabled":true})),
$("<td/>").append($("<input/>").val(response)
.addClass("ctcpreplies_row_response")
.attr({"type":"text","placeholder":$("#ctcpreplies_js").data("placeholder"),"disabled":true})),
);
}
$("input", row).change(serialize);
$("#ctcpreplies_tbody").append(row);
}
@@ -3,6 +3,10 @@
<? AddRow CSSLoop HREF=/modfiles/global/webadmin/webadmin.css ?>
<? INC Header.tmpl ?>
<script>
var NetworkEdit = <? VAR NetworkEdit ?>;
</script>
<div class="section">
<? IF Edit ?>
<? SETBLOCK ClientConnectHint_Password ?><? VAR Username ?>/<? VAR Name ?>:<? FORMAT "&lt;password&gt;" ?><? ENDSETBLOCK ?>
@@ -28,7 +32,7 @@
<div class="subsection">
<div class="inputlabel"><label for="name"><? FORMAT "Network Name:" ?></label></div>
<input id="name" type="text" name="name" value="<? VAR Name ?>" class="half" maxlength="128"
title="<? FORMAT "The name of the IRC network." ?>"/>
title="<? FORMAT "The name of the IRC network." ?>" <? IF !NameEdit ?>disabled<? ENDIF ?> />
</div>
<div class="subsection">
@@ -45,12 +49,12 @@
<div class="subsection">
<div class="inputlabel"><label for="ident"><? FORMAT "Ident:" ?></label></div>
<input id="ident" type="text" name="ident" value="<? VAR Ident ?>" class="half" maxlength="128"
title="<? FORMAT "Your ident." ?>"/>
title="<? FORMAT "Your ident." ?>" <? IF !IdentEdit ?>disabled<? ENDIF ?> />
</div>
<div class="subsection">
<div class="inputlabel"><label for="realname"><? FORMAT "Realname:" ?></label></div>
<input id="realname" type="text" name="realname" value="<? VAR RealName ?>" class="full" maxlength="256"
title="<? FORMAT "Your real name." ?>"/>
title="<? FORMAT "Your real name." ?>" <? IF !RealNameEdit ?>disabled<? ENDIF ?> />
</div>
<? IF BindHostEdit ?>
@@ -64,7 +68,8 @@
<div class="subsection">
<div class="inputlabel"><label for="quitmsg"><? FORMAT "Quit Message:" ?></label></div>
<input id="quitmsg" type="text" name="quitmsg" value="<? VAR QuitMsg ?>" class="full" maxlength="256"
title="<? FORMAT "You may define a Message shown, when you quit IRC." ?>"/>
title="<? FORMAT "You may define a Message shown, when you quit IRC." ?>"
<? IF !QuitMsgEdit ?>disabled<? ENDIF ?> />
</div>
<div class="subsection">
@@ -87,7 +92,7 @@
<div class="subsection half" id="servers_plain">
<div class="inputlabel"><label for="servers_text"><? FORMAT "Servers of this IRC network:" ?></servers></div>
<div><textarea name="servers" cols="70" rows="5" id="servers_text"><? LOOP ServerLoop ?><? VAR Server ?>
<div><textarea name="servers" cols="70" rows="5" id="servers_text" <? IF !NetworkEdit ?>disabled<? ENDIF ?>><? LOOP ServerLoop ?><? VAR Server ?>
<? ENDLOOP ?>
</textarea></div>
<br/><span class="info"><? FORMAT "One server per line, “host [[+]port] [password]”, + means SSL" ?></span>
@@ -102,12 +107,16 @@
<th><? FORMAT "Port" ?></th>
<th><? FORMAT "SSL" ?></th>
<th><? FORMAT "Password" ?></th>
<? IF NetworkEdit ?>
<th/>
<? ENDIF ?>
</tr>
</thead>
<tbody id="servers_tbody"/>
</table>
<? IF NetworkEdit ?>
<input type="button" value="Add" id="servers_add"/>
<? ENDIF ?>
</div>
</div>
<script type="text/javascript">serverlist_init(jQuery);</script>
+32 -13
View File
@@ -3,6 +3,10 @@
<? AddRow CSSLoop HREF=/modfiles/global/webadmin/webadmin.css ?>
<? INC Header.tmpl ?>
<script>
var CTCPEdit = <? VAR CTCPEdit ?>;
</script>
<form action="<? VAR URIPrefix TOP ?><? VAR ModPath TOP ?><? IF Edit ?>edituser<? ELSE ?>adduser<? ENDIF ?>" method="post">
<? INC _csrf_check.tmpl ?>
<div class="section">
@@ -79,7 +83,8 @@
<div class="subsection">
<div class="inputlabel"><label for="ident"><? FORMAT "Ident:" ?></label></div>
<input id="ident" type="text" name="ident" value="<? VAR Ident ?>" class="half" maxlength="128"
title="<? FORMAT "The Ident is sent to server as username." ?>"/>
title="<? FORMAT "The Ident is sent to server as username." ?>"
<? IF !IdentEdit ?>disabled<? ENDIF ?> />
</div>
<div class="subsection">
<div class="inputlabel"><label for="statusprefix"><? FORMAT "Status Prefix:" ?></label></div>
@@ -90,7 +95,7 @@
<div class="subsection">
<div class="inputlabel"><label for="realname"><? FORMAT "Realname:" ?></label></div>
<input id="realname" type="text" name="realname" value="<? VAR RealName ?>" class="full" maxlength="256"
title="<? FORMAT "Your real name." ?>"/>
title="<? FORMAT "Your real name." ?>" <? IF !RealNameEdit ?>disabled<? ENDIF ?> />
</div>
<div style="clear: both;"></div>
@@ -111,7 +116,8 @@
<div class="subsection">
<div class="inputlabel"><label for="quitmsg"><? FORMAT "Quit Message:" ?></label></div>
<input type="text" name="quitmsg" value="<? VAR QuitMsg ?>" class="full" maxlength="256"
title="<? FORMAT "You may define a Message shown, when you quit IRC." ?>"/>
title="<? FORMAT "You may define a Message shown, when you quit IRC." ?>"
<? IF !QuitMsgEdit ?>disabled<? ENDIF ?> />
</div>
<div style="clear: both;"></div>
</div>
@@ -123,36 +129,47 @@
<? IF Edit ?>
<div class="sectionbg">
<div class="sectionbody">
<table class="sortable">
<? IF !NetworkEdit && !NetworkLoop ?>
<? FORMAT "No networks have been added for you yet." ?>
<? ELSE ?>
<table class="sortable networks" data-network-edit="<? IF NetworkEdit ?>1<? ELSE ?>0<? ENDIF ?>">
<thead>
<tr>
<td class="ignore-sort">[<a href="<? VAR URIPrefix TOP ?><? VAR ModPath TOP ?>addnetwork?user=<? VAR Username ESC=URL ?>"><? FORMAT "Add" ?></a>]</td>
<? IF NetworkLoop ?>
<td class="ignore-sort">
<? IF NetworkEdit ?>
[<a href="<? VAR URIPrefix TOP ?><? VAR ModPath TOP ?>addnetwork?user=<? VAR Username ESC=URL ?>"><? FORMAT "Add" ?></a>]
<? ELSE ?>
&nbsp;
<? ENDIF ?>
</td>
<? IF NetworkLoop ?>
<th><? FORMAT "Name" ?></th>
<th><? FORMAT "Clients" ?></th>
<th><? FORMAT "Current Server" ?></th>
<th><? FORMAT "Nick" ?></th>
<? ELSE ?>
<td><? FORMAT "← Add a network (opens in same page)" ?></td>
<? ENDIF ?>
<? ENDIF ?>
</tr>
</thead>
<tbody>
<? LOOP NetworkLoop SORTASC=Name ?>
<? LOOP NetworkLoop SORTASC=Name ?>
<tr class="<? IF __EVEN__ ?>evenrow<? ELSE ?>oddrow<? ENDIF ?>">
<td>
<input type="hidden" name="network" value="<? VAR Name ?>" />
[<a href="<? VAR URIPrefix TOP ?><? VAR ModPath TOP ?>editnetwork?user=<? VAR Username ESC=URL ?>&amp;network=<? VAR Name ESC=URL ?>"><? FORMAT "Edit" ?></a>] [<a href="<? VAR URIPrefix TOP ?><? VAR ModPath TOP ?>delnetwork?user=<? VAR Username ESC=URL ?>&amp;name=<? VAR Name ESC=URL ?>"><? FORMAT "Del" ?></a>]
<span class="network_edit">[<a href="<? VAR URIPrefix TOP ?><? VAR ModPath TOP ?>editnetwork?user=<? VAR Username ESC=URL ?>&amp;network=<? VAR Name ESC=URL ?>"><? FORMAT "Edit" ?></a>]</span>
<span class="network_delete">[<a href="<? VAR URIPrefix TOP ?><? VAR ModPath TOP ?>delnetwork?user=<? VAR Username ESC=URL ?>&amp;name=<? VAR Name ESC=URL ?>"><? FORMAT "Del" ?></a>]</span>
</td>
<td><? VAR Name ?></td>
<td><? VAR Clients ?></td>
<td><? VAR Server DEFAULT="-N/A-" ?></td>
<td><? VAR IRCNick ?></td>
</tr>
<? ENDLOOP ?>
<? ENDLOOP ?>
</tbody>
</table>
<? ENDIF ?>
</div>
</div>
<? ELSE ?>
@@ -202,7 +219,7 @@
checked="checked"
<? ENDIF ?>
disabled="disabled"/>
<? ENDIF ?>
<? ENDIF ?>
</td>
<td class="center">
<? IF CanBeLoadedByNetwork ?>
@@ -332,7 +349,7 @@
<? SETBLOCK Substitutions_Link ?><a href="https://wiki.znc.in/ExpandString" target="_blank" class="external"><? FORMAT "Substitutions" ?></a><? ENDSETBLOCK ?>
<div class="subsection half" id="ctcpreplies_plain">
<div class="inputlabel"><label for="ctcpreplies_text"><? FORMAT "CTCP Replies:" ?></label></div>
<div><textarea name="ctcpreplies" cols="70" rows="3" id="ctcpreplies_text"><? LOOP CTCPLoop ?><? VAR CTCP ?>
<div><textarea name="ctcpreplies" cols="70" rows="3" id="ctcpreplies_text" <? IF !CTCPEdit ?>disabled<? ENDIF ?>><? LOOP CTCPLoop ?><? VAR CTCP ?>
<? ENDLOOP ?>
</textarea></div>
<br /><span class="info"><? FORMAT "One reply per line. Example: <code>TIME Buy a watch!</code>" ?></span>
@@ -346,12 +363,14 @@
<tr>
<th><? FORMAT "Request" ?></th>
<th><? FORMAT "Response" ?></th>
<? IF CTCPEdit ?>
<th/>
<? ENDIF ?>
</tr>
</thead>
<tbody id="ctcpreplies_tbody"/>
</table>
<input type="button" value="<? FORMAT "Add" ?>" id="ctcpreplies_add"/>
<? IF CTCPEdit ?><input type="button" value="<? FORMAT "Add" ?>" id="ctcpreplies_add"/><? ENDIF ?>
<span class="info"><? FORMAT "{1} are available" "Substitutions_Link ESC=" ?></span>
<datalist id="ctcpreplies_list">
<option value="PING"/>
+186 -47
View File
@@ -231,9 +231,11 @@ class CWebAdminMod : public CModule {
}
WebSock.GetRawParam("ctcpreplies").Split("\n", vsArgs);
for (const CString& sReply : vsArgs) {
pNewUser->AddCTCPReply(sReply.Token(0).Trim_n(),
sReply.Token(1, true).Trim_n());
if (spSession->IsAdmin() || !spSession->GetUser()->DenySetCTCPReplies()) {
for (const CString& sReply : vsArgs) {
pNewUser->AddCTCPReply(sReply.Token(0).Trim_n(),
sReply.Token(1, true).Trim_n());
}
}
sArg = WebSock.GetParam("nick");
@@ -249,16 +251,28 @@ class CWebAdminMod : public CModule {
pNewUser->SetStatusPrefix(sArg);
}
sArg = WebSock.GetParam("ident");
if (!sArg.empty()) {
pNewUser->SetIdent(sArg);
if (spSession->IsAdmin() || !spSession->GetUser()->DenySetIdent()) {
if (!sArg.empty()) {
pNewUser->SetIdent(sArg);
}
} else if (pUser) {
pNewUser->SetIdent(pUser->GetIdent());
}
sArg = WebSock.GetParam("realname");
if (!sArg.empty()) {
pNewUser->SetRealName(sArg);
if (spSession->IsAdmin() || !spSession->GetUser()->DenySetRealName()) {
if (!sArg.empty()) {
pNewUser->SetRealName(sArg);
}
} else if (pUser) {
pNewUser->SetRealName(pUser->GetRealName());
}
sArg = WebSock.GetParam("quitmsg");
if (!sArg.empty()) {
pNewUser->SetQuitMsg(sArg);
if (spSession->IsAdmin() || !spSession->GetUser()->DenySetQuitMsg()) {
if (!sArg.empty()) {
pNewUser->SetQuitMsg(sArg);
}
} else if (pUser) {
pNewUser->SetQuitMsg(pUser->GetQuitMsg());
}
sArg = WebSock.GetParam("chanmodes");
if (!sArg.empty()) {
@@ -353,6 +367,16 @@ class CWebAdminMod : public CModule {
pNewUser->SetDenyLoadMod(WebSock.GetParam("denyloadmod").ToBool());
pNewUser->SetDenySetBindHost(
WebSock.GetParam("denysetbindhost").ToBool());
pNewUser->SetDenySetIdent(
WebSock.GetParam("denysetident").ToBool());
pNewUser->SetDenySetNetwork(
WebSock.GetParam("denysetnetwork").ToBool());
pNewUser->SetDenySetRealName(
WebSock.GetParam("denysetrealname").ToBool());
pNewUser->SetDenySetQuitMsg(
WebSock.GetParam("denysetquitmsg").ToBool());
pNewUser->SetDenySetCTCPReplies(
WebSock.GetParam("denysetctcpreplies").ToBool());
pNewUser->SetAuthOnlyViaModule(
WebSock.GetParam("authonlyviamodule").ToBool());
sArg = WebSock.GetParam("maxnetworks");
@@ -360,6 +384,11 @@ class CWebAdminMod : public CModule {
} else if (pUser) {
pNewUser->SetDenyLoadMod(pUser->DenyLoadMod());
pNewUser->SetDenySetBindHost(pUser->DenySetBindHost());
pNewUser->SetDenySetIdent(pUser->DenySetIdent());
pNewUser->SetDenySetNetwork(pUser->DenySetNetwork());
pNewUser->SetDenySetRealName(pUser->DenySetRealName());
pNewUser->SetDenySetQuitMsg(pUser->DenySetQuitMsg());
pNewUser->SetDenySetCTCPReplies(pUser->DenySetCTCPReplies());
pNewUser->SetAuthOnlyViaModule(pUser->AuthOnlyViaModule());
pNewUser->SetMaxNetworks(pUser->MaxNetworks());
}
@@ -514,11 +543,16 @@ class CWebAdminMod : public CModule {
return false;
}
if (pUser) {
if (!pUser) {
WebSock.PrintErrorPage(t_s("No such user"));
return true;
}
if (spSession->IsAdmin() || !spSession->GetUser()->DenySetNetwork()) {
return NetworkPage(WebSock, Tmpl, pUser);
}
WebSock.PrintErrorPage(t_s("No such user"));
WebSock.PrintErrorPage(t_s("Permission denied"));
return true;
} else if (sPageName == "editnetwork") {
CIRCNetwork* pNetwork = SafeGetNetworkFromParam(WebSock);
@@ -551,7 +585,12 @@ class CWebAdminMod : public CModule {
return false;
}
return DelNetwork(WebSock, pUser, Tmpl);
if (spSession->IsAdmin() || !spSession->GetUser()->DenySetNetwork()) {
return DelNetwork(WebSock, pUser, Tmpl);
}
WebSock.PrintErrorPage(t_s("Permission denied"));
return true;
} else if (sPageName == "editchan") {
CIRCNetwork* pNetwork = SafeGetNetworkFromParam(WebSock);
@@ -882,6 +921,11 @@ class CWebAdminMod : public CModule {
std::shared_ptr<CWebSession> spSession = WebSock.GetSession();
Tmpl.SetFile("add_edit_network.tmpl");
if (!pNetwork && !spSession->IsAdmin() && pUser->DenySetNetwork()) {
WebSock.PrintErrorPage(t_s("Permission denied"));
return true;
}
if (!pNetwork && !spSession->IsAdmin() &&
!pUser->HasSpaceForNewNetwork()) {
WebSock.PrintErrorPage(t_s(
@@ -973,14 +1017,36 @@ class CWebAdminMod : public CModule {
breadUser["URL"] =
GetWebPath() + "edituser?user=" + pUser->GetUsername();
Tmpl["Name"] = pNetwork->GetName();
if (spSession->IsAdmin() ||
!spSession->GetUser()->DenySetNetwork()) {
Tmpl["NameEdit"] = "true";
}
Tmpl["Name"] = pNetwork->GetName();
Tmpl["Nick"] = pNetwork->GetNick();
Tmpl["AltNick"] = pNetwork->GetAltNick();
Tmpl["Ident"] = pNetwork->GetIdent();
Tmpl["RealName"] = pNetwork->GetRealName();
Tmpl["QuitMsg"] = pNetwork->GetQuitMsg();
if (spSession->IsAdmin() ||
!spSession->GetUser()->DenySetIdent()) {
Tmpl["IdentEdit"] = "true";
Tmpl["Ident"] = pNetwork->GetIdent();
}
if (spSession->IsAdmin() ||
!spSession->GetUser()->DenySetRealName()) {
Tmpl["RealNameEdit"] = "true";
Tmpl["RealName"] = pNetwork->GetRealName();
}
if (spSession->IsAdmin() ||
!spSession->GetUser()->DenySetQuitMsg()) {
Tmpl["QuitMsgEdit"] = "true";
Tmpl["QuitMsg"] = pNetwork->GetQuitMsg();
}
Tmpl["NetworkEdit"] =
spSession->IsAdmin() || !spSession->GetUser()->DenySetNetwork()
? "true" : "false";
Tmpl["FloodProtection"] =
CString(CIRCSock::IsFloodProtected(pNetwork->GetFloodRate()));
@@ -1077,22 +1143,24 @@ class CWebAdminMod : public CModule {
WebSock.PrintErrorPage(t_s("Network name is a required argument"));
return true;
}
if (!pNetwork || pNetwork->GetName() != sName) {
CString sNetworkAddError;
CIRCNetwork* pOldNetwork = pNetwork;
pNetwork = pUser->AddNetwork(sName, sNetworkAddError);
if (!pNetwork) {
WebSock.PrintErrorPage(sNetworkAddError);
return true;
}
if (pOldNetwork) {
for (CModule* pModule : pOldNetwork->GetModules()) {
CString sPath = pUser->GetUserPath() + "/networks/" +
sName + "/moddata/" + pModule->GetModName();
pModule->MoveRegistry(sPath);
if (spSession->IsAdmin() || !spSession->GetUser()->DenySetNetwork()) {
if (!pNetwork || pNetwork->GetName() != sName) {
CString sNetworkAddError;
CIRCNetwork* pOldNetwork = pNetwork;
pNetwork = pUser->AddNetwork(sName, sNetworkAddError);
if (!pNetwork) {
WebSock.PrintErrorPage(sNetworkAddError);
return true;
}
if (pOldNetwork) {
for (CModule* pModule : pOldNetwork->GetModules()) {
CString sPath = pUser->GetUserPath() + "/networks/" +
sName + "/moddata/" + pModule->GetModName();
pModule->MoveRegistry(sPath);
}
pNetwork->Clone(*pOldNetwork, false);
pUser->DeleteNetwork(pOldNetwork->GetName());
}
pNetwork->Clone(*pOldNetwork, false);
pUser->DeleteNetwork(pOldNetwork->GetName());
}
}
@@ -1100,10 +1168,18 @@ class CWebAdminMod : public CModule {
pNetwork->SetNick(WebSock.GetParam("nick"));
pNetwork->SetAltNick(WebSock.GetParam("altnick"));
pNetwork->SetIdent(WebSock.GetParam("ident"));
pNetwork->SetRealName(WebSock.GetParam("realname"));
pNetwork->SetQuitMsg(WebSock.GetParam("quitmsg"));
if (spSession->IsAdmin() || !spSession->GetUser()->DenySetIdent()) {
pNetwork->SetIdent(WebSock.GetParam("ident"));
}
if (spSession->IsAdmin() || !spSession->GetUser()->DenySetRealName()) {
pNetwork->SetRealName(WebSock.GetParam("realname"));
}
if (spSession->IsAdmin() || !spSession->GetUser()->DenySetQuitMsg()) {
pNetwork->SetQuitMsg(WebSock.GetParam("quitmsg"));
}
pNetwork->SetIRCConnectEnabled(WebSock.GetParam("doconnect").ToBool());
@@ -1145,10 +1221,12 @@ class CWebAdminMod : public CModule {
VCString vsArgs;
pNetwork->DelServers();
WebSock.GetRawParam("servers").Split("\n", vsArgs);
for (const CString& sServer : vsArgs) {
pNetwork->AddServer(sServer.Trim_n());
if (spSession->IsAdmin() || !spSession->GetUser()->DenySetNetwork()) {
pNetwork->DelServers();
WebSock.GetRawParam("servers").Split("\n", vsArgs);
for (const CString& sServer : vsArgs) {
pNetwork->AddServer(sServer.Trim_n());
}
}
WebSock.GetRawParam("fingerprints").Split("\n", vsArgs);
@@ -1347,9 +1425,33 @@ class CWebAdminMod : public CModule {
Tmpl["Nick"] = pUser->GetNick();
Tmpl["AltNick"] = pUser->GetAltNick();
Tmpl["StatusPrefix"] = pUser->GetStatusPrefix();
Tmpl["Ident"] = pUser->GetIdent();
Tmpl["RealName"] = pUser->GetRealName();
Tmpl["QuitMsg"] = pUser->GetQuitMsg();
if (spSession->IsAdmin() ||
!spSession->GetUser()->DenySetIdent()) {
Tmpl["IdentEdit"] = "true";
Tmpl["Ident"] = pUser->GetIdent();
}
if (spSession->IsAdmin() ||
!spSession->GetUser()->DenySetRealName()) {
Tmpl["RealNameEdit"] = "true";
Tmpl["RealName"] = pUser->GetRealName();
}
if (spSession->IsAdmin() ||
!spSession->GetUser()->DenySetQuitMsg()) {
Tmpl["QuitMsgEdit"] = "true";
Tmpl["QuitMsg"] = pUser->GetQuitMsg();
}
Tmpl["NetworkEdit"] =
spSession->IsAdmin() || !spSession->GetUser()->DenySetNetwork()
? "true" : "false";
Tmpl["CTCPEdit"] =
spSession->IsAdmin() || !spSession->GetUser()->DenySetCTCPReplies()
? "true" : "false";
Tmpl["DefaultChanModes"] = pUser->GetDefaultChanModes();
Tmpl["ChanBufferSize"] = CString(pUser->GetChanBufferSize());
Tmpl["QueryBufferSize"] = CString(pUser->GetQueryBufferSize());
@@ -1569,19 +1671,56 @@ class CWebAdminMod : public CModule {
CTemplate& o11 = Tmpl.AddRow("OptionLoop");
o11["Name"] = "denysetbindhost";
o11["DisplayName"] = t_s("Deny SetBindHost");
o11["DisplayName"] = t_s("Deny Setting BindHost");
if (pUser->DenySetBindHost()) {
o11["Checked"] = "true";
}
CTemplate& o12 = Tmpl.AddRow("OptionLoop");
o12["Name"] = "denysetident";
o12["DisplayName"] = t_s("Deny Setting Ident");
if (pUser->DenySetIdent()) {
o12["Checked"] = "true";
}
CTemplate& o13 = Tmpl.AddRow("OptionLoop");
o13["Name"] = "denysetnetwork";
o13["DisplayName"] = t_s("Deny Editing Networks/Servers");
o13["Tooltip"] =
t_s("Deny adding/deleting networks, setting network name and editing the server list");
if (pUser->DenySetNetwork()) {
o13["Checked"] = "true";
}
CTemplate& o14 = Tmpl.AddRow("OptionLoop");
o14["Name"] = "denysetrealname";
o14["DisplayName"] = t_s("Deny Setting RealName");
if (pUser->DenySetRealName()) {
o14["Checked"] = "true";
}
CTemplate& o15 = Tmpl.AddRow("OptionLoop");
o15["Name"] = "denysetquitmsg";
o15["DisplayName"] = t_s("Deny Setting Quit Message");
if (pUser->DenySetQuitMsg()) {
o15["Checked"] = "true";
}
CTemplate& o16 = Tmpl.AddRow("OptionLoop");
o16["Name"] = "denysetctcpreplies";
o16["DisplayName"] = t_s("Deny Setting CTCP Replies");
if (pUser->DenySetCTCPReplies()) {
o16["Checked"] = "true";
}
}
CTemplate& o12 = Tmpl.AddRow("OptionLoop");
o12["Name"] = "autoclearquerybuffer";
o12["DisplayName"] = t_s("Auto Clear Query Buffer");
o12["Tooltip"] =
CTemplate& o17 = Tmpl.AddRow("OptionLoop");
o17["Name"] = "autoclearquerybuffer";
o17["DisplayName"] = t_s("Auto Clear Query Buffer");
o17["Tooltip"] =
t_s("Automatically Clear Query Buffer After Playback");
if (pUser->AutoClearQueryBuffer()) {
o12["Checked"] = "true";
o17["Checked"] = "true";
}
FOR_EACH_MODULE(i, pUser) {