Commit 80b0b21b authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Allow to have bare JIDs inside shared groups (does not include JIDs of remote users). JM-210

git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@3117 b35dd754-fafc-0310-a699-88a17e54d16e
parent c61a38c2
...@@ -12,16 +12,17 @@ ...@@ -12,16 +12,17 @@
package org.jivesoftware.messenger.group; package org.jivesoftware.messenger.group;
import org.jivesoftware.database.DbConnectionManager; import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.util.*; import org.jivesoftware.messenger.XMPPServer;
import org.jivesoftware.messenger.user.User; import org.jivesoftware.util.Log;
import org.xmpp.packet.JID;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import java.util.Collection; import java.util.Collection;
import java.util.List;
/** /**
* Database implementation of the GroupManager interface. * Database implementation of the GroupManager interface.
...@@ -63,6 +64,8 @@ public class DefaultGroupProvider implements GroupProvider { ...@@ -63,6 +64,8 @@ public class DefaultGroupProvider implements GroupProvider {
"SELECT groupName FROM jiveGroupUser WHERE username=?"; "SELECT groupName FROM jiveGroupUser WHERE username=?";
private static final String ALL_GROUPS = "SELECT groupName FROM jiveGroup ORDER BY groupName"; private static final String ALL_GROUPS = "SELECT groupName FROM jiveGroup ORDER BY groupName";
private XMPPServer server = XMPPServer.getInstance();
public Group createGroup(String name) throws GroupAlreadyExistsException { public Group createGroup(String name) throws GroupAlreadyExistsException {
Connection con = null; Connection con = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
...@@ -82,8 +85,8 @@ public class DefaultGroupProvider implements GroupProvider { ...@@ -82,8 +85,8 @@ public class DefaultGroupProvider implements GroupProvider {
try { if (con != null) con.close(); } try { if (con != null) con.close(); }
catch (Exception e) { Log.error(e); } catch (Exception e) { Log.error(e); }
} }
Collection<String> members = getMembers(name, false); Collection<JID> members = getMembers(name, false);
Collection<String> administrators = getMembers(name, true); Collection<JID> administrators = getMembers(name, true);
return new Group(this, name, "", members, administrators); return new Group(this, name, "", members, administrators);
} }
...@@ -112,8 +115,8 @@ public class DefaultGroupProvider implements GroupProvider { ...@@ -112,8 +115,8 @@ public class DefaultGroupProvider implements GroupProvider {
try { if (con != null) con.close(); } try { if (con != null) con.close(); }
catch (Exception e) { Log.error(e); } catch (Exception e) { Log.error(e); }
} }
Collection<String> members = getMembers(name, false); Collection<JID> members = getMembers(name, false);
Collection<String> administrators = getMembers(name, true); Collection<JID> administrators = getMembers(name, true);
return new Group(this, name, description, members, administrators); return new Group(this, name, description, members, administrators);
} }
...@@ -306,14 +309,14 @@ public class DefaultGroupProvider implements GroupProvider { ...@@ -306,14 +309,14 @@ public class DefaultGroupProvider implements GroupProvider {
return groups; return groups;
} }
public Collection<Group> getGroups(User user) { public Collection<Group> getGroups(JID user) {
List<String> groupNames = new ArrayList<String>(); List<String> groupNames = new ArrayList<String>();
Connection con = null; Connection con = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
try { try {
con = DbConnectionManager.getConnection(); con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(USER_GROUPS); pstmt = con.prepareStatement(USER_GROUPS);
pstmt.setString(1, user.getUsername()); pstmt.setString(1, server.isLocal(user) ? user.getNode() : user.toString());
ResultSet rs = pstmt.executeQuery(); ResultSet rs = pstmt.executeQuery();
while (rs.next()) { while (rs.next()) {
groupNames.add(rs.getString(1)); groupNames.add(rs.getString(1));
...@@ -342,14 +345,14 @@ public class DefaultGroupProvider implements GroupProvider { ...@@ -342,14 +345,14 @@ public class DefaultGroupProvider implements GroupProvider {
return groups; return groups;
} }
public void addMember(String groupName, String username, boolean administrator) { public void addMember(String groupName, JID user, boolean administrator) {
Connection con = null; Connection con = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
try { try {
con = DbConnectionManager.getConnection(); con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(ADD_USER); pstmt = con.prepareStatement(ADD_USER);
pstmt.setString(1, groupName); pstmt.setString(1, groupName);
pstmt.setString(2, username); pstmt.setString(2, server.isLocal(user) ? user.getNode() : user.toString());
pstmt.setInt(3, administrator ? 1 : 0); pstmt.setInt(3, administrator ? 1 : 0);
pstmt.executeUpdate(); pstmt.executeUpdate();
} }
...@@ -364,7 +367,7 @@ public class DefaultGroupProvider implements GroupProvider { ...@@ -364,7 +367,7 @@ public class DefaultGroupProvider implements GroupProvider {
} }
} }
public void updateMember(String groupName, String username, boolean administrator) { public void updateMember(String groupName, JID user, boolean administrator) {
Connection con = null; Connection con = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
try { try {
...@@ -372,7 +375,7 @@ public class DefaultGroupProvider implements GroupProvider { ...@@ -372,7 +375,7 @@ public class DefaultGroupProvider implements GroupProvider {
pstmt = con.prepareStatement(UPDATE_USER); pstmt = con.prepareStatement(UPDATE_USER);
pstmt.setInt(1, administrator ? 1 : 0); pstmt.setInt(1, administrator ? 1 : 0);
pstmt.setString(2, groupName); pstmt.setString(2, groupName);
pstmt.setString(3, username); pstmt.setString(3, server.isLocal(user) ? user.getNode() : user.toString());
pstmt.executeUpdate(); pstmt.executeUpdate();
} }
catch (SQLException e) { catch (SQLException e) {
...@@ -386,14 +389,14 @@ public class DefaultGroupProvider implements GroupProvider { ...@@ -386,14 +389,14 @@ public class DefaultGroupProvider implements GroupProvider {
} }
} }
public void deleteMember(String groupName, String username) { public void deleteMember(String groupName, JID user) {
Connection con = null; Connection con = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
try { try {
con = DbConnectionManager.getConnection(); con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(REMOVE_USER); pstmt = con.prepareStatement(REMOVE_USER);
pstmt.setString(1, groupName); pstmt.setString(1, groupName);
pstmt.setString(2, username); pstmt.setString(2, server.isLocal(user) ? user.getNode() : user.toString());
pstmt.executeUpdate(); pstmt.executeUpdate();
} }
catch (SQLException e) { catch (SQLException e) {
...@@ -411,8 +414,8 @@ public class DefaultGroupProvider implements GroupProvider { ...@@ -411,8 +414,8 @@ public class DefaultGroupProvider implements GroupProvider {
return false; return false;
} }
private Collection<String> getMembers(String groupName, boolean adminsOnly) { private Collection<JID> getMembers(String groupName, boolean adminsOnly) {
List<String> members = new ArrayList<String>(); List<JID> members = new ArrayList<JID>();
Connection con = null; Connection con = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
try { try {
...@@ -426,7 +429,15 @@ public class DefaultGroupProvider implements GroupProvider { ...@@ -426,7 +429,15 @@ public class DefaultGroupProvider implements GroupProvider {
pstmt.setString(1, groupName); pstmt.setString(1, groupName);
ResultSet rs = pstmt.executeQuery(); ResultSet rs = pstmt.executeQuery();
while (rs.next()) { while (rs.next()) {
members.add(rs.getString(1)); String user = rs.getString(1);
JID userJID = new JID(user);
if (user.indexOf('@') == -1) {
// Create JID of local user if JID does not match a component's JID
if (!server.matchesComponent(userJID)) {
userJID = server.createJID(user, null);
}
}
members.add(userJID);
} }
rs.close(); rs.close();
} }
......
...@@ -14,8 +14,6 @@ package org.jivesoftware.messenger.group; ...@@ -14,8 +14,6 @@ package org.jivesoftware.messenger.group;
import org.jivesoftware.database.DbConnectionManager; import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.messenger.XMPPServer; import org.jivesoftware.messenger.XMPPServer;
import org.jivesoftware.messenger.event.GroupEventDispatcher; import org.jivesoftware.messenger.event.GroupEventDispatcher;
import org.jivesoftware.messenger.user.UserManager;
import org.jivesoftware.stringprep.Stringprep;
import org.jivesoftware.util.CacheSizes; import org.jivesoftware.util.CacheSizes;
import org.jivesoftware.util.Cacheable; import org.jivesoftware.util.Cacheable;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
...@@ -51,8 +49,8 @@ public class Group implements Cacheable { ...@@ -51,8 +49,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<JID> members;
private Collection<String> administrators; private Collection<JID> administrators;
/** /**
* Constructs a new group. Note: this constructor is intended for implementors of the * Constructs a new group. Note: this constructor is intended for implementors of the
...@@ -66,7 +64,7 @@ public class Group implements Cacheable { ...@@ -66,7 +64,7 @@ public class Group implements Cacheable {
* @param administrators a Collection of the group administrators. * @param administrators a Collection of the group administrators.
*/ */
public Group(GroupProvider provider, String name, String description, public Group(GroupProvider provider, String name, String description,
Collection<String> members, Collection<String> administrators) Collection<JID> members, Collection<JID> administrators)
{ {
this.provider = provider; this.provider = provider;
this.groupManager = GroupManager.getInstance(); this.groupManager = GroupManager.getInstance();
...@@ -172,7 +170,7 @@ public class Group implements Cacheable { ...@@ -172,7 +170,7 @@ public class Group implements Cacheable {
* *
* @return a Collection of the group administrators. * @return a Collection of the group administrators.
*/ */
public Collection<String> getAdmins() { public Collection<JID> getAdmins() {
// Return a wrapper that will intercept add and remove commands. // Return a wrapper that will intercept add and remove commands.
return new MemberCollection(administrators, true); return new MemberCollection(administrators, true);
} }
...@@ -182,24 +180,19 @@ public class Group implements Cacheable { ...@@ -182,24 +180,19 @@ public class Group implements Cacheable {
* *
* @return a Collection of the group members. * @return a Collection of the group members.
*/ */
public Collection<String> getMembers() { public Collection<JID> getMembers() {
// Return a wrapper that will intercept add and remove commands. // Return a wrapper that will intercept add and remove commands.
return new MemberCollection(members, false); return new MemberCollection(members, false);
} }
/** /**
* Returns true if the provided username belongs to a local user that is part of the group. * Returns true if the provided username belongs to a user that is part of the group.
* *
* @param user the JID address of the user to check. * @param user the JID address of the user to check.
* @return true if the provided username belongs to a user of the group. * @return true if the specified user is a group user.
*/ */
public boolean isUser(JID user) { public boolean isUser(JID user) {
String serverName = XMPPServer.getInstance().getServerInfo().getName(); return user != null && (members.contains(user) || administrators.contains(user));
if (user != null && serverName.equals(user.getDomain())) {
return isUser(user.getNode());
} else {
return false;
}
} }
/** /**
...@@ -210,7 +203,7 @@ public class Group implements Cacheable { ...@@ -210,7 +203,7 @@ public class Group implements Cacheable {
*/ */
public boolean isUser(String username) { public boolean isUser(String username) {
if (username != null) { if (username != null) {
return members.contains(username) || administrators.contains(username); return isUser(XMPPServer.getInstance().createJID(username, null));
} else { } else {
return false; return false;
} }
...@@ -232,18 +225,18 @@ public class Group implements Cacheable { ...@@ -232,18 +225,18 @@ public class Group implements Cacheable {
*/ */
private class MemberCollection extends AbstractCollection { private class MemberCollection extends AbstractCollection {
private Collection<String> users; private Collection<JID> users;
private boolean adminCollection; private boolean adminCollection;
public MemberCollection(Collection<String> users, boolean adminCollection) { public MemberCollection(Collection<JID> users, boolean adminCollection) {
this.users = users; this.users = users;
this.adminCollection = adminCollection; this.adminCollection = adminCollection;
} }
public Iterator iterator() { public Iterator<JID> iterator() {
return new Iterator() { return new Iterator() {
Iterator iter = users.iterator(); Iterator<JID> iter = users.iterator();
Object current = null; Object current = null;
public boolean hasNext() { public boolean hasNext() {
...@@ -259,7 +252,7 @@ public class Group implements Cacheable { ...@@ -259,7 +252,7 @@ public class Group implements Cacheable {
if (current == null) { if (current == null) {
throw new IllegalStateException(); throw new IllegalStateException();
} }
String user = (String)current; JID user = (JID)current;
// Remove the user from the collection in memory. // Remove the user from the collection in memory.
iter.remove(); iter.remove();
// Remove the group user from the backend store. // Remove the group user from the backend store.
...@@ -267,13 +260,13 @@ public class Group implements Cacheable { ...@@ -267,13 +260,13 @@ public class Group implements Cacheable {
// Fire event. // Fire event.
if (adminCollection) { if (adminCollection) {
Map<String, String> params = new HashMap<String, String>(); Map<String, String> params = new HashMap<String, String>();
params.put("admin", user); params.put("admin", user.toString());
GroupEventDispatcher.dispatchEvent(Group.this, GroupEventDispatcher.dispatchEvent(Group.this,
GroupEventDispatcher.EventType.admin_removed, params); GroupEventDispatcher.EventType.admin_removed, params);
} }
else { else {
Map<String, String> params = new HashMap<String, String>(); Map<String, String> params = new HashMap<String, String>();
params.put("member", user); params.put("member", user.toString());
GroupEventDispatcher.dispatchEvent(Group.this, GroupEventDispatcher.dispatchEvent(Group.this,
GroupEventDispatcher.EventType.member_removed, params); GroupEventDispatcher.EventType.member_removed, params);
} }
...@@ -286,36 +279,29 @@ public class Group implements Cacheable { ...@@ -286,36 +279,29 @@ public class Group implements Cacheable {
} }
public boolean add(Object member) { public boolean add(Object member) {
String username = (String) member; JID user = (JID) member;
try {
username = Stringprep.nodeprep(username);
UserManager.getInstance().getUser(username);
}
catch (Exception e) {
throw new IllegalArgumentException("Invalid user.", e);
}
// Find out if the user was already a group user // Find out if the user was already a group user
boolean alreadyGroupUser = false; boolean alreadyGroupUser = false;
if (adminCollection) { if (adminCollection) {
alreadyGroupUser = members.contains(username); alreadyGroupUser = members.contains(user);
} }
else { else {
alreadyGroupUser = administrators.contains(username); alreadyGroupUser = administrators.contains(user);
} }
if (users.add(username)) { if (users.add(user)) {
if (alreadyGroupUser) { if (alreadyGroupUser) {
// Update the group user privileges in the backend store. // Update the group user privileges in the backend store.
provider.updateMember(name, username, adminCollection); provider.updateMember(name, user, adminCollection);
} }
else { else {
// Add the group user to the backend store. // Add the group user to the backend store.
provider.addMember(name, username, adminCollection); provider.addMember(name, user, adminCollection);
} }
// Fire event. // Fire event.
if (adminCollection) { if (adminCollection) {
Map<String, String> params = new HashMap<String, String>(); Map<String, String> params = new HashMap<String, String>();
params.put("admin", username); params.put("admin", user.toString());
if (alreadyGroupUser) { if (alreadyGroupUser) {
GroupEventDispatcher.dispatchEvent(Group.this, GroupEventDispatcher.dispatchEvent(Group.this,
GroupEventDispatcher.EventType.member_removed, params); GroupEventDispatcher.EventType.member_removed, params);
...@@ -325,7 +311,7 @@ public class Group implements Cacheable { ...@@ -325,7 +311,7 @@ public class Group implements Cacheable {
} }
else { else {
Map<String, String> params = new HashMap<String, String>(); Map<String, String> params = new HashMap<String, String>();
params.put("member", username); params.put("member", user.toString());
if (alreadyGroupUser) { if (alreadyGroupUser) {
GroupEventDispatcher.dispatchEvent(Group.this, GroupEventDispatcher.dispatchEvent(Group.this,
GroupEventDispatcher.EventType.admin_removed, params); GroupEventDispatcher.EventType.admin_removed, params);
...@@ -337,13 +323,13 @@ public class Group implements Cacheable { ...@@ -337,13 +323,13 @@ public class Group implements Cacheable {
// user from the other collection // user from the other collection
if (alreadyGroupUser) { if (alreadyGroupUser) {
if (adminCollection) { if (adminCollection) {
if (members.contains(username)) { if (members.contains(user)) {
members.remove(username); members.remove(user);
} }
} }
else { else {
if (administrators.contains(username)) { if (administrators.contains(user)) {
administrators.remove(username); administrators.remove(user);
} }
} }
} }
......
...@@ -15,6 +15,8 @@ import org.jivesoftware.util.*; ...@@ -15,6 +15,8 @@ import org.jivesoftware.util.*;
import org.jivesoftware.messenger.user.User; import org.jivesoftware.messenger.user.User;
import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.messenger.event.GroupEventDispatcher; import org.jivesoftware.messenger.event.GroupEventDispatcher;
import org.jivesoftware.messenger.XMPPServer;
import org.xmpp.packet.JID;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
...@@ -136,12 +138,13 @@ public class GroupManager { ...@@ -136,12 +138,13 @@ public class GroupManager {
* @param user the deleted user from the system. * @param user the deleted user from the system.
*/ */
public void deleteUser(User user) { public void deleteUser(User user) {
for (Group group : getGroups(user)) { JID userJID = XMPPServer.getInstance().createJID(user.getUsername(), null);
if (group.getAdmins().contains(user.getUsername())) { for (Group group : getGroups(userJID)) {
group.getAdmins().remove(user.getUsername()); if (group.getAdmins().contains(userJID)) {
group.getAdmins().remove(userJID);
} }
else { else {
group.getMembers().remove(user.getUsername()); group.getMembers().remove(userJID);
} }
} }
} }
...@@ -186,12 +189,12 @@ public class GroupManager { ...@@ -186,12 +189,12 @@ public class GroupManager {
} }
/** /**
* Returns an iterator for all groups that a user is a member of. * Returns an iterator for all groups that the entity with the specified JID is a member of.
* *
* @param user the user to get a list of groups for. * @param user the JID of the entity to get a list of groups for.
* @return all groups that a user belongs to. * @return all groups that an entity belongs to.
*/ */
public Collection<Group> getGroups(User user) { public Collection<Group> getGroups(JID user) {
// TODO: add caching // TODO: add caching
return provider.getGroups(user); return provider.getGroups(user);
} }
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
package org.jivesoftware.messenger.group; package org.jivesoftware.messenger.group;
import org.jivesoftware.messenger.user.User; import org.xmpp.packet.JID;
import java.util.Collection; import java.util.Collection;
...@@ -113,46 +113,46 @@ public interface GroupProvider { ...@@ -113,46 +113,46 @@ public interface GroupProvider {
Collection<Group> getGroups(int startIndex, int numResults); Collection<Group> getGroups(int startIndex, int numResults);
/** /**
* Returns the Collection of Groups that a user belongs to. * Returns the Collection of Groups that an entity belongs to.
* *
* @param user the user. * @param user the JID of the entity.
* @return the Collection of groups that the user belongs to. * @return the Collection of groups that the user belongs to.
*/ */
Collection<Group> getGroups(User user); Collection<Group> getGroups(JID user);
/** /**
* Adds a user to a group (optional operation). * Adds an entity to a group (optional operation).
* *
* @param groupName the group to add the member to * @param groupName the group to add the member to
* @param username the username to add * @param user the JID of the entity to add
* @param administrator True if the member is an administrator of the group * @param administrator True if the member is an administrator of the group
* @throws UnsupportedOperationException if the provider does not * @throws UnsupportedOperationException if the provider does not
* support the operation. * support the operation.
*/ */
void addMember(String groupName, String username, boolean administrator) void addMember(String groupName, JID user, boolean administrator)
throws UnsupportedOperationException; throws UnsupportedOperationException;
/** /**
* Updates the privileges of a user in a group. * Updates the privileges of an entity in a group.
* *
* @param groupName the group where the change happened * @param groupName the group where the change happened
* @param username the username to of the user with new privileges * @param user the JID of the entity with new privileges
* @param administrator True if the member is an administrator of the group * @param administrator True if the member is an administrator of the group
* @throws UnsupportedOperationException if the provider does not * @throws UnsupportedOperationException if the provider does not
* support the operation. * support the operation.
*/ */
void updateMember(String groupName, String username, boolean administrator) void updateMember(String groupName, JID user, boolean administrator)
throws UnsupportedOperationException; throws UnsupportedOperationException;
/** /**
* Deletes a user from a group (optional operation). * Deletes an entity from a group (optional operation).
* *
* @param groupName the group name. * @param groupName the group name.
* @param username the username. * @param user the JID of the entity to delete.
* @throws UnsupportedOperationException if the provider does not * @throws UnsupportedOperationException if the provider does not
* support the operation. * support the operation.
*/ */
void deleteMember(String groupName, String username) throws UnsupportedOperationException; void deleteMember(String groupName, JID user) throws UnsupportedOperationException;
/** /**
* Returns true if this GroupProvider is read-only. When read-only, * Returns true if this GroupProvider is read-only. When read-only,
......
...@@ -11,22 +11,20 @@ ...@@ -11,22 +11,20 @@
package org.jivesoftware.messenger.ldap; package org.jivesoftware.messenger.ldap;
import org.jivesoftware.util.*; import org.jivesoftware.messenger.XMPPServer;
import org.jivesoftware.messenger.user.*; import org.jivesoftware.messenger.group.Group;
import org.jivesoftware.messenger.group.*; import org.jivesoftware.messenger.group.GroupProvider;
import org.jivesoftware.messenger.user.UserManager;
import org.jivesoftware.messenger.user.UserNotFoundException;
import org.jivesoftware.util.JiveConstants;
import org.jivesoftware.util.Log;
import org.xmpp.packet.JID; import org.xmpp.packet.JID;
import java.util.ArrayList;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Vector;
import java.text.MessageFormat;
import javax.naming.NamingEnumeration; import javax.naming.NamingEnumeration;
import javax.naming.directory.*; import javax.naming.directory.*;
import javax.naming.ldap.LdapName; import javax.naming.ldap.LdapName;
import java.text.MessageFormat;
import java.util.*;
/** /**
* LDAP implementation of the GroupProvider interface. All data in the directory is * LDAP implementation of the GroupProvider interface. All data in the directory is
...@@ -171,8 +169,9 @@ public class LdapGroupProvider implements GroupProvider { ...@@ -171,8 +169,9 @@ public class LdapGroupProvider implements GroupProvider {
return populateGroups(v.elements()); return populateGroups(v.elements());
} }
public Collection<Group> getGroups(User user) { public Collection<Group> getGroups(JID user) {
String username = JID.unescapeNode(user.getUsername()); XMPPServer server = XMPPServer.getInstance();
String username = server.isLocal(user) ? JID.unescapeNode(user.getNode()) : user.toString();
if (!manager.isPosixMode()) { if (!manager.isPosixMode()) {
try { try {
username = manager.findUserDN(username) + "," + username = manager.findUserDN(username) + "," +
...@@ -192,11 +191,11 @@ public class LdapGroupProvider implements GroupProvider { ...@@ -192,11 +191,11 @@ public class LdapGroupProvider implements GroupProvider {
* LDAP groups are read-only. * LDAP groups are read-only.
* *
* @param groupName name of a group. * @param groupName name of a group.
* @param username name of a user. * @param user the JID of the user to add
* @param administrator true if is an administrator. * @param administrator true if is an administrator.
* @throws UnsupportedOperationException when called. * @throws UnsupportedOperationException when called.
*/ */
public void addMember(String groupName, String username, boolean administrator) public void addMember(String groupName, JID user, boolean administrator)
throws UnsupportedOperationException throws UnsupportedOperationException
{ {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
...@@ -207,11 +206,11 @@ public class LdapGroupProvider implements GroupProvider { ...@@ -207,11 +206,11 @@ public class LdapGroupProvider implements GroupProvider {
* LDAP groups are read-only. * LDAP groups are read-only.
* *
* @param groupName the naame of a group. * @param groupName the naame of a group.
* @param username the name of a user. * @param user the JID of the user with new privileges
* @param administrator true if is an administrator. * @param administrator true if is an administrator.
* @throws UnsupportedOperationException when called. * @throws UnsupportedOperationException when called.
*/ */
public void updateMember(String groupName, String username, boolean administrator) public void updateMember(String groupName, JID user, boolean administrator)
throws UnsupportedOperationException throws UnsupportedOperationException
{ {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
...@@ -222,10 +221,10 @@ public class LdapGroupProvider implements GroupProvider { ...@@ -222,10 +221,10 @@ public class LdapGroupProvider implements GroupProvider {
* LDAP groups are read-only. * LDAP groups are read-only.
* *
* @param groupName the name of a group. * @param groupName the name of a group.
* @param username the ame of a user. * @param user the JID of the user to delete.
* @throws UnsupportedOperationException when called. * @throws UnsupportedOperationException when called.
*/ */
public void deleteMember(String groupName, String username) public void deleteMember(String groupName, JID user)
throws UnsupportedOperationException { throws UnsupportedOperationException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
...@@ -306,6 +305,8 @@ public class LdapGroupProvider implements GroupProvider { ...@@ -306,6 +305,8 @@ public class LdapGroupProvider implements GroupProvider {
ctrls.setSearchScope(SearchControls.SUBTREE_SCOPE); ctrls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String userSearchFilter = MessageFormat.format(manager.getSearchFilter(), "*"); String userSearchFilter = MessageFormat.format(manager.getSearchFilter(), "*");
XMPPServer server = XMPPServer.getInstance();
String serverName = server.getServerInfo().getName();
while (answer.hasMoreElements()) { while (answer.hasMoreElements()) {
String name = ""; String name = "";
...@@ -319,7 +320,7 @@ public class LdapGroupProvider implements GroupProvider { ...@@ -319,7 +320,7 @@ public class LdapGroupProvider implements GroupProvider {
catch (Exception e) { catch (Exception e) {
description = ""; description = "";
} }
TreeSet<String> members = new TreeSet<String>(); TreeSet<JID> members = new TreeSet<JID>();
Attribute member = a.get(manager.getGroupMemberField()); Attribute member = a.get(manager.getGroupMemberField());
NamingEnumeration ne = member.getAll(); NamingEnumeration ne = member.getAll();
while (ne.hasMore()) { while (ne.hasMore()) {
...@@ -352,13 +353,22 @@ public class LdapGroupProvider implements GroupProvider { ...@@ -352,13 +353,22 @@ public class LdapGroupProvider implements GroupProvider {
// Therefore, we have to try to load each user we found to see if // Therefore, we have to try to load each user we found to see if
// it passes the filter. // it passes the filter.
try { try {
JID userJID = null;
// Create JID of local user if JID does not match a component's JID
if (!username.contains(serverName)) {
// In order to lookup a username from the manager, the username // In order to lookup a username from the manager, the username
// must be a properly escaped JID node. // must be a properly escaped JID node.
String escapedUsername = JID.escapeNode(username); String escapedUsername = JID.escapeNode(username);
userManager.getUser(escapedUsername); userManager.getUser(escapedUsername);
// No exception, so the user must exist. Add the user as a group // No exception, so the user must exist. Add the user as a group
// member using the escaped username. // member using the escaped username.
members.add(escapedUsername); userJID = server.createJID(escapedUsername, null);
}
else {
// This is a JID of a component or node of a server's component
userJID = new JID(username);
}
members.add(userJID);
} }
catch (UserNotFoundException e) { catch (UserNotFoundException e) {
if (manager.isDebugEnabled()) { if (manager.isDebugEnabled()) {
...@@ -369,7 +379,7 @@ public class LdapGroupProvider implements GroupProvider { ...@@ -369,7 +379,7 @@ public class LdapGroupProvider implements GroupProvider {
if (manager.isDebugEnabled()) { if (manager.isDebugEnabled()) {
Log.debug("Adding group \"" + name + "\" with " + members.size() + " members."); Log.debug("Adding group \"" + name + "\" with " + members.size() + " members.");
} }
Group g = new Group(this, name, description, members, new ArrayList<String>()); Group g = new Group(this, name, description, members, new ArrayList<JID>());
groups.put(name, g); groups.put(name, g);
} }
catch (Exception e) { catch (Exception e) {
......
...@@ -83,7 +83,7 @@ public class Roster implements Cacheable { ...@@ -83,7 +83,7 @@ public class Roster implements Cacheable {
try { try {
User rosterUser = UserManager.getInstance().getUser(getUsername()); User rosterUser = UserManager.getInstance().getUser(getUsername());
sharedGroups = rosterManager.getSharedGroups(rosterUser); sharedGroups = rosterManager.getSharedGroups(rosterUser);
userGroups = GroupManager.getInstance().getGroups(rosterUser); userGroups = GroupManager.getInstance().getGroups(getUserJID());
} }
catch (UserNotFoundException e) { catch (UserNotFoundException e) {
sharedGroups = new ArrayList<Group>(); sharedGroups = new ArrayList<Group>();
...@@ -110,8 +110,7 @@ public class Roster implements Cacheable { ...@@ -110,8 +110,7 @@ public class Roster implements Cacheable {
for (JID jid : sharedUsers.keySet()) { for (JID jid : sharedUsers.keySet()) {
try { try {
Collection<Group> itemGroups = new ArrayList<Group>(); Collection<Group> itemGroups = new ArrayList<Group>();
User user = UserManager.getInstance().getUser(jid.getNode()); String nickname = getContactNickname(jid);
String nickname = "".equals(user.getName()) ? jid.getNode() : user.getName();
RosterItem item = new RosterItem(jid, RosterItem.SUB_TO, RosterItem.ASK_NONE, RosterItem item = new RosterItem(jid, RosterItem.SUB_TO, RosterItem.ASK_NONE,
RosterItem.RECV_NONE, nickname , null); RosterItem.RECV_NONE, nickname , null);
// Add the shared groups to the new roster item // Add the shared groups to the new roster item
...@@ -126,8 +125,7 @@ public class Roster implements Cacheable { ...@@ -126,8 +125,7 @@ public class Roster implements Cacheable {
} }
// Set subscription type to BOTH if the roster user belongs to a shared group // Set subscription type to BOTH if the roster user belongs to a shared group
// that is mutually visible with a shared group of the new roster item // that is mutually visible with a shared group of the new roster item
if (rosterManager.hasMutualVisibility(username, userGroups, jid.getNode(), if (rosterManager.hasMutualVisibility(username, userGroups, jid, itemGroups)) {
itemGroups)) {
item.setSubStatus(RosterItem.SUB_BOTH); item.setSubStatus(RosterItem.SUB_BOTH);
} }
else { else {
...@@ -479,13 +477,12 @@ public class Roster implements Cacheable { ...@@ -479,13 +477,12 @@ public class Roster implements Cacheable {
Map<JID,List<Group>> sharedGroupUsers = new HashMap<JID,List<Group>>(); Map<JID,List<Group>> sharedGroupUsers = new HashMap<JID,List<Group>>();
for (Group group : sharedGroups) { for (Group group : sharedGroups) {
// Get all the users that should be in this roster // Get all the users that should be in this roster
Collection<String> users = rosterManager.getSharedUsersForRoster(group, this); Collection<JID> users = rosterManager.getSharedUsersForRoster(group, this);
// 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 user : users) { for (JID jid : users) {
// 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 = XMPPServer.getInstance().createJID(user, null); if (!isRosterItem(jid) && !getUsername().equals(jid.getNode())) {
if (!isRosterItem(jid) && !getUsername().equals(user)) {
List<Group> groups = sharedGroupUsers.get(jid); List<Group> groups = sharedGroupUsers.get(jid);
if (groups == null) { if (groups == null) {
groups = new ArrayList<Group>(); groups = new ArrayList<Group>();
...@@ -572,13 +569,12 @@ public class Roster implements Cacheable { ...@@ -572,13 +569,12 @@ public class Roster implements Cacheable {
* @param group the shared group where the user was added. * @param group the shared group where the user was added.
* @param addedUser the contact to update in the roster. * @param addedUser the contact to update in the roster.
*/ */
void addSharedUser(Group group, String addedUser) { void addSharedUser(Group group, JID addedUser) {
boolean newItem = false; boolean newItem = false;
RosterItem item = null; RosterItem item = null;
JID jid = XMPPServer.getInstance().createJID(addedUser, "");
try { try {
// Get the RosterItem for the *local* user to add // Get the RosterItem for the *local* user to add
item = getRosterItem(jid); item = getRosterItem(addedUser);
// Do nothing if the item already includes the shared group // Do nothing if the item already includes the shared group
if (item.getSharedGroups().contains(group)) { if (item.getSharedGroups().contains(group)) {
return; return;
...@@ -588,10 +584,9 @@ public class Roster implements Cacheable { ...@@ -588,10 +584,9 @@ public class Roster implements Cacheable {
catch (UserNotFoundException e) { catch (UserNotFoundException e) {
try { try {
// Create a new RosterItem for this new user // Create a new RosterItem for this new user
User user = UserManager.getInstance().getUser(addedUser); String nickname = getContactNickname(addedUser);
String nickname = "".equals(user.getName()) ? jid.getNode() : user.getName();
item = item =
new RosterItem(jid, RosterItem.SUB_BOTH, RosterItem.ASK_NONE, new RosterItem(addedUser, RosterItem.SUB_BOTH, RosterItem.ASK_NONE,
RosterItem.RECV_NONE, nickname, null); RosterItem.RECV_NONE, nickname, null);
// Add the new item to the list of items // Add the new item to the list of items
rosterItems.put(item.getJid().toBareJID(), item); rosterItems.put(item.getJid().toBareJID(), item);
...@@ -611,19 +606,14 @@ public class Roster implements Cacheable { ...@@ -611,19 +606,14 @@ public class Roster implements Cacheable {
} }
// Update the subscription of the item **based on the item groups** // Update the subscription of the item **based on the item groups**
Collection<Group> userGroups = null; Collection<Group> userGroups = GroupManager.getInstance().getGroups(getUserJID());
Collection<Group> sharedGroups = new ArrayList<Group>(); Collection<Group> sharedGroups = new ArrayList<Group>();
try {
User rosterUser = UserManager.getInstance().getUser(getUsername());
GroupManager groupManager = GroupManager.getInstance();
userGroups = groupManager.getGroups(rosterUser);
sharedGroups.addAll(item.getSharedGroups()); sharedGroups.addAll(item.getSharedGroups());
// Add the new group to the list of groups to check // Add the new group to the list of groups to check
sharedGroups.add(group); sharedGroups.add(group);
// Set subscription type to BOTH if the roster user belongs to a shared group // Set subscription type to BOTH if the roster user belongs to a shared group
// that is mutually visible with a shared group of the new roster item // that is mutually visible with a shared group of the new roster item
if (rosterManager.hasMutualVisibility(getUsername(), userGroups, jid.getNode(), if (rosterManager.hasMutualVisibility(getUsername(), userGroups, addedUser, sharedGroups)) {
sharedGroups)) {
item.setSubStatus(RosterItem.SUB_BOTH); item.setSubStatus(RosterItem.SUB_BOTH);
} }
// Update the subscription status depending on the group membership of the new // Update the subscription status depending on the group membership of the new
...@@ -634,9 +624,6 @@ public class Roster implements Cacheable { ...@@ -634,9 +624,6 @@ public class Roster implements Cacheable {
else if (!group.isUser(addedUser) && group.isUser(getUsername())) { else if (!group.isUser(addedUser) && group.isUser(getUsername())) {
item.setSubStatus(RosterItem.SUB_FROM); item.setSubStatus(RosterItem.SUB_FROM);
} }
}
catch (UserNotFoundException e) {
}
// Add the shared group to the list of shared groups // Add the shared group to the list of shared groups
if (item.getSubStatus() != RosterItem.SUB_FROM) { if (item.getSubStatus() != RosterItem.SUB_FROM) {
...@@ -675,22 +662,20 @@ public class Roster implements Cacheable { ...@@ -675,22 +662,20 @@ public class Roster implements Cacheable {
* @param addedUser the new contact to add to the roster * @param addedUser the new contact to add to the roster
* @param groups the groups where the contact is a member * @param groups the groups where the contact is a member
*/ */
void addSharedUser(String addedUser, Collection<Group> groups, Group addedGroup) { void addSharedUser(JID addedUser, Collection<Group> groups, Group addedGroup) {
boolean newItem = false; boolean newItem = false;
RosterItem item = null; RosterItem item = null;
JID jid = XMPPServer.getInstance().createJID(addedUser, "");
try { try {
// Get the RosterItem for the *local* user to add // Get the RosterItem for the *local* user to add
item = getRosterItem(jid); item = getRosterItem(addedUser);
newItem = false; newItem = false;
} }
catch (UserNotFoundException e) { catch (UserNotFoundException e) {
try { try {
// Create a new RosterItem for this new user // Create a new RosterItem for this new user
User user = UserManager.getInstance().getUser(addedUser); String nickname = getContactNickname(addedUser);
String nickname = "".equals(user.getName()) ? jid.getNode() : user.getName();
item = item =
new RosterItem(jid, RosterItem.SUB_BOTH, RosterItem.ASK_NONE, new RosterItem(addedUser, RosterItem.SUB_BOTH, RosterItem.ASK_NONE,
RosterItem.RECV_NONE, nickname, null); RosterItem.RECV_NONE, nickname, null);
// Add the new item to the list of items // Add the new item to the list of items
rosterItems.put(item.getJid().toBareJID(), item); rosterItems.put(item.getJid().toBareJID(), item);
...@@ -701,18 +686,13 @@ public class Roster implements Cacheable { ...@@ -701,18 +686,13 @@ public class Roster implements Cacheable {
} }
} }
// Update the subscription of the item **based on the item groups** // Update the subscription of the item **based on the item groups**
Collection<Group> userGroups = null; Collection<Group> userGroups = GroupManager.getInstance().getGroups(getUserJID());
try {
User rosterUser = UserManager.getInstance().getUser(getUsername());
GroupManager groupManager = GroupManager.getInstance();
userGroups = groupManager.getGroups(rosterUser);
// Set subscription type to BOTH if the roster user belongs to a shared group // Set subscription type to BOTH if the roster user belongs to a shared group
// that is mutually visible with a shared group of the new roster item // that is mutually visible with a shared group of the new roster item
if (rosterManager.hasMutualVisibility(getUsername(), userGroups, jid.getNode(), if (rosterManager.hasMutualVisibility(getUsername(), userGroups, addedUser, groups)) {
groups)) {
item.setSubStatus(RosterItem.SUB_BOTH); item.setSubStatus(RosterItem.SUB_BOTH);
for (Group group : groups) { for (Group group : groups) {
if (rosterManager.isGroupVisible(group, getUsername())) { if (rosterManager.isGroupVisible(group, getUserJID())) {
// Add the shared group to the list of shared groups // Add the shared group to the list of shared groups
item.addSharedGroup(group); item.addSharedGroup(group);
} }
...@@ -722,8 +702,7 @@ public class Roster implements Cacheable { ...@@ -722,8 +702,7 @@ public class Roster implements Cacheable {
// fact there is a TO-FROM relation between these two users that ends up in a // fact there is a TO-FROM relation between these two users that ends up in a
// BOTH subscription // BOTH subscription
for (Group group : userGroups) { for (Group group : userGroups) {
if (!group.isUser(addedUser) && if (!group.isUser(addedUser) && rosterManager.isGroupVisible(group, addedUser)) {
rosterManager.isGroupVisible(group, addedUser)) {
// Add the shared group to the list of invisible shared groups // Add the shared group to the list of invisible shared groups
item.addInvisibleSharedGroup(group); item.addInvisibleSharedGroup(group);
} }
...@@ -741,7 +720,7 @@ public class Roster implements Cacheable { ...@@ -741,7 +720,7 @@ public class Roster implements Cacheable {
item.setSubStatus(RosterItem.SUB_FROM); item.setSubStatus(RosterItem.SUB_FROM);
// Check if the user may see the new contact in a shared group // Check if the user may see the new contact in a shared group
for (Group group : groups) { for (Group group : groups) {
if (rosterManager.isGroupVisible(group, getUsername())) { if (rosterManager.isGroupVisible(group, getUserJID())) {
// Add the shared group to the list of shared groups // Add the shared group to the list of shared groups
item.addSharedGroup(group); item.addSharedGroup(group);
item.setSubStatus(RosterItem.SUB_TO); item.setSubStatus(RosterItem.SUB_TO);
...@@ -764,9 +743,6 @@ public class Roster implements Cacheable { ...@@ -764,9 +743,6 @@ public class Roster implements Cacheable {
} }
} }
} }
}
catch (UserNotFoundException e) {
}
// Brodcast to all the user resources of the updated roster item // Brodcast to all the user resources of the updated roster item
broadcast(item, true); broadcast(item, true);
// Probe the presence of the new group user // Probe the presence of the new group user
...@@ -785,11 +761,10 @@ public class Roster implements Cacheable { ...@@ -785,11 +761,10 @@ public class Roster implements Cacheable {
* @param sharedGroup the shared group from where the user was deleted. * @param sharedGroup the shared group from where the user was deleted.
* @param deletedUser the contact to update in the roster. * @param deletedUser the contact to update in the roster.
*/ */
void deleteSharedUser(Group sharedGroup, String deletedUser) { void deleteSharedUser(Group sharedGroup, JID deletedUser) {
JID jid = XMPPServer.getInstance().createJID(deletedUser, "");
try { try {
// Get the RosterItem for the *local* user to remove // Get the RosterItem for the *local* user to remove
RosterItem item = getRosterItem(jid); RosterItem item = getRosterItem(deletedUser);
int groupSize = item.getSharedGroups().size() + item.getInvisibleSharedGroups().size(); int groupSize = item.getSharedGroups().size() + item.getInvisibleSharedGroups().size();
if (item.isOnlyShared() && groupSize == 1) { if (item.isOnlyShared() && groupSize == 1) {
// Do nothing if the existing shared group is not the sharedGroup to remove // Do nothing if the existing shared group is not the sharedGroup to remove
...@@ -798,24 +773,21 @@ public class Roster implements Cacheable { ...@@ -798,24 +773,21 @@ public class Roster implements Cacheable {
} }
// Delete the roster item from the roster since it exists only because of this // Delete the roster item from the roster since it exists only because of this
// group which is being removed // group which is being removed
deleteRosterItem(jid, false); deleteRosterItem(deletedUser, false);
} }
else { else {
// Remove the removed shared group from the list of shared groups // Remove the removed shared group from the list of shared groups
item.removeSharedGroup(sharedGroup); item.removeSharedGroup(sharedGroup);
// Update the subscription of the item based on the remaining groups // Update the subscription of the item based on the remaining groups
if (item.isOnlyShared()) { if (item.isOnlyShared()) {
Collection<Group> userGroups = null; Collection<Group> userGroups =
GroupManager.getInstance().getGroups(getUserJID());
Collection<Group> sharedGroups = new ArrayList<Group>(); Collection<Group> sharedGroups = new ArrayList<Group>();
try {
User rosterUser = UserManager.getInstance().getUser(getUsername());
GroupManager groupManager = GroupManager.getInstance();
userGroups = groupManager.getGroups(rosterUser);
sharedGroups.addAll(item.getSharedGroups()); sharedGroups.addAll(item.getSharedGroups());
// Set subscription type to BOTH if the roster user belongs to a shared group // Set subscription type to BOTH if the roster user belongs to a shared group
// that is mutually visible with a shared group of the new roster item // that is mutually visible with a shared group of the new roster item
if (rosterManager.hasMutualVisibility(getUsername(), userGroups, if (rosterManager.hasMutualVisibility(getUsername(), userGroups, deletedUser,
jid.getNode(), sharedGroups)) { sharedGroups)) {
item.setSubStatus(RosterItem.SUB_BOTH); item.setSubStatus(RosterItem.SUB_BOTH);
} }
else if (item.getSharedGroups().isEmpty() && else if (item.getSharedGroups().isEmpty() &&
...@@ -825,10 +797,6 @@ public class Roster implements Cacheable { ...@@ -825,10 +797,6 @@ public class Roster implements Cacheable {
else { else {
item.setSubStatus(RosterItem.SUB_TO); item.setSubStatus(RosterItem.SUB_TO);
} }
}
catch (UserNotFoundException e) {
}
} }
// Brodcast to all the user resources of the updated roster item // Brodcast to all the user resources of the updated roster item
broadcast(item, false); broadcast(item, false);
...@@ -842,11 +810,10 @@ public class Roster implements Cacheable { ...@@ -842,11 +810,10 @@ public class Roster implements Cacheable {
} }
} }
void deleteSharedUser(String deletedUser, Collection<Group> groups, Group deletedGroup) { void deleteSharedUser(JID deletedUser, Collection<Group> groups, Group deletedGroup) {
JID jid = XMPPServer.getInstance().createJID(deletedUser, "");
try { try {
// Get the RosterItem for the *local* user to remove // Get the RosterItem for the *local* user to remove
RosterItem item = getRosterItem(jid); RosterItem item = getRosterItem(deletedUser);
int groupSize = item.getSharedGroups().size() + item.getInvisibleSharedGroups().size(); int groupSize = item.getSharedGroups().size() + item.getInvisibleSharedGroups().size();
if (item.isOnlyShared() && groupSize == 1 && if (item.isOnlyShared() && groupSize == 1 &&
// Do not delete the item if deletedUser belongs to a public group since the // Do not delete the item if deletedUser belongs to a public group since the
...@@ -855,7 +822,7 @@ public class Roster implements Cacheable { ...@@ -855,7 +822,7 @@ public class Roster implements Cacheable {
rosterManager.isGroupPublic(deletedGroup))) { rosterManager.isGroupPublic(deletedGroup))) {
// Delete the roster item from the roster since it exists only because of this // Delete the roster item from the roster since it exists only because of this
// group which is being removed // group which is being removed
deleteRosterItem(jid, false); deleteRosterItem(deletedUser, false);
} }
else { else {
// Remove the shared group from the item if deletedUser does not belong to a // Remove the shared group from the item if deletedUser does not belong to a
...@@ -866,7 +833,7 @@ public class Roster implements Cacheable { ...@@ -866,7 +833,7 @@ public class Roster implements Cacheable {
} }
// Remove all invalid shared groups from the roster item // Remove all invalid shared groups from the roster item
for (Group group : groups) { for (Group group : groups) {
if (!rosterManager.isGroupVisible(group, getUsername())) { if (!rosterManager.isGroupVisible(group, getUserJID())) {
// Remove the shared group from the list of shared groups // Remove the shared group from the list of shared groups
item.removeSharedGroup(group); item.removeSharedGroup(group);
} }
...@@ -874,15 +841,12 @@ public class Roster implements Cacheable { ...@@ -874,15 +841,12 @@ public class Roster implements Cacheable {
// Update the subscription of the item **based on the item groups** // Update the subscription of the item **based on the item groups**
if (item.isOnlyShared()) { if (item.isOnlyShared()) {
Collection<Group> userGroups = null; Collection<Group> userGroups =
try { userGroups = GroupManager.getInstance().getGroups(getUserJID());
User rosterUser = UserManager.getInstance().getUser(getUsername());
GroupManager groupManager = GroupManager.getInstance();
userGroups = groupManager.getGroups(rosterUser);
// Set subscription type to BOTH if the roster user belongs to a shared group // Set subscription type to BOTH if the roster user belongs to a shared group
// that is mutually visible with a shared group of the new roster item // that is mutually visible with a shared group of the new roster item
if (rosterManager.hasMutualVisibility(getUsername(), userGroups, if (rosterManager
jid.getNode(), groups)) { .hasMutualVisibility(getUsername(), userGroups, deletedUser, groups)) {
item.setSubStatus(RosterItem.SUB_BOTH); item.setSubStatus(RosterItem.SUB_BOTH);
} }
else { else {
...@@ -891,15 +855,12 @@ public class Roster implements Cacheable { ...@@ -891,15 +855,12 @@ public class Roster implements Cacheable {
item.setSubStatus(RosterItem.SUB_FROM); item.setSubStatus(RosterItem.SUB_FROM);
// Check if the user may see the new contact in a shared group // Check if the user may see the new contact in a shared group
for (Group group : groups) { for (Group group : groups) {
if (rosterManager.isGroupVisible(group, getUsername())) { if (rosterManager.isGroupVisible(group, getUserJID())) {
item.setSubStatus(RosterItem.SUB_TO); item.setSubStatus(RosterItem.SUB_TO);
} }
} }
} }
} }
catch (UserNotFoundException e) {
}
}
// Brodcast to all the user resources of the updated roster item // Brodcast to all the user resources of the updated roster item
broadcast(item, false); broadcast(item, false);
} }
...@@ -918,16 +879,16 @@ public class Roster implements Cacheable { ...@@ -918,16 +879,16 @@ public class Roster implements Cacheable {
* *
* @param users group users of the renamed group. * @param users group users of the renamed group.
*/ */
void shareGroupRenamed(Collection<String> users) { void shareGroupRenamed(Collection<JID> users) {
for (String user : users) { JID userJID = getUserJID();
if (username.equals(user)) { for (JID user : users) {
if (userJID.equals(user)) {
continue; continue;
} }
RosterItem item = null; RosterItem item = null;
JID jid = XMPPServer.getInstance().createJID(user, "");
try { try {
// Get the RosterItem for the *local* user to add // Get the RosterItem for the *local* user to add
item = getRosterItem(jid); item = getRosterItem(user);
// Brodcast to all the user resources of the updated roster item // Brodcast to all the user resources of the updated roster item
broadcast(item, true); broadcast(item, true);
} }
...@@ -936,4 +897,22 @@ public class Roster implements Cacheable { ...@@ -936,4 +897,22 @@ public class Roster implements Cacheable {
} }
} }
} }
private String getContactNickname(JID jid) throws UserNotFoundException {
String nickname;
if (server.isLocal(jid)) {
// Contact is a local user so search for his user name
User user = UserManager.getInstance().getUser(jid.getNode());
nickname = "".equals(user.getName()) ? jid.getNode() : user.getName();
}
else {
// Contact is a remote user so use his JID as his nickname
nickname = jid.toString();
}
return nickname;
}
private JID getUserJID() {
return XMPPServer.getInstance().createJID(getUsername(), null);
}
} }
\ No newline at end of file
/** /**
* $RCSfile$ * $RCSfile: RosterManager.java,v $
* $Revision$ * $Revision$
* $Date$ * $Date$
* *
...@@ -12,13 +12,15 @@ ...@@ -12,13 +12,15 @@
package org.jivesoftware.messenger.roster; package org.jivesoftware.messenger.roster;
import org.xmpp.packet.JID; import org.xmpp.packet.JID;
import org.xmpp.packet.Presence;
import org.jivesoftware.util.Cache; import org.jivesoftware.util.Cache;
import org.jivesoftware.util.CacheManager; 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.user.User; import org.jivesoftware.messenger.user.User;
import org.jivesoftware.messenger.user.UserManager; import org.jivesoftware.messenger.user.UserManager;
import org.jivesoftware.messenger.SharedGroupException; import org.jivesoftware.messenger.*;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.event.GroupEventListener; import org.jivesoftware.messenger.event.GroupEventListener;
import org.jivesoftware.messenger.event.GroupEventDispatcher; import org.jivesoftware.messenger.event.GroupEventDispatcher;
import org.jivesoftware.messenger.group.Group; import org.jivesoftware.messenger.group.Group;
...@@ -41,6 +43,8 @@ import java.util.*; ...@@ -41,6 +43,8 @@ import java.util.*;
public class RosterManager extends BasicModule implements GroupEventListener { public class RosterManager extends BasicModule implements GroupEventListener {
private Cache rosterCache = null; private Cache rosterCache = null;
private XMPPServer server;
private RoutingTable routingTable;
public RosterManager() { public RosterManager() {
super("Roster Manager"); super("Roster Manager");
...@@ -82,6 +86,10 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -82,6 +86,10 @@ public class RosterManager extends BasicModule implements GroupEventListener {
* @param user the user. * @param user the user.
*/ */
public void deleteRoster(JID user) { public void deleteRoster(JID user) {
if (!server.isLocal(user)) {
// Ignore request if user is not a local user
return;
}
try { try {
String username = user.getNode(); String username = user.getNode();
// Get the roster of the deleted user // Get the roster of the deleted user
...@@ -197,7 +205,7 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -197,7 +205,7 @@ public class RosterManager extends BasicModule implements GroupEventListener {
public void groupDeleting(Group group, Map params) { public void groupDeleting(Group group, Map params) {
// Iterate on all the group users and update their rosters // Iterate on all the group users and update their rosters
for (String deletedUser : getAffectedUsers(group)) { for (JID deletedUser : getAffectedUsers(group)) {
groupUserDeleted(group, deletedUser); groupUserDeleted(group, deletedUser);
} }
} }
...@@ -218,24 +226,21 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -218,24 +226,21 @@ public class RosterManager extends BasicModule implements GroupEventListener {
return; return;
} }
// Get the users of the group // Get the users of the group
Collection<String> users = new HashSet<String>(group.getMembers()); Collection<JID> users = new HashSet<JID>(group.getMembers());
users.addAll(group.getAdmins()); users.addAll(group.getAdmins());
// Get the users whose roster will be affected // Get the users whose roster will be affected
Collection<String> affectedUsers = getAffectedUsers(group, originalValue, Collection<JID> affectedUsers = getAffectedUsers(group, originalValue,
group.getProperties().get("sharedRoster.groupList")); group.getProperties().get("sharedRoster.groupList"));
// Remove the group members from the affected rosters // Remove the group members from the affected rosters
for (String deletedUser : users) { for (JID deletedUser : users) {
groupUserDeleted(group, affectedUsers, deletedUser); groupUserDeleted(group, affectedUsers, deletedUser);
} }
// Simulate that the group users has been added to the group. This will cause to push // Simulate that the group users has been added to the group. This will cause to push
// roster items to the "affected" users for the group users // roster items to the "affected" users for the group users
//Collection<Group> visibleGroups = getVisibleGroups(group); //Collection<Group> visibleGroups = getVisibleGroups(group);
for (String user : users) { for (JID user : users) {
groupUserAdded(group, user); groupUserAdded(group, user);
/*for (Group visibleGroup : visibleGroups) {
addSharedGroupToRoster(visibleGroup, user);
}*/
} }
} }
else if ("sharedRoster.groupList".equals(keyChanged)) { else if ("sharedRoster.groupList".equals(keyChanged)) {
...@@ -245,24 +250,21 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -245,24 +250,21 @@ public class RosterManager extends BasicModule implements GroupEventListener {
return; return;
} }
// Get the users of the group // Get the users of the group
Collection<String> users = new HashSet<String>(group.getMembers()); Collection<JID> users = new HashSet<JID>(group.getMembers());
users.addAll(group.getAdmins()); users.addAll(group.getAdmins());
// Get the users whose roster will be affected // Get the users whose roster will be affected
Collection<String> affectedUsers = getAffectedUsers(group, Collection<JID> affectedUsers = getAffectedUsers(group,
group.getProperties().get("sharedRoster.showInRoster"), originalValue); group.getProperties().get("sharedRoster.showInRoster"), originalValue);
// Remove the group members from the affected rosters // Remove the group members from the affected rosters
for (String deletedUser : users) { for (JID deletedUser : users) {
groupUserDeleted(group, affectedUsers, deletedUser); groupUserDeleted(group, affectedUsers, deletedUser);
} }
// Simulate that the group users has been added to the group. This will cause to push // Simulate that the group users has been added to the group. This will cause to push
// roster items to the "affected" users for the group users // roster items to the "affected" users for the group users
//Collection<Group> visibleGroups = getVisibleGroups(group); //Collection<Group> visibleGroups = getVisibleGroups(group);
for (String user : users) { for (JID user : users) {
groupUserAdded(group, user); groupUserAdded(group, user);
/*for (Group visibleGroup : visibleGroups) {
addSharedGroupToRoster(visibleGroup, user);
}*/
} }
} }
else if ("sharedRoster.displayName".equals(keyChanged)) { else if ("sharedRoster.displayName".equals(keyChanged)) {
...@@ -276,11 +278,15 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -276,11 +278,15 @@ public class RosterManager extends BasicModule implements GroupEventListener {
return; return;
} }
// Get all the affected users // Get all the affected users
Collection<String> users = getAffectedUsers(group); Collection<JID> users = getAffectedUsers(group);
// Iterate on all the affected users and update their rosters // Iterate on all the affected users and update their rosters
for (String updatedUser : users) { for (JID updatedUser : users) {
// Get the roster to update. // Get the roster to update.
Roster roster = (Roster) CacheManager.getCache("username2roster").get(updatedUser); Roster roster = null;
if (server.isLocal(updatedUser)) {
roster = (Roster) CacheManager.getCache("username2roster")
.get(updatedUser.getNode());
}
if (roster != null) { if (roster != null) {
// Update the roster with the new group display name // Update the roster with the new group display name
roster.shareGroupRenamed(users); roster.shareGroupRenamed(users);
...@@ -289,6 +295,12 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -289,6 +295,12 @@ public class RosterManager extends BasicModule implements GroupEventListener {
} }
} }
public void initialize(XMPPServer server) {
super.initialize(server);
this.server = server;
this.routingTable = server.getRoutingTable();
}
/** /**
* Returns true if the specified Group may be included in a user roster. The decision is made * Returns true if the specified Group may be included in a user roster. The decision is made
* based on the group properties that are configurable through the Admin Console. * based on the group properties that are configurable through the Admin Console.
...@@ -305,14 +317,17 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -305,14 +317,17 @@ public class RosterManager extends BasicModule implements GroupEventListener {
} }
public void memberAdded(Group group, Map params) { public void memberAdded(Group group, Map params) {
String addedUser = (String) params.get("member"); JID addedUser = new JID((String) params.get("member"));
// Do nothing if the user was an admin that became a member // Do nothing if the user was an admin that became a member
if (group.getAdmins().contains(addedUser)) { if (group.getAdmins().contains(addedUser)) {
return; return;
} }
if (!isSharedGroup(group)) { if (!isSharedGroup(group)) {
for (Group visibleGroup : getVisibleGroups(group)) { for (Group visibleGroup : getVisibleGroups(group)) {
addSharedGroupToRoster(visibleGroup, addedUser); // Get the list of affected users
Collection<JID> users = new HashSet<JID>(group.getMembers());
users.addAll(group.getAdmins());
groupUserAdded(visibleGroup, users, addedUser);
} }
} }
else { else {
...@@ -321,14 +336,17 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -321,14 +336,17 @@ public class RosterManager extends BasicModule implements GroupEventListener {
} }
public void memberRemoved(Group group, Map params) { public void memberRemoved(Group group, Map params) {
String deletedUser = (String) params.get("member"); JID deletedUser = new JID((String) params.get("member"));
// Do nothing if the user is still an admin // Do nothing if the user is still an admin
if (group.getAdmins().contains(deletedUser)) { if (group.getAdmins().contains(deletedUser)) {
return; return;
} }
if (!isSharedGroup(group)) { if (!isSharedGroup(group)) {
for (Group visibleGroup : getVisibleGroups(group)) { for (Group visibleGroup : getVisibleGroups(group)) {
removeSharedGroupFromRoster(visibleGroup, deletedUser); // Get the list of affected users
Collection<JID> users = new HashSet<JID>(group.getMembers());
users.addAll(group.getAdmins());
groupUserDeleted(visibleGroup, users, deletedUser);
} }
} }
else { else {
...@@ -337,14 +355,17 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -337,14 +355,17 @@ public class RosterManager extends BasicModule implements GroupEventListener {
} }
public void adminAdded(Group group, Map params) { public void adminAdded(Group group, Map params) {
String addedUser = (String) params.get("admin"); JID addedUser = new JID((String) params.get("admin"));
// Do nothing if the user was a member that became an admin // Do nothing if the user was a member that became an admin
if (group.getMembers().contains(addedUser)) { if (group.getMembers().contains(addedUser)) {
return; return;
} }
if (!isSharedGroup(group)) { if (!isSharedGroup(group)) {
for (Group visibleGroup : getVisibleGroups(group)) { for (Group visibleGroup : getVisibleGroups(group)) {
addSharedGroupToRoster(visibleGroup, addedUser); // Get the list of affected users
Collection<JID> users = new HashSet<JID>(group.getMembers());
users.addAll(group.getAdmins());
groupUserAdded(visibleGroup, users, addedUser);
} }
} }
else { else {
...@@ -353,7 +374,7 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -353,7 +374,7 @@ public class RosterManager extends BasicModule implements GroupEventListener {
} }
public void adminRemoved(Group group, Map params) { public void adminRemoved(Group group, Map params) {
String deletedUser = (String) params.get("admin"); JID deletedUser = new JID((String) params.get("admin"));
// Do nothing if the user is still a member // Do nothing if the user is still a member
if (group.getMembers().contains(deletedUser)) { if (group.getMembers().contains(deletedUser)) {
return; return;
...@@ -361,7 +382,10 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -361,7 +382,10 @@ public class RosterManager extends BasicModule implements GroupEventListener {
// Do nothing if the group is not being shown in group members' rosters // Do nothing if the group is not being shown in group members' rosters
if (!isSharedGroup(group)) { if (!isSharedGroup(group)) {
for (Group visibleGroup : getVisibleGroups(group)) { for (Group visibleGroup : getVisibleGroups(group)) {
removeSharedGroupFromRoster(visibleGroup, deletedUser); // Get the list of affected users
Collection<JID> users = new HashSet<JID>(group.getMembers());
users.addAll(group.getAdmins());
groupUserDeleted(visibleGroup, users, deletedUser);
} }
} }
else { else {
...@@ -375,30 +399,62 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -375,30 +399,62 @@ public class RosterManager extends BasicModule implements GroupEventListener {
* @param group the group where the user was added. * @param group the group where the user was added.
* @param addedUser the username of the user that has been added to the group. * @param addedUser the username of the user that has been added to the group.
*/ */
private void groupUserAdded(Group group, String addedUser) { private void groupUserAdded(Group group, JID addedUser) {
// Get all the affected users groupUserAdded(group, getAffectedUsers(group), addedUser);
Collection<String> users = getAffectedUsers(group); }
/**
* Notification that a Group user has been added. Update the group users' roster accordingly.
*
* @param group the group where the user was added.
* @param users the users to update their rosters
* @param addedUser the username of the user that has been added to the group.
*/
private void groupUserAdded(Group group, Collection<JID> users, JID addedUser) {
// Get the roster of the added user. // Get the roster of the added user.
Roster addedUserRoster = (Roster) CacheManager.getCache("username2roster").get(addedUser); Roster addedUserRoster = null;
if (server.isLocal(addedUser)) {
addedUserRoster =
(Roster) CacheManager.getCache("username2roster").get(addedUser.getNode());
}
// Iterate on all the affected users and update their rosters // Iterate on all the affected users and update their rosters
for (String userToUpdate : users) { for (JID userToUpdate : users) {
if (!addedUser.equals(userToUpdate)) { if (!addedUser.equals(userToUpdate)) {
// Get the roster to update // Get the roster to update
Roster roster = (Roster)CacheManager.getCache("username2roster").get(userToUpdate); Roster roster = null;
if (server.isLocal(userToUpdate)) {
// Check that the user exists, if not then continue with the next user
try {
UserManager.getInstance().getUser(userToUpdate.getNode());
}
catch (UserNotFoundException e) {
continue;
}
roster = (Roster) CacheManager.getCache("username2roster")
.get(userToUpdate.getNode());
}
if (!server.isLocal(addedUser)) {
// Susbcribe to the presence of the remote user. This is only necessary for
// remote users and may only work with remote users that **automatically**
// accept presence subscription requests
sendSubscribeRequest(userToUpdate, addedUser, true);
}
if (!server.isLocal(userToUpdate)) {
// Susbcribe to the presence of the remote user. This is only necessary for
// remote users and may only work with remote users that **automatically**
// accept presence subscription requests
sendSubscribeRequest(addedUser, userToUpdate, true);
}
// Only update rosters in memory // Only update rosters in memory
if (roster != null) { if (roster != null) {
roster.addSharedUser(group, addedUser); roster.addSharedUser(group, addedUser);
} }
// Update the roster of the newly added group user. // Update the roster of the newly added group user.
if (addedUserRoster != null) { if (addedUserRoster != null) {
try { Collection<Group> groups = GroupManager.getInstance().getGroups(userToUpdate);
User user = UserManager.getInstance().getUser(userToUpdate);
Collection<Group> groups = GroupManager.getInstance().getGroups(user);
addedUserRoster.addSharedUser(userToUpdate, groups, group); addedUserRoster.addSharedUser(userToUpdate, groups, group);
} }
catch (UserNotFoundException e) {}
}
} }
} }
} }
...@@ -409,7 +465,7 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -409,7 +465,7 @@ public class RosterManager extends BasicModule implements GroupEventListener {
* @param group the group from where the user was deleted. * @param group the group from where the user was deleted.
* @param deletedUser the username of the user that has been deleted from the group. * @param deletedUser the username of the user that has been deleted from the group.
*/ */
private void groupUserDeleted(Group group, String deletedUser) { private void groupUserDeleted(Group group, JID deletedUser) {
groupUserDeleted(group, getAffectedUsers(group), deletedUser); groupUserDeleted(group, getAffectedUsers(group), deletedUser);
} }
...@@ -420,28 +476,69 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -420,28 +476,69 @@ public class RosterManager extends BasicModule implements GroupEventListener {
* @param users the users to update their rosters * @param users the users to update their rosters
* @param deletedUser the username of the user that has been deleted from the group. * @param deletedUser the username of the user that has been deleted from the group.
*/ */
private void groupUserDeleted(Group group, Collection<String> users, String deletedUser) { private void groupUserDeleted(Group group, Collection<JID> users, JID deletedUser) {
// Get the roster of the deleted user. // Get the roster of the deleted user.
Roster deletedUserRoster = (Roster) CacheManager.getCache("username2roster").get(deletedUser); Roster deletedUserRoster = null;
if (server.isLocal(deletedUser)) {
deletedUserRoster =
(Roster) CacheManager.getCache("username2roster").get(deletedUser.getNode());
}
// Iterate on all the affected users and update their rosters // Iterate on all the affected users and update their rosters
for (String userToUpdate : users) { for (JID userToUpdate : users) {
// Get the roster to update // Get the roster to update
Roster roster = (Roster)CacheManager.getCache("username2roster").get(userToUpdate); Roster roster = null;
if (server.isLocal(userToUpdate)) {
// Check that the user exists, if not then continue with the next user
try {
UserManager.getInstance().getUser(userToUpdate.getNode());
}
catch (UserNotFoundException e) {
continue;
}
roster = (Roster) CacheManager.getCache("username2roster")
.get(userToUpdate.getNode());
}
if (!server.isLocal(deletedUser)) {
// Unsusbcribe from the presence of the remote user. This is only necessary for
// remote users and may only work with remote users that **automatically**
// accept presence subscription requests
sendSubscribeRequest(userToUpdate, deletedUser, false);
}
if (!server.isLocal(userToUpdate)) {
// Unsusbcribe from the presence of the remote user. This is only necessary for
// remote users and may only work with remote users that **automatically**
// accept presence subscription requests
sendSubscribeRequest(deletedUser, userToUpdate, false);
}
// Only update rosters in memory // Only update rosters in memory
if (roster != null) { if (roster != null) {
roster.deleteSharedUser(group, deletedUser); roster.deleteSharedUser(group, deletedUser);
} }
// Update the roster of the newly deleted group user. // Update the roster of the newly deleted group user.
if (deletedUserRoster != null) { if (deletedUserRoster != null) {
try { Collection<Group> groups = GroupManager.getInstance().getGroups(userToUpdate);
User user = UserManager.getInstance().getUser(userToUpdate);
Collection<Group> groups = GroupManager.getInstance().getGroups(user);
deletedUserRoster.deleteSharedUser(userToUpdate, groups, group); deletedUserRoster.deleteSharedUser(userToUpdate, groups, group);
} }
catch (UserNotFoundException e) {}
} }
} }
private void sendSubscribeRequest(JID sender, JID recipient, boolean isSubscribe) {
Presence presence = new Presence();
presence.setFrom(sender);
presence.setTo(recipient);
if (isSubscribe) {
presence.setType(Presence.Type.subscribe);
}
else {
presence.setType(Presence.Type.unsubscribe);
}
try {
ChannelHandler handler = routingTable.getRoute(recipient);
handler.process(presence);
}
catch (NoSuchRouteException e) {}
catch (UnauthorizedException e) {}
} }
private Collection<Group> getVisibleGroups(Group groupToCheck) { private Collection<Group> getVisibleGroups(Group groupToCheck) {
...@@ -487,23 +584,23 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -487,23 +584,23 @@ public class RosterManager extends BasicModule implements GroupEventListener {
* see the group in his roster. * see the group in his roster.
* *
* @param group the group to check if the user can see. * @param group the group to check if the user can see.
* @param username the user to check if he may see the group. * @param user the JID of the user to check if he may see the group.
* @return true if a given group is visible to a given user. * @return true if a given group is visible to a given user.
*/ */
boolean isGroupVisible(Group group, String username) { boolean isGroupVisible(Group group, JID user) {
String showInRoster = group.getProperties().get("sharedRoster.showInRoster"); String showInRoster = group.getProperties().get("sharedRoster.showInRoster");
if ("everybody".equals(showInRoster)) { if ("everybody".equals(showInRoster)) {
return true; return true;
} }
else if ("onlyGroup".equals(showInRoster)) { else if ("onlyGroup".equals(showInRoster)) {
if (group.isUser(username)) { if (group.isUser(user)) {
return true; return true;
} }
// Check if the user belongs to a group that may see this group // Check if the user belongs to a group that may see this group
Collection<Group> groupList = parseGroups(group.getProperties().get( Collection<Group> groupList = parseGroups(group.getProperties().get(
"sharedRoster.groupList")); "sharedRoster.groupList"));
for (Group groupInList : groupList) { for (Group groupInList : groupList) {
if (groupInList.isUser(username)) { if (groupInList.isUser(user)) {
return true; return true;
} }
} }
...@@ -511,68 +608,6 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -511,68 +608,6 @@ public class RosterManager extends BasicModule implements GroupEventListener {
return false; return false;
} }
/**
* Adds the group users of the given shared group to the roster of the specified user.
*
* @param group the shared group to add to the roster of a user.
* @param username the name of the user to add a shared group to his roster.
*/
private void addSharedGroupToRoster(Group group, String username) {
// Get the group users to add to the user's roster
Collection<String> users = new HashSet<String>(group.getMembers());
users.addAll(group.getAdmins());
// Get the roster of the user from which we need to add the shared group users
Roster userRoster = (Roster) CacheManager.getCache("username2roster").get(username);
// Iterate on all the group users and update their rosters
for (String userToAdd : users) {
// Get the roster to update
Roster roster = (Roster)CacheManager.getCache("username2roster").get(userToAdd);
// Only update rosters in memory
if (roster != null) {
roster.addSharedUser(group, username);
}
// Update the roster of the user
if (userRoster != null) {
try {
User user = UserManager.getInstance().getUser(userToAdd);
Collection<Group> groups = GroupManager.getInstance().getGroups(user);
userRoster.addSharedUser(userToAdd, groups, group);
}
catch (UserNotFoundException e) {}
}
}
}
private void removeSharedGroupFromRoster(Group group, String username) {
// Get the group users to remove from the user's roster
Collection<String> users = new HashSet<String>(group.getMembers());
users.addAll(group.getAdmins());
// Get the roster of the user from which we need to remove the shared group users
Roster userRoster = (Roster) CacheManager.getCache("username2roster").get(username);
// Iterate on all the group users and update their rosters
for (String userToRemove : users) {
// Get the roster to update
Roster roster = (Roster)CacheManager.getCache("username2roster").get(userToRemove);
// Only update rosters in memory
if (roster != null) {
roster.deleteSharedUser(group, username);
}
// Update the roster of the user
if (userRoster != null) {
try {
User user = UserManager.getInstance().getUser(userToRemove);
Collection<Group> groups = GroupManager.getInstance().getGroups(user);
userRoster.deleteSharedUser(userToRemove, groups, group);
}
catch (UserNotFoundException e) {}
}
}
}
/** /**
* Returns all the users that are related to a shared group. This is the logic that we are * Returns all the users that are related to a shared group. This is the logic that we are
* using: 1) If the group visiblity is configured as "Everybody" then all users in the system or * using: 1) If the group visiblity is configured as "Everybody" then all users in the system or
...@@ -582,7 +617,7 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -582,7 +617,7 @@ public class RosterManager extends BasicModule implements GroupEventListener {
* the group allows other groups to include the group in the groups users' roster then all * the group allows other groups to include the group in the groups users' roster then all
* the users of the allowed groups will be included in the answer. * the users of the allowed groups will be included in the answer.
*/ */
private Collection<String> getAffectedUsers(Group group) { private Collection<JID> getAffectedUsers(Group group) {
return getAffectedUsers(group, group.getProperties().get("sharedRoster.showInRoster"), return getAffectedUsers(group, group.getProperties().get("sharedRoster.showInRoster"),
group.getProperties().get("sharedRoster.groupList")); group.getProperties().get("sharedRoster.groupList"));
} }
...@@ -595,19 +630,19 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -595,19 +630,19 @@ public class RosterManager extends BasicModule implements GroupEventListener {
* This is useful when the group is being edited and some properties has changed and we need to * This is useful when the group is being edited and some properties has changed and we need to
* obtain the related users of the group based on the previous group state. * obtain the related users of the group based on the previous group state.
*/ */
private Collection<String> getAffectedUsers(Group group, String showInRoster, String groupNames) { private Collection<JID> getAffectedUsers(Group group, String showInRoster, String groupNames) {
// Answer an empty collection if the group is not being shown in users' rosters // Answer an empty collection if the group is not being shown in users' rosters
if (!"onlyGroup".equals(showInRoster) && !"everybody".equals(showInRoster)) { if (!"onlyGroup".equals(showInRoster) && !"everybody".equals(showInRoster)) {
return new ArrayList<String>(); return new ArrayList<JID>();
} }
// Add the users of the group // Add the users of the group
Collection<String> users = new HashSet<String>(group.getMembers()); Collection<JID> users = new HashSet<JID>(group.getMembers());
users.addAll(group.getAdmins()); users.addAll(group.getAdmins());
// Check if anyone can see this shared group // Check if anyone can see this shared group
if ("everybody".equals(showInRoster)) { if ("everybody".equals(showInRoster)) {
// Add all users in the system // Add all users in the system
for (User user : UserManager.getInstance().getUsers()) { for (User user : UserManager.getInstance().getUsers()) {
users.add(user.getUsername()); users.add(server.createJID(user.getUsername(), null));
} }
// Add all logged users. We don't need to add all users in the system since only the // Add all logged users. We don't need to add all users in the system since only the
// logged ones will be affected. // logged ones will be affected.
...@@ -624,17 +659,17 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -624,17 +659,17 @@ public class RosterManager extends BasicModule implements GroupEventListener {
return users; return users;
} }
Collection<String> getSharedUsersForRoster(Group group, Roster roster) { Collection<JID> getSharedUsersForRoster(Group group, Roster roster) {
String showInRoster = group.getProperties().get("sharedRoster.showInRoster"); String showInRoster = group.getProperties().get("sharedRoster.showInRoster");
String groupNames = group.getProperties().get("sharedRoster.groupList"); String groupNames = group.getProperties().get("sharedRoster.groupList");
// Answer an empty collection if the group is not being shown in users' rosters // Answer an empty collection if the group is not being shown in users' rosters
if (!"onlyGroup".equals(showInRoster) && !"everybody".equals(showInRoster)) { if (!"onlyGroup".equals(showInRoster) && !"everybody".equals(showInRoster)) {
return new ArrayList<String>(); return new ArrayList<JID>();
} }
// Add the users of the group // Add the users of the group
Collection<String> users = new HashSet<String>(group.getMembers()); Collection<JID> users = new HashSet<JID>(group.getMembers());
users.addAll(group.getAdmins()); users.addAll(group.getAdmins());
// Check if anyone can see this shared group // Check if anyone can see this shared group
...@@ -644,7 +679,7 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -644,7 +679,7 @@ public class RosterManager extends BasicModule implements GroupEventListener {
if (group.isUser(roster.getUsername())) { if (group.isUser(roster.getUsername())) {
// Add all users in the system // Add all users in the system
for (User user : UserManager.getInstance().getUsers()) { for (User user : UserManager.getInstance().getUsers()) {
users.add(user.getUsername()); users.add(server.createJID(user.getUsername(),null));
} }
} }
} }
...@@ -666,14 +701,14 @@ public class RosterManager extends BasicModule implements GroupEventListener { ...@@ -666,14 +701,14 @@ public class RosterManager extends BasicModule implements GroupEventListener {
* each other and the users are members of those groups or if one group is public and the * each other and the users are members of those groups or if one group is public and the
* other group allowed the public group to see it. * other group allowed the public group to see it.
* *
* @param user the name of the user associated to the first collection of groups. * @param user the name of the user associated to the first collection of groups. This is always a local user.
* @param groups a collection of groups to check against the other collection of groups. * @param groups a collection of groups to check against the other collection of groups.
* @param otherUser the name of the user associated to the second collection of groups. * @param otherUser the JID of the user associated to the second collection of groups.
* @param otherGroups the other collection of groups to check against the first collection. * @param otherGroups the other collection of groups to check against the first collection.
* @return true if a group in the first collection may mutually see a group of the * @return true if a group in the first collection may mutually see a group of the
* second collection. * second collection.
*/ */
boolean hasMutualVisibility(String user, Collection<Group> groups, String otherUser, boolean hasMutualVisibility(String user, Collection<Group> groups, JID otherUser,
Collection<Group> otherGroups) { Collection<Group> otherGroups) {
for (Group group : groups) { for (Group group : groups) {
for (Group otherGroup : otherGroups) { for (Group otherGroup : otherGroups) {
......
...@@ -164,9 +164,8 @@ public class BroadcastPlugin implements Plugin, Component, PropertyEventListener ...@@ -164,9 +164,8 @@ public class BroadcastPlugin implements Plugin, Component, PropertyEventListener
if (disableGroupPermissions || if (disableGroupPermissions ||
(groupMembersAllowed && group.isUser(message.getFrom())) || (groupMembersAllowed && group.isUser(message.getFrom())) ||
allowedUsers.contains(message.getFrom().toBareJID())) { allowedUsers.contains(message.getFrom().toBareJID())) {
for (String user : group.getMembers()) { for (JID userJID : group.getMembers()) {
Message newMessage = message.createCopy(); Message newMessage = message.createCopy();
JID userJID = XMPPServer.getInstance().createJID(user, null);
newMessage.setTo(userJID); newMessage.setTo(userJID);
try { try {
componentManager.sendPacket(this, newMessage); componentManager.sendPacket(this, newMessage);
......
...@@ -304,7 +304,8 @@ public class RegistrationPlugin implements Plugin { ...@@ -304,7 +304,8 @@ public class RegistrationPlugin implements Plugin {
try { try {
GroupManager groupManager = GroupManager.getInstance(); GroupManager groupManager = GroupManager.getInstance();
Group group = groupManager.getGroup(getGroup()); Group group = groupManager.getGroup(getGroup());
group.getMembers().add(user.getUsername()); group.getMembers()
.add(XMPPServer.getInstance().createJID(user.getUsername(), null));
} }
catch (GroupNotFoundException e) { catch (GroupNotFoundException e) {
Log.error(e); Log.error(e);
......
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