From 004dcaf7ecfbc64e9936eeeed2aad3e55ad3d91f Mon Sep 17 00:00:00 2001 From: "Eric J. Bowersox" Date: Thu, 29 Nov 2001 07:46:57 +0000 Subject: [PATCH] added administrative control of user photos - ability to replace or clear a user's photo, keep the user from uploading a new one --- etc/web.xml | 13 ++ .../venice/core/AdminUserContext.java | 4 + .../venice/core/AdminUserProperties.java | 58 +++++ .../silverwrist/venice/core/ContactInfo.java | 2 + .../silverwrist/venice/core/UserContext.java | 2 + .../venice/core/UserProperties.java | 2 +- .../core/impl/AdminUserContextImpl.java | 124 ++++++++++- .../core/impl/CommunityUserContextImpl.java | 4 +- .../venice/core/impl/ContactInfoImpl.java | 20 +- .../venice/core/impl/UserContextImpl.java | 25 ++- .../silverwrist/venice/servlets/Account.java | 4 +- .../venice/servlets/AdminUserPhoto.java | 203 ++++++++++++++++++ .../format/AdminModifyUserDialog.java | 125 +++++++++-- .../servlets/format/AdminUserPhotoData.java | 135 ++++++++++++ .../servlets/format/EditProfileDialog.java | 4 +- web/format/admin_user_photo.jsp | 43 ++++ 16 files changed, 728 insertions(+), 40 deletions(-) create mode 100644 src/com/silverwrist/venice/core/AdminUserProperties.java create mode 100644 src/com/silverwrist/venice/servlets/AdminUserPhoto.java create mode 100644 src/com/silverwrist/venice/servlets/format/AdminUserPhotoData.java create mode 100644 web/format/admin_user_photo.jsp diff --git a/etc/web.xml b/etc/web.xml index 4b50443..a2daa79 100644 --- a/etc/web.xml +++ b/etc/web.xml @@ -262,6 +262,14 @@ com.silverwrist.venice.servlets.MemberRedirect + + adminuserphoto + + Changes the photo in a user's profile (uploads a new one). + + com.silverwrist.venice.servlets.AdminUserPhoto + + @@ -400,6 +408,11 @@ /members + + adminuserphoto + /adminuserphoto + + testformdata diff --git a/src/com/silverwrist/venice/core/AdminUserContext.java b/src/com/silverwrist/venice/core/AdminUserContext.java index 522f993..e3bd057 100644 --- a/src/com/silverwrist/venice/core/AdminUserContext.java +++ b/src/com/silverwrist/venice/core/AdminUserContext.java @@ -69,4 +69,8 @@ public interface AdminUserContext public abstract Date getLastAccessDate(); + public abstract AdminUserProperties getProperties() throws DataException; + + public abstract void setProperties(AdminUserProperties props) throws DataException; + } // end interface AdminUserContext diff --git a/src/com/silverwrist/venice/core/AdminUserProperties.java b/src/com/silverwrist/venice/core/AdminUserProperties.java new file mode 100644 index 0000000..4b2e019 --- /dev/null +++ b/src/com/silverwrist/venice/core/AdminUserProperties.java @@ -0,0 +1,58 @@ +/* + * 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; + +public class AdminUserProperties extends UserProperties +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private boolean disallow_photo; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + public AdminUserProperties() + { + super(); + disallow_photo = false; + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Public getters/setters + *-------------------------------------------------------------------------------- + */ + + public final boolean getDisallowPhoto() + { + return disallow_photo; + + } // end getDisplayPostPictures + + public final void setDisallowPhoto(boolean b) + { + disallow_photo = b; + + } // end setDisplayPostPictures + +} // end class AdminUserProperties diff --git a/src/com/silverwrist/venice/core/ContactInfo.java b/src/com/silverwrist/venice/core/ContactInfo.java index b7ce7bd..43cf757 100644 --- a/src/com/silverwrist/venice/core/ContactInfo.java +++ b/src/com/silverwrist/venice/core/ContactInfo.java @@ -126,4 +126,6 @@ public interface ContactInfo public abstract void importVCard(VCard vc); + public abstract boolean canSetPhoto(); + } // end interface ContactInfo diff --git a/src/com/silverwrist/venice/core/UserContext.java b/src/com/silverwrist/venice/core/UserContext.java index 3aeb034..3edbcc3 100644 --- a/src/com/silverwrist/venice/core/UserContext.java +++ b/src/com/silverwrist/venice/core/UserContext.java @@ -121,4 +121,6 @@ public interface UserContext extends SearchMode public abstract void setProperties(UserProperties props) throws DataException; + public abstract boolean canSetUserPhoto() throws DataException; + } // end interface UserContext diff --git a/src/com/silverwrist/venice/core/UserProperties.java b/src/com/silverwrist/venice/core/UserProperties.java index 21cd1f1..462db0c 100644 --- a/src/com/silverwrist/venice/core/UserProperties.java +++ b/src/com/silverwrist/venice/core/UserProperties.java @@ -17,7 +17,7 @@ */ package com.silverwrist.venice.core; -public final class UserProperties +public class UserProperties { /*-------------------------------------------------------------------------------- * Attributes diff --git a/src/com/silverwrist/venice/core/impl/AdminUserContextImpl.java b/src/com/silverwrist/venice/core/impl/AdminUserContextImpl.java index ef833f1..3bf6200 100644 --- a/src/com/silverwrist/venice/core/impl/AdminUserContextImpl.java +++ b/src/com/silverwrist/venice/core/impl/AdminUserContextImpl.java @@ -21,6 +21,7 @@ import java.sql.*; import java.util.*; import org.apache.log4j.*; import com.silverwrist.util.International; +import com.silverwrist.util.OptionSet; import com.silverwrist.venice.core.*; import com.silverwrist.venice.core.internals.*; import com.silverwrist.venice.db.*; @@ -53,13 +54,14 @@ class AdminUserContextImpl implements AdminUserContext private String description; // personal description private Locale my_locale; // my default locale (cached) private TimeZone my_tz; // my default timezone (cached) + private OptionSet flags = null; // option flags /*-------------------------------------------------------------------------------- * Constructor *-------------------------------------------------------------------------------- */ - protected AdminUserContextImpl(EnvUser env, ResultSet rs) throws SQLException + protected AdminUserContextImpl(Connection conn, EnvUser env, ResultSet rs) throws SQLException { this.env = env; this.uid = rs.getInt("uid"); @@ -74,8 +76,91 @@ class AdminUserContextImpl implements AdminUserContext this.my_locale = International.get().createLocale(rs.getString("localeid")); this.my_tz = TimeZone.getTimeZone(rs.getString("tzid")); + Statement stmt = conn.createStatement(); + ResultSet rs2 = stmt.executeQuery("SELECT ndx, data FROM propuser WHERE uid = " + this.uid + ";"); + while (rs2.next()) + { // load the properties... + switch (rs2.getInt(1)) + { // based on the property, do what is needed + case UserContextImpl.PROP_FLAGS: + flags = new OptionSet(rs2.getString(2)); + break; + + default: + break; + + } // end switch + + } // end while + } // end constructor + /*-------------------------------------------------------------------------------- + * Internal operations + *-------------------------------------------------------------------------------- + */ + + private final void updateProperties(BitSet delta) throws DataException + { + Connection conn = null; + try + { // get a connection and create a statement + conn = env.getConnection(); + Statement stmt = conn.createStatement(); + StringBuffer sql = new StringBuffer(); + + if (delta.get(UserContextImpl.PROP_FLAGS)) + { // store the flags + sql.append("UPDATE propuser SET data = '").append(flags.asString()).append("' WHERE uid = "); + sql.append(uid).append(" AND ndx = ").append(UserContextImpl.PROP_FLAGS).append(';'); + stmt.executeUpdate(sql.toString()); + sql.setLength(0); + + } // end if + + } // end try + catch (SQLException e) + { // database error - this is a DataException + logger.error("DB error storing user properties: " + e.getMessage(),e); + throw new DataException("unable to save user properties: " + e.getMessage(),e); + + } // end catch + finally + { // make sure the connection is released before we go + env.releaseConnection(conn); + + } // end finally + + } // end updateProperties + + private final void updateProperties() throws DataException + { + updateProperties(UserContextImpl.ALL_PROPS); + + } // end updateProperties + + private final AdminUserProperties createProperties() + { + AdminUserProperties rc = new AdminUserProperties(); + rc.setDisplayPostPictures(flags.get(UserContextImpl.BF_POSTPICTURES)); + rc.setDisallowPhoto(flags.get(UserContextImpl.BF_ADM_NOPHOTO)); + return rc; + + } // end createProperties + + private final BitSet storeProperties(AdminUserProperties props) + { + BitSet rc = new BitSet(); + + if (flags.assign(UserContextImpl.BF_POSTPICTURES,props.getDisplayPostPictures())) + rc.set(UserContextImpl.PROP_FLAGS); + if (flags.assign(UserContextImpl.BF_ADM_NOPHOTO,props.getDisallowPhoto())) + rc.set(UserContextImpl.PROP_FLAGS); + + return rc; + + } // end storeProperties + /*-------------------------------------------------------------------------------- * Implementations from interface AdminUserContext *-------------------------------------------------------------------------------- @@ -282,9 +367,9 @@ class AdminUserContextImpl implements AdminUserContext ContactInfoImpl rc; if (contactid>=0) - rc = new ContactInfoImpl(env,contactid); + rc = new ContactInfoImpl(env,contactid,true); else - rc = new ContactInfoImpl(uid); + rc = new ContactInfoImpl(uid,true); return rc; } // end getContactInfo @@ -477,6 +562,35 @@ class AdminUserContextImpl implements AdminUserContext } // end getLastAccessDate + public AdminUserProperties getProperties() throws DataException + { + return createProperties(); + + } // end getProperties + + public void setProperties(AdminUserProperties props) throws DataException + { + AdminUserProperties orig = createProperties(); + BitSet delta = storeProperties(props); + if (delta.length()==0) + return; + + boolean succeeded = false; + try + { // update the properties in the database + updateProperties(delta); + succeeded = true; + + } // end try + finally + { // make sure the connection is released before we go + if (!succeeded) + storeProperties(orig); + + } // end finally + + } // end setProperties + /*-------------------------------------------------------------------------------- * Package-level static operations *-------------------------------------------------------------------------------- @@ -497,7 +611,7 @@ class AdminUserContextImpl implements AdminUserContext if (rs.getBoolean("is_anon")) throw new DataException("Cannot modify the defaults for the anonymous user."); - return new AdminUserContextImpl(env,rs); + return new AdminUserContextImpl(conn,env,rs); } // end try catch (SQLException e) @@ -530,7 +644,7 @@ class AdminUserContextImpl implements AdminUserContext if (rs.getBoolean("is_anon")) throw new DataException("Cannot modify the defaults for the anonymous user."); - return new AdminUserContextImpl(env,rs); + return new AdminUserContextImpl(conn,env,rs); } // end try catch (SQLException e) diff --git a/src/com/silverwrist/venice/core/impl/CommunityUserContextImpl.java b/src/com/silverwrist/venice/core/impl/CommunityUserContextImpl.java index 5eb21b5..0360504 100644 --- a/src/com/silverwrist/venice/core/impl/CommunityUserContextImpl.java +++ b/src/com/silverwrist/venice/core/impl/CommunityUserContextImpl.java @@ -468,9 +468,9 @@ class CommunityUserContextImpl implements CommunityContext, CommunityBackend int id = getData().getContactID(); ContactInfo rc; if (id>=0) - rc = new ContactInfoImpl(env,id); + rc = new ContactInfoImpl(env,id,true); else - rc = new ContactInfoImpl(getData().getHostUID(),cid); + rc = new ContactInfoImpl(getData().getHostUID(),cid,true); getData().touch(); return rc; diff --git a/src/com/silverwrist/venice/core/impl/ContactInfoImpl.java b/src/com/silverwrist/venice/core/impl/ContactInfoImpl.java index 32b1b48..075b011 100644 --- a/src/com/silverwrist/venice/core/impl/ContactInfoImpl.java +++ b/src/com/silverwrist/venice/core/impl/ContactInfoImpl.java @@ -138,6 +138,7 @@ class ContactInfoImpl implements ContactInfo, Stashable private java.util.Date last_update; // date of last update private boolean is_modified = false; // have we modified this ContactInfo? private ImageHook image_hook = null; // image hook object + private boolean can_set_photo; // can we set the user photo? /*-------------------------------------------------------------------------------- * Constructors @@ -149,10 +150,11 @@ class ContactInfoImpl implements ContactInfo, Stashable * * @param owner_uid UID that owns this object. */ - ContactInfoImpl(int owner_uid) + ContactInfoImpl(int owner_uid, boolean can_set_photo) { if (logger.isDebugEnabled()) logger.debug("new ContactInfoImpl (empty) for UID = " + owner_uid); + this.can_set_photo = can_set_photo; makeEmpty(owner_uid,-1); } // end constructor @@ -163,10 +165,11 @@ class ContactInfoImpl implements ContactInfo, Stashable * @param owner_uid UID that owns this object. * @param owner_cid Community ID that owns this object. */ - ContactInfoImpl(int owner_uid, int owner_cid) + ContactInfoImpl(int owner_uid, int owner_cid, boolean can_set_photo) { if (logger.isDebugEnabled()) logger.debug("new ContactInfoImpl (empty) for UID = " + owner_uid + ", Community ID = " + owner_cid); + this.can_set_photo = can_set_photo; makeEmpty(owner_uid,owner_cid); } // end constructor @@ -178,10 +181,11 @@ class ContactInfoImpl implements ContactInfo, Stashable * @param contactid ID of the contact to load. * @exception DataException The contact could not be loaded for some reason. */ - ContactInfoImpl(EnvEngine env, int contactid) throws DataException + ContactInfoImpl(EnvEngine env, int contactid, boolean can_set_photo) throws DataException { if (logger.isDebugEnabled()) logger.debug("new ContactInfoImpl (loading CID " + contactid + ")"); + this.can_set_photo = can_set_photo; Connection conn = null; try @@ -571,6 +575,8 @@ class ContactInfoImpl implements ContactInfo, Stashable public void setPhotoURL(String addr) { + if (!can_set_photo) + return; if ((addr!=null) && (addr.length()>255)) photo_url = addr.substring(0,255); else @@ -582,6 +588,8 @@ class ContactInfoImpl implements ContactInfo, Stashable public void setPhotoData(String prefix, String mimetype, int length, InputStream data) { + if (!can_set_photo) + return; if ((photo_url!=null) && (photo_url.startsWith(prefix))) { // extract the image ID and create an image hook object int img_id = Integer.parseInt(photo_url.substring(prefix.length())); @@ -908,6 +916,12 @@ class ContactInfoImpl implements ContactInfo, Stashable } // end importVCard + public boolean canSetPhoto() + { + return can_set_photo; + + } // end canSetPhoto + /*-------------------------------------------------------------------------------- * Implementations from interface Stashable *-------------------------------------------------------------------------------- diff --git a/src/com/silverwrist/venice/core/impl/UserContextImpl.java b/src/com/silverwrist/venice/core/impl/UserContextImpl.java index 0cd9634..df998ea 100644 --- a/src/com/silverwrist/venice/core/impl/UserContextImpl.java +++ b/src/com/silverwrist/venice/core/impl/UserContextImpl.java @@ -36,12 +36,13 @@ class UserContextImpl implements UserContext, UserBackend */ // Property set indexes - private static final int PROP_FLAGS = 0; // flags + static final int PROP_FLAGS = 0; // flags - private static final BitSet ALL_PROPS; // BitSet representing all properties + static final BitSet ALL_PROPS; // BitSet representing all properties // Boolean flag indexes - private static final int BF_POSTPICTURES = 0; + static final int BF_POSTPICTURES = 0; + static final int BF_ADM_NOPHOTO = 1; private static Category logger = Category.getInstance(UserContextImpl.class); @@ -288,8 +289,8 @@ class UserContextImpl implements UserContext, UserBackend } // end try catch (SQLException e) { // database error - this is a DataException - logger.error("DB error storing community properties: " + e.getMessage(),e); - throw new DataException("unable to save community properties: " + e.getMessage(),e); + logger.error("DB error storing user properties: " + e.getMessage(),e); + throw new DataException("unable to save user properties: " + e.getMessage(),e); } // end catch finally @@ -581,11 +582,13 @@ class UserContextImpl implements UserContext, UserBackend if (logger.isDebugEnabled()) logger.debug("getContactInfo() for UID " + uid); + if (flags==null) + loadPrefs(); ContactInfoImpl rc; if (contactid>=0) - rc = new ContactInfoImpl(env,contactid); + rc = new ContactInfoImpl(env,contactid,!(flags.get(BF_ADM_NOPHOTO))); else - rc = new ContactInfoImpl(uid); + rc = new ContactInfoImpl(uid,!(flags.get(BF_ADM_NOPHOTO))); if (my_email==null) my_email = rc.getEmail(); if (full_name==null) @@ -1416,6 +1419,14 @@ class UserContextImpl implements UserContext, UserBackend } // end setProperties + public boolean canSetUserPhoto() throws DataException + { + if (flags==null) + loadPrefs(); + return !(flags.get(BF_ADM_NOPHOTO)); + + } // end canSetUserPhoto + /*-------------------------------------------------------------------------------- * Implementations from interface UserBackend *-------------------------------------------------------------------------------- diff --git a/src/com/silverwrist/venice/servlets/Account.java b/src/com/silverwrist/venice/servlets/Account.java index 989be73..a5f3db7 100644 --- a/src/com/silverwrist/venice/servlets/Account.java +++ b/src/com/silverwrist/venice/servlets/Account.java @@ -489,8 +489,10 @@ public class Account extends VeniceServlet { // we're ready to update the user profile dlg.loadValues(request); // load field values + boolean photo_flag = true; try { // validate the dialog and reset profile info + photo_flag = user.canSetUserPhoto(); if (dlg.doDialog(user)) // need to reconfirm email address throw new RedirectResult("account?cmd=V&tgt=" + URLEncoder.encode(tgt)); else @@ -499,7 +501,7 @@ public class Account extends VeniceServlet } // end try catch (ValidationException ve) { // there was a validation error... - dlg.resetOnError(ve.getMessage() + " Please try again."); + dlg.resetOnError(photo_flag,ve.getMessage() + " Please try again."); } // end catch catch (DataException de) diff --git a/src/com/silverwrist/venice/servlets/AdminUserPhoto.java b/src/com/silverwrist/venice/servlets/AdminUserPhoto.java new file mode 100644 index 0000000..67f3fae --- /dev/null +++ b/src/com/silverwrist/venice/servlets/AdminUserPhoto.java @@ -0,0 +1,203 @@ +/* + * 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 java.util.*; +import javax.servlet.*; +import javax.servlet.http.*; +import org.apache.log4j.*; +import com.silverwrist.util.StringUtil; +import com.silverwrist.util.ServletMultipartHandler; +import com.silverwrist.util.ServletMultipartException; +import com.silverwrist.util.image.*; +import com.silverwrist.venice.core.*; +import com.silverwrist.venice.except.*; +import com.silverwrist.venice.servlets.format.*; + +public class AdminUserPhoto extends VeniceServlet +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static Category logger = Category.getInstance(AdminUserPhoto.class); + + /*-------------------------------------------------------------------------------- + * Overrides from class HttpServlet + *-------------------------------------------------------------------------------- + */ + + public String getServletInfo() + { + String rc = "AdminUserPhoto servlet - changes the user photo for a user\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 + { + try + { // get the user to be modified + AdminOperations adm = user.getAdminInterface(); + String s_uid = request.getParameter("uid"); + if (s_uid==null) + throw new ErrorBox(null,"User ID parameter not found.","sysadmin?cmd=UF"); + AdminUserContext admuser = adm.getUserContext(Integer.parseInt(s_uid)); + + if (request.getParameter("null")!=null) + { // null the photo out and return + ContactInfo ci = admuser.getContactInfo(); + ci.setPhotoURL(null); + admuser.putContactInfo(ci); + throw new RedirectResult("sysadmin?cmd=UM&uid=" + admuser.getUID()); + + } // end if + + return new AdminUserPhotoData(engine,admuser,rdat); + + } // end try + catch (AccessError ae) + { // an access error generally means we're not an administrator + return new ErrorBox("Access Error","You do not have permission to administer the system.",null); + + } // end catch + catch (DataException de) + { // error pulling the audit records + return new ErrorBox("Database Error","Unable to retrieve user information: " + de.getMessage(), + "sysadmin?cmd=UF"); + + } // end catch + catch (NumberFormatException nfe) + { // this is if we get a bogus UID + return new ErrorBox(null,"Invalid user ID parameter.","sysadmin?cmd=UF"); + + } // end catch + + } // end doVeniceGet + + protected VeniceContent doVenicePost(HttpServletRequest request, ServletMultipartHandler mphandler, + VeniceEngine engine, UserContext user, RenderData rdat) + throws ServletException, IOException, VeniceServletResult + { + AdminUserContext admuser; + try + { // get the user to be modified + AdminOperations adm = user.getAdminInterface(); + String s_uid = mphandler.getValue("uid"); + if (s_uid==null) + throw new ErrorBox(null,"User ID parameter not found.","sysadmin?cmd=UF"); + admuser = adm.getUserContext(Integer.parseInt(s_uid)); + + } // end try + catch (AccessError ae) + { // an access error generally means we're not an administrator + return new ErrorBox("Access Error","You do not have permission to administer the system.",null); + + } // end catch + catch (DataException de) + { // error pulling the audit records + return new ErrorBox("Database Error","Unable to retrieve user information: " + de.getMessage(), + "sysadmin?cmd=UF"); + + } // end catch + catch (NumberFormatException nfe) + { // this is if we get a bogus UID + return new ErrorBox(null,"Invalid user ID parameter.","sysadmin?cmd=UF"); + + } // end catch + + if (isImageButtonClicked(mphandler,"cancel")) + throw new RedirectResult("sysadmin?cmd=UM&uid=" + admuser.getUID()); + + if (isImageButtonClicked(mphandler,"upload")) + { // uploading the image here! + // also check on file parameter status + if (!(mphandler.isFileParam("thepic"))) + { // bogus file parameter + logger.error("Internal Error: 'thepic' should be a file param"); + return new ErrorBox(null,"Internal Error: 'thepic' should be a file param", + "sysadmin?cmd=UM&uid=" + admuser.getUID()); + + } // end if + + if (!(mphandler.getContentType("thepic").startsWith("image/"))) + { // must be an image type we uploaded! + logger.error("Error: 'thepic' not an image type"); + return new ErrorBox(null,"You did not upload an image file. Try again.", + "sysadmin?cmd=UM&uid=" + admuser.getUID()); + + } // end if + + try + { // get the real picture (normalized to 100x100 size) + ImageLengthPair real_pic = ImageNormalizer.normalizeImage(mphandler.getFileContentStream("thepic"), + engine.getUserPhotoSize(),"jpeg"); + + // set the user photo data! + ContactInfo ci = admuser.getContactInfo(); + ci.setPhotoData(request.getContextPath() + "/imagedata/","image/jpeg",real_pic.getLength(), + real_pic.getData()); + admuser.putContactInfo(ci); + + // Jump back to the profile form. + throw new RedirectResult("sysadmin?cmd=UM&uid=" + admuser.getUID()); + + } // end try + catch (ServletMultipartException smpe) + { // the servlet multipart parser screwed up + logger.error("Servlet multipart error:",smpe); + return new ErrorBox(null,"Internal Error: " + smpe.getMessage(), + "sysadmin?cmd=UM&uid=" + admuser.getUID()); + + } // end catch + catch (ImageNormalizerException ine) + { // the image was not valid + logger.error("Image normalizer error:",ine); + return new ErrorBox(null,ine.getMessage(),"admuserphoto?uid=" + admuser.getUID()); + + } // end catch + catch (DataException de) + { // error in the database! + logger.error("DataException:",de); + return new ErrorBox("Database Error","Database error storing user photo: " + de.getMessage(), + "sysadmin?cmd=UM&uid=" + admuser.getUID()); + + } // end catch + + } // end if + else + { // the button must be wrong! + logger.error("no known button click on AdminUserPhoto.doPost"); + return new ErrorBox("Internal Error","Unknown command button pressed", + "sysadmin?cmd=UM&uid=" + admuser.getUID()); + + } // end else + + } // end doVenicePost + +} // end class AdminUserPhoto diff --git a/src/com/silverwrist/venice/servlets/format/AdminModifyUserDialog.java b/src/com/silverwrist/venice/servlets/format/AdminModifyUserDialog.java index 2a86660..6c5fcd3 100644 --- a/src/com/silverwrist/venice/servlets/format/AdminModifyUserDialog.java +++ b/src/com/silverwrist/venice/servlets/format/AdminModifyUserDialog.java @@ -17,6 +17,8 @@ */ package com.silverwrist.venice.servlets.format; +import java.io.Writer; +import java.io.IOException; import java.util.*; import com.silverwrist.util.*; import com.silverwrist.venice.core.*; @@ -25,6 +27,74 @@ import com.silverwrist.venice.security.Role; public class AdminModifyUserDialog extends ContentDialog { + /*-------------------------------------------------------------------------------- + * The photo URL control class. + *-------------------------------------------------------------------------------- + */ + + static class CDUserPhotoControl extends CDBaseFormField + { + private String linkURL; + + public CDUserPhotoControl(String name, String caption, String linkURL) + { + super(name,caption,"(click to change)",false); + this.linkURL = linkURL; + + } // end constructor + + protected CDUserPhotoControl(CDUserPhotoControl other) + { + super(other); + this.linkURL = other.linkURL; + + } // end constructor + + protected void renderActualField(Writer out, RenderData rdat) throws IOException + { + if (isEnabled()) + out.write(""); + String photo = getValue(); + if (StringUtil.isStringEmpty(photo)) + photo = rdat.getPhotoNotAvailURL(); + out.write("\"\""); + if (isEnabled()) + out.write(""); + + } // end renderActualField + + protected void validateContents(String value) throws ValidationException + { // this is a do-nothing value + } // end validateContents + + public CDFormField duplicate() + { + return new CDUserPhotoControl(this); + + } // end clone + + public void setLinkURL(String s) + { + linkURL = s; + + } // end setLinkURL + + } // end class CDUserPhotoControl + + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static final String YES = "Y"; + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private CDUserPhotoControl photo_control; + /*-------------------------------------------------------------------------------- * Constructors *-------------------------------------------------------------------------------- @@ -43,8 +113,9 @@ public class AdminModifyUserDialog extends ContentDialog addFormField(new CDTextFormField("remind","Password reminder phrase",null,false,32,255)); addFormField(new CDRoleListFormField("base_lvl","Base security level",null,true, Collections.EMPTY_LIST)); - addFormField(new CDCheckBoxFormField("verify_email","E-mail address verified",null,"Y")); - addFormField(new CDCheckBoxFormField("lockout","Account locked out",null,"Y")); + addFormField(new CDCheckBoxFormField("verify_email","E-mail address verified",null,YES)); + addFormField(new CDCheckBoxFormField("lockout","Account locked out",null,YES)); + addFormField(new CDCheckBoxFormField("nophoto","Disallow photo uploads for this user",null,YES)); addFormField(new CDFormCategoryHeader("Name")); addFormField(new CDTextFormField("prefix","Prefix","(Mr., Ms., etc.)",false,8,8)); addFormField(new CDTextFormField("first","First name",null,true,32,64)); @@ -55,7 +126,7 @@ public class AdminModifyUserDialog extends ContentDialog addFormField(new CDTextFormField("company","Company",null,false,32,255)); addFormField(new CDTextFormField("addr1","Address",null,false,32,255)); addFormField(new CDTextFormField("addr2","Address","(line 2)",false,32,255)); - addFormField(new CDCheckBoxFormField("pvt_addr","Hide address in profile",null,"Y")); + addFormField(new CDCheckBoxFormField("pvt_addr","Hide address in profile",null,YES)); addFormField(new CDTextFormField("loc","City",null,true,32,64)); addFormField(new CDTextFormField("reg","State/Province",null,true,32,64)); addFormField(new CDTextFormField("pcode","Zip/Postal Code",null,true,32,64)); @@ -63,16 +134,20 @@ public class AdminModifyUserDialog extends ContentDialog addFormField(new CDFormCategoryHeader("Phone Numbers")); addFormField(new CDTextFormField("phone","Telephone",null,false,32,32)); addFormField(new CDTextFormField("mobile","Mobile/cellphone",null,false,32,32)); - addFormField(new CDCheckBoxFormField("pvt_phone","Hide phone/mobile numbers in profile",null,"Y")); + addFormField(new CDCheckBoxFormField("pvt_phone","Hide phone/mobile numbers in profile",null,YES)); addFormField(new CDTextFormField("fax","Fax",null,false,32,32)); - addFormField(new CDCheckBoxFormField("pvt_fax","Hide fax number in profile",null,"Y")); + addFormField(new CDCheckBoxFormField("pvt_fax","Hide fax number in profile",null,YES)); addFormField(new CDFormCategoryHeader("Internet")); addFormField(new CDEmailAddressFormField("email","E-mail address",null,true,32,255)); - addFormField(new CDCheckBoxFormField("pvt_email","Hide e-mail address in profile",null,"Y")); + addFormField(new CDCheckBoxFormField("pvt_email","Hide e-mail address in profile",null,YES)); addFormField(new CDTextFormField("url","Home page","(URL)",false,32,255)); addFormField(new CDFormCategoryHeader("Personal")); addFormField(new CDTextFormField("descr","Personal description",null,false,32,255)); + photo_control = new CDUserPhotoControl("photo","User Photo","userphoto"); + addFormField(photo_control); addFormField(new CDFormCategoryHeader("User Preferences")); + addFormField(new CDCheckBoxFormField("pic_in_post","Display user photos next to conference posts", + "(where applicable)",YES)); addFormField(new CDLocaleListFormField("locale","Default locale","(for formatting dates/times)",true)); addFormField(new CDTimeZoneListFormField("tz","Default time zone",null,true)); addCommandButton(new CDImageButton("update","bn_update.gif","Update",80,24)); @@ -83,6 +158,7 @@ public class AdminModifyUserDialog extends ContentDialog protected AdminModifyUserDialog(AdminModifyUserDialog other) { super(other); + photo_control = (CDUserPhotoControl)modifyField("photo"); } // end AdminModifyUserDialog @@ -172,12 +248,15 @@ public class AdminModifyUserDialog extends ContentDialog setFieldValue("base_lvl",String.valueOf(admuser.getBaseLevel())); if (admuser.isEmailVerified()) - setFieldValue("verify_email","Y"); + setFieldValue("verify_email",YES); if (admuser.isLockedOut()) - setFieldValue("lockout","Y"); + setFieldValue("lockout",YES); ContactInfo ci = admuser.getContactInfo(); // get the main contact info + AdminUserProperties props = admuser.getProperties(); + if (props.getDisallowPhoto()) + setFieldValue("nophoto",YES); setFieldValue("prefix",ci.getNamePrefix()); setFieldValue("first",ci.getGivenName()); char init = ci.getMiddleInitial(); @@ -189,7 +268,7 @@ public class AdminModifyUserDialog extends ContentDialog setFieldValue("addr1",ci.getAddressLine1()); setFieldValue("addr2",ci.getAddressLine2()); if (ci.getPrivateAddress()) - setFieldValue("pvt_addr","Y"); + setFieldValue("pvt_addr",YES); setFieldValue("loc",ci.getLocality()); setFieldValue("reg",ci.getRegion()); setFieldValue("pcode",ci.getPostalCode()); @@ -197,15 +276,19 @@ public class AdminModifyUserDialog extends ContentDialog setFieldValue("phone",ci.getPhone()); setFieldValue("mobile",ci.getMobile()); if (ci.getPrivatePhone()) - setFieldValue("pvt_phone","Y"); + setFieldValue("pvt_phone",YES); setFieldValue("fax",ci.getFax()); if (ci.getPrivateFax()) - setFieldValue("pvt_fax","Y"); + setFieldValue("pvt_fax",YES); setFieldValue("email",ci.getEmail()); if (ci.getPrivateEmail()) - setFieldValue("pvt_email","Y"); + setFieldValue("pvt_email",YES); setFieldValue("url",ci.getURL()); setFieldValue("descr",admuser.getDescription()); + setFieldValue("photo",ci.getPhotoURL()); + photo_control.setLinkURL("adminuserphoto?uid=" + admuser.getUID()); + if (props.getDisplayPostPictures()) + setFieldValue("pic_in_post",YES); setFieldValue("locale",admuser.getLocale().toString()); setFieldValue("tz",admuser.getTimeZone().getID()); @@ -215,8 +298,6 @@ public class AdminModifyUserDialog extends ContentDialog { validate(); // validate the dialog - final String yes = "Y"; // the "yes" string - try { // reset the base level admuser.setBaseLevel(Integer.parseInt(getFieldValue("base_lvl"))); @@ -233,12 +314,14 @@ public class AdminModifyUserDialog extends ContentDialog if (!StringUtil.isStringEmpty(foo)) admuser.setPassword(foo,getFieldValue("remind")); - admuser.setEmailVerified(yes.equals(getFieldValue("verify_email"))); - admuser.setLockedOut(yes.equals(getFieldValue("lockout"))); + admuser.setEmailVerified(YES.equals(getFieldValue("verify_email"))); + admuser.setLockedOut(YES.equals(getFieldValue("lockout"))); ContactInfo ci = admuser.getContactInfo(); // get the main contact info + AdminUserProperties props = admuser.getProperties(); // Reset all the contact info fields. + props.setDisallowPhoto(YES.equals(getFieldValue("nophoto"))); ci.setNamePrefix(getFieldValue("prefix")); ci.setGivenName(getFieldValue("first")); foo = getFieldValue("mid"); @@ -251,22 +334,24 @@ public class AdminModifyUserDialog extends ContentDialog ci.setCompany(getFieldValue("company")); ci.setAddressLine1(getFieldValue("addr1")); ci.setAddressLine2(getFieldValue("addr2")); - ci.setPrivateAddress(yes.equals(getFieldValue("pvt_addr"))); + ci.setPrivateAddress(YES.equals(getFieldValue("pvt_addr"))); ci.setLocality(getFieldValue("loc")); ci.setRegion(getFieldValue("reg")); ci.setPostalCode(getFieldValue("pcode")); ci.setCountry(getFieldValue("country")); ci.setPhone(getFieldValue("phone")); ci.setMobile(getFieldValue("mobile")); - ci.setPrivatePhone(yes.equals(getFieldValue("pvt_phone"))); + ci.setPrivatePhone(YES.equals(getFieldValue("pvt_phone"))); ci.setFax(getFieldValue("fax")); - ci.setPrivateFax(yes.equals(getFieldValue("pvt_fax"))); + ci.setPrivateFax(YES.equals(getFieldValue("pvt_fax"))); ci.setEmail(getFieldValue("email")); - ci.setPrivateEmail(yes.equals(getFieldValue("pvt_email"))); + ci.setPrivateEmail(YES.equals(getFieldValue("pvt_email"))); ci.setURL(getFieldValue("url")); + props.setDisplayPostPictures(YES.equals(getFieldValue("pic_in_post"))); // Store the completed contact info. admuser.putContactInfo(ci); + admuser.setProperties(props); // Save off the user's description and preferences. admuser.setDescription(getFieldValue("descr")); diff --git a/src/com/silverwrist/venice/servlets/format/AdminUserPhotoData.java b/src/com/silverwrist/venice/servlets/format/AdminUserPhotoData.java new file mode 100644 index 0000000..a1e7eb5 --- /dev/null +++ b/src/com/silverwrist/venice/servlets/format/AdminUserPhotoData.java @@ -0,0 +1,135 @@ +/* + * 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.awt.Dimension; +import javax.servlet.*; +import javax.servlet.http.*; +import com.silverwrist.util.StringUtil; +import com.silverwrist.venice.core.*; +import com.silverwrist.venice.except.*; + +public class AdminUserPhotoData implements JSPRender +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + // Attribute name for request attribute + protected static final String ATTR_NAME = "com.silverwrist.venice.content.AdminUserPhotoData"; + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private Dimension photo_dims; + private String photo_url; + private int uid; + private String user_name; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + public AdminUserPhotoData(VeniceEngine engine, AdminUserContext admuser, RenderData rdat) + throws DataException + { + photo_dims = engine.getUserPhotoSize(); + photo_url = admuser.getContactInfo().getPhotoURL(); + if (StringUtil.isStringEmpty(photo_url)) + photo_url = rdat.getPhotoNotAvailURL(); + this.uid = admuser.getUID(); + this.user_name = admuser.getUserName(); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * External static functions + *-------------------------------------------------------------------------------- + */ + + public static AdminUserPhotoData retrieve(ServletRequest request) + { + return (AdminUserPhotoData)(request.getAttribute(ATTR_NAME)); + + } // end retrieve + + /*-------------------------------------------------------------------------------- + * Implementations from interface VeniceContent + *-------------------------------------------------------------------------------- + */ + + public String getPageTitle(RenderData rdat) + { + return "Set User Photo"; + + } // end getPageTitle + + public String getPageQID() + { + return null; + + } // end getPageQID + + /*-------------------------------------------------------------------------------- + * Implementations from interface JSPRender + *-------------------------------------------------------------------------------- + */ + + public void store(ServletRequest request) + { + request.setAttribute(ATTR_NAME,this); + + } // end store + + public String getTargetJSPName() + { + return "admin_user_photo.jsp"; + + } // end getTargetJSPName + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + public int getUID() + { + return uid; + + } // end getUID + + public String getUserName() + { + return user_name; + + } // end getUserName + + public String getPhotoTag(RenderData rdat) + { + StringBuffer buf = new StringBuffer("\"\""); + return buf.toString(); + + } // end getPhotoTag + +} // end class AdminUserPhotoData diff --git a/src/com/silverwrist/venice/servlets/format/EditProfileDialog.java b/src/com/silverwrist/venice/servlets/format/EditProfileDialog.java index 9a32b6f..ee3941a 100644 --- a/src/com/silverwrist/venice/servlets/format/EditProfileDialog.java +++ b/src/com/silverwrist/venice/servlets/format/EditProfileDialog.java @@ -208,6 +208,7 @@ public class EditProfileDialog extends ContentDialog ContactInfo ci = uc.getContactInfo(); // get the main contact info UserProperties props = uc.getProperties(); // get the properties + setFieldEnabled("photo",ci.canSetPhoto()); setFieldValue("prefix",ci.getNamePrefix()); setFieldValue("first",ci.getGivenName()); char init = ci.getMiddleInitial(); @@ -300,11 +301,12 @@ public class EditProfileDialog extends ContentDialog } // end doDialog - public void resetOnError(String message) + public void resetOnError(boolean photo_flag, String message) { setErrorMessage(message); setFieldValue("pass1",null); setFieldValue("pass2",null); + setFieldEnabled("photo",photo_flag); } // end resetOnError diff --git a/web/format/admin_user_photo.jsp b/web/format/admin_user_photo.jsp new file mode 100644 index 0000000..1d6db45 --- /dev/null +++ b/web/format/admin_user_photo.jsp @@ -0,0 +1,43 @@ +<%-- + 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.*" %> +<% + AdminUserPhotoData data = AdminUserPhotoData.retrieve(request); + Variables.failIfNull(data); + RenderData rdat = RenderConfig.createRenderData(application,request,response); +%> +<% rdat.writeContentHeader(out,"Change User Photo","User: " + data.getUserName()); %> + +
"> +
<%= rdat.getStdFontTag(ColorSelectors.CONTENT_FOREGROUND,2) %> + + <%= data.getPhotoTag(rdat) %> + New user photo:
+

+ " NAME="upload" ALT="Upload" + WIDTH=80 HEIGHT=24 BORDER=0>  + " NAME="cancel" ALT="Cancel" + WIDTH=80 HEIGHT=24 BORDER=0>

+ ">Click + here to clear user's photo +

+