implemented SIG membership control, Delete SIG, and the "shell" for the

System Administration menu; also added "Post & Go Topics" as an option for the
post box in conferencing
This commit is contained in:
Eric J. Bowersox 2001-02-23 07:49:42 +00:00
parent e23de5dae6
commit 680b84b9d8
33 changed files with 1517 additions and 31 deletions

11
TODO
View File

@ -2,19 +2,20 @@ Lots!
- Unimplemented functions on the SIG Administration page:
Set SIG Features (sigadmin, command=F)
Membership Control (sigadmin, command=M)
Delete SIG (sigadmin, command=DEL)
- Implement SIG invitations ("Invite" button on the profile).
- Unimplemented functions in the system admin menu:
Set Global Parameters
View/Edit Banned Users
User Account Management
(More stuff needs to be added, I'm just not sure what.)
- Should we provide the sysadmin the ability to disable SIG creation for
non-admin users? Maybe there needs to be a "global" set of levels that
aren't hardcoded. Where do they get stored? The database? (Maybe the
nice shiny new "globals" table?)
- There's no system admin functionality AT ALL. We need to have this stuff
before we go live. (It plugs into the Administrative SIG features.)
- Unimplemented functions on the Top page:
Customize Sideboxes

View File

@ -77,6 +77,14 @@
<servlet-class>com.silverwrist.venice.servlets.Account</servlet-class>
</servlet>
<servlet>
<servlet-name>systemadmin</servlet-name>
<description>
System administration operations.
</description>
<servlet-class>com.silverwrist.venice.servlets.SystemAdmin</servlet-class>
</servlet>
<servlet>
<servlet-name>settings</servlet-name>
<description>
@ -208,6 +216,11 @@
<url-pattern>/account</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>systemadmin</servlet-name>
<url-pattern>/sysadmin</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>settings</servlet-name>
<url-pattern>/settings</url-pattern>

View File

@ -1,3 +1,4 @@
# MySQL script for initializing the Venice database.
# Written by Eric J. Bowersox <erbo@silcom.com>
#---------------------------------------------------------------------------
@ -427,6 +428,7 @@ INSERT INTO refaudit (type, descr) VALUES
(209, 'Set SIG Members-Only Flag'),
(210, 'Set SIG Join Key'),
(211, 'Set SIG Security Levels'),
(212, 'Delete SIG'),
(301, 'Create New Conference'),
(302, 'Set Conference Security Levels'),
(303, 'Set Conference Name'),
@ -1302,7 +1304,7 @@ INSERT INTO refsigftr (ftr_code, is_default, is_locked, is_hidden, require_read,
symbol, name, applet) VALUES
(0, 1, 1, 1, 0, 4900, 0, 'PROF', 'Profile', 'sigprofile'),
(1, 1, 1, 1, 0, 5000, 57000, 'ADMN', 'Administration', 'sigadmin'),
(2, 0, 1, 1, 0, 10000, 63000, 'SYSA', 'System Administration', 'TODO'),
(2, 0, 1, 1, 0, 10000, 63000, 'SYSA', 'System Administration', 'sysadmin'),
(3, 1, 0, 0, 1, 500, 0, 'CONF', 'Conferences', 'confops');
##############################################################################

View File

@ -7,7 +7,7 @@
* 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 Community System.
* 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
@ -20,4 +20,5 @@ package com.silverwrist.venice.core;
public interface AdminOperations
{
// TODO: fill this in
} // end interface AdminOperations

View File

@ -153,4 +153,13 @@ public interface SIGContext extends SearchMode
public abstract boolean canManageConferences();
public abstract int getMemberLevel(int uid) throws DataException, AccessError;
public abstract void setMembership(int uid, int new_level)
throws DataException, AccessError;
public abstract boolean canDelete();
public abstract void delete() throws DataException, AccessError;
} // end interface SIGContext

View File

@ -89,4 +89,8 @@ public interface UserContext extends SearchMode
public abstract List getConferenceHotlist() throws DataException;
public abstract boolean hasAdminAccess();
public abstract AdminOperations getAdminInterface() throws AccessError;
} // end interface UserContext

View File

@ -0,0 +1,61 @@
/*
* 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) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.core.impl;
import java.sql.*;
import org.apache.log4j.*;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.db.*;
class AdminOperationsImpl implements AdminOperations
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Category logger = Category.getInstance(AdminOperationsImpl.class.getName());
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private EngineBackend engine; // the back end of the engine
private UserBackend user; // the UserContext that created this object
private DataPool datapool; // the data pool used by this object
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
AdminOperationsImpl(EngineBackend engine, UserBackend user, DataPool datapool)
{
this.engine = engine;
this.user = user;
this.datapool = datapool;
} // end constructor
/*--------------------------------------------------------------------------------
* Implementations from interface AdminOperations
*--------------------------------------------------------------------------------
*/
} // end class AdminOperationsImpl

View File

@ -0,0 +1,178 @@
/*
* 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) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.core.impl;
import java.sql.*;
import java.util.*;
import org.apache.log4j.*;
import com.silverwrist.util.ParallelRunQueue;
import com.silverwrist.venice.db.*;
import com.silverwrist.venice.core.DataException;
import com.silverwrist.venice.core.InternalStateError;
class BackgroundSIGPurge implements Runnable
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Category logger = Category.getInstance(BackgroundSIGPurge.class.getName());
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private DataPool datapool;
private UserBackend user;
private int sigid;
private int num_confs;
private int max_confid;
private Hashtable conf_objects;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
BackgroundSIGPurge(DataPool datapool, UserBackend user, int sigid, int num_confs, int max_confid,
Hashtable conf_objects)
{
this.datapool = datapool;
this.user = user;
this.sigid = sigid;
this.num_confs = num_confs;
this.max_confid = max_confid;
this.conf_objects = conf_objects;
} // end constructor
/*--------------------------------------------------------------------------------
* Implementations from interface Runnable
*--------------------------------------------------------------------------------
*/
public void run()
{
if (logger.isDebugEnabled())
logger.debug("BackgroundSIGPurge running on SIG #" + sigid);
Connection conn = null; // pooled database connection
ParallelRunQueue rq = new ParallelRunQueue(2);
try
{ // get a database connection from the pool
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
// run some "lower priority" deletes
stmt.executeUpdate("DELETE FROM contacts WHERE owner_sigid = " + sigid + ";");
stmt.executeUpdate("DELETE FROM sigftrs WHERE sigid = " + sigid + ";");
stmt.executeUpdate("DELETE FROM sigban WHERE sigid = " + sigid + ";");
// look up all conference IDs in this SIG
int[] conf_ids = new int[num_confs];
StringBuffer sql = new StringBuffer("SELECT confid FROM sigtoconf WHERE sigid = ");
sql.append(sigid).append(" AND confid <= ").append(max_confid).append(" ORDER BY confid;");
ResultSet rs = stmt.executeQuery(sql.toString());
int conferences = 0;
while (rs.next())
conf_ids[conferences++] = rs.getInt(1);
for (int i=0; i<conferences; i++)
{ // look to see if there's a conference SIG object first
Integer key = new Integer(conf_ids[i]);
ConferenceSIGContext confobj = (ConferenceSIGContext)(conf_objects.get(key));
if (confobj!=null)
{ // OK, there's an object - do the delete internally and release the object
conf_objects.remove(key);
confobj.delete(user);
confobj.rd_release();
} // end if
else
{ // we need to manually remove the conference ourselves
boolean delete_core = true;
// see if conference is linked to other SIGs - will determine whether we do the core purge
// routine
sql.setLength(0);
sql.append("SELECT sigid FROM sigtoconf WHERE confid = ").append(key).append(" AND sigid <> ");
sql.append(sigid).append(" LIMIT 1;");
rs = stmt.executeQuery(sql.toString());
if (rs.next())
delete_core = false;
// delete the sigtoconf record
sql.setLength(0);
sql.append("DELETE FROM sigtoconf WHERE sigid = ").append(sigid).append(" AND confid = ");
sql.append(key).append(';');
if (delete_core)
{ // OK, we officially need to delete the whole core now...purge from the two important
// tables first
stmt.executeUpdate("DELETE FROM confs WHERE confid = " + key + ";");
stmt.executeUpdate("DELETE FROM confalias WHERE confid = " + key + ";");
// determine the number of topics in this conference, and the maximum topic ID, and use
// that information to queue up the conference deletion
sql.setLength(0);
sql.append("SELECT COUNT(*), MAX(topicid) FROM topics WHERE confid = ").append(key).append(';');
rs = stmt.executeQuery(sql.toString());
if (!(rs.next()))
throw new InternalStateError("BackgroundSIGPurge.run screwup on conference SELECT");
rq.queue(new BackgroundConferencePurge(datapool,key.intValue(),rs.getInt(1),rs.getInt(2)));
} // end if (have to delete conference data)
} // end else (deleting conference data manually)
} // end for
if (logger.isDebugEnabled())
logger.debug("BackgroundSIGPurge basic delete complete for sig #" + sigid);
} // end try
catch (SQLException e)
{ // on an error, just die
logger.error("BackgroundSIGPurge FATAL EXCEPTION purging #" + sigid + ": " + e.getMessage(),e);
return;
} // end catch
catch (DataException de)
{ // on an error, just die
logger.error("BackgroundSIGPurge FATAL EXCEPTION purging #" + sigid + ": " + de.getMessage(),de);
return;
} // end catch
finally
{ // make sure we release the connection before we go
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
rq.run(); // now run the parallel queue to finish processing
if (logger.isDebugEnabled())
logger.debug("BackgroundSIGPurge COMPLETE for sig #" + sigid);
} // end run
} // end class BackgroundSIGPurge

View File

@ -1154,7 +1154,7 @@ class ConferenceCoreData implements ConferenceData
} // end canDeleteConference
public synchronized void delete(SIGBackend sig) throws DataException
public synchronized void delete(UserBackend user, int the_sigid) throws DataException
{
if (deleted)
throw new DataException("This conference has been deleted.");
@ -1208,7 +1208,7 @@ class ConferenceCoreData implements ConferenceData
} // end finally
// create an audit record indicating we were successful
ar = new AuditRecord(AuditRecord.DELETE_CONF,sig.realUID(),sig.userRemoteAddress(),sig.realSIGID(),
ar = new AuditRecord(AuditRecord.DELETE_CONF,user.realUID(),user.userRemoteAddress(),the_sigid,
"confid=" + confid);
} // end try

View File

@ -100,6 +100,6 @@ public interface ConferenceData extends ReferencedData
public abstract boolean canDeleteConference(int level);
public abstract void delete(SIGBackend sig) throws DataException;
public abstract void delete(UserBackend user, int the_sigid) throws DataException;
} // end interface ConferenceData

View File

@ -106,6 +106,6 @@ public interface ConferenceSIGContext extends ReferencedData
public abstract boolean canDeleteConference(int level);
public abstract void delete(SIGBackend sig) throws DataException;
public abstract void delete(UserBackend user) throws DataException;
} // end interface ConferenceSIGContext

View File

@ -769,7 +769,7 @@ class ConferenceSIGContextImpl implements ConferenceSIGContext
} // end canDeleteConference
public void delete(SIGBackend sig) throws DataException
public void delete(UserBackend user) throws DataException
{
ConferenceData c = getConferenceData();
Connection conn = null;
@ -782,7 +782,7 @@ class ConferenceSIGContextImpl implements ConferenceSIGContext
// see if we have to delete the core object as well
StringBuffer sql = new StringBuffer("SELECT sigid FROM sigtoconf WHERE confid = ");
sql.append(confid).append(" AND sigid <> ").append(this.sig.realSIGID()).append(" LIMIT 1;");
sql.append(confid).append(" AND sigid <> ").append(sig.realSIGID()).append(" LIMIT 1;");
ResultSet rs = stmt.executeQuery(sql.toString());
if (rs.next())
delete_core = false; // we don't delete the core yet
@ -790,7 +790,7 @@ class ConferenceSIGContextImpl implements ConferenceSIGContext
// remove the row that links this conference to this SIG
sql.setLength(0);
sql.append("DELETE FROM sigtoconf WHERE confid = ").append(confid).append(" AND sigid = ");
sql.append(this.sig.realSIGID()).append(';');
sql.append(sig.realSIGID()).append(';');
stmt.executeUpdate(sql.toString());
// record that we've been deleted
@ -816,7 +816,7 @@ class ConferenceSIGContextImpl implements ConferenceSIGContext
if (delete_core)
{ // the conference is not linked to any other SIGs - we need to delete the core as well
c.delete(sig);
c.delete(user,sig.realSIGID());
engine.detachConferenceDataObject(confid);
} // end if

View File

@ -69,6 +69,7 @@ class SIGCoreData implements SIGData, SIGDataBackend
private boolean public_sig; // is this a public SIG?
private BitSet features; // set of available features
private Hashtable conf_objects = new Hashtable(); // holder for ConferenceSIGContextImpl objects
private boolean deleted = false; // has this SIG been deleted?
/*--------------------------------------------------------------------------------
* Constructor
@ -340,8 +341,10 @@ class SIGCoreData implements SIGData, SIGDataBackend
} // end getLastUpdateDate
public void testMembership(int level, boolean is_member) throws AccessError
public void testMembership(int level, boolean is_member) throws DataException, AccessError
{
if (deleted)
throw new DataException("This SIG has been deleted.");
if (Capability.exemptFromMembershipRequirement(level))
return;
if (members_only && !is_member)
@ -355,6 +358,8 @@ class SIGCoreData implements SIGData, SIGDataBackend
public boolean checkMembership(int level, boolean is_member)
{
if (deleted)
return false;
if (Capability.exemptFromMembershipRequirement(level))
return true;
return !members_only || is_member;
@ -363,31 +368,39 @@ class SIGCoreData implements SIGData, SIGDataBackend
public boolean canReadSIGSubObjects(int level)
{
if (deleted)
return false;
return (level>=read_level);
} // end canReadSIGSubObjects
public boolean canModifySIGProfile(int level)
{
if (deleted)
return false;
return (level>=write_level);
} // end canModifySIGProfile
public boolean canCreateSIGSubObjects(int level)
{
if (deleted)
return false;
return (level>=create_level);
} // end canCreateSIGSubObjects
public boolean canDeleteSIG(int level)
{
if (deleted)
return false;
return (level>=delete_level);
} // end canDeleteSIG
public boolean canJoinSIG(int uid, int level)
{
if (level<join_level)
if (deleted || (level<join_level))
return false; // rejected on a level basis
Connection conn = null; // database connection
@ -423,6 +436,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public synchronized void putContactInfo(UserBackend user, ContactInfo ci) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
Connection conn = null; // database connection
AuditRecord ar = null; // audit record
@ -488,6 +504,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public synchronized void putFeatureSet(UserBackend user, BitSet set) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
Connection conn = null; // database connection
AuditRecord ar = null; // audit record
@ -583,6 +602,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public synchronized void setName(UserBackend user, String name) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
Connection conn = null; // database connection
AuditRecord ar = null; // audit record
@ -629,6 +651,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public synchronized void setAlias(UserBackend user, String alias) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
Connection conn = null; // database connection
AuditRecord ar = null; // audit record
@ -676,6 +701,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public synchronized void setCategoryID(UserBackend user, int catid) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
Connection conn = null; // database connection
AuditRecord ar = null; // audit record
@ -723,6 +751,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public synchronized void setSynopsis(String synopsis) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
Connection conn = null; // database connection
try
@ -755,6 +786,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public synchronized void setLanguage(String language) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
Connection conn = null; // database connection
try
@ -787,6 +821,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public synchronized void setRules(String rules) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
Connection conn = null; // database connection
try
@ -819,6 +856,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public synchronized void touch() throws DataException
{
if (deleted)
return; // no need to touch anything
Connection conn = null; // database connection
try
@ -862,6 +902,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public synchronized void setHideFlags(UserBackend user, boolean directory, boolean search)
throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
Connection conn = null; // database connection
AuditRecord ar = null; // audit record
@ -917,6 +960,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public synchronized void setMembersOnly(UserBackend user, boolean flag) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
Connection conn = null; // database connection
AuditRecord ar = null; // audit record
@ -970,6 +1016,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public synchronized void setInitialFeatureIndex(short ndx) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
Connection conn = null; // database connection
try
@ -1002,6 +1051,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public String getJoinKey() throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
Connection conn = null; // database connection
try
@ -1038,6 +1090,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public synchronized void setJoinKey(UserBackend user, String key) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
Connection conn = null; // database connection
AuditRecord ar = null; // audit record
@ -1115,6 +1170,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public synchronized void setSecurityLevels(UserBackend user, int read, int write, int create, int delete,
int join) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
Connection conn = null; // database connection
AuditRecord ar = null; // audit record
@ -1182,6 +1240,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public synchronized void setMembership(UserBackend user, int uid, int grant_level, boolean locked,
boolean hidden) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
Connection conn = null; // database connection
AuditRecord ar = null; // successful audit record
@ -1274,6 +1335,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public int getMemberCount(boolean include_hidden) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
Connection conn = null; // database connection
try
@ -1311,6 +1375,8 @@ class SIGCoreData implements SIGData, SIGDataBackend
public boolean isFeaturePresent(String symbol)
{
if (deleted)
return false;
int ndx = engine.getFeatureIndexBySymbol(symbol);
if (ndx>=0)
return features.get(ndx);
@ -1321,6 +1387,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public synchronized ConferenceSIGContext getConferenceDataObject(int confid) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
if (logger.isDebugEnabled())
logger.debug("getConferenceDataObject(" + confid + ")...");
@ -1367,6 +1436,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public ConferenceSIGContext createConference(SIGBackend sig, String name, String alias, String description,
boolean pvt, boolean hide_list) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
ReturnConfSeq rcs = ConferenceCoreData.createConference(engine,sig,datapool,name,alias,description,
pvt,hide_list,host_uid);
ConferenceData cdata = rcs.getConference();
@ -1399,6 +1471,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public List searchForMembers(int field, int mode, String term, int offset, int count,
boolean include_hidden) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
if (logger.isDebugEnabled())
logger.debug("Member search: SIG = " + sigid + ", field = " + field + ", mode = " + mode + ", term '"
+ term + "', offset = " + offset + ", count = " + count);
@ -1501,6 +1576,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public int getSearchMemberCount(int field, int mode, String term, boolean include_hidden)
throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
if (logger.isDebugEnabled())
logger.debug("User search: SIG = " + sigid + ", field = " + field + ", mode = " + mode + ", term '"
+ term + "'");
@ -1590,6 +1668,9 @@ class SIGCoreData implements SIGData, SIGDataBackend
public List getMemberList(boolean include_hidden) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
if (logger.isDebugEnabled())
logger.debug("Member list: SIG = " + sigid);
@ -1645,6 +1726,139 @@ class SIGCoreData implements SIGData, SIGDataBackend
} // end getMemberList
public int getMemberLevel(int uid) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
if (logger.isDebugEnabled())
logger.debug("Member level: SIG = " + sigid + ", user = " + uid);
Connection conn = null; // pooled database connection
try
{ // get a database connection
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
// a relatively simple search
StringBuffer sql = new StringBuffer("SELECT granted_lvl FROM sigmember WHERE sigid = ");
sql.append(sigid).append(" AND uid = ").append(uid).append(';');
if (logger.isDebugEnabled())
logger.debug("SQL: " + sql.toString());
ResultSet rs = stmt.executeQuery(sql.toString());
if (rs.next())
return rs.getInt(1);
else
return -1;
} // end try
catch (SQLException e)
{ // turn SQLException into data exception
logger.error("DB error reading member level: " + e.getMessage(),e);
throw new DataException("unable to retrieve member information: " + e.getMessage(),e);
} // end catch
finally
{ // make sure we release the connection before we go
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
} // end getMemberLevel
public void delete(UserBackend user) throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
if (logger.isDebugEnabled())
logger.debug("Delete SIG: SIG = " + sigid);
Connection conn = null; // database connection
AuditRecord ar = null; // audit record
int conf_count, conf_max;
try
{ // get a database connection
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
// lock the tables we need to reference immediately
stmt.executeUpdate("LOCK TABLES sigs WRITE, sigmember WRITE, sigtoconf READ;");
try
{ // first delete the SIG record itself
stmt.executeUpdate("DELETE FROM sigs WHERE sigid = " + sigid + ";");
// now delete the members list
stmt.executeUpdate("DELETE FROM sigmember WHERE sigid = " + sigid + ";");
// determine the number of conferences in this SIG, and the maximum conference ID
ResultSet rs = stmt.executeQuery("SELECT COUNT(*), MAX(confid) FROM sigtoconf WHERE sigid = "
+ sigid + ";");
if (!(rs.next()))
throw new InternalStateError("SIGCoreData.delete screwup on conference SELECT");
conf_count = rs.getInt(1);
conf_max = rs.getInt(2);
// record that we're now deleted
created = null;
last_access = null;
last_update = null;
contactid = -1;
name = null;
language = null;
synopsis = null;
rules = null;
alias = null;
deleted = true;
} // end try
finally
{ // make sure to unlock the tables before we go
Statement ulk_stmt = conn.createStatement();
ulk_stmt.executeUpdate("UNLOCK TABLES;");
} // end finally
// create an audit record indicating what happened
ar = new AuditRecord(AuditRecord.DELETE_SIG,user.realUID(),user.userRemoteAddress(),sigid);
} // end try
catch (SQLException e)
{ // database error - this is a DataException
logger.error("DB error deleting SIG: " + e.getMessage(),e);
throw new DataException("unable to delete SIG: " + e.getMessage(),e);
} // end catch
finally
{ // make sure the connection is released before we go
try
{ // save off the audit record before we go, though
if ((ar!=null) && (conn!=null))
ar.store(conn);
} // end try
catch (SQLException e)
{ // we couldn't store the audit record!
logger.error("DB error saving audit record: " + e.getMessage(),e);
} // end catch
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
// Delete the rest of the gunk in the background; use another thread to do it.
BackgroundSIGPurge purger = new BackgroundSIGPurge(datapool,user,sigid,conf_count,conf_max,conf_objects);
Thread thrd = new Thread(purger);
thrd.setPriority(Thread.NORM_PRIORITY-1);
thrd.start();
} // end delete
/*--------------------------------------------------------------------------------
* Implementations from interface SIGDataBackend
*--------------------------------------------------------------------------------

View File

@ -52,7 +52,7 @@ public interface SIGData extends ReferencedData
public abstract Date getLastUpdateDate();
public abstract void testMembership(int level, boolean is_member) throws AccessError;
public abstract void testMembership(int level, boolean is_member) throws DataException, AccessError;
public abstract boolean checkMembership(int level, boolean is_member);
@ -146,4 +146,8 @@ public interface SIGData extends ReferencedData
public abstract List getMemberList(boolean include_hidden) throws DataException;
public abstract int getMemberLevel(int uid) throws DataException;
public abstract void delete(UserBackend user) throws DataException;
} // end interface SIGData

View File

@ -80,6 +80,7 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
private boolean locked; // is our membership locked?
private SIGSimpleDataCache cache; // cache object for name and alias
private SIGData sigdata = null; // the actual SIG data
private boolean deleted = false; // has this SIG been deleted?
/*--------------------------------------------------------------------------------
* Constructors
@ -174,6 +175,8 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
{
if (sigdata==null)
{ // attempt to load the SIGDataObject
if (deleted)
throw new DataException("This SIG has been deleted.");
sigdata = engine.getSIGDataObject(sigid);
// clear cache when we get the real sigdata
@ -189,6 +192,8 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
{
if (sigdata==null)
{ // we need to load the SIGData...
if (deleted)
return null; // we're deleted
try
{ // attempt to load the SIGDataObject
sigdata = engine.getSIGDataObject(sigid);
@ -212,6 +217,9 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
private void testConferenceAccess() throws DataException, AccessError
{
if (deleted)
throw new DataException("This SIG has been deleted.");
if (!(getSIGData().isFeaturePresent("CONF")))
{ // the SIG doesn't use conferencing
logger.error("the SIG doesn't use conferencing");
@ -340,6 +348,8 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
public CategoryDescriptor getCategory() throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
return new CategoryDescriptorImpl(datapool,getSIGData().getCategoryID(),
Capability.hideHiddenCategories(user.realBaseLevel()));
@ -367,6 +377,9 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
public UserProfile getHostProfile() throws DataException
{
if (deleted)
throw new DataException("This SIG has been deleted.");
Connection conn = null; // pooled database connection
try
@ -942,6 +955,9 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
public void join(String joinkey) throws DataException, AccessError
{
if (deleted)
throw new DataException("This SIG has been deleted.");
if (is_member)
{ // we're already a member!
logger.info("attempting to join SIG, but already a member");
@ -986,6 +1002,9 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
public void unjoin() throws DataException, AccessError
{
if (deleted)
throw new DataException("This SIG has been deleted.");
if (!is_member)
{ // we're already a member!
logger.info("attempting to unjoin SIG, but not currently a member");
@ -1016,13 +1035,13 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
public boolean canUnjoin()
{
return is_member && !locked;
return !deleted && is_member && !locked;
} // end canUnjoin
public boolean canJoin()
{
if (is_member)
if (is_member || deleted)
return false;
SIGData sd = getSIGDataNE();
if (sd!=null)
@ -1138,6 +1157,70 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
} // end canManageConferences
public int getMemberLevel(int uid) throws DataException, AccessError
{
getSIGData().testMembership(level,is_member);
return getSIGData().getMemberLevel(uid);
} // end getMemberLevel
public void setMembership(int uid, int new_level) throws DataException, AccessError
{
getSIGData().testMembership(level,is_member);
if (!(getSIGData().canModifySIGProfile(level)))
{ // this user can't modify the SIG feature set
logger.error("user not permitted to modify the SIG's membership");
if (logger.isDebugEnabled())
logger.debug("(your level = " + level + ")");
throw new AccessError("You are not permitted to modify the SIG's membership.");
} // end if
// actually set the data in the database
getSIGData().setMembership(user,uid,new_level,false,false);
if (uid==user.realUID()) // and update our internal data store
setMemberValues(new_level,(new_level>0),false);
} // end setMembership
public boolean canDelete()
{
SIGData sd = getSIGDataNE();
if (sd==null)
return false;
if (!(sd.checkMembership(level,is_member)))
return false;
return sd.canDeleteSIG(level);
} // end canDelete
public void delete() throws DataException, AccessError
{
SIGData my_sig = getSIGData();
my_sig.testMembership(level,is_member);
if (!(my_sig.canDeleteSIG(level)))
{ // no, repeat NO, way can we delete the SIG!
logger.error("user not permitted to delete SIG");
throw new AccessError("You are not permitted to delete this SIG.");
} // end if
// call the methods required to delete the SIG
my_sig.delete(user);
engine.detachSIGDataObject(sigid);
// flag that we've been deleted
cache = null;
deleted = true;
// detach our references from the lower-level object
sigdata = null;
my_sig.rd_release();
} // end delete
/*--------------------------------------------------------------------------------
* Implementations from interface UserBackend
*--------------------------------------------------------------------------------

View File

@ -868,6 +868,26 @@ class UserContextImpl implements UserContext, UserBackend
} // end getConferenceHotlist
public boolean hasAdminAccess()
{
return Capability.canAdministerSystem(level);
} // end hasAdminAccess
public AdminOperations getAdminInterface() throws AccessError
{
if (!(Capability.canAdministerSystem(level)))
{ // you don't have access to get this!
logger.error("user does not have access to do system admin stuff");
throw new AccessError("You are not permitted to administer the server.");
} // end if
// create the return object
return new AdminOperationsImpl(engine,this,datapool);
} // end getAdminInterface
/*--------------------------------------------------------------------------------
* Implementations from interface UserBackend
*--------------------------------------------------------------------------------

View File

@ -1176,10 +1176,9 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
while (rs.next())
{ // add all the found users to the list
UserFoundImpl ufi = new UserFoundImpl(rs.getInt(1),rs.getString(2),rs.getString(3),rs.getString(4),
UserFound uf = new UserFoundImpl(rs.getInt(1),rs.getString(2),rs.getString(3),rs.getString(4),
rs.getString(5),rs.getString(6),rs.getString(7),rs.getString(8));
UserFound tmp = (UserFound)ufi;
rc.add(tmp);
rc.add(uf);
} // end while

View File

@ -43,6 +43,7 @@ public interface Audit
public static final int SIG_MEMBERS_ONLY = 209;
public static final int SIG_JOIN_KEY = 210;
public static final int SIG_SECURITY = 211;
public static final int DELETE_SIG = 212;
// Codes 301-400 - Conference events
public static final int CREATE_CONF = 301;

View File

@ -97,4 +97,10 @@ public class Capability implements SecLevels
} // end hideHiddenConferences
public static boolean canAdministerSystem(int level)
{
return (level>=GLOBAL_ANYADMIN);
} // end canAdministerSystem
} // end class Capability

View File

@ -7,7 +7,7 @@
* 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 Community System.
* 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
@ -66,6 +66,7 @@ public class Role implements Comparable, SecLevels
private static Role not_in_list = null;
private static Role no_access = null;
private static Role unrestricted_user = null;
private static Role sig_host = null;
private static Vector global_low = null;
private static Vector global_high = null;
private static Vector sig_low = null;
@ -142,7 +143,8 @@ public class Role implements Comparable, SecLevels
sig_high = new Vector(3);
sig_high.addElement(new Role(SIG_ANYADMIN,"Any SIG Administrator"));
sig_high.addElement(new Role(SIG_COHOST,"SIG Co-Host"));
sig_high.addElement(new Role(SIG_HOST,"SIG Host"));
sig_host = new Role(SIG_HOST,"SIG Host");
sig_high.addElement(sig_host);
sig_high.trimToSize();
} // end if
@ -282,6 +284,26 @@ public class Role implements Comparable, SecLevels
} // end getSIGJoinList
public static List getSIGMemberLevelChoices()
{
initAllSets();
Vector rc = new Vector();
rc.add(not_in_list);
rc.addAll(global_low);
rc.addAll(sig_low);
rc.add(unrestricted_user);
rc.addAll(sig_high);
rc.remove(rc.size()-1);
return new ReadOnlyVector(rc);
} // end getSIGMemberLevelChoices
public static Role getSIGHostRole()
{
return sig_host;
} // end getSIGHostRole
public static List getConferenceReadList()
{
initAllSets();

View File

@ -109,9 +109,11 @@ public class PostMessage extends VeniceServlet
request.getParameter("next"),getPostNumber(request,on_error),
yes.equals(request.getParameter("attach")));
if (isImageButtonClicked(request,"post") || isImageButtonClicked(request,"postnext"))
if ( isImageButtonClicked(request,"post") || isImageButtonClicked(request,"postnext")
|| isImageButtonClicked(request,"posttopics"))
{ // post the message, and then either go back to the same topic or on to the next one
boolean go_next = isImageButtonClicked(request,"postnext");
boolean go_topics = isImageButtonClicked(request,"posttopics");
int pn = getPostNumber(request,on_error);
try
@ -124,6 +126,9 @@ public class PostMessage extends VeniceServlet
// post the darn thing!
TopicMessageContext msg = topic.postNewMessage(0,request.getParameter("pseud"),raw_postdata);
if (go_topics) // jump back to the topic list, puhleaze
throw new RedirectResult("confdisp?sig=" + sig.getSIGID() + "&conf=" + conf.getConfID());
short next;
try
{ // attempt to get the value of the "next topic" parameter

View File

@ -18,6 +18,7 @@
package com.silverwrist.venice.servlets;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.log4j.*;
@ -33,6 +34,9 @@ public class SIGAdmin extends VeniceServlet
*--------------------------------------------------------------------------------
*/
private static final String DELETE_CONFIRM_ATTR = "servlets.SIGAdmin.delete.confirm";
private static final String DELETE_CONFIRM_PARAM = "confirm";
private static Category logger = Category.getInstance(SIGAdmin.class.getName());
/*--------------------------------------------------------------------------------
@ -224,6 +228,76 @@ public class SIGAdmin extends VeniceServlet
} // end if ("T" command)
if (cmd.equals("M"))
{ // "M" = Set Membership
if (!(sig.canModifyProfile()))
{ // no access - sorry man
logger.error("tried to call up membership set screen without access...naughty naughty!");
return new ErrorBox("Unauthorized","You do not have access to modify this SIG's membership.",on_error);
} // end else
try
{ // display the conference member list!
SIGMembership m = new SIGMembership(engine,sig);
m.doSIGMemberList();
setMyLocation(request,"sigadmin?sig=" + sig.getSIGID() + "&cmd=M");
return m;
} // end try
catch (DataException de)
{ // something wrong in the database
return new ErrorBox("Database Error","Database error listing SIG members: " + de.getMessage(),
on_error);
} // end catch
} // end if ("M" command)
if (cmd.equals("DEL"))
{ // "DEL" = "Delete SIG" (requires a confirmation)
if (!(sig.canDelete()))
{ // we can't delete the SIG, so what are we doing here?
logger.error("you can't delete the SIG - not gonna do it, wouldn't be prudent");
return new ErrorBox("Access Error","You do not have permission to delete this SIG.",on_error);
} // end if
if (ConfirmBox.isConfirmed(request,DELETE_CONFIRM_ATTR,DELETE_CONFIRM_PARAM))
{ // we are confirmed - delete the SIG!
try
{ // delete the SIG!
sig.delete();
} // end try
catch (DataException de)
{ // something wrong in the database
logger.error("Database error deleting SIG: " + de.getMessage(),de);
return new ErrorBox("Database Error","Database error deleting SIG: " + de.getMessage(),on_error);
} // end catch
catch (AccessError ae)
{ // access error changing the SIG values
logger.error("Access error deleting SIG: " + ae.getMessage(),ae);
return new ErrorBox("Access Error",ae.getMessage(),on_error);
} // end catch
// the SIG is now GONE - there's noplace else to go but back to the Top page
throw new RedirectResult("top");
} // end if
else
{ // throw up a confirm box to let the user think it over
String message = "You are about to permanently delete the \"" + sig.getName() + "\" SIG, including "
+ "all conferences and other resources it contains! Are you sure you want to do this?";
return new ConfirmBox(request,DELETE_CONFIRM_ATTR,DELETE_CONFIRM_PARAM,"Delete Conference",message,
on_error + "&cmd=DEL",on_error);
} // end else
} // end if ("DEL" command)
// all unknown requests get turned into menu display requests
if (!(sig.canAdministerSIG()))
{ // no access - sorry buddy
@ -316,6 +390,149 @@ public class SIGAdmin extends VeniceServlet
} // end if ("P" command)
if (cmd.equals("M"))
{ // "M" = Modify SIG Membership
on_error += "&cmd=M";
setMyLocation(request,on_error);
if (!(sig.canModifyProfile()))
{ // no access - sorry, dude
logger.error("tried to call up SIG membership screen without access...naughty naughty!");
return new ErrorBox("Unauthorized","You do not have access to modify this SIG's membership.",on_error);
} // end if
if (isImageButtonClicked(request,"update"))
{ // the "update" command that changes all the security levels
HashMap org_vals = new HashMap();
HashMap new_vals = new HashMap();
try
{ // retrieve all parameters and filter them for the levels
Enumeration p_names = request.getParameterNames();
while (p_names.hasMoreElements())
{ // examine each parameter name in turn
String p_name = (String)(p_names.nextElement());
if (p_name.startsWith("zxcur_"))
{ // this is a current value (from a hidden field)
int uid = Integer.parseInt(p_name.substring(6));
int level = Integer.parseInt(request.getParameter(p_name));
org_vals.put(new Integer(uid),new Integer(level));
} // end if
else if (p_name.startsWith("zxnew_"))
{ // this is a new value (from a dropdown list box)
int uid = Integer.parseInt(p_name.substring(6));
int level = Integer.parseInt(request.getParameter(p_name));
new_vals.put(new Integer(uid),new Integer(level));
} // end else if
} // end while
if (org_vals.size()!=new_vals.size())
{ // we read the wrong number of parameters - this is bad
logger.error("level parameters mismatch (" + org_vals.size() + " old, " + new_vals.size()
+ " new)");
return new ErrorBox(null,"Invalid parameters.",on_error);
} // end if
} // end try
catch (NumberFormatException nfe)
{ // error converting the parameters
logger.error("got number format exception parsing a level parameter");
return new ErrorBox(null,"Invalid parameter conversion.",on_error);
} // end catch
try
{ // loop through the hashmaps and set the value
Iterator it = org_vals.keySet().iterator();
while (it.hasNext())
{ // extract the UID, old level, and new level
Integer uid = (Integer)(it.next());
Integer org_level = (Integer)(org_vals.get(uid));
Integer new_level = (Integer)(new_vals.get(uid));
if (new_level==null)
{ // whoops
logger.error("new SIG level not found for uid " + uid.intValue());
return new ErrorBox(null,"Invalid new level parameter.",on_error);
} // end if
int new_level_x = new_level.intValue();
if (new_level_x==0)
new_level_x = -1;
// call down to set the membership level
if (org_level.intValue()!=new_level_x)
{ // we need to reset the SIG membership
if (logger.isDebugEnabled())
logger.debug("resetting SIG member level for uid " + uid.intValue() + "(old = "
+ org_level.intValue() + ", new = " + new_level_x + ")");
sig.setMembership(uid.intValue(),new_level_x);
} // end if
} // end while
} // end try
catch (AccessError ae)
{ // some sort of access error - display an error dialog
logger.error("AccessError on sig.setMembership: " + ae.getMessage(),ae);
return new ErrorBox("Access Error",ae.getMessage(),on_error);
} // end catch
catch (DataException de)
{ // database error creating the conference
logger.error("DataException on sig.setMembership: " + de.getMessage(),de);
return new ErrorBox("Database Error","Database error setting memberships: " + de.getMessage(),
on_error);
} // end catch
// trap back to the SIG membership display
throw new RedirectResult(on_error);
} // end if ("update" clicked)
if ( isImageButtonClicked(request,"search") || isImageButtonClicked(request,"previous")
|| isImageButtonClicked(request,"next"))
{ // create the new dialog box
SIGMembership m = new SIGMembership(engine,sig);
try
{ // perform the search!
m.doSearch(request);
} // end try
catch (ValidationException ve)
{ // validation error - throw it back to the user
return new ErrorBox(null,ve.getMessage() + " Please try again.",on_error);
} // end catch
catch (AccessError ae)
{ // some sort of access error - display an error dialog
return new ErrorBox("Access Error",ae.getMessage(),on_error);
} // end catch
catch (DataException de)
{ // database error creating the conference
return new ErrorBox("Database Error","Database error searching for users: " + de.getMessage(),
on_error);
} // end catch
return m;
} // end if (search function clicked)
// we don't know what button was pressed
logger.error("no known button click on SIGAdmin.doPost, cmd=M");
return new ErrorBox("Internal Error","Unknown command button pressed",on_error);
} // end if ("M" command)
// on unknown command, redirect to the GET function
return doVeniceGet(request,engine,user,rdat);

View File

@ -0,0 +1,95 @@
/*
* 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) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.servlets;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.log4j.*;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.servlets.format.*;
public class SystemAdmin extends VeniceServlet
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Category logger = Category.getInstance(SIGAdmin.class.getName());
/*--------------------------------------------------------------------------------
* Internal functions
*--------------------------------------------------------------------------------
*/
private SystemAdminTop makeSystemAdminTop() throws ServletException
{
final String desired_name = "SystemAdminTop";
MenuPanelCache cache = MenuPanelCache.getMenuPanelCache(getServletContext());
if (!(cache.isCached(desired_name)))
{ // create a template and save it off
SystemAdminTop template = new SystemAdminTop();
cache.saveTemplate(template);
} // end if
// return a new copy
return (SystemAdminTop)(cache.getNewMenuPanel(desired_name));
} // end makeSystemAdminTop
/*--------------------------------------------------------------------------------
* Overrides from class HttpServlet
*--------------------------------------------------------------------------------
*/
public String getServletInfo()
{
String rc = "SystemAdmin servlet - Administrative functions for the entire system\n"
+ "Part of the Venice Web Communities System\n";
return rc;
} // end getServletInfo
/*--------------------------------------------------------------------------------
* Overrides from class VeniceServlet
*--------------------------------------------------------------------------------
*/
protected VeniceContent doVeniceGet(HttpServletRequest request, VeniceEngine engine,
UserContext user, RenderData rdat)
throws ServletException, IOException, VeniceServletResult
{
// decide what to do based on the "cmd" parameter
String cmd = getStandardCommandParam(request);
if (logger.isDebugEnabled())
logger.debug("SystemAdmin/doGet command value = " + cmd);
// TODO: command handling
if (!(user.hasAdminAccess()))
return new ErrorBox("Access Error","You do not have permission to administer the system.",null);
setMyLocation(request,"sysadmin");
return makeSystemAdminTop();
} // end doVeniceGet
} // end class SystemAdmin

View File

@ -21,6 +21,7 @@ import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.ValidationException;
import com.silverwrist.venice.security.Role;
import com.silverwrist.venice.core.*;
@ -326,7 +327,7 @@ public class ConferenceMembership implements JSPRender, SearchMode
out.write("<OPTION VALUE=\"" + r.getLevel() + "\"");
if (r.getLevel()==cur_level)
out.write(" SELECTED");
out.write(">" + r.getName() + "</OPTION>\n");
out.write(">" + StringUtil.encodeHTML(r.getName()) + "</OPTION>\n");
} // end while

View File

@ -7,7 +7,7 @@
* 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 Community System.
* 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

View File

@ -7,7 +7,7 @@
* 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 Community System.
* 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

View File

@ -0,0 +1,333 @@
/*
* 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) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.servlets.format;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.ValidationException;
import com.silverwrist.venice.security.Role;
import com.silverwrist.venice.core.*;
public class SIGMembership implements JSPRender, SearchMode
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
// Attribute name for request attribute
protected static final String ATTR_NAME = "com.silverwrist.venice.content.ConferenceMembership";
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private VeniceEngine engine; // reference to the engine
private SIGContext sig; // the SIG we're in
private List display_list = null; // list of members to display
private boolean sig_members = false; // is this a list of SIG members?
private int field = -1; // search field
private int mode = -1; // search mode
private String term = null; // search term
private int offset = 0; // search result offset
private int find_count = -1; // search results count
private List role_choices; // the list of security roles
private Role role_sig_host; // the "SIG Host" security role
/*--------------------------------------------------------------------------------
* Constructors
*--------------------------------------------------------------------------------
*/
public SIGMembership(VeniceEngine engine, SIGContext sig)
{
this.engine = engine;
this.sig = sig;
this.role_choices = Role.getSIGMemberLevelChoices();
this.role_sig_host = Role.getSIGHostRole();
} // end constructor
/*--------------------------------------------------------------------------------
* Internal functions
*--------------------------------------------------------------------------------
*/
private static int getParamInt(ServletRequest request, String name, int default_val)
{
String str = request.getParameter(name);
if (str==null)
return -1;
try
{ // parse the integer value
return Integer.parseInt(str);
} // end try
catch (NumberFormatException nfe)
{ // in case of conversion error, return default
return default_val;
} // end catch
} // end getParamInt
private static boolean isImageButtonClicked(ServletRequest request, String name)
{
String val = request.getParameter(name + ".x");
return (val!=null);
} // end isImageButtonClicked
/*--------------------------------------------------------------------------------
* External static functions
*--------------------------------------------------------------------------------
*/
public static SIGMembership retrieve(ServletRequest request)
{
return (SIGMembership)(request.getAttribute(ATTR_NAME));
} // end retrieve
/*--------------------------------------------------------------------------------
* Implementations from interface VeniceContent
*--------------------------------------------------------------------------------
*/
public String getPageTitle(RenderData rdat)
{
return "Membership in SIG " + sig.getName();
} // end getPageTitle
/*--------------------------------------------------------------------------------
* Implementations from interface JSPRender
*--------------------------------------------------------------------------------
*/
public void store(ServletRequest request)
{
request.setAttribute(ATTR_NAME,this);
} // end store
public String getTargetJSPName()
{
return "sig_member.jsp";
} // end getTargetJSPName
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public void doSIGMemberList() throws DataException
{
this.display_list = sig.getMemberList();
this.sig_members = true;
this.term = "";
} // end doSIGMemberList
public void doSearch(ServletRequest request) throws ValidationException, DataException, AccessError
{
// Validate the search field parameter.
field = getParamInt(request,"field",FIELD_USER_NAME);
if ( (field!=FIELD_USER_NAME) && (field!=FIELD_USER_DESCRIPTION) && (field!=FIELD_USER_GIVEN_NAME)
&& (field!=FIELD_USER_FAMILY_NAME))
throw new ValidationException("The field search parameter is not valid.");
// Validate the search mode parameter.
mode = getParamInt(request,"mode",SEARCH_PREFIX);
if ((mode!=SEARCH_PREFIX) && (mode!=SEARCH_SUBSTRING) && (mode!=SEARCH_REGEXP))
throw new ValidationException("The search mode parameter is not valid.");
// Retrieve the search term parameter.
term = request.getParameter("term");
if (term==null)
term = "";
// Retrieve the offset and find count parameters.
offset = getParamInt(request,"ofs",0);
find_count = getParamInt(request,"fcount",-1);
// Adjust the search return offset based on the command button click.
int count = getNumResultsDisplayed();
if (isImageButtonClicked(request,"search"))
offset = 0;
else if (isImageButtonClicked(request,"previous"))
{ // adjust the offset in the reverse direction
offset -= count;
if (offset<0)
offset = 0;
} // end else if
else if (isImageButtonClicked(request,"next"))
offset += count; // go forwards instead
else
throw new ValidationException("Unable to determine what action triggered the form.");
// Perform the search!
List intermediate = engine.searchForUsers(field,mode,term,offset,count);
if (find_count<0)
find_count = engine.getSearchUserCount(field,mode,term);
// Create the real display list by getting the SIG security levels.
Iterator it = intermediate.iterator();
Vector rc = new Vector(count+1);
while (it.hasNext())
{ // loop around and find the member level of every one
UserFound uf = (UserFound)(it.next());
int new_level = sig.getMemberLevel(uf.getUID());
if (new_level==-1)
new_level = 0;
rc.add(uf.createNewLevel(new_level));
} // end while
display_list = rc; // save display list for display
} // end doSearch
public int getSIGID()
{
return sig.getSIGID();
} // end getSIGID
public String getSIGName()
{
return sig.getName();
} // end getSIGName
public String getLocator()
{
return "sig=" + sig.getSIGID();
} // end getLocator
public boolean displayList()
{
if ((display_list==null) || (display_list.size()==0))
return false;
if (sig_members && (display_list.size()>engine.getMaxNumSIGMembersDisplay()))
return false;
return true;
} // end displayList
public boolean isSIGMemberList()
{
return sig_members;
} // end isSIGMemberList
public int getSearchField()
{
return field;
} // end getSearchField
public int getSearchMode()
{
return mode;
} // end getSearchMode
public boolean searchFieldIs(int value)
{
return (field==value);
} // end searchFieldIs
public boolean searchModeIs(int value)
{
return (mode==value);
} // end searchModeIs
public String getSearchTerm()
{
return term;
} // end getSearchTerm
public int getFindCount()
{
return find_count;
} // end getFindCount
public int getOffset()
{
return offset;
} // end getOffset
public int getSize()
{
return display_list.size();
} // end getSize
public int getNumResultsDisplayed()
{
return engine.getStdNumSearchResults();
} // end getNumResultsDisplayed
public UserFound getItem(int ndx)
{
return (UserFound)(display_list.get(ndx));
} // end getItem
public void outputDropDown(Writer out, int uid, int cur_level) throws IOException
{
out.write("<INPUT TYPE=HIDDEN NAME=\"zxcur_" + uid + "\" VALUE=\"" + cur_level + "\">\n");
out.write("<SELECT NAME=\"zxnew_" + uid + "\" SIZE=1>\n");
if (cur_level==role_sig_host.getLevel()) // cheat and put in just the host level
out.write("<OPTION VALUE=\"" + role_sig_host.getLevel() + "\" SELECTED>"
+ StringUtil.encodeHTML(role_sig_host.getName()) + "</OPTION>\n");
else
{ // display all the level choices properly
Iterator it = role_choices.iterator();
while (it.hasNext())
{ // output the <OPTION> lines for the dropdown
Role r = (Role)(it.next());
out.write("<OPTION VALUE=\"" + r.getLevel() + "\"");
if (r.getLevel()==cur_level)
out.write(" SELECTED");
out.write(">" + StringUtil.encodeHTML(r.getName()) + "</OPTION>\n");
} // end while
} // end else
out.write("</SELECT>\n");
} // end outputDropDown
} // end class SIGMembership

