From 680b84b9d848be3d1da071c983f2ec22ad1af0a4 Mon Sep 17 00:00:00 2001 From: "Eric J. Bowersox" Date: Fri, 23 Feb 2001 07:49:42 +0000 Subject: [PATCH] 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 --- TODO | 11 +- etc/web.xml | 13 + setup/database.sql | 4 +- .../venice/core/AdminOperations.java | 3 +- .../silverwrist/venice/core/SIGContext.java | 9 + .../silverwrist/venice/core/UserContext.java | 4 + .../venice/core/impl/AdminOperationsImpl.java | 61 ++++ .../venice/core/impl/BackgroundSIGPurge.java | 178 ++++++++++ .../venice/core/impl/ConferenceCoreData.java | 4 +- .../venice/core/impl/ConferenceData.java | 2 +- .../core/impl/ConferenceSIGContext.java | 2 +- .../core/impl/ConferenceSIGContextImpl.java | 8 +- .../venice/core/impl/SIGCoreData.java | 218 +++++++++++- .../silverwrist/venice/core/impl/SIGData.java | 6 +- .../venice/core/impl/SIGUserContextImpl.java | 87 ++++- .../venice/core/impl/UserContextImpl.java | 20 ++ .../venice/core/impl/VeniceEngineImpl.java | 7 +- .../silverwrist/venice/security/Audit.java | 1 + .../venice/security/Capability.java | 6 + src/com/silverwrist/venice/security/Role.java | 26 +- .../venice/servlets/PostMessage.java | 7 +- .../silverwrist/venice/servlets/SIGAdmin.java | 219 +++++++++++- .../venice/servlets/SystemAdmin.java | 95 +++++ .../servlets/format/ConferenceMembership.java | 3 +- .../servlets/format/ContentMenuPanel.java | 2 +- .../venice/servlets/format/SIGAdminTop.java | 2 +- .../venice/servlets/format/SIGMembership.java | 333 ++++++++++++++++++ .../servlets/format/SystemAdminTop.java | 57 +++ web/format/posts.jsp | 3 + web/format/preview.jsp | 3 + web/format/sig_member.jsp | 151 ++++++++ web/format/slippage.jsp | 3 + web/images/bn_post_go_topics.gif | Bin 0 -> 1029 bytes 33 files changed, 1517 insertions(+), 31 deletions(-) create mode 100644 src/com/silverwrist/venice/core/impl/AdminOperationsImpl.java create mode 100644 src/com/silverwrist/venice/core/impl/BackgroundSIGPurge.java create mode 100644 src/com/silverwrist/venice/servlets/SystemAdmin.java create mode 100644 src/com/silverwrist/venice/servlets/format/SIGMembership.java create mode 100644 src/com/silverwrist/venice/servlets/format/SystemAdminTop.java create mode 100644 web/format/sig_member.jsp create mode 100644 web/images/bn_post_go_topics.gif diff --git a/TODO b/TODO index 4118e12..868b954 100644 --- a/TODO +++ b/TODO @@ -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 diff --git a/etc/web.xml b/etc/web.xml index 1143203..5084b58 100644 --- a/etc/web.xml +++ b/etc/web.xml @@ -77,6 +77,14 @@ com.silverwrist.venice.servlets.Account + + systemadmin + + System administration operations. + + com.silverwrist.venice.servlets.SystemAdmin + + settings @@ -208,6 +216,11 @@ /account + + systemadmin + /sysadmin + + settings /settings diff --git a/setup/database.sql b/setup/database.sql index e665e8c..c86e7d4 100644 --- a/setup/database.sql +++ b/setup/database.sql @@ -1,3 +1,4 @@ + # MySQL script for initializing the Venice database. # Written by Eric J. Bowersox #--------------------------------------------------------------------------- @@ -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'); ############################################################################## diff --git a/src/com/silverwrist/venice/core/AdminOperations.java b/src/com/silverwrist/venice/core/AdminOperations.java index 3b7c498..7f6ff53 100644 --- a/src/com/silverwrist/venice/core/AdminOperations.java +++ b/src/com/silverwrist/venice/core/AdminOperations.java @@ -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 , * 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 diff --git a/src/com/silverwrist/venice/core/SIGContext.java b/src/com/silverwrist/venice/core/SIGContext.java index cebe8d6..3bdf3d7 100644 --- a/src/com/silverwrist/venice/core/SIGContext.java +++ b/src/com/silverwrist/venice/core/SIGContext.java @@ -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 diff --git a/src/com/silverwrist/venice/core/UserContext.java b/src/com/silverwrist/venice/core/UserContext.java index a768d01..73a007c 100644 --- a/src/com/silverwrist/venice/core/UserContext.java +++ b/src/com/silverwrist/venice/core/UserContext.java @@ -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 diff --git a/src/com/silverwrist/venice/core/impl/AdminOperationsImpl.java b/src/com/silverwrist/venice/core/impl/AdminOperationsImpl.java new file mode 100644 index 0000000..991e031 --- /dev/null +++ b/src/com/silverwrist/venice/core/impl/AdminOperationsImpl.java @@ -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 . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 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 diff --git a/src/com/silverwrist/venice/core/impl/BackgroundSIGPurge.java b/src/com/silverwrist/venice/core/impl/BackgroundSIGPurge.java new file mode 100644 index 0000000..c1c6672 --- /dev/null +++ b/src/com/silverwrist/venice/core/impl/BackgroundSIGPurge.java @@ -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 . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 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 "); + 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 diff --git a/src/com/silverwrist/venice/core/impl/ConferenceCoreData.java b/src/com/silverwrist/venice/core/impl/ConferenceCoreData.java index 44a8798..c087a2a 100644 --- a/src/com/silverwrist/venice/core/impl/ConferenceCoreData.java +++ b/src/com/silverwrist/venice/core/impl/ConferenceCoreData.java @@ -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 diff --git a/src/com/silverwrist/venice/core/impl/ConferenceData.java b/src/com/silverwrist/venice/core/impl/ConferenceData.java index e860ea2..13b35dc 100644 --- a/src/com/silverwrist/venice/core/impl/ConferenceData.java +++ b/src/com/silverwrist/venice/core/impl/ConferenceData.java @@ -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 diff --git a/src/com/silverwrist/venice/core/impl/ConferenceSIGContext.java b/src/com/silverwrist/venice/core/impl/ConferenceSIGContext.java index 49075ed..7310bfc 100644 --- a/src/com/silverwrist/venice/core/impl/ConferenceSIGContext.java +++ b/src/com/silverwrist/venice/core/impl/ConferenceSIGContext.java @@ -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 diff --git a/src/com/silverwrist/venice/core/impl/ConferenceSIGContextImpl.java b/src/com/silverwrist/venice/core/impl/ConferenceSIGContextImpl.java index 7ad4ede..570625b 100644 --- a/src/com/silverwrist/venice/core/impl/ConferenceSIGContextImpl.java +++ b/src/com/silverwrist/venice/core/impl/ConferenceSIGContextImpl.java @@ -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 diff --git a/src/com/silverwrist/venice/core/impl/SIGCoreData.java b/src/com/silverwrist/venice/core/impl/SIGCoreData.java index 3455190..c6f5549 100644 --- a/src/com/silverwrist/venice/core/impl/SIGCoreData.java +++ b/src/com/silverwrist/venice/core/impl/SIGCoreData.java @@ -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=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 *-------------------------------------------------------------------------------- diff --git a/src/com/silverwrist/venice/core/impl/SIGData.java b/src/com/silverwrist/venice/core/impl/SIGData.java index 633ac3b..5573b05 100644 --- a/src/com/silverwrist/venice/core/impl/SIGData.java +++ b/src/com/silverwrist/venice/core/impl/SIGData.java @@ -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 diff --git a/src/com/silverwrist/venice/core/impl/SIGUserContextImpl.java b/src/com/silverwrist/venice/core/impl/SIGUserContextImpl.java index c62db18..0bbd127 100644 --- a/src/com/silverwrist/venice/core/impl/SIGUserContextImpl.java +++ b/src/com/silverwrist/venice/core/impl/SIGUserContextImpl.java @@ -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 *-------------------------------------------------------------------------------- diff --git a/src/com/silverwrist/venice/core/impl/UserContextImpl.java b/src/com/silverwrist/venice/core/impl/UserContextImpl.java index 7c9da46..206bb2f 100644 --- a/src/com/silverwrist/venice/core/impl/UserContextImpl.java +++ b/src/com/silverwrist/venice/core/impl/UserContextImpl.java @@ -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 *-------------------------------------------------------------------------------- diff --git a/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java b/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java index 88d0102..be0aa15 100644 --- a/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java +++ b/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java @@ -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), - rs.getString(5),rs.getString(6),rs.getString(7),rs.getString(8)); - UserFound tmp = (UserFound)ufi; - rc.add(tmp); + 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)); + rc.add(uf); } // end while diff --git a/src/com/silverwrist/venice/security/Audit.java b/src/com/silverwrist/venice/security/Audit.java index 728e501..c583c6d 100644 --- a/src/com/silverwrist/venice/security/Audit.java +++ b/src/com/silverwrist/venice/security/Audit.java @@ -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; diff --git a/src/com/silverwrist/venice/security/Capability.java b/src/com/silverwrist/venice/security/Capability.java index 9793304..b53f1cc 100644 --- a/src/com/silverwrist/venice/security/Capability.java +++ b/src/com/silverwrist/venice/security/Capability.java @@ -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 diff --git a/src/com/silverwrist/venice/security/Role.java b/src/com/silverwrist/venice/security/Role.java index 4cafcd1..173a0d8 100644 --- a/src/com/silverwrist/venice/security/Role.java +++ b/src/com/silverwrist/venice/security/Role.java @@ -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 , * 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(); diff --git a/src/com/silverwrist/venice/servlets/PostMessage.java b/src/com/silverwrist/venice/servlets/PostMessage.java index 1a61c25..4e53756 100644 --- a/src/com/silverwrist/venice/servlets/PostMessage.java +++ b/src/com/silverwrist/venice/servlets/PostMessage.java @@ -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 diff --git a/src/com/silverwrist/venice/servlets/SIGAdmin.java b/src/com/silverwrist/venice/servlets/SIGAdmin.java index 68d3d0b..1ec34e5 100644 --- a/src/com/silverwrist/venice/servlets/SIGAdmin.java +++ b/src/com/silverwrist/venice/servlets/SIGAdmin.java @@ -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()); /*-------------------------------------------------------------------------------- @@ -94,7 +98,7 @@ public class SIGAdmin extends VeniceServlet protected VeniceContent doVeniceGet(HttpServletRequest request, VeniceEngine engine, UserContext user, RenderData rdat) - throws ServletException, IOException, VeniceServletResult + throws ServletException, IOException, VeniceServletResult { // get the SIG context SIGContext sig = getSIGParameter(request,user,true,"top"); @@ -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); diff --git a/src/com/silverwrist/venice/servlets/SystemAdmin.java b/src/com/silverwrist/venice/servlets/SystemAdmin.java new file mode 100644 index 0000000..f4ff99e --- /dev/null +++ b/src/com/silverwrist/venice/servlets/SystemAdmin.java @@ -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 . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 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 diff --git a/src/com/silverwrist/venice/servlets/format/ConferenceMembership.java b/src/com/silverwrist/venice/servlets/format/ConferenceMembership.java index dac553f..c64748d 100644 --- a/src/com/silverwrist/venice/servlets/format/ConferenceMembership.java +++ b/src/com/silverwrist/venice/servlets/format/ConferenceMembership.java @@ -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("\n"); + out.write(">" + StringUtil.encodeHTML(r.getName()) + "\n"); } // end while diff --git a/src/com/silverwrist/venice/servlets/format/ContentMenuPanel.java b/src/com/silverwrist/venice/servlets/format/ContentMenuPanel.java index 79f1e9d..0eb44cd 100644 --- a/src/com/silverwrist/venice/servlets/format/ContentMenuPanel.java +++ b/src/com/silverwrist/venice/servlets/format/ContentMenuPanel.java @@ -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 , * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are diff --git a/src/com/silverwrist/venice/servlets/format/SIGAdminTop.java b/src/com/silverwrist/venice/servlets/format/SIGAdminTop.java index d8d3b43..65dbe95 100644 --- a/src/com/silverwrist/venice/servlets/format/SIGAdminTop.java +++ b/src/com/silverwrist/venice/servlets/format/SIGAdminTop.java @@ -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 , * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are diff --git a/src/com/silverwrist/venice/servlets/format/SIGMembership.java b/src/com/silverwrist/venice/servlets/format/SIGMembership.java new file mode 100644 index 0000000..195552e --- /dev/null +++ b/src/com/silverwrist/venice/servlets/format/SIGMembership.java @@ -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 . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 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("\n"); + out.write("\n"); + + } // end outputDropDown + +} // end class SIGMembership diff --git a/src/com/silverwrist/venice/servlets/format/SystemAdminTop.java b/src/com/silverwrist/venice/servlets/format/SystemAdminTop.java new file mode 100644 index 0000000..9df7483 --- /dev/null +++ b/src/com/silverwrist/venice/servlets/format/SystemAdminTop.java @@ -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 . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 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 diff --git a/web/format/posts.jsp b/web/format/posts.jsp index bab79f3..0d5a8a0 100644 --- a/web/format/posts.jsp +++ b/web/format/posts.jsp @@ -325,6 +325,9 @@ " ALT="Post & Go Next" NAME="postnext" WIDTH=80 HEIGHT=24 BORDER=0> <% } // end if %> +   + " ALT="Post & Go Topics" + NAME="posttopics" WIDTH=80 HEIGHT=24 BORDER=0> diff --git a/web/format/preview.jsp b/web/format/preview.jsp index 77454b8..1a68ee9 100644 --- a/web/format/preview.jsp +++ b/web/format/preview.jsp @@ -73,6 +73,9 @@ NAME="postnext" WIDTH=80 HEIGHT=24 BORDER=0> <% } // end if %>   + " ALT="Post & Go Topics" + NAME="posttopics" WIDTH=80 HEIGHT=24 BORDER=0> +   " ALT="Cancel" NAME="cancel" WIDTH=80 HEIGHT=24 BORDER=0> diff --git a/web/format/sig_member.jsp b/web/format/sig_member.jsp new file mode 100644 index 0000000..9618d9f --- /dev/null +++ b/web/format/sig_member.jsp @@ -0,0 +1,151 @@ +<%-- + The contents of this file are subject to the Mozilla Public License Version 1.1 + (the "License"); you may not use this file except in compliance with the License. + You may obtain a copy of the License at . + + Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + WARRANTY OF ANY KIND, either express or implied. See the License for the specific + language governing rights and limitations under the License. + + The Original Code is the Venice Web Communities System. + + The Initial Developer of the Original Code is Eric J. Bowersox , + for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + Copyright (C) 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) %> + Return to SIG + Administration Menu +

+ +<%= rdat.getStdFontTag(null,3) %>Find Users:

+

"> + + + + <%= rdat.getStdFontTag(null,2) %> + Display all users whose   +
+ + +
+ " + ALT="Search" WIDTH=80 HEIGHT=24 BORDER=0>
+ +
+ +<% if (data.displayList()) { %> + <% int dcount = data.getSize(); %> +
+ <% if (data.isSIGMemberList()) { %> + <%-- The SIG list header --%> + <%= rdat.getStdFontTag(null,3) %> + Members of SIG "<%= StringUtil.encodeHTML(data.getSIGName()) %>": +
+ <% } 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 + %> + + + +
<%= rdat.getStdFontTag(null,2) %> + <%-- The search results header --%> + Search Results: + <% if (data.getFindCount()>0) { %> + (Displaying <%= data.getOffset() + 1 %>-<%= data.getOffset() + dcount %> of + <%= data.getFindCount() %>) + <% } else { %>(None)<% } %> + + <% if (go_next || (data.getOffset()>0)) { %> + <%-- The navigational form that allows us to page through the results --%> + <% if (rdat.useHTMLComments()) { %><% } %> +
"> + + + + + + + + <% if (data.getOffset()>0) { %> + " + ALT="Previous" WIDTH=80 HEIGHT=24 BORDER=0> + <% } else { %> + " WIDTH=80 HEIGHT=24 BORDER=0> + <% } // end if %> +   + <% if (go_next) { %> + " + ALT="Next" WIDTH=80 HEIGHT=24 BORDER=0> + <% } else { %> + " WIDTH=80 HEIGHT=24 BORDER=0> + <% } // end if %> + +
+ <% } else { %> <% } %> +

+ <% } // end if %> + + <%-- Display the results of the search --%> +
"> + + + + <% for (int i=0; i + <% UserFound uf = data.getItem(i); %> + + + + + + <% } // end for %> +
+ " ALT="*" WIDTH=14 HEIGHT=14 BORDER=0> + <%= rdat.getStdFontTag(null,2) %> + "><%= uf.getName() %> + <%= rdat.getStdFontTag(null,2) %> + <% data.outputDropDown(out,uf.getUID(),uf.getLevel()); %> +

+ " NAME="update" ALT="Update" + WIDTH=80 HEIGHT=24 BORDER=0> +

+<% } // end if %> +<% rdat.writeFooter(out); %> diff --git a/web/format/slippage.jsp b/web/format/slippage.jsp index e816d4c..707fa02 100644 --- a/web/format/slippage.jsp +++ b/web/format/slippage.jsp @@ -97,6 +97,9 @@ NAME="postnext" WIDTH=80 HEIGHT=24 BORDER=0> <% } // end if %>   + " ALT="Post & Go Topics" + NAME="posttopics" WIDTH=80 HEIGHT=24 BORDER=0> +   " ALT="Cancel" NAME="cancel" WIDTH=80 HEIGHT=24 BORDER=0> diff --git a/web/images/bn_post_go_topics.gif b/web/images/bn_post_go_topics.gif new file mode 100644 index 0000000000000000000000000000000000000000..02db1612bd8913e816312042368da87658667bf5 GIT binary patch literal 1029 zcmV+g1p50&Nk%v~VNd`V0Q3L=%*gYW-~K0 z0A^-0%$YL)003q)GtA60GXMbp|7J60Gynh0napMYGXR-pX3YO)nane0nKNcH0L=fH zW|?LH05daY00000EC2ui08juJ000I4-~b#z0hE_HnnilPFc8G@JJToevM_e> zm=F#mq;k0|L<&c!NkE8haH<_z5K{GzAy4A5H0|ElI8%`aYA??M01u}XKNFc(-9smLo2w2eX*NIX? z+Of)!Y(jz#4kSQWP%98T00;j61PIVTfdK{-7}QYEz<>b`|7AVj)zyM26Q60Q6kbuSvnH;nN!*oNYCT$RjOeEKUfB>2XWEf~E zpg{u(0i;!x`ssmz0e}V|NC2UMg>MPs!n0tvD9@SzcmhaJp+VOL4Ip%#5#g<1=gODomjd9 z<2)7g762BwR8Rna)&5WwZ+V%gV0Kl>6rV&1NbueQ8hFB+0^N1OoB<^PP#S91aiD=@ zGVmpwSTiW6Lr4KsAVX<26i}fIZ_U6RLJK&M0atOclmJ3k1u($@LtcWTOBDnlk^vPk z1OZ?tbl{Rtot$LAPu0bBWp5{tH)Bs$ZMo$_agpgjT~|Ux$N;v$6Hx#%MPwgD8Zm@J zepGUT&_zQ8m0nQ;c#uE__6F;e5UvNnc?qbUZiO&r@5bGwLF>y<$0PL&;Kta`3!AGgyvf~h-c$m_!zjrhX?!f{+dqSOm zG_+Do+0ORaXV;w!m_LbLmolE6RAisa{`hL&%qr)s=+1U7#Pes0TA=93Apih7z=ox0 literal 0 HcmV?d00001