added Members and Unjoin functionality, setting of public/private/invitation-

only for communities
This commit is contained in:
Eric J. Bowersox 2003-06-19 03:34:12 +00:00
parent 3be3c52161
commit fbaf90e156
31 changed files with 1079 additions and 27 deletions

View File

@ -534,7 +534,8 @@ INSERT INTO namespaces (nsid, namespace) VALUES
(16, 'http://www.silverwrist.com/NS/venice/2003/05/30/community.globals' ), (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' ), (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' ), (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 # Initial global properties setup
INSERT INTO globalprop (nsid, prop_name, prop_value) VALUES INSERT INTO globalprop (nsid, prop_name, prop_value) VALUES
@ -672,6 +673,20 @@ Report abuses to: <abuse@example.com>'),
#stacktrace( $except ) #stacktrace( $except )
--> -->
#end'), #end'),
(6, 'confirm.box',
'<p><table align="center" width="70%" border="1" cellpadding="2" cellspacing="1">
<tr valign="middle"><td class="confirmhead">
#encodeHTML( $title )
</td></tr>
<tr valign="middle"><td class="confirmbody">
<p>#encodeHTML( $message )</p>
<p>
<a href="#formatURL( $yes_type $yes_url )">#button( "IMAGE" "yes" )</a>
&nbsp;&nbsp;
<a href="#formatURL( $no_type $no_url )">#button( "IMAGE" "no" )</a>
</p>
</td></tr>
</table></p>'),
(6, 'user.agreement', (6, 'user.agreement',
'Text of this agreement is to be determined.'), 'Text of this agreement is to be determined.'),
(12, 'confirm.message', (12, 'confirm.message',
@ -1323,7 +1338,8 @@ INSERT INTO commprops (cid, nsid, prop_name, prop_value) VALUES
(1, 15, 'region', '!XX' ), (1, 15, 'region', '!XX' ),
(1, 15, 'postal.code', '!00000' ), (1, 15, 'postal.code', '!00000' ),
(1, 15, 'country', '_CTRY:US' ), (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) # Create the "global" menu. (ID #1)
INSERT INTO menus (menuid, menu_nsid, menu_name, title, subtitle) 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); (5, 'name', NULL);
INSERT INTO menuitems (menuid, sequence, itemtype, text, linktype, link) VALUES INSERT INTO menuitems (menuid, sequence, itemtype, text, linktype, link) VALUES
(5, 0, 'TEXT', 'Home Page', 'SERVLET', 'community/${alias}' ), (5, 0, 'TEXT', 'Home Page', 'SERVLET', 'community/${alias}' ),
(5, 60000, 'TEXT', 'Members', 'SERVLET', 'TODO' ), (5, 100, 'MARKER', 'begin-services', NULL, NULL ),
(5, 60100, 'TEXT', 'Profile', 'SERVLET', 'comm/profile.js.vs?cc=${cid}' ), (5, 60000, 'MARKER', 'end-services', NULL, NULL ),
(5, 60200, 'TEXT', 'Administration', 'SERVLET', 'comm/admin/main.js.vs?cc=${cid}'), (5, 60100, 'TEXT', 'Members', 'SERVLET', 'comm/members.js.vs?cc=${cid}' ),
(5, 60300, 'SEPARATOR', NULL, NULL, NULL ), (5, 60200, 'TEXT', 'Profile', 'SERVLET', 'comm/profile.js.vs?cc=${cid}' ),
(5, 60400, 'TEXT', 'Unjoin', 'SERVLET', 'TODO' ); (5, 60300, 'TEXT', 'Administration', 'SERVLET', 'comm/admin/main.js.vs?cc=${cid}'),
UPDATE menuitems SET perm_nsid = 16, perm_name = 'administration' WHERE menuid = 5 AND sequence = 60200; (5, 60400, 'SEPARATOR', NULL, NULL, NULL ),
UPDATE menuitems SET perm_nsid = 14, perm_name = 'unjoin' WHERE menuid = 5 AND sequence = 60300; (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 = 60400;
UPDATE menuitems SET perm_nsid = 14, perm_name = 'unjoin' WHERE menuid = 5 AND sequence = 60500;
# Create the "top" menu (non-community). (ID #6) # Create the "top" menu (non-community). (ID #6)
INSERT INTO menus (menuid, menu_nsid, menu_name, title, subtitle) INSERT INTO menus (menuid, menu_nsid, menu_name, title, subtitle)

View File

@ -614,4 +614,14 @@ class GroupObject implements DynamoGroup
} // end getMemberCount } // 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<ids.length; i++)
rc.add(m_upm.getUserProxy(ids[i]));
return Collections.unmodifiableList(rc);
} // end getMembers
} // end class GroupObject } // end class GroupObject

View File

@ -58,6 +58,8 @@ abstract class GroupObjectOps extends OpsBase
abstract int[] getMembers(int gid) throws DatabaseException; abstract int[] getMembers(int gid) throws DatabaseException;
abstract int[] getMembers(int gid, int offset, int count) throws DatabaseException;
abstract void setAclID(int gid, int aclid) throws DatabaseException; abstract void setAclID(int gid, int aclid) throws DatabaseException;
abstract int getMemberCount(int gid) throws DatabaseException; abstract int getMemberCount(int gid) throws DatabaseException;

View File

@ -517,6 +517,52 @@ class GroupObjectOps_mysql extends GroupObjectOps
} // end getMembers } // end getMembers
int[] getMembers(int gid, int offset, int count) throws DatabaseException
{
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
int[] tmp = new int[count+1];
int level = 0;
try
{ // get a connection
conn = getConnection();
// create the statement that does the lookup
stmt = conn.prepareStatement("SELECT u.uid FROM users u, groupmembers g WHERE u.uid = g.uid AND g.gid = ? "
+ "ORDER BY u.username LIMIT ?, ?;");
stmt.setInt(1,gid);
stmt.setInt(2,offset);
stmt.setInt(3,count+1);
rs = stmt.executeQuery();
// fill the temporary array
while (rs.next())
tmp[level++] = rs.getInt(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
// set up the return value
if (level==tmp.length)
return tmp;
int[] rc = new int[level];
System.arraycopy(tmp,0,rc,0,level);
return rc;
} // end getMembers
void setAclID(int gid, int aclid) throws DatabaseException void setAclID(int gid, int aclid) throws DatabaseException
{ {
Connection conn = null; Connection conn = null;

View File

@ -241,6 +241,12 @@ abstract class GroupProxy implements DynamoGroup, DynamicWrapper
} // end getMemberCount } // end getMemberCount
public List getMembers(int offset, int count) throws DatabaseException
{
return getRealGroup().getMembers(offset,count);
} // end getMembers
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Implementations from interface DynamicWrapper * Implementations from interface DynamicWrapper
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------

View File

@ -11,7 +11,7 @@
* *
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>, * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are * 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): * Contributor(s):
*/ */
@ -20,6 +20,7 @@ package com.silverwrist.dynamo.iface;
import java.security.Principal; import java.security.Principal;
import java.security.acl.AclNotFoundException; import java.security.acl.AclNotFoundException;
import java.security.acl.Group; import java.security.acl.Group;
import java.util.List;
import com.silverwrist.dynamo.except.DatabaseException; import com.silverwrist.dynamo.except.DatabaseException;
import com.silverwrist.dynamo.except.DynamoSecurityException; import com.silverwrist.dynamo.except.DynamoSecurityException;
@ -47,4 +48,6 @@ public interface DynamoGroup extends Group, NamedObject, SecureObjectStore
public int getMemberCount() throws DatabaseException; public int getMemberCount() throws DatabaseException;
public List getMembers(int offset, int count) throws DatabaseException;
} // end interface DynamoGroup } // end interface DynamoGroup

View File

@ -95,6 +95,12 @@ public class LibraryCast
} // end newIntArray } // end newIntArray
public final AuthenticatorLookup queryAuthenticatorLookup(Object obj)
{
return (AuthenticatorLookup)query(obj,AuthenticatorLookup.class);
} // end queryAuthenticatorLookup
public final ChainParameterInput queryChainParameterInput(Object obj) public final ChainParameterInput queryChainParameterInput(Object obj)
{ {
return (ChainParameterInput)query(obj,ChainParameterInput.class); return (ChainParameterInput)query(obj,ChainParameterInput.class);

View File

@ -73,4 +73,7 @@ public interface VeniceNamespaces
public static final String COMMUNITY_NAMESPACE = public static final String COMMUNITY_NAMESPACE =
"http://www.silverwrist.com/NS/venice/2003/06/15/community"; "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 } // end interface VeniceNamespaces

View File

@ -275,4 +275,46 @@ public class AdvancedUserManager implements NamedObject, ComponentInitialize, Co
} // end getSearchUserCount } // 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 } // end class AdvancedUserManager

View File

@ -43,12 +43,23 @@ abstract class AdvancedUserOps extends OpsBase
abstract int[] searchProperty(int nsid, String name, SearchMode mode, String term, int offset, int count) abstract int[] searchProperty(int nsid, String name, SearchMode mode, String term, int offset, int count)
throws DatabaseException; 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 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(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(SearchMode mode, String term) throws DatabaseException;
abstract int searchNameCount(int member_gid, SearchMode mode, String term) throws DatabaseException;
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* External static operations * External static operations
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------

View File

@ -116,6 +116,58 @@ public class AdvancedUserOps_mysql extends AdvancedUserOps
tmp[ct++] = rs.getInt(1); tmp[ct++] = rs.getInt(1);
// Create the actual return array and fill it. // 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]; int[] rc = new int[ct];
System.arraycopy(tmp,0,rc,0,ct); System.arraycopy(tmp,0,rc,0,ct);
return rc; return rc;
@ -171,6 +223,41 @@ public class AdvancedUserOps_mysql extends AdvancedUserOps
} // end searchPropertyCount } // 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 int[] searchName(SearchMode mode, String term, int offset, int count) throws DatabaseException
{ {
Connection conn = null; Connection conn = null;
@ -200,6 +287,61 @@ public class AdvancedUserOps_mysql extends AdvancedUserOps
tmp[ct++] = rs.getInt(1); tmp[ct++] = rs.getInt(1);
// Create the actual return array and fill it. // 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]; int[] rc = new int[ct];
System.arraycopy(tmp,0,rc,0,ct); System.arraycopy(tmp,0,rc,0,ct);
return rc; return rc;
@ -258,4 +400,44 @@ public class AdvancedUserOps_mysql extends AdvancedUserOps
} // end searchNameCount } // 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 } // end class AdvancedUserOps_mysql

View File

@ -20,6 +20,7 @@ package com.silverwrist.venice.app;
import java.util.List; import java.util.List;
import com.silverwrist.dynamo.db.UserManagement; import com.silverwrist.dynamo.db.UserManagement;
import com.silverwrist.dynamo.except.DatabaseException; import com.silverwrist.dynamo.except.DatabaseException;
import com.silverwrist.dynamo.iface.DynamoGroup;
import com.silverwrist.dynamo.iface.DynamoUser; import com.silverwrist.dynamo.iface.DynamoUser;
import com.silverwrist.venice.SearchMode; import com.silverwrist.venice.SearchMode;
import com.silverwrist.venice.UserSearchField; 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) public int getSearchUserCount(DynamoUser caller, UserSearchField field, SearchMode mode, String term)
throws DatabaseException; 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 } // end interface AdvancedUserService