View File

@ -0,0 +1,57 @@
/*
* 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) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.servlets.format;
import java.util.*;
import java.io.Writer;
import java.io.IOException;
public class SystemAdminTop extends ContentMenuPanel
{
/*--------------------------------------------------------------------------------
* Constructors
*--------------------------------------------------------------------------------
*/
public SystemAdminTop()
{
super("System Administration",null);
addChoice("Set Global Parameters","TODO");
addChoice("View/Edit Banned Users","TODO");
addChoice("User Account Management","TODO");
} // end constructor
protected SystemAdminTop(SystemAdminTop other)
{
super(other);
} // end constructor
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public Object clone()
{
return new SystemAdminTop(this);
} // end clone
} // end class SystemAdminTop

View File

@ -325,6 +325,9 @@
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_post_go_next.gif") %>" ALT="Post & Go Next"
NAME="postnext" WIDTH=80 HEIGHT=24 BORDER=0>
<% } // end if %>
&nbsp;
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_post_go_topics.gif") %>" ALT="Post & Go Topics"
NAME="posttopics" WIDTH=80 HEIGHT=24 BORDER=0>
</TD></TR>
</TABLE>
</FORM>

View File

@ -73,6 +73,9 @@
NAME="postnext" WIDTH=80 HEIGHT=24 BORDER=0>
<% } // end if %>
&nbsp;
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_post_go_topics.gif") %>" ALT="Post & Go Topics"
NAME="posttopics" WIDTH=80 HEIGHT=24 BORDER=0>
&nbsp;
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_cancel.gif") %>" ALT="Cancel"
NAME="cancel" WIDTH=80 HEIGHT=24 BORDER=0>
</TD></TR>

151
web/format/sig_member.jsp Normal file
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) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
Contributor(s):
--%>
<%@ page import = "java.util.*" %>
<%@ page import = "com.silverwrist.util.StringUtil" %>
<%@ page import = "com.silverwrist.venice.core.*" %>
<%@ page import = "com.silverwrist.venice.servlets.Variables" %>
<%@ page import = "com.silverwrist.venice.servlets.format.*" %>
<%
SIGMembership data = SIGMembership.retrieve(request);
Variables.failIfNull(data);
RenderData rdat = RenderConfig.createRenderData(application,request,response);
%>
<% rdat.writeContentHeader(out,"Set SIG Membership:",data.getSIGName()); %>
<%= rdat.getStdFontTag(null,2) %>
<A HREF="<%= rdat.getEncodedServletPath("sigadmin?sig=" + data.getSIGID()) %>">Return to SIG
Administration Menu</A>
</FONT><P>
<%= rdat.getStdFontTag(null,3) %><B>Find Users:</B></FONT><P>
<FORM METHOD="POST" ACTION="<%= rdat.getEncodedServletPath("sigadmin") %>">
<INPUT TYPE="HIDDEN" NAME="sig" VALUE="<%= data.getSIGID() %>">
<INPUT TYPE="HIDDEN" NAME="cmd" VALUE="M">
<INPUT TYPE="HIDDEN" NAME="ofs" VALUE="0">
<%= rdat.getStdFontTag(null,2) %>
Display all users whose&nbsp;&nbsp;
<SELECT NAME="field" SIZE=1>
<OPTION VALUE="<%= SearchMode.FIELD_USER_NAME %>"
<% if (data.searchFieldIs(SearchMode.FIELD_USER_NAME)) { %>SELECTED<% } %> >user name</OPTION>
<OPTION VALUE="<%= SearchMode.FIELD_USER_DESCRIPTION %>"
<% if (data.searchFieldIs(SearchMode.FIELD_USER_DESCRIPTION)) { %>SELECTED<% } %> >description</OPTION>
<OPTION VALUE="<%= SearchMode.FIELD_USER_GIVEN_NAME %>"
<% if (data.searchFieldIs(SearchMode.FIELD_USER_GIVEN_NAME)) { %>SELECTED<% } %> >first name</OPTION>
<OPTION VALUE="<%= SearchMode.FIELD_USER_FAMILY_NAME %>"
<% if (data.searchFieldIs(SearchMode.FIELD_USER_FAMILY_NAME)) { %>SELECTED<% } %> >last name</OPTION>
</SELECT><BR>
<SELECT NAME="mode" SIZE=1>
<OPTION VALUE="<%= SearchMode.SEARCH_PREFIX %>"
<% if (data.searchModeIs(SearchMode.SEARCH_PREFIX)) { %>SELECTED<% } %> >starts with the string</OPTION>
<OPTION VALUE="<%= SearchMode.SEARCH_SUBSTRING %>"
<% if (data.searchModeIs(SearchMode.SEARCH_SUBSTRING)) { %>SELECTED<% } %> >contains the string</OPTION>
<OPTION VALUE="<%= SearchMode.SEARCH_REGEXP %>"
<% if (data.searchModeIs(SearchMode.SEARCH_REGEXP)) { %>SELECTED<% } %> >matches the regular
expression</OPTION>
</SELECT>
<INPUT TYPE=TEXT NAME="term" SIZE=32 MAXLENGTH=255 VALUE="<%= data.getSearchTerm() %>"><BR>
<INPUT TYPE=IMAGE NAME="search" SRC="<%= rdat.getFullImagePath("bn_search.gif") %>"
ALT="Search" WIDTH=80 HEIGHT=24 BORDER=0><BR>
</FONT>
</FORM>
<% if (data.displayList()) { %>
<% int dcount = data.getSize(); %>
<HR>
<% if (data.isSIGMemberList()) { %>
<%-- The SIG list header --%>
<%= rdat.getStdFontTag(null,3) %><B>
Members of SIG "<%= StringUtil.encodeHTML(data.getSIGName()) %>":
</B></FONT><BR>
<% } else { %>
<%
// Determine the number of results to display and whether to display a "next" button
boolean go_next = false;
if (dcount>data.getNumResultsDisplayed())
{ // there's a "next"
dcount = data.getNumResultsDisplayed();
go_next = true;
} // end if
%>
<TABLE WIDTH="100%" BORDER=0 ALIGN=CENTER><TR VALIGN=MIDDLE>
<TD WIDTH="50%" ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>
<%-- The search results header --%>
<FONT SIZE=+1><B>Search Results:</B></FONT>
<% if (data.getFindCount()>0) { %>
(Displaying <%= data.getOffset() + 1 %>-<%= data.getOffset() + dcount %> of
<%= data.getFindCount() %>)
<% } else { %>(None)<% } %>
</FONT></TD>
<TD WIDTH="50%" ALIGN=RIGHT>
<% if (go_next || (data.getOffset()>0)) { %>
<%-- The navigational form that allows us to page through the results --%>
<% if (rdat.useHTMLComments()) { %><!-- Navigational Form --><% } %>
<FORM METHOD="POST" ACTION="<%= rdat.getEncodedServletPath("sigadmin") %>">
<INPUT TYPE=HIDDEN NAME="sig" VALUE="<%= data.getSIGID() %>">
<INPUT TYPE=HIDDEN NAME="cmd" VALUE="M">
<INPUT TYPE=HIDDEN NAME="ofs" VALUE="<%= data.getOffset() %>">
<INPUT TYPE=HIDDEN NAME="field" VALUE="<%= data.getSearchField() %>">
<INPUT TYPE=HIDDEN NAME="mode" VALUE="<%= data.getSearchMode() %>">
<INPUT TYPE=HIDDEN NAME="term" VALUE="<%= data.getSearchTerm() %>">
<INPUT TYPE=HIDDEN NAME="fcount" VALUE="<%= data.getFindCount() %>">
<% if (data.getOffset()>0) { %>
<INPUT TYPE=IMAGE NAME="previous" SRC="<%= rdat.getFullImagePath("bn_ar_previous.gif") %>"
ALT="Previous" WIDTH=80 HEIGHT=24 BORDER=0>
<% } else { %>
<IMG SRC="<%= rdat.getFullImagePath("bn_transparent.gif") %>" WIDTH=80 HEIGHT=24 BORDER=0>
<% } // end if %>
&nbsp;
<% if (go_next) { %>
<INPUT TYPE=IMAGE NAME="next" SRC="<%= rdat.getFullImagePath("bn_ar_next.gif") %>"
ALT="Next" WIDTH=80 HEIGHT=24 BORDER=0>
<% } else { %>
<IMG SRC="<%= rdat.getFullImagePath("bn_transparent.gif") %>" WIDTH=80 HEIGHT=24 BORDER=0>
<% } // end if %>
</FORM>
<% } else { %>&nbsp;<% } %>
</TD>
</TR></TABLE><BR>
<% } // end if %>
<%-- Display the results of the search --%>
<FORM METHOD="POST" ACTION="<%= rdat.getEncodedServletPath("sigadmin") %>">
<INPUT TYPE=HIDDEN NAME="sig" VALUE="<%= data.getSIGID() %>">
<INPUT TYPE=HIDDEN NAME="cmd" VALUE="M">
<TABLE BORDER=0 ALIGN=LEFT CELLPADDING=0 CELLSPACING=4>
<% for (int i=0; i<dcount; i++) { %>
<% UserFound uf = data.getItem(i); %>
<TR VALIGN=MIDDLE>
<TD ALIGN=CENTER WIDTH=14>
<IMG SRC="<%= rdat.getFullImagePath("purple-ball.gif") %>" ALT="*" WIDTH=14 HEIGHT=14 BORDER=0>
</TD>
<TD ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>
<A HREF="<%= rdat.getEncodedServletPath("user/" + uf.getName()) %>"><%= uf.getName() %></A>
</FONT></TD>
<TD ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>
<% data.outputDropDown(out,uf.getUID(),uf.getLevel()); %>
</FONT></TD>
</TR>
<% } // end for %>
</TABLE><BR CLEAR=LEFT>
<INPUT TYPE=IMAGE SRC="<%= rdat.getFullImagePath("bn_update.gif") %>" NAME="update" ALT="Update"
WIDTH=80 HEIGHT=24 BORDER=0>
</FORM><BR>
<% } // end if %>
<% rdat.writeFooter(out); %>

View File

@ -97,6 +97,9 @@
NAME="postnext" WIDTH=80 HEIGHT=24 BORDER=0>
<% } // end if %>
&nbsp;
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_post_go_topics.gif") %>" ALT="Post & Go Topics"
NAME="posttopics" WIDTH=80 HEIGHT=24 BORDER=0>
&nbsp;
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_cancel.gif") %>" ALT="Cancel"
NAME="cancel" WIDTH=80 HEIGHT=24 BORDER=0>
</TD></TR>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB