Commit cf6444ba authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gaston

Added shared groups support. JM-22


git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@781 b35dd754-fafc-0310-a699-88a17e54d16e
parent 03681b42
...@@ -15,9 +15,11 @@ import org.jivesoftware.util.Log; ...@@ -15,9 +15,11 @@ import org.jivesoftware.util.Log;
import org.jivesoftware.util.Cacheable; import org.jivesoftware.util.Cacheable;
import org.jivesoftware.util.CacheSizes; import org.jivesoftware.util.CacheSizes;
import org.jivesoftware.database.DbConnectionManager; import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.messenger.XMPPServer;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
...@@ -46,8 +48,8 @@ public class Group implements Cacheable { ...@@ -46,8 +48,8 @@ public class Group implements Cacheable {
private String name; private String name;
private String description; private String description;
private Map<String, String> properties; private Map<String, String> properties;
private Collection<String> members; private Collection<String> members = new CopyOnWriteArrayList<String>();
private Collection<String> administrators; private Collection<String> administrators = new CopyOnWriteArrayList<String>();
/** /**
* Constructs a new group. * Constructs a new group.
...@@ -55,7 +57,7 @@ public class Group implements Cacheable { ...@@ -55,7 +57,7 @@ public class Group implements Cacheable {
* @param provider the group provider. * @param provider the group provider.
* @param name the name. * @param name the name.
* @param description the description. * @param description the description.
* @param members a Collection of the group members (includes administrators). * @param members a Collection of the group members.
* @param administrators a Collection of the group administrators. * @param administrators a Collection of the group administrators.
*/ */
protected Group(GroupProvider provider, String name, String description, protected Group(GroupProvider provider, String name, String description,
...@@ -65,8 +67,8 @@ public class Group implements Cacheable { ...@@ -65,8 +67,8 @@ public class Group implements Cacheable {
this.groupManager = GroupManager.getInstance(); this.groupManager = GroupManager.getInstance();
this.name = name; this.name = name;
this.description = description; this.description = description;
this.members = members; this.members.addAll(members);
this.administrators = administrators; this.administrators.addAll(administrators);
} }
/** /**
...@@ -142,23 +144,35 @@ public class Group implements Cacheable { ...@@ -142,23 +144,35 @@ public class Group implements Cacheable {
} }
/** /**
* Returns a Collection of the group members that are administrators. * Returns a Collection of the group administrators. Use <code>getUsers()</code> to get the
* complete list of group users.
* *
* @return a Collection of the group administrators. * @return a Collection of the group administrators.
*/ */
public Collection<String> getAdministrators() { public Collection<String> getAdmins() {
// Return a wrapper that will intercept add and remove commands. return Collections.unmodifiableCollection(administrators);
return new MemberCollection(administrators, true);
} }
/** /**
* Returns a Collection of the group members. * Returns a Collection of the group members. Use <code>getUsers()</code> to get the complete
* list of group users.
* *
* @return a Collection of the group members. * @return a Collection of the group members.
*/ */
public Collection<String> getMembers() { public Collection<String> getMembers() {
// Return a wrapper that will intercept add and remove commands. return Collections.unmodifiableCollection(members);
return new MemberCollection(members, false); }
/**
* Returns a Collection with all the group users. The collection will include group members
* as well as group administrators.
*
* @return a Collection with all the group users.
*/
public Collection<String> getUsers() {
Collection<String> answer = new ArrayList<String>(members);
answer.addAll(administrators);
return Collections.unmodifiableCollection(answer);
} }
/** /**
...@@ -171,63 +185,110 @@ public class Group implements Cacheable { ...@@ -171,63 +185,110 @@ public class Group implements Cacheable {
return members.contains(username) || administrators.contains(username); return members.contains(username) || administrators.contains(username);
} }
public int getCachedSize() { /**
// Approximate the size of the object in bytes by calculating the size * Returns true if the provided username belongs to a member of the group.
// of each field. *
int size = 0; * @param username the username to check.
size += CacheSizes.sizeOfObject(); // overhead of object * @return true if the provided username belongs to a member of the group.
size += CacheSizes.sizeOfString(name); */
size += CacheSizes.sizeOfString(description); public boolean isMember(String username) {
return size; return members.contains(username);
} }
/** /**
* Collection implementation that notifies the GroupProvider of any * Returns true if the provided username belongs to an administrator of the group.
* changes to the collection. *
* @param username the username to check.
* @return true if the provided username belongs to an administrator of the group.
*/ */
private class MemberCollection extends AbstractCollection { public boolean isAdmin(String username) {
return administrators.contains(username);
private Collection<String> users;
private boolean adminCollection;
public MemberCollection(Collection<String> users, boolean adminCollection) {
this.users = users;
this.adminCollection = adminCollection;
} }
public Iterator iterator() { /**
return new Iterator() { * Adds a new user as a member of the group. The roster of all group users that are currently
* logged into the server will be updated.
Iterator iter = users.iterator(); *
Object current = null; * @param user the user to add as a member of the goup.
*/
public boolean hasNext() { public void addMember(String user) {
return iter.hasNext(); if (members.contains(user)) {
return;
}
members.add(user);
userAdded(user, false);
} }
public Object next() { /**
current = iter.next(); * Removes a member from the group. The roster of all group users that are currently
return current; * logged into the server will be updated.
*
* @param user the user to remove as a member of the group.
*/
public void removeMember(String user) {
if (members.remove(user)) {
userRemoved(user);
}
} }
public void remove() { /**
if (current == null) { * Adds a new user as an administrator of the group. The roster of all group users that are
throw new IllegalStateException(); * currently logged into the server will be updated.
*
* @param user the user to add as an administrator of the goup.
*/
public void addAdmin(String user) {
if (administrators.contains(user)) {
return;
} }
provider.deleteMember(name, (String)current); administrators.add(user);
iter.remove(); userAdded(user, true);
}
/**
* Removes an administrator from the group. The roster of all group users that are currently
* logged into the server will be updated.
*
* @param user the user to remove as an administrator of the group.
*/
public void removeAdmin(String user) {
if (administrators.remove(user)) {
userRemoved(user);
} }
};
} }
public int size() { /**
return users.size(); * Update backend store and update group users' roster.
*
* @param user the user that was added to the group.
*/
private void userAdded(String user, boolean administrator) {
// Add the new group user to the backend store
provider.addMember(name, user, administrator);
// Update the group users' roster
XMPPServer.getInstance().getRosterManager().groupUserAdded(this, user);
} }
public boolean add(Object member) { /**
provider.addMember(name, (String)member, adminCollection); * Update backend store and update group users' roster.
return users.add((String)member); *
* @param user the user that was removed from the group.
*/
private void userRemoved(String user) {
// Remove the group user from the backend store
provider.deleteMember(name, user);
// Update the group users' roster
XMPPServer.getInstance().getRosterManager().groupUserDeleted(this, user);
} }
public int getCachedSize() {
// Approximate the size of the object in bytes by calculating the size
// of each field.
int size = 0;
size += CacheSizes.sizeOfObject(); // overhead of object
size += CacheSizes.sizeOfString(name);
size += CacheSizes.sizeOfString(description);
return size;
} }
/** /**
......
...@@ -17,6 +17,8 @@ import org.jivesoftware.util.ClassUtils; ...@@ -17,6 +17,8 @@ import org.jivesoftware.util.ClassUtils;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.messenger.user.User; import org.jivesoftware.messenger.user.User;
import org.jivesoftware.messenger.JiveGlobals; import org.jivesoftware.messenger.JiveGlobals;
import org.jivesoftware.messenger.XMPPServer;
import org.jivesoftware.messenger.roster.RosterManager;
import java.util.Collection; import java.util.Collection;
...@@ -118,6 +120,27 @@ public class GroupManager { ...@@ -118,6 +120,27 @@ public class GroupManager {
// Expire all relevant caches. // Expire all relevant caches.
groupCache.remove(group.getName()); groupCache.remove(group.getName());
// Notify the RosterManager that the group has been deleted
RosterManager rosterManager = XMPPServer.getInstance().getRosterManager();
rosterManager.groupDeleted(group);
}
/**
* Deletes a user from all the groups where he/she belongs. The most probable cause for this
* request is that the user has been deleted from the system.
*
* @param user the deleted user from the system.
*/
public void deleteUser(User user) {
for (Group group : getGroups(user)) {
if (group.isAdmin(user.getUsername())) {
group.removeAdmin(user.getUsername());
}
else {
group.removeMember(user.getUsername());
}
}
} }
/** /**
......
...@@ -18,6 +18,7 @@ import org.jivesoftware.messenger.forms.spi.XDataFormImpl; ...@@ -18,6 +18,7 @@ import org.jivesoftware.messenger.forms.spi.XDataFormImpl;
import org.jivesoftware.messenger.forms.spi.XFormFieldImpl; import org.jivesoftware.messenger.forms.spi.XFormFieldImpl;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.messenger.*; import org.jivesoftware.messenger.*;
import org.jivesoftware.messenger.group.GroupManager;
import org.jivesoftware.messenger.roster.RosterManager; import org.jivesoftware.messenger.roster.RosterManager;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.*; import org.jivesoftware.messenger.user.*;
...@@ -202,10 +203,13 @@ public class IQRegisterHandler extends IQHandler implements ServerFeaturesProvid ...@@ -202,10 +203,13 @@ public class IQRegisterHandler extends IQHandler implements ServerFeaturesProvid
Element iqElement = packet.getChildElement(); Element iqElement = packet.getChildElement();
if (iqElement.element("remove") != null) { if (iqElement.element("remove") != null) {
if (session.getStatus() == Session.STATUS_AUTHENTICATED) { if (session.getStatus() == Session.STATUS_AUTHENTICATED) {
User user = userManager.getUser(session.getUsername());
// Delete the user // Delete the user
userManager.deleteUser(userManager.getUser(session.getUsername())); userManager.deleteUser(user);
// Delete the roster of the user // Delete the roster of the user
rosterManager.deleteRoster(session.getAddress()); rosterManager.deleteRoster(session.getAddress());
// Delete the user from all the Groups
GroupManager.getInstance().deleteUser(user);
reply = IQ.createResultIQ(packet); reply = IQ.createResultIQ(packet);
session.getConnection().deliver(reply); session.getConnection().deliver(reply);
......
...@@ -60,7 +60,7 @@ public class Roster implements Cacheable { ...@@ -60,7 +60,7 @@ public class Roster implements Cacheable {
* *
* <p>RosterItems that ONLY belong to shared groups won't be persistent unless the user * <p>RosterItems that ONLY belong to shared groups won't be persistent unless the user
* explicitly subscribes to the contact's presence, renames the contact in his roster or adds * explicitly subscribes to the contact's presence, renames the contact in his roster or adds
* the item to a personal group.</> * the item to a personal group.</p>
* *
* @param username The username of the user that owns this roster * @param username The username of the user that owns this roster
*/ */
...@@ -88,7 +88,7 @@ public class Roster implements Cacheable { ...@@ -88,7 +88,7 @@ public class Roster implements Cacheable {
for (Group group : sharedGroups) { for (Group group : sharedGroups) {
if (group.isUser(item.getJid().getNode())) { if (group.isUser(item.getJid().getNode())) {
// TODO Group name conflicts are not being considered (do we need this?) // TODO Group name conflicts are not being considered (do we need this?)
item.addSharedGroups(group.getName()); item.addSharedGroup(group.getName());
} }
} }
rosterItems.put(item.getJid().toBareJID(), item); rosterItems.put(item.getJid().toBareJID(), item);
...@@ -101,7 +101,7 @@ public class Roster implements Cacheable { ...@@ -101,7 +101,7 @@ public class Roster implements Cacheable {
RosterItem item = new RosterItem(jid, RosterItem.SUB_BOTH, RosterItem.ASK_NONE, RosterItem item = new RosterItem(jid, RosterItem.SUB_BOTH, RosterItem.ASK_NONE,
RosterItem.RECV_NONE, user.getName(), null); RosterItem.RECV_NONE, user.getName(), null);
for (String group : sharedUsers.get(jid)) { for (String group : sharedUsers.get(jid)) {
item.addSharedGroups(group); item.addSharedGroup(group);
} }
rosterItems.put(item.getJid().toBareJID(), item); rosterItems.put(item.getJid().toBareJID(), item);
} }
...@@ -269,19 +269,7 @@ public class Roster implements Cacheable { ...@@ -269,19 +269,7 @@ public class Roster implements Cacheable {
// broadcast roster update // broadcast roster update
if (!(item.getSubStatus() == RosterItem.SUB_NONE if (!(item.getSubStatus() == RosterItem.SUB_NONE
&& item.getAskStatus() == RosterItem.ASK_NONE)) { && item.getAskStatus() == RosterItem.ASK_NONE)) {
broadcast(item);
// Set the groups to broadcast (include personal and shared groups)
List<String> groups = new ArrayList<String>(item.getGroups());
groups.addAll(item.getSharedGroups());
org.xmpp.packet.Roster roster = new org.xmpp.packet.Roster();
roster.setType(IQ.Type.set);
roster.addItem(item.getJid(), item.getNickname(),
getAskStatus(item.getAskStatus()),
org.xmpp.packet.Roster.Subscription.valueOf(item.getSubStatus().getName()),
groups);
broadcast(roster);
} }
if (item.getSubStatus() == RosterItem.SUB_BOTH if (item.getSubStatus() == RosterItem.SUB_BOTH
|| item.getSubStatus() == RosterItem.SUB_TO) { || item.getSubStatus() == RosterItem.SUB_TO) {
...@@ -296,14 +284,14 @@ public class Roster implements Cacheable { ...@@ -296,14 +284,14 @@ public class Roster implements Cacheable {
* Remove a user from the roster. * Remove a user from the roster.
* *
* @param user the user to remove from the roster. * @param user the user to remove from the roster.
* @param forceRemove flag that indicates if checkings should be done before deleting the user. * @param doChecking flag that indicates if checkings should be done before deleting the user.
* @return The roster item being removed or null if none existed * @return The roster item being removed or null if none existed
* @throws SharedGroupException if the user to remove belongs to a shared group * @throws SharedGroupException if the user to remove belongs to a shared group
*/ */
public RosterItem deleteRosterItem(JID user, boolean forceRemove) throws SharedGroupException { public RosterItem deleteRosterItem(JID user, boolean doChecking) throws SharedGroupException {
// Answer an error if user (i.e. contact) to delete belongs to a shared group // Answer an error if user (i.e. contact) to delete belongs to a shared group
RosterItem itemToRemove = rosterItems.get(user.toBareJID()); RosterItem itemToRemove = rosterItems.get(user.toBareJID());
if (itemToRemove.isShared()) { if (doChecking && itemToRemove.isShared()) {
throw new SharedGroupException("Cannot remove contact that belongs to a shared group"); throw new SharedGroupException("Cannot remove contact that belongs to a shared group");
} }
...@@ -413,12 +401,8 @@ public class Roster implements Cacheable { ...@@ -413,12 +401,8 @@ public class Roster implements Cacheable {
// will have one entry in the map associated with all the groups // will have one entry in the map associated with all the groups
Map<JID,List<String>> sharedGroupUsers = new HashMap<JID,List<String>>(); Map<JID,List<String>> sharedGroupUsers = new HashMap<JID,List<String>>();
for (Group group : sharedGroups) { for (Group group : sharedGroups) {
// Collect all the users of the group (i.e. members and administrators)
Collection<String> users = new ArrayList<String>(group.getAdministrators());
users.addAll(group.getMembers());
// Add the users of the group to the general list of users to process // Add the users of the group to the general list of users to process
for (String groupUser : users) { for (String groupUser : group.getUsers()) {
// Add the user to the answer if the user doesn't belong to the personal roster // Add the user to the answer if the user doesn't belong to the personal roster
// (since we have already added the user to the answer) // (since we have already added the user to the answer)
JID jid = new JID(groupUser, XMPPServer.getInstance().getServerInfo().getName(), JID jid = new JID(groupUser, XMPPServer.getInstance().getServerInfo().getName(),
...@@ -453,6 +437,20 @@ public class Roster implements Cacheable { ...@@ -453,6 +437,20 @@ public class Roster implements Cacheable {
} }
} }
void broadcast(RosterItem item) {
// Set the groups to broadcast (include personal and shared groups)
List<String> groups = new ArrayList<String>(item.getGroups());
groups.addAll(item.getSharedGroups());
org.xmpp.packet.Roster roster = new org.xmpp.packet.Roster();
roster.setType(IQ.Type.set);
roster.addItem(item.getJid(), item.getNickname(),
getAskStatus(item.getAskStatus()),
org.xmpp.packet.Roster.Subscription.valueOf(item.getSubStatus().getName()),
groups);
broadcast(roster);
}
public int getCachedSize() { public int getCachedSize() {
// Approximate the size of the object in bytes by calculating the size // Approximate the size of the object in bytes by calculating the size
// of each field. // of each field.
...@@ -462,4 +460,80 @@ public class Roster implements Cacheable { ...@@ -462,4 +460,80 @@ public class Roster implements Cacheable {
size += CacheSizes.sizeOfString(username); // username size += CacheSizes.sizeOfString(username); // username
return size; return size;
} }
/**
* Update the roster since a group user has been added to a shared group. Create a new
* RosterItem if the there doesn't exist an item for the added user. The new RosterItem won't be
* saved to the backend store unless the user explicitly subscribes to the contact's presence,
* renames the contact in his roster or adds the item to a personal group. Otherwise the shared
* group will be added to the shared groups lists. In any case an update broadcast will be sent
* to all the users logged resources.
*
* @param sharedGroup the shared group where the user was added.
* @param addedUser the contact to update in the roster.
*/
void addSharedUser(String sharedGroup, String addedUser) {
JID jid = new JID(addedUser, XMPPServer.getInstance().getServerInfo().getName(), "");
try {
// Get the RosterItem for the *local* user to add
RosterItem item = getRosterItem(jid);
// Add the shared group to the list of shared groups
item.addSharedGroup(sharedGroup);
// Brodcast to all the user resources of the updated roster item
broadcast(item);
}
catch (UserNotFoundException e) {
try {
// Create a new RosterItem for this new user
User user = UserManager.getInstance().getUser(addedUser);
RosterItem item = new RosterItem(jid, RosterItem.SUB_BOTH, RosterItem.ASK_NONE,
RosterItem.RECV_NONE, user.getName(), null);
item.addSharedGroup(sharedGroup);
// Add the new item to the list of items
rosterItems.put(item.getJid().toBareJID(), item);
// Brodcast to all the user resources of the updated roster item
broadcast(item);
}
catch (UserNotFoundException ex) {
Log.error("Group (" + sharedGroup + ") includes non-existent username (" +
addedUser +
")");
}
}
}
/**
* Update the roster since a group user has been deleted from a shared group. If the RosterItem
* (of the deleted contact) exists only because of of the sahred group then the RosterItem will
* be deleted physically from the backend store. Otherwise the shared group will be removed from
* the shared groups lists. In any case an update broadcast will be sent to all the users
* logged resources.
*
* @param sharedGroup the shared group from where the user was deleted.
* @param deletedUser the contact to update in the roster.
*/
void deleteSharedUser(String sharedGroup, String deletedUser) {
JID jid = new JID(deletedUser, XMPPServer.getInstance().getServerInfo().getName(), "");
try {
// Get the RosterItem for the *local* user to remove
RosterItem item = getRosterItem(jid);
if (item.isOnlyShared() && item.getSharedGroups().size() == 1) {
// Delete the roster item from the roster since it exists only because of this
// group which is being removed
deleteRosterItem(jid, false);
}
else {
// Remove the removed shared group from the list of shared groups
item.removeSharedGroup(sharedGroup);
// Brodcast to all the user resources of the updated roster item
broadcast(item);
}
}
catch (SharedGroupException e) {
// Do nothing. Checkings are disabled so this exception should never happen.
}
catch (UserNotFoundException e) {
// Do nothing since the contact does not exist in the user's roster. (strange case!)
}
}
} }
\ No newline at end of file
...@@ -354,10 +354,19 @@ public class RosterItem implements Cacheable { ...@@ -354,10 +354,19 @@ public class RosterItem implements Cacheable {
* *
* @param sharedGroup The shared group to add to the list of shared groups. * @param sharedGroup The shared group to add to the list of shared groups.
*/ */
public void addSharedGroups(String sharedGroup) { public void addSharedGroup(String sharedGroup) {
sharedGroups.add(sharedGroup); sharedGroups.add(sharedGroup);
} }
/**
* Removes a group from the shared groups list.
*
* @param sharedGroup The shared group to remove from the list of shared groups.
*/
public void removeSharedGroup(String sharedGroup) {
sharedGroups.remove(sharedGroup);
}
/** /**
* Returns true if this item belongs to a shared group. Return true even if the item belongs * Returns true if this item belongs to a shared group. Return true even if the item belongs
* to a personal group and a shared group. * to a personal group and a shared group.
......
...@@ -17,6 +17,7 @@ import org.jivesoftware.util.CacheManager; ...@@ -17,6 +17,7 @@ import org.jivesoftware.util.CacheManager;
import org.jivesoftware.messenger.container.BasicModule; import org.jivesoftware.messenger.container.BasicModule;
import org.jivesoftware.messenger.user.UserNotFoundException; import org.jivesoftware.messenger.user.UserNotFoundException;
import org.jivesoftware.messenger.SharedGroupException; import org.jivesoftware.messenger.SharedGroupException;
import org.jivesoftware.messenger.group.Group;
import java.util.Iterator; import java.util.Iterator;
...@@ -117,4 +118,57 @@ public class RosterManager extends BasicModule { ...@@ -117,4 +118,57 @@ public class RosterManager extends BasicModule {
// Do nothing // Do nothing
} }
} }
/**
* Notification that a Group has been deleted. Update the group users' roster accordingly.
*
* @param group the group that has been deleted.
*/
public void groupDeleted(Group group) {
// Iterate on all the group users and update their rosters
for (String deletedUser : group.getUsers()) {
groupUserDeleted(group, deletedUser);
}
}
/**
* Notification that a Group user has been added. Update the group users' roster accordingly.
*
* @param group the group where the user was added.
* @param addedUser the username of the user that has been added to the group.
*/
public void groupUserAdded(Group group, String addedUser) {
// Iterate on all the group users and update their rosters
for (String userToUpdate : group.getUsers()) {
if (!addedUser.equals(userToUpdate)) {
// Get the roster to update
Roster roster = (Roster)CacheManager.getCache("username2roster").get(userToUpdate);
// Only update rosters in memory
if (roster != null) {
roster.addSharedUser(group.getName(), addedUser);
}
}
}
}
/**
* Notification that a Group user has been deleted. Update the group users' roster accordingly.
*
* @param group the group from where the user was deleted.
* @param deletedUser the username of the user that has been deleted from the group.
*/
public void groupUserDeleted(Group group, String deletedUser) {
// Iterate on all the group users and update their rosters
for (String userToUpdate : group.getUsers()) {
if (!deletedUser.equals(userToUpdate)) {
// Get the roster to update
Roster roster = (Roster)CacheManager.getCache("username2roster").get(userToUpdate);
// Only update rosters in memory
if (roster != null) {
roster.deleteSharedUser(group.getName(), deletedUser);
}
}
}
}
} }
\ No newline at end of file
...@@ -38,8 +38,6 @@ public class DefaultUserProvider implements UserProvider { ...@@ -38,8 +38,6 @@ public class DefaultUserProvider implements UserProvider {
private static final String INSERT_USER = private static final String INSERT_USER =
"INSERT INTO jiveUser (username,password,name,email,creationDate,modificationDate) " + "INSERT INTO jiveUser (username,password,name,email,creationDate,modificationDate) " +
"VALUES (?,?,?,?,?,?)"; "VALUES (?,?,?,?,?,?)";
private static final String DELETE_USER_GROUPS =
"DELETE FROM jiveGroupUser WHERE username=?";
private static final String DELETE_USER_PROPS = private static final String DELETE_USER_PROPS =
"DELETE FROM jiveUserProp WHERE username=?"; "DELETE FROM jiveUserProp WHERE username=?";
private static final String DELETE_VCARD_PROPS = private static final String DELETE_VCARD_PROPS =
...@@ -140,11 +138,6 @@ public class DefaultUserProvider implements UserProvider { ...@@ -140,11 +138,6 @@ public class DefaultUserProvider implements UserProvider {
boolean abortTransaction = false; boolean abortTransaction = false;
try { try {
con = DbConnectionManager.getTransactionConnection(); con = DbConnectionManager.getTransactionConnection();
// Remove user from all groups
pstmt = con.prepareStatement(DELETE_USER_GROUPS);
pstmt.setString(1, username);
pstmt.execute();
pstmt.close();
// Delete all of the users's extended properties // Delete all of the users's extended properties
pstmt = con.prepareStatement(DELETE_USER_PROPS); pstmt = con.prepareStatement(DELETE_USER_PROPS);
pstmt.setString(1, username); pstmt.setString(1, username);
......
...@@ -139,7 +139,7 @@ Total Groups: <%= webManager.getGroupManager().getGroupCount() %>, ...@@ -139,7 +139,7 @@ Total Groups: <%= webManager.getGroupManager().getGroupCount() %>,
<%= group.getMembers().size() %> <%= group.getMembers().size() %>
</td> </td>
<td width="10%" align="center"> <td width="10%" align="center">
<%= group.getAdministrators().size() %> <%= group.getAdmins().size() %>
</td> </td>
<td width="1%" align="center"> <td width="1%" align="center">
<a href="group-edit-form.jsp?group=<%= group.getName() %>" <a href="group-edit-form.jsp?group=<%= group.getName() %>"
......
...@@ -13,7 +13,8 @@ ...@@ -13,7 +13,8 @@
org.jivesoftware.messenger.user.*, org.jivesoftware.messenger.user.*,
org.jivesoftware.admin.*, org.jivesoftware.admin.*,
org.xmpp.packet.JID, org.xmpp.packet.JID,
java.net.URLEncoder" java.net.URLEncoder,
org.jivesoftware.messenger.group.GroupManager"
errorPage="error.jsp" errorPage="error.jsp"
%> %>
...@@ -42,7 +43,10 @@ ...@@ -42,7 +43,10 @@
webManager.getUserManager().deleteUser(user); webManager.getUserManager().deleteUser(user);
// Delete the user's roster // Delete the user's roster
JID userAddress = new JID(username, webManager.getServerInfo().getName(), null); JID userAddress = new JID(username, webManager.getServerInfo().getName(), null);
// Delete the roster of the user
webManager.getRosterManager().deleteRoster(userAddress); webManager.getRosterManager().deleteRoster(userAddress);
// Delete the user from all the Groups
GroupManager.getInstance().deleteUser(user);
// Deleted your own user account, force login // Deleted your own user account, force login
if (username.equals(webManager.getAuthToken().getUsername())){ if (username.equals(webManager.getAuthToken().getUsername())){
session.removeAttribute("jive.admin.authToken"); session.removeAttribute("jive.admin.authToken");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment