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 @@
package org.jivesoftware.messenger.group;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.util.*;
import org.jivesoftware.messenger.user.User;
import org.jivesoftware.messenger.XMPPServer;
import org.jivesoftware.util.Log;
import org.xmpp.packet.JID;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Collection;
import java.util.List;
/**
* Database implementation of the GroupManager interface.
......@@ -63,6 +64,8 @@ public class DefaultGroupProvider implements GroupProvider {
"SELECT groupName FROM jiveGroupUser WHERE username=?";
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 {
Connection con = null;
PreparedStatement pstmt = null;
......@@ -82,8 +85,8 @@ public class DefaultGroupProvider implements GroupProvider {
try { if (con != null) con.close(); }
catch (Exception e) { Log.error(e); }
}
Collection<String> members = getMembers(name, false);
Collection<String> administrators = getMembers(name, true);
Collection<JID> members = getMembers(name, false);
Collection<JID> administrators = getMembers(name, true);
return new Group(this, name, "", members, administrators);
}
......@@ -112,8 +115,8 @@ public class DefaultGroupProvider implements GroupProvider {
try { if (con != null) con.close(); }
catch (Exception e) { Log.error(e); }
}
Collection<String> members = getMembers(name, false);
Collection<String> administrators = getMembers(name, true);
Collection<JID> members = getMembers(name, false);
Collection<JID> administrators = getMembers(name, true);
return new Group(this, name, description, members, administrators);
}
......@@ -306,14 +309,14 @@ public class DefaultGroupProvider implements GroupProvider {
return groups;
}
public Collection<Group> getGroups(User user) {
public Collection<Group> getGroups(JID user) {
List<String> groupNames = new ArrayList<String>();
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(USER_GROUPS);
pstmt.setString(1, user.getUsername());
pstmt.setString(1, server.isLocal(user) ? user.getNode() : user.toString());
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
groupNames.add(rs.getString(1));
......@@ -342,14 +345,14 @@ public class DefaultGroupProvider implements GroupProvider {
return groups;
}
public void addMember(String groupName, String username, boolean administrator) {
public void addMember(String groupName, JID user, boolean administrator) {
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(ADD_USER);
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.executeUpdate();
}
......@@ -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;
PreparedStatement pstmt = null;
try {
......@@ -372,7 +375,7 @@ public class DefaultGroupProvider implements GroupProvider {
pstmt = con.prepareStatement(UPDATE_USER);
pstmt.setInt(1, administrator ? 1 : 0);
pstmt.setString(2, groupName);
pstmt.setString(3, username);
pstmt.setString(3, server.isLocal(user) ? user.getNode() : user.toString());
pstmt.executeUpdate();
}
catch (SQLException e) {
......@@ -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;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(REMOVE_USER);
pstmt.setString(1, groupName);
pstmt.setString(2, username);
pstmt.setString(2, server.isLocal(user) ? user.getNode() : user.toString());
pstmt.executeUpdate();
}
catch (SQLException e) {
......@@ -411,8 +414,8 @@ public class DefaultGroupProvider implements GroupProvider {
return false;
}
private Collection<String> getMembers(String groupName, boolean adminsOnly) {
List<String> members = new ArrayList<String>();
private Collection<JID> getMembers(String groupName, boolean adminsOnly) {
List<JID> members = new ArrayList<JID>();
Connection con = null;
PreparedStatement pstmt = null;
try {
......@@ -426,7 +429,15 @@ public class DefaultGroupProvider implements GroupProvider {
pstmt.setString(1, groupName);
ResultSet rs = pstmt.executeQuery();
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();
}
......
......@@ -14,8 +14,6 @@ package org.jivesoftware.messenger.group;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.messenger.XMPPServer;
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.Cacheable;
import org.jivesoftware.util.Log;
......@@ -51,8 +49,8 @@ public class Group implements Cacheable {
private String name;
private String description;
private Map<String, String> properties;
private Collection<String> members;
private Collection<String> administrators;
private Collection<JID> members;
private Collection<JID> administrators;
/**
* Constructs a new group. Note: this constructor is intended for implementors of the
......@@ -66,7 +64,7 @@ public class Group implements Cacheable {
* @param administrators a Collection of the group administrators.
*/
public Group(GroupProvider provider, String name, String description,
Collection<String> members, Collection<String> administrators)
Collection<JID> members, Collection<JID> administrators)
{
this.provider = provider;
this.groupManager = GroupManager.getInstance();
......@@ -172,7 +170,7 @@ public class Group implements Cacheable {
*
* @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 new MemberCollection(administrators, true);
}
......@@ -182,24 +180,19 @@ public class Group implements Cacheable {
*
* @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 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.
* @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) {
String serverName = XMPPServer.getInstance().getServerInfo().getName();
if (user != null && serverName.equals(user.getDomain())) {
return isUser(user.getNode());
} else {
return false;
}
return user != null && (members.contains(user) || administrators.contains(user));
}
/**
......@@ -210,7 +203,7 @@ public class Group implements Cacheable {
*/
public boolean isUser(String username) {
if (username != null) {
return members.contains(username) || administrators.contains(username);
return isUser(XMPPServer.getInstance().createJID(username, null));
} else {
return false;
}
......@@ -232,18 +225,18 @@ public class Group implements Cacheable {
*/
private class MemberCollection extends AbstractCollection {
private Collection<String> users;
private Collection<JID> users;
private boolean adminCollection;
public MemberCollection(Collection<String> users, boolean adminCollection) {
public MemberCollection(Collection<JID> users, boolean adminCollection) {
this.users = users;
this.adminCollection = adminCollection;
}
public Iterator iterator() {
public Iterator<JID> iterator() {
return new Iterator() {
Iterator iter = users.iterator();
Iterator<JID> iter = users.iterator();
Object current = null;
public boolean hasNext() {
......@@ -259,7 +252,7 @@ public class Group implements Cacheable {
if (current == null) {
throw new IllegalStateException();
}
String user = (String)current;
JID user = (JID)current;
// Remove the user from the collection in memory.
iter.remove();
// Remove the group user from the backend store.
......@@ -267,13 +260,13 @@ public class Group implements Cacheable {
// Fire event.
if (adminCollection) {
Map<String, String> params = new HashMap<String, String>();
params.put("admin", user);
params.put("admin", user.toString());
GroupEventDispatcher.dispatchEvent(Group.this,
GroupEventDispatcher.EventType.admin_removed, params);
}
else {
Map<String, String> params = new HashMap<String, String>();
params.put("member", user);
params.put("member", user.toString());
GroupEventDispatcher.dispatchEvent(Group.this,
GroupEventDispatcher.EventType.member_removed, params);
}
......@@ -286,36 +279,29 @@ public class Group implements Cacheable {
}
public boolean add(Object member) {
String username = (String) member;
try {
username = Stringprep.nodeprep(username);
UserManager.getInstance().getUser(username);
}
catch (Exception e) {
throw new IllegalArgumentException("Invalid user.", e);
}
JID user = (JID) member;
// Find out if the user was already a group user
boolean alreadyGroupUser = false;
if (adminCollection) {
alreadyGroupUser = members.contains(username);
alreadyGroupUser = members.contains(user);
}
else {
alreadyGroupUser = administrators.contains(username);
alreadyGroupUser = administrators.contains(user);
}
if (users.add(username)) {
if (users.add(user)) {
if (alreadyGroupUser) {
// Update the group user privileges in the backend store.
provider.updateMember(name, username, adminCollection);
provider.updateMember(name, user, adminCollection);
}
else {
// Add the group user to the backend store.
provider.addMember(name, username, adminCollection);
provider.addMember(name, user, adminCollection);
}
// Fire event.
if (adminCollection) {
Map<String, String> params = new HashMap<String, String>();
params.put("admin", username);
params.put("admin", user.toString());
if (alreadyGroupUser) {
GroupEventDispatcher.dispatchEvent(Group.this,
GroupEventDispatcher.EventType.member_removed, params);
......@@ -325,7 +311,7 @@ public class Group implements Cacheable {
}
else {
Map<String, String> params = new HashMap<String, String>();
params.put("member", username);
params.put("member", user.toString());
if (alreadyGroupUser) {
GroupEventDispatcher.dispatchEvent(Group.this,
GroupEventDispatcher.EventType.admin_removed, params);
......@@ -337,13 +323,13 @@ public class Group implements Cacheable {
// user from the other collection
if (alreadyGroupUser) {
if (adminCollection) {
if (members.contains(username)) {
members.remove(username);
if (members.contains(user)) {
members.remove(user);
}
}
else {
if (administrators.contains(username)) {
administrators.remove(username);
if (administrators.contains(user)) {
administrators.remove(user);
}
}
}
......
......@@ -15,6 +15,8 @@ import org.jivesoftware.util.*;
import org.jivesoftware.messenger.user.User;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.messenger.event.GroupEventDispatcher;
import org.jivesoftware.messenger.XMPPServer;
import org.xmpp.packet.JID;
import java.util.Collection;
import java.util.Collections;
......@@ -136,12 +138,13 @@ public class GroupManager {
* @param user the deleted user from the system.
*/
public void deleteUser(User user) {
for (Group group : getGroups(user)) {
if (group.getAdmins().contains(user.getUsername())) {
group.getAdmins().remove(user.getUsername());
JID userJID = XMPPServer.getInstance().createJID(user.getUsername(), null);
for (Group group : getGroups(userJID)) {
if (group.getAdmins().contains(userJID)) {
group.getAdmins().remove(userJID);
}
else {
group.getMembers().remove(user.getUsername());
group.getMembers().remove(userJID);
}
}
}
......@@ -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.
* @return all groups that a user belongs to.
* @param user the JID of the entity to get a list of groups for.
* @return all groups that an entity belongs to.
*/
public Collection<Group> getGroups(User user) {
public Collection<Group> getGroups(JID user) {
// TODO: add caching
return provider.getGroups(user);
}
......
......@@ -11,7 +11,7 @@
package org.jivesoftware.messenger.group;
import org.jivesoftware.messenger.user.User;
import org.xmpp.packet.JID;
import java.util.Collection;
......@@ -113,46 +113,46 @@ public interface GroupProvider {
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.
*/
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 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
* @throws UnsupportedOperationException if the provider does not
* support the operation.
*/
void addMember(String groupName, String username, boolean administrator)
void addMember(String groupName, JID user, boolean administrator)
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 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
* @throws UnsupportedOperationException if the provider does not
* support the operation.
*/
void updateMember(String groupName, String username, boolean administrator)
void updateMember(String groupName, JID user, boolean administrator)
throws UnsupportedOperationException;
/**
* Deletes a user from a group (optional operation).
* Deletes an entity from a group (optional operation).
*
* @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
* 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,
......
......@@ -11,22 +11,20 @@
package org.jivesoftware.messenger.ldap;
import org.jivesoftware.util.*;
import org.jivesoftware.messenger.user.*;
import org.jivesoftware.messenger.group.*;
import org.jivesoftware.messenger.XMPPServer;
import org.jivesoftware.messenger.group.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 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.directory.*;
import javax.naming.ldap.LdapName;
import java.text.MessageFormat;
import java.util.*;
/**
* LDAP implementation of the GroupProvider interface. All data in the directory is
......@@ -171,8 +169,9 @@ public class LdapGroupProvider implements GroupProvider {
return populateGroups(v.elements());
}
public Collection<Group> getGroups(User user) {
String username = JID.unescapeNode(user.getUsername());
public Collection<Group> getGroups(JID user) {
XMPPServer server = XMPPServer.getInstance();
String username = server.isLocal(user) ? JID.unescapeNode(user.getNode()) : user.toString();
if (!manager.isPosixMode()) {
try {
username = manager.findUserDN(username) + "," +
......@@ -192,11 +191,11 @@ public class LdapGroupProvider implements GroupProvider {
* LDAP groups are read-only.
*
* @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.
* @throws UnsupportedOperationException when called.
*/
public void addMember(String groupName, String username, boolean administrator)
public void addMember(String groupName, JID user, boolean administrator)
throws UnsupportedOperationException
{
throw new UnsupportedOperationException();
......@@ -207,11 +206,11 @@ public class LdapGroupProvider implements GroupProvider {
* LDAP groups are read-only.
*
* @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.
* @throws UnsupportedOperationException when called.
*/
public void updateMember(String groupName, String username, boolean administrator)
public void updateMember(String groupName, JID user, boolean administrator)
throws UnsupportedOperationException
{
throw new UnsupportedOperationException();
......@@ -222,10 +221,10 @@ public class LdapGroupProvider implements GroupProvider {
* LDAP groups are read-only.
*
* @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.
*/
public void deleteMember(String groupName, String username)
public void deleteMember(String groupName, JID user)
throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
......@@ -306,6 +305,8 @@ public class LdapGroupProvider implements GroupProvider {
ctrls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String userSearchFilter = MessageFormat.format(manager.getSearchFilter(), "*");
XMPPServer server = XMPPServer.getInstance();
String serverName = server.getServerInfo().getName();
while (answer.hasMoreElements()) {
String name = "";
......@@ -319,7 +320,7 @@ public class LdapGroupProvider implements GroupProvider {
catch (Exception e) {
description = "";
}
TreeSet<String> members = new TreeSet<String>();
TreeSet<JID> members = new TreeSet<JID>();
Attribute member = a.get(manager.getGroupMemberField());
NamingEnumeration ne = member.getAll();
while (ne.hasMore()) {
......@@ -352,13 +353,22 @@ public class LdapGroupProvider implements GroupProvider {
// Therefore, we have to try to load each user we found to see if
// it passes the filter.
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
// must be a properly escaped JID node.
String escapedUsername = JID.escapeNode(username);
userManager.getUser(escapedUsername);
// No exception, so the user must exist. Add the user as a group
// 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) {
if (manager.isDebugEnabled()) {
......@@ -369,7 +379,7 @@ public class LdapGroupProvider implements GroupProvider {
if (manager.isDebugEnabled()) {
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);
}
catch (Exception e) {
......
......@@ -83,7 +83,7 @@ public class Roster implements Cacheable {
try {
User rosterUser = UserManager.getInstance().getUser(getUsername());
sharedGroups = rosterManager.getSharedGroups(rosterUser);
userGroups = GroupManager.getInstance().getGroups(rosterUser);
userGroups = GroupManager.getInstance().getGroups(getUserJID());
}
catch (UserNotFoundException e) {
sharedGroups = new ArrayList<Group>();
......@@ -110,8 +110,7 @@ public class Roster implements Cacheable {
for (JID jid : sharedUsers.keySet()) {
try {
Collection<Group> itemGroups = new ArrayList<Group>();
User user = UserManager.getInstance().getUser(jid.getNode());
String nickname = "".equals(user.getName()) ? jid.getNode() : user.getName();
String nickname = getContactNickname(jid);
RosterItem item = new RosterItem(jid, RosterItem.SUB_TO, RosterItem.ASK_NONE,
RosterItem.RECV_NONE, nickname , null);
// Add the shared groups to the new roster item
......@@ -126,8 +125,7 @@ public class Roster implements Cacheable {
}
// 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
if (rosterManager.hasMutualVisibility(username, userGroups, jid.getNode(),
itemGroups)) {
if (rosterManager.hasMutualVisibility(username, userGroups, jid, itemGroups)) {
item.setSubStatus(RosterItem.SUB_BOTH);
}
else {
......@@ -479,13 +477,12 @@ public class Roster implements Cacheable {
Map<JID,List<Group>> sharedGroupUsers = new HashMap<JID,List<Group>>();
for (Group group : sharedGroups) {
// 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
for (String user : users) {
for (JID jid : users) {
// 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)
JID jid = XMPPServer.getInstance().createJID(user, null);
if (!isRosterItem(jid) && !getUsername().equals(user)) {
if (!isRosterItem(jid) && !getUsername().equals(jid.getNode())) {
List<Group> groups = sharedGroupUsers.get(jid);
if (groups == null) {
groups = new ArrayList<Group>();
......@@ -572,13 +569,12 @@ public class Roster implements Cacheable {
* @param group the shared group where the user was added.
* @param addedUser the contact to update in the roster.
*/
void addSharedUser(Group group, String addedUser) {
void addSharedUser(Group group, JID addedUser) {
boolean newItem = false;
RosterItem item = null;
JID jid = XMPPServer.getInstance().createJID(addedUser, "");
try {
// 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
if (item.getSharedGroups().contains(group)) {
return;
......@@ -588,10 +584,9 @@ public class Roster implements Cacheable {
catch (UserNotFoundException e) {
try {
// Create a new RosterItem for this new user
User user = UserManager.getInstance().getUser(addedUser);
String nickname = "".equals(user.getName()) ? jid.getNode() : user.getName();
String nickname = getContactNickname(addedUser);
item =
new RosterItem(jid, RosterItem.SUB_BOTH, RosterItem.ASK_NONE,
new RosterItem(addedUser, RosterItem.SUB_BOTH, RosterItem.ASK_NONE,
RosterItem.RECV_NONE, nickname, null);
// Add the new item to the list of items
rosterItems.put(item.getJid().toBareJID(), item);
......@@ -611,19 +606,14 @@ public class Roster implements Cacheable {
}
// 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>();
try {
User rosterUser = UserManager.getInstance().getUser(getUsername());
GroupManager groupManager = GroupManager.getInstance();
userGroups = groupManager.getGroups(rosterUser);
sharedGroups.addAll(item.getSharedGroups());
// Add the new group to the list of groups to check
sharedGroups.add(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
if (rosterManager.hasMutualVisibility(getUsername(), userGroups, jid.getNode(),
sharedGroups)) {
if (rosterManager.hasMutualVisibility(getUsername(), userGroups, addedUser, sharedGroups)) {
item.setSubStatus(RosterItem.SUB_BOTH);
}
// Update the subscription status depending on the group membership of the new
......@@ -634,9 +624,6 @@ public class Roster implements Cacheable {
else if (!group.isUser(addedUser) && group.isUser(getUsername())) {
item.setSubStatus(RosterItem.SUB_FROM);
}
}
catch (UserNotFoundException e) {
}
// Add the shared group to the list of shared groups
if (item.getSubStatus() != RosterItem.SUB_FROM) {
......@@ -675,22 +662,20 @@ public class Roster implements Cacheable {
* @param addedUser the new contact to add to the roster
* @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;
RosterItem item = null;
JID jid = XMPPServer.getInstance().createJID(addedUser, "");
try {
// Get the RosterItem for the *local* user to add
item = getRosterItem(jid);
item = getRosterItem(addedUser);
newItem = false;
}
catch (UserNotFoundException e) {
try {
// Create a new RosterItem for this new user
User user = UserManager.getInstance().getUser(addedUser);
String nickname = "".equals(user.getName()) ? jid.getNode() : user.getName();
String nickname = getContactNickname(addedUser);
item =
new RosterItem(jid, RosterItem.SUB_BOTH, RosterItem.ASK_NONE,
new RosterItem(addedUser, RosterItem.SUB_BOTH, RosterItem.ASK_NONE,
RosterItem.RECV_NONE, nickname, null);
// Add the new item to the list of items
rosterItems.put(item.getJid().toBareJID(), item);
......@@ -701,18 +686,13 @@ public class Roster implements Cacheable {
}
}
// Update the subscription of the item **based on the item groups**
Collection<Group> userGroups = null;
try {
User rosterUser = UserManager.getInstance().getUser(getUsername());
GroupManager groupManager = GroupManager.getInstance();
userGroups = groupManager.getGroups(rosterUser);
Collection<Group> userGroups = GroupManager.getInstance().getGroups(getUserJID());
// 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
if (rosterManager.hasMutualVisibility(getUsername(), userGroups, jid.getNode(),
groups)) {
if (rosterManager.hasMutualVisibility(getUsername(), userGroups, addedUser, groups)) {
item.setSubStatus(RosterItem.SUB_BOTH);
for (Group group : groups) {
if (rosterManager.isGroupVisible(group, getUsername())) {
if (rosterManager.isGroupVisible(group, getUserJID())) {
// Add the shared group to the list of shared groups
item.addSharedGroup(group);
}
......@@ -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
// BOTH subscription
for (Group group : userGroups) {
if (!group.isUser(addedUser) &&
rosterManager.isGroupVisible(group, addedUser)) {
if (!group.isUser(addedUser) && rosterManager.isGroupVisible(group, addedUser)) {
// Add the shared group to the list of invisible shared groups
item.addInvisibleSharedGroup(group);
}
......@@ -741,7 +720,7 @@ public class Roster implements Cacheable {
item.setSubStatus(RosterItem.SUB_FROM);
// Check if the user may see the new contact in a shared group
for (Group group : groups) {
if (rosterManager.isGroupVisible(group, getUsername())) {
if (rosterManager.isGroupVisible(group, getUserJID())) {
// Add the shared group to the list of shared groups
item.addSharedGroup(group);
item.setSubStatus(RosterItem.SUB_TO);
......@@ -764,9 +743,6 @@ public class Roster implements Cacheable {
}
}
}
}
catch (UserNotFoundException e) {
}
// Brodcast to all the user resources of the updated roster item
broadcast(item, true);
// Probe the presence of the new group user
......@@ -785,11 +761,10 @@ public class Roster implements Cacheable {
* @param sharedGroup the shared group from where the user was deleted.
* @param deletedUser the contact to update in the roster.
*/
void deleteSharedUser(Group sharedGroup, String deletedUser) {
JID jid = XMPPServer.getInstance().createJID(deletedUser, "");
void deleteSharedUser(Group sharedGroup, JID deletedUser) {
try {
// 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();
if (item.isOnlyShared() && groupSize == 1) {
// Do nothing if the existing shared group is not the sharedGroup to remove
......@@ -798,24 +773,21 @@ public class Roster implements Cacheable {
}
// Delete the roster item from the roster since it exists only because of this
// group which is being removed
deleteRosterItem(jid, false);
deleteRosterItem(deletedUser, false);
}
else {
// Remove the removed shared group from the list of shared groups
item.removeSharedGroup(sharedGroup);
// Update the subscription of the item based on the remaining groups
if (item.isOnlyShared()) {
Collection<Group> userGroups = null;
Collection<Group> userGroups =
GroupManager.getInstance().getGroups(getUserJID());
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());
// 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
if (rosterManager.hasMutualVisibility(getUsername(), userGroups,
jid.getNode(), sharedGroups)) {
if (rosterManager.hasMutualVisibility(getUsername(), userGroups, deletedUser,
sharedGroups)) {
item.setSubStatus(RosterItem.SUB_BOTH);
}
else if (item.getSharedGroups().isEmpty() &&
......@@ -825,10 +797,6 @@ public class Roster implements Cacheable {
else {
item.setSubStatus(RosterItem.SUB_TO);
}
}
catch (UserNotFoundException e) {
}
}
// Brodcast to all the user resources of the updated roster item
broadcast(item, false);
......@@ -842,11 +810,10 @@ public class Roster implements Cacheable {
}
}
void deleteSharedUser(String deletedUser, Collection<Group> groups, Group deletedGroup) {
JID jid = XMPPServer.getInstance().createJID(deletedUser, "");
void deleteSharedUser(JID deletedUser, Collection<Group> groups, Group deletedGroup) {
try {
// 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();
if (item.isOnlyShared() && groupSize == 1 &&
// Do not delete the item if deletedUser belongs to a public group since the
......@@ -855,7 +822,7 @@ public class Roster implements Cacheable {
rosterManager.isGroupPublic(deletedGroup))) {
// Delete the roster item from the roster since it exists only because of this
// group which is being removed
deleteRosterItem(jid, false);
deleteRosterItem(deletedUser, false);
}
else {
// Remove the shared group from the item if deletedUser does not belong to a
......@@ -866,7 +833,7 @@ public class Roster implements Cacheable {
}
// Remove all invalid shared groups from the roster item
for (Group group : groups) {
if (!rosterManager.isGroupVisible(group, getUsername())) {
if (!rosterManager.isGroupVisible(group, getUserJID())) {
// Remove the shared group from the list of shared groups
item.removeSharedGroup(group);
}
......@@ -874,15 +841,12 @@ public class Roster implements Cacheable {
// Update the subscription of the item **based on the item groups**
if (item.isOnlyShared()) {
Collection<Group> userGroups = null;
try {
User rosterUser = UserManager.getInstance().getUser(getUsername());
GroupManager groupManager = GroupManager.getInstance();
userGroups = groupManager.getGroups(rosterUser);
Collection<Group> userGroups =
userGroups = GroupManager.getInstance().getGroups(getUserJID());
// 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
if (rosterManager.hasMutualVisibility(getUsername(), userGroups,
jid.getNode(), groups)) {
if (rosterManager
.hasMutualVisibility(getUsername(), userGroups, deletedUser, groups)) {
item.setSubStatus(RosterItem.SUB_BOTH);
}
else {
......@@ -891,15 +855,12 @@ public class Roster implements Cacheable {
item.setSubStatus(RosterItem.SUB_FROM);
// Check if the user may see the new contact in a shared group
for (Group group : groups) {
if (rosterManager.isGroupVisible(group, getUsername())) {
if (rosterManager.isGroupVisible(group, getUserJID())) {
item.setSubStatus(RosterItem.SUB_TO);
}
}
}
}
catch (UserNotFoundException e) {
}
}
// Brodcast to all the user resources of the updated roster item
broadcast(item, false);
}
......@@ -918,16 +879,16 @@ public class Roster implements Cacheable {
*
* @param users group users of the renamed group.
*/
void shareGroupRenamed(Collection<String> users) {
for (String user : users) {
if (username.equals(user)) {
void shareGroupRenamed(Collection<JID> users) {
JID userJID = getUserJID();
for (JID user : users) {
if (userJID.equals(user)) {
continue;
}
RosterItem item = null;
JID jid = XMPPServer.getInstance().createJID(user, "");
try {
// 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
broadcast(item, true);
}
......@@ -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$
* $Date$
*
......@@ -12,13 +12,15 @@
package org.jivesoftware.messenger.roster;
import org.xmpp.packet.JID;
import org.xmpp.packet.Presence;
import org.jivesoftware.util.Cache;
import org.jivesoftware.util.CacheManager;
import org.jivesoftware.messenger.container.BasicModule;
import org.jivesoftware.messenger.user.UserNotFoundException;
import org.jivesoftware.messenger.user.User;
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.GroupEventDispatcher;
import org.jivesoftware.messenger.group.Group;
......@@ -41,6 +43,8 @@ import java.util.*;
public class RosterManager extends BasicModule implements GroupEventListener {
private Cache rosterCache = null;
private XMPPServer server;
private RoutingTable routingTable;
public RosterManager() {
super("Roster Manager");
......@@ -82,6 +86,10 @@ public class RosterManager extends BasicModule implements GroupEventListener {
* @param user the user.
*/
public void deleteRoster(JID user) {
if (!server.isLocal(user)) {
// Ignore request if user is not a local user
return;
}
try {
String username = user.getNode();
// Get the roster of the deleted user
......@@ -197,7 +205,7 @@ public class RosterManager extends BasicModule implements GroupEventListener {
public void groupDeleting(Group group, Map params) {
// Iterate on all the group users and update their rosters
for (String deletedUser : getAffectedUsers(group)) {
for (JID deletedUser : getAffectedUsers(group)) {
groupUserDeleted(group, deletedUser);
}
}
......@@ -218,24 +226,21 @@ public class RosterManager extends BasicModule implements GroupEventListener {
return;
}
// 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());
// 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"));
// Remove the group members from the affected rosters
for (String deletedUser : users) {
for (JID deletedUser : users) {
groupUserDeleted(group, affectedUsers, deletedUser);
}
// 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
//Collection<Group> visibleGroups = getVisibleGroups(group);
for (String user : users) {
for (JID user : users) {
groupUserAdded(group, user);
/*for (Group visibleGroup : visibleGroups) {
addSharedGroupToRoster(visibleGroup, user);
}*/
}
}
else if ("sharedRoster.groupList".equals(keyChanged)) {
......@@ -245,24 +250,21 @@ public class RosterManager extends BasicModule implements GroupEventListener {
return;
}
// 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());
// Get the users whose roster will be affected
Collection<String> affectedUsers = getAffectedUsers(group,
Collection<JID> affectedUsers = getAffectedUsers(group,
group.getProperties().get("sharedRoster.showInRoster"), originalValue);
// Remove the group members from the affected rosters
for (String deletedUser : users) {
for (JID deletedUser : users) {
groupUserDeleted(group, affectedUsers, deletedUser);
}
// 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
//Collection<Group> visibleGroups = getVisibleGroups(group);
for (String user : users) {
for (JID user : users) {
groupUserAdded(group, user);
/*for (Group visibleGroup : visibleGroups) {
addSharedGroupToRoster(visibleGroup, user);
}*/
}
}
else if ("sharedRoster.displayName".equals(keyChanged)) {
......@@ -276,11 +278,15 @@ public class RosterManager extends BasicModule implements GroupEventListener {
return;
}
// 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
for (String updatedUser : users) {
for (JID updatedUser : users) {
// 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) {
// Update the roster with the new group display name
roster.shareGroupRenamed(users);
......@@ -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
* based on the group properties that are configurable through the Admin Console.
......@@ -305,14 +317,17 @@ public class RosterManager extends BasicModule implements GroupEventListener {
}
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
if (group.getAdmins().contains(addedUser)) {
return;
}
if (!isSharedGroup(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 {
......@@ -321,14 +336,17 @@ public class RosterManager extends BasicModule implements GroupEventListener {
}
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
if (group.getAdmins().contains(deletedUser)) {
return;
}
if (!isSharedGroup(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 {
......@@ -337,14 +355,17 @@ public class RosterManager extends BasicModule implements GroupEventListener {
}
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
if (group.getMembers().contains(addedUser)) {
return;
}
if (!isSharedGroup(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 {
......@@ -353,7 +374,7 @@ public class RosterManager extends BasicModule implements GroupEventListener {
}
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
if (group.getMembers().contains(deletedUser)) {
return;
......@@ -361,7 +382,10 @@ public class RosterManager extends BasicModule implements GroupEventListener {
// Do nothing if the group is not being shown in group members' rosters
if (!isSharedGroup(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 {
......@@ -375,30 +399,62 @@ public class RosterManager extends BasicModule implements GroupEventListener {
* @param group the group where the user was added.
* @param addedUser the username of the user that has been added to the group.
*/
private void groupUserAdded(Group group, String addedUser) {
// Get all the affected users
Collection<String> users = getAffectedUsers(group);
private void groupUserAdded(Group group, JID addedUser) {
groupUserAdded(group, getAffectedUsers(group), addedUser);
}
/**
* 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.
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
for (String userToUpdate : users) {
for (JID userToUpdate : users) {
if (!addedUser.equals(userToUpdate)) {
// 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
if (roster != null) {
roster.addSharedUser(group, addedUser);
}
// Update the roster of the newly added group user.
if (addedUserRoster != null) {
try {
User user = UserManager.getInstance().getUser(userToUpdate);
Collection<Group> groups = GroupManager.getInstance().getGroups(user);
Collection<Group> groups = GroupManager.getInstance().getGroups(userToUpdate);
addedUserRoster.addSharedUser(userToUpdate, groups, group);
}
catch (UserNotFoundException e) {}
}
}
}
}
......@@ -409,7 +465,7 @@ public class RosterManager extends BasicModule implements GroupEventListener {
* @param group the group from where the user was deleted.
* @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);
}
......@@ -420,28 +476,69 @@ public class RosterManager extends BasicModule implements GroupEventListener {
* @param users the users to update their rosters
* @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.
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
for (String userToUpdate : users) {
for (JID userToUpdate : users) {
// 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
if (roster != null) {
roster.deleteSharedUser(group, deletedUser);
}
// Update the roster of the newly deleted group user.
if (deletedUserRoster != null) {
try {
User user = UserManager.getInstance().getUser(userToUpdate);
Collection<Group> groups = GroupManager.getInstance().getGroups(user);
Collection<Group> groups = GroupManager.getInstance().getGroups(userToUpdate);
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) {
......@@ -487,23 +584,23 @@ public class RosterManager extends BasicModule implements GroupEventListener {
* see the group in his roster.
*
* @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.
*/
boolean isGroupVisible(Group group, String username) {
boolean isGroupVisible(Group group, JID user) {
String showInRoster = group.getProperties().get("sharedRoster.showInRoster");
if ("everybody".equals(showInRoster)) {
return true;
}
else if ("onlyGroup".equals(showInRoster)) {
if (group.isUser(username)) {
if (group.isUser(user)) {
return true;
}
// Check if the user belongs to a group that may see this group
Collection<Group> groupList = parseGroups(group.getProperties().get(
"sharedRoster.groupList"));
for (Group groupInList : groupList) {
if (groupInList.isUser(username)) {
if (groupInList.isUser(user)) {
return true;
}
}
......@@ -511,68 +608,6 @@ public class RosterManager extends BasicModule implements GroupEventListener {
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
* 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 {
* 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.
*/
private Collection<String> getAffectedUsers(Group group) {
private Collection<JID> getAffectedUsers(Group group) {
return getAffectedUsers(group, group.getProperties().get("sharedRoster.showInRoster"),
group.getProperties().get("sharedRoster.groupList"));
}
......@@ -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
* 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
if (!"onlyGroup".equals(showInRoster) && !"everybody".equals(showInRoster)) {
return new ArrayList<String>();
return new ArrayList<JID>();
}
// 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());
// Check if anyone can see this shared group
if ("everybody".equals(showInRoster)) {
// Add all users in the system
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
// logged ones will be affected.
......@@ -624,17 +659,17 @@ public class RosterManager extends BasicModule implements GroupEventListener {
return users;
}
Collection<String> getSharedUsersForRoster(Group group, Roster roster) {
Collection<JID> getSharedUsersForRoster(Group group, Roster roster) {
String showInRoster = group.getProperties().get("sharedRoster.showInRoster");
String groupNames = group.getProperties().get("sharedRoster.groupList");
// Answer an empty collection if the group is not being shown in users' rosters
if (!"onlyGroup".equals(showInRoster) && !"everybody".equals(showInRoster)) {
return new ArrayList<String>();
return new ArrayList<JID>();
}
// 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());
// Check if anyone can see this shared group
......@@ -644,7 +679,7 @@ public class RosterManager extends BasicModule implements GroupEventListener {
if (group.isUser(roster.getUsername())) {
// Add all users in the system
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 {
* 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.
*
* @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 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.
* @return true if a group in the first collection may mutually see a group of the
* second collection.
*/
boolean hasMutualVisibility(String user, Collection<Group> groups, String otherUser,
boolean hasMutualVisibility(String user, Collection<Group> groups, JID otherUser,
Collection<Group> otherGroups) {
for (Group group : groups) {
for (Group otherGroup : otherGroups) {
......
......@@ -164,9 +164,8 @@ public class BroadcastPlugin implements Plugin, Component, PropertyEventListener
if (disableGroupPermissions ||
(groupMembersAllowed && group.isUser(message.getFrom())) ||
allowedUsers.contains(message.getFrom().toBareJID())) {
for (String user : group.getMembers()) {
for (JID userJID : group.getMembers()) {
Message newMessage = message.createCopy();
JID userJID = XMPPServer.getInstance().createJID(user, null);
newMessage.setTo(userJID);
try {
componentManager.sendPacket(this, newMessage);
......
......@@ -304,7 +304,8 @@ public class RegistrationPlugin implements Plugin {
try {
GroupManager groupManager = GroupManager.getInstance();
Group group = groupManager.getGroup(getGroup());
group.getMembers().add(user.getUsername());
group.getMembers()
.add(XMPPServer.getInstance().createJID(user.getUsername(), null));
}
catch (GroupNotFoundException 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