View File

@ -880,6 +880,7 @@ class CommunityImpl implements VeniceCommunity
synchronized (this) synchronized (this)
{ // update the access table and touch the community { // update the access table and touch the community
java.util.Date update = m_ops.revokeAccess(m_id,ugid,is_group); java.util.Date update = m_ops.revokeAccess(m_id,ugid,is_group);
if (update!=null)
m_lastaccessed = m_lastupdate = update; m_lastaccessed = m_lastupdate = update;
} // end synchronized block } // end synchronized block
@ -953,7 +954,8 @@ class CommunityImpl implements VeniceCommunity
logger.debug("CommunityImpl.join: " + joiner.getName() + " joining " + m_name); 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 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; return false;
boolean ok_to_join = false; boolean ok_to_join = false;
@ -1030,7 +1032,7 @@ class CommunityImpl implements VeniceCommunity
if (ok_to_join) if (ok_to_join)
{ // we're OK to join this group! { // 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) if (task!=null)
task.run(); task.run();
return true; return true;
@ -1051,6 +1053,16 @@ class CommunityImpl implements VeniceCommunity
} // end join } // 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) public boolean isAdministrator(DynamoUser user)
{ {
try try

View File

@ -33,3 +33,4 @@ join.disallowed=You are not permitted to join community "{0}."
join.authFail=Unable to authenticate to community "{0}"; cannot join. 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.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. svc.object.badType=The service controller object {0}::{1} was of the wrong type.
auth.unjoin=You are not permitted to unjoin community "{0}."

View File

@ -650,7 +650,19 @@ class CommunityOps_mysql extends CommunityOps
stmt2 = conn.createStatement(); stmt2 = conn.createStatement();
stmt2.executeUpdate("LOCK TABLES commaccess WRITE, communities WRITE;"); stmt2.executeUpdate("LOCK TABLES commaccess WRITE, communities WRITE;");
// create the insert statement and execute it // 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));
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, " stmt = conn.prepareStatement("INSERT INTO commaccess (cid, ugid, is_group, single_use, auth_nsid, auth_name, "
+ "source_data, auth_data) VALUES (?, ?, ?, ?, ?, ?, ?, ?);"); + "source_data, auth_data) VALUES (?, ?, ?, ?, ?, ?, ?, ?);");
stmt.setInt(1,cid); stmt.setInt(1,cid);
@ -664,6 +676,26 @@ class CommunityOps_mysql extends CommunityOps
stmt.setString(6,auth_name); stmt.setString(6,auth_name);
stmt.setString(7,source_data); stmt.setString(7,source_data);
stmt.setString(8,auth_data); stmt.setString(8,auth_data);
} // end if
else
{ // 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(); stmt.executeUpdate();
// Touch the community entry. // Touch the community entry.
@ -707,7 +739,8 @@ class CommunityOps_mysql extends CommunityOps
stmt.setInt(1,cid); stmt.setInt(1,cid);
stmt.setInt(2,ugid); stmt.setInt(2,ugid);
stmt.setInt(3,(is_group ? 1 : 0)); stmt.setInt(3,(is_group ? 1 : 0));
stmt.executeUpdate(); if (stmt.executeUpdate()<=0)
return null;
// Touch the community entry. // Touch the community entry.
return touchCommunity(conn,cid); return touchCommunity(conn,cid);

View File

@ -603,6 +603,12 @@ abstract class CommunityProxy implements VeniceCommunity, DynamicWrapper
} // end join } // end join
public void unjoin(DynamoUser unjoiner) throws DatabaseException, DynamoSecurityException
{
getRealCommunity().unjoin(unjoiner);
} // end unjoin
public boolean isAdministrator(DynamoUser user) public boolean isAdministrator(DynamoUser user)
{ {
return getRealCommunity().isAdministrator(user); return getRealCommunity().isAdministrator(user);

View File

@ -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 <http://www.mozilla.org/MPL/>.
*
* 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 <erbo@silcom.com>,
* 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 <EM>menu selector</EM> 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 <CODE>null</CODE>, 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 <EM>site title</EM> (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 <EM>page quick ID</EM> 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 <CODE>null</CODE>, 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

View File

@ -27,3 +27,4 @@ activity.never=Never
activity.today=Today, {0} activity.today=Today, {0}
activity.yesterday=Yesterday, {0} activity.yesterday=Yesterday, {0}
activity.daysago={0} days ago activity.daysago={0} days ago
render.confirmBox=Unable to render a confirmation box: {0}\nBox title was: {1}\nBox message was: {2}

View File

@ -94,6 +94,7 @@ public class StandardContentSupplier
private String m_name = null; // name of the object private String m_name = null; // name of the object
private ObjectProvider m_blocks; // global blocks provider private ObjectProvider m_blocks; // global blocks provider
private ComponentShutdown m_shut_1; // shut down renderer 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 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. // Register this object as a renderer for some objects.
RendererRegistration rr = (RendererRegistration)(services.queryService(RendererRegistration.class)); RendererRegistration rr = (RendererRegistration)(services.queryService(RendererRegistration.class));
m_shut_1 = rr.registerRenderer(ErrorBox.class,this); 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. // Add an object to the standard objects available to Velocity.
VelocityRendererConfig vrcon = VelocityRendererConfig vrcon =
@ -194,6 +196,8 @@ public class StandardContentSupplier
{ {
m_shut_2.shutdown(); m_shut_2.shutdown();
m_shut_2 = null; m_shut_2 = null;
m_shut_1a.shutdown();
m_shut_1a = null;
m_shut_1.shutdown(); m_shut_1.shutdown();
m_shut_1 = null; m_shut_1 = null;
m_blocks = null; m_blocks = null;
@ -307,6 +311,33 @@ public class StandardContentSupplier
} // end catch } // end catch
} // end if } // 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 } // end render

View File

@ -312,6 +312,8 @@ public interface VeniceCommunity extends NamedObject, SecureObjectStore
public boolean join(DynamoUser joiner) throws DatabaseException, DynamoSecurityException; public boolean join(DynamoUser joiner) throws DatabaseException, DynamoSecurityException;
public void unjoin(DynamoUser unjoiner) throws DatabaseException, DynamoSecurityException;
public boolean isAdministrator(DynamoUser user); public boolean isAdministrator(DynamoUser user);
public List getServices() throws DatabaseException; public List getServices() throws DatabaseException;

View File

@ -273,6 +273,8 @@ class InlineMenuRendering implements MenuRenderObject, SelfRenderable
if (m_showitem[i] && item.itemDefined(m_local_vars)) if (m_showitem[i] && item.itemDefined(m_local_vars))
{ // render this item { // render this item
String s = item.getItemType(); String s = item.getItemType();
if (s.equalsIgnoreCase("MARKER"))
continue; // ignore markers
if (s.equalsIgnoreCase("TEXT")) if (s.equalsIgnoreCase("TEXT"))
renderTextItem(tctrl,item,(i==m_selected_index)); renderTextItem(tctrl,item,(i==m_selected_index));
else if (s.equalsIgnoreCase("HEADER")) else if (s.equalsIgnoreCase("HEADER"))

View File

@ -266,6 +266,8 @@ class LeftMenuRendering implements MenuRenderObject, SelfRenderable
if (m_showitem[i] && item.itemDefined(m_local_vars)) if (m_showitem[i] && item.itemDefined(m_local_vars))
{ // render this item { // render this item
String s = item.getItemType(); String s = item.getItemType();
if (s.equalsIgnoreCase("MARKER"))
continue; // ignore markers
if (s.equalsIgnoreCase("TEXT")) if (s.equalsIgnoreCase("TEXT"))
renderTextItem(tctrl,item,(m_selected_index==i)); renderTextItem(tctrl,item,(m_selected_index==i));
else if (s.equalsIgnoreCase("HEADER")) else if (s.equalsIgnoreCase("HEADER"))

View File

@ -278,6 +278,8 @@ class StandardMenuRendering implements MenuRenderObject, SelfRenderable, FramedC
if (m_showitem[i] && item.itemDefined(m_local_vars)) if (m_showitem[i] && item.itemDefined(m_local_vars))
{ // render this item { // render this item
s = item.getItemType(); s = item.getItemType();
if (s.equalsIgnoreCase("MARKER"))
continue; // ignore markers
if (s.equalsIgnoreCase("TEXT")) if (s.equalsIgnoreCase("TEXT"))
renderTextItem(tctl,item,(m_selected_index==i)); renderTextItem(tctl,item,(m_selected_index==i));
else if (s.equalsIgnoreCase("HEADER")) else if (s.equalsIgnoreCase("HEADER"))

View File

@ -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) public String dialogFrameTitle(Dialog dlg)
{ {
String s = dlg.getSubtitle(); String s = dlg.getSubtitle();

View File

@ -16,8 +16,10 @@
importPackage(java.lang); importPackage(java.lang);
importClass(Packages.com.silverwrist.dynamo.Namespaces); importClass(Packages.com.silverwrist.dynamo.Namespaces);
importClass(Packages.com.silverwrist.dynamo.UserInfoNamespace);
importPackage(Packages.com.silverwrist.dynamo.except); importPackage(Packages.com.silverwrist.dynamo.except);
importPackage(Packages.com.silverwrist.dynamo.iface); importPackage(Packages.com.silverwrist.dynamo.iface);
importPackage(Packages.com.silverwrist.dynamo.security);
importPackage(Packages.com.silverwrist.dynamo.util); importPackage(Packages.com.silverwrist.dynamo.util);
importClass(Packages.com.silverwrist.venice.CommunityVisibility); importClass(Packages.com.silverwrist.venice.CommunityVisibility);
importClass(Packages.com.silverwrist.venice.VeniceNamespaces); 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", dynamo.scriptReturn(vlib.stdErrorBox(req,"Security Error",
"You are not permitted to modify this community's profile.")); "You are not permitted to modify this community's profile."));
variable_type = acl.testPermission(user,VeniceNamespaces.COMMUNITY_SECURITY_NAMESPACE,"set.property")
// Create the dialog. // Create the dialog.
loader = cast.queryDialogLoader(req); loader = cast.queryDialogLoader(req);
dlg = loader.loadDialogResource("comm/community_profile.dlg.xml"); 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("pcode",comm.getObject(VeniceNamespaces.COMMUNITY_PROFILE_NAMESPACE,"postal.code"));
dlg.setValue("country",comm.getObject(VeniceNamespaces.COMMUNITY_PROFILE_NAMESPACE,"country")); dlg.setValue("country",comm.getObject(VeniceNamespaces.COMMUNITY_PROFILE_NAMESPACE,"country"));
dlg.setValue("comtype","0"); // TODO: replace with something real dlg.setValue("comtype",comm.getObject(VeniceNamespaces.COMMUNITY_SECURITY_NAMESPACE,"type.hint"));
dlg.setValue("joinkey",""); // TODO: replace with something real dlg.setValue("joinkey",PropertyUtils.getPropertyNoErr(comm,VeniceNamespaces.COMMUNITY_SECURITY_NAMESPACE,
"join.key"));
dlg.setValue("visibility",comm.getVisibility().getName()); dlg.setValue("visibility",comm.getVisibility().getName());
} // end if } // 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,"postal.code",dlg.getValue("pcode"));
comm.setObject(user,VeniceNamespaces.COMMUNITY_PROFILE_NAMESPACE,"country",dlg.getValue("country")); 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"))); comm.setVisibility(user,CommunityVisibility.getEnum(dlg.getValue("visibility")));
vlib.forceReloadMenu(req); // the menu might have changed, so reload it 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 { // output dialog if we don't have another value
dlg.setSubtitle(comm.getName()); dlg.setSubtitle(comm.getName());
dlg.setRenderParam("cid",comm.getCID() + ""); 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 = new FrameDialog(dlg);
rc.menuSelector = "community"; rc.menuSelector = "community";

View File

@ -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 <http://www.mozilla.org/MPL/>.
//
// 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 <erbo@silcom.com>,
// 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);

View File

@ -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 <http://www.mozilla.org/MPL/>.
//
// 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 <erbo@silcom.com>,
// 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));

View File

@ -156,6 +156,7 @@ if (op=="create")
logger.debug("OK to join community: " + comm.name); logger.debug("OK to join community: " + comm.name);
if (comm.join(new_user)) if (comm.join(new_user))
{ {
// TODO: what do we do after we join the community?
} }
} // end if } // end if

View File

@ -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 <http://www.mozilla.org/MPL/>.
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 <erbo@silcom.com>,
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" )
<form method="POST" action="#formatURL( "SERVLET" "comm/members.js.vs")">
<input type="hidden" name="cc" value="${comm.getCID()}" />
<input type="hidden" name="ofs" value="0" />
<input type="hidden" name="sl" value="0" />
#comment( "Find Community Members form" )
<div align="left">
<p><b>Search for members of community &quot;$comm.Name&quot;:</b></p>
<p>Display all users whose&nbsp;
<select name="field" size="1">
<option value="USERNAME" #if( $field.equals("USERNAME") )selected="selected"#end >username</option>
<option value="DESCRIPTION" #if( $field.equals("DESCRIPTION") )selected="selected"#end >description</option>
<option value="FIRSTNAME" #if( $field.equals("FIRSTNAME") )selected="selected"#end >first name</option>
<option value="LASTNAME" #if( $field.equals("LASTNAME") )selected="selected"#end >last name</option>
</select>&nbsp;
<select name="mode" size="1">
<option value="PREFIX" #if( $mode.equals("PREFIX") )selected="selected"#end >starts with the string</option>
<option value="SUBSTRING" #if( $mode.equals("SUBSTRING") )selected="selected"#end >contains the string</option>
<option value="REGEXP" #if( $mode.equals("REGEXP") )selected="selected"#end >matches the regular
expression</option>
</select>&nbsp;&nbsp;
<input type="text" name="term" size="32" maxlength="255" value="$!term" /></p>
<p>#button( "INPUT" "search" )</p>
</div>
#comment( "end Find Community Members form" )
</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" )
<hr />
<table width="100%" border="0" align="center"><tr valign="middle">
<td width="50%" align="left" class="subhead">
#if( $stdlist == 1 )
<b>Community Members</b>
#else
<b>Search Results</b>
#end
#if( $is_form >= 1 )
(Displaying ${ndx_first}-${ndx_last} of ${fcount})
#end
</td>
<td width="50%" align="right">
#if( $is_form >= 1 )
#comment( "Results navigation form" )
<form method="POST" action="#formatURL( "SERVLET" "comm/members.js.vs")">
<input type="hidden" name="cc" value="${comm.getCID()}" />
<input type="hidden" name="sl" value="$stdlist" />
<input type="hidden" name="field" value="$!field" />
<input type="hidden" name="mode" value="$!mode" />
<input type="hidden" name="term" value="$!term" />
<input type="hidden" name="ofs" value="$ofs" />
<input type="hidden" name="fcount" value="$fcount" />
#if( $is_prev == 1 )
#button( "INPUT" "previous" )
#else
#button( "IMAGE" "0transparent" )
#end
&nbsp;&nbsp;
#if( $is_next == 1 )
#button( "INPUT" "next" )
#else
#button( "IMAGE" "0transparent" )
#end
</form>
#else
&nbsp;
#end
</td>
</tr></table>
#if( $fcount > 0 )
#set( $i = $resultcount )
#set( $prof_ns = "http://www.silverwrist.com/NS/venice/2002/12/31/user.profile" )
<table border="0" align="left" cellpadding="0" cellspacing="4">
#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") )
<tr valign="top">
<td align="center" width="14">#bullet()</td>
<td align="left" class="content">
<a href="#formatURL( "SERVLET" "user/${usr.Name}" )">#encodeHTML( $usr.Name )</a><br />
#encodeHTML( $first ) #encodeHTML( $last ), from #encodeHTML( $city ), #encodeHTML( $state )
&nbsp;#encodeHTML( $country.getCode() )
#if( $descr )
<br /><em>#encodeHTML( $descr )</em>
#end
</td>
</tr>
#end
#end
</table>
#else
<em>No members found.</em>
#end
#comment( "End results display" )
#end

View File

@ -73,6 +73,13 @@ body td.errorhead, body td.errorbody {
font-size: medium; 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 { body td.sideboxtop, body div.sideboxtop, body p.sideboxtop {
font-size: small; font-size: small;
voice-family: "\"}\""; voice-family: "\"}\"";
@ -119,6 +126,10 @@ html>body td.errorhead, html>body td.errorbody {
font-size: medium; 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 { html>body td.sideboxtop, html>body div.sideboxtop, html>body p.sideboxtop {
font-size: medium; font-size: medium;
} }

View File

@ -97,6 +97,7 @@ td.errorhead {
background-color: #660000; background-color: #660000;
text-align: center; text-align: center;
font-size: 15px; font-size: 15px;
font-weight: bold;
} }
td.errorbody { td.errorbody {
@ -104,6 +105,19 @@ td.errorbody {
font-size: 15px; 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 { .selectedItem {
color: #3333aa; color: #3333aa;
font-weight: bold; font-weight: bold;