mirror of
https://github.com/znc/znc.git
synced 2026-06-29 14:31:19 +02:00
@@ -91,6 +91,7 @@ public:
|
||||
CString AddTimestamp(const CString& sStr) const;
|
||||
CString AddTimestamp(time_t tm, const CString& sStr) const;
|
||||
|
||||
void CloneNetworks(const CUser& User);
|
||||
bool Clone(const CUser& User, CString& sErrorRet, bool bCloneNetworks = true);
|
||||
void BounceAllClients();
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
<div class="subsection">
|
||||
<div class="inputlabel">Username:</div>
|
||||
<div>
|
||||
<? IF Clone ?>
|
||||
<input type="hidden" name="clone" value="<? VAR CloneUsername ?>" />
|
||||
<? ENDIF ?>
|
||||
<? IF Edit ?>
|
||||
<input type="hidden" name="user" value="<? VAR Username ?>" />
|
||||
<input type="text" name="newuser" value="<? VAR Username ?>" class="half" maxlength="128" disabled="disabled" />
|
||||
@@ -104,9 +107,7 @@
|
||||
|
||||
<div class="section">
|
||||
<h3>Networks</h3>
|
||||
<? IF !Edit ?>
|
||||
<span class="info">You will be able to add + modify networks here after you created the user.</span><br />
|
||||
<? ELSE ?>
|
||||
<? IF Edit ?>
|
||||
<div class="sectionbg">
|
||||
<div class="sectionbody">
|
||||
<table>
|
||||
@@ -135,6 +136,8 @@
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<? ELSE ?>
|
||||
<span class="info">You will be able to add + modify networks here after you <? IF Clone ?>have cloned<? ELSE ?>created<? ENDIF ?> the user.</span><br />
|
||||
<? ENDIF ?>
|
||||
</div>
|
||||
|
||||
@@ -261,7 +264,7 @@
|
||||
<? ENDLOOP ?>
|
||||
|
||||
<div class="submitline">
|
||||
<input type="submit" value="<? IF Edit ?>Save<? ELSE ?>Create<? ENDIF ?>" />
|
||||
<input type="submit" value="<? IF Edit ?>Save<? ELSE ?><? IF Clone ?>Clone<? ELSE ?>Create<? ENDIF ?><? ENDIF ?>" />
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
<td>
|
||||
<span class="nowrap">
|
||||
[<a href="edituser?user=<?VAR Username ESC=URL?>">Edit</a>]
|
||||
[<a href="adduser?clone=<? VAR Username ESC=URL ?>" alt="Clone <? VAR Username ESC=URL ?>">Clone</a>]
|
||||
<? IF !IsSelf ?>[<a href="deluser?user=<?VAR Username ESC=URL?>">Delete</a>]<? ENDIF ?>
|
||||
</span>
|
||||
</td>
|
||||
|
||||
@@ -865,6 +865,18 @@ public:
|
||||
Tmpl["Action"] = "edituser";
|
||||
Tmpl["Title"] = "Edit User [" + pUser->GetUserName() + "]";
|
||||
Tmpl["Edit"] = "true";
|
||||
} else {
|
||||
CString sUsername = WebSock.GetParam("clone", false);
|
||||
pUser = CZNC::Get().FindUser(sUsername);
|
||||
|
||||
if (pUser) {
|
||||
Tmpl["Title"] = "Clone User [" + pUser->GetUserName() + "]";
|
||||
Tmpl["Clone"] = "true";
|
||||
Tmpl["CloneUsername"] = pUser->GetUserName();
|
||||
}
|
||||
}
|
||||
|
||||
if (pUser) {
|
||||
Tmpl["Username"] = pUser->GetUserName();
|
||||
Tmpl["Nick"] = pUser->GetNick();
|
||||
Tmpl["AltNick"] = pUser->GetAltNick();
|
||||
@@ -1049,6 +1061,11 @@ public:
|
||||
CString sAction;
|
||||
|
||||
if (!pUser) {
|
||||
CString sClone = WebSock.GetParam("clone");
|
||||
if (CUser *pCloneUser = CZNC::Get().FindUser(sClone)) {
|
||||
pNewUser->CloneNetworks(*pCloneUser);
|
||||
}
|
||||
|
||||
// Add User Submission
|
||||
if (!CZNC::Get().AddUser(pNewUser, sErr)) {
|
||||
delete pNewUser;
|
||||
|
||||
+39
-35
@@ -566,6 +566,44 @@ void CUser::UserDisconnected(CClient* pClient) {
|
||||
}
|
||||
}
|
||||
|
||||
void CUser::CloneNetworks(const CUser& User) {
|
||||
const vector<CIRCNetwork*>& vNetworks = User.GetNetworks();
|
||||
for (vector<CIRCNetwork*>::const_iterator it = vNetworks.begin(); it != vNetworks.end(); ++it) {
|
||||
CIRCNetwork *pNetwork = FindNetwork((*it)->GetName());
|
||||
|
||||
if (pNetwork) {
|
||||
pNetwork->Clone(*(*it));
|
||||
} else {
|
||||
new CIRCNetwork(this, *(*it));
|
||||
}
|
||||
}
|
||||
|
||||
set<CString> ssDeleteNetworks;
|
||||
for (vector<CIRCNetwork*>::const_iterator it = m_vIRCNetworks.begin(); it != m_vIRCNetworks.end(); ++it) {
|
||||
if (!(User.FindNetwork((*it)->GetName()))) {
|
||||
ssDeleteNetworks.insert((*it)->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
for (set<CString>::const_iterator it = ssDeleteNetworks.begin(); it != ssDeleteNetworks.end(); ++it) {
|
||||
// The following will move all the clients to the user.
|
||||
// So the clients are not disconnected. The client could
|
||||
// have requested the rehash. Then when we do
|
||||
// client->PutStatus("Rehashing succeeded!") we would
|
||||
// crash if there was no client anymore.
|
||||
vector<CClient*>& vClients = FindNetwork(*it)->GetClients();
|
||||
|
||||
while (vClients.begin() != vClients.end()) {
|
||||
CClient *pClient = vClients.front();
|
||||
// This line will remove pClient from vClients,
|
||||
// because it's a reference to the internal Network's vector.
|
||||
pClient->SetNetwork(NULL);
|
||||
}
|
||||
|
||||
DeleteNetwork(*it);
|
||||
}
|
||||
}
|
||||
|
||||
bool CUser::Clone(const CUser& User, CString& sErrorRet, bool bCloneNetworks) {
|
||||
unsigned int a = 0;
|
||||
sErrorRet.clear();
|
||||
@@ -619,41 +657,7 @@ bool CUser::Clone(const CUser& User, CString& sErrorRet, bool bCloneNetworks) {
|
||||
|
||||
// Networks
|
||||
if (bCloneNetworks) {
|
||||
const vector<CIRCNetwork*>& vNetworks = User.GetNetworks();
|
||||
for (vector<CIRCNetwork*>::const_iterator it = vNetworks.begin(); it != vNetworks.end(); ++it) {
|
||||
CIRCNetwork *pNetwork = FindNetwork((*it)->GetName());
|
||||
|
||||
if (pNetwork) {
|
||||
pNetwork->Clone(*(*it));
|
||||
} else {
|
||||
new CIRCNetwork(this, *(*it));
|
||||
}
|
||||
}
|
||||
|
||||
set<CString> ssDeleteNetworks;
|
||||
for (vector<CIRCNetwork*>::const_iterator it = m_vIRCNetworks.begin(); it != m_vIRCNetworks.end(); ++it) {
|
||||
if (!(User.FindNetwork((*it)->GetName()))) {
|
||||
ssDeleteNetworks.insert((*it)->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
for (set<CString>::const_iterator it = ssDeleteNetworks.begin(); it != ssDeleteNetworks.end(); ++it) {
|
||||
// The following will move all the clients to the user.
|
||||
// So the clients are not disconnected. The client could
|
||||
// have requested the rehash. Then when we do
|
||||
// client->PutStatus("Rehashing succeeded!") we would
|
||||
// crash if there was no client anymore.
|
||||
vector<CClient*>& vClients = FindNetwork(*it)->GetClients();
|
||||
|
||||
while (vClients.begin() != vClients.end()) {
|
||||
CClient *pClient = vClients.front();
|
||||
// This line will remove pClient from vClients,
|
||||
// because it's a reference to the internal Network's vector.
|
||||
pClient->SetNetwork(NULL);
|
||||
}
|
||||
|
||||
DeleteNetwork(*it);
|
||||
}
|
||||
CloneNetworks(User);
|
||||
}
|
||||
// !Networks
|
||||
|
||||
|
||||
Reference in New Issue
Block a user