webadmin: Implement clone user

Closes #127
This commit is contained in:
Kyle Fuller
2012-02-24 17:35:00 +00:00
parent 7f8fbc2294
commit c54b3d0b87
5 changed files with 65 additions and 39 deletions
+1
View File
@@ -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>
+17
View File
@@ -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
View File
@@ -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