Commit 3d9dd958 authored by Matt Tucker's avatar Matt Tucker Committed by matt

Refactored group support.


git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@528 b35dd754-fafc-0310-a699-88a17e54d16e
parent c965dd6d
......@@ -72,30 +72,28 @@ CREATE TABLE jiveVCard (
CREATE TABLE jiveGroup (
groupID INTEGER NOT NULL,
name VARCHAR(50) NOT NULL,
description VARCHAR(255),
creationDate CHAR(15) NOT NULL,
modificationDate CHAR(15) NOT NULL,
CONSTRAINT jiveGroup_pk PRIMARY KEY (groupID)
CONSTRAINT jiveGroup_pk PRIMARY KEY (name)
);
CREATE INDEX jiveGrp_cDate_idx ON jiveGroup (creationDate ASC);
CREATE INDEX jiveGrp_name_idx ON jiveGroup (name);
CREATE TABLE jiveGroupProp (
groupID INTEGER NOT NULL,
groupName VARCHAR(50) NOT NULL,
name VARCHAR(100) NOT NULL,
propValue VARCHAR(2000) NOT NULL,
CONSTRAINT jiveGrpProp_pk PRIMARY KEY (groupID, name)
CONSTRAINT jiveGrpProp_pk PRIMARY KEY (groupName, name)
);
CREATE TABLE jiveGroupUser (
groupID INTEGER NOT NULL,
groupName VARCHAR(50) NOT NULL,
username VARCHAR(32) NOT NULL,
administrator INTEGER NOT NULL,
CONSTRAINT jiveGrpUser PRIMARY KEY (groupID, username, administrator)
CONSTRAINT jiveGrpUser PRIMARY KEY (groupName, username, administrator)
);
......@@ -163,8 +161,6 @@ CREATE TABLE mucConversationLog (
-- Finally, insert default table values
INSERT INTO jiveID (idType, id) VALUES (3, 2);
INSERT INTO jiveID (idType, id) VALUES (4, 1);
INSERT INTO jiveID (idType, id) VALUES (18, 1);
INSERT INTO jiveID (idType, id) VALUES (19, 1);
INSERT INTO jiveID (idType, id) VALUES (23, 1);
......
......@@ -83,30 +83,28 @@ CREATE TABLE jiveDomain (
CREATE TABLE jiveGroup (
groupID BIGINT NOT NULL,
name VARCHAR(50) NOT NULL,
description VARCHAR(255),
creationDate VARCHAR(15) NOT NULL,
modificationDate VARCHAR(15) NOT NULL,
CONSTRAINT jiveGroup_pk PRIMARY KEY (groupID)
CONSTRAINT jiveGroup_pk PRIMARY KEY (name)
);
CREATE INDEX jiveGroup_cDate_idx ON jiveGroup (creationDate);
CREATE INDEX jiveGroup_name_idx ON jiveGroup (name);
CREATE TABLE jiveGroupProp (
groupID BIGINT NOT NULL,
groupName VARCHAR(50) NOT NULL,
name VARCHAR(100) NOT NULL,
propValue VARCHAR(4000) NOT NULL,
CONSTRAINT jiveGroupProp_pk PRIMARY KEY (groupID, name)
CONSTRAINT jiveGroupProp_pk PRIMARY KEY (groupName, name)
);
CREATE TABLE jiveGroupUser (
groupID BIGINT NOT NULL,
groupName VARCHAR(50) NOT NULL,
username VARCHAR(32) NOT NULL,
administrator INTEGER NOT NULL,
CONSTRAINT jiveGroupUser_pk PRIMARY KEY (groupID, username, administrator)
CONSTRAINT jiveGroupUser_pk PRIMARY KEY (groupName, username, administrator)
);
......@@ -174,14 +172,10 @@ CREATE TABLE mucConversationLog (
// Finally, insert default table values.
// Unique ID entry for user, group
// The User ID entry starts at 2 (after admin user entry).
INSERT INTO jiveID (idType, id) VALUES (3, 2);
INSERT INTO jiveID (idType, id) VALUES (4, 1);
INSERT INTO jiveID (idType, id) VALUES (18, 1);
INSERT INTO jiveID (idType, id) VALUES (19, 1);
INSERT INTO jiveID (idType, id) VALUES (23, 1);
// Entry for admin user -- password is "admin"
// Entry for admin user
INSERT INTO jiveUser (username, password, name, email, creationDate, modificationDate)
VALUES ('admin', 'admin', 'Administrator', 'admin@example.com', '0', '0');
\ No newline at end of file
......@@ -21,28 +21,26 @@ CREATE TABLE jiveUserProp (
);
CREATE TABLE jiveGroup (
groupID BIGINT NOT NULL,
name VARCHAR(50) NOT NULL,
description VARCHAR(255),
creationDate CHAR(15) NOT NULL,
modificationDate CHAR(15) NOT NULL,
PRIMARY KEY (groupID),
INDEX jiveGroup_cDate_idx (creationDate),
INDEX jiveGroup_name_idx (name(10))
PRIMARY KEY (name),
INDEX jiveGroup_cDate_idx (creationDate)
);
CREATE TABLE jiveGroupProp (
groupID BIGINT NOT NULL,
groupName VARCHAR(50) NOT NULL,
name VARCHAR(100) NOT NULL,
propValue TEXT NOT NULL,
PRIMARY KEY (groupID, name)
PRIMARY KEY (groupName, name)
);
CREATE TABLE jiveGroupUser (
groupID BIGINT NOT NULL,
groupName VARCHAR(50) NOT NULL,
username VARCHAR(32) NOT NULL,
administrator TINYINT NOT NULL,
PRIMARY KEY (groupID, username, administrator)
PRIMARY KEY (groupName, username, administrator)
);
CREATE TABLE jivePrivate (
......@@ -151,10 +149,6 @@ CREATE TABLE mucConversationLog (
# Finally, insert default table values.
# Unique ID entry for user, group
# The User ID entry starts at 2 (after admin user entry).
INSERT INTO jiveID (idType, id) VALUES (3, 2);
INSERT INTO jiveID (idType, id) VALUES (4, 1);
INSERT INTO jiveID (idType, id) VALUES (18, 1);
INSERT INTO jiveID (idType, id) VALUES (19, 1);
INSERT INTO jiveID (idType, id) VALUES (23, 1);
......
......@@ -72,28 +72,26 @@ CREATE TABLE jiveVCard (
);
CREATE TABLE jiveGroup (
groupID INTEGER NOT NULL,
name VARCHAR2(50) NOT NULL,
description VARCHAR2(255),
creationDate CHAR(15) NOT NULL,
modificationDate CHAR(15) NOT NULL,
CONSTRAINT jiveGroup_pk PRIMARY KEY (groupID)
CONSTRAINT jiveGroup_pk PRIMARY KEY (groupName)
);
CREATE INDEX jiveGroup_cDate_idx ON jiveGroup (creationDate ASC);
CREATE INDEX jiveGroup_name_idx ON jiveGroup (name);
CREATE TABLE jiveGroupProp (
groupID INTEGER NOT NULL,
groupName VARCHAR(50) NOT NULL,
name VARCHAR2(100) NOT NULL,
propValue VARCHAR2(4000) NOT NULL,
CONSTRAINT jiveGroupProp_pk PRIMARY KEY (groupID, name)
CONSTRAINT jiveGroupProp_pk PRIMARY KEY (groupName, name)
);
CREATE TABLE jiveGroupUser (
groupID INTEGER NOT NULL,
groupName VARCHAR(50) NOT NULL,
username VARCHAR2(32) NOT NULL,
administrator INTEGER NOT NULL,
CONSTRAINT jiveGroupUser PRIMARY KEY (groupID, username, administrator)
CONSTRAINT jiveGroupUser PRIMARY KEY (groupName, username, administrator)
);
CREATE TABLE jiveID (
......@@ -158,10 +156,6 @@ CREATE TABLE mucConversationLog (
REM // Finally, insert default table values.
REM // Unique ID entry for user, group
REM // The User ID entry starts at 2 (after admin user entry).
INSERT INTO jiveID (idType, id) VALUES (3, 2);
INSERT INTO jiveID (idType, id) VALUES (4, 1);
INSERT INTO jiveID (idType, id) VALUES (18, 1);
INSERT INTO jiveID (idType, id) VALUES (19, 1);
INSERT INTO jiveID (idType, id) VALUES (23, 1);
......
......@@ -75,33 +75,28 @@ CREATE TABLE jiveVCard (
CREATE TABLE jiveGroup (
groupID INTEGER NOT NULL,
name VARCHAR(50) NOT NULL,
description VARCHAR(255),
creationDate CHAR(15) NOT NULL,
modificationDate CHAR(15) NOT NULL,
CONSTRAINT jiveGroup_pk PRIMARY KEY (groupID)
CONSTRAINT jiveGroup_pk PRIMARY KEY (name)
);
CREATE INDEX jiveGroup_cDate_idx ON jiveGroup (creationDate);
CREATE INDEX jiveGroup_name_idx ON jiveGroup (name);
CREATE TABLE jiveGroupProp (
groupID INTEGER NOT NULL,
groupName VARCHAR(50) NOT NULL,
name VARCHAR(100) NOT NULL,
propValue TEXT NOT NULL,
CONSTRAINT jiveGroupProp_pk PRIMARY KEY (groupID, name)
CONSTRAINT jiveGroupProp_pk PRIMARY KEY (groupName, name)
);
-- Commented out since this will cause a third party user system to break
-- If you do not use a third part user system, uncomment these constraints
-- ALTER TABLE jiveGroupProp ADD CONSTRAINT jiveGroupProp_groupID_fk FOREIGN KEY (groupID) REFERENCES jiveGroup INITIALLY DEFERRED DEFERRABLE;
CREATE TABLE jiveGroupUser (
groupID INTEGER NOT NULL,
groupName VARCHAR(50) NOT NULL,
username VARCHAR(32) NOT NULL,
administrator INTEGER NOT NULL,
CONSTRAINT jiveGroupUser_pk PRIMARY KEY (groupID, username, administrator)
CONSTRAINT jiveGroupUser_pk PRIMARY KEY (groupName, username, administrator)
);
......@@ -168,10 +163,6 @@ CREATE TABLE mucConversationLog (
-- Finally, insert default table values.
-- Unique ID entry for user, group
-- The User ID entry starts at 2 (after admin user entry).
INSERT INTO jiveID (idType, id) VALUES (3, 2);
INSERT INTO jiveID (idType, id) VALUES (4, 1);
INSERT INTO jiveID (idType, id) VALUES (18, 1);
INSERT INTO jiveID (idType, id) VALUES (19, 1);
INSERT INTO jiveID (idType, id) VALUES (23, 1);
......
......@@ -75,33 +75,28 @@ CREATE TABLE jiveVCard (
CREATE TABLE jiveGroup (
groupID INTEGER NOT NULL,
name NVARCHAR(100) NOT NULL,
description NVARCHAR(255),
creationDate CHAR(15) NOT NULL,
modificationDate CHAR(15) NOT NULL,
CONSTRAINT group_pk PRIMARY KEY (groupID)
CONSTRAINT group_pk PRIMARY KEY (name)
);
CREATE INDEX jiveGroup_cDate_idx ON jiveGroup (creationDate);
CREATE INDEX jiveGroup_name_idx ON jiveGroup (name);
CREATE TABLE jiveGroupProp (
groupID INTEGER NOT NULL,
groupName NVARCHAR(100) NOT NULL,
name NVARCHAR(100) NOT NULL,
propValue NVARCHAR(3900) NOT NULL,
CONSTRAINT jiveGroupProp_pk PRIMARY KEY (groupID, name)
CONSTRAINT jiveGroupProp_pk PRIMARY KEY (groupName, name)
);
/* Commented out since this will cause a third party user system to break */
/* If you do not use a third part user system, uncomment these constraints */
/* ALTER TABLE jiveGroupProp ADD CONSTRAINT jiveGroupProp_groupID_fk FOREIGN KEY (groupID) REFERENCES jiveGroup; */
CREATE TABLE jiveGroupUser (
groupID INTEGER NOT NULL,
groupName NVARCHAR(100) NOT NULL,
username NVARCHAR(32) NOT NULL,
administrator INTEGER NOT NULL,
CONSTRAINT jiveGroupUser_pk PRIMARY KEY (groupID, username, administrator)
CONSTRAINT jiveGroupUser_pk PRIMARY KEY (groupName, username, administrator)
);
......@@ -168,10 +163,6 @@ CREATE TABLE mucConversationLog (
/* Finally, insert default table values. */
/* Unique ID entry for user, group */
/* The User ID entry starts at 2 (after admin user entry). */
INSERT INTO jiveID (idType, id) VALUES (3, 2);
INSERT INTO jiveID (idType, id) VALUES (4, 1);
INSERT INTO jiveID (idType, id) VALUES (18, 1);
INSERT INTO jiveID (idType, id) VALUES (19, 1);
INSERT INTO jiveID (idType, id) VALUES (23, 1);
......
......@@ -55,8 +55,6 @@ public class SequenceManager {
static {
managers = new HashMap<Integer,Object>();
new SequenceManager(JiveConstants.USER, 1);
new SequenceManager(JiveConstants.GROUP, 1);
new SequenceManager(JiveConstants.ROSTER, 5);
new SequenceManager(JiveConstants.OFFLINE, 1);
new SequenceManager(JiveConstants.MUC_ROOM, 1);
......
......@@ -345,6 +345,42 @@ public class JiveGlobals {
return xmlProperties.getProperty(name);
}
/**
* Returns a local property. Local properties are stored in the file
* <tt>jive-messenger.xml</tt> that exists in the <tt>jiveMessenger/conf</tt> directory.
* Properties are always specified as "foo.bar.prop", which would map to
* the following entry in the XML file:
* <pre>
* &lt;foo&gt;
* &lt;bar&gt;
* &lt;prop&gt;some value&lt;/prop&gt;
* &lt;/bar&gt;
* &lt;/foo&gt;
* </pre>
*
* If the specified property can't be found, the <tt>defaultValue</tt> will be returned.
*
* @param name the name of the property to return.
* @param defaultValue the default value for the property.
* @return the property value specified by name.
*/
public static String getXMLProperty(String name, String defaultValue) {
if (xmlProperties == null) {
loadSetupProperties();
}
// messengerHome not loaded?
if (xmlProperties == null) {
return null;
}
String value = xmlProperties.getProperty(name);
if (value == null) {
value = defaultValue;
}
return value;
}
/**
* Returns an integer value local property. Local properties are stored in the file
* <tt>jive_forums.xml</tt> that exists in the <tt>jiveHome</tt> directory.
......
......@@ -37,7 +37,6 @@ public interface SessionManager {
*/
public Session createSession(Connection conn) throws UnauthorizedException;
/**
* Change the priority of a session associated with the sender.
*
......@@ -82,28 +81,27 @@ public interface SessionManager {
throws UnauthorizedException, SessionNotFoundException;
/**
* <p>Obtain an iterator of all sessions on the server.</p>
* Returns the Collection of all sessions on the server.
*
* @return An iterator over the sessions (never null)
* @return the Collection of all sessions.
*/
public Iterator getSessions() throws UnauthorizedException;
public Collection<Session> getSessions();
/**
* <p>Obtain an iterator of all sessions on the server.</p>
* Returns a Collection of all sessions on the server given the
* specified ResultFilter.
*
* @param filter The result filter to apply to the search
* @return An iterator over the sessions (never null)
* @param filter the result filter to apply to the search.
* @return the Collection of all sessions.
*/
public Iterator getSessions(SessionResultFilter filter) throws UnauthorizedException;
public Collection<Session> getSessions(SessionResultFilter filter);
/**
* <p>Obtain an iterator of all anonymous sessions on the server.</p>
*
* @return An iterator over the anonynmous sessions (never null)
* @throws UnauthorizedException
* @throws UnauthorizedException If caller doesn't have permission to access this method
*/
public Iterator getAnonymousSessions() throws UnauthorizedException;
public Iterator getAnonymousSessions();
/**
* <p>Obtain an iterator of all sessions for a given user on the server.</p>
......
......@@ -421,7 +421,7 @@ public class SessionResultFilter {
*
* @return A comparator that sorts Sessions matching the sort order for this filter.
*/
public Comparator getSortComparator() {
public Comparator<Session> getSortComparator() {
return new SessionComparator();
}
......
......@@ -16,7 +16,6 @@ import org.jivesoftware.messenger.disco.IQDiscoInfoHandler;
import org.jivesoftware.messenger.disco.IQDiscoItemsHandler;
import org.jivesoftware.messenger.muc.spi.MultiUserChatServerImpl;
import org.jivesoftware.messenger.audit.spi.AuditManagerImpl;
import org.jivesoftware.messenger.auth.spi.GroupManagerImpl;
import org.jivesoftware.messenger.handler.*;
import org.jivesoftware.messenger.spi.*;
import org.jivesoftware.messenger.transport.TransportHandler;
......@@ -47,7 +46,6 @@ public class XMPPBootContainer extends BootstrapContainer {
protected String[] getCoreModuleNames() {
return new String[]{
GroupManagerImpl.class.getName(),
ConnectionManagerImpl.class.getName(),
PresenceManagerImpl.class.getName(),
SessionManagerImpl.class.getName(),
......
......@@ -52,7 +52,6 @@ public class AuthProviderFactory {
"org.jivesoftware.messenger.auth.spi.DbGroupProvider";
private static AuthProvider authProvider = null;
private static GroupProvider groupProvider = null;
/**
* Returns a concrete AuthProvider. By default, the implementation
......@@ -86,37 +85,4 @@ public class AuthProviderFactory {
}
return authProvider;
}
/**
* <p>Obtains a concrete GroupProvider.<p>
* <p/>
* <p>By default, the implementation used will be an instance
* of DbGroupProvider -- the standard database implementation
* that uses the Jive group table. A different GroupProvider can be
* specified by setting the Jive property "GroupProvider.className".
* However, you must restart Jive for any change to take effect.</p>
*/
public static GroupProvider getGroupProvider() {
if (groupProvider == null) {
// Use className as a convenient object to get a lock on.
synchronized (groupClassName) {
if (groupProvider == null) {
//See if the classname has been set as a Jive property.
String classNameProp =
JiveGlobals.getProperty("GroupProvider.className");
if (classNameProp != null) {
groupClassName = classNameProp;
}
try {
Class c = ClassUtils.forName(groupClassName);
groupProvider = (GroupProvider)c.newInstance();
}
catch (Exception e) {
Log.error("Exception loading class: " + groupClassName, e);
}
}
}
}
return groupProvider;
}
}
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.auth;
import org.jivesoftware.messenger.user.UserAlreadyExistsException;
import org.jivesoftware.messenger.user.User;
import java.util.Date;
import java.util.Iterator;
/**
* Organizes entities into a group for easier permissions management.
* In this way, groups essentially serve the same purpose that
* they do in Unix or Windows.<p>
* <p/>
* For example, CREATE_THREAD permissions can be set per forum. A
* forum administrator may wish to create a "Thread Posters" group
* that has CREATE_THREAD permissions in the forum. Then, users can
* be added to that group and will automatically receive CREATE_THREAD
* permissions in that forum.<p>
* <p/>
* Security for Group objects is provide by GroupProxy protection proxy objects.
*
* @author Iain Shigeoka
*/
public interface Group {
/**
* Returns the id of the group.
*
* @return the id of the group.
*/
public long getID();
/**
* Returns the name of the group. For example, 'XYZ Admins'.
*
* @return the name of the group.
*/
public String getName();
/**
* Sets the name of the group. For example, 'XYZ Admins'. This
* method is restricted to those with group administration permission.
*
* @param name the name for the group.
* @throws UnauthorizedException if does not have group administrator permissions.
*/
public void setName(String name) throws UnauthorizedException;
/**
* Returns the description of the group. The description often
* summarizes a group's function, such as 'Administrators of the XYZ forum'.
*
* @return the description of the group.
*/
public String getDescription();
/**
* Sets the description of the group. The description often
* summarizes a group's function, such as 'Administrators of
* the XYZ forum'. This method is restricted to those with group
* administration permission.
*
* @param description the description of the group.
* @throws UnauthorizedException if does not have group administrator permissions.
*/
public void setDescription(String description) throws UnauthorizedException;
/**
* Returns the date that the group was created.
*
* @return the date the group was created.
*/
public Date getCreationDate();
/**
* Sets the creation date of the group. In most cases, the
* creation date will default to when the group was entered
* into the system. However, the date needs to be set manually when
* importing data. In other words, skin authors should ignore
* this method since it only intended for system maintenance.
*
* @param creationDate the date the group was created.
* @throws UnauthorizedException if does not have administrator permissions.
*/
public void setCreationDate(Date creationDate) throws UnauthorizedException;
/**
* Returns the date that the group was last modified.
*
* @return the date the group record was last modified.
*/
public Date getModificationDate();
/**
* Sets the date the group was last modified. Skin authors
* should ignore this method since it only intended for
* system maintenance.
*
* @param modificationDate the date the group was modified.
* @throws UnauthorizedException if does not have administrator permissions.
*/
public void setModificationDate(Date modificationDate) throws UnauthorizedException;
/**
* Returns an extended property of the group. Each group can
* have an arbitrary number of extended properties. This
* lets particular skins or filters provide enhanced functionality
* that is not part of the base interface.
*
* @param name the name of the property to get.
* @return the value of the property
*/
public String getProperty(String name);
/**
* Sets an extended property of the group. Each group can have
* an arbitrary number of extended properties. This lets
* particular skins or filters provide enhanced functionality that is not
* part of the base interface.
*
* @param name the name of the property to set.
* @param value the new value for the property.
* @throws UnauthorizedException if not allowed to change the group.
*/
public void setProperty(String name, String value) throws UnauthorizedException;
/**
* Deletes an extended property. If the property specified by
* <code>name</code> does not exist, this method will do nothing.
*
* @param name the name of the property to delete.
* @throws UnauthorizedException if not allowed to edit messages.
*/
public void deleteProperty(String name) throws UnauthorizedException;
/**
* Returns an Iterator for all the names of the extended group properties.
*
* @return an Iterator for the property names.
*/
public Iterator getPropertyNames();
/**
* Grants administrator privileges of the group to a user. This
* method is restricted to those with group administration permission.
*
* @param user the User to grant adminstrative privileges to.
* @throws UnauthorizedException if does not have group administrator permissions.
*/
public void addAdministrator(User user) throws UnauthorizedException, UserAlreadyExistsException;
/**
* Revokes administrator privileges of the group to a user.
* This method is restricted to those with group administration permission.
*
* @param user the User to grant adminstrative privileges to.
* @throws UnauthorizedException if does not have group administrator permissions.
*/
public void removeAdministrator(User user) throws UnauthorizedException;
/**
* Adds a member to the group. This method is restricted to
* those with group administration permission.
*
* @param user the User to add to the group.
* @throws UnauthorizedException if does not have group administrator permissions.
*/
public void addMember(User user) throws UnauthorizedException, UserAlreadyExistsException;
/**
* Removes a member from the group. If the User is not
* in the group, this method does nothing. This method
* is restricted to those with group administration permission.
*
* @param user the User to remove from the group.
* @throws UnauthorizedException if does not have group administrator permissions.
*/
public void removeMember(User user) throws UnauthorizedException;
/**
* Returns true if the User has group administrator permissions.
*
* @return true if the User is an administrator of the group.
*/
public boolean isAdministrator(User user);
/**
* Returns true if if the User is a member of the group.
*
* @return true if the User is a member of the group.
*/
public boolean isMember(User user);
/**
* Returns the number of group administrators.
*
* @return the number of group administrators.
*/
public int getAdministratorCount();
/**
* Returns the number of group members.
*
* @return the number of group members.
*/
public int getMemberCount();
/**
* An iterator for all the Entities that are members of the group.
*
* @return an Iterator for all members of the group.
*/
public Iterator members();
/**
* An iterator for all the Entities that are administrators of the group.
*
* @return an Iterator for all administrators of the group.
*/
public Iterator administrators();
/**
* Returns the permissions for the group that correspond to the passed-in AuthToken.
*
* @param authToken the auth token to lookup permissions for.
* @return the permissions for the group that correspond to the passed-in AuthToken.
* @see Permissions
*/
public Permissions getPermissions(AuthToken authToken);
/**
* Returns true if the handle on the object has the
* permission specified. A list of possible
* permissions can be found in the Permissions class.
* Certain methods of this class are restricted to
* certain permissions as specified in the method comments.
*
* @param permissionType a permission type.
* @return true if the specified permission is valid.
* @see Permissions
*/
public boolean isAuthorized(long permissionType);
}
\ No newline at end of file
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.auth.spi;
import org.jivesoftware.database.DatabaseObjectFactory;
import org.jivesoftware.messenger.auth.Group;
import org.jivesoftware.messenger.auth.GroupManager;
import org.jivesoftware.messenger.auth.GroupNotFoundException;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* <p>An class that defines the logic to iterate through an array of
* long unique ID's of Jive objects.</p>
* <p/>
* <p>One feature of the class is the ability to recover from underlying
* modifications to the dataset in some cases. Consider the following
* sequence of events:</p>
* <ul>
* <li> Time 00: An Iterator for users in a group is obtained.
* <li> Time 01: 3 of the 8 users in the group are deleted.
* <li> Time 02: Iteration of users begins.
* </ul>
* <p/>
* <p>In the above example, the underlying users in the group were
* changed after the initial iterator was obtained. The logic in
* this class will attempt to automatically compensate for these changes
* by skipping over items that cannot be loaded. In the above example,
* that would translate to the iterator returning 5 users instead of 8.</p>
*
* @author Iain Shigeoka
*/
public class GroupIterator implements Iterator {
private long[] elements;
private int currentIndex = -1;
private Object nextElement = null;
private DatabaseObjectFactory objectFactory;
/**
* Creates a new GroupIterator.
*/
public GroupIterator(GroupManager manager, long[] elements) {
this.elements = elements;
// Create an objectFactory to load users.
this.objectFactory = new GroupDOFactory(manager);
}
private class GroupDOFactory implements DatabaseObjectFactory {
private GroupManager manager;
public GroupDOFactory(GroupManager manager) {
this.manager = manager;
}
public Object loadObject(long id) {
try {
Group group = manager.getGroup(id);
return group;
}
catch (GroupNotFoundException e) { /* ignore */
}
return null;
}
}
/**
* Returns true if there are more elements in the iteration.
*
* @return true if the iterator has more elements.
*/
public boolean hasNext() {
// If we are at the end of the list, there can't be any more elements
// to iterate through.
if (currentIndex + 1 >= elements.length && nextElement == null) {
return false;
}
// Otherwise, see if nextElement is null. If so, try to load the next
// element to make sure it exists.
if (nextElement == null) {
nextElement = getNextElement();
if (nextElement == null) {
return false;
}
}
return true;
}
/**
* Returns the next element.
*
* @return the next element.
* @throws java.util.NoSuchElementException
* if there are no more elements.
*/
public Object next() throws java.util.NoSuchElementException {
Object element = null;
if (nextElement != null) {
element = nextElement;
nextElement = null;
}
else {
element = getNextElement();
if (element == null) {
throw new NoSuchElementException();
}
}
return element;
}
/**
* Not supported for security reasons.
*/
public void remove() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/**
* Returns the next available element, or null if there are no more elements to return.
*
* @return the next available element.
*/
public Object getNextElement() {
while (currentIndex + 1 < elements.length) {
currentIndex++;
Object element = objectFactory.loadObject(elements[currentIndex]);
if (element != null) {
return element;
}
}
return null;
}
}
\ No newline at end of file
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.auth.spi;
import org.jivesoftware.util.ProxyFactory;
import org.jivesoftware.messenger.auth.AuthToken;
import org.jivesoftware.messenger.auth.Group;
import org.jivesoftware.messenger.auth.Permissions;
import java.util.Iterator;
/**
* Protection proxy for Iterators of groups.
*
* @author Iain Shigeoka
*/
public class GroupIteratorProxy implements Iterator {
private Iterator iterator;
private Object nextElement = null;
private AuthToken auth;
private Permissions permissions;
private ProxyFactory proxyFactory;
/**
* Creates a new group iterator proxy.
*
* @param iterator the Iterator to create proxies for.
* @param auth the authorization token.
* @param permissions the permissions that the new proxy will inherit.
*/
public GroupIteratorProxy(Iterator iterator, AuthToken auth, Permissions permissions) {
this.iterator = iterator;
this.auth = auth;
this.permissions = permissions;
// Create a class that wraps groups with proxies.
proxyFactory = new ProxyFactory() {
public Object createProxy(Object obj, AuthToken auth, Permissions perms) {
Group group = (Group)obj;
Permissions userPerms = group.getPermissions(auth);
Permissions newPerms = new Permissions(userPerms, perms);
return new GroupProxy(group, auth, newPerms);
}
};
}
/**
* Returns true if there are more elements in the iteration.
*
* @return true if the iterator has more elements.
*/
public boolean hasNext() {
// If we are at the end of the list, there can't be any more elements to iterate through.
if (!iterator.hasNext() && nextElement == null) {
return false;
}
// Otherwise, see if nextElement is null. If so, try to load the next element to make sure
// it exists.
if (nextElement == null) {
nextElement = getNextElement();
if (nextElement == null) {
return false;
}
}
return true;
}
/**
* Returns the next element.
*
* @return the next element.
* @throws java.util.NoSuchElementException
* if there are no more elements.
*/
public Object next() throws java.util.NoSuchElementException {
Object element = null;
if (nextElement != null) {
element = nextElement;
nextElement = null;
}
else {
element = getNextElement();
if (element == null) {
throw new java.util.NoSuchElementException();
}
}
return element;
}
/**
* Not supported for security reasons.
*/
public void remove() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/**
* Returns the next available element, or null if there are no more elements.
*
* @return the next available element.
*/
public Object getNextElement() {
while (iterator.hasNext()) {
Object element = proxyFactory.createProxy(iterator.next(), auth, permissions);
if (element != null) {
return element;
}
}
return null;
}
}
\ No newline at end of file
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.auth.spi;
import org.jivesoftware.util.CacheManager;
import org.jivesoftware.messenger.container.BasicModule;
import org.jivesoftware.messenger.container.Container;
import org.jivesoftware.util.Cache;
import org.jivesoftware.util.*;
import org.jivesoftware.messenger.auth.*;
import org.jivesoftware.messenger.user.User;
import java.util.Iterator;
/**
* Database implementation of the GroupManager interface.
*
* @author Iain Shigeoka
*/
public class GroupManagerImpl extends BasicModule implements GroupManager {
private GroupProvider provider = AuthProviderFactory.getGroupProvider();
/**
* A cache for group object.s
*/
private Cache groupCache;
/**
* A cache that maps group names to ID's.
*/
private Cache groupIDCache;
/**
* A cache for the list members of in each group.
*/
private Cache groupMemberCache;
public GroupManagerImpl() {
super("Group Manager (database-backed)");
}
public Group createGroup(String name)
throws UnauthorizedException, GroupAlreadyExistsException {
Group newGroup = null;
try {
getGroup(name);
// The group already exists since now exception, so:
throw new GroupAlreadyExistsException();
}
catch (GroupNotFoundException unfe) {
// The group doesn't already exist so we can create a new group
newGroup = provider.createGroup(name);
groupCache.put(new Long(newGroup.getID()), newGroup);
}
return newGroup;
}
public Group getGroup(long groupID) throws GroupNotFoundException {
Group group = (Group)groupCache.get(new Long(groupID));
if (group == null) {
group = provider.getGroup(groupID);
groupCache.put(new Long(groupID), group);
}
return group;
}
public Group getGroup(String name) throws GroupNotFoundException {
Long groupIDLong = (Long)groupIDCache.get(name);
// If ID wan't found in cache, load it up and put it there.
if (groupIDLong == null) {
Group group = provider.getGroup(name);
groupIDLong = new Long(group.getID());
groupIDCache.put(name, groupIDLong);
}
return getGroup(groupIDLong.longValue());
}
public void deleteGroup(Group group) throws UnauthorizedException {
long groupID = group.getID();
String[] members = new String[group.getMemberCount()];
Iterator iter = group.members();
for (int i = 0; i < members.length; i++) {
User user = (User)iter.next();
members[i] = user.getUsername();
}
provider.deleteGroup(group.getID());
// Finally, expire all relevant caches
groupCache.remove(new Long(groupID));
groupIDCache.remove(group.getName());
// Remove entries in the group membership cache for all members of the group.
for (int i = 0; i < members.length; i++) {
groupMemberCache.remove("userGroups-" + members[i]);
}
// Removing a group can change the permissions of all the users in that
// group. Therefore, expire permissions cache.
}
public int getGroupCount() {
return provider.getGroupCount();
}
public Iterator getGroups() {
LongList groups = provider.getGroups();
return new GroupIterator(this, groups.toArray());
}
public Iterator getGroups(BasicResultFilter filter) {
LongList groups = provider.getGroups(filter);
return new GroupIterator(this, groups.toArray());
}
public Iterator getGroups(User user) {
String username = user.getUsername();
String key = "userGroups-" + username;
// Look in the group membership cache for the value.
long[] groups = (long[])groupMemberCache.get(key);
if (groups == null) {
groups = provider.getGroups(username).toArray();
}
return new GroupIterator(this, groups);
}
// #####################################################################
// Module management
// #####################################################################
public void initialize(Container container) {
super.initialize(container);
CacheManager.initializeCache(GROUP_CACHE_NAME, 128 * 1024);
CacheManager.initializeCache(GROUP_ID_CACHE_NAME, 128 * 1024);
CacheManager.initializeCache(GROUP_MEMBER_CACHE_NAME, 16 * 1024);
groupCache = CacheManager.getCache(GROUP_CACHE_NAME);
groupIDCache = CacheManager.getCache(GROUP_ID_CACHE_NAME);
groupMemberCache = CacheManager.getCache(GROUP_MEMBER_CACHE_NAME);
}
}
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.auth.spi;
import org.jivesoftware.util.BasicResultFilter;
import org.jivesoftware.util.JiveConstants;
import org.jivesoftware.messenger.auth.*;
import org.jivesoftware.messenger.user.spi.UserGroupIteratorProxy;
import org.jivesoftware.messenger.user.User;
import java.util.Iterator;
/**
* Protection proxy for the GroupManager class. It restricts access to
* protected methods by throwing UnauthorizedExceptions when necessary.
*
* @author Iain Shigeoka
* @see org.jivesoftware.messenger.auth.GroupManager
*/
public class GroupManagerProxy implements GroupManager {
private GroupManager groupManager;
private AuthToken auth;
private Permissions permissions;
/**
* Creates a new GroupManagerProxy.
*/
public GroupManagerProxy(GroupManager groupManager, AuthToken auth, Permissions permissions) {
this.groupManager = groupManager;
this.auth = auth;
this.permissions = permissions;
}
public Group createGroup(String name)
throws UnauthorizedException, GroupAlreadyExistsException {
if (permissions.hasPermission(Permissions.SYSTEM_ADMIN)) {
Group group = groupManager.createGroup(name);
return new GroupProxy(group, auth, permissions);
}
else {
throw new UnauthorizedException();
}
}
public Group getGroup(long groupID) throws GroupNotFoundException {
Group group = groupManager.getGroup(groupID);
Permissions groupPermissions = group.getPermissions(auth);
Permissions newPermissions = new Permissions(permissions, groupPermissions);
return new GroupProxy(group, auth, newPermissions);
}
public Group getGroup(String name) throws GroupNotFoundException {
Group group = groupManager.getGroup(name);
Permissions groupPermissions = group.getPermissions(auth);
Permissions newPermissions =
new Permissions(permissions, groupPermissions);
return new GroupProxy(group, auth, newPermissions);
}
public void deleteGroup(Group group) throws UnauthorizedException {
if (permissions.hasPermission(Permissions.SYSTEM_ADMIN)) {
groupManager.deleteGroup(group);
}
else {
throw new UnauthorizedException();
}
}
public int getGroupCount() {
return groupManager.getGroupCount();
}
public Iterator getGroups() {
Iterator iterator = groupManager.getGroups();
return new UserGroupIteratorProxy(JiveConstants.GROUP, iterator, auth, permissions);
}
public Iterator getGroups(BasicResultFilter filter) {
Iterator iterator = groupManager.getGroups(filter);
return new UserGroupIteratorProxy(JiveConstants.GROUP, iterator, auth, permissions);
}
public Iterator getGroups(User user) {
Iterator iterator = groupManager.getGroups(user);
return new UserGroupIteratorProxy(JiveConstants.GROUP, iterator, auth, permissions);
}
}
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.auth.spi;
import org.jivesoftware.messenger.auth.AuthToken;
import org.jivesoftware.messenger.auth.Group;
import org.jivesoftware.messenger.auth.Permissions;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.UserAlreadyExistsException;
import org.jivesoftware.messenger.user.User;
import org.jivesoftware.messenger.user.spi.UserIteratorProxy;
import java.util.Date;
import java.util.Iterator;
/**
* Protection proxy for the Group interface. It restricts access of certain
* methods to those that have the proper permissions to administer this object.
*
* @author Iain Shigeoka
*/
public class GroupProxy implements Group {
private Group group;
private AuthToken authToken;
private Permissions permissions;
public GroupProxy(Group group, AuthToken authToken, Permissions permissions) {
this.group = group;
this.authToken = authToken;
this.permissions = permissions;
}
public long getID() {
return group.getID();
}
public String getName() {
return group.getName();
}
public void setName(String name) throws UnauthorizedException {
if (permissions.hasPermission(Permissions.SYSTEM_ADMIN
| Permissions.GROUP_ADMIN)) {
group.setName(name);
}
else {
throw new UnauthorizedException();
}
}
public String getDescription() {
return group.getDescription();
}
public void setDescription(String description) throws UnauthorizedException {
if (permissions.hasPermission(Permissions.SYSTEM_ADMIN
| Permissions.GROUP_ADMIN)) {
group.setDescription(description);
}
else {
throw new UnauthorizedException();
}
}
public Date getCreationDate() {
return group.getCreationDate();
}
public void setCreationDate(Date creationDate)
throws UnauthorizedException {
if (permissions.hasPermission(Permissions.SYSTEM_ADMIN)) {
group.setCreationDate(creationDate);
}
else
throw new UnauthorizedException();
}
public Date getModificationDate() {
return group.getModificationDate();
}
public void setModificationDate(Date modificationDate)
throws UnauthorizedException {
if (permissions.hasPermission(Permissions.SYSTEM_ADMIN)) {
group.setModificationDate(modificationDate);
}
else
throw new UnauthorizedException();
}
public String getProperty(String name) {
return group.getProperty(name);
}
public void setProperty(String name, String value)
throws UnauthorizedException {
if (permissions.hasPermission(Permissions.SYSTEM_ADMIN
| Permissions.GROUP_ADMIN)) {
group.setProperty(name, value);
}
else {
throw new UnauthorizedException();
}
}
public void deleteProperty(String name) throws UnauthorizedException {
if (permissions.hasPermission(Permissions.SYSTEM_ADMIN
| Permissions.GROUP_ADMIN)) {
group.deleteProperty(name);
}
else {
throw new UnauthorizedException();
}
}
public Iterator getPropertyNames() {
return group.getPropertyNames();
}
public void addAdministrator(User user)
throws UnauthorizedException, UserAlreadyExistsException {
if (permissions.hasPermission(Permissions.SYSTEM_ADMIN
| Permissions.GROUP_ADMIN)) {
group.addAdministrator(user);
}
else {
throw new UnauthorizedException();
}
}
public void removeAdministrator(User user) throws UnauthorizedException {
if (permissions.hasPermission(Permissions.SYSTEM_ADMIN
| Permissions.GROUP_ADMIN)) {
group.removeAdministrator(user);
}
else {
throw new UnauthorizedException();
}
}
public void addMember(User user)
throws UnauthorizedException, UserAlreadyExistsException {
if (permissions.hasPermission(Permissions.SYSTEM_ADMIN
| Permissions.GROUP_ADMIN)) {
group.addMember(user);
}
else {
throw new UnauthorizedException();
}
}
public void removeMember(User user) throws UnauthorizedException {
if (permissions.hasPermission(Permissions.SYSTEM_ADMIN
| Permissions.GROUP_ADMIN)) {
group.removeMember(user);
}
else {
throw new UnauthorizedException();
}
}
public boolean isAdministrator(User user) {
return group.isAdministrator(user);
}
public boolean isMember(User user) {
return group.isMember(user);
}
public int getAdministratorCount() {
return group.getAdministratorCount();
}
public int getMemberCount() {
return group.getMemberCount();
}
public Iterator members() {
return new UserIteratorProxy(group.members(), authToken, permissions);
}
public Iterator administrators() {
return new UserIteratorProxy(group.administrators(), authToken, permissions);
}
public Permissions getPermissions(AuthToken authToken) {
return group.getPermissions(authToken);
}
public boolean isAuthorized(long type) {
return permissions.hasPermission(type);
}
}
\ No newline at end of file
......@@ -69,6 +69,7 @@ public class AdminConsolePlugin implements Plugin {
log.add(logSink);
jetty = new Server();
// Configure HTTP socket listener
port = JiveGlobals.getProperty("embedded-web.port", "9090");
......
This diff is collapsed.
......@@ -9,7 +9,7 @@
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.auth;
package org.jivesoftware.messenger.group;
import java.io.PrintStream;
import java.io.PrintWriter;
......
......@@ -9,34 +9,52 @@
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.auth;
package org.jivesoftware.messenger.group;
import org.jivesoftware.util.BasicResultFilter;
import org.jivesoftware.util.Cache;
import org.jivesoftware.util.CacheManager;
import org.jivesoftware.util.ClassUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.messenger.user.User;
import org.jivesoftware.messenger.JiveGlobals;
import java.util.Iterator;
import java.util.Collection;
import java.util.ArrayList;
/**
* <p>Manages groups.</p>
* Manages groups
*
* @author Iain Shigeoka
* @see Group
* @author Matt Tucker
*/
public interface GroupManager {
public class GroupManager {
/**
* <p>The name of the group cache mapping long ID to Group object.</p>
*/
String GROUP_CACHE_NAME = "group";
/**
* <p>Cache of group names to group Long ID's.</p>
*/
String GROUP_ID_CACHE_NAME = "groupID";
/**
* <p>Cache of String("userGroups-" + memberID) to long[]
* array of group ID's that member belongs to.</p>
*/
String GROUP_MEMBER_CACHE_NAME = "groupMember";
Cache groupCache;
Cache groupMemberCache;
private GroupProvider provider;
public static GroupManager getInstance() {
return null;
}
private GroupManager() {
// Initialize caches.
CacheManager.initializeCache("group", 128 * 1024);
CacheManager.initializeCache("group member", 32 * 1024);
groupCache = CacheManager.getCache("group");
groupMemberCache = CacheManager.getCache("group member");
// Load a group provider.
String className = JiveGlobals.getXMLProperty("group.provider.className",
"org.jivesoftware.messenger.group.DbGroupProvider");
try {
Class c = ClassUtils.forName(className);
provider = (GroupProvider)c.newInstance();
}
catch (Exception e) {
Log.error("Error loading group provider: " + className, e);
provider = new DbGroupProvider();
}
}
/**
* Factory method for creating a new Group. A unique name is the only required field.
......@@ -45,48 +63,77 @@ public interface GroupManager {
* @return a new Group.
* @throws GroupAlreadyExistsException if the group name already exists in the system.
*/
Group createGroup(String name)
throws UnauthorizedException, GroupAlreadyExistsException;
public Group createGroup(String name) throws GroupAlreadyExistsException {
synchronized (name.intern()) {
Group newGroup = null;
try {
getGroup(name);
// The group already exists since now exception, so:
throw new GroupAlreadyExistsException();
}
catch (GroupNotFoundException unfe) {
// The group doesn't already exist so we can create a new group
newGroup = provider.createGroup(name);
groupCache.put(name, newGroup);
}
return newGroup;
}
}
/**
* Gets a Group by ID.
*
* @param groupID The ID of the group to retrieve
* @return The group corresponding to the given ID
* @throws GroupNotFoundException if the group does not exist.
*/
Group getGroup(long groupID) throws GroupNotFoundException;
/**
* Gets a Group by name.
* Returns a Group by name.
*
* @param name The name of the group to retrieve
* @return The group corresponding to that name
* @throws GroupNotFoundException if the group does not exist.
*/
Group getGroup(String name) throws GroupNotFoundException;
public Group getGroup(String name) throws GroupNotFoundException {
Group group = (Group)groupCache.get(name);
// If ID wan't found in cache, load it up and put it there.
if (group == null) {
group = provider.getGroup(name);
groupCache.put(name, group);
}
return group;
}
/**
* Deletes a group from the system.
*
* @param group the group to delete.
* @throws UnauthorizedException if not a system administrator.
*/
void deleteGroup(Group group) throws UnauthorizedException;
public void deleteGroup(Group group) {
// Make a copy of the group members.
Collection<String> members = new ArrayList<String>(group.getMembers());
// Delete the group.
provider.deleteGroup(group.getName());
// Expire all relevant caches.
groupCache.remove(group.getName());
// Remove entries in the group membership cache for all members of the group.
for (String username : members) {
groupMemberCache.remove("userGroups-" + username);
}
}
/**
* Returns the total number of groups in the system.
*
* @return the total number of groups.
*/
int getGroupCount();
public int getGroupCount() {
return provider.getGroupCount();
}
/**
* Returns an iterator for all groups in the system.
* Returns an unmodifiable Collection of all groups in the system.
*
* @return an Iterator for all groups.
* @return an unmodifiable Collection of all groups.
*/
public Iterator getGroups();
public Collection<Group> getGroups() {
return provider.getGroups();
}
/**
* Returns an iterator for all groups according to a filter.
......@@ -98,10 +145,13 @@ public interface GroupManager {
* numResults if numResults is greater than the number of records left in
* the system to display.
*
* @param filter the filter to restrict results with
* @param startIndex start index in results.
* @param numResults number of results to return.
* @return an Iterator for all groups in the specified range.
*/
public Iterator getGroups(BasicResultFilter filter);
public Collection<Group> getGroups(int startIndex, int numResults) {
return provider.getGroups(startIndex, numResults);
}
/**
* Returns an iterator for all groups that a user is a member of.
......@@ -109,5 +159,7 @@ public interface GroupManager {
* @param user the user to get a list of groups for.
* @return all groups that a user belongs to.
*/
public Iterator getGroups(User user);
public Collection<Group> getGroups(User user) {
return provider.getGroups(user);
}
}
\ No newline at end of file
......@@ -9,7 +9,7 @@
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.auth;
package org.jivesoftware.messenger.group;
import java.io.PrintStream;
import java.io.PrintWriter;
......
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.group;
import org.jivesoftware.messenger.user.User;
import java.util.Collection;
import java.util.Date;
/**
* Group providers load and store group information from a back-end store
* such as a database table, LDAP, etc.
*
* @author Matt Tucker
*/
public interface GroupProvider {
/**
* Creates a group with the given name (optional operation).<p>
*
* The provider is responsible for setting the creation date and
* modification date to the current date/time.
*
* @param name name of the group.
* @return the newly created group.
* @throws GroupAlreadyExistsException if a group with the same name already
* exists.
* @throws UnsupportedOperationException if the provider does not
* support the operation.
*/
Group createGroup(String name) throws UnsupportedOperationException,
GroupAlreadyExistsException;
/**
* Deletes the group (optional operation).
*
* @param name the name of the group to delete
* @throws UnsupportedOperationException if the provider does not
* support the operation.
*/
void deleteGroup(String name) throws UnsupportedOperationException;
/**
* Returns a group based on it's name.
*
* @param name the name of the group.
* @return the group with the given name.
* @throws GroupNotFoundException If no group with that ID could be found
*/
Group getGroup(String name) throws GroupNotFoundException;
/**
* Sets the name of a group to a new name.
*
* @param oldName the current name of the group.
* @param newName the desired new name of the group.
* @throws GroupAlreadyExistsException if a group with the same name already
* exists.
* @throws UnsupportedOperationException if the provider does not
* support the operation.
*/
public void setGroupName(String oldName, String newName) throws UnsupportedOperationException,
GroupAlreadyExistsException;
/**
* Updates the backend storage with the group's information.
*
* @param name the group name.
* @param description the group description.
* @param creationDate the date the group was created.
* @param modificationDate the date the group was last modified.
* @throws GroupNotFoundException if no existing group could be found to update.
*/
void updateGroup(String name, String description, Date creationDate, Date modificationDate)
throws GroupNotFoundException;
/**
* Returns the number of groups in the system.
*
* @return the number of groups in the system.
*/
int getGroupCount();
/**
* Returns the Collection of all groups in the system.
*
* @return the Collection of all groups.
*/
Collection<Group> getGroups();
/**
* Returns the Collection of all groups in the system.
*
* @param startIndex start index in results.
* @param numResults number of results to return.
* @return the Collection of all groups given the <tt>startIndex</tt> and <tt>numResults</tt>.
*/
Collection<Group> getGroups(int startIndex, int numResults);
/**
* Returns the Collection of Groups that a user belongs to.
*
* @param user the user.
* @return the Collection of groups that the user belongs to.
*/
Collection<Group> getGroups(User user);
/**
* Adds a user to a group (optional operation).
*
* @param groupName the group to add the member to
* @param username the username 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)
throws UnsupportedOperationException;
/**
* Deletes a user from a group (optional operation).
*
* @param groupName the group name.
* @param username the username.
* @throws UnsupportedOperationException if the provider does not
* support the operation.
*/
void deleteMember(String groupName, String username) throws UnsupportedOperationException;
}
\ No newline at end of file
......@@ -36,34 +36,15 @@ public class SessionManagerImpl extends BasicModule implements SessionManager,
ConnectionCloseListener
{
/**
* Total number of sessions being managed
*/
private int sessionCount = 0;
public XMPPServer server;
/**
* Packet deliverer
*/
public PacketRouter router;
/**
* Packet router
*/
public PacketTransporter transporter;
/**
* Name of the local server
*/
private String serverName;
private XMPPAddress serverAddress;
public UserManager userManager;
/**
* Sets the conflict limit of the server.
*/
private int conflictLimit;
/**
* Random resource name generation
*/
private Random randomResource = new Random();
public SessionManagerImpl() {
......@@ -458,20 +439,18 @@ public class SessionManagerImpl extends BasicModule implements SessionManager,
return session;
}
public Iterator getSessions() throws UnauthorizedException {
LinkedList allSessions = new LinkedList();
public Collection<Session> getSessions() {
List<Session> allSessions = new ArrayList<Session>();
copyUserSessions(allSessions);
copyAnonSessions(allSessions);
return allSessions.iterator();
return allSessions;
}
public Iterator getSessions(SessionResultFilter filter) throws UnauthorizedException {
Iterator resultIterator = null;
public Collection<Session> getSessions(SessionResultFilter filter) {
List<Session> results = new ArrayList<Session>();
if (filter != null) {
// Grab all the possible matching sessions by user
LinkedList results = new LinkedList();
if (filter.getUsername() == null) {
// No user id filtering
copyAnonSessions(results);
......@@ -479,7 +458,8 @@ public class SessionManagerImpl extends BasicModule implements SessionManager,
}
else {
try {
copyUserSessions(userManager.getUser(filter.getUsername()).getUsername(), results);
copyUserSessions(userManager.getUser(filter.getUsername()).getUsername(),
results);
}
catch (UserNotFoundException e) {
}
......@@ -490,20 +470,11 @@ public class SessionManagerImpl extends BasicModule implements SessionManager,
Date activityMin = filter.getLastActivityDateRangeMin();
Date activityMax = filter.getLastActivityDateRangeMax();
// Stores the sorted results of the filtering
// We defer sorting until we have the final list
// I'm not sure if this is faster than just dumping everything into
// the sorted tree set from the beginning...
TreeSet sortedResults = new TreeSet(filter.getSortComparator());
// Now we have a copy of the references so we can spend some time
// doing the rest of the filtering without locking out session access
// so let's iterate and filter each session one by one
// Should this checking be done in the session class instead?
Iterator resultIter = results.iterator();
while (resultIter.hasNext()) {
Session session = (Session)resultIter.next();
List<Session> filteredResults = new ArrayList<Session>();
for (Session session : results) {
// Now filter on creation date if needed
if (createMin != null || createMax != null) {
if (!isBetweenDates(session.getCreationDate(), createMin, createMax)) {
......@@ -531,28 +502,32 @@ public class SessionManagerImpl extends BasicModule implements SessionManager,
}
}
if (session != null) {
sortedResults.add(session);
filteredResults.add(session);
}
}
// Sort list.
Collections.sort(filteredResults, filter.getSortComparator());
int maxResults = filter.getNumResults();
if (maxResults == SessionResultFilter.NO_RESULT_LIMIT) {
maxResults = sortedResults.size();
maxResults = filteredResults.size();
}
// Now generate the final list. I believe it's faster to to build up a new
// list than it is to remove items from head and tail of the sorted tree
LinkedList finalResults = new LinkedList();
Iterator sortedIter = sortedResults.iterator();
List<Session> finalResults = new ArrayList<Session>();
int startIndex = filter.getStartIndex();
Iterator<Session> sortedIter = filteredResults.iterator();
for (int i = 0; sortedIter.hasNext() && finalResults.size() < maxResults; i++) {
Object result = sortedIter.next();
Session result = sortedIter.next();
if (i >= startIndex) {
finalResults.add(result);
}
}
resultIterator = finalResults.iterator();
return finalResults;
}
return resultIterator;
return results;
}
/**
......@@ -653,7 +628,7 @@ public class SessionManagerImpl extends BasicModule implements SessionManager,
}
}
public Iterator getAnonymousSessions() throws UnauthorizedException {
public Iterator getAnonymousSessions() {
return Arrays.asList(anonymousSessions.values().toArray()).iterator();
}
......@@ -961,9 +936,7 @@ public class SessionManagerImpl extends BasicModule implements SessionManager,
sendServerMessage(null, LocaleUtils.getLocalizedString("admin.shutdown.now"));
super.stop();
try {
Iterator sIter = this.getSessions();
while (sIter.hasNext()) {
Session session = (Session)sIter.next();
for (Session session : getSessions()) {
try {
session.getConnection().close();
}
......
......@@ -70,31 +70,16 @@ public class SessionManagerProxy implements SessionManager {
}
}
public Iterator getSessions() throws UnauthorizedException {
if (permissions.hasPermission(Permissions.SYSTEM_ADMIN | Permissions.USER_ADMIN)) {
return sessionManager.getSessions();
}
else {
throw new UnauthorizedException();
}
public Collection<Session> getSessions() {
return sessionManager.getSessions();
}
public Iterator getSessions(SessionResultFilter filter) throws UnauthorizedException {
if (permissions.hasPermission(Permissions.SYSTEM_ADMIN | Permissions.USER_ADMIN)) {
return sessionManager.getSessions(filter);
}
else {
throw new UnauthorizedException();
}
public Collection<Session> getSessions(SessionResultFilter filter) {
return sessionManager.getSessions(filter);
}
public Iterator getAnonymousSessions() throws UnauthorizedException {
if (permissions.hasPermission(Permissions.SYSTEM_ADMIN | Permissions.USER_ADMIN)) {
return sessionManager.getAnonymousSessions();
}
else {
throw new UnauthorizedException();
}
public Iterator getAnonymousSessions() {
return sessionManager.getAnonymousSessions();
}
public Collection<Session> getSessions(String username) throws UnauthorizedException {
......
......@@ -12,7 +12,6 @@
package org.jivesoftware.messenger.user;
import org.jivesoftware.messenger.auth.AuthToken;
import org.jivesoftware.messenger.auth.Group;
import org.jivesoftware.messenger.auth.Permissions;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import java.util.Iterator;
......@@ -25,8 +24,6 @@ import java.util.Iterator;
* <p>Security for User objects is provide by UserProxy protection proxy objects.</p>
*
* @author Iain Shigeoka
*
* @see Group
*/
public interface User {
......
......@@ -11,7 +11,6 @@
package org.jivesoftware.messenger.user;
import org.jivesoftware.messenger.auth.Group;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.util.Cacheable;
......@@ -29,7 +28,6 @@ import java.util.Date;
* <p>Security for UserInfo objects is provide by UserInfoProxy protection proxy objects.</p>
*
* @author Iain Shigeoka
* @see Group
*/
public interface UserInfo extends Cacheable {
......
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.user.spi;
import org.jivesoftware.util.JiveConstants;
import org.jivesoftware.util.ProxyFactory;
import org.jivesoftware.messenger.auth.AuthToken;
import org.jivesoftware.messenger.auth.Group;
import org.jivesoftware.messenger.auth.Permissions;
import org.jivesoftware.messenger.auth.spi.GroupProxy;
import org.jivesoftware.messenger.user.User;
import java.util.Iterator;
/**
* Protection proxy for Iterators of users and groups. The class is also smart enough to skip
* over elements in the Iterator that the user doesn't have permission to read.
*
* @author Iain Shigeoka
*/
public class UserGroupIteratorProxy implements Iterator {
private Iterator iterator;
private Object nextElement = null;
private AuthToken auth;
private Permissions permissions;
private ProxyFactory proxyFactory;
/**
* Creates a new iterator proxy.
*
* @param type the type of object to be proxied. Must be a valid value from JiveConstants.
* @param iterator the Iterator to create proxies for.
* @param auth the authorization token.
* @param permissions the permissions that the new proxy will inherit.
*/
public UserGroupIteratorProxy(int type, Iterator iterator, AuthToken auth,
Permissions permissions) {
this.iterator = iterator;
this.auth = auth;
this.permissions = permissions;
// Load the appropriate proxy factory depending on the type of object that we're iterating
// through. Each proxy factory is responsible for checking that the user has permission to
// view the object, and then wrapping it with an appropriate proxy.
switch (type) {
// USER
case JiveConstants.USER:
// Create a class that wraps users with proxies.
proxyFactory = new ProxyFactory() {
public Object createProxy(Object obj, AuthToken auth, Permissions perms) {
User user = (User)obj;
Permissions userPerms = user.getPermissions(auth);
Permissions newPerms = new Permissions(perms, userPerms);
return new UserProxy(user, auth, newPerms);
}
};
break;
// GROUP
case JiveConstants.GROUP:
// Create a class that wraps groups with proxies.
proxyFactory = new ProxyFactory() {
public Object createProxy(Object obj, AuthToken auth, Permissions perms) {
Group group = (Group)obj;
Permissions groupPerms = group.getPermissions(auth);
Permissions newPerms = new Permissions(perms, groupPerms);
return new GroupProxy(group, auth, newPerms);
}
};
break;
// Otherwise, an invalid value was passed in so throw an exception.
default:
throw new IllegalArgumentException();
}
}
/**
* Returns true if there are more elements in the iteration.
*
* @return true if the iterator has more elements.
*/
public boolean hasNext() {
// If we are at the end of the list, there can't be any more elements to iterate through.
if (!iterator.hasNext() && nextElement == null) {
return false;
}
// Otherwise, see if nextElement is null. If so, try to load the next element to make sure
// it exists.
if (nextElement == null) {
nextElement = getNextElement();
if (nextElement == null) {
return false;
}
}
return true;
}
/**
* Returns the next element.
*
* @return the next element.
* @throws java.util.NoSuchElementException
* if there are no more elements.
*/
public Object next() throws java.util.NoSuchElementException {
Object element = null;
if (nextElement != null) {
element = nextElement;
nextElement = null;
}
else {
element = getNextElement();
if (element == null) {
throw new java.util.NoSuchElementException();
}
}
return element;
}
/**
* Not supported for security reasons.
*/
public void remove() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/**
* Returns the next available element, or null if there are no more elements.
*
* @return the next available element.
*/
public Object getNextElement() {
while (iterator.hasNext()) {
Object element = proxyFactory.createProxy(iterator.next(), auth, permissions);
if (element != null) {
return element;
}
}
return null;
}
}
......@@ -71,13 +71,11 @@ public class UserManagerProxy implements UserManager {
}
public Iterator users() throws UnauthorizedException {
Iterator iterator = userManager.users();
return new UserGroupIteratorProxy(JiveConstants.USER, iterator, auth, permissions);
return userManager.users();
}
public Iterator users(int startIndex, int numResults) throws UnauthorizedException {
Iterator iterator = userManager.users(startIndex, numResults);
return new UserGroupIteratorProxy(JiveConstants.USER, iterator, auth, permissions);
return userManager.users(startIndex, numResults);
}
public String getName() {
......
......@@ -16,9 +16,6 @@ package org.jivesoftware.util;
*/
public class JiveConstants {
public static final int USER = 3;
public static final int GROUP = 4;
public static final int SYSTEM = 17;
public static final int ROSTER = 18;
public static final int OFFLINE = 19;
......
......@@ -10,7 +10,7 @@
--%>
<%@ page import="org.jivesoftware.util.*,
java.util.Iterator,
java.util.*,
org.jivesoftware.messenger.*,
java.util.Date,
org.jivesoftware.admin.*,
......@@ -129,8 +129,8 @@ Below is a list of sessions on this server.
SessionResultFilter filter = new SessionResultFilter();
filter.setStartIndex(start);
filter.setNumResults(range);
Iterator sessions = sessionManager.getSessions(filter);
if (!sessions.hasNext()) {
Collection<Session> sessions = sessionManager.getSessions(filter);
if (sessions.isEmpty()) {
%>
<tr>
<td colspan="8">
......@@ -145,8 +145,7 @@ Below is a list of sessions on this server.
<% int count = start;
boolean current = false; // needed in session-row.jspf
String linkURL = "session-details.jsp";
while (sessions.hasNext()) {
Session sess = (Session)sessions.next();
for (Session sess : sessions) {
count++;
%>
<%@ include file="session-row.jspf" %>
......
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