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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
*--------------------------------------------------------------------------------
@@ -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
@@ -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
*--------------------------------------------------------------------------------
@@ -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
*--------------------------------------------------------------------------------
@@ -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