diff --git a/conf/venice-db-init-mysql.sql b/conf/venice-db-init-mysql.sql
index ed379a5..af6033b 100644
--- a/conf/venice-db-init-mysql.sql
+++ b/conf/venice-db-init-mysql.sql
@@ -534,7 +534,8 @@ INSERT INTO namespaces (nsid, namespace) VALUES
(16, 'http://www.silverwrist.com/NS/venice/2003/05/30/community.globals' ),
(17, 'http://www.silverwrist.com/NS/venice/2003/05/31/sidebox.context.ids' ),
(18, 'http://www.silverwrist.com/NS/venice/2003/05/31/test.sideboxes' ),
- (19, 'http://www.silverwrist.com/NS/venice/2003/06/03/standard.sideboxes' );
+ (19, 'http://www.silverwrist.com/NS/venice/2003/06/03/standard.sideboxes' ),
+ (20, 'http://www.silverwrist.com/NS/venice/2003/06/18/community.security' );
# Initial global properties setup
INSERT INTO globalprop (nsid, prop_name, prop_value) VALUES
@@ -672,6 +673,20 @@ Report abuses to: '),
#stacktrace( $except )
-->
#end'),
+ (6, 'confirm.box',
+'
'),
(6, 'user.agreement',
'Text of this agreement is to be determined.'),
(12, 'confirm.message',
@@ -1323,7 +1338,8 @@ INSERT INTO commprops (cid, nsid, prop_name, prop_value) VALUES
(1, 15, 'region', '!XX' ),
(1, 15, 'postal.code', '!00000' ),
(1, 15, 'country', '_CTRY:US' ),
- (1, 15, 'url.homepage', '!http://venice.sourceforge.net' );
+ (1, 15, 'url.homepage', '!http://venice.sourceforge.net' ),
+ (1, 20, 'type.hint', 'I0' );
# Create the "global" menu. (ID #1)
INSERT INTO menus (menuid, menu_nsid, menu_name, title, subtitle)
@@ -1380,14 +1396,16 @@ INSERT INTO menuvars (menuid, var_name, default_val) VALUES
(5, 'name', NULL);
INSERT INTO menuitems (menuid, sequence, itemtype, text, linktype, link) VALUES
(5, 0, 'TEXT', 'Home Page', 'SERVLET', 'community/${alias}' ),
- (5, 60000, 'TEXT', 'Members', 'SERVLET', 'TODO' ),
- (5, 60100, 'TEXT', 'Profile', 'SERVLET', 'comm/profile.js.vs?cc=${cid}' ),
- (5, 60200, 'TEXT', 'Administration', 'SERVLET', 'comm/admin/main.js.vs?cc=${cid}'),
- (5, 60300, 'SEPARATOR', NULL, NULL, NULL ),
- (5, 60400, 'TEXT', 'Unjoin', 'SERVLET', 'TODO' );
-UPDATE menuitems SET perm_nsid = 16, perm_name = 'administration' WHERE menuid = 5 AND sequence = 60200;
-UPDATE menuitems SET perm_nsid = 14, perm_name = 'unjoin' WHERE menuid = 5 AND sequence = 60300;
+ (5, 100, 'MARKER', 'begin-services', NULL, NULL ),
+ (5, 60000, 'MARKER', 'end-services', NULL, NULL ),
+ (5, 60100, 'TEXT', 'Members', 'SERVLET', 'comm/members.js.vs?cc=${cid}' ),
+ (5, 60200, 'TEXT', 'Profile', 'SERVLET', 'comm/profile.js.vs?cc=${cid}' ),
+ (5, 60300, 'TEXT', 'Administration', 'SERVLET', 'comm/admin/main.js.vs?cc=${cid}'),
+ (5, 60400, 'SEPARATOR', NULL, NULL, NULL ),
+ (5, 60500, 'TEXT', 'Unjoin', 'SERVLET', 'comm/unjoin.js.vs?cc=${cid}' );
+UPDATE menuitems SET perm_nsid = 16, perm_name = 'administration' WHERE menuid = 5 AND sequence = 60300;
UPDATE menuitems SET perm_nsid = 14, perm_name = 'unjoin' WHERE menuid = 5 AND sequence = 60400;
+UPDATE menuitems SET perm_nsid = 14, perm_name = 'unjoin' WHERE menuid = 5 AND sequence = 60500;
# Create the "top" menu (non-community). (ID #6)
INSERT INTO menus (menuid, menu_nsid, menu_name, title, subtitle)
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/GroupObject.java b/src/dynamo-framework/com/silverwrist/dynamo/db/GroupObject.java
index e93b71e..b5d8ad1 100644
--- a/src/dynamo-framework/com/silverwrist/dynamo/db/GroupObject.java
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/GroupObject.java
@@ -614,4 +614,14 @@ class GroupObject implements DynamoGroup
} // end getMemberCount
+ public List getMembers(int offset, int count) throws DatabaseException
+ {
+ int[] ids = m_ops.getMembers(m_gid,offset,count);
+ ArrayList rc = new ArrayList(ids.length);
+ for (int i=0; i,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
- * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
@@ -20,6 +20,7 @@ package com.silverwrist.dynamo.iface;
import java.security.Principal;
import java.security.acl.AclNotFoundException;
import java.security.acl.Group;
+import java.util.List;
import com.silverwrist.dynamo.except.DatabaseException;
import com.silverwrist.dynamo.except.DynamoSecurityException;
@@ -47,4 +48,6 @@ public interface DynamoGroup extends Group, NamedObject, SecureObjectStore
public int getMemberCount() throws DatabaseException;
+ public List getMembers(int offset, int count) throws DatabaseException;
+
} // end interface DynamoGroup
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/script/LibraryCast.java b/src/dynamo-framework/com/silverwrist/dynamo/script/LibraryCast.java
index e4ca407..6abac9e 100644
--- a/src/dynamo-framework/com/silverwrist/dynamo/script/LibraryCast.java
+++ b/src/dynamo-framework/com/silverwrist/dynamo/script/LibraryCast.java
@@ -95,6 +95,12 @@ public class LibraryCast
} // end newIntArray
+ public final AuthenticatorLookup queryAuthenticatorLookup(Object obj)
+ {
+ return (AuthenticatorLookup)query(obj,AuthenticatorLookup.class);
+
+ } // end queryAuthenticatorLookup
+
public final ChainParameterInput queryChainParameterInput(Object obj)
{
return (ChainParameterInput)query(obj,ChainParameterInput.class);
diff --git a/src/venice-base/com/silverwrist/venice/VeniceNamespaces.java b/src/venice-base/com/silverwrist/venice/VeniceNamespaces.java
index dd82ee7..9856040 100644
--- a/src/venice-base/com/silverwrist/venice/VeniceNamespaces.java
+++ b/src/venice-base/com/silverwrist/venice/VeniceNamespaces.java
@@ -73,4 +73,7 @@ public interface VeniceNamespaces
public static final String COMMUNITY_NAMESPACE =
"http://www.silverwrist.com/NS/venice/2003/06/15/community";
+ public static final String COMMUNITY_SECURITY_NAMESPACE =
+ "http://www.silverwrist.com/NS/venice/2003/06/18/community.security";
+
} // end interface VeniceNamespaces
diff --git a/src/venice-base/com/silverwrist/venice/app/AdvancedUserManager.java b/src/venice-base/com/silverwrist/venice/app/AdvancedUserManager.java
index 62cf625..bc6c5c2 100644
--- a/src/venice-base/com/silverwrist/venice/app/AdvancedUserManager.java
+++ b/src/venice-base/com/silverwrist/venice/app/AdvancedUserManager.java
@@ -275,4 +275,46 @@ public class AdvancedUserManager implements NamedObject, ComponentInitialize, Co
} // end getSearchUserCount
+ public List searchForMembers(DynamoUser caller, DynamoGroup group, UserSearchField field, SearchMode mode,
+ String term, int offset, int count) throws DatabaseException
+ {
+ int[] rc = null;
+ String prop = null;
+ if (UserSearchField.USERNAME.equals(field))
+ rc = m_ops.searchName(group.getGID(),mode,term,offset,count);
+ else if (UserSearchField.DESCRIPTION.equals(field))
+ prop = "description";
+ else if (UserSearchField.FIRSTNAME.equals(field))
+ prop = "name.given";
+ else if (UserSearchField.LASTNAME.equals(field))
+ prop = "name.family";
+ else
+ throw new IllegalArgumentException("invalid search field (shouldn't happen)");
+ if ((rc==null) && (prop!=null))
+ rc = m_ops.searchProperty(group.getGID(),m_ns_cache.namespaceNameToId(VeniceNamespaces.USER_PROFILE_NAMESPACE),
+ prop,mode,term,offset,count);
+ return translateUIDArray(rc);
+
+ } // end searchForMembers
+
+ public int getSearchMemberCount(DynamoUser caller, DynamoGroup group, UserSearchField field, SearchMode mode,
+ String term) throws DatabaseException
+ {
+ String prop = null;
+ if (UserSearchField.USERNAME.equals(field))
+ return m_ops.searchNameCount(group.getGID(),mode,term);
+ else if (UserSearchField.DESCRIPTION.equals(field))
+ prop = "description";
+ else if (UserSearchField.FIRSTNAME.equals(field))
+ prop = "name.given";
+ else if (UserSearchField.LASTNAME.equals(field))
+ prop = "name.family";
+ else
+ throw new IllegalArgumentException("invalid search field (shouldn't happen)");
+ return m_ops.searchPropertyCount(group.getGID(),
+ m_ns_cache.namespaceNameToId(VeniceNamespaces.USER_PROFILE_NAMESPACE),
+ prop,mode,term);
+
+ } // end getSearchMemberCount
+
} // end class AdvancedUserManager
diff --git a/src/venice-base/com/silverwrist/venice/app/AdvancedUserOps.java b/src/venice-base/com/silverwrist/venice/app/AdvancedUserOps.java
index 6d24e09..33d1e68 100644
--- a/src/venice-base/com/silverwrist/venice/app/AdvancedUserOps.java
+++ b/src/venice-base/com/silverwrist/venice/app/AdvancedUserOps.java
@@ -43,12 +43,23 @@ abstract class AdvancedUserOps extends OpsBase
abstract int[] searchProperty(int nsid, String name, SearchMode mode, String term, int offset, int count)
throws DatabaseException;
+ abstract int[] searchProperty(int member_gid, int nsid, String name, SearchMode mode, String term, int offset,
+ int count) throws DatabaseException;
+
abstract int searchPropertyCount(int nsid, String name, SearchMode mode, String term) throws DatabaseException;
+ abstract int searchPropertyCount(int member_gid, int nsid, String name, SearchMode mode, String term)
+ throws DatabaseException;
+
abstract int[] searchName(SearchMode mode, String term, int offset, int count) throws DatabaseException;
+ abstract int[] searchName(int member_gid, SearchMode mode, String term, int offset, int count)
+ throws DatabaseException;
+
abstract int searchNameCount(SearchMode mode, String term) throws DatabaseException;
+ abstract int searchNameCount(int member_gid, SearchMode mode, String term) throws DatabaseException;
+
/*--------------------------------------------------------------------------------
* External static operations
*--------------------------------------------------------------------------------
diff --git a/src/venice-base/com/silverwrist/venice/app/AdvancedUserOps_mysql.java b/src/venice-base/com/silverwrist/venice/app/AdvancedUserOps_mysql.java
index 1e57805..6c20104 100644
--- a/src/venice-base/com/silverwrist/venice/app/AdvancedUserOps_mysql.java
+++ b/src/venice-base/com/silverwrist/venice/app/AdvancedUserOps_mysql.java
@@ -116,6 +116,58 @@ public class AdvancedUserOps_mysql extends AdvancedUserOps
tmp[ct++] = rs.getInt(1);
// Create the actual return array and fill it.
+ if (ct==tmp.length)
+ return tmp;
+ int[] rc = new int[ct];
+ System.arraycopy(tmp,0,rc,0,ct);
+ return rc;
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end searchProperty
+
+ int[] searchProperty(int member_gid, int nsid, String name, SearchMode mode, String term, int offset,
+ int count) throws DatabaseException
+ {
+ Connection conn = null;
+ Statement stmt = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // prepare and execute a query (note that we assemble it in SQL form)
+ StringBuffer sql = new StringBuffer("SELECT u.uid FROM users u, userprop p, groupmembers g WHERE u.uid = p.uid "
+ + "AND u.is_anon = 0 AND u.uid = g.uid AND g.gid = ");
+ sql.append(member_gid).append(" AND p.nsid = ").append(nsid).append(" AND p.prop_name = '");
+ sql.append(m_utils.encodeString(name)).append("' AND p.prop_value ");
+ sql.append(preparePropertySearchTerm(mode,term));
+ sql.append(" ORDER BY u.name LIMIT ").append(offset).append(", ").append(count+1).append(';');
+ stmt = conn.createStatement();
+ rs = stmt.executeQuery(sql.toString());
+
+ // We *know* the maximum number of indexes that can be returned, so allocate a temporary array big
+ // enough to hold them all.
+ int[] tmp = new int[count+1];
+ int ct = 0;
+ while (rs.next())
+ tmp[ct++] = rs.getInt(1);
+
+ // Create the actual return array and fill it.
+ if (ct==tmp.length)
+ return tmp;
int[] rc = new int[ct];
System.arraycopy(tmp,0,rc,0,ct);
return rc;
@@ -171,6 +223,41 @@ public class AdvancedUserOps_mysql extends AdvancedUserOps
} // end searchPropertyCount
+ int searchPropertyCount(int member_gid, int nsid, String name, SearchMode mode, String term) throws DatabaseException
+ {
+ Connection conn = null;
+ Statement stmt = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // prepare and execute a query (note that we assemble it in SQL form)
+ StringBuffer sql = new StringBuffer("SELECT COUNT(*) FROM users u, userprop p, groupmembers g "
+ + "WHERE u.uid = p.uid AND u.is_anon = 0 AND u.uid = g.uid AND g.gid = ");
+ sql.append(member_gid).append(" AND p.nsid = ").append(nsid).append(" AND p.prop_name = '");
+ sql.append(m_utils.encodeString(name)).append("' AND p.prop_value ");
+ sql.append(preparePropertySearchTerm(mode,term)).append(';');
+ stmt = conn.createStatement();
+ rs = stmt.executeQuery(sql.toString());
+ return SQLUtils.getReturnCountInt(rs,1);
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end searchPropertyCount
+
int[] searchName(SearchMode mode, String term, int offset, int count) throws DatabaseException
{
Connection conn = null;
@@ -200,6 +287,61 @@ public class AdvancedUserOps_mysql extends AdvancedUserOps
tmp[ct++] = rs.getInt(1);
// Create the actual return array and fill it.
+ if (ct==tmp.length)
+ return tmp;
+ int[] rc = new int[ct];
+ System.arraycopy(tmp,0,rc,0,ct);
+ return rc;
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end searchName
+
+ int[] searchName(int member_gid, SearchMode mode, String term, int offset, int count) throws DatabaseException
+ {
+ Connection conn = null;
+ Statement stmt = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // prepare and execute a query (note that we assemble it in SQL form)
+ StringBuffer sql = new StringBuffer("SELECT u.uid FROM users u, groupmembers g WHERE u.is_anon = 0 "
+ + "AND u.uid = g.uid AND g.gid = ");
+ sql.append(member_gid).append(" AND u.username ");
+ if (SearchMode.PREFIX.equals(mode))
+ sql.append("LIKE '").append(m_utils.encodeStringWildcards(term)).append("%'");
+ else if (SearchMode.SUBSTRING.equals(mode))
+ sql.append("LIKE '%").append(m_utils.encodeStringWildcards(term)).append("%'");
+ else if (SearchMode.REGEXP.equals(mode))
+ sql.append("REGEXP '").append(m_utils.encodeString(term)).append('\'');
+ sql.append(" ORDER BY u.username LIMIT ").append(offset).append(", ").append(count+1).append(';');
+ stmt = conn.createStatement();
+ rs = stmt.executeQuery(sql.toString());
+
+ // We *know* the maximum number of indexes that can be returned, so allocate a temporary array big
+ // enough to hold them all.
+ int[] tmp = new int[count+1];
+ int ct = 0;
+ while (rs.next())
+ tmp[ct++] = rs.getInt(1);
+
+ // Create the actual return array and fill it.
+ if (ct==tmp.length)
+ return tmp;
int[] rc = new int[ct];
System.arraycopy(tmp,0,rc,0,ct);
return rc;
@@ -258,4 +400,44 @@ public class AdvancedUserOps_mysql extends AdvancedUserOps
} // end searchNameCount
+ int searchNameCount(int member_gid, SearchMode mode, String term) throws DatabaseException
+ {
+ Connection conn = null;
+ Statement stmt = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // prepare and execute a query (note that we assemble it in SQL form)
+ StringBuffer sql = new StringBuffer("SELECT COUNT(*) FROM users u, groupmembers g WHERE u.is_anon = 0 "
+ + "AND u.uid = g.uid AND g.gid = ");
+ sql.append(member_gid).append(" AND u.username ");
+ if (SearchMode.PREFIX.equals(mode))
+ sql.append("LIKE '").append(m_utils.encodeStringWildcards(term)).append("%'");
+ else if (SearchMode.SUBSTRING.equals(mode))
+ sql.append("LIKE '%").append(m_utils.encodeStringWildcards(term)).append("%'");
+ else if (SearchMode.REGEXP.equals(mode))
+ sql.append("REGEXP '").append(m_utils.encodeString(term)).append('\'');
+ sql.append(';');
+ stmt = conn.createStatement();
+ rs = stmt.executeQuery(sql.toString());
+ return SQLUtils.getReturnCountInt(rs,1);
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end searchNameCount
+
} // end class AdvancedUserOps_mysql
diff --git a/src/venice-base/com/silverwrist/venice/app/AdvancedUserService.java b/src/venice-base/com/silverwrist/venice/app/AdvancedUserService.java
index e8772f9..a48387a 100644
--- a/src/venice-base/com/silverwrist/venice/app/AdvancedUserService.java
+++ b/src/venice-base/com/silverwrist/venice/app/AdvancedUserService.java
@@ -20,6 +20,7 @@ package com.silverwrist.venice.app;
import java.util.List;
import com.silverwrist.dynamo.db.UserManagement;
import com.silverwrist.dynamo.except.DatabaseException;
+import com.silverwrist.dynamo.iface.DynamoGroup;
import com.silverwrist.dynamo.iface.DynamoUser;
import com.silverwrist.venice.SearchMode;
import com.silverwrist.venice.UserSearchField;
@@ -32,4 +33,10 @@ public interface AdvancedUserService extends UserManagement
public int getSearchUserCount(DynamoUser caller, UserSearchField field, SearchMode mode, String term)
throws DatabaseException;
+ public List searchForMembers(DynamoUser caller, DynamoGroup group, UserSearchField field, SearchMode mode,
+ String term, int offset, int count) throws DatabaseException;
+
+ public int getSearchMemberCount(DynamoUser caller, DynamoGroup group, UserSearchField field, SearchMode mode,
+ String term) throws DatabaseException;
+
} // end interface AdvancedUserService
diff --git a/src/venice-base/com/silverwrist/venice/community/CommunityImpl.java b/src/venice-base/com/silverwrist/venice/community/CommunityImpl.java
index 0df4412..a960c18 100644
--- a/src/venice-base/com/silverwrist/venice/community/CommunityImpl.java
+++ b/src/venice-base/com/silverwrist/venice/community/CommunityImpl.java
@@ -880,7 +880,8 @@ class CommunityImpl implements VeniceCommunity
synchronized (this)
{ // update the access table and touch the community
java.util.Date update = m_ops.revokeAccess(m_id,ugid,is_group);
- m_lastaccessed = m_lastupdate = update;
+ if (update!=null)
+ m_lastaccessed = m_lastupdate = update;
} // end synchronized block
@@ -953,7 +954,8 @@ class CommunityImpl implements VeniceCommunity
logger.debug("CommunityImpl.join: " + joiner.getName() + " joining " + m_name);
// If the user is already a member, return the value that dictates that we are already a member.
- if (m_users.getGroup(m_member_gid).isMember(joiner))
+ DynamoGroup mbr_group = m_users.getGroup(m_member_gid);
+ if (mbr_group.isMember(joiner))
return false;
boolean ok_to_join = false;
@@ -1030,7 +1032,7 @@ class CommunityImpl implements VeniceCommunity
if (ok_to_join)
{ // we're OK to join this group!
- m_users.getGroup(m_member_gid).addMember(m_users.getUser(m_host_uid),joiner);
+ mbr_group.addMember(m_users.getUser(m_host_uid),joiner);
if (task!=null)
task.run();
return true;
@@ -1051,6 +1053,16 @@ class CommunityImpl implements VeniceCommunity
} // end join
+ public void unjoin(DynamoUser unjoiner) throws DatabaseException, DynamoSecurityException
+ {
+ DynamoGroup mbr_group = m_users.getGroup(m_member_gid);
+ if (!(mbr_group.isMember(unjoiner)))
+ return; // if you're not a member, unjoining is a no-op
+ testPermission(unjoiner,VeniceNamespaces.COMMUNITY_PERMS_NAMESPACE,"unjoin","auth.unjoin");
+ mbr_group.removeMember(m_users.getUser(m_host_uid),unjoiner);
+
+ } // end unjoin
+
public boolean isAdministrator(DynamoUser user)
{
try
diff --git a/src/venice-base/com/silverwrist/venice/community/CommunityMessages.properties b/src/venice-base/com/silverwrist/venice/community/CommunityMessages.properties
index 36f66bc..bd08a0b 100644
--- a/src/venice-base/com/silverwrist/venice/community/CommunityMessages.properties
+++ b/src/venice-base/com/silverwrist/venice/community/CommunityMessages.properties
@@ -33,3 +33,4 @@ join.disallowed=You are not permitted to join community "{0}."
join.authFail=Unable to authenticate to community "{0}"; cannot join.
svc.modname.mismatch=The name of the service module "{0}" did not match the name stored in the database.
svc.object.badType=The service controller object {0}::{1} was of the wrong type.
+auth.unjoin=You are not permitted to unjoin community "{0}."
diff --git a/src/venice-base/com/silverwrist/venice/community/CommunityOps_mysql.java b/src/venice-base/com/silverwrist/venice/community/CommunityOps_mysql.java
index 30758da..b27992c 100644
--- a/src/venice-base/com/silverwrist/venice/community/CommunityOps_mysql.java
+++ b/src/venice-base/com/silverwrist/venice/community/CommunityOps_mysql.java
@@ -650,20 +650,52 @@ class CommunityOps_mysql extends CommunityOps
stmt2 = conn.createStatement();
stmt2.executeUpdate("LOCK TABLES commaccess WRITE, communities WRITE;");
- // create the insert statement and execute it
- stmt = conn.prepareStatement("INSERT INTO commaccess (cid, ugid, is_group, single_use, auth_nsid, auth_name, "
- + "source_data, auth_data) VALUES (?, ?, ?, ?, ?, ?, ?, ?);");
+ // see if the key is already there
+ stmt = conn.prepareStatement("SELECT single_use FROM commaccess WHERE cid = ? AND ugid = ? AND is_group = ?;");
stmt.setInt(1,cid);
stmt.setInt(2,ugid);
stmt.setInt(3,(is_group ? 1 : 0));
- stmt.setInt(4,(single_use ? 1 : 0));
- if (auth_nsid==0)
- stmt.setNull(5,Types.INTEGER);
+ rs = stmt.executeQuery();
+ boolean newbie = !(rs.next());
+ rs.close();
+ rs = null;
+ stmt.close();
+
+ if (newbie)
+ { // create the insert statement and execute it
+ stmt = conn.prepareStatement("INSERT INTO commaccess (cid, ugid, is_group, single_use, auth_nsid, auth_name, "
+ + "source_data, auth_data) VALUES (?, ?, ?, ?, ?, ?, ?, ?);");
+ stmt.setInt(1,cid);
+ stmt.setInt(2,ugid);
+ stmt.setInt(3,(is_group ? 1 : 0));
+ stmt.setInt(4,(single_use ? 1 : 0));
+ if (auth_nsid==0)
+ stmt.setNull(5,Types.INTEGER);
+ else
+ stmt.setInt(5,auth_nsid);
+ stmt.setString(6,auth_name);
+ stmt.setString(7,source_data);
+ stmt.setString(8,auth_data);
+
+ } // end if
else
- stmt.setInt(5,auth_nsid);
- stmt.setString(6,auth_name);
- stmt.setString(7,source_data);
- stmt.setString(8,auth_data);
+ { // update the existing access information
+ stmt = conn.prepareStatement("UPDATE commaccess SET single_use = ?, auth_nsid = ?, auth_name = ?, "
+ + "source_data = ?, auth_data = ? WHERE cid = ? AND ugid = ? AND is_group = ?;");
+ stmt.setInt(1,(single_use ? 1 : 0));
+ if (auth_nsid==0)
+ stmt.setNull(2,Types.INTEGER);
+ else
+ stmt.setInt(2,auth_nsid);
+ stmt.setString(3,auth_name);
+ stmt.setString(4,source_data);
+ stmt.setString(5,auth_data);
+ stmt.setInt(6,cid);
+ stmt.setInt(7,ugid);
+ stmt.setInt(8,(is_group ? 1 : 0));
+
+ } // end else
+
stmt.executeUpdate();
// Touch the community entry.
@@ -707,7 +739,8 @@ class CommunityOps_mysql extends CommunityOps
stmt.setInt(1,cid);
stmt.setInt(2,ugid);
stmt.setInt(3,(is_group ? 1 : 0));
- stmt.executeUpdate();
+ if (stmt.executeUpdate()<=0)
+ return null;
// Touch the community entry.
return touchCommunity(conn,cid);
diff --git a/src/venice-base/com/silverwrist/venice/community/CommunityProxy.java b/src/venice-base/com/silverwrist/venice/community/CommunityProxy.java
index ccd3612..0e573c5 100644
--- a/src/venice-base/com/silverwrist/venice/community/CommunityProxy.java
+++ b/src/venice-base/com/silverwrist/venice/community/CommunityProxy.java
@@ -603,6 +603,12 @@ abstract class CommunityProxy implements VeniceCommunity, DynamicWrapper
} // end join
+ public void unjoin(DynamoUser unjoiner) throws DatabaseException, DynamoSecurityException
+ {
+ getRealCommunity().unjoin(unjoiner);
+
+ } // end unjoin
+
public boolean isAdministrator(DynamoUser user)
{
return getRealCommunity().isAdministrator(user);
diff --git a/src/venice-base/com/silverwrist/venice/content/ConfirmBox.java b/src/venice-base/com/silverwrist/venice/content/ConfirmBox.java
new file mode 100644
index 0000000..220ef2e
--- /dev/null
+++ b/src/venice-base/com/silverwrist/venice/content/ConfirmBox.java
@@ -0,0 +1,237 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.venice.content;
+
+import java.util.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+import com.silverwrist.venice.frame.FramedContent;
+
+public class ConfirmBox implements FramedContent
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final long TIMEOUT = 60000; // 1 minute
+
+ private static Random s_rng;
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String m_title; // confirm box title
+ private String m_message; // confirm box message
+ private int m_confirmation_number; // confirmation number
+ private String m_yes_type; // "yes" link type
+ private String m_yes_url; // "yes" link URL
+ private String m_no_type; // "no" link type
+ private String m_no_url; // "no" link URL
+ private java.util.Date m_created; // this box was created when?
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public ConfirmBox(Request r, String attr_namespace, String attr_name, String param_name, String title,
+ String message, String yes_url_type, String yes_url, String no_url_type, String no_url)
+ {
+ // Fill in all the parameters except m_created.
+ m_title = title;
+ m_message = message;
+ m_confirmation_number = s_rng.nextInt(0x1000000);
+ m_yes_type = yes_url_type;
+ m_yes_url = yes_url;
+ if (m_yes_url.indexOf('?')>=0)
+ m_yes_url += ("&" + param_name + "=" + m_confirmation_number);
+ else
+ m_yes_url += ("?" + param_name + "=" + m_confirmation_number);
+ m_no_type = no_url_type;
+ m_no_url = no_url;
+
+ // Save this object in a session attribute.
+ SessionInfoProvider prov = (SessionInfoProvider)(r.queryService(SessionInfoProvider.class));
+ prov.getSessionInfo().setObject(attr_namespace,attr_name,this);
+
+ // Now start the timer ticking...
+ m_created = new java.util.Date();
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ protected boolean doConfirm(int num)
+ {
+ java.util.Date now = new java.util.Date();
+ if ((now.getTime() - m_created.getTime())>TIMEOUT)
+ return false; // confirmation has timed out
+ return (num==m_confirmation_number);
+
+ } // end doConfirm
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface FramedContent
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Returns the desired menu selector for this page. The menu selector is a string that specifies
+ * which menu is to be displayed on the left menu bar, in addition to the "global menu." This value may
+ * be null
, in which case the current menu selector is not changed.
+ *
+ * @return The desired menu selector.
+ */
+ public String getMenuSelector()
+ {
+ return null;
+
+ } // end getMenuSelector
+
+ /**
+ * Returns the desired title for the page. This title is concatenated with the site title (set in
+ * global properties) to form the actual page title that gets sent to the browser.
+ *
+ * @return The desired page title.
+ */
+ public String getPageTitle()
+ {
+ return m_title;
+
+ } // end getPageTitle
+
+ /**
+ * Returns the desired quick ID for the page. The page quick ID is a small text string which can be used
+ * to "tag" the page with a unique identifier, for use with external tools such as offsite hit counters.
+ * If this value is null
, the quick ID is not used for this page.
+ *
+ * @return The desired page quick ID.
+ */
+ public String getPageQID()
+ {
+ return null;
+
+ } // end getPageQID
+
+ /*--------------------------------------------------------------------------------
+ * External static operations
+ *--------------------------------------------------------------------------------
+ */
+
+ public static boolean isConfirmed(Request r, String attr_namespace, String attr_name, String param_name)
+ {
+ // First, retrieve the confirm box out of the session data.
+ ConfirmBox cb = null;
+ RequestHelper rhelp = new RequestHelper(r);
+ try
+ { // look up the session data and retrieve the confirmation box
+ SessionInfo session = rhelp.getSession();
+ cb = (ConfirmBox)(session.getObject(attr_namespace,attr_name));
+ session.removeObject(attr_namespace,attr_name);
+
+ } // end try
+ catch (NoSuchObjectException e)
+ { // there's no confirm box there
+ return false;
+
+ } // end catch
+ catch (ClassCastException cce)
+ { // there's something there but it's not a confirm box
+ return false;
+
+ } // end catch
+
+ // Now get the confirmation number out of the parameters.
+ int num = rhelp.getParameterInt(param_name,-1);
+ if (num<0)
+ return false; // there's no hope this will match
+
+ return cb.doConfirm(num);
+
+ } // end isConfirmed
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Returns the title of the confirmation message box.
+ *
+ * @return The title of the confirmation message box.
+ */
+ public String getTitle()
+ {
+ return m_title;
+
+ } // end getTitle
+
+ /**
+ * Returns the confirmation message text.
+ *
+ * @return The confirmation message text.
+ */
+ public String getMessage()
+ {
+ return m_message;
+
+ } // end getMessage
+
+ public String getYesLinkType()
+ {
+ return m_yes_type;
+
+ } // end getYesLinkType
+
+ public String getYesLink()
+ {
+ return m_yes_url;
+
+ } // end getYesLink
+
+ public String getNoLinkType()
+ {
+ return m_no_type;
+
+ } // end getNoLinkType
+
+ public String getNoLink()
+ {
+ return m_no_url;
+
+ } // end getNoLink
+
+ /*--------------------------------------------------------------------------------
+ * Static initializer
+ *--------------------------------------------------------------------------------
+ */
+
+ static
+ { // initialize the random number generator
+ s_rng = new Random(System.currentTimeMillis());
+
+ } // end static initializer
+
+} // end class ConfirmBox
diff --git a/src/venice-base/com/silverwrist/venice/content/ContentMessages.properties b/src/venice-base/com/silverwrist/venice/content/ContentMessages.properties
index 066ce28..d1c4d8a 100644
--- a/src/venice-base/com/silverwrist/venice/content/ContentMessages.properties
+++ b/src/venice-base/com/silverwrist/venice/content/ContentMessages.properties
@@ -27,3 +27,4 @@ activity.never=Never
activity.today=Today, {0}
activity.yesterday=Yesterday, {0}
activity.daysago={0} days ago
+render.confirmBox=Unable to render a confirmation box: {0}\nBox title was: {1}\nBox message was: {2}
diff --git a/src/venice-base/com/silverwrist/venice/content/StandardContentSupplier.java b/src/venice-base/com/silverwrist/venice/content/StandardContentSupplier.java
index 70cde8b..5e20fd9 100644
--- a/src/venice-base/com/silverwrist/venice/content/StandardContentSupplier.java
+++ b/src/venice-base/com/silverwrist/venice/content/StandardContentSupplier.java
@@ -94,6 +94,7 @@ public class StandardContentSupplier
private String m_name = null; // name of the object
private ObjectProvider m_blocks; // global blocks provider
private ComponentShutdown m_shut_1; // shut down renderer
+ private ComponentShutdown m_shut_1a; // shut down renderer
private ComponentShutdown m_shut_2; // shut down Velocity object
/*--------------------------------------------------------------------------------
@@ -177,6 +178,7 @@ public class StandardContentSupplier
// Register this object as a renderer for some objects.
RendererRegistration rr = (RendererRegistration)(services.queryService(RendererRegistration.class));
m_shut_1 = rr.registerRenderer(ErrorBox.class,this);
+ m_shut_1a = rr.registerRenderer(ConfirmBox.class,this);
// Add an object to the standard objects available to Velocity.
VelocityRendererConfig vrcon =
@@ -194,6 +196,8 @@ public class StandardContentSupplier
{
m_shut_2.shutdown();
m_shut_2 = null;
+ m_shut_1a.shutdown();
+ m_shut_1a = null;
m_shut_1.shutdown();
m_shut_1 = null;
m_blocks = null;
@@ -307,6 +311,33 @@ public class StandardContentSupplier
} // end catch
} // end if
+ else if (obj instanceof ConfirmBox)
+ { // render a confirmation box
+ ConfirmBox cbox = (ConfirmBox)obj;
+ try
+ { // get the confirm box template out of the database
+ ContentBlock blk = this.getContentBlock("confirm.box");
+ blk.setContentParameter("title",cbox.getTitle());
+ blk.setContentParameter("message",cbox.getMessage());
+ blk.setContentParameter("yes_type",cbox.getYesLinkType());
+ blk.setContentParameter("yes_url",cbox.getYesLink());
+ blk.setContentParameter("no_type",cbox.getNoLinkType());
+ blk.setContentParameter("no_url",cbox.getNoLink());
+ control.renderSubObject(blk); // render the block
+
+ } // end try
+ catch (DatabaseException e)
+ { // translate this into a rendering exception
+ RenderingException re = new RenderingException(StandardContentSupplier.class,"ContentMessages",
+ "render.confirmBox",e);
+ re.setParameter(0,e.getMessage());
+ re.setParameter(1,cbox.getTitle());
+ re.setParameter(2,cbox.getMessage());
+ throw re;
+
+ } // end catch
+
+ } // end else if
} // end render
diff --git a/src/venice-base/com/silverwrist/venice/iface/VeniceCommunity.java b/src/venice-base/com/silverwrist/venice/iface/VeniceCommunity.java
index fd89f12..6e63935 100644
--- a/src/venice-base/com/silverwrist/venice/iface/VeniceCommunity.java
+++ b/src/venice-base/com/silverwrist/venice/iface/VeniceCommunity.java
@@ -312,6 +312,8 @@ public interface VeniceCommunity extends NamedObject, SecureObjectStore
public boolean join(DynamoUser joiner) throws DatabaseException, DynamoSecurityException;
+ public void unjoin(DynamoUser unjoiner) throws DatabaseException, DynamoSecurityException;
+
public boolean isAdministrator(DynamoUser user);
public List getServices() throws DatabaseException;
diff --git a/src/venice-base/com/silverwrist/venice/menu/InlineMenuRendering.java b/src/venice-base/com/silverwrist/venice/menu/InlineMenuRendering.java
index a812d2f..edc14df 100644
--- a/src/venice-base/com/silverwrist/venice/menu/InlineMenuRendering.java
+++ b/src/venice-base/com/silverwrist/venice/menu/InlineMenuRendering.java
@@ -273,6 +273,8 @@ class InlineMenuRendering implements MenuRenderObject, SelfRenderable
if (m_showitem[i] && item.itemDefined(m_local_vars))
{ // render this item
String s = item.getItemType();
+ if (s.equalsIgnoreCase("MARKER"))
+ continue; // ignore markers
if (s.equalsIgnoreCase("TEXT"))
renderTextItem(tctrl,item,(i==m_selected_index));
else if (s.equalsIgnoreCase("HEADER"))
diff --git a/src/venice-base/com/silverwrist/venice/menu/LeftMenuRendering.java b/src/venice-base/com/silverwrist/venice/menu/LeftMenuRendering.java
index 0179f21..441eb23 100644
--- a/src/venice-base/com/silverwrist/venice/menu/LeftMenuRendering.java
+++ b/src/venice-base/com/silverwrist/venice/menu/LeftMenuRendering.java
@@ -266,6 +266,8 @@ class LeftMenuRendering implements MenuRenderObject, SelfRenderable
if (m_showitem[i] && item.itemDefined(m_local_vars))
{ // render this item
String s = item.getItemType();
+ if (s.equalsIgnoreCase("MARKER"))
+ continue; // ignore markers
if (s.equalsIgnoreCase("TEXT"))
renderTextItem(tctrl,item,(m_selected_index==i));
else if (s.equalsIgnoreCase("HEADER"))
diff --git a/src/venice-base/com/silverwrist/venice/menu/StandardMenuRendering.java b/src/venice-base/com/silverwrist/venice/menu/StandardMenuRendering.java
index 8c6a250..7452869 100644
--- a/src/venice-base/com/silverwrist/venice/menu/StandardMenuRendering.java
+++ b/src/venice-base/com/silverwrist/venice/menu/StandardMenuRendering.java
@@ -278,6 +278,8 @@ class StandardMenuRendering implements MenuRenderObject, SelfRenderable, FramedC
if (m_showitem[i] && item.itemDefined(m_local_vars))
{ // render this item
s = item.getItemType();
+ if (s.equalsIgnoreCase("MARKER"))
+ continue; // ignore markers
if (s.equalsIgnoreCase("TEXT"))
renderTextItem(tctl,item,(m_selected_index==i));
else if (s.equalsIgnoreCase("HEADER"))
diff --git a/src/venice-base/com/silverwrist/venice/script/LibraryVenice.java b/src/venice-base/com/silverwrist/venice/script/LibraryVenice.java
index ab6c1ad..4055eb0 100644
--- a/src/venice-base/com/silverwrist/venice/script/LibraryVenice.java
+++ b/src/venice-base/com/silverwrist/venice/script/LibraryVenice.java
@@ -123,6 +123,12 @@ public class LibraryVenice
*--------------------------------------------------------------------------------
*/
+ public boolean confirmed(Request r, String attr_namespace, String attr_name, String param_name)
+ {
+ return ConfirmBox.isConfirmed(r,attr_namespace,attr_name,param_name);
+
+ } // end confirmed
+
public String dialogFrameTitle(Dialog dlg)
{
String s = dlg.getSubtitle();
diff --git a/venice-data/scripts/comm/admin/profile.js b/venice-data/scripts/comm/admin/profile.js
index 85c36ae..294cfeb 100644
--- a/venice-data/scripts/comm/admin/profile.js
+++ b/venice-data/scripts/comm/admin/profile.js
@@ -16,8 +16,10 @@
importPackage(java.lang);
importClass(Packages.com.silverwrist.dynamo.Namespaces);
+importClass(Packages.com.silverwrist.dynamo.UserInfoNamespace);
importPackage(Packages.com.silverwrist.dynamo.except);
importPackage(Packages.com.silverwrist.dynamo.iface);
+importPackage(Packages.com.silverwrist.dynamo.security);
importPackage(Packages.com.silverwrist.dynamo.util);
importClass(Packages.com.silverwrist.venice.CommunityVisibility);
importClass(Packages.com.silverwrist.venice.VeniceNamespaces);
@@ -39,6 +41,8 @@ if (!( acl.testPermission(user,VeniceNamespaces.COMMUNITY_PROFILE_NAMESPACE,"s
dynamo.scriptReturn(vlib.stdErrorBox(req,"Security Error",
"You are not permitted to modify this community's profile."));
+variable_type = acl.testPermission(user,VeniceNamespaces.COMMUNITY_SECURITY_NAMESPACE,"set.property")
+
// Create the dialog.
loader = cast.queryDialogLoader(req);
dlg = loader.loadDialogResource("comm/community_profile.dlg.xml");
@@ -77,8 +81,9 @@ if (req_help.isVerb("GET"))
dlg.setValue("pcode",comm.getObject(VeniceNamespaces.COMMUNITY_PROFILE_NAMESPACE,"postal.code"));
dlg.setValue("country",comm.getObject(VeniceNamespaces.COMMUNITY_PROFILE_NAMESPACE,"country"));
- dlg.setValue("comtype","0"); // TODO: replace with something real
- dlg.setValue("joinkey",""); // TODO: replace with something real
+ dlg.setValue("comtype",comm.getObject(VeniceNamespaces.COMMUNITY_SECURITY_NAMESPACE,"type.hint"));
+ dlg.setValue("joinkey",PropertyUtils.getPropertyNoErr(comm,VeniceNamespaces.COMMUNITY_SECURITY_NAMESPACE,
+ "join.key"));
dlg.setValue("visibility",comm.getVisibility().getName());
} // end if
@@ -118,7 +123,47 @@ else
comm.setObject(user,VeniceNamespaces.COMMUNITY_PROFILE_NAMESPACE,"postal.code",dlg.getValue("pcode"));
comm.setObject(user,VeniceNamespaces.COMMUNITY_PROFILE_NAMESPACE,"country",dlg.getValue("country"));
- // TODO: do something with "comtype" and "joinkey"
+ if (variable_type)
+ { // see if the community type is changing, set a join key if it is
+ old_comtype = cast.toInteger(comm.getObject(VeniceNamespaces.COMMUNITY_SECURITY_NAMESPACE,"type.hint"));
+ new_comtype = cast.toInteger(dlg.getValue("comtype"));
+ if (old_comtype!=new_comtype)
+ { // "Community type" mainly affects the authentication required for the "All Verified Users" group.
+ srm = cast.querySecurityReferenceMonitor(req_help.getRequestObject(Namespaces.DYNAMO_OBJECT_NAMESPACE,
+ "srm"));
+ the_group = srm.getVerifiedUsersGroup();
+
+ switch (new_comtype)
+ {
+ case 0: // public access
+ comm.grantAccess(user,the_group,null,null,null,null,false);
+ if (PropertyUtils.hasProperty(comm,VeniceNamespaces.COMMUNITY_SECURITY_NAMESPACE,"join.key"))
+ comm.removeObject(user,VeniceNamespaces.COMMUNITY_SECURITY_NAMESPACE,"join.key");
+ break;
+
+ case 1: // private access
+ jkey = dlg.getValue("joinkey");
+ comm.grantAccess(user,the_group,UserInfoNamespace.NAMESPACE,UserInfoNamespace.AUTH_DEFAULT,"",
+ jkey,false);
+ PropertyUtils.setOrRemove(comm,user,VeniceNamespaces.COMMUNITY_SECURITY_NAMESPACE,"join.key",jkey);
+ break;
+
+ case 2: // invitation-only access
+ comm.revokeAccess(user,the_group);
+ if (PropertyUtils.hasProperty(comm,VeniceNamespaces.COMMUNITY_SECURITY_NAMESPACE,"join.key"))
+ comm.removeObject(user,VeniceNamespaces.COMMUNITY_SECURITY_NAMESPACE,"join.key");
+ break;
+
+ } // end switch
+
+ // save off the new type
+ comm.setObject(user,VeniceNamespaces.COMMUNITY_SECURITY_NAMESPACE,"type.hint",
+ cast.toIntegerObject(new_comtype));
+
+ } // end if
+
+ } // end if
+
comm.setVisibility(user,CommunityVisibility.getEnum(dlg.getValue("visibility")));
vlib.forceReloadMenu(req); // the menu might have changed, so reload it
@@ -166,6 +211,13 @@ if (rc==null)
{ // output dialog if we don't have another value
dlg.setSubtitle(comm.getName());
dlg.setRenderParam("cid",comm.getCID() + "");
+ if (!variable_type)
+ { // disable "community type" and "join key"
+ dlg.setEnabled("comtype",false);
+ dlg.setEnabled("joinkey",false);
+
+ } // end if
+
rc = new FrameDialog(dlg);
rc.menuSelector = "community";
diff --git a/venice-data/scripts/comm/members.js b/venice-data/scripts/comm/members.js
new file mode 100644
index 0000000..2d70d29
--- /dev/null
+++ b/venice-data/scripts/comm/members.js
@@ -0,0 +1,111 @@
+// The contents of this file are subject to the Mozilla Public License Version 1.1
+// (the "License"); you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at .
+//
+// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+// WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+// language governing rights and limitations under the License.
+//
+// The Original Code is the Venice Web Communities System.
+//
+// The Initial Developer of the Original Code is Eric J. Bowersox ,
+// for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+// Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+//
+// Contributor(s):
+
+importPackage(java.lang);
+importClass(Packages.com.silverwrist.dynamo.Namespaces);
+importPackage(Packages.com.silverwrist.dynamo.iface);
+importPackage(Packages.com.silverwrist.dynamo.util);
+importClass(Packages.com.silverwrist.venice.SearchMode);
+importClass(Packages.com.silverwrist.venice.UserSearchField);
+importClass(Packages.com.silverwrist.venice.VeniceNamespaces);
+importClass(Packages.com.silverwrist.venice.app.AdvancedUserService);
+importPackage(Packages.com.silverwrist.venice.content);
+
+req = bsf.lookupBean("request"); // get request
+rhelp = bsf.lookupBean("request_help"); // get request helper
+user = vlib.getUser(req); // get user
+comm = vlib.getCommunity(req); // get community
+
+membergroup = comm.getMemberGroup();
+
+// Get the user's configured page size.
+pagesize = cast.toInteger(user.getObject(VeniceNamespaces.USER_SETTINGS_NAMESPACE,"search.result.count"));
+
+stdlist = 1;
+field = UserSearchField.USERNAME;
+mode = SearchMode.PREFIX;
+term = "";
+ofs = 0;
+fcount = -1;
+results = null;
+rc = null;
+
+if (rhelp.isVerb("POST"))
+{ // Read the form parameters
+ stdlist = rhelp.getParameterInt("sl",1);
+ field = UserSearchField.getEnum(rhelp.getParameter("field"));
+ mode = SearchMode.getEnum(rhelp.getParameter("mode"));
+ term = rhelp.getParameter("term");
+ ofs = rhelp.getParameterInt("ofs",0);
+ fcount = rhelp.getParameterInt("fcount",-1);
+
+ // Adjust offset based on the button that was clicked.
+ if (rhelp.isImageButtonClicked("search"))
+ { // beginning of a new search
+ ofs = 0;
+ fcount = -1;
+
+ } // end if
+ else if (rhelp.isImageButtonClicked("previous"))
+ ofs = Math.max(ofs - pagesize,0);
+ else if (rhelp.isImageButtonClicked("next"))
+ ofs += pagesize;
+
+} // end else
+
+try
+{ // fill in the results and find count
+ if (stdlist==1)
+ { // get the usual member list
+ if (fcount<0)
+ fcount = membergroup.getMemberCount();
+ results = membergroup.getMembers(ofs,pagesize);
+
+ } // end if
+ else
+ { // we're searching
+ usersvc = vcast.queryAdvancedUserService(rhelp.getRequestObject(Namespaces.DYNAMO_OBJECT_NAMESPACE,"adv-users"));
+ if (fcount<0)
+ fcount = usersvc.getSearchMemberCount(user,membergroup,field,mode,term);
+ results = usersvc.searchForMembers(user,membergroup,field,mode,term,ofs,pagesize);
+
+ } // end else
+
+} // end try
+catch (e)
+{ // exception thrown
+ rc = new ErrorBox("Database Error",e,"SERVLET","comm/members.js.vs");
+
+} // end catch
+
+if (rc==null)
+{ // create the VelocityView for the output
+ rc = new VelocityView(comm.name + ": Members","comm/members.vm");
+ rc.menuSelector = "community";
+ rc.setParameter("comm",comm);
+ rc.setParameter("stdlist",cast.toIntegerObject(stdlist));
+ rc.setParameter("field",field.getName());
+ rc.setParameter("mode",mode.getName());
+ rc.setParameter("term",term.toString());
+ rc.setParameter("ofs",cast.toIntegerObject(ofs));
+ rc.setParameter("fcount",cast.toIntegerObject(fcount));
+ rc.setParameter("pagesize",cast.toIntegerObject(pagesize));
+ if (results!=null)
+ rc.setParameter("results",results);
+
+} // end if
+
+dynamo.scriptOutput(rc);
diff --git a/venice-data/scripts/comm/unjoin.js b/venice-data/scripts/comm/unjoin.js
new file mode 100644
index 0000000..3cf068f
--- /dev/null
+++ b/venice-data/scripts/comm/unjoin.js
@@ -0,0 +1,41 @@
+// The contents of this file are subject to the Mozilla Public License Version 1.1
+// (the "License"); you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at .
+//
+// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+// WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+// language governing rights and limitations under the License.
+//
+// The Original Code is the Venice Web Communities System.
+//
+// The Initial Developer of the Original Code is Eric J. Bowersox ,
+// for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+// Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+//
+// Contributor(s):
+
+importPackage(java.lang);
+importPackage(java.util);
+importPackage(Packages.com.silverwrist.util);
+importClass(Packages.com.silverwrist.dynamo.Namespaces);
+importPackage(Packages.com.silverwrist.dynamo.except);
+importPackage(Packages.com.silverwrist.dynamo.iface);
+importPackage(Packages.com.silverwrist.dynamo.util);
+importPackage(Packages.com.silverwrist.venice.content);
+importPackage(Packages.com.silverwrist.venice.iface);
+
+req = bsf.lookupBean("request");
+req_help = bsf.lookupBean("request_help");
+user = vlib.getUser(req);
+comm = vlib.getCommunity(req);
+
+if (vlib.confirmed(req,"/comm/unjoin.js.vs","confirmation","confnum"))
+{ // we're confirmed - unjoin us and throw us back to the front page
+ comm.unjoin(user);
+ dynamo.scriptReturn(new Redirect("SERVLET","top.js.vs"));
+
+} // end if
+
+dynamo.scriptOutput(new ConfirmBox(req,"/comm/unjoin.js.vs","confirmation","confnum","Unjoin Confirmation",
+ "You are about to unjoin the '" + comm.name + "' community! Are you sure you want to do this?",
+ "SERVLET","comm/unjoin.js.vs?cc=" + comm.getCID(),"SERVLET","community/" + comm.alias));
diff --git a/venice-data/scripts/new_account_2.js b/venice-data/scripts/new_account_2.js
index e8456d1..28b42f9 100644
--- a/venice-data/scripts/new_account_2.js
+++ b/venice-data/scripts/new_account_2.js
@@ -156,6 +156,7 @@ if (op=="create")
logger.debug("OK to join community: " + comm.name);
if (comm.join(new_user))
{
+ // TODO: what do we do after we join the community?
}
} // end if
diff --git a/venice-data/velocity/comm/members.vm b/venice-data/velocity/comm/members.vm
new file mode 100644
index 0000000..c7baca9
--- /dev/null
+++ b/venice-data/velocity/comm/members.vm
@@ -0,0 +1,151 @@
+#*
+ The contents of this file are subject to the Mozilla Public License Version 1.1
+ (the "License"); you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at .
+
+ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ language governing rights and limitations under the License.
+
+ The Original Code is the Venice Web Communities System.
+
+ The Initial Developer of the Original Code is Eric J. Bowersox ,
+ for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+
+ Contributor(s):
+*#
+#*
+ Parameters:
+ comm = Community we're working with
+ stdlist = 0 if this is a "search" operation, 1 if this is a "member list" operation
+ field = Search field (string equivalent)
+ mode = Search mode (string equivalent)
+ term = Search term
+ ofs = Offset within the search we're at right now
+ fcount = Total number of items found in current search
+ pagesize = Number of items to display per page
+ results = Results list from find/member list, a List of DynamoUser objects (may be null)
+*#
+#header2( "Community Members:" "$comm.Name" )
+
+
+#if( $results )
+ ## Do a tricky set of computations here to figure out what we need to display in terms of the search results
+ ## and the form to the right that lets us page through results.
+ #set( $resultcount = $results.size() )
+ #set( $is_next = 0 )
+ #set( $is_prev = 0 )
+ #if( $resultcount > $pagesize )
+ #set( $resultcount = $pagesize )
+ #set( $is_next = 1 )
+ #end
+ #if( $ofs > 0 )
+ #set( $is_prev = 1 )
+ #end
+ #set( $is_form = $is_next + $is_prev )
+ #set( $ndx_first = $ofs + 1 )
+ #set( $ndx_last = $ofs + $pagesize )
+ #if( $ndx_last > $fcount )
+ #set( $ndx_last = $fcount )
+ #end
+
+ #comment( "Results display" )
+
+
+
+ #if( $stdlist == 1 )
+ Community Members
+ #else
+ Search Results
+ #end
+ #if( $is_form >= 1 )
+ (Displaying ${ndx_first}-${ndx_last} of ${fcount})
+ #end
+ |
+
+ #if( $is_form >= 1 )
+ #comment( "Results navigation form" )
+
+ #else
+
+ #end
+ |
+
+
+ #if( $fcount > 0 )
+ #set( $i = $resultcount )
+ #set( $prof_ns = "http://www.silverwrist.com/NS/venice/2002/12/31/user.profile" )
+
+ #foreach( $usr in $results )
+ #set( $i = $i - 1 )
+ #if( $i >= 0 )
+ #set( $first = $std.getProperty($usr,$prof_ns,"name.given") )
+ #set( $last = $std.getProperty($usr,$prof_ns,"name.family") )
+ #set( $city = $std.getProperty($usr,$prof_ns,"locality") )
+ #set( $state = $std.getProperty($usr,$prof_ns,"region") )
+ #set( $country = $std.getProperty($usr,$prof_ns,"country") )
+ #set( $descr = $std.getProperty($usr,$prof_ns,"description") )
+
+ #bullet() |
+
+ #encodeHTML( $usr.Name )
+ #encodeHTML( $first ) #encodeHTML( $last ), from #encodeHTML( $city ), #encodeHTML( $state )
+ #encodeHTML( $country.getCode() )
+ #if( $descr )
+ #encodeHTML( $descr )
+ #end
+ |
+
+ #end
+ #end
+
+ #else
+ No members found.
+ #end
+
+ #comment( "End results display" )
+#end
diff --git a/venice-data/velocity/stylesheets/adv_base.vm b/venice-data/velocity/stylesheets/adv_base.vm
index f36db71..25c96c5 100644
--- a/venice-data/velocity/stylesheets/adv_base.vm
+++ b/venice-data/velocity/stylesheets/adv_base.vm
@@ -73,6 +73,13 @@ body td.errorhead, body td.errorbody {
font-size: medium;
}
+body td.confirmhead, body td.confirmbody {
+ font-size: small;
+ voice-family: "\"}\"";
+ voice-family: inherit;
+ font-size: medium;
+ }
+
body td.sideboxtop, body div.sideboxtop, body p.sideboxtop {
font-size: small;
voice-family: "\"}\"";
@@ -119,6 +126,10 @@ html>body td.errorhead, html>body td.errorbody {
font-size: medium;
}
+html>body td.confirmhead, html>body td.confirmbody {
+ font-size: medium;
+ }
+
html>body td.sideboxtop, html>body div.sideboxtop, html>body p.sideboxtop {
font-size: medium;
}
diff --git a/venice-data/velocity/stylesheets/normal_base.vm b/venice-data/velocity/stylesheets/normal_base.vm
index d1f8343..796ace2 100644
--- a/venice-data/velocity/stylesheets/normal_base.vm
+++ b/venice-data/velocity/stylesheets/normal_base.vm
@@ -97,6 +97,7 @@ td.errorhead {
background-color: #660000;
text-align: center;
font-size: 15px;
+ font-weight: bold;
}
td.errorbody {
@@ -104,6 +105,19 @@ td.errorbody {
font-size: 15px;
}
+td.confirmhead {
+ color: #ffffff;
+ background-color: #006600;
+ text-align: center;
+ font-size: 15px;
+ font-weight: bold;
+ }
+
+td.confirmbody {
+ text-align: center;
+ font-size: 15px;
+ }
+
.selectedItem {
color: #3333aa;
font-weight: bold;