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', +'

+ + +
+ #encodeHTML( $title ) +
+

#encodeHTML( $message )

+

+ #button( "IMAGE" "yes" ) +    + #button( "IMAGE" "no" ) +

+

'), (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" ) +
+ + + + #comment( "Find Community Members form" ) +
+

Search for members of community "$comm.Name":

+

Display all users whose  +   +    +

+

#button( "INPUT" "search" )

+
+ #comment( "end Find Community Members form" ) +
+ +#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" ) +
+ + + + + + + + #if( $is_prev == 1 ) + #button( "INPUT" "previous" ) + #else + #button( "IMAGE" "0transparent" ) + #end +    + #if( $is_next == 1 ) + #button( "INPUT" "next" ) + #else + #button( "IMAGE" "0transparent" ) + #end +
+ #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") ) + + + + + #end + #end +
#bullet() + #encodeHTML( $usr.Name )
+ #encodeHTML( $first ) #encodeHTML( $last ), from #encodeHTML( $city ), #encodeHTML( $state ) +  #encodeHTML( $country.getCode() ) + #if( $descr ) +
#encodeHTML( $descr ) + #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;