Committing changes resulted in merging trunk(r8181) to branch(r8120)

This commit is contained in:
deepakkoni 2011-06-10 18:08:34 +00:00
commit 3f2bf662d0
295 changed files with 10271 additions and 11133 deletions

View file

@ -66,7 +66,7 @@
--> -->
<!-- The StrField type is not analyzed, but indexed/stored verbatim. --> <!-- The StrField type is not analyzed, but indexed/stored verbatim. -->
<fieldType name="string" class="solr.StrField" sortMissingLast="true"/> <fieldType name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true"/>
<!-- boolean type: "true" or "false" --> <!-- boolean type: "true" or "false" -->
<fieldType name="boolean" class="solr.BoolField" sortMissingLast="true" omitNorms="true"/> <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true" omitNorms="true"/>
@ -480,19 +480,23 @@
<field name="classLocalName" type="text" indexed="true" stored="true" multiValued="true"/> <field name="classLocalName" type="text" indexed="true" stored="true" multiValued="true"/>
<field name="classLocalNameLowerCase" type="text" indexed="true" stored="false" multiValued="true"/> <field name="classLocalNameLowerCase" type="text" indexed="true" stored="false" multiValued="true"/>
<field name="classgroup" type="string" indexed="true" stored="true" omitNorms="true" multiValued="true"/> <field name="classgroup" type="string" indexed="true" stored="true" required="true" multiValued="true"/>
<field name="PROHIBITED_FROM_TEXT_RESULTS" type="string" indexed="true" stored="false" omitNorms="true" multiValued="false"/> <field name="PROHIBITED_FROM_TEXT_RESULTS" type="string" indexed="true" stored="false" omitNorms="true" multiValued="true"/>
<field name="URI" type="string" indexed="true" stored="true" multiValued="false" omitNorms="true"/> <field name="URI" type="string" indexed="true" stored="true" multiValued="false" omitNorms="true"/>
<field name="nameRaw" type="string" indexed="true" stored="true" multiValued="true"/> <field name="nameRaw" type="string" indexed="false" stored="true" multiValued="true"/>
<!-- RY Not sure if we need to store nameLowercase --> <!-- RY Not sure if we need to store nameLowercase -->
<field name="nameLowercase" type="string" indexed="true" stored="true" multiValued="true"/> <field name="nameLowercase" type="string" indexed="true" stored="true" multiValued="true"/>
<!-- A sortable version of nameLowercase --> <!-- A sortable version of nameLowercase -->
<field name="nameLowercaseSingleValued" type="lowercase" indexed="true" stored="false" multiValued="false" /> <field name="nameLowercaseSingleValued" type="lowercase" indexed="true" stored="false" multiValued="false" />
<field name="nameUnstemmed" type="text" indexed="true" stored="false" multiValued="true"/> <field name="nameUnstemmed" type="lowercase" indexed="true" stored="false" multiValued="true"/>
<field name="nameStemmed" type="text" indexed="true" stored="false" multiValued="true"/> <field name="nameStemmed" type="text" indexed="true" stored="false" multiValued="true"/>
<field name="acNameUnstemmed" type="textUnstemmed" indexed="true" stored="false" multiValued="true"/>
<field name="acNameStemmed" type="text" indexed="true" stored="false" multiValued="true"/> <!--
<field name="prefixNameUnstemmed" type="prefixTextUnstemmed" indexed="true" stored="false" multiValued="true"/>
<field name="prefixNameStemmed" type="prefixText" indexed="true" stored="false" multiValued="true"/>
-->
<field name="indexedTime" type="string" indexed="true" stored="true" multiValued="true"/> <field name="indexedTime" type="string" indexed="true" stored="true" multiValued="true"/>
<field name="NAME_PHONETIC" type ="phonetic" indexed="true" stored="false" multiValued="true"/> <field name="NAME_PHONETIC" type ="phonetic" indexed="true" stored="false" multiValued="true"/>

View file

@ -108,16 +108,14 @@ deploy - Deploy the application directly into the Tomcat webapps directory.
message="${deploy.properties.file} must contain a value for vitro.home.directory" /> message="${deploy.properties.file} must contain a value for vitro.home.directory" />
<fail unless="Vitro.defaultNamespace" <fail unless="Vitro.defaultNamespace"
message="${deploy.properties.file} must contain a value for Vitro.defaultNamespace" /> message="${deploy.properties.file} must contain a value for Vitro.defaultNamespace" />
<fail unless="Vitro.smtpHost"
message="${deploy.properties.file} must contain a value for Vitro.smtpHost (may be empty)" />
<fail unless="VitroConnection.DataSource.url" <fail unless="VitroConnection.DataSource.url"
message="${deploy.properties.file} must contain a value for VitroConnection.DataSource.url" /> message="${deploy.properties.file} must contain a value for VitroConnection.DataSource.url" />
<fail unless="VitroConnection.DataSource.username" <fail unless="VitroConnection.DataSource.username"
message="${deploy.properties.file} must contain a value for VitroConnection.DataSource.username" /> message="${deploy.properties.file} must contain a value for VitroConnection.DataSource.username" />
<fail unless="VitroConnection.DataSource.password" <fail unless="VitroConnection.DataSource.password"
message="${deploy.properties.file} must contain a value for VitroConnection.DataSource.password" /> message="${deploy.properties.file} must contain a value for VitroConnection.DataSource.password" />
<fail unless="initialAdminUser" <fail unless="rootUser.emailAddress"
message="${deploy.properties.file} must contain a value for initialAdminUser" /> message="${deploy.properties.file} must contain a value for rootUser.emailAddress" />
</target> </target>

View file

@ -38,10 +38,12 @@ webapp.name = vitro
vitro.home.directory = /usr/local/vitro/data vitro.home.directory = /usr/local/vitro/data
# #
# SMTP host which the "Contact Us" form can use to send mail. If this is left # Email parameters which VIVO can use to send mail. If these are left empty,
# empty, the "Contact Us" form will be disabled. # the "Contact Us" form will be disabled and users will not be notified of
# changes to their accounts.
# #
Vitro.smtpHost = email.smtpHost = smtp.my.domain.edu
email.replyTo = vivoAdmin@my.domain.edu
# #
# The basic parameters for a MySQL database connection. Change the end of the # The basic parameters for a MySQL database connection. Change the end of the
@ -52,6 +54,27 @@ VitroConnection.DataSource.url = jdbc:mysql://localhost/vitro
VitroConnection.DataSource.username = vitroweb VitroConnection.DataSource.username = vitroweb
VitroConnection.DataSource.password = vitrovitro VitroConnection.DataSource.password = vitrovitro
#
# The maximum number of active connections in the database connection pool.
# Increase this value to support a greater number of concurrent page requests.
#
VitroConnection.DataSource.pool.maxActive = 40
#
# The maximum number of database connections that will be allowed
# to remain idle in the connection pool. Default is 25%
# of the maximum number of active connections.
#
VitroConnection.DataSource.pool.maxIdle = 10
#
# Parameters to change in order to use VIVO with a database other than
# MySQL.
#
VitroConnection.DataSource.dbtype = MySQL
VitroConnection.DataSource.driver = com.mysql.jdbc.Driver
VitroConnection.DataSource.validationQuery = SELECT 1
# #
# The URL to connect to for the Solr service that is used by the application. # The URL to connect to for the Solr service that is used by the application.
# The Solr service provides the application with full text search and many # The Solr service provides the application with full text search and many
@ -61,11 +84,11 @@ VitroConnection.DataSource.password = vitrovitro
# vitro.local.solr.url = # vitro.local.solr.url =
# #
# The name of your first admin user for the Vitro application. The password # The email address of the root user for the VIVO application. The password
# for this user is initially set to "defaultAdmin", but you will be asked to # for this user is initially set to "rootPassword", but you will be asked to
# change the password the first time you log in. # change the password the first time you log in.
# #
initialAdminUser = defaultAdmin rootUser.emailAddress = root@myDomain.com
# #
# How is a logged-in user associated with a particular Individual? One way is # How is a logged-in user associated with a particular Individual? One way is

View file

@ -50,6 +50,10 @@
<listener-class>edu.cornell.mannlib.vitro.webapp.config.RevisionInfoSetup</listener-class> <listener-class>edu.cornell.mannlib.vitro.webapp.config.RevisionInfoSetup</listener-class>
</listener> </listener>
<listener>
<listener-class>edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory$Setup</listener-class>
</listener>
<!-- DefaultThemeSetup needs to run before the JenaDataSourceSetup <!-- DefaultThemeSetup needs to run before the JenaDataSourceSetup
to allow creation of default portal and tab --> to allow creation of default portal and tab -->
<listener> <listener>
@ -100,6 +104,13 @@
</listener-class> </listener-class>
</listener> </listener>
<!-- Update to the new UserAccounts model (1.3). Needs to run after JenaDataSourceSetup. -->
<listener>
<listener-class>
edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateUserAccounts
</listener-class>
</listener>
<!-- Attaching submodels permits extra RDF files to be made visible without storing the data in the DB. --> <!-- Attaching submodels permits extra RDF files to be made visible without storing the data in the DB. -->
<listener> <listener>
<listener-class>edu.cornell.mannlib.vitro.webapp.servlet.setup.AttachSubmodels</listener-class> <listener-class>edu.cornell.mannlib.vitro.webapp.servlet.setup.AttachSubmodels</listener-class>
@ -110,11 +121,9 @@
<!-- See documentation for details. --> <!-- See documentation for details. -->
<!-- If used, must be run after JenaDataSourceSetup --> <!-- If used, must be run after JenaDataSourceSetup -->
<!--
<listener> <listener>
<listener-class>edu.cornell.mannlib.vitro.webapp.servlet.setup.PelletReasonerSetup</listener-class> <listener-class>edu.cornell.mannlib.vitro.webapp.servlet.setup.PelletReasonerSetup</listener-class>
</listener> </listener>
-->
<!-- The followng listener records all edit changes, in reified form, to another database model --> <!-- The followng listener records all edit changes, in reified form, to another database model -->
<!-- still at an experimental stage --> <!-- still at an experimental stage -->
@ -128,6 +137,10 @@
</listener> </listener>
--> -->
<listener>
<listener-class>edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSetsLoader</listener-class>
</listener>
<listener> <listener>
<listener-class> edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper$Setup <listener-class> edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper$Setup
</listener-class> </listener-class>
@ -138,39 +151,21 @@
</listener-class> </listener-class>
</listener> </listener>
<listener>
<listener-class> edu.cornell.mannlib.vitro.webapp.auth.policy.RootUserPolicy$Setup</listener-class>
</listener>
<!-- The Lucene index uses a "public" filter, so the PropertyRestrictionPolicyHelper must already be set up. --> <!-- The Lucene index uses a "public" filter, so the PropertyRestrictionPolicyHelper must already be set up. -->
<!--
<listener> <listener>
<listener-class> edu.cornell.mannlib.vitro.webapp.search.lucene.LuceneSetup </listener-class> <listener-class> edu.cornell.mannlib.vitro.webapp.search.lucene.LuceneSetup </listener-class>
</listener> </listener>
-->
<!--
<listener> <listener>
<listener-class> <listener-class>
edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup
</listener-class> </listener-class>
</listener> </listener>
-->
<!--<listener>
<listener-class>
edu.cornell.mannlib.vitro.webapp.auth.policy.setup.SelfEditingPolicySetup
</listener-class>
</listener> -->
<listener>
<listener-class> edu.cornell.mannlib.vitro.webapp.auth.policy.setup.EditorEditingPolicySetup
</listener-class>
</listener>
<listener>
<listener-class> edu.cornell.mannlib.vitro.webapp.auth.policy.setup.CuratorEditingPolicySetup
</listener-class>
</listener>
<listener>
<listener-class> edu.cornell.mannlib.vitro.webapp.auth.policy.setup.DbAdminEditingPolicySetup
</listener-class>
</listener>
<listener> <listener>
<listener-class> <listener-class>
@ -644,15 +639,6 @@
<url-pattern>/keywordEdit</url-pattern> <url-pattern>/keywordEdit</url-pattern>
</servlet-mapping> </servlet-mapping>
<servlet>
<servlet-name>UserEditController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.edit.UserEditController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserEditController</servlet-name>
<url-pattern>/userEdit</url-pattern>
</servlet-mapping>
<servlet> <servlet>
<servlet-name>OntologyEditController</servlet-name> <servlet-name>OntologyEditController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.edit.OntologyEditController</servlet-class> <servlet-class>edu.cornell.mannlib.vitro.webapp.controller.edit.OntologyEditController</servlet-class>
@ -752,23 +738,31 @@
<url-pattern>/addRestriction</url-pattern> <url-pattern>/addRestriction</url-pattern>
</servlet-mapping> </servlet-mapping>
<!-- TODO This should go away as soon as the new UserAccounts are fully implemented. jblake -->
<servlet> <servlet>
<servlet-name>UsersListingController</servlet-name> <servlet-name>AccountsAdmin</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.edit.listing.UsersListingController</servlet-class> <servlet-class>edu.cornell.mannlib.vitro.webapp.controller.accounts.admin.UserAccountsAdminController</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>
<servlet-name>UsersListingController</servlet-name> <servlet-name>AccountsAdmin</servlet-name>
<url-pattern>/listUsers</url-pattern> <url-pattern>/accountsAdmin/*</url-pattern>
</servlet-mapping> </servlet-mapping>
<servlet> <servlet>
<servlet-name>UserAccounts</servlet-name> <servlet-name>AccountsUser</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsController</servlet-class> <servlet-class>edu.cornell.mannlib.vitro.webapp.controller.accounts.user.UserAccountsUserController</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>
<servlet-name>UserAccounts</servlet-name> <servlet-name>AccountsUser</servlet-name>
<url-pattern>/userAccounts/*</url-pattern> <url-pattern>/accounts/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ShowAuth</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.admin.ShowAuthController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ShowAuth</servlet-name>
<url-pattern>/admin/showAuth</url-pattern>
</servlet-mapping> </servlet-mapping>
<servlet> <servlet>
@ -871,42 +865,42 @@
<url-pattern>/listObjectPropertyStatements</url-pattern> <url-pattern>/listObjectPropertyStatements</url-pattern>
</servlet-mapping> </servlet-mapping>
<!--
<servlet> <servlet>
<servlet-name>IndividualListController</servlet-name> <servlet-name>IndividualListController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController</servlet-class> <servlet-class>edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController</servlet-class>
</servlet> </servlet>
<!-- -->
<servlet> <servlet>
<servlet-name>IndividualListController</servlet-name> <servlet-name>IndividualListController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.freemarker.SolrIndividualListController</servlet-class> <servlet-class>edu.cornell.mannlib.vitro.webapp.controller.freemarker.SolrIndividualListController</servlet-class>
</servlet> </servlet>
-->
<servlet-mapping> <servlet-mapping>
<servlet-name>IndividualListController</servlet-name> <servlet-name>IndividualListController</servlet-name>
<url-pattern>/individuallist</url-pattern> <url-pattern>/individuallist</url-pattern>
</servlet-mapping> </servlet-mapping>
<servlet> <!--
<servlet>
<servlet-name>IndividualListRdf</servlet-name> <servlet-name>IndividualListRdf</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.EntityURLController</servlet-class> <servlet-class>edu.cornell.mannlib.vitro.webapp.controller.EntityURLController</servlet-class>
</servlet> </servlet>
<!-- -->
<servlet> <servlet>
<servlet-name>IndividualListRdf</servlet-name> <servlet-name>IndividualListRdf</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.IndividualListRdfController</servlet-class> <servlet-class>edu.cornell.mannlib.vitro.webapp.controller.IndividualListRdfController</servlet-class>
</servlet> </servlet>
-->
<servlet-mapping> <servlet-mapping>
<servlet-name>IndividualListRdf</servlet-name> <servlet-name>IndividualListRdf</servlet-name>
<url-pattern>/listrdf/*</url-pattern> <url-pattern>/listrdf/*</url-pattern>
</servlet-mapping> </servlet-mapping>
<!-- <!--
<servlet> <servlet>
<servlet-name>SearchController</servlet-name> <servlet-name>SearchController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.search.controller.PagedSearchController</servlet-class> <servlet-class>edu.cornell.mannlib.vitro.webapp.search.controller.PagedSearchController</servlet-class>
</servlet> </servlet>
--> -->
<servlet> <servlet>
<servlet-name>SearchController</servlet-name> <servlet-name>SearchController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.search.controller.SolrPagedSearchController</servlet-class> <servlet-class>edu.cornell.mannlib.vitro.webapp.search.controller.SolrPagedSearchController</servlet-class>
@ -930,16 +924,16 @@
<url-pattern>/searchcontroller</url-pattern> <url-pattern>/searchcontroller</url-pattern>
</servlet-mapping> </servlet-mapping>
<!--
<servlet> <servlet>
<servlet-name>AutocompleteController</servlet-name> <servlet-name>AutocompleteController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.search.controller.AutocompleteController</servlet-class> <servlet-class>edu.cornell.mannlib.vitro.webapp.search.controller.AutocompleteController</servlet-class>
</servlet> </servlet>
<!-- -->
<servlet> <servlet>
<servlet-name>AutocompleteController</servlet-name> <servlet-name>AutocompleteController</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.search.controller.SolrAutocompleteController</servlet-class> <servlet-class>edu.cornell.mannlib.vitro.webapp.search.controller.SolrAutocompleteController</servlet-class>
</servlet> </servlet>
-->
<servlet-mapping> <servlet-mapping>
<servlet-name>AutocompleteController</servlet-name> <servlet-name>AutocompleteController</servlet-name>
<url-pattern>/autocomplete</url-pattern> <url-pattern>/autocomplete</url-pattern>
@ -985,10 +979,16 @@
<url-pattern>/contact</url-pattern> <url-pattern>/contact</url-pattern>
</servlet-mapping> </servlet-mapping>
<!--
<servlet> <servlet>
<servlet-name>JSON Service</servlet-name> <servlet-name>JSON Service</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.JSONServlet</servlet-class> <servlet-class>edu.cornell.mannlib.vitro.webapp.controller.JSONServlet</servlet-class>
</servlet> </servlet>
-->
<servlet>
<servlet-name>JSON Service</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.SolrJsonServlet</servlet-class>
</servlet>
<servlet-mapping> <servlet-mapping>
<servlet-name>JSON Service</servlet-name> <servlet-name>JSON Service</servlet-name>
<url-pattern>/dataservice</url-pattern> <url-pattern>/dataservice</url-pattern>

Binary file not shown.

View file

@ -0,0 +1,33 @@
# $This file is distributed under the terms of the license in /doc/license.txt$
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix display: <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
### This file defines the default menu for vitro. ###
#### Default Menu ####
display:DefaultMenu
a display:MainMenu ;
display:hasElement display:EventsMenuItem ;
display:hasElement display:HomeMenuItem ;
display:hasElement display:OrganizationsMenuItem ;
display:hasElement display:PeopleMenuItem ;
display:hasElement display:ResearchMenuItem .
#### Menu Items for Default Menu ####
display:HomeMenuItem
a display:NavigationElement ;
display:menuPosition 1;
display:linkText "Home";
display:toPage display:Home .
########## Pages ############
display:Home
a display:HomePage ;
a display:Page ;
display:title "Home" ;
display:urlMapping "/" .

View file

@ -1,242 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vedit.beans;
import java.util.Hashtable;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
*
* @author jc55
*
*/
public class LoginFormBean {
public static final int ANYBODY = 0;
public int getAnybody() {
return ANYBODY;
}
public static final int NON_EDITOR = 1;
public int getNonEditor() {
return NON_EDITOR;
}
public static final int EDITOR = 4;
public int getEditor() {
return EDITOR;
}
public static final int CURATOR = 5;
public int getCurator() {
return CURATOR;
}
public static final int DBA = 50;
public int getDba() {
return DBA;
}
public boolean getBla() {
return true;
}
private String userURI;
private String sessionId;
private String loginBrowser;
private String loginRemoteAddr;
private String loginName;
private String loginPassword;
private String loginStatus;
private int loginUserId;
private String loginRole;
private String duplicatePassword;
private String emailAddress;
private Hashtable<String, String> errors;
public boolean validateLoginForm() {
boolean allOk = true;
if (loginName.equals("")) {
errors.put("loginName", "Please enter your Vivo user name");
loginName = "";
allOk = false;
}
if (loginPassword.equals("")) {
errors.put("loginPassword", "Please enter your Vivo password");
loginPassword = "";
allOk = false;
}
return allOk;
}
public LoginFormBean() {
sessionId = "";
loginBrowser = "";
loginRemoteAddr = "";
loginName = "";
loginPassword = "";
loginStatus = "none";
loginUserId = 0;
loginRole = "1";
duplicatePassword = "";
emailAddress = "";
errors = new Hashtable<String, String>();
}
public String toString() {
String name = "-not-logged-in-";
if (getLoginName() != null && !"".equals(getLoginName()))
name = getLoginName();
return this.getClass().getName() + " loginName: " + name
+ " loginStatus: " + getLoginStatus() + " loginRole: "
+ getLoginRole();
}
/**
* Tests a HttpSession to see if logged in and authenticated.
*
* @returns loginRole if seems to be authenticated, -1 otherwise
*/
public int testSessionLevel(HttpServletRequest request) {
// TODO: security code added by bdc34, should be checked by jc55
HttpSession currentSession = request.getSession();
int returnRole = -1;
if (getLoginStatus().equals("authenticated")
&& currentSession.getId().equals(getSessionId())
&& request.getRemoteAddr().equals(getLoginRemoteAddr())) {
try {
returnRole = Integer.parseInt(getLoginRole());
} catch (Throwable thr) {
}
}
return returnRole;
}
public static boolean loggedIn(HttpServletRequest request, int minLevel) {
if (request == null)
return false;
HttpSession sess = request.getSession(false);
if (sess == null)
return false;
Object obj = sess.getAttribute("loginHandler");
if (obj == null || !(obj instanceof LoginFormBean))
return false;
LoginFormBean lfb = (LoginFormBean) obj;
return ("authenticated".equals(lfb.loginStatus) && Integer
.parseInt(lfb.loginRole) >= minLevel);
}
/********************** GET METHODS *********************/
public String getUserURI() {
return userURI;
}
public String getSessionId() {
return sessionId;
}
public String getLoginBrowser() {
return loginBrowser;
}
public String getLoginRemoteAddr() {
return loginRemoteAddr;
}
public String getLoginName() {
return loginName;
}
public String getLoginPassword() {
return loginPassword;
}
public String getLoginStatus() {
return loginStatus;
}
public int getLoginUserId() {
return loginUserId;
}
public String getLoginRole() {
return loginRole;
}
public String getDuplicatePassword() {
return duplicatePassword;
}
public String getEmailAddress() {
return emailAddress;
}
public String getErrorMsg(String s) {
String errorMsg = (String) errors.get(s.trim());
return (errorMsg == null) ? "" : errorMsg;
}
/********************** SET METHODS *********************/
public void setUserURI(String uri) {
this.userURI = uri;
}
public void setSessionId(String id) {
sessionId = id;
}
public void setLoginBrowser(String b) {
loginBrowser = b;
}
public void setLoginRemoteAddr(String ra) {
loginRemoteAddr = ra;
}
public void setLoginName(String ln) {
loginName = ln;
}
public void setLoginPassword(String lp) {
loginPassword = lp;
}
public void setLoginStatus(String ls) {
loginStatus = ls;
}
public void setLoginUserId(int int_val) {
loginUserId = int_val;
}
public void setLoginRole(String lr) {
loginRole = lr;
}
public void setDuplicatePassword(String dp) {
duplicatePassword = dp;
}
public void setEmailAddress(String ea) {
emailAddress = ea;
}
public void setErrorMsg(String key, String msg) {
errors.put(key, msg);
}
}

View file

@ -2,12 +2,17 @@
package edu.cornell.mannlib.vedit.beans; package edu.cornell.mannlib.vedit.beans;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
/** /**
* An immutable object that records the user's login info as a session * An immutable object that records the user's login info as a session
* attribute. * attribute.
@ -15,27 +20,9 @@ import org.apache.commons.logging.LogFactory;
public class LoginStatusBean { public class LoginStatusBean {
private static final Log log = LogFactory.getLog(LoginStatusBean.class); private static final Log log = LogFactory.getLog(LoginStatusBean.class);
/**
* Security level when the user has not logged in. Also used as a minimum
* level when we want to include every user, logged in or not.
*/
public static final int ANYBODY = 0;
/** Security level when a user with no privileges is logged in. */
public static final int NON_EDITOR = 1;
/** Security level when an authorized editor is logged in. */
public static final int EDITOR = 4;
/** Security level when an authorized curator is logged in. */
public static final int CURATOR = 5;
/** Security level when a system administrator is logged in. */
public static final int DBA = 50;
/** A bean to return when the user has not logged in. */ /** A bean to return when the user has not logged in. */
private static final LoginStatusBean DUMMY_BEAN = new LoginStatusBean("", private static final LoginStatusBean DUMMY_BEAN = new LoginStatusBean("",
"", ANYBODY, AuthenticationSource.UNKNOWN); AuthenticationSource.UNKNOWN);
/** The bean is attached to the session by this name. */ /** The bean is attached to the session by this name. */
private static final String ATTRIBUTE_NAME = "loginStatus"; private static final String ATTRIBUTE_NAME = "loginStatus";
@ -91,6 +78,46 @@ public class LoginStatusBean {
return (LoginStatusBean) o; return (LoginStatusBean) o;
} }
/**
* Get the current user, or null if not logged in.
*/
public static UserAccount getCurrentUser(HttpServletRequest request) {
if (request == null) {
return null;
}
return getCurrentUser(request.getSession(false));
}
/**
* Get the current user, or null if not logged in.
*/
public static UserAccount getCurrentUser(HttpSession session) {
if (session == null) {
return null;
}
if (!getBean(session).isLoggedIn()) {
return null;
}
ServletContext ctx = session.getServletContext();
WebappDaoFactory wadf = (WebappDaoFactory) ctx
.getAttribute("webappDaoFactory");
if (wadf == null) {
log.error("No WebappDaoFactory");
return null;
}
UserAccountsDao userAccountsDao = wadf.getUserAccountsDao();
if (userAccountsDao == null) {
log.error("No UserAccountsDao");
return null;
}
String userUri = getBean(session).getUserURI();
return userAccountsDao.getUserAccountByUri(userUri);
}
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// the bean // the bean
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@ -100,15 +127,11 @@ public class LoginStatusBean {
} }
private final String userURI; private final String userURI;
private final String username;
private final int securityLevel;
private final AuthenticationSource authenticationSource; private final AuthenticationSource authenticationSource;
public LoginStatusBean(String userURI, String username, int securityLevel, public LoginStatusBean(String userURI,
AuthenticationSource authenticationSource) { AuthenticationSource authenticationSource) {
this.userURI = userURI; this.userURI = userURI;
this.username = username;
this.securityLevel = securityLevel;
this.authenticationSource = authenticationSource; this.authenticationSource = authenticationSource;
} }
@ -116,28 +139,12 @@ public class LoginStatusBean {
return userURI; return userURI;
} }
public String getUsername() {
return username;
}
public int getSecurityLevel() {
return securityLevel;
}
public AuthenticationSource getAuthenticationSource() { public AuthenticationSource getAuthenticationSource() {
return authenticationSource; return authenticationSource;
} }
public boolean isLoggedIn() { public boolean isLoggedIn() {
return securityLevel > ANYBODY; return authenticationSource != AuthenticationSource.UNKNOWN;
}
public boolean isLoggedInExactly(int level) {
return securityLevel == level;
}
public boolean isLoggedInAtLeast(int minimumLevel) {
return securityLevel >= minimumLevel;
} }
public boolean hasExternalAuthentication() { public boolean hasExternalAuthentication() {
@ -146,9 +153,8 @@ public class LoginStatusBean {
@Override @Override
public String toString() { public String toString() {
return "LoginStatusBean[userURI=" + userURI + ", username=" + username return "LoginStatusBean[userURI=" + userURI + ", authenticationSource="
+ ", securityLevel=" + securityLevel + authenticationSource + "]";
+ ", authenticationSource=" + authenticationSource + "]";
} }
} }

View file

@ -51,6 +51,18 @@ public class ActiveIdentifierBundleFactories {
getActiveFactories(ctx).addFactory(factory); getActiveFactories(ctx).addFactory(factory);
} }
/**
* Just for diagnostics. Don't expose the factories themselves, only their names.
*/
public static List<String> getFactoryNames(ServletContext ctx) {
List<String> names = new ArrayList<String>();
ActiveIdentifierBundleFactories actFact = getActiveFactories(ctx);
for (IdentifierBundleFactory factory: actFact.factories) {
names.add(factory.toString());
}
return names;
}
/** /**
* Get the Identifiers from the list of factories. This might return an * Get the Identifiers from the list of factories. This might return an
* empty bundle, but it never returns null. * empty bundle, but it never returns null.
@ -118,5 +130,4 @@ public class ActiveIdentifierBundleFactories {
} }
return ib; return ib;
} }
} }

View file

@ -1,45 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.identifier;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpSession;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.auth.policy.RoleBasedPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.RoleBasedPolicy.AuthRole;
public class CuratorEditingIdentifierFactory implements IdentifierBundleFactory{
public IdentifierBundle getIdentifierBundle(ServletRequest request,
HttpSession session, ServletContext context) {
IdentifierBundle ib = new ArrayIdentifierBundle();
ib.add( RoleBasedPolicy.AuthRole.ANYBODY);
LoginStatusBean loginBean = LoginStatusBean.getBean(session);
if (loginBean.isLoggedInAtLeast(LoginStatusBean.CURATOR)) {
String loginRole = String.valueOf(loginBean.getSecurityLevel());
ib.add(new CuratorEditingId(loginRole, loginBean.getUserURI()));
ib.add(AuthRole.CURATOR);
}
return ib;
}
public static class CuratorEditingId extends RoleIdentifier {
final String role;
final String uri;
public CuratorEditingId( String role, String uri) {
this.role = role;
this.uri = uri;
}
public String getRole() { return role; }
public String getUri(){ return uri; }
public String toString(){ return "CuratorEditingId: " + uri; }
}
}

View file

@ -1,49 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.identifier;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpSession;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.auth.policy.RoleBasedPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.RoleBasedPolicy.AuthRole;
public class DbAdminEditingIdentifierFactory implements IdentifierBundleFactory{
public IdentifierBundle getIdentifierBundle(ServletRequest request,
HttpSession session, ServletContext context) {
IdentifierBundle ib = new ArrayIdentifierBundle();
ib.add( RoleBasedPolicy.AuthRole.ANYBODY);
LoginStatusBean loginBean = LoginStatusBean.getBean(session);
if (loginBean.isLoggedInAtLeast(LoginStatusBean.DBA)) {
String loginRole = String.valueOf(loginBean.getSecurityLevel());
ib.add(new DbAdminEditingId(loginRole, loginBean.getUserURI()));
ib.add(AuthRole.DBA);
}
return ib;
}
public static class DbAdminEditingId extends RoleIdentifier{
final String role;
final String uri;
public DbAdminEditingId( String role, String uri) {
this.role = role;
this.uri = uri;
}
public String getRole() {
return role;
}
public String getUri(){ return uri; }
public String toString(){
return "DbAdminEditingId: role of " + getRole();
}
}
}

View file

@ -1,48 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.identifier;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpSession;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.auth.policy.RoleBasedPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.RoleBasedPolicy.AuthRole;
public class EditorEditingIdentifierFactory implements IdentifierBundleFactory{
public IdentifierBundle getIdentifierBundle(ServletRequest request,
HttpSession session, ServletContext context) {
IdentifierBundle ib = new ArrayIdentifierBundle();
ib.add( RoleBasedPolicy.AuthRole.ANYBODY);
LoginStatusBean loginBean = LoginStatusBean.getBean(session);
if (loginBean.isLoggedInAtLeast(LoginStatusBean.EDITOR)) {
String loginRole = String.valueOf(loginBean.getSecurityLevel());
ib.add(new EditorEditingId(loginRole, loginBean.getUserURI()));
ib.add(AuthRole.EDITOR);
}
return ib;
}
public static class EditorEditingId implements Identifier {
final String role;
final String uri;
public EditorEditingId( String role, String uri) {
this.role = role;
this.uri = uri;
}
public String getUri(){ return uri; }
public String getRole() {
return role;
}
public String toString(){
return "Editor role of " + getRole();
}
}
}

View file

@ -1,363 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.identifier;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
/**
* Attempts to pull a NetId and a SelfEditing identifier from the externally
* authorized username.
*/
public class SelfEditingIdentifierFactory implements IdentifierBundleFactory {
private static final Log log = LogFactory.getLog(SelfEditingIdentifierFactory.class);
private static final int MAXIMUM_USERNAME_LENGTH = 100;
@Override
public IdentifierBundle getIdentifierBundle(ServletRequest request,
HttpSession session, ServletContext context) {
if (!(request instanceof HttpServletRequest)) {
log.debug("request is null or not an HttpServletRequest");
return null;
}
HttpServletRequest req = (HttpServletRequest) request;
log.debug("request is for " + req.getRequestURI());
NetId netId = figureNetId(req);
SelfEditing selfId = figureSelfEditingId(req);
return buildIdentifierBundle(netId, selfId);
}
/**
* If the user is externally authorized, create a NetId identifier.
*/
private NetId figureNetId(HttpServletRequest req) {
LoginStatusBean bean = LoginStatusBean.getBean(req);
String username = bean.getUsername();
if (!bean.isLoggedIn()) {
log.debug("No NetId: not logged in.");
return null;
}
if (isEmpty(username)) {
log.debug("No NetId: username is empty.");
return null;
}
if (!bean.hasExternalAuthentication()) {
log.debug("No NetId: user '" + bean.getUsername() +
"' did not use external authentication.");
return null;
}
if (username.length() > MAXIMUM_USERNAME_LENGTH) {
log.info("The external username is longer than " + MAXIMUM_USERNAME_LENGTH
+ " chars; this may be a malicious request");
return null;
}
return new NetId(username);
}
/**
* If the authorized username is associated with an Individual in the model,
* create a SelfEditing identifier.
*/
private SelfEditing figureSelfEditingId(HttpServletRequest req) {
LoginStatusBean bean = LoginStatusBean.getBean(req);
String username = bean.getUsername();
if (!bean.isLoggedIn()) {
log.debug("No SelfEditing: not logged in.");
return null;
}
if (isEmpty(username)) {
log.debug("No SelfEditing: username is empty.");
return null;
}
HttpSession session = req.getSession(false);
if (session == null) {
log.debug("No SelfEditing: session is null.");
return null;
}
ServletContext context = session.getServletContext();
WebappDaoFactory wdf = (WebappDaoFactory) context
.getAttribute("webappDaoFactory");
if (wdf == null) {
log.error("Could not get a WebappDaoFactory from the ServletContext");
return null;
}
IndividualDao indDao = wdf.getIndividualDao();
SelfEditingConfiguration sec = SelfEditingConfiguration.getBean(req);
String uri = sec.getIndividualUriFromUsername(indDao, username);
if (uri == null) {
log.debug("Could not find an Individual with a netId of "
+ username);
return null;
}
Individual ind = indDao.getIndividualByURI(uri);
if (ind == null) {
log.warn("Found a URI for the netId " + username
+ " but could not build Individual");
return null;
}
log.debug("Found an Individual for netId " + username + " URI: " + uri);
String blacklisted = checkForBlacklisted(ind, context);
return new SelfEditing(ind, blacklisted, false);
}
/**
* Create a bundle that holds the identifiers we created, or null if we
* didn't create any.
*/
private IdentifierBundle buildIdentifierBundle(NetId netId,
SelfEditing selfId) {
if (netId == null && selfId == null) {
log.debug("no self-editing IDs in the session");
return null;
}
IdentifierBundle idb = new ArrayIdentifierBundle();
if (netId != null) {
idb.add(netId);
log.debug("added NetId from session: " + netId);
}
if (selfId != null) {
idb.add(selfId);
log.debug("added SelfEditing from Session: " + selfId);
}
return idb;
}
private boolean isEmpty(String string) {
return (string == null || string.isEmpty());
}
// ----------------------------------------------------------------------
// static utility methods
// ----------------------------------------------------------------------
public static final String NOT_BLACKLISTED = null;
private final static String BLACKLIST_SPARQL_DIR = "/admin/selfEditBlacklist";
/**
* Runs through .sparql files in the BLACKLIST_SPARQL_DIR, the first that returns one
* or more rows will be cause the user to be blacklisted. The first variable from
* the first solution set will be returned.
*/
public static String checkForBlacklisted(Individual ind, ServletContext context) {
if( ind == null || context == null ) {
log.error("could not check for Blacklist, null individual or context");
return NOT_BLACKLISTED;
}
String realPath = context.getRealPath(BLACKLIST_SPARQL_DIR);
File blacklistDir = new File(realPath );
if( !blacklistDir.exists()){
log.debug("could not find blacklist directory " + realPath);
return NOT_BLACKLISTED;
}
if( ! blacklistDir.canRead() || ! blacklistDir.isDirectory() ){
log.debug("cannot read blacklist directory " + realPath);
return NOT_BLACKLISTED;
}
log.debug("checking directlry " + realPath + " for blacklisting sparql query files");
File[] files = blacklistDir.listFiles(new FileFilter(){
@Override
public boolean accept(File pathname) {
return pathname.getName().endsWith(".sparql");
}}
);
String reasonForBlacklist = NOT_BLACKLISTED;
for( File file : files ){
try{
reasonForBlacklist = runSparqlFileForBlacklist( file, ind, context);
if( reasonForBlacklist != NOT_BLACKLISTED )
break;
}catch(RuntimeException ex){
log.error("Could not run blacklist check query for file " +
file.getAbsolutePath() + File.separatorChar + file.getName(),
ex);
}
}
return reasonForBlacklist;
}
/**
* Runs the SPARQL query in the file with the uri of the individual
* substituted in. If there are any solution sets, then the URI of
* the variable named "cause" will be returned, make sure that it is a
* resource with a URI. Otherwise null will be returned.
* The URI of ind will be substituted into the query where ever the
* token "?individualURI" is found.
*/
private static String runSparqlFileForBlacklist
(File file, Individual ind, ServletContext context)
{
if( !file.canRead() ){
log.debug("cannot read blacklisting SPARQL file " + file.getName());
return NOT_BLACKLISTED;
}
String queryString = null;
FileInputStream fis = null;
try{
fis = new FileInputStream(file);
byte b[]= new byte[fis.available()];
fis.read(b);
queryString = new String(b);
}catch( FileNotFoundException fnfe){
log.debug(fnfe);
return NOT_BLACKLISTED;
}catch( IOException ioe){
log.debug(ioe);
return NOT_BLACKLISTED;
}finally{
try {
fis.close();
} catch (IOException e) {
log.warn("could not close file", e);
}
}
if( queryString == null || queryString.length() == 0 ){
log.debug(file.getName() + " is empty");
return NOT_BLACKLISTED;
}
Model model = (Model)context.getAttribute("jenaOntModel");
// VitroRequest request = new VitroRequest(req);
// Dataset dataset = request.getDataset();
queryString = queryString.replaceAll("\\?individualURI", "<" + ind.getURI() + ">");
log.debug(queryString);
Query query = QueryFactory.create(queryString);
QueryExecution qexec = QueryExecutionFactory.create(query,model);
try{
ResultSet results = qexec.execSelect();
while(results.hasNext()){
QuerySolution solution = results.nextSolution();
if( solution.contains("cause") ){
RDFNode node = solution.get("cause");
if( node.canAs( Resource.class ) ){
Resource x = solution.getResource("cause");
return x.getURI();
}else if( node.canAs(Literal.class)){
Literal x = (Literal)node.as(Literal.class);
return x.getString();
}
}else{
log.error("Query solution must contain a variable \"cause\" of type Resource or Literal.");
return null;
}
}
}finally{ qexec.close(); }
return null;
}
public static SelfEditing getSelfEditingIdentifier( IdentifierBundle whoToAuth ){
if( whoToAuth == null ) return null;
for(Identifier id : whoToAuth){
if (id instanceof SelfEditing)
return (SelfEditing)id;
}
return null;
}
public static String getSelfEditingUri( IdentifierBundle whoToAuth){
SelfEditing sid = getSelfEditingIdentifier(whoToAuth);
if( sid != null )
return sid.getValue();
else
return null;
}
// ----------------------------------------------------------------------
// Helper classes
// ----------------------------------------------------------------------
public static class NetId implements Identifier{
public final String value;
public NetId(String value){
this.value = value;
}
public String getValue(){return value;}
public String toString(){ return "NetID: " + value;}
}
/**
* An identifier with the Individual that represents the human self-editor.
*/
public static class SelfEditing implements Identifier{
final Individual individual;
final String blacklisted;
final boolean faked; //if this is true it was setup by FakeSeflEditingIdentifierFactory
public SelfEditing ( Individual individual, String blacklisted ){
this(individual,blacklisted,false);
}
public SelfEditing ( Individual individual, String blacklisted, boolean faked){
if( individual == null )
throw new IllegalArgumentException("Individual must not be null");
this.individual = individual;
this.blacklisted = blacklisted;
this.faked = faked;
}
public String getValue(){
return individual.getURI();
}
public Individual getIndividual(){
return individual;
}
public String getBlacklisted(){
return blacklisted;
}
public String toString(){
return "SelfEditing as " + getValue() +
(getBlacklisted()!=null? " blacklisted via " + getBlacklisted():"");
}
public boolean isFake() {
return faked;
}
}
}

View file

@ -11,7 +11,6 @@ import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -23,7 +22,9 @@ import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundleFactory;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration; import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
/** /**
@ -49,6 +50,7 @@ public class CommonIdentifierBundleFactory implements IdentifierBundleFactory {
ArrayIdentifierBundle bundle = new ArrayIdentifierBundle(); ArrayIdentifierBundle bundle = new ArrayIdentifierBundle();
bundle.addAll(createUserIdentifiers(req)); bundle.addAll(createUserIdentifiers(req));
bundle.addAll(createRootUserIdentifiers(req));
bundle.addAll(createRoleLevelIdentifiers(req)); bundle.addAll(createRoleLevelIdentifiers(req));
bundle.addAll(createBlacklistOrAssociatedIndividualIdentifiers(req)); bundle.addAll(createBlacklistOrAssociatedIndividualIdentifiers(req));
@ -68,6 +70,16 @@ public class CommonIdentifierBundleFactory implements IdentifierBundleFactory {
} }
} }
private Collection<? extends Identifier> createRootUserIdentifiers(
HttpServletRequest req) {
UserAccount user = LoginStatusBean.getCurrentUser(req);
if (isRootUser(user)) {
return Collections.singleton(new IsRootUser());
} else {
return Collections.emptySet();
}
}
/** /**
* Create an identifier that shows the role level of the current user, or * Create an identifier that shows the role level of the current user, or
* PUBLIC if the user is not logged in. * PUBLIC if the user is not logged in.
@ -100,23 +112,22 @@ public class CommonIdentifierBundleFactory implements IdentifierBundleFactory {
return ids; return ids;
} }
/**
* Get all Individuals associated with the current user.
*
* TODO Currently only uses the matching property. Should also use
* "mayEditAs" type of association.
*/
private Collection<Individual> getAssociatedIndividuals( private Collection<Individual> getAssociatedIndividuals(
HttpServletRequest req) { HttpServletRequest req) {
Collection<Individual> individuals = new ArrayList<Individual>(); Collection<Individual> individuals = new ArrayList<Individual>();
LoginStatusBean bean = LoginStatusBean.getBean(req); UserAccount user = LoginStatusBean.getCurrentUser(req);
String username = bean.getUsername(); if (user == null) {
if (!bean.isLoggedIn()) {
log.debug("No Associated Individuals: not logged in."); log.debug("No Associated Individuals: not logged in.");
return individuals; return individuals;
} }
if (StringUtils.isEmpty(username)) {
log.debug("No Associated Individuals: username is empty.");
return individuals;
}
WebappDaoFactory wdf = (WebappDaoFactory) context WebappDaoFactory wdf = (WebappDaoFactory) context
.getAttribute("webappDaoFactory"); .getAttribute("webappDaoFactory");
if (wdf == null) { if (wdf == null) {
@ -127,22 +138,33 @@ public class CommonIdentifierBundleFactory implements IdentifierBundleFactory {
IndividualDao indDao = wdf.getIndividualDao(); IndividualDao indDao = wdf.getIndividualDao();
SelfEditingConfiguration sec = SelfEditingConfiguration.getBean(req); SelfEditingConfiguration sec = SelfEditingConfiguration.getBean(req);
String uri = sec.getIndividualUriFromUsername(indDao, username); individuals.addAll(sec.getAssociatedIndividuals(indDao, user));
if (uri == null) {
log.debug("Could not find an Individual with a netId of "
+ username);
return individuals;
}
Individual ind = indDao.getIndividualByURI(uri);
if (ind == null) {
log.warn("Found a URI for the netId " + username
+ " but could not build Individual");
return individuals;
}
log.debug("Found an Individual for netId " + username + " URI: " + uri);
individuals.add(ind);
return individuals; return individuals;
} }
/**
* Is this user a root user?
*/
private boolean isRootUser(UserAccount user) {
if (user == null) {
return false;
}
WebappDaoFactory wdf = (WebappDaoFactory) context
.getAttribute("webappDaoFactory");
if (wdf == null) {
log.error("Could not get a WebappDaoFactory from the ServletContext");
return false;
}
UserAccountsDao uaDao = wdf.getUserAccountsDao();
return uaDao.isRootUser(user);
}
@Override
public String toString() {
return this.getClass().getSimpleName() + " - " + hashCode();
}
} }

View file

@ -43,6 +43,6 @@ public class HasAssociatedIndividual extends AbstractCommonIdentifier implements
@Override @Override
public String toString() { public String toString() {
return "HasAssociatedIndividual['" + associatedIndividualUri + "']"; return "HasAssociatedIndividual[" + associatedIndividualUri + "]";
} }
} }

View file

@ -224,7 +224,8 @@ public class IsBlacklisted extends AbstractCommonIdentifier implements
@Override @Override
public String toString() { public String toString() {
return "IsBlacklisted['" + reasonForBlacklisting + "']"; return "IsBlacklisted[" + associatedIndividualUri + ", "
+ reasonForBlacklisting + "]";
} }
} }

View file

@ -0,0 +1,21 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.identifier.common;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.Identifier;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
/**
* The current user is a root user.
*/
public class IsRootUser extends AbstractCommonIdentifier implements Identifier {
public static boolean isRootUser(IdentifierBundle ids) {
return !getIdentifiersForClass(ids, IsRootUser.class).isEmpty();
}
@Override
public String toString() {
return "IsRootUser";
}
}

View file

@ -0,0 +1,98 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.permissions;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.shared.Lock;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.AbortStartup;
/**
* Load the initial configuration of PermissionSets and Permissions.
*
* The UserAccounts model must be created before this runs.
*
* For now, we just use the four hard-coded "roles".
*/
public class PermissionSetsLoader implements ServletContextListener {
private static final Log log = LogFactory
.getLog(PermissionSetsLoader.class);
public static final String URI_SELF_EDITOR = "http://permissionSet-1";
public static final String URI_EDITOR = "http://permissionSet-4";
public static final String URI_CURATOR = "http://permissionSet-5";
public static final String URI_DBA = "http://permissionSet-50";
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext ctx = sce.getServletContext();
if (AbortStartup.isStartupAborted(ctx)) {
return;
}
try {
String ns = ConfigurationProperties.getBean(ctx).getProperty(
"Vitro.defaultNamespace");
OntModel model = ModelContext.getBaseOntModelSelector(ctx)
.getUserAccountsModel();
ModelWrapper wrapper = new ModelWrapper(model);
wrapper.createPermissionSet(URI_SELF_EDITOR, "Self Editor");
wrapper.createPermissionSet(URI_EDITOR, "Editor");
wrapper.createPermissionSet(URI_CURATOR, "Curator");
wrapper.createPermissionSet(URI_DBA, "Site Admin");
} catch (Exception e) {
log.error("could not run PermissionSetsLoader" + e);
AbortStartup.abortStartup(ctx);
throw new RuntimeException(e);
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// Nothing to tear down.
}
private static class ModelWrapper {
private final OntModel model;
private final Property typeProperty;
private final Property labelProperty;
private final Resource permissionSet;
public ModelWrapper(OntModel model) {
this.model = model;
typeProperty = model.createProperty(VitroVocabulary.RDF_TYPE);
labelProperty = model.createProperty(VitroVocabulary.LABEL);
permissionSet = model.createResource(VitroVocabulary.PERMISSIONSET);
}
public void createPermissionSet(String uri, String label) {
model.enterCriticalSection(Lock.WRITE);
try {
Resource r = model.createResource(uri);
model.add(r, typeProperty, permissionSet);
model.add(r, labelProperty, label);
log.debug("Created permission set: '" + uri + "', '" + label
+ "'");
} finally {
model.leaveCriticalSection();
}
}
}
}

View file

@ -1,173 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.policy;
import javax.servlet.ServletContext;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.CuratorEditingIdentifierFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.Identifier;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.AdminRequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.OntoRequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropDataPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.resource.AbstractResourceAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.resource.AddResource;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.resource.DropResource;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
/**
* Policy to use for Vivo Curator-Editing for use at Cornell. All methods in
* this class should be thread safe and side effect free.
*/
public class CuratorEditingPolicy implements PolicyIface {
private final ServletContext ctx;
public CuratorEditingPolicy(ServletContext ctx) {
this.ctx = ctx;
}
/**
* Indicates which Authorization to use when the user isn't explicitly
* authorized.
*/
private PolicyDecision defaultDecision(String message) {
return new BasicPolicyDecision(Authorization.INCONCLUSIVE, message);
}
@Override
public PolicyDecision isAuthorized(IdentifierBundle whomToAuth,
RequestedAction whatToAuth) {
if (whomToAuth == null) {
return defaultDecision("whomToAuth was null");
}
if (whatToAuth == null) {
return defaultDecision("whatToAuth was null");
}
if (!isCurator(whomToAuth)) {
return defaultDecision("IdBundle does not include a Curator identifier");
}
if (whatToAuth instanceof OntoRequestedAction) {
return defaultDecision("CuratorEditingPolicy doesn't authorize OntoRequestedActions");
} else if (whatToAuth instanceof AdminRequestedAction) {
return defaultDecision("CuratorEditingPolicy doesn't authorize AdminRequestedActions");
}
if (whatToAuth instanceof AddDataPropStmt) {
return isAuthorized((AddDataPropStmt) whatToAuth);
} else if (whatToAuth instanceof DropDataPropStmt) {
return isAuthorized((DropDataPropStmt) whatToAuth);
} else if (whatToAuth instanceof EditDataPropStmt) {
return isAuthorized((EditDataPropStmt) whatToAuth);
} else if (whatToAuth instanceof AddObjectPropStmt) {
return isAuthorized((AddObjectPropStmt) whatToAuth);
} else if (whatToAuth instanceof DropObjectPropStmt) {
return isAuthorized((DropObjectPropStmt) whatToAuth);
} else if (whatToAuth instanceof EditObjPropStmt) {
return isAuthorized((EditObjPropStmt) whatToAuth);
} else if (whatToAuth instanceof AddResource) {
return isAuthorized((AddResource) whatToAuth);
} else if (whatToAuth instanceof DropResource) {
return isAuthorized((DropResource) whatToAuth);
} else {
return defaultDecision("unrecognized requested action: "
+ whatToAuth);
}
}
private boolean isCurator(IdentifierBundle whomToAuth) {
for (Identifier id : whomToAuth) {
if (id instanceof CuratorEditingIdentifierFactory.CuratorEditingId) {
return true;
}
}
return false;
}
private boolean canModifyResource(String uri) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyResource(
uri, RoleLevel.CURATOR);
}
private boolean canModifyPredicate(String uri) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate(
uri, RoleLevel.CURATOR);
}
/**
* Check authorization for Adding, Editing or Dropping a DataProperty.
*/
private PolicyDecision isAuthorized(AbstractDataPropertyAction action) {
if (!canModifyResource(action.getSubjectUri())) {
return defaultDecision("CuratorEditingPolicy does not grant access to admin resources; "
+ "may not modify " + action.getSubjectUri());
}
if (!canModifyPredicate(action.getPredicateUri())) {
return defaultDecision("CuratorEditingPolicy does not grant access to admin predicates; "
+ "may not modify " + action.getPredicateUri());
}
return new BasicPolicyDecision(Authorization.AUTHORIZED,
"CuratorEditingPolicy: user may modify '"
+ action.getSubjectUri() + "' ==> '"
+ action.getPredicateUri() + "'");
}
/**
* Check authorization for Adding, Editing or Dropping an ObjectProperty.
*/
private PolicyDecision isAuthorized(AbstractObjectPropertyAction action) {
if (!canModifyResource(action.uriOfSubject)) {
return defaultDecision("CuratorEditingPolicy does not grant access to admin resources; "
+ "may not modify " + action.uriOfSubject);
}
if (!canModifyPredicate(action.uriOfPredicate)) {
return defaultDecision("CuratorEditingPolicy does not grant access to admin predicates; "
+ "may not modify " + action.uriOfPredicate);
}
if (!canModifyResource(action.uriOfObject)) {
return defaultDecision("CuratorEditingPolicy does not grant access to admin resources; "
+ "may not modify " + action.uriOfObject);
}
return new BasicPolicyDecision(Authorization.AUTHORIZED,
"CuratorEditingPolicy: user may modify '" + action.uriOfSubject
+ "' ==> '" + action.uriOfPredicate + "' ==> '"
+ action.uriOfObject + "'");
}
/**
* Check authorization for Adding or Dropping a Resource.
*/
private PolicyDecision isAuthorized(AbstractResourceAction action) {
if (!canModifyResource(action.getSubjectUri())) {
return defaultDecision("CuratorEditingPolicy does not grant access to admin resources; "
+ "may not modify " + action.getSubjectUri());
}
return new BasicPolicyDecision(Authorization.AUTHORIZED,
"CuratorEditingPolicy: may add or remove resource: "
+ action.getSubjectUri());
}
@Override
public String toString() {
return "CuratorEditingPolicy - " + hashCode();
}
}

View file

@ -1,173 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.policy;
import javax.servlet.ServletContext;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.DbAdminEditingIdentifierFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.Identifier;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.AdminRequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.OntoRequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropDataPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.resource.AbstractResourceAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.resource.AddResource;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.resource.DropResource;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
/**
* Policy to use for Vivo non-privileged but user accouunt-based editing All
* methods in this class should be thread safe and side effect free.
*/
public class DbAdminEditingPolicy implements PolicyIface {
private final ServletContext ctx;
public DbAdminEditingPolicy(ServletContext ctx) {
this.ctx = ctx;
}
/**
* Indicates which Authorization to use when the user isn't explicitly
* authorized.
*/
private PolicyDecision defaultDecision(String message) {
return new BasicPolicyDecision(Authorization.INCONCLUSIVE, message);
}
@Override
public PolicyDecision isAuthorized(IdentifierBundle whoToAuth,
RequestedAction whatToAuth) {
if (whoToAuth == null) {
return defaultDecision("whomToAuth was null");
}
if (whatToAuth == null) {
return defaultDecision("whatToAuth was null");
}
if (!isDba(whoToAuth)) {
return defaultDecision("IdBundle does not include a DbAdmin identifier");
}
if (whatToAuth instanceof OntoRequestedAction) {
return defaultDecision("DbAdminEditingPolicy doesn't authorize OntoRequestedActions");
} else if (whatToAuth instanceof AdminRequestedAction) {
return defaultDecision("DbAdminEditingPolicy doesn't authorize AdminRequestedActions");
}
if (whatToAuth instanceof AddDataPropStmt) {
return isAuthorized((AddDataPropStmt) whatToAuth);
} else if (whatToAuth instanceof DropDataPropStmt) {
return isAuthorized((DropDataPropStmt) whatToAuth);
} else if (whatToAuth instanceof EditDataPropStmt) {
return isAuthorized((EditDataPropStmt) whatToAuth);
} else if (whatToAuth instanceof AddObjectPropStmt) {
return isAuthorized((AddObjectPropStmt) whatToAuth);
} else if (whatToAuth instanceof DropObjectPropStmt) {
return isAuthorized((DropObjectPropStmt) whatToAuth);
} else if (whatToAuth instanceof EditObjPropStmt) {
return isAuthorized((EditObjPropStmt) whatToAuth);
} else if (whatToAuth instanceof AddResource) {
return isAuthorized((AddResource) whatToAuth);
} else if (whatToAuth instanceof DropResource) {
return isAuthorized((DropResource) whatToAuth);
} else {
return defaultDecision("unrecognized requested action: "
+ whatToAuth);
}
}
private boolean isDba(IdentifierBundle whomToAuth) {
for (Identifier id : whomToAuth) {
if (id instanceof DbAdminEditingIdentifierFactory.DbAdminEditingId) {
return true;
}
}
return false;
}
private boolean canModifyResource(String uri) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyResource(
uri, RoleLevel.DB_ADMIN);
}
private boolean canModifyPredicate(String uri) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate(
uri, RoleLevel.DB_ADMIN);
}
/**
* Check authorization for Adding, Editing or Dropping a DataProperty.
*/
private PolicyDecision isAuthorized(AbstractDataPropertyAction action) {
if (!canModifyResource(action.getSubjectUri())) {
return defaultDecision("DbAdminEditingPolicy does not grant access to admin resources; "
+ "may not modify " + action.getSubjectUri());
}
if (!canModifyPredicate(action.getPredicateUri())) {
return defaultDecision("DbAdminEditingPolicy does not grant access to admin predicates; "
+ "may not modify " + action.getPredicateUri());
}
return new BasicPolicyDecision(Authorization.AUTHORIZED,
"DbAdminEditingPolicy: user may modify '"
+ action.getSubjectUri() + "' ==> '"
+ action.getPredicateUri() + "'");
}
/**
* Check authorization for Adding, Editing or Dropping an ObjectProperty.
*/
private PolicyDecision isAuthorized(AbstractObjectPropertyAction action) {
if (!canModifyResource(action.uriOfSubject)) {
return defaultDecision("DbAdminEditingPolicy does not grant access to admin resources; "
+ "may not modify " + action.uriOfSubject);
}
if (!canModifyPredicate(action.uriOfPredicate)) {
return defaultDecision("DbAdminEditingPolicy does not grant access to admin predicates; "
+ "may not modify " + action.uriOfPredicate);
}
if (!canModifyResource(action.uriOfObject)) {
return defaultDecision("DbAdminEditingPolicy does not grant access to admin resources; "
+ "may not modify " + action.uriOfObject);
}
return new BasicPolicyDecision(Authorization.AUTHORIZED,
"DbAdminEditingPolicy: user may modify '" + action.uriOfSubject
+ "' ==> '" + action.uriOfPredicate + "' ==> '"
+ action.uriOfObject + "'");
}
/**
* Check authorization for Adding or Dropping a Resource.
*/
private PolicyDecision isAuthorized(AbstractResourceAction action) {
if (!canModifyResource(action.getSubjectUri())) {
return defaultDecision("DbAdminEditingPolicy does not grant access to admin resources; "
+ "may not modify " + action.getSubjectUri());
}
return new BasicPolicyDecision(Authorization.AUTHORIZED,
"DbAdminEditingPolicy: may add or remove resource: "
+ action.getSubjectUri());
}
@Override
public String toString() {
return "DbAdminEditingPolicy - " + hashCode();
}
}

View file

@ -163,4 +163,9 @@ public class DisplayRestrictedDataByRoleLevelPolicy implements PolicyIface {
.canDisplayPredicate(uri, userRole); .canDisplayPredicate(uri, userRole);
} }
@Override
public String toString() {
return this.getClass().getSimpleName() + " - " + hashCode();
}
} }

View file

@ -175,4 +175,9 @@ public class DisplayRestrictedDataToSelfPolicy implements PolicyIface {
return false; return false;
} }
@Override
public String toString() {
return this.getClass().getSimpleName() + " - " + hashCode();
}
} }

View file

@ -0,0 +1,147 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.policy;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasRoleLevel;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyAction;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
/**
* Permit adding, editing, or deleting of various data based on the user's Role
* level and the restrictions in the ontology.
*
* This policy only authorizes users who are Editors, Curators or DBAs.
* Self-editors and users who are not logged in must look elsewhere for
* authorization.
*/
public class EditRestrictedDataByRoleLevelPolicy implements PolicyIface {
private static final Log log = LogFactory
.getLog(EditRestrictedDataByRoleLevelPolicy.class);
private final ServletContext ctx;
public EditRestrictedDataByRoleLevelPolicy(ServletContext ctx) {
this.ctx = ctx;
}
/**
* If the requested action is to edit a property statement, we might
* authorize it based on their role level.
*/
@Override
public PolicyDecision isAuthorized(IdentifierBundle whoToAuth,
RequestedAction whatToAuth) {
if (whoToAuth == null) {
return defaultDecision("whomToAuth was null");
}
if (whatToAuth == null) {
return defaultDecision("whatToAuth was null");
}
RoleLevel userRole = HasRoleLevel.getUsersRoleLevel(whoToAuth);
if (!userRoleIsHighEnough(userRole)) {
return defaultDecision("insufficient role level: " + userRole);
}
PolicyDecision result;
if (whatToAuth instanceof AbstractDataPropertyAction) {
result = isAuthorized((AbstractDataPropertyAction) whatToAuth,
userRole);
} else if (whatToAuth instanceof AbstractObjectPropertyAction) {
result = isAuthorized((AbstractObjectPropertyAction) whatToAuth,
userRole);
} else {
result = defaultDecision("Unrecognized action");
}
log.debug("whoToAuth: " + whoToAuth);
log.debug("decision for '" + whatToAuth + "' is " + result);
return result;
}
/**
* We only consider Editors, Curators and DBAs.
*/
private boolean userRoleIsHighEnough(RoleLevel userRole) {
return (userRole == RoleLevel.EDITOR)
|| (userRole == RoleLevel.CURATOR)
|| (userRole == RoleLevel.DB_ADMIN);
}
/**
* The user may add, edit, or delete this data property if they are allowed
* to modify its subject and its predicate.
*/
private PolicyDecision isAuthorized(AbstractDataPropertyAction action,
RoleLevel userRole) {
String subjectUri = action.getSubjectUri();
String predicateUri = action.getPredicateUri();
if (canModifyResource(subjectUri, userRole)
&& canModifyPredicate(predicateUri, userRole)) {
return authorized("user may modify DataPropertyStatement "
+ subjectUri + " ==> " + predicateUri);
} else {
return defaultDecision("user may not modify DataPropertyStatement "
+ subjectUri + " ==> " + predicateUri);
}
}
/**
* The user may add, edit, or delete this data property if they are allowed
* to modify its subject, its predicate, and its object.
*/
private PolicyDecision isAuthorized(AbstractObjectPropertyAction action,
RoleLevel userRole) {
String subjectUri = action.getUriOfSubject();
String predicateUri = action.getUriOfPredicate();
String objectUri = action.getUriOfObject();
if (canModifyResource(subjectUri, userRole)
&& canModifyPredicate(predicateUri, userRole)
&& canModifyResource(objectUri, userRole)) {
return authorized("user may modify ObjectPropertyStatement "
+ subjectUri + " ==> " + predicateUri + " ==> " + objectUri);
} else {
return defaultDecision("user may not modify ObjectPropertyStatement "
+ subjectUri + " ==> " + predicateUri + " ==> " + objectUri);
}
}
/** If the user is explicitly authorized, return this. */
private PolicyDecision authorized(String message) {
String className = this.getClass().getSimpleName();
return new BasicPolicyDecision(Authorization.AUTHORIZED, className
+ ": " + message);
}
/** If the user isn't explicitly authorized, return this. */
private PolicyDecision defaultDecision(String message) {
return new BasicPolicyDecision(Authorization.INCONCLUSIVE, message);
}
private boolean canModifyResource(String uri, RoleLevel userRole) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyResource(
uri, userRole);
}
private boolean canModifyPredicate(String uri, RoleLevel userRole) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate(
uri, userRole);
}
@Override
public String toString() {
return this.getClass().getSimpleName() + " - " + hashCode();
}
}

View file

@ -1,173 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.policy;
import javax.servlet.ServletContext;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.EditorEditingIdentifierFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.Identifier;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.AdminRequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.OntoRequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropDataPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.resource.AbstractResourceAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.resource.AddResource;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.resource.DropResource;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
/**
* Policy to use for Vivo non-privileged but user accouunt-based editing All
* methods in this class should be thread safe and side effect free.
*/
public class EditorEditingPolicy implements PolicyIface {
private final ServletContext ctx;
public EditorEditingPolicy(ServletContext ctx) {
this.ctx = ctx;
}
/**
* Indicates which Authorization to use when the user isn't explicitly
* authorized.
*/
private PolicyDecision defaultDecision(String message) {
return new BasicPolicyDecision(Authorization.INCONCLUSIVE, message);
}
@Override
public PolicyDecision isAuthorized(IdentifierBundle whomToAuth,
RequestedAction whatToAuth) {
if (whomToAuth == null) {
return defaultDecision("whomToAuth was null");
}
if (whatToAuth == null) {
return defaultDecision("whatToAuth was null");
}
if (!isEditor(whomToAuth)) {
return defaultDecision("IdBundle does not include an Editor identifier");
}
if (whatToAuth instanceof OntoRequestedAction) {
return defaultDecision("EditorEditingPolicy doesn't authorize OntoRequestedActions");
} else if (whatToAuth instanceof AdminRequestedAction) {
return defaultDecision("EditorEditingPolicy doesn't authorize AdminRequestedActions");
}
if (whatToAuth instanceof AddDataPropStmt) {
return isAuthorized((AddDataPropStmt) whatToAuth);
} else if (whatToAuth instanceof DropDataPropStmt) {
return isAuthorized((DropDataPropStmt) whatToAuth);
} else if (whatToAuth instanceof EditDataPropStmt) {
return isAuthorized((EditDataPropStmt) whatToAuth);
} else if (whatToAuth instanceof AddObjectPropStmt) {
return isAuthorized((AddObjectPropStmt) whatToAuth);
} else if (whatToAuth instanceof DropObjectPropStmt) {
return isAuthorized((DropObjectPropStmt) whatToAuth);
} else if (whatToAuth instanceof EditObjPropStmt) {
return isAuthorized((EditObjPropStmt) whatToAuth);
} else if (whatToAuth instanceof AddResource) {
return isAuthorized((AddResource) whatToAuth);
} else if (whatToAuth instanceof DropResource) {
return isAuthorized((DropResource) whatToAuth);
} else {
return defaultDecision("unrecognized requested action: "
+ whatToAuth);
}
}
private boolean isEditor(IdentifierBundle whomToAuth) {
for (Identifier id : whomToAuth) {
if (id instanceof EditorEditingIdentifierFactory.EditorEditingId) {
return true;
}
}
return false;
}
private boolean canModifyResource(String uri) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyResource(
uri, RoleLevel.EDITOR);
}
private boolean canModifyPredicate(String uri) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate(
uri, RoleLevel.EDITOR);
}
/**
* Check authorization for Adding, Editing or Dropping a DataProperty.
*/
private PolicyDecision isAuthorized(AbstractDataPropertyAction action) {
if (!canModifyResource(action.getSubjectUri())) {
return defaultDecision("EditorEditingPolicy does not grant access to admin resources; "
+ "may not modify " + action.getSubjectUri());
}
if (!canModifyPredicate(action.getPredicateUri())) {
return defaultDecision("EditorEditingPolicy does not grant access to admin predicates; "
+ "may not modify " + action.getPredicateUri());
}
return new BasicPolicyDecision(Authorization.AUTHORIZED,
"EditorEditingPolicy: user may modify '"
+ action.getSubjectUri() + "' ==> '"
+ action.getPredicateUri() + "'");
}
/**
* Check authorization for Adding, Editing or Dropping an ObjectProperty.
*/
private PolicyDecision isAuthorized(AbstractObjectPropertyAction action) {
if (!canModifyResource(action.uriOfSubject)) {
return defaultDecision("EditorEditingPolicy does not grant access to admin resources; "
+ "may not modify " + action.uriOfSubject);
}
if (!canModifyPredicate(action.uriOfPredicate)) {
return defaultDecision("EditorEditingPolicy does not grant access to admin predicates; "
+ "may not modify " + action.uriOfPredicate);
}
if (!canModifyResource(action.uriOfObject)) {
return defaultDecision("EditorEditingPolicy does not grant access to admin resources; "
+ "may not modify " + action.uriOfObject);
}
return new BasicPolicyDecision(Authorization.AUTHORIZED,
"EditorEditingPolicy: user may modify '" + action.uriOfSubject
+ "' ==> '" + action.uriOfPredicate + "' ==> '"
+ action.uriOfObject + "'");
}
/**
* Check authorization for Adding or Dropping a Resource.
*/
private PolicyDecision isAuthorized(AbstractResourceAction action) {
if (!canModifyResource(action.getSubjectUri())) {
return defaultDecision("EditorEditingPolicy does not grant access to admin resources; "
+ "may not modify " + action.getSubjectUri());
}
return new BasicPolicyDecision(Authorization.AUTHORIZED,
"EditorEditingPolicy: may add or remove resource: "
+ action.getSubjectUri());
}
@Override
public String toString() {
return "EditorEditingPolicy - " + hashCode();
}
}

View file

@ -1,171 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.policy;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.Identifier;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.DefaultInconclusivePolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.admin.AddNewUser;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.admin.LoadOntology;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.admin.RebuildTextIndex;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.admin.RemoveUser;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.admin.ServerStatus;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.admin.UpdateTextIndex;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.admin.UploadFile;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ontology.CreateOwlClass;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ontology.DefineDataProperty;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ontology.DefineObjectProperty;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ontology.RemoveOwlClass;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropDataPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropStmt;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.resource.AddResource;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.resource.DropResource;
/**
* Policy that mimics the authorization roles of the old system. So each
* principle that is to be authorized needs to be associated with an individual
* in the model and the individual needs to have a ObjectPropertyStatement between it and
* a authorization role.
*
* ex.
*
* vivo:indvidual23323 vivo:cornellNetId "bdc34".
* vivo:indvidual22323 vitro:authRole <role://50>.
*
* Notice that this policy doesn't need setup because it will look for
* an authorization role identifier in the model.
*
* @author bdc34
*
*/
public class RoleBasedPolicy extends DefaultInconclusivePolicy implements PolicyIface {
private static final Log log = LogFactory.getLog(RoleBasedPolicy.class.getName());
/**
* What is the minimum AuthRole needed to perform a given action?
*/
private static Map<Class<?>,AuthRole> actionToMinRole = new HashMap<Class<?>,AuthRole>();
static{
//anybody actions
//view resources?
//user actions
//allow netid authenticated people to do things?
//edit actions
actionToMinRole.put(AddDataPropStmt.class, AuthRole.EDITOR);
actionToMinRole.put(AddObjectPropStmt.class, AuthRole.EDITOR);
actionToMinRole.put(AddResource.class, AuthRole.EDITOR);
actionToMinRole.put(DropDataPropStmt.class, AuthRole.EDITOR);
actionToMinRole.put(DropObjectPropStmt.class, AuthRole.EDITOR);
actionToMinRole.put(DropResource.class, AuthRole.EDITOR);
actionToMinRole.put(UploadFile.class, AuthRole.EDITOR);
actionToMinRole.put(ServerStatus.class, AuthRole.EDITOR);
actionToMinRole.put(UpdateTextIndex.class, AuthRole.EDITOR);
//curator actions
actionToMinRole.put(DefineDataProperty.class, AuthRole.CURATOR);
actionToMinRole.put(DefineObjectProperty.class, AuthRole.CURATOR);
actionToMinRole.put(CreateOwlClass.class, AuthRole.CURATOR);
actionToMinRole.put(RemoveOwlClass.class, AuthRole.CURATOR);
//dba actions (dba role is allowed to do anything)
actionToMinRole.put(AddNewUser.class, AuthRole.DBA);
actionToMinRole.put(LoadOntology.class, AuthRole.DBA);
actionToMinRole.put(RemoveUser.class, AuthRole.DBA);
actionToMinRole.put(RebuildTextIndex.class, AuthRole.DBA);
};
public PolicyDecision isAuthorized(IdentifierBundle whomToAuth, RequestedAction whatToAuth) {
if( whomToAuth == null ){
log.error( "null was passed as whoToAuth" );
return new BasicPolicyDecision(Authorization.INCONCLUSIVE,"null was passed as whoToAuth");
}
if( whatToAuth == null ){
log.error("null was passed as whatToAuth");
return new BasicPolicyDecision(Authorization.INCONCLUSIVE,"null was passed as whatToAuth");
}
//dba can do anything
if( AuthRole.DBA.thisRoleOrGreater(whomToAuth))
return new BasicPolicyDecision(Authorization.AUTHORIZED,"in DBA role");
//We need to find the class of the RequestedAction since that
//encodes what type of action is being requested.
Class<?> requesetClass = whatToAuth.getClass();
AuthRole minmumRoleForAction = actionToMinRole.get(requesetClass);
if( minmumRoleForAction == null ){
String msg = "no minimum role found for action " + whatToAuth.getClass().getName();
log.error(msg);
return new BasicPolicyDecision(Authorization.UNAUTHORIZED,msg);
}
if( minmumRoleForAction.thisRoleOrGreater(whomToAuth) )
return new BasicPolicyDecision(Authorization.AUTHORIZED,"authorized for role");
else
return new BasicPolicyDecision(Authorization.UNAUTHORIZED,"not authorized for role");
}
@Override
public String toString() {
return "RoleBasedPolicy";
}
/********************** Roles *****************************************/
public static enum AuthRole implements Identifier {
ANYBODY( "role:/0" ,LoginStatusBean.ANYBODY),
USER( "role:/1" ,LoginStatusBean.NON_EDITOR),
EDITOR( "role:/4" ,LoginStatusBean.EDITOR),
CURATOR( "role:/5" ,LoginStatusBean.CURATOR),
DBA( "role:/50",LoginStatusBean.DBA);
private final String roleUri;
private final int level;
AuthRole(String uri, int level) {
this.roleUri = uri;
this.level = level;
}
public String roleUri() { return roleUri; }
public int level() {return level;}
/** returns null if not found */
public static AuthRole convertUriToAuthRole(String uri){
for( AuthRole role : AuthRole.values()){
if( role.roleUri().equals( uri ))
return role;
}
return null;
}
public boolean thisRoleOrGreater(IdentifierBundle ibundle){
if( ibundle == null )
return false;
for(Object obj : ibundle){
if( obj instanceof AuthRole &&
((AuthRole)obj).level() >= this.level())
return true;
}
return false;
}
@Override
public String toString() {
return "AuthRole: " + name();
}
}/* end of enum AuthRole */
}/* end of class RoleBasedPolicy */

View file

@ -0,0 +1,171 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.policy;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.vocabulary.RDF;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsRootUser;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.AbortStartup;
/**
* If the user has an IsRootUser identifier, they can do anything!
*
* On setup, check to see that there is a root user. If not, create one. If we
* can't create one, abort.
*/
public class RootUserPolicy implements PolicyIface {
private static final Log log = LogFactory.getLog(RootUserPolicy.class);
private static final String PROPERTY_ROOT_USER_EMAIL = "rootUser.emailAddress";
private static final String ROOT_USER_INITIAL_PASSWORD = "rootPassword";
/**
* This is the entire policy. If you are a root user, you are authorized.
*/
@Override
public PolicyDecision isAuthorized(IdentifierBundle whoToAuth,
RequestedAction whatToAuth) {
if (IsRootUser.isRootUser(whoToAuth)) {
return new BasicPolicyDecision(Authorization.AUTHORIZED,
"RootUserPolicy: approved");
} else {
return new BasicPolicyDecision(Authorization.INCONCLUSIVE,
"not root user");
}
}
// ----------------------------------------------------------------------
// Setup class
// ----------------------------------------------------------------------
public static class Setup implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext ctx = sce.getServletContext();
if (AbortStartup.isStartupAborted(ctx)) {
return;
}
try {
UserAccountsDao uaDao = getUserAccountsDao(ctx);
OntModel userAccountsModel = getUserAccountsModel(ctx);
if (!rootUserExists(uaDao)) {
createRootUser(ctx, uaDao, userAccountsModel);
}
ServletPolicyList.addPolicy(ctx, new RootUserPolicy());
} catch (Exception e) {
log.error("could not run " + this.getClass().getSimpleName()
+ ": " + e);
AbortStartup.abortStartup(ctx);
throw new RuntimeException(e);
}
}
private UserAccountsDao getUserAccountsDao(ServletContext ctx) {
WebappDaoFactory wadf = (WebappDaoFactory) ctx
.getAttribute("webappDaoFactory");
if (wadf == null) {
throw new IllegalStateException(
"No webappDaoFactory on the servlet context");
}
return wadf.getUserAccountsDao();
}
private OntModel getUserAccountsModel(ServletContext ctx) {
return ModelContext.getBaseOntModelSelector(ctx)
.getUserAccountsModel();
}
private boolean rootUserExists(UserAccountsDao uaDao) {
for (UserAccount ua : uaDao.getAllUserAccounts()) {
if (uaDao.isRootUser(ua)) {
return true;
}
}
return false;
}
/**
* TODO The first and last name should be left blank, so the user will
* be forced to edit them. However, that's not in place yet.
*/
private void createRootUser(ServletContext ctx, UserAccountsDao uaDao,
OntModel userAccountsModel) {
String emailAddress = ConfigurationProperties.getBean(ctx)
.getProperty(PROPERTY_ROOT_USER_EMAIL);
if (emailAddress == null) {
throw new IllegalStateException(
"deploy.properties must contain a value for '"
+ PROPERTY_ROOT_USER_EMAIL + "'");
}
if (!Authenticator.isValidEmailAddress(emailAddress)) {
throw new IllegalStateException("Value for '"
+ PROPERTY_ROOT_USER_EMAIL
+ "' is not a valid email address: '" + emailAddress
+ "'");
}
if (null != uaDao.getUserAccountByEmail(emailAddress)) {
throw new IllegalStateException("Can't create root user - "
+ "an account already exists with email address '"
+ emailAddress + "'");
}
UserAccount ua = new UserAccount();
ua.setEmailAddress(emailAddress);
ua.setFirstName("root");
ua.setLastName("user");
ua.setMd5Password(Authenticator
.applyMd5Encoding(ROOT_USER_INITIAL_PASSWORD));
ua.setPasswordChangeRequired(true);
ua.setStatus(Status.ACTIVE);
uaDao.insertUserAccount(ua);
userAccountsModel.enterCriticalSection(Lock.WRITE);
try {
Resource r = userAccountsModel.getResource(ua.getUri());
Resource t = userAccountsModel
.getResource(VitroVocabulary.USERACCOUNT_ROOT_USER);
userAccountsModel.add(r, RDF.type, t);
} finally {
userAccountsModel.leaveCriticalSection();
}
log.info("Created root user as '" + emailAddress + "'");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// Nothing to destroy
}
}
}

View file

@ -13,6 +13,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditIndividuals; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditIndividuals;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOntology; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOntology;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOwnAccount;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditSiteInformation; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditSiteInformation;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageMenus; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageMenus;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManagePortals; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManagePortals;
@ -102,6 +103,9 @@ public class UseRestrictedPagesByRoleLevelPolicy implements PolicyIface {
} else if (whatToAuth instanceof UseMiscellaneousPages) { } else if (whatToAuth instanceof UseMiscellaneousPages) {
result = isAuthorized(whatToAuth, RoleLevel.SELF, userRole); result = isAuthorized(whatToAuth, RoleLevel.SELF, userRole);
} else if (whatToAuth instanceof EditOwnAccount) {
result = isAuthorized(whatToAuth, RoleLevel.SELF, userRole);
} else { } else {
result = defaultDecision("Unrecognized action"); result = defaultDecision("Unrecognized action");
} }
@ -140,4 +144,8 @@ public class UseRestrictedPagesByRoleLevelPolicy implements PolicyIface {
return new BasicPolicyDecision(Authorization.INCONCLUSIVE, message); return new BasicPolicyDecision(Authorization.INCONCLUSIVE, message);
} }
@Override
public String toString() {
return this.getClass().getSimpleName() + " - " + hashCode();
}
} }

View file

@ -16,7 +16,8 @@ public class DefaultInconclusivePolicy implements PolicyIface {
Authorization.INCONCLUSIVE, Authorization.INCONCLUSIVE,
"This is the default decision defined in DefaultInconclusivePolicy"); "This is the default decision defined in DefaultInconclusivePolicy");
public PolicyDecision isAuthorized(IdentifierBundle whoToAuth, @Override
public PolicyDecision isAuthorized(IdentifierBundle whoToAuth,
RequestedAction whatToAuth) { RequestedAction whatToAuth) {
if (whoToAuth == null) if (whoToAuth == null)
return new BasicPolicyDecision(Authorization.INCONCLUSIVE, return new BasicPolicyDecision(Authorization.INCONCLUSIVE,
@ -29,7 +30,7 @@ public class DefaultInconclusivePolicy implements PolicyIface {
@Override @Override
public String toString() { public String toString() {
return "DefaultInconclusivePolicy"; return this.getClass().getSimpleName() + " - " + hashCode();
} }
} }

View file

@ -13,6 +13,8 @@ import edu.cornell.mannlib.vitro.webapp.auth.identifier.ActiveIdentifierBundleFa
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.CommonIdentifierBundleFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.CommonIdentifierBundleFactory;
import edu.cornell.mannlib.vitro.webapp.auth.policy.DisplayRestrictedDataByRoleLevelPolicy; import edu.cornell.mannlib.vitro.webapp.auth.policy.DisplayRestrictedDataByRoleLevelPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.DisplayRestrictedDataToSelfPolicy; import edu.cornell.mannlib.vitro.webapp.auth.policy.DisplayRestrictedDataToSelfPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.EditRestrictedDataByRoleLevelPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.SelfEditingPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList; import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList;
import edu.cornell.mannlib.vitro.webapp.auth.policy.UseRestrictedPagesByRoleLevelPolicy; import edu.cornell.mannlib.vitro.webapp.auth.policy.UseRestrictedPagesByRoleLevelPolicy;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.AbortStartup; import edu.cornell.mannlib.vitro.webapp.servlet.setup.AbortStartup;
@ -37,11 +39,16 @@ public class CommonPolicyFamilySetup implements ServletContextListener {
new DisplayRestrictedDataByRoleLevelPolicy(ctx)); new DisplayRestrictedDataByRoleLevelPolicy(ctx));
ServletPolicyList.addPolicy(ctx, ServletPolicyList.addPolicy(ctx,
new DisplayRestrictedDataToSelfPolicy(ctx)); new DisplayRestrictedDataToSelfPolicy(ctx));
ServletPolicyList.addPolicy(ctx,
new EditRestrictedDataByRoleLevelPolicy(ctx));
ServletPolicyList.addPolicy(ctx, ServletPolicyList.addPolicy(ctx,
new UseRestrictedPagesByRoleLevelPolicy()); new UseRestrictedPagesByRoleLevelPolicy());
ServletPolicyList.addPolicy(ctx, new SelfEditingPolicy(ctx));
// This factory creates Identifiers for all of the above policies. // This factory creates Identifiers for all of the above policies.
CommonIdentifierBundleFactory factory = new CommonIdentifierBundleFactory(ctx); CommonIdentifierBundleFactory factory = new CommonIdentifierBundleFactory(
ctx);
ActiveIdentifierBundleFactories.addFactory(sce, factory); ActiveIdentifierBundleFactories.addFactory(sce, factory);
} catch (Exception e) { } catch (Exception e) {

View file

@ -1,62 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.policy.setup;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.ActiveIdentifierBundleFactories;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.CuratorEditingIdentifierFactory;
import edu.cornell.mannlib.vitro.webapp.auth.policy.CuratorEditingPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.AbortStartup;
/**
* Sets up RoleBasedPolicy and IdentifierBundleFactory. This will cause the
* vitro native login to add Identifiers that can be used by the Auth system and
* the in-line editing.
*
* To use this add it as a listener to the web.xml.
*
* See RoleBasedPolicy.java
*/
public class CuratorEditingPolicySetup implements ServletContextListener {
private static final Log log = LogFactory
.getLog(CuratorEditingPolicySetup.class.getName());
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext ctx = sce.getServletContext();
if (AbortStartup.isStartupAborted(ctx)) {
return;
}
try {
log.debug("Setting up CuratorEditingPolicy");
// need to make a policy and add it to the ServletContext
CuratorEditingPolicy cep = new CuratorEditingPolicy(ctx);
ServletPolicyList.addPolicy(ctx, cep);
// need to put an IdentifierFactory for CuratorEditingIds into the
// ServletContext
ActiveIdentifierBundleFactories.addFactory(sce,
new CuratorEditingIdentifierFactory());
log.debug("Finished setting up CuratorEditingPolicy: " + cep);
} catch (Exception e) {
log.error("could not run CuratorEditingPolicySetup: " + e);
AbortStartup.abortStartup(ctx);
throw new RuntimeException(e);
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) { /* nothing */
}
}

View file

@ -1,62 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.policy.setup;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.ActiveIdentifierBundleFactories;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.DbAdminEditingIdentifierFactory;
import edu.cornell.mannlib.vitro.webapp.auth.policy.DbAdminEditingPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.AbortStartup;
/**
* Sets up RoleBasedPolicy and IdentifierBundleFactory. This will cause the
* vitro native login to add Identifiers that can be used by the Auth system and
* the in-line editing.
*
* To use this add it as a listener to the web.xml.
*
* See RoleBasedPolicy.java
*/
public class DbAdminEditingPolicySetup implements ServletContextListener {
private static final Log log = LogFactory
.getLog(DbAdminEditingPolicySetup.class.getName());
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext ctx = sce.getServletContext();
if (AbortStartup.isStartupAborted(ctx)) {
return;
}
try {
log.debug("Setting up DbAdminEditingPolicy");
// need to make a policy and add it to the ServletContext
DbAdminEditingPolicy dep = new DbAdminEditingPolicy(ctx);
ServletPolicyList.addPolicy(ctx, dep);
// need to put an IdentifierFactory for DbAdminEditingIds into the
// ServletContext
ActiveIdentifierBundleFactories.addFactory(sce,
new DbAdminEditingIdentifierFactory());
log.debug("Finished setting up DbAdminEditingPolicy: " + dep);
} catch (Exception e) {
log.error("could not run DbAdminEditingPolicySetup: " + e);
AbortStartup.abortStartup(ctx);
throw new RuntimeException(e);
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) { /* nothing */
}
}

View file

@ -1,62 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.policy.setup;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.ActiveIdentifierBundleFactories;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.EditorEditingIdentifierFactory;
import edu.cornell.mannlib.vitro.webapp.auth.policy.EditorEditingPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.AbortStartup;
/**
* Sets up RoleBasedPolicy and IdentifierBundleFactory. This will cause the
* vitro native login to add Identifiers that can be used by the Auth system and
* the in-line editing.
*
* To use this add it as a listener to the web.xml.
*
* See RoleBasedPolicy.java
*/
public class EditorEditingPolicySetup implements ServletContextListener {
private static final Log log = LogFactory
.getLog(EditorEditingPolicySetup.class.getName());
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext ctx = sce.getServletContext();
if (AbortStartup.isStartupAborted(ctx)) {
return;
}
try {
log.debug("Setting up EditorEditingPolicy");
// need to make a policy and add it to the ServletContext
EditorEditingPolicy cep = new EditorEditingPolicy(ctx);
ServletPolicyList.addPolicy(ctx, cep);
// need to put an IdentifierFactory for EditorEditingIds into the
// ServletContext
ActiveIdentifierBundleFactories.addFactory(sce,
new EditorEditingIdentifierFactory());
log.debug("Finished setting up EditorEditingPolicy: " + cep);
} catch (Exception e) {
log.error("could not run EditorEditingPolicySetup: " + e);
AbortStartup.abortStartup(ctx);
throw new RuntimeException(e);
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) { /* nothing */
}
}

View file

@ -1,65 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.policy.setup;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.ActiveIdentifierBundleFactories;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.SelfEditingIdentifierFactory;
import edu.cornell.mannlib.vitro.webapp.auth.policy.SelfEditingPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.AbortStartup;
/**
* Policy for SelfEditors. This will set up the self-editing policy which will
* will look for SelfEditing identifier in the IdentifierBundle. If the user is
* associated with a URI in the system then they will be allowed to edit
* resources related to that URI.
*
* To use this add it as a listener to the web.xml.
*/
public class SelfEditingPolicySetup implements ServletContextListener {
private static final Log log = LogFactory
.getLog(SelfEditingPolicySetup.class.getName());
public static final String SELF_EDITING_POLICY_WAS_SETUP = "selfEditingPolicyWasSetup";
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext ctx = sce.getServletContext();
if (AbortStartup.isStartupAborted(ctx)) {
return;
}
try {
log.debug("Setting up SelfEditingPolicy");
// need to make a policy and add it to the ServletContext
SelfEditingPolicy cep = new SelfEditingPolicy(ctx);
ServletPolicyList.addPolicy(ctx, cep);
// need to put an IdentifierFactory for CuratorEditingIds into the
// ServletContext
ActiveIdentifierBundleFactories.addFactory(sce,
new SelfEditingIdentifierFactory());
sce.getServletContext().setAttribute(SELF_EDITING_POLICY_WAS_SETUP,
Boolean.TRUE);
log.debug("Finished setting up SelfEditingPolicy: " + cep);
} catch (Exception e) {
log.error("could not run SelfEditingPolicySetup: " + e);
AbortStartup.abortStartup(ctx);
throw new RuntimeException(e);
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) { /* nothing */
}
}

View file

@ -195,6 +195,13 @@ public class SelfEditorRelationshipPolicy extends AbstractRelationshipPolicy
return userNotAuthorizedToStatement(); return userNotAuthorizedToStatement();
} }
@Override
public String toString() {
return this.getClass().getSimpleName()
+ ": information resources, grants, projects, etc. - "
+ hashCode();
}
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// methods for InformationResource // methods for InformationResource
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------

View file

@ -0,0 +1,11 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
/** Should we allow the user to edit his own account (name, email, etc)? */
public class EditOwnAccount extends RequestedAction implements
UsePagesRequestedAction {
// no fields
}

View file

@ -2,6 +2,8 @@
package edu.cornell.mannlib.vitro.webapp.beans; package edu.cornell.mannlib.vitro.webapp.beans;
import java.util.Set;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -9,6 +11,7 @@ import org.apache.commons.logging.LogFactory;
import org.openrdf.model.impl.URIImpl; import org.openrdf.model.impl.URIImpl;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean; import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSetsLoader;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
public class BaseResourceBean implements ResourceBean { public class BaseResourceBean implements ResourceBean {
@ -68,21 +71,25 @@ public class BaseResourceBean implements ResourceBean {
return RoleLevel.values()[0]; return RoleLevel.values()[0];
} }
public static RoleLevel getRoleFromLoginStatus(HttpServletRequest req) { public static RoleLevel getRoleFromLoginStatus(HttpServletRequest req) {
int level = LoginStatusBean.getBean(req).getSecurityLevel(); UserAccount u = LoginStatusBean.getCurrentUser(req);
if( level == LoginStatusBean.ANYBODY) // 0 if (u == null) {
return PUBLIC; return PUBLIC;
if( level == LoginStatusBean.NON_EDITOR) // 1 }
return SELF;
if( level == LoginStatusBean.EDITOR ) // 4 Set<String> roles = u.getPermissionSetUris();
return EDITOR; if (roles.contains(PermissionSetsLoader.URI_DBA)) {
if( level == LoginStatusBean.CURATOR ) // 5 return DB_ADMIN;
return CURATOR; } else if (roles.contains(PermissionSetsLoader.URI_CURATOR)) {
if( level == LoginStatusBean.DBA ) // 50 return CURATOR;
return DB_ADMIN; } else if (roles.contains(PermissionSetsLoader.URI_EDITOR)) {
else return EDITOR;
return PUBLIC; } else if (roles.contains(PermissionSetsLoader.URI_SELF_EDITOR)) {
} return SELF;
} else {
return PUBLIC;
}
}
} }
public boolean isAnonymous() { public boolean isAnonymous() {

View file

@ -2,6 +2,9 @@
package edu.cornell.mannlib.vitro.webapp.beans; package edu.cornell.mannlib.vitro.webapp.beans;
import java.util.Collections;
import java.util.List;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
@ -64,7 +67,9 @@ public class SelfEditingConfiguration {
} }
private static SelfEditingConfiguration buildBean(HttpSession session) { private static SelfEditingConfiguration buildBean(HttpSession session) {
String selfEditingIdMatchingProperty = ConfigurationProperties.getBean(session) ConfigurationProperties config = ConfigurationProperties
.getBean(session);
String selfEditingIdMatchingProperty = config
.getProperty(PROPERTY_SELF_EDITING_ID_MATCHING_PROPERTY); .getProperty(PROPERTY_SELF_EDITING_ID_MATCHING_PROPERTY);
return new SelfEditingConfiguration(selfEditingIdMatchingProperty); return new SelfEditingConfiguration(selfEditingIdMatchingProperty);
} }
@ -87,25 +92,39 @@ public class SelfEditingConfiguration {
} }
} }
public String getIndividualUriFromUsername(IndividualDao indDao, /**
String username) { * Get all Individuals associated with this user through the matching
* property. Never returns null.
*/
public List<Individual> getAssociatedIndividuals(IndividualDao indDao,
UserAccount user) {
if (user == null) {
log.debug("user is null");
return Collections.emptyList();
}
return getAssociatedIndividuals(indDao, user.getExternalAuthId());
}
/**
* Get all Individuals associated with this externalAuthId through the
* matching property. Never returns null.
*/
public List<Individual> getAssociatedIndividuals(IndividualDao indDao,
String externalAuthId) {
if (indDao == null) { if (indDao == null) {
log.warn("No IndividualDao"); log.warn("No IndividualDao");
return null; return Collections.emptyList();
} }
if (username == null) { if (externalAuthId == null) {
log.debug("username is null"); log.debug("externalAuthId is null");
return null; return Collections.emptyList();
} }
if (selfEditingIdMatchingProperty == null) { if (selfEditingIdMatchingProperty == null) {
log.debug("selfEditingMatchingProperty is null"); log.debug("selfEditingMatchingProperty is null");
return null; return Collections.emptyList();
} }
return indDao.getIndividualsByDataProperty(
String uri = indDao.getIndividualURIFromNetId(username, selfEditingIdMatchingProperty, externalAuthId);
selfEditingIdMatchingProperty);
log.debug("Username=" + username + ", individual URI=" + uri);
return uri;
} }
@Override @Override

View file

@ -1,137 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.beans;
import java.text.Collator;
import java.util.Date;
public class User implements Comparable<User> {
public final static int MIN_PASSWORD_LENGTH = 6;
public final static int MAX_PASSWORD_LENGTH = 12;
private String URI = null;
private String namespace = null;
private String localName = null;
private String username = null;
private String oldPassword = null;
private String md5password = null;
private Date modTime = null;
private Date firstTime = null;
private int loginCount = 0;
private String roleURI = null;
private String lastName = null;
private String firstName = null;
public String getURI() {
return URI;
}
public void setURI(String URI) {
this.URI = URI;
}
public String getNamespace() {
return namespace;
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
public String getLocalName() {
return localName;
}
public void setLocalName(String localName) {
this.localName = localName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getOldPassword() {
return oldPassword;
}
public void setOldPassword(String oldPassword) {
this.oldPassword = oldPassword;
}
public String getMd5password() {
return md5password;
}
public void setMd5password(String md5password) {
this.md5password = md5password;
}
public Date getModTime() {
return modTime;
}
public void setModTime(Date modTime) {
this.modTime = modTime;
}
public Date getFirstTime() {
return firstTime;
}
public void setFirstTime(Date firstTime) {
this.firstTime = firstTime;
}
public int getLoginCount() {
return loginCount;
}
public void setLoginCount(int loginCount) {
this.loginCount = loginCount;
}
public String getRoleURI() {
return roleURI;
}
public void setRoleURI(String roleURI) {
this.roleURI = roleURI;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@Override
public int compareTo(User other) {
Collator collator = Collator.getInstance();
if( this.getUsername() == null && other.getUsername() == null )
return 0;
else if( this.getUsername() == null )
return -1;
else if( other.getUsername() == null)
return 1;
else
return collator.compare(this.getUsername(),other.getUsername());
}
@Override
public String toString() {
return "User[URI=" + URI + ", namespace=" + namespace + ", localName="
+ localName + ", username=" + username + ", oldPassword="
+ oldPassword + ", md5password=" + md5password + ", modTime="
+ dateToString(modTime) + ", firstTime="
+ dateToString(firstTime) + ", loginCount=" + loginCount
+ ", roleURI=" + roleURI + ", lastName=" + lastName
+ ", firstName=" + firstName + "]";
}
private String dateToString(Date date) {
return (date == null) ? "null" : String.valueOf(date.getTime());
}
}

View file

@ -7,13 +7,21 @@ import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
/** /**
* Information about the account of a user. URI, email, password, etc. * Information about the account of a user. URI, email, password, etc.
*
* The "password link expires hash" is just a string that is derived from the
* value in the passwordLinkExpires field. It doesn't have to be a hash, and
* there is no need for it to be cryptographic, but it seems embarrassing to
* just send the value as a clear string. There is no real need for security
* here, except that a brute force attack would allow someone to change the
* password on an account that they know has a password change pending.
*/ */
public class UserAccount { public class UserAccount {
public static final int MIN_PASSWORD_LENGTH = 6;
public final static int MIN_PASSWORD_LENGTH = 6; public static final int MAX_PASSWORD_LENGTH = 12;
public final static int MAX_PASSWORD_LENGTH = 12;
public enum Status { public enum Status {
ACTIVE, INACTIVE; ACTIVE, INACTIVE;
@ -107,6 +115,11 @@ public class UserAccount {
return passwordLinkExpires; return passwordLinkExpires;
} }
public String getPasswordLinkExpiresHash() {
return limitStringLength(8, Authenticator.applyMd5Encoding(String
.valueOf(passwordLinkExpires)));
}
public void setPasswordLinkExpires(long passwordLinkExpires) { public void setPasswordLinkExpires(long passwordLinkExpires) {
this.passwordLinkExpires = Math.max(0, passwordLinkExpires); this.passwordLinkExpires = Math.max(0, passwordLinkExpires);
} }
@ -163,6 +176,16 @@ public class UserAccount {
return (value == null) ? defaultValue : value; return (value == null) ? defaultValue : value;
} }
private String limitStringLength(int limit, String s) {
if (s == null) {
return "";
} else if (s.length() <= limit) {
return s;
} else {
return s.substring(0, limit);
}
}
@Override @Override
public String toString() { public String toString() {
return "UserAccount[uri=" + uri + (", emailAddress=" + emailAddress) return "UserAccount[uri=" + uri + (", emailAddress=" + emailAddress)

View file

@ -7,7 +7,6 @@ import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.Properties;
import javax.mail.Message; import javax.mail.Message;
import javax.mail.MessagingException; import javax.mail.MessagingException;
@ -25,10 +24,9 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
public class ContactMailServlet extends VitroHttpServlet { public class ContactMailServlet extends VitroHttpServlet {
public static final String SMTPHOST_PROPERTY = "Vitro.smtpHost";
private static final Log log = LogFactory.getLog(ContactMailServlet.class); private static final Log log = LogFactory.getLog(ContactMailServlet.class);
@ -41,24 +39,6 @@ public class ContactMailServlet extends VitroHttpServlet {
private final static String WEB_USEREMAIL_PARAM = "webuseremail"; private final static String WEB_USEREMAIL_PARAM = "webuseremail";
private final static String COMMENTS_PARAM = "s34gfd88p9x1"; private final static String COMMENTS_PARAM = "s34gfd88p9x1";
private static String smtpHost = null;
public static boolean isSmtpHostConfigured(HttpServletRequest req) {
return ConfigurationProperties.getBean(req)
.getProperty(SMTPHOST_PROPERTY, "").length() > 0;
}
@Override
public void init() {
smtpHost = ConfigurationProperties.getBean(getServletContext())
.getProperty(SMTPHOST_PROPERTY, "");
if (smtpHost.isEmpty()) {
log.debug("No Vitro.smtpHost specified");
} else {
log.debug("Found Vitro.smtpHost value of " + smtpHost);
}
}
@Override @Override
public void doGet( HttpServletRequest request, HttpServletResponse response ) public void doGet( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException { throws ServletException, IOException {
@ -69,9 +49,9 @@ public class ContactMailServlet extends VitroHttpServlet {
String statusMsg = null; // holds the error status String statusMsg = null; // holds the error status
if (smtpHost==null || smtpHost.equals("")){ if (!FreemarkerEmailFactory.isConfigured(vreq)) {
statusMsg = "This application has not yet been configured to send mail " + statusMsg = "This application has not yet been configured to send mail. "
"-- smtp host has not been identified in the Configuration Properties file."; + "Email properties must be specified in the configuration properties file.";
redirectToError(response, statusMsg); redirectToError(response, statusMsg);
return; return;
} }
@ -166,10 +146,7 @@ public class ContactMailServlet extends VitroHttpServlet {
.getRealPath(EMAIL_BACKUP_FILE_PATH),true)); //autoflush .getRealPath(EMAIL_BACKUP_FILE_PATH),true)); //autoflush
writeBackupCopy(outFile, msgText, spamReason); writeBackupCopy(outFile, msgText, spamReason);
// Set the smtp host Session s = FreemarkerEmailFactory.getEmailSession(vreq);
Properties props = System.getProperties();
props.put("mail.smtp.host", smtpHost);
Session s = Session.getDefaultInstance(props,null); // was Session.getInstance(props,null);
//s.setDebug(true); //s.setDebug(true);
try { try {

View file

@ -34,8 +34,8 @@ public class IndividualListRdfController extends VitroHttpServlet {
public void doGet (HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { public void doGet (HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
// Make the query // Make the query
String classUri = (String) getServletContext().getAttribute("classuri"); String vclassUri = req.getParameter("vclass");
String queryStr = VitroLuceneTermNames.RDFTYPE + ":\"" + classUri + "\""; String queryStr = VitroLuceneTermNames.RDFTYPE + ":\"" + vclassUri + "\"";
SolrQuery query = new SolrQuery(queryStr); SolrQuery query = new SolrQuery(queryStr);
query.setStart(0) query.setStart(0)
.setRows(ENTITY_LIST_CONTROLLER_MAX_RESULTS) .setRows(ENTITY_LIST_CONTROLLER_MAX_RESULTS)
@ -67,7 +67,7 @@ public class IndividualListRdfController extends VitroHttpServlet {
for (SolrDocument doc : docs) { for (SolrDocument doc : docs) {
String uri = doc.get(VitroLuceneTermNames.URI).toString(); String uri = doc.get(VitroLuceneTermNames.URI).toString();
Resource resource = ResourceFactory.createResource(uri); Resource resource = ResourceFactory.createResource(uri);
RDFNode node = (RDFNode) ResourceFactory.createResource(classUri); RDFNode node = (RDFNode) ResourceFactory.createResource(vclassUri);
model.add(resource, RDF.type, node); model.add(resource, RDF.type, node);
} }

View file

@ -377,7 +377,7 @@ public class JSONReconcileServlet extends VitroHttpServlet {
String stemParam = (String) request.getParameter("stem"); String stemParam = (String) request.getParameter("stem");
boolean stem = "true".equals(stemParam); boolean stem = "true".equals(stemParam);
String termName = stem ? VitroLuceneTermNames.AC_NAME_STEMMED : VitroLuceneTermNames.AC_NAME_UNSTEMMED; String termName = stem ? VitroLuceneTermNames.NAME_STEMMED : VitroLuceneTermNames.NAME_UNSTEMMED;
BooleanQuery boolQuery = new BooleanQuery(); BooleanQuery boolQuery = new BooleanQuery();

View file

@ -3,10 +3,10 @@
package edu.cornell.mannlib.vitro.webapp.controller; package edu.cornell.mannlib.vitro.webapp.controller;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Properties;
import javax.mail.Message; import javax.mail.Message;
import javax.mail.MessagingException; import javax.mail.MessagingException;
@ -23,27 +23,15 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.dao.UserDao; import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
public class MailUsersServlet extends VitroHttpServlet { public class MailUsersServlet extends VitroHttpServlet {
private static final Log log = LogFactory.getLog(MailUsersServlet.class); private static final Log log = LogFactory.getLog(MailUsersServlet.class);
public static HttpServletRequest request; public static HttpServletRequest request;
public static HttpServletRequest response; public static HttpServletRequest response;
private static String smtpHost = "";
// private static final Log log = LogFactory.getLog(ContactMailServlet.class.getName());
@Override
public void init() {
smtpHost = ConfigurationProperties.getBean(getServletContext())
.getProperty(ContactMailServlet.SMTPHOST_PROPERTY, "");
if (smtpHost.isEmpty()) {
log.debug("No Vitro.smtpHost specified");
} else {
log.debug("Found Vitro.smtpHost value of " + smtpHost);
}
}
@Override @Override
public void doGet( HttpServletRequest request, HttpServletResponse response ) public void doGet( HttpServletRequest request, HttpServletResponse response )
@ -54,9 +42,9 @@ public class MailUsersServlet extends VitroHttpServlet {
String errpage = "/contact_err.jsp"; String errpage = "/contact_err.jsp";
String status = null; // holds the error status String status = null; // holds the error status
if (smtpHost==null || smtpHost.equals("")){ if (!FreemarkerEmailFactory.isConfigured(vreq)) {
status = "This application has not yet been configured to send mail " + status = "This application has not yet been configured to send mail. "
"-- smtp host has not been identified in the Configuration Properties file."; + "Email properties must be specified in the configuration properties file.";
response.sendRedirect( "test?bodyJsp=" + errpage + "&ERR=" + status ); response.sendRedirect( "test?bodyJsp=" + errpage + "&ERR=" + status );
return; return;
} }
@ -88,10 +76,8 @@ public class MailUsersServlet extends VitroHttpServlet {
int recipientCount = 0; int recipientCount = 0;
String deliveryfrom = null; String deliveryfrom = null;
UserDao uDao = vreq.getFullWebappDaoFactory().getUserDao();
// get Individuals that the User mayEditAs // get Individuals that the User mayEditAs
deliverToArray = uDao.getUserAccountEmails(); deliverToArray = getEmailsForAllUserAccounts(vreq);
//Removed all form type stuff b/c recipients pre-configured //Removed all form type stuff b/c recipients pre-configured
recipientCount=(deliverToArray == null) ? 0 : deliverToArray.size(); recipientCount=(deliverToArray == null) ? 0 : deliverToArray.size();
@ -162,10 +148,8 @@ public class MailUsersServlet extends VitroHttpServlet {
outFile.flush(); outFile.flush();
// outFile.close(); // outFile.close();
*/ */
// Set the smtp host
Properties props = System.getProperties(); Session s = FreemarkerEmailFactory.getEmailSession(vreq);
props.put("mail.smtp.host", smtpHost);
Session s = Session.getDefaultInstance(props,null); // was Session.getInstance(props,null);
//s.setDebug(true); //s.setDebug(true);
try { try {
// Construct the message // Construct the message
@ -225,6 +209,18 @@ public class MailUsersServlet extends VitroHttpServlet {
} }
private List<String> getEmailsForAllUserAccounts(VitroRequest vreq) {
UserAccountsDao uaDao = vreq.getFullWebappDaoFactory()
.getUserAccountsDao();
List<String> emails = new ArrayList<String>();
for (UserAccount user : uaDao.getAllUserAccounts()) {
emails.add(user.getEmailAddress());
}
return emails;
}
@Override @Override
public void doPost( HttpServletRequest request, HttpServletResponse response ) public void doPost( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException throws ServletException, IOException

View file

@ -0,0 +1,457 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.util.Version;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.search.SearchException;
import edu.cornell.mannlib.vitro.webapp.search.lucene.Entity2LuceneDoc;
import edu.cornell.mannlib.vitro.webapp.search.lucene.Entity2LuceneDoc.VitroLuceneTermNames;
import edu.cornell.mannlib.vitro.webapp.search.lucene.LuceneIndexFactory;
import edu.cornell.mannlib.vitro.webapp.search.lucene.LuceneSetup;
/**
* This servlet is for servicing JSON requests from Google Refine's
* Reconciliation Service.
*
* @author Eliza Chan (elc2013@med.cornell.edu)
*
*/
public class SolrJsonReconcileServlet extends VitroHttpServlet {
private static final long serialVersionUID = 1L;
private static String QUERY_PARAMETER_NAME = "term";
public static final int MAX_QUERY_LENGTH = 500;
private static final Log log = LogFactory.getLog(SolrJsonReconcileServlet.class.getName());
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//resp.setContentType("application/json");
super.doPost(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
super.doGet(req, resp);
resp.setContentType("application/json");
VitroRequest vreq = new VitroRequest(req);
log.debug("vreq");
log.debug(vreq.getWebappDaoFactory());
try {
if (vreq.getParameter("query") != null
|| vreq.getParameter("queries") != null) {
JSONObject qJson = getResult(vreq, req, resp);
log.debug("result: " + qJson.toString());
String responseStr = (vreq.getParameter("callback") == null) ? qJson
.toString() : vreq.getParameter("callback") + "("
+ qJson.toString() + ")";
ServletOutputStream out = resp.getOutputStream();
out.print(responseStr);
} else { // metadata
String defaultNamespace = null;
String defaultTypeList = null;
String serverName = null;
int serverPort = req.getServerPort();
if (vreq.getWebappDaoFactory() != null) {
defaultNamespace = vreq.getWebappDaoFactory().getDefaultNamespace();
}
defaultTypeList = ConfigurationProperties.getBean(req).getProperty("Vitro.reconcile.defaultTypeList");
serverName = req.getServerName();
JSONObject metaJson = getMetadata(req, resp, defaultNamespace, defaultTypeList, serverName, serverPort);
String callbackStr = (vreq.getParameter("callback") == null) ? ""
: vreq.getParameter("callback");
ServletOutputStream out = resp.getOutputStream();
out.print(callbackStr + "(" + metaJson.toString() + ")");
}
} catch (Exception ex) {
log.warn(ex, ex);
}
}
protected JSONObject getResult(VitroRequest vreq, HttpServletRequest req,
HttpServletResponse resp) throws ServletException {
HashMap<String, JSONObject> searchWithTypeMap = new HashMap<String, JSONObject>();
HashMap<String, JSONObject> searchNoTypeMap = new HashMap<String, JSONObject>();
ArrayList<String> queries = new ArrayList<String>();
Object qObj = vreq.getParameter("queries");
if (qObj == null) {
qObj = vreq.getParameter("query");
}
if (qObj != null && qObj instanceof String) {
// e.g.
// {"q0":{"query":"Cathleen","type":"http://xmlns.com/foaf/0.1/Person","type_strict":"should"},
// "q1":{"query":"Geoffrey","type":"http://xmlns.com/foaf/0.1/Person","type_strict":"should"},
// "q2":{"query":"Dina","type":"http://xmlns.com/foaf/0.1/Person","type_strict":"should"}}
String qStr = (String) qObj;
queries.add(qStr);
log.debug("\nquery: " + qStr + "\n");
}
try {
for (int i = 0; i < queries.size(); i++) {
String queryStr = (String) queries.get(i);
JSONObject json = new JSONObject(queryStr);
if (json.has("query")) { // single query
if (json.has("type")) {
searchWithTypeMap.put("query", json);
} else {
// user did not specify a type
searchNoTypeMap.put("query", json);
}
} else { // multiple queries
for (Iterator<String> iter = json.keys(); iter.hasNext();) {
ArrayList<JSONObject> jsonList = new ArrayList<JSONObject>();
String key = (String) iter.next();
Object obj = json.get(key);
JSONObject jsonLvl2 = (JSONObject) obj;
if (jsonLvl2.has("query")) {
if (jsonLvl2.has("type")) {
searchWithTypeMap.put(key, jsonLvl2);
} else {
// user did not specify a type
searchNoTypeMap.put(key, jsonLvl2);
}
}
}
}
}
} catch (JSONException ex) {
log.error("JSONException: " + ex);
throw new ServletException("JSONReconcileServlet JSONException: "
+ ex);
}
// Run index search
JSONObject qJson = null;
if (searchWithTypeMap.size() > 0) {
qJson = runSearch(searchWithTypeMap, vreq);
} else {
qJson = runSearch(searchNoTypeMap, vreq);
}
return qJson;
}
/**
* Returns a default JSON response.
*
* @param req
* @param resp
* @return
* @throws ServletException
*/
protected JSONObject getMetadata(HttpServletRequest req, HttpServletResponse resp, String defaultNamespace,
String defaultTypeList, String serverName, int serverPort) throws ServletException {
JSONObject json = new JSONObject();
try {
json.put("name", "VIVO Reconciliation Service");
if (defaultNamespace != null) {
json.put("identifierSpace", defaultNamespace);
json.put("schemaSpace", defaultNamespace);
}
JSONObject viewJson = new JSONObject();
StringBuffer urlBuf = new StringBuffer();
urlBuf.append("http://" + serverName);
if (serverPort == 8080) {
urlBuf.append(":" + serverPort);
}
if (req.getContextPath() != null) {
urlBuf.append(req.getContextPath());
}
viewJson.put("url", urlBuf.toString() + "/individual?uri={{id}}");
json.put("view", viewJson);
// parse defaultTypeList from deploy.properties
if (defaultTypeList != null) {
String[] splitList = defaultTypeList.split(";");
String[][] idNameArray = new String[splitList.length][splitList.length];
for(int i = 0; i<splitList.length; i++) {
idNameArray[i] = splitList[i].split(",");
}
// process and add to json defaultTypes
JSONArray defaultTypesJsonArr = new JSONArray();
for (int i = 0; i<idNameArray.length; i++) {
JSONObject defaultTypesJson = new JSONObject();
defaultTypesJson.put("id", idNameArray[i][0].trim());
defaultTypesJson.put("name", idNameArray[i][1].trim());
defaultTypesJsonArr.put(defaultTypesJson);
}
json.put("defaultTypes", defaultTypesJsonArr);
}
} catch (JSONException ex) {
throw new ServletException(
"JSONReconcileServlet: Could not create metadata: " + ex);
}
return json;
}
private JSONObject runSearch(HashMap<String, JSONObject> currMap,
VitroRequest vreq) throws ServletException {
JSONObject qJson = new JSONObject();
try {
Analyzer analyzer = getAnalyzer(getServletContext());
IndexSearcher searcherForRequest = LuceneIndexFactory
.getIndexSearcher(getServletContext());
for (Map.Entry<String, JSONObject> entry : currMap.entrySet()) {
JSONObject resultAllJson = new JSONObject();
String key = entry.getKey();
JSONObject json = (JSONObject) entry.getValue();
String queryVal = json.getString("query");
// continue with properties list
String searchType = null;
int limit = 3; // default
String typeStrict = "should"; // default
ArrayList<String[]> propertiesList = new ArrayList<String[]>();
if (json.has("type")) {
searchType = json.getString("type");
}
if (json.has("limit")) {
limit = json.getInt("limit");
}
if (json.has("type_strict")) { // Not sure what this variable
// represents. Skip for now.
typeStrict = json.getString("type_strict");
}
if (json.has("properties")) {
JSONArray properties = json.getJSONArray("properties");
for (int i = 0; i < properties.length(); i++) {
String[] pvPair = new String[2];
JSONObject jsonProperty = properties.getJSONObject(i);
String pid = jsonProperty.getString("pid");
String v = jsonProperty.getString("v");
pvPair[0] = pid;
pvPair[1] = v;
propertiesList.add(pvPair);
}
}
// begin search
JSONArray resultJsonArr = new JSONArray();
Query query = getReconcileQuery(vreq, analyzer,
queryVal, searchType, propertiesList);
TopDocs topDocs = searcherForRequest.search(query, null, limit);
if (topDocs != null && topDocs.scoreDocs != null) {
int hitsLength = topDocs.scoreDocs.length;
if (hitsLength > 0) {
for (int i = 0; i < topDocs.scoreDocs.length; i++) {
JSONObject resultJson = new JSONObject();
float score = topDocs.scoreDocs[i].score;
resultJson.put("score", score);
Document doc = searcherForRequest
.doc(topDocs.scoreDocs[i].doc);
String uri = doc.get(Entity2LuceneDoc.term.URI);
IndividualDao iDao = vreq.getWebappDaoFactory()
.getIndividualDao();
Individual ind = iDao.getIndividualByURI(uri);
if (ind != null) {
String name = ind.getName();
// encode # to %23
String modUri = uri.replace("#", "%23");
resultJson.put("id", modUri);
resultJson.put("name", name);
}
List fields = doc.getFields();
JSONArray typesJsonArr = new JSONArray();
for (int j = 0; j < fields.size(); j++) {
Field field = (Field) fields.get(j);
String fieldName = field.name();
if ("type".equals(fieldName)) {
// e.g. http://aims.fao.org/aos/geopolitical.owl#area
String type = field.stringValue();
int lastIndex2 = type.lastIndexOf('/') + 1;
String typeName = type
.substring(lastIndex2);
typeName = typeName.replace("#", ":");
JSONObject typesJson = new JSONObject();
typesJson.put("id", type);
typesJson.put("name", typeName);
typesJsonArr.put(typesJson);
}
}
resultJson.put("type", typesJsonArr);
resultJson.put("match", "false");
resultJsonArr.put(resultJson);
}
}
}
resultAllJson.put("result", resultJsonArr);
qJson.put(key, resultAllJson);
}
} catch (JSONException ex) {
log.error("JSONException: " + ex);
throw new ServletException("JSONReconcileServlet JSONException: "
+ ex);
} catch (SearchException ex) {
log.error("SearchException: " + ex);
throw new ServletException("JSONReconcileServlet SearchException: "
+ ex);
} catch (IOException ex) {
log.error("IOException: " + ex);
throw new ServletException("JSONReconcileServlet IOException: "
+ ex);
}
return qJson;
}
private Analyzer getAnalyzer(ServletContext servletContext)
throws SearchException {
Object obj = servletContext.getAttribute(LuceneSetup.ANALYZER);
if (obj == null || !(obj instanceof Analyzer))
throw new SearchException("Could not get anlyzer");
else
return (Analyzer) obj;
}
private Query makeReconcileNameQuery(String querystr, Analyzer analyzer, HttpServletRequest request) {
return makeTokenizedNameQuery(querystr, analyzer, request);
}
private Query makeTokenizedNameQuery(String querystr, Analyzer analyzer, HttpServletRequest request) {
String termName = VitroLuceneTermNames.NAME_STEMMED;
BooleanQuery boolQuery = new BooleanQuery();
// Use the query parser to analyze the search term the same way the indexed text was analyzed.
// For example, text is lowercased, and function words are stripped out.
QueryParser parser = getQueryParser(termName, analyzer);
// The wildcard query doesn't play well with stemming. Query term name:tales* doesn't match
// "tales", which is indexed as "tale", while query term name:tales does. Obviously we need
// the wildcard for name:tal*, so the only way to get them all to match is use a disjunction
// of wildcard and non-wildcard queries. The query will look have only an implicit disjunction
// operator: e.g., +(name:tales name:tales*)
try {
log.debug("Adding non-wildcard query for " + querystr);
Query query = parser.parse(querystr);
boolQuery.add(query, BooleanClause.Occur.SHOULD);
// Prevent ParseException here when adding * after a space.
// If there's a space at the end, we don't need the wildcard query.
if (! querystr.endsWith(" ")) {
log.debug("Adding wildcard query for " + querystr);
Query wildcardQuery = parser.parse(querystr + "*");
boolQuery.add(wildcardQuery, BooleanClause.Occur.SHOULD);
}
log.debug("Name query is: " + boolQuery.toString());
} catch (ParseException e) {
log.warn(e, e);
}
return boolQuery;
}
private QueryParser getQueryParser(String searchField, Analyzer analyzer){
// searchField indicates which field to search against when there is no term
// indicated in the query string.
// The analyzer is needed so that we use the same analyzer on the search queries as
// was used on the text that was indexed.
QueryParser qp = new QueryParser(Version.LUCENE_29, searchField,analyzer);
//this sets the query parser to AND all of the query terms it finds.
qp.setDefaultOperator(QueryParser.AND_OPERATOR);
return qp;
}
private Query getReconcileQuery(VitroRequest request, Analyzer analyzer,
String querystr, String typeParam, ArrayList<String[]> propertiesList) throws SearchException{
Query query = null;
try {
if( querystr == null){
log.error("There was no Parameter '"+ QUERY_PARAMETER_NAME
+"' in the request.");
return null;
}else if( querystr.length() > MAX_QUERY_LENGTH ){
log.debug("The search was too long. The maximum " +
"query length is " + MAX_QUERY_LENGTH );
return null;
}
query = makeReconcileNameQuery(querystr, analyzer, request);
// filter by type
if (typeParam != null) {
BooleanQuery boolQuery = new BooleanQuery();
boolQuery.add( new TermQuery(
new Term(VitroLuceneTermNames.RDFTYPE,
typeParam)),
BooleanClause.Occur.MUST);
boolQuery.add(query, BooleanClause.Occur.MUST);
query = boolQuery;
}
// if propertiesList has elements, add extra queries to query
Iterator<String[]> it = propertiesList.iterator();
while (it.hasNext()) {
String[] pvPair = it.next();
Query extraQuery = makeReconcileNameQuery(pvPair[1], analyzer, request);
if ( ! StringUtils.isEmpty(pvPair[0]) ) {
BooleanQuery boolQuery = new BooleanQuery();
boolQuery.add(new TermQuery(new Term(
VitroLuceneTermNames.RDFTYPE, pvPair[0])),
BooleanClause.Occur.MUST);
boolQuery.add(extraQuery, BooleanClause.Occur.MUST);
extraQuery = boolQuery;
}
((BooleanQuery)query).add(extraQuery, BooleanClause.Occur.MUST);
}
} catch (Exception ex) {
throw new SearchException(ex.getMessage());
}
return query;
}
}

View file

@ -33,8 +33,8 @@ import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.SolrIndividualListController.PageRecord;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController.PageRecord; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.SolrIndividualListController;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
@ -43,7 +43,6 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.SelectListGenerator; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.SelectListGenerator;
import edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch; import edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.IndividualTemplateModel;
/** /**
* This servlet is for servicing requests for JSON objects/data. * This servlet is for servicing requests for JSON objects/data.
@ -51,10 +50,12 @@ import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.Individual
* @author bdc34 * @author bdc34
* *
*/ */
// RY Rename to JsonServlet once the transition to Solr is complete.
public class SolrJsonServlet extends VitroHttpServlet { public class SolrJsonServlet extends VitroHttpServlet {
private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(SolrJsonServlet.class);
private static final int REPLY_SIZE = 256;
@Override @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp); super.doPost(req, resp);
@ -77,8 +78,8 @@ public class SolrJsonServlet extends VitroHttpServlet {
}else if( vreq.getParameter("getN3EditOptionList") != null ){ }else if( vreq.getParameter("getN3EditOptionList") != null ){
doN3EditOptionList(req,resp); doN3EditOptionList(req,resp);
return; return;
}else if( vreq.getParameter("getLuceneIndividualsByVClass") != null ){ }else if( vreq.getParameter("getSolrIndividualsByVClass") != null ){
getLuceneIndividualsByVClass(req,resp); getSolrIndividualsByVClass(req,resp);
return; return;
}else if( vreq.getParameter("getVClassesForVClassGroup") != null ){ }else if( vreq.getParameter("getVClassesForVClassGroup") != null ){
getVClassesForVClassGroup(req,resp); getVClassesForVClassGroup(req,resp);
@ -125,7 +126,7 @@ public class SolrJsonServlet extends VitroHttpServlet {
writer.write(map.toString()); writer.write(map.toString());
} }
private void getLuceneIndividualsByVClass( HttpServletRequest req, HttpServletResponse resp ){ private void getSolrIndividualsByVClass( HttpServletRequest req, HttpServletResponse resp ){
String errorMessage = null; String errorMessage = null;
JSONObject rObj = null; JSONObject rObj = null;
try{ try{
@ -144,7 +145,7 @@ public class SolrJsonServlet extends VitroHttpServlet {
log.debug("parameter vclassId URI parameter expected "); log.debug("parameter vclassId URI parameter expected ");
throw new Exception("parameter vclassId URI parameter expected "); throw new Exception("parameter vclassId URI parameter expected ");
} }
rObj = getLuceneIndividualsByVClass(vclass.getURI(),req, getServletContext()); rObj = getSolrIndividualsByVClass(vclass.getURI(),req, getServletContext());
}catch(Exception ex){ }catch(Exception ex){
errorMessage = ex.toString(); errorMessage = ex.toString();
log.error(ex,ex); log.error(ex,ex);
@ -173,7 +174,7 @@ public class SolrJsonServlet extends VitroHttpServlet {
} }
public static JSONObject getLuceneIndividualsByVClass(String vclassURI, HttpServletRequest req, ServletContext context) throws Exception { public static JSONObject getSolrIndividualsByVClass(String vclassURI, HttpServletRequest req, ServletContext context) throws Exception {
VitroRequest vreq = new VitroRequest(req); VitroRequest vreq = new VitroRequest(req);
VClass vclass=null; VClass vclass=null;
@ -191,6 +192,7 @@ public class SolrJsonServlet extends VitroHttpServlet {
if( log.isDebugEnabled() ){ if( log.isDebugEnabled() ){
@SuppressWarnings("unchecked")
Enumeration<String> e = vreq.getParameterNames(); Enumeration<String> e = vreq.getParameterNames();
while(e.hasMoreElements()){ while(e.hasMoreElements()){
String name = (String)e.nextElement(); String name = (String)e.nextElement();
@ -222,9 +224,9 @@ public class SolrJsonServlet extends VitroHttpServlet {
.put("name",vclass.getName())); .put("name",vclass.getName()));
if (vclass != null) { if (vclass != null) {
String alpha = IndividualListController.getAlphaParameter(vreq); String alpha = SolrIndividualListController.getAlphaParameter(vreq);
int page = IndividualListController.getPageParameter(vreq); int page = SolrIndividualListController.getPageParameter(vreq);
Map<String,Object> map = IndividualListController.getResultsForVClass( Map<String,Object> map = SolrIndividualListController.getResultsForVClass(
vclass.getURI(), vclass.getURI(),
page, page,
alpha, alpha,
@ -234,8 +236,9 @@ public class SolrJsonServlet extends VitroHttpServlet {
rObj.put("totalCount", map.get("totalCount")); rObj.put("totalCount", map.get("totalCount"));
rObj.put("alpha", map.get("alpha")); rObj.put("alpha", map.get("alpha"));
@SuppressWarnings("unchecked")
List<Individual> inds = (List<Individual>)map.get("entities"); List<Individual> inds = (List<Individual>)map.get("entities");
List<IndividualTemplateModel> indsTm = new ArrayList<IndividualTemplateModel>();
JSONArray jInds = new JSONArray(); JSONArray jInds = new JSONArray();
for(Individual ind : inds ){ for(Individual ind : inds ){
JSONObject jo = new JSONObject(); JSONObject jo = new JSONObject();
@ -259,6 +262,7 @@ public class SolrJsonServlet extends VitroHttpServlet {
rObj.put("individuals", jInds); rObj.put("individuals", jInds);
JSONArray wpages = new JSONArray(); JSONArray wpages = new JSONArray();
@SuppressWarnings("unchecked")
List<PageRecord> pages = (List<PageRecord>)map.get("pages"); List<PageRecord> pages = (List<PageRecord>)map.get("pages");
for( PageRecord pr: pages ){ for( PageRecord pr: pages ){
JSONObject p = new JSONObject(); JSONObject p = new JSONObject();
@ -382,6 +386,7 @@ public class SolrJsonServlet extends VitroHttpServlet {
HttpSession session = vreq.getSession(); HttpSession session = vreq.getSession();
if( session == null ) if( session == null )
throw new ServletException("there is no session to get the pervious results from"); throw new ServletException("there is no session to get the pervious results from");
@SuppressWarnings("unchecked")
List<Individual> entsInVClass = (List<Individual>) session.getAttribute(resKey); List<Individual> entsInVClass = (List<Individual>) session.getAttribute(resKey);
if( entsInVClass == null ) if( entsInVClass == null )
throw new ServletException("Could not find List<Individual> for resultKey " + resKey); throw new ServletException("Could not find List<Individual> for resultKey " + resKey);
@ -389,7 +394,6 @@ public class SolrJsonServlet extends VitroHttpServlet {
List<Individual> entsToReturn = new ArrayList<Individual>(REPLY_SIZE); List<Individual> entsToReturn = new ArrayList<Individual>(REPLY_SIZE);
boolean more = false; boolean more = false;
int count = 0; int count = 0;
int size = REPLY_SIZE;
/* we have a large number of items to send back so we need to stash the list in the session scope */ /* we have a large number of items to send back so we need to stash the list in the session scope */
if( entsInVClass.size() > REPLY_SIZE){ if( entsInVClass.size() > REPLY_SIZE){
more = true; more = true;
@ -544,7 +548,7 @@ public class SolrJsonServlet extends VitroHttpServlet {
private JSONArray individualsToJson(List<Individual> individuals) throws ServletException { private JSONArray individualsToJson(List<Individual> individuals) throws ServletException {
JSONArray ja = new JSONArray(); JSONArray ja = new JSONArray();
Iterator it = individuals.iterator(); Iterator<Individual> it = individuals.iterator();
try{ try{
while(it.hasNext()){ while(it.hasNext()){
Individual ent = (Individual) it.next(); Individual ent = (Individual) it.next();
@ -560,7 +564,4 @@ public class SolrJsonServlet extends VitroHttpServlet {
return ja; return ja;
} }
private static final int REPLY_SIZE = 256;
private static final Log log = LogFactory.getLog(JSONServlet.class.getName());
} }

View file

@ -10,6 +10,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
/** /**
* Controller for comments ("contact us") page * Controller for comments ("contact us") page
@ -30,11 +31,12 @@ public class UserMailController extends VitroHttpServlet{
VitroRequest vreq = new VitroRequest(request); VitroRequest vreq = new VitroRequest(request);
try { try {
//this try block passes any errors to error.jsp //this try block passes any errors to error.jsp
if (!ContactMailServlet.isSmtpHostConfigured(request)) { if (!FreemarkerEmailFactory.isConfigured(request)) {
request.setAttribute("title", "Mail All Users Form"); request.setAttribute("title", "Mail All Users Form");
request.setAttribute("bodyJsp", "/contact_err.jsp");// <<< this is where the body gets set request.setAttribute("bodyJsp", "/contact_err.jsp");// <<< this is where the body gets set
request.setAttribute("ERR","This application has not yet been configured to send mail -- " + request.setAttribute("ERR",
"smtp host has not been specified in the configuration properties file."); "This application has not yet been configured to send mail. "
+ "Email properties must be specified in the configuration properties file.");
RequestDispatcher errd = request.getRequestDispatcher(Controllers.BASIC_JSP); RequestDispatcher errd = request.getRequestDispatcher(Controllers.BASIC_JSP);
errd.forward(request, response); errd.forward(request, response);
} }

View file

@ -1,88 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.accounts;
import java.util.Collection;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageUserAccounts;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
/**
* Parcel out the different actions required of the UserAccounts GUI.
*/
public class UserAccountsController extends FreemarkerHttpServlet {
private static final Log log = LogFactory
.getLog(UserAccountsController.class);
private static final String ACTION_ADD = "/add";
private static final String ACTION_DELETE = "/delete";
private static final String ACTION_EDIT = "/edit";
@Override
protected Actions requiredActions(VitroRequest vreq) {
return new Actions(new ManageUserAccounts());
}
@Override
protected ResponseValues processRequest(VitroRequest vreq) {
if (log.isDebugEnabled()) {
dumpRequestParameters(vreq);
}
String action = vreq.getPathInfo();
log.debug("action = '" + action + "'");
if (ACTION_ADD.equals(action)) {
UserAccountsAddPage page = new UserAccountsAddPage(vreq);
page.parseParametersAndValidate();
if (page.isSubmit() && page.isValid()) {
return addAccountAndShowList(vreq, page);
} else {
return page.showPage();
}
} else if (ACTION_EDIT.equals(action)) {
UserAccountsEditPage page = new UserAccountsEditPage(vreq);
page.parseParametersAndValidate();
if (page.isSubmit() && page.isValid()) {
return editAccountAndShowList(vreq, page);
} else {
return page.showPage();
}
} else if (ACTION_DELETE.equals(action)) {
UserAccountsDeleter deleter = new UserAccountsDeleter(vreq);
Collection<String> deletedUris = deleter.delete();
return new UserAccountsListPage(vreq)
.showPageWithDeletions(deletedUris);
} else {
UserAccountsListPage page = new UserAccountsListPage(vreq);
return page.showPage();
}
}
private ResponseValues addAccountAndShowList(VitroRequest vreq,
UserAccountsAddPage addPage) {
addPage.createNewAccount();
UserAccountsListPage listPage = new UserAccountsListPage(vreq);
return listPage.showPageWithNewAccount(addPage.getAddedAccount(),
addPage.wasPasswordEmailSent());
}
private ResponseValues editAccountAndShowList(VitroRequest vreq,
UserAccountsEditPage editPage) {
editPage.updateAccount();
UserAccountsListPage listPage = new UserAccountsListPage(vreq);
return listPage.showPageWithUpdatedAccount(
editPage.getUpdatedAccount(), editPage.wasPasswordEmailSent());
}
}

View file

@ -1,30 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.accounts;
import java.util.Collection;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
/**
* TODO delete and kick to Accounts list with message, telling how many were
* deleted. If there was a problem, the user will need to infer it from the
* count??
*/
public class UserAccountsDeleter extends UserAccountsPage {
protected UserAccountsDeleter(VitroRequest vreq) {
super(vreq);
}
/**
* @return
*
*/
public Collection<String> delete() {
// TODO Auto-generated method stub
throw new RuntimeException(
"UserAccountsDeleter.delete() not implemented.");
}
}

View file

@ -1,83 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.accounts;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
/**
* TODO present the form. Get the submission.
*
* TODO If email is available, present the reset flag with message templage, and send email
*
* TODO if email is not available, allow password change with checks for validity
*
* TODO If successful, go to AccountsList with message and optional password message.
*
* TODO if unsuccessful, go back to the page, with errors.
*
* TODO How much of this can be shared with AddPage? Email templates?
*/
public class UserAccountsEditPage extends UserAccountsPage {
private static final String TEMPLATE_NAME = "userAccounts-edit.ftl";
public UserAccountsEditPage(VitroRequest vreq) {
super(vreq);
}
public ResponseValues showPage() {
return new TemplateResponseValues(TEMPLATE_NAME);
}
/**
* @return
*/
public UserAccount updateAccount() {
// TODO Auto-generated method stub
throw new RuntimeException("UserAccountsEditPage.updateAccount() not implemented.");
}
/**
* @return
*/
public boolean wasPasswordEmailSent() {
// TODO Auto-generated method stub
throw new RuntimeException("UserAccountsEditPage.wasPasswordEmailSent() not implemented.");
}
/**
* @return
*/
public UserAccount getUpdatedAccount() {
// TODO Auto-generated method stub
throw new RuntimeException("UserAccountsEditPage.getUpdatedAccount() not implemented.");
}
/**
*
*/
public void parseParametersAndValidate() {
// TODO Auto-generated method stub
throw new RuntimeException("UserAccountsEditPage.parseParametersAndValidate() not implemented.");
}
/**
* @return
*/
public boolean isValid() {
// TODO Auto-generated method stub
throw new RuntimeException("UserAccountsEditPage.isValid() not implemented.");
}
/**
* @return
*/
public boolean isSubmit() {
// TODO Auto-generated method stub
throw new RuntimeException("UserAccountsEditPage.isSubmit() not implemented.");
}
}

View file

@ -2,7 +2,6 @@
package edu.cornell.mannlib.vitro.webapp.controller.accounts; package edu.cornell.mannlib.vitro.webapp.controller.accounts;
/** /**
* How are the accounts to be sorted? * How are the accounts to be sorted?
*/ */
@ -78,4 +77,10 @@ public class UserAccountsOrdering {
public Direction getDirection() { public Direction getDirection() {
return direction; return direction;
} }
@Override
public String toString() {
return "UserAccountsOrdering[field=" + field + ", direction="
+ direction + "]";
}
} }

View file

@ -3,13 +3,16 @@
package edu.cornell.mannlib.vitro.webapp.controller.accounts; package edu.cornell.mannlib.vitro.webapp.controller.accounts;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -17,11 +20,14 @@ import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
/** /**
* Common routines for the page controllers. * Common routines for the page controllers.
@ -29,6 +35,12 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
public abstract class UserAccountsPage { public abstract class UserAccountsPage {
private static final Log log = LogFactory.getLog(UserAccountsPage.class); private static final Log log = LogFactory.getLog(UserAccountsPage.class);
/**
* After the account is created, or the password is reset, the user has this
* many days to repond to the email.
*/
protected static final int DAYS_TO_USE_PASSWORD_LINK = 90;
protected final VitroRequest vreq; protected final VitroRequest vreq;
protected final ServletContext ctx; protected final ServletContext ctx;
protected final OntModel userAccountsModel; protected final OntModel userAccountsModel;
@ -47,6 +59,10 @@ public abstract class UserAccountsPage {
userAccountsDao = wdf.getUserAccountsDao(); userAccountsDao = wdf.getUserAccountsDao();
} }
protected boolean isEmailEnabled() {
return FreemarkerEmailFactory.isConfigured(vreq);
}
protected String getStringParameter(String key, String defaultValue) { protected String getStringParameter(String key, String defaultValue) {
String value = vreq.getParameter(key); String value = vreq.getParameter(key);
return (value == null) ? defaultValue : value; return (value == null) ? defaultValue : value;
@ -75,6 +91,17 @@ public abstract class UserAccountsPage {
return (value != null); return (value != null);
} }
/**
* Treat the presence of a certain parameter, with a desired value, as a
* boolean flag.
*
* An example would be radio buttons with values of "yes" and
* "no". The expected value would be "yes".
*/
protected boolean isParameterAsExpected(String key, String expected) {
return expected.equals(getStringParameter(key, ""));
}
/** /**
* Create a list of all known PermissionSets. * Create a list of all known PermissionSets.
*/ */
@ -94,15 +121,32 @@ public abstract class UserAccountsPage {
* Make these URLs available to all of the pages. * Make these URLs available to all of the pages.
*/ */
protected Map<String, String> buildUrlsMap() { protected Map<String, String> buildUrlsMap() {
UrlBuilder urlBuilder = new UrlBuilder(vreq.getAppBean());
Map<String, String> map = new HashMap<String, String>(); Map<String, String> map = new HashMap<String, String>();
map.put("list", urlBuilder.getPortalUrl("/userAccounts/list")); map.put("list", UrlBuilder.getUrl("/accountsAdmin/list"));
map.put("add", urlBuilder.getPortalUrl("/userAccounts/add")); map.put("add", UrlBuilder.getUrl("/accountsAdmin/add"));
map.put("delete", urlBuilder.getPortalUrl("/userAccounts/delete")); map.put("delete", UrlBuilder.getUrl("/accountsAdmin/delete"));
map.put("myAccount", UrlBuilder.getUrl("/accounts/myAccount"));
map.put("createPassword", UrlBuilder.getUrl("/accounts/createPassword"));
map.put("resetPassword", UrlBuilder.getUrl("/accounts/resetPassword"));
return map; return map;
} }
protected static String editAccountUrl(String uri) {
return UrlBuilder.getUrl("/accountsAdmin/edit", new ParamMap(
"editAccount", uri));
}
protected Date figureExpirationDate() {
Calendar c = Calendar.getInstance();
c.add(Calendar.DATE, DAYS_TO_USE_PASSWORD_LINK);
return c.getTime();
}
protected boolean checkPasswordLength(String pw) {
return pw.length() >= UserAccount.MIN_PASSWORD_LENGTH
&& pw.length() <= UserAccount.MAX_PASSWORD_LENGTH;
}
} }

View file

@ -75,4 +75,11 @@ public class UserAccountsSelectionCriteria {
return (t == null) ? nullValue : t; return (t == null) ? nullValue : t;
} }
@Override
public String toString() {
return "UserAccountsSelectionCriteria[accountsPerPage="
+ accountsPerPage + ", pageIndex=" + pageIndex + ", orderBy="
+ orderBy + ", roleFilterUri='" + roleFilterUri
+ "', searchTerm='" + searchTerm + "']";
}
} }

View file

@ -1,21 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.accounts;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
/**
* TODO If hash is not valid display bogus message.
*
* TODO Set the password fields, reset the expire time, set account active, kick
* to home page with message. Send confirmation email.
*
* TODO How do we know "createPassword" from "setPassword"? a parameter? or just by account status?
*/
public class UserAccountsSetPasswordPage extends UserAccountsPage {
protected UserAccountsSetPasswordPage(VitroRequest vreq) {
super(vreq);
}
}

View file

@ -1,6 +1,6 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */ /* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.accounts; package edu.cornell.mannlib.vitro.webapp.controller.accounts.admin;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -9,6 +9,8 @@ import java.util.Map;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
@ -16,11 +18,6 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Tem
* Handle the "Add new account" form display and submission. * Handle the "Add new account" form display and submission.
* *
* TODO Associate a profile from this account * TODO Associate a profile from this account
*
* TODO Handle sending of email.
*
* TODO Handle initial password set if email isn't available. Set password
* fields, change-required flag, account is active.
*/ */
public class UserAccountsAddPage extends UserAccountsPage { public class UserAccountsAddPage extends UserAccountsPage {
private static final String PARAMETER_SUBMIT = "submitAdd"; private static final String PARAMETER_SUBMIT = "submitAdd";
@ -32,12 +29,15 @@ public class UserAccountsAddPage extends UserAccountsPage {
private static final String ERROR_NO_EMAIL = "errorEmailIsEmpty"; private static final String ERROR_NO_EMAIL = "errorEmailIsEmpty";
private static final String ERROR_EMAIL_IN_USE = "errorEmailInUse"; private static final String ERROR_EMAIL_IN_USE = "errorEmailInUse";
private static final String ERROR_EMAIL_INVALID_FORMAT = "errorEmailInvalidFormat";
private static final String ERROR_NO_FIRST_NAME = "errorFirstNameIsEmpty"; private static final String ERROR_NO_FIRST_NAME = "errorFirstNameIsEmpty";
private static final String ERROR_NO_LAST_NAME = "errorLastNameIsEmpty"; private static final String ERROR_NO_LAST_NAME = "errorLastNameIsEmpty";
private static final String ERROR_NO_ROLE = "errorNoRoleSelected"; private static final String ERROR_NO_ROLE = "errorNoRoleSelected";
private static final String TEMPLATE_NAME = "userAccounts-add.ftl"; private static final String TEMPLATE_NAME = "userAccounts-add.ftl";
private final UserAccountsAddPageStrategy strategy;
/* The request parameters */ /* The request parameters */
private boolean submit; private boolean submit;
private String emailAddress = ""; private String emailAddress = "";
@ -46,14 +46,18 @@ public class UserAccountsAddPage extends UserAccountsPage {
private String selectedRoleUri = ""; private String selectedRoleUri = "";
private boolean associateWithProfile; private boolean associateWithProfile;
/* The result of validating a "submit" request. */ /** The result of validating a "submit" request. */
private String errorCode = ""; private String errorCode = "";
/** The new user account, if one was created. */
private UserAccount addedAccount;
public UserAccountsAddPage(VitroRequest vreq) { public UserAccountsAddPage(VitroRequest vreq) {
super(vreq); super(vreq);
}
public void parseParametersAndValidate() { this.strategy = UserAccountsAddPageStrategy.getInstance(vreq, this,
isEmailEnabled());
parseRequestParameters(); parseRequestParameters();
if (submit) { if (submit) {
@ -66,8 +70,11 @@ public class UserAccountsAddPage extends UserAccountsPage {
emailAddress = getStringParameter(PARAMETER_EMAIL_ADDRESS, ""); emailAddress = getStringParameter(PARAMETER_EMAIL_ADDRESS, "");
firstName = getStringParameter(PARAMETER_FIRST_NAME, ""); firstName = getStringParameter(PARAMETER_FIRST_NAME, "");
lastName = getStringParameter(PARAMETER_LAST_NAME, ""); lastName = getStringParameter(PARAMETER_LAST_NAME, "");
selectedRoleUri = getRoleChoices(); selectedRoleUri = getStringParameter(PARAMETER_ROLE, "");
associateWithProfile = getAssociateFlag(); associateWithProfile = isParameterAsExpected(
PARAMETER_ASSOCIATE_WITH_PROFILE, "yes");
strategy.parseAdditionalParameters();
} }
public boolean isSubmit() { public boolean isSubmit() {
@ -79,12 +86,16 @@ public class UserAccountsAddPage extends UserAccountsPage {
errorCode = ERROR_NO_EMAIL; errorCode = ERROR_NO_EMAIL;
} else if (isEmailInUse()) { } else if (isEmailInUse()) {
errorCode = ERROR_EMAIL_IN_USE; errorCode = ERROR_EMAIL_IN_USE;
} else if (!isEmailValidFormat()) {
errorCode = ERROR_EMAIL_INVALID_FORMAT;
} else if (firstName.isEmpty()) { } else if (firstName.isEmpty()) {
errorCode = ERROR_NO_FIRST_NAME; errorCode = ERROR_NO_FIRST_NAME;
} else if (lastName.isEmpty()) { } else if (lastName.isEmpty()) {
errorCode = ERROR_NO_LAST_NAME; errorCode = ERROR_NO_LAST_NAME;
} else if (selectedRoleUri.isEmpty()) { } else if (selectedRoleUri.isEmpty()) {
errorCode = ERROR_NO_ROLE; errorCode = ERROR_NO_ROLE;
} else {
errorCode = strategy.additionalValidations();
} }
} }
@ -92,11 +103,15 @@ public class UserAccountsAddPage extends UserAccountsPage {
return userAccountsDao.getUserAccountByEmail(emailAddress) != null; return userAccountsDao.getUserAccountByEmail(emailAddress) != null;
} }
private boolean isEmailValidFormat() {
return Authenticator.isValidEmailAddress(emailAddress);
}
public boolean isValid() { public boolean isValid() {
return errorCode.isEmpty(); return errorCode.isEmpty();
} }
public UserAccount createNewAccount() { public void createNewAccount() {
UserAccount u = new UserAccount(); UserAccount u = new UserAccount();
u.setEmailAddress(emailAddress); u.setEmailAddress(emailAddress);
u.setFirstName(firstName); u.setFirstName(firstName);
@ -112,60 +127,42 @@ public class UserAccountsAddPage extends UserAccountsPage {
u.setPermissionSetUris(Collections.singleton(selectedRoleUri)); u.setPermissionSetUris(Collections.singleton(selectedRoleUri));
strategy.setAdditionalProperties(u);
String uri = userAccountsDao.insertUserAccount(u); String uri = userAccountsDao.insertUserAccount(u);
return userAccountsDao.getUserAccountByUri(uri); this.addedAccount = userAccountsDao.getUserAccountByUri(uri);
strategy.notifyUser();
} }
/** What role are they asking for? */ public final ResponseValues showPage() {
private String getRoleChoices() {
String[] roles = vreq.getParameterValues(PARAMETER_ROLE);
if ((roles == null) || (roles.length == 0)) {
return "";
} else {
return roles[0];
}
}
/** Are they associating with an Individual profile? */
private boolean getAssociateFlag() {
return "yes".equals(getStringParameter(
PARAMETER_ASSOCIATE_WITH_PROFILE, "no"));
}
public ResponseValues showPage() {
Map<String, Object> body = new HashMap<String, Object>(); Map<String, Object> body = new HashMap<String, Object>();
body.put("emailAddress", emailAddress); body.put("emailAddress", emailAddress);
body.put("firstName", firstName); body.put("firstName", firstName);
body.put("lastName", lastName); body.put("lastName", lastName);
body.put("selectedRole", selectedRoleUri); body.put("selectedRole", selectedRoleUri);
body.put("associate", associateWithProfile); if (associateWithProfile) {
body.put("associate", Boolean.TRUE);
}
body.put("roles", buildRolesList()); body.put("roles", buildRolesList());
body.put("formUrls", buildUrlsMap()); body.put("formUrls", buildUrlsMap());
if (!errorCode.isEmpty()) { if (!errorCode.isEmpty()) {
body.put(errorCode, Boolean.TRUE); body.put(errorCode, Boolean.TRUE);
} }
strategy.addMoreBodyValues(body);
return new TemplateResponseValues(TEMPLATE_NAME, body); return new TemplateResponseValues(TEMPLATE_NAME, body);
} }
/**
* @return
*/
public UserAccount getAddedAccount() { public UserAccount getAddedAccount() {
// TODO Auto-generated method stub return addedAccount;
throw new RuntimeException("UserAccountsAddPage.getAddedAccount() not implemented.");
} }
/**
* @return
*/
public boolean wasPasswordEmailSent() { public boolean wasPasswordEmailSent() {
// TODO Auto-generated method stub return this.strategy.wasPasswordEmailSent();
throw new RuntimeException("UserAccountsAddPage.wasPasswordEmailSent() not implemented.");
} }
} }

View file

@ -0,0 +1,201 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.accounts.admin;
import static javax.mail.Message.RecipientType.TO;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailMessage;
/**
* Handle the variant details of the UserAccountsAddPage.
*/
public abstract class UserAccountsAddPageStrategy extends UserAccountsPage {
protected final UserAccountsAddPage page;
public static UserAccountsAddPageStrategy getInstance(VitroRequest vreq,
UserAccountsAddPage page, boolean emailEnabled) {
if (emailEnabled) {
return new EmailStrategy(vreq, page);
} else {
return new NoEmailStrategy(vreq, page);
}
}
public UserAccountsAddPageStrategy(VitroRequest vreq,
UserAccountsAddPage page) {
super(vreq);
this.page = page;
}
protected abstract void parseAdditionalParameters();
protected abstract String additionalValidations();
protected abstract void addMoreBodyValues(Map<String, Object> body);
protected abstract void setAdditionalProperties(UserAccount u);
protected abstract void notifyUser();
protected abstract boolean wasPasswordEmailSent();
// ----------------------------------------------------------------------
// Strategy to use if email is enabled.
// ----------------------------------------------------------------------
private static class EmailStrategy extends UserAccountsAddPageStrategy {
public static final String CREATE_PASSWORD_URL = "/accounts/createPassword";
private boolean sentEmail;
public EmailStrategy(VitroRequest vreq, UserAccountsAddPage page) {
super(vreq, page);
}
@Override
protected void parseAdditionalParameters() {
// No additional parameters
}
@Override
protected String additionalValidations() {
// No additional validations
return "";
}
@Override
protected void setAdditionalProperties(UserAccount u) {
u.setPasswordLinkExpires(figureExpirationDate().getTime());
u.setStatus(Status.INACTIVE);
}
@Override
protected void addMoreBodyValues(Map<String, Object> body) {
body.put("emailIsEnabled", Boolean.TRUE);
}
@Override
protected void notifyUser() {
Map<String, Object> body = new HashMap<String, Object>();
body.put("userAccount", page.getAddedAccount());
body.put("passwordLink", buildCreatePasswordLink());
body.put("subjectLine", "Your VIVO account has been created.");
FreemarkerEmailMessage email = FreemarkerEmailFactory
.createNewMessage(vreq);
email.addRecipient(TO, page.getAddedAccount().getEmailAddress());
email.setSubject("Your VIVO account has been created.");
email.setHtmlTemplate("userAccounts-acctCreatedEmail-html.ftl");
email.setTextTemplate("userAccounts-acctCreatedEmail-text.ftl");
email.setBodyMap(body);
email.send();
sentEmail = true;
}
private String buildCreatePasswordLink() {
try {
String email = page.getAddedAccount().getEmailAddress();
String hash = page.getAddedAccount()
.getPasswordLinkExpiresHash();
String relativeUrl = UrlBuilder.getUrl(CREATE_PASSWORD_URL,
"user", email, "key", hash);
URL context = new URL(vreq.getRequestURL().toString());
URL url = new URL(context, relativeUrl);
return url.toExternalForm();
} catch (MalformedURLException e) {
return "error_creating_password_link";
}
}
@Override
protected boolean wasPasswordEmailSent() {
return sentEmail;
}
}
// ----------------------------------------------------------------------
// Strategy to use if email is not enabled.
// ----------------------------------------------------------------------
private static class NoEmailStrategy extends UserAccountsAddPageStrategy {
private static final String PARAMETER_INITIAL_PASSWORD = "initialPassword";
private static final String PARAMETER_CONFIRM_PASSWORD = "confirmPassword";
private static final String ERROR_NO_PASSWORD = "errorPasswordIsEmpty";
private static final String ERROR_WRONG_PASSWORD_LENGTH = "errorPasswordIsWrongLength";
private static final String ERROR_PASSWORDS_DONT_MATCH = "errorPasswordsDontMatch";
private String initialPassword;
private String confirmPassword;
public NoEmailStrategy(VitroRequest vreq, UserAccountsAddPage page) {
super(vreq, page);
}
@Override
protected void parseAdditionalParameters() {
initialPassword = getStringParameter(PARAMETER_INITIAL_PASSWORD, "");
confirmPassword = getStringParameter(PARAMETER_CONFIRM_PASSWORD, "");
}
@Override
protected String additionalValidations() {
if (initialPassword.isEmpty()) {
return ERROR_NO_PASSWORD;
} else if (!checkPasswordLength()) {
return ERROR_WRONG_PASSWORD_LENGTH;
} else if (!initialPassword.equals(confirmPassword)) {
return ERROR_PASSWORDS_DONT_MATCH;
} else {
return "";
}
}
private boolean checkPasswordLength() {
return initialPassword.length() >= UserAccount.MIN_PASSWORD_LENGTH
&& initialPassword.length() <= UserAccount.MAX_PASSWORD_LENGTH;
}
@Override
protected void addMoreBodyValues(Map<String, Object> body) {
body.put("initialPassword", initialPassword);
body.put("confirmPassword", confirmPassword);
body.put("minimumLength", UserAccount.MIN_PASSWORD_LENGTH);
body.put("maximumLength", UserAccount.MAX_PASSWORD_LENGTH);
}
@Override
protected void setAdditionalProperties(UserAccount u) {
u.setMd5Password(Authenticator.applyMd5Encoding(initialPassword));
u.setPasswordChangeRequired(true);
u.setStatus(Status.ACTIVE);
}
@Override
protected void notifyUser() {
// Do nothing.
}
@Override
protected boolean wasPasswordEmailSent() {
return false;
}
}
}

View file

@ -0,0 +1,100 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.accounts.admin;
import java.util.Collection;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageUserAccounts;
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.RedirectResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
/**
* Parcel out the different actions required of the Administrators portion of
* the UserAccounts GUI.
*/
public class UserAccountsAdminController extends FreemarkerHttpServlet {
private static final Log log = LogFactory
.getLog(UserAccountsAdminController.class);
private static final String ACTION_ADD = "/add";
private static final String ACTION_DELETE = "/delete";
private static final String ACTION_EDIT = "/edit";
@Override
protected Actions requiredActions(VitroRequest vreq) {
return new Actions(new ManageUserAccounts());
}
@Override
protected ResponseValues processRequest(VitroRequest vreq) {
if (log.isDebugEnabled()) {
dumpRequestParameters(vreq);
}
String action = vreq.getPathInfo();
log.debug("action = '" + action + "'");
if (ACTION_ADD.equals(action)) {
return handleAddRequest(vreq);
} else if (ACTION_EDIT.equals(action)) {
return handleEditRequest(vreq);
} else if (ACTION_DELETE.equals(action)) {
return handleDeleteRequest(vreq);
} else {
return handleListRequest(vreq);
}
}
private ResponseValues handleAddRequest(VitroRequest vreq) {
UserAccountsAddPage page = new UserAccountsAddPage(vreq);
if (page.isSubmit() && page.isValid()) {
page.createNewAccount();
UserAccountsListPage listPage = new UserAccountsListPage(vreq);
return listPage.showPageWithNewAccount(page.getAddedAccount(),
page.wasPasswordEmailSent());
} else {
return page.showPage();
}
}
private ResponseValues handleEditRequest(VitroRequest vreq) {
UserAccountsEditPage page = new UserAccountsEditPage(vreq);
if (page.isBogus()) {
return showHomePage(vreq, page.getBogusMessage());
} else if (page.isSubmit() && page.isValid()) {
page.updateAccount();
UserAccountsListPage listPage = new UserAccountsListPage(vreq);
return listPage.showPageWithUpdatedAccount(
page.getUpdatedAccount(), page.wasPasswordEmailSent());
} else {
return page.showPage();
}
}
private ResponseValues handleDeleteRequest(VitroRequest vreq) {
UserAccountsDeleter deleter = new UserAccountsDeleter(vreq);
Collection<String> deletedUris = deleter.delete();
return new UserAccountsListPage(vreq)
.showPageWithDeletions(deletedUris);
}
private ResponseValues handleListRequest(VitroRequest vreq) {
UserAccountsListPage page = new UserAccountsListPage(vreq);
return page.showPage();
}
private ResponseValues showHomePage(VitroRequest vreq, String message) {
DisplayMessage.setMessage(vreq, message);
return new RedirectResponseValues("/");
}
}

View file

@ -0,0 +1,53 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.accounts.admin;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage;
import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
/**
* Process a request to delete User Accounts.
*/
public class UserAccountsDeleter extends UserAccountsPage {
private static final String PARAMETER_DELETE_ACCOUNT = "deleteAccount";
/** Might be empty, but never null. */
private final String[] uris;
public UserAccountsDeleter(VitroRequest vreq) {
super(vreq);
String[] values = vreq.getParameterValues(PARAMETER_DELETE_ACCOUNT);
if (values == null) {
this.uris = new String[0];
} else {
this.uris = values;
}
}
public Collection<String> delete() {
List<String> deletedUris = new ArrayList<String>();
WebappDaoFactory wadf = vreq.getWebappDaoFactory();
UserAccountsDao dao = wadf.getUserAccountsDao();
for (String uri: uris) {
UserAccount u = dao.getUserAccountByUri(uri);
if (u != null) {
dao.deleteUserAccount(uri);
deletedUris.add(uri);
}
}
return deletedUris;
}
}

View file

@ -0,0 +1,214 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.accounts.admin;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage;
import edu.cornell.mannlib.vitro.webapp.controller.accounts.user.UserAccountsUserController;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
/**
* Handle the "Edit Account" form display and submission.
*/
public class UserAccountsEditPage extends UserAccountsPage {
private static final Log log = LogFactory
.getLog(UserAccountsEditPage.class);
private static final String PARAMETER_SUBMIT = "submitEdit";
private static final String PARAMETER_USER_URI = "editAccount";
private static final String PARAMETER_EMAIL_ADDRESS = "emailAddress";
private static final String PARAMETER_FIRST_NAME = "firstName";
private static final String PARAMETER_LAST_NAME = "lastName";
private static final String PARAMETER_ROLE = "role";
private static final String PARAMETER_ASSOCIATE_WITH_PROFILE = "associate";
private static final String ERROR_NO_EMAIL = "errorEmailIsEmpty";
private static final String ERROR_EMAIL_IN_USE = "errorEmailInUse";
private static final String ERROR_EMAIL_INVALID_FORMAT = "errorEmailInvalidFormat";
private static final String ERROR_NO_FIRST_NAME = "errorFirstNameIsEmpty";
private static final String ERROR_NO_LAST_NAME = "errorLastNameIsEmpty";
private static final String ERROR_NO_ROLE = "errorNoRoleSelected";
private static final String TEMPLATE_NAME = "userAccounts-edit.ftl";
private final UserAccountsEditPageStrategy strategy;
/* The request parameters */
private boolean submit;
private String userUri = "";
private String emailAddress = "";
private String firstName = "";
private String lastName = "";
private String selectedRoleUri = "";
private boolean associateWithProfile;
private UserAccount userAccount;
/** The result of checking whether this request is even appropriate. */
private String bogusMessage = "";
/** The result of validating a "submit" request. */
private String errorCode = "";
public UserAccountsEditPage(VitroRequest vreq) {
super(vreq);
this.strategy = UserAccountsEditPageStrategy.getInstance(vreq, this,
isEmailEnabled());
parseRequestParameters();
validateUserAccountInfo();
if (isSubmit() && !isBogus()) {
validateParameters();
}
}
private void parseRequestParameters() {
submit = isFlagOnRequest(PARAMETER_SUBMIT);
userUri = getStringParameter(PARAMETER_USER_URI, "");
emailAddress = getStringParameter(PARAMETER_EMAIL_ADDRESS, "");
firstName = getStringParameter(PARAMETER_FIRST_NAME, "");
lastName = getStringParameter(PARAMETER_LAST_NAME, "");
selectedRoleUri = getStringParameter(PARAMETER_ROLE, "");
associateWithProfile = isParameterAsExpected(
PARAMETER_ASSOCIATE_WITH_PROFILE, "yes");
strategy.parseAdditionalParameters();
}
private void validateUserAccountInfo() {
userAccount = userAccountsDao.getUserAccountByUri(userUri);
if (userAccount == null) {
log.warn("Edit account for '" + userUri
+ "' is bogus: no such user");
bogusMessage = UserAccountsUserController.BOGUS_STANDARD_MESSAGE;
return;
}
}
public boolean isBogus() {
return !bogusMessage.isEmpty();
}
public String getBogusMessage() {
return bogusMessage;
}
public boolean isSubmit() {
return submit;
}
private void validateParameters() {
if (emailAddress.isEmpty()) {
errorCode = ERROR_NO_EMAIL;
} else if (emailIsChanged() && isEmailInUse()) {
errorCode = ERROR_EMAIL_IN_USE;
} else if (!isEmailValidFormat()) {
errorCode = ERROR_EMAIL_INVALID_FORMAT;
} else if (firstName.isEmpty()) {
errorCode = ERROR_NO_FIRST_NAME;
} else if (lastName.isEmpty()) {
errorCode = ERROR_NO_LAST_NAME;
} else if (selectedRoleUri.isEmpty()) {
errorCode = ERROR_NO_ROLE;
} else {
errorCode = strategy.additionalValidations();
}
}
private boolean emailIsChanged() {
return !emailAddress.equals(userAccount.getEmailAddress());
}
private boolean isEmailInUse() {
return userAccountsDao.getUserAccountByEmail(emailAddress) != null;
}
private boolean isEmailValidFormat() {
return Authenticator.isValidEmailAddress(emailAddress);
}
public boolean isValid() {
return errorCode.isEmpty();
}
public final ResponseValues showPage() {
Map<String, Object> body = new HashMap<String, Object>();
if (isSubmit()) {
body.put("emailAddress", emailAddress);
body.put("firstName", firstName);
body.put("lastName", lastName);
body.put("selectedRole", selectedRoleUri);
} else {
body.put("emailAddress", userAccount.getEmailAddress());
body.put("firstName", userAccount.getFirstName());
body.put("lastName", userAccount.getLastName());
body.put("selectedRole", getExistingRoleUri());
}
body.put("roles", buildRolesList());
if (associateWithProfile) {
body.put("associate", Boolean.TRUE);
}
body.put("formUrls", buildUrlsMapWithEditUrl());
if (!errorCode.isEmpty()) {
body.put(errorCode, Boolean.TRUE);
}
strategy.addMoreBodyValues(body);
return new TemplateResponseValues(TEMPLATE_NAME, body);
}
private String getExistingRoleUri() {
Set<String> uris = userAccount.getPermissionSetUris();
if (uris.isEmpty()) {
return "";
} else {
return uris.iterator().next();
}
}
private Map<String, String> buildUrlsMapWithEditUrl() {
Map<String, String> map = buildUrlsMap();
map.put("edit", editAccountUrl(userAccount.getUri()));
return map;
}
public void updateAccount() {
userAccount.setEmailAddress(emailAddress);
userAccount.setFirstName(firstName);
userAccount.setLastName(lastName);
userAccount
.setPermissionSetUris(Collections.singleton(selectedRoleUri));
strategy.setAdditionalProperties(userAccount);
userAccountsDao.updateUserAccount(userAccount);
strategy.notifyUser();
}
public boolean wasPasswordEmailSent() {
return strategy.wasPasswordEmailSent();
}
public UserAccount getUpdatedAccount() {
return userAccount;
}
}

View file

@ -0,0 +1,207 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.accounts.admin;
import static javax.mail.Message.RecipientType.TO;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailMessage;
/**
* Handle the variant details of the UserAccountsAddPage.
*/
public abstract class UserAccountsEditPageStrategy extends UserAccountsPage {
protected final UserAccountsEditPage page;
public static UserAccountsEditPageStrategy getInstance(VitroRequest vreq,
UserAccountsEditPage page, boolean emailEnabled) {
if (emailEnabled) {
return new EmailStrategy(vreq, page);
} else {
return new NoEmailStrategy(vreq, page);
}
}
public UserAccountsEditPageStrategy(VitroRequest vreq,
UserAccountsEditPage page) {
super(vreq);
this.page = page;
}
protected abstract void parseAdditionalParameters();
protected abstract String additionalValidations();
protected abstract void addMoreBodyValues(Map<String, Object> body);
protected abstract void setAdditionalProperties(UserAccount u);
protected abstract void notifyUser();
protected abstract boolean wasPasswordEmailSent();
// ----------------------------------------------------------------------
// Strategy to use if email is enabled.
// ----------------------------------------------------------------------
private static class EmailStrategy extends UserAccountsEditPageStrategy {
private static final String PARAMETER_RESET_PASSWORD = "resetPassword";
public static final String RESET_PASSWORD_URL = "/accounts/resetPassword";
private boolean resetPassword;
private boolean sentEmail;
public EmailStrategy(VitroRequest vreq, UserAccountsEditPage page) {
super(vreq, page);
}
@Override
protected void parseAdditionalParameters() {
resetPassword = isFlagOnRequest(PARAMETER_RESET_PASSWORD);
}
@Override
protected String additionalValidations() {
// No additional validations
return "";
}
@Override
protected void setAdditionalProperties(UserAccount u) {
if (resetPassword) {
u.setPasswordLinkExpires(figureExpirationDate().getTime());
}
}
@Override
protected void addMoreBodyValues(Map<String, Object> body) {
body.put("emailIsEnabled", Boolean.TRUE);
if (resetPassword) {
body.put("resetPassword", Boolean.TRUE);
}
}
@Override
protected void notifyUser() {
if (!resetPassword) {
return;
}
Map<String, Object> body = new HashMap<String, Object>();
body.put("userAccount", page.getUpdatedAccount());
body.put("passwordLink", buildResetPasswordLink());
body.put("subjectLine", "Reset password request");
FreemarkerEmailMessage email = FreemarkerEmailFactory
.createNewMessage(vreq);
email.addRecipient(TO, page.getUpdatedAccount().getEmailAddress());
email.setSubject("Reset password request");
email.setHtmlTemplate("userAccounts-resetPasswordEmail-html.ftl");
email.setTextTemplate("userAccounts-resetPasswordEmail-text.ftl");
email.setBodyMap(body);
email.send();
sentEmail = true;
}
private String buildResetPasswordLink() {
try {
String email = page.getUpdatedAccount().getEmailAddress();
String hash = page.getUpdatedAccount()
.getPasswordLinkExpiresHash();
String relativeUrl = UrlBuilder.getUrl(RESET_PASSWORD_URL,
"user", email, "key", hash);
URL context = new URL(vreq.getRequestURL().toString());
URL url = new URL(context, relativeUrl);
return url.toExternalForm();
} catch (MalformedURLException e) {
return "error_creating_password_link";
}
}
@Override
protected boolean wasPasswordEmailSent() {
return sentEmail;
}
}
// ----------------------------------------------------------------------
// Strategy to use if email is not enabled.
// ----------------------------------------------------------------------
private static class NoEmailStrategy extends UserAccountsEditPageStrategy {
private static final String PARAMETER_NEW_PASSWORD = "newPassword";
private static final String PARAMETER_CONFIRM_PASSWORD = "confirmPassword";
private static final String ERROR_WRONG_PASSWORD_LENGTH = "errorPasswordIsWrongLength";
private static final String ERROR_PASSWORDS_DONT_MATCH = "errorPasswordsDontMatch";
private String newPassword;
private String confirmPassword;
public NoEmailStrategy(VitroRequest vreq, UserAccountsEditPage page) {
super(vreq, page);
}
@Override
protected void parseAdditionalParameters() {
newPassword = getStringParameter(PARAMETER_NEW_PASSWORD, "");
confirmPassword = getStringParameter(PARAMETER_CONFIRM_PASSWORD, "");
}
@Override
protected String additionalValidations() {
if (newPassword.isEmpty() && confirmPassword.isEmpty()) {
return "";
} else if (!checkPasswordLength(newPassword)) {
return ERROR_WRONG_PASSWORD_LENGTH;
} else if (!newPassword.equals(confirmPassword)) {
return ERROR_PASSWORDS_DONT_MATCH;
} else {
return "";
}
}
@Override
protected void addMoreBodyValues(Map<String, Object> body) {
body.put("newPassword", newPassword);
body.put("confirmPassword", confirmPassword);
body.put("minimumLength", UserAccount.MIN_PASSWORD_LENGTH);
body.put("maximumLength", UserAccount.MAX_PASSWORD_LENGTH);
}
@Override
protected void setAdditionalProperties(UserAccount u) {
if (!newPassword.isEmpty()) {
u.setMd5Password(Authenticator.applyMd5Encoding(newPassword));
u.setPasswordChangeRequired(true);
}
}
@Override
protected void notifyUser() {
// Do nothing.
}
@Override
protected boolean wasPasswordEmailSent() {
return false;
}
}
}

View file

@ -1,6 +1,6 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */ /* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.accounts; package edu.cornell.mannlib.vitro.webapp.controller.accounts.admin;
import static edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsSelectionCriteria.DEFAULT_ACCOUNTS_PER_PAGE; import static edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsSelectionCriteria.DEFAULT_ACCOUNTS_PER_PAGE;
@ -18,10 +18,13 @@ import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsOrdering;
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage;
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsSelection;
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsSelectionCriteria;
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsSelector;
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsOrdering.Direction; import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsOrdering.Direction;
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsOrdering.Field; import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsOrdering.Field;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
@ -54,12 +57,13 @@ public class UserAccountsListPage extends UserAccountsPage {
public UserAccountsListPage(VitroRequest vreq) { public UserAccountsListPage(VitroRequest vreq) {
super(vreq); super(vreq);
parseParameters();
} }
/** /**
* Build the criteria from the request parameters. * Build the criteria from the request parameters.
*/ */
public void parseParameters() { private void parseParameters() {
int accountsPerPage = getIntegerParameter(PARAMETER_ACCOUNTS_PER_PAGE, int accountsPerPage = getIntegerParameter(PARAMETER_ACCOUNTS_PER_PAGE,
DEFAULT_ACCOUNTS_PER_PAGE); DEFAULT_ACCOUNTS_PER_PAGE);
int pageIndex = getIntegerParameter(PARAMETER_PAGE_INDEX, 1); int pageIndex = getIntegerParameter(PARAMETER_PAGE_INDEX, 1);
@ -76,6 +80,7 @@ public class UserAccountsListPage extends UserAccountsPage {
criteria = new UserAccountsSelectionCriteria(accountsPerPage, criteria = new UserAccountsSelectionCriteria(accountsPerPage,
pageIndex, ordering, roleFilterUri, searchTerm); pageIndex, ordering, roleFilterUri, searchTerm);
log.debug("selection criteria is: " + criteria);
} }
/** /**
@ -98,8 +103,11 @@ public class UserAccountsListPage extends UserAccountsPage {
userAccountsModel, criteria); userAccountsModel, criteria);
Map<String, Object> body = buildTemplateBodyMap(selection); Map<String, Object> body = buildTemplateBodyMap(selection);
body.put("newUserAccount", new UserAccountWrapper(vreq, userAccount, body.put("newUserAccount", new UserAccountWrapper(userAccount,
Collections.<String> emptyList())); Collections.<String> emptyList()));
if (emailWasSent) {
body.put("emailWasSent", Boolean.TRUE);
}
return new TemplateResponseValues(TEMPLATE_NAME, body); return new TemplateResponseValues(TEMPLATE_NAME, body);
} }
@ -109,8 +117,17 @@ public class UserAccountsListPage extends UserAccountsPage {
*/ */
public ResponseValues showPageWithUpdatedAccount(UserAccount userAccount, public ResponseValues showPageWithUpdatedAccount(UserAccount userAccount,
boolean emailWasSent) { boolean emailWasSent) {
throw new RuntimeException( UserAccountsSelection selection = UserAccountsSelector.select(
"UserAccountsListPage.showPageWithUpdatedAccount not implemented."); userAccountsModel, criteria);
Map<String, Object> body = buildTemplateBodyMap(selection);
body.put("updatedUserAccount", new UserAccountWrapper(userAccount,
Collections.<String> emptyList()));
if (emailWasSent) {
body.put("emailWasSent", Boolean.TRUE);
}
return new TemplateResponseValues(TEMPLATE_NAME, body);
} }
/** /**
@ -213,7 +230,7 @@ public class UserAccountsListPage extends UserAccountsPage {
UserAccountsSelection selection) { UserAccountsSelection selection) {
List<UserAccountWrapper> list = new ArrayList<UserAccountWrapper>(); List<UserAccountWrapper> list = new ArrayList<UserAccountWrapper>();
for (UserAccount account : selection.getUserAccounts()) { for (UserAccount account : selection.getUserAccounts()) {
list.add(new UserAccountWrapper(vreq, account, list.add(new UserAccountWrapper(account,
findPermissionSetLabels(account))); findPermissionSetLabels(account)));
} }
return list; return list;
@ -238,14 +255,11 @@ public class UserAccountsListPage extends UserAccountsPage {
private final List<String> permissionSets; private final List<String> permissionSets;
private final String editUrl; private final String editUrl;
public UserAccountWrapper(VitroRequest vreq, UserAccount account, public UserAccountWrapper(UserAccount account,
List<String> permissionSets) { List<String> permissionSets) {
this.account = account; this.account = account;
this.permissionSets = permissionSets; this.permissionSets = permissionSets;
this.editUrl = UserAccountsPage.editAccountUrl(account.getUri());
UrlBuilder urlBuilder = new UrlBuilder(vreq.getAppBean());
this.editUrl = urlBuilder.getPortalUrl("/userAccounts/edit",
new ParamMap("editAccount", account.getUri()));
} }
public String getUri() { public String getUri() {

View file

@ -0,0 +1,70 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.accounts.user;
import static javax.mail.Message.RecipientType.TO;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailMessage;
/**
* When the user clicks on the link in their notification email, handle their
* request to create a password.
*/
public class UserAccountsCreatePasswordPage extends
UserAccountsPasswordBasePage {
private static final Log log = LogFactory
.getLog(UserAccountsCreatePasswordPage.class);
private static final String TEMPLATE_NAME = "userAccounts-createPassword.ftl";
public UserAccountsCreatePasswordPage(VitroRequest vreq) {
super(vreq);
}
public void createPassword() {
userAccount.setMd5Password(Authenticator.applyMd5Encoding(newPassword));
userAccount.setPasswordLinkExpires(0L);
userAccount.setPasswordChangeRequired(false);
userAccount.setStatus(Status.ACTIVE);
userAccountsDao.updateUserAccount(userAccount);
log.debug("Set password on '" + userAccount.getEmailAddress()
+ "' to '" + newPassword + "'");
notifyUser();
}
@Override
protected String passwordChangeNotPendingMessage() {
return "The account for " + userEmail + " has already been activated.";
}
@Override
protected String templateName() {
return TEMPLATE_NAME;
}
private void notifyUser() {
Map<String, Object> body = new HashMap<String, Object>();
body.put("userAccount", userAccount);
body.put("subjectLine", "Password successfully created.");
FreemarkerEmailMessage email = FreemarkerEmailFactory
.createNewMessage(vreq);
email.addRecipient(TO, userAccount.getEmailAddress());
email.setSubject("Password successfully created.");
email.setHtmlTemplate("userAccounts-passwordCreatedEmail-html.ftl");
email.setTextTemplate("userAccounts-passwordCreatedEmail-text.ftl");
email.setBodyMap(body);
email.send();
}
}

View file

@ -0,0 +1,162 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.accounts.user;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage;
import edu.cornell.mannlib.vitro.webapp.controller.accounts.admin.UserAccountsEditPage;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
/**
* Handle the "My Account" form display and submission.
*/
public class UserAccountsMyAccountPage extends UserAccountsPage {
private static final Log log = LogFactory
.getLog(UserAccountsEditPage.class);
private static final String PARAMETER_SUBMIT = "submitMyAccount";
private static final String PARAMETER_EMAIL_ADDRESS = "emailAddress";
private static final String PARAMETER_FIRST_NAME = "firstName";
private static final String PARAMETER_LAST_NAME = "lastName";
private static final String ERROR_NO_EMAIL = "errorEmailIsEmpty";
private static final String ERROR_EMAIL_IN_USE = "errorEmailInUse";
private static final String ERROR_EMAIL_INVALID_FORMAT = "errorEmailInvalidFormat";
private static final String ERROR_NO_FIRST_NAME = "errorFirstNameIsEmpty";
private static final String ERROR_NO_LAST_NAME = "errorLastNameIsEmpty";
private static final String TEMPLATE_NAME = "userAccounts-myAccount.ftl";
private final UserAccountsMyAccountPageStrategy strategy;
private final UserAccount userAccount;
/* The request parameters */
private boolean submit;
private String emailAddress = "";
private String firstName = "";
private String lastName = "";
/** The result of validating a "submit" request. */
private String errorCode = "";
/** The result of updating the account. */
private String confirmationCode = "";
public UserAccountsMyAccountPage(VitroRequest vreq) {
super(vreq);
this.userAccount = LoginStatusBean.getCurrentUser(vreq);
this.strategy = UserAccountsMyAccountPageStrategy.getInstance(vreq,
this, isExternalAccount());
parseRequestParameters();
if (isSubmit()) {
validateParameters();
}
}
public UserAccount getUserAccount() {
return userAccount;
}
private void parseRequestParameters() {
submit = isFlagOnRequest(PARAMETER_SUBMIT);
emailAddress = getStringParameter(PARAMETER_EMAIL_ADDRESS, "");
firstName = getStringParameter(PARAMETER_FIRST_NAME, "");
lastName = getStringParameter(PARAMETER_LAST_NAME, "");
strategy.parseAdditionalParameters();
}
public boolean isSubmit() {
return submit;
}
private void validateParameters() {
if (emailAddress.isEmpty()) {
errorCode = ERROR_NO_EMAIL;
} else if (emailIsChanged() && isEmailInUse()) {
errorCode = ERROR_EMAIL_IN_USE;
} else if (!isEmailValidFormat()) {
errorCode = ERROR_EMAIL_INVALID_FORMAT;
} else if (firstName.isEmpty()) {
errorCode = ERROR_NO_FIRST_NAME;
} else if (lastName.isEmpty()) {
errorCode = ERROR_NO_LAST_NAME;
} else {
errorCode = strategy.additionalValidations();
}
}
private boolean emailIsChanged() {
return !emailAddress.equals(userAccount.getEmailAddress());
}
private boolean isEmailInUse() {
return userAccountsDao.getUserAccountByEmail(emailAddress) != null;
}
private boolean isEmailValidFormat() {
return Authenticator.isValidEmailAddress(emailAddress);
}
public boolean isValid() {
return errorCode.isEmpty();
}
private boolean isExternalAccount() {
return LoginStatusBean.getBean(vreq).hasExternalAuthentication();
}
public final ResponseValues showPage() {
Map<String, Object> body = new HashMap<String, Object>();
if (isSubmit()) {
body.put("emailAddress", emailAddress);
body.put("firstName", firstName);
body.put("lastName", lastName);
} else {
body.put("emailAddress", userAccount.getEmailAddress());
body.put("firstName", userAccount.getFirstName());
body.put("lastName", userAccount.getLastName());
}
body.put("formUrls", buildUrlsMap());
if (!errorCode.isEmpty()) {
body.put(errorCode, Boolean.TRUE);
}
if (!confirmationCode.isEmpty()) {
body.put(confirmationCode, Boolean.TRUE);
}
strategy.addMoreBodyValues(body);
return new TemplateResponseValues(TEMPLATE_NAME, body);
}
public void updateAccount() {
userAccount.setEmailAddress(emailAddress);
userAccount.setFirstName(firstName);
userAccount.setLastName(lastName);
strategy.setAdditionalProperties(userAccount);
userAccountsDao.updateUserAccount(userAccount);
strategy.notifyUser();
confirmationCode = strategy.getConfirmationCode();
}
}

View file

@ -0,0 +1,196 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.accounts.user;
import static javax.mail.Message.RecipientType.TO;
import java.util.HashMap;
import java.util.Map;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailMessage;
/**
* Handle the variant details of the MyAccounts page
*/
public abstract class UserAccountsMyAccountPageStrategy extends
UserAccountsPage {
private static final String CONFIRM_CHANGE = "confirmChange";
private static final String CONFIRM_EMAIL_SENT = "confirmEmailSent";
protected final UserAccountsMyAccountPage page;
public static UserAccountsMyAccountPageStrategy getInstance(
VitroRequest vreq, UserAccountsMyAccountPage page,
boolean externalAuth) {
if (externalAuth) {
return new ExternalAuthStrategy(vreq, page);
} else {
return new InternalAuthStrategy(vreq, page);
}
}
protected UserAccountsMyAccountPageStrategy(VitroRequest vreq,
UserAccountsMyAccountPage page) {
super(vreq);
this.page = page;
}
public abstract void parseAdditionalParameters();
public abstract String additionalValidations();
public abstract void addMoreBodyValues(Map<String, Object> body);
public abstract void setAdditionalProperties(UserAccount userAccount);
public abstract void notifyUser();
public abstract String getConfirmationCode();
// ----------------------------------------------------------------------
// Strategy to use if the account used External Authentication
// ----------------------------------------------------------------------
private static class ExternalAuthStrategy extends
UserAccountsMyAccountPageStrategy {
ExternalAuthStrategy(VitroRequest vreq, UserAccountsMyAccountPage page) {
super(vreq, page);
}
@Override
public void parseAdditionalParameters() {
// No additional parameters
}
@Override
public String additionalValidations() {
// No additional validations
return "";
}
@Override
public void addMoreBodyValues(Map<String, Object> body) {
body.put("externalAuth", Boolean.TRUE);
}
@Override
public void setAdditionalProperties(UserAccount userAccount) {
// No additional properties.
}
@Override
public void notifyUser() {
// No notification beyond the screen message.
}
@Override
public String getConfirmationCode() {
return CONFIRM_CHANGE;
}
}
// ----------------------------------------------------------------------
// Strategy to use if the account used Internal Authentication
// ----------------------------------------------------------------------
private static class InternalAuthStrategy extends
UserAccountsMyAccountPageStrategy {
private static final String PARAMETER_NEW_PASSWORD = "newPassword";
private static final String PARAMETER_CONFIRM_PASSWORD = "confirmPassword";
private static final String ERROR_WRONG_PASSWORD_LENGTH = "errorPasswordIsWrongLength";
private static final String ERROR_PASSWORDS_DONT_MATCH = "errorPasswordsDontMatch";
private final String originalEmail;
private String newPassword;
private String confirmPassword;
private boolean emailSent;
InternalAuthStrategy(VitroRequest vreq, UserAccountsMyAccountPage page) {
super(vreq, page);
originalEmail = page.getUserAccount().getEmailAddress();
}
@Override
public void parseAdditionalParameters() {
newPassword = getStringParameter(PARAMETER_NEW_PASSWORD, "");
confirmPassword = getStringParameter(PARAMETER_CONFIRM_PASSWORD, "");
}
@Override
public String additionalValidations() {
if (newPassword.isEmpty() && confirmPassword.isEmpty()) {
return "";
} else if (!newPassword.equals(confirmPassword)) {
return ERROR_PASSWORDS_DONT_MATCH;
} else if (!checkPasswordLength(newPassword)) {
return ERROR_WRONG_PASSWORD_LENGTH;
} else {
return "";
}
}
@Override
public void addMoreBodyValues(Map<String, Object> body) {
body.put("newPassword", newPassword);
body.put("confirmPassword", confirmPassword);
body.put("minimumLength", UserAccount.MIN_PASSWORD_LENGTH);
body.put("maximumLength", UserAccount.MAX_PASSWORD_LENGTH);
}
@Override
public void setAdditionalProperties(UserAccount userAccount) {
if (!newPassword.isEmpty()) {
userAccount.setMd5Password(Authenticator
.applyMd5Encoding(newPassword));
userAccount.setPasswordChangeRequired(false);
userAccount.setPasswordLinkExpires(0L);
}
}
@Override
public void notifyUser() {
if (!isEmailEnabled()) {
return;
}
if (!emailHasChanged()) {
return;
}
Map<String, Object> body = new HashMap<String, Object>();
body.put("userAccount", page.getUserAccount());
body.put("subjectLine", "Your VIVO email account has been changed.");
FreemarkerEmailMessage email = FreemarkerEmailFactory
.createNewMessage(vreq);
email.addRecipient(TO, page.getUserAccount().getEmailAddress());
email.setSubject("Your VIVO email account has been changed.");
email.setHtmlTemplate("userAccounts-confirmEmailChangedEmail-html.ftl");
email.setTextTemplate("userAccounts-confirmEmailChangedEmail-text.ftl");
email.setBodyMap(body);
email.send();
emailSent = true;
}
private boolean emailHasChanged() {
return !page.getUserAccount().getEmailAddress()
.equals(originalEmail);
}
@Override
public String getConfirmationCode() {
return emailSent ? CONFIRM_EMAIL_SENT : CONFIRM_CHANGE;
}
}
}

View file

@ -0,0 +1,150 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.accounts.user;
import static edu.cornell.mannlib.vitro.webapp.controller.accounts.user.UserAccountsUserController.BOGUS_STANDARD_MESSAGE;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
/**
* Routines in common to the "Create Password" and "Reset Password" pages.
*/
public abstract class UserAccountsPasswordBasePage extends UserAccountsPage {
private static final Log log = LogFactory
.getLog(UserAccountsPasswordBasePage.class);
private static final String PARAMETER_SUBMIT = "submit";
private static final String PARAMETER_USER = "user";
private static final String PARAMETER_KEY = "key";
private static final String PARAMETER_NEW_PASSWORD = "newPassword";
private static final String PARAMETER_CONFIRM_PASSWORD = "confirmPassword";
private static final String ERROR_NO_PASSWORD = "errorPasswordIsEmpty";
private static final String ERROR_WRONG_PASSWORD_LENGTH = "errorPasswordIsWrongLength";
private static final String ERROR_PASSWORDS_DONT_MATCH = "errorPasswordsDontMatch";
protected boolean submit;
protected String userEmail = "";
protected String key = "";
protected String newPassword = "";
protected String confirmPassword = "";
protected UserAccount userAccount;
/** The result of checking whether this request is even appropriate. */
private String bogusMessage = "";
/** The result of validating a "submit" request. */
private String errorCode = "";
protected UserAccountsPasswordBasePage(VitroRequest vreq) {
super(vreq);
parseRequestParameters();
validateUserAccountInfo();
if (isSubmit() && !isBogus()) {
validateParameters();
}
}
private void parseRequestParameters() {
submit = isFlagOnRequest(PARAMETER_SUBMIT);
userEmail = getStringParameter(PARAMETER_USER, "");
key = getStringParameter(PARAMETER_KEY, "");
newPassword = getStringParameter(PARAMETER_NEW_PASSWORD, "");
confirmPassword = getStringParameter(PARAMETER_CONFIRM_PASSWORD, "");
}
public boolean isSubmit() {
return submit;
}
private void validateUserAccountInfo() {
userAccount = userAccountsDao.getUserAccountByEmail(userEmail);
if (userAccount == null) {
log.warn("Password request for '" + userEmail
+ "' is bogus: no such user");
bogusMessage = BOGUS_STANDARD_MESSAGE;
return;
}
if (userAccount.getPasswordLinkExpires() == 0L) {
log.warn("Password request for '" + userEmail
+ "' is bogus: password change is not pending.");
bogusMessage = passwordChangeNotPendingMessage();
return;
}
Date expirationDate = new Date(userAccount.getPasswordLinkExpires());
if (expirationDate.before(new Date())) {
log.warn("Password request for '" + userEmail
+ "' is bogus: expiration date has passed.");
bogusMessage = BOGUS_STANDARD_MESSAGE;
return;
}
String expectedKey = userAccount.getPasswordLinkExpiresHash();
if (!key.equals(expectedKey)) {
log.warn("Password request for '" + userEmail + "' is bogus: key ("
+ key + ") doesn't match expected key (" + expectedKey
+ ")");
bogusMessage = BOGUS_STANDARD_MESSAGE;
return;
}
}
public boolean isBogus() {
return !bogusMessage.isEmpty();
}
public String getBogusMessage() {
return bogusMessage;
}
private void validateParameters() {
if (newPassword.isEmpty()) {
errorCode = ERROR_NO_PASSWORD;
} else if (!checkPasswordLength(newPassword)) {
errorCode = ERROR_WRONG_PASSWORD_LENGTH;
} else if (!newPassword.equals(confirmPassword)) {
errorCode = ERROR_PASSWORDS_DONT_MATCH;
}
}
public boolean isValid() {
return errorCode.isEmpty();
}
public final ResponseValues showPage() {
Map<String, Object> body = new HashMap<String, Object>();
body.put("minimumLength", UserAccount.MIN_PASSWORD_LENGTH);
body.put("maximumLength", UserAccount.MAX_PASSWORD_LENGTH);
body.put("userAccount", userAccount);
body.put("key", userAccount.getPasswordLinkExpiresHash());
body.put("newPassword", newPassword);
body.put("confirmPassword", confirmPassword);
body.put("formUrls", buildUrlsMap());
if (!errorCode.isEmpty()) {
body.put(errorCode, Boolean.TRUE);
}
return new TemplateResponseValues(templateName(), body);
}
protected abstract String passwordChangeNotPendingMessage();
protected abstract String templateName();
}

View file

@ -0,0 +1,70 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.accounts.user;
import static javax.mail.Message.RecipientType.TO;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailMessage;
/**
* When the user clicks on the link in their notification email, handle their
* request to reset their password.
*/
public class UserAccountsResetPasswordPage extends UserAccountsPasswordBasePage {
private static final Log log = LogFactory
.getLog(UserAccountsResetPasswordPage.class);
private static final String TEMPLATE_NAME = "userAccounts-resetPassword.ftl";
protected UserAccountsResetPasswordPage(VitroRequest vreq) {
super(vreq);
}
public void resetPassword() {
userAccount.setMd5Password(Authenticator.applyMd5Encoding(newPassword));
userAccount.setPasswordLinkExpires(0L);
userAccount.setPasswordChangeRequired(false);
userAccount.setStatus(Status.ACTIVE);
userAccountsDao.updateUserAccount(userAccount);
log.debug("Set password on '" + userAccount.getEmailAddress()
+ "' to '" + newPassword + "'");
notifyUser();
}
@Override
protected String passwordChangeNotPendingMessage() {
return "The password for " + userEmail + " has already been reset.";
}
@Override
protected String templateName() {
return TEMPLATE_NAME;
}
private void notifyUser() {
Map<String, Object> body = new HashMap<String, Object>();
body.put("userAccount", userAccount);
body.put("subjectLine", "Password changed.");
FreemarkerEmailMessage email = FreemarkerEmailFactory
.createNewMessage(vreq);
email.addRecipient(TO, userAccount.getEmailAddress());
email.setSubject("Password changed.");
email.setHtmlTemplate("userAccounts-passwordResetEmail-html.ftl");
email.setTextTemplate("userAccounts-passwordResetEmail-text.ftl");
email.setBodyMap(body);
email.send();
}
}

View file

@ -0,0 +1,107 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.accounts.user;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOwnAccount;
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.RedirectResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
/**
* Parcel out the different actions required of the UserAccounts GUI.
*/
public class UserAccountsUserController extends FreemarkerHttpServlet {
private static final Log log = LogFactory
.getLog(UserAccountsUserController.class);
public static final String BOGUS_STANDARD_MESSAGE = "Request failed. Please contact your system administrator.";
private static final String ACTION_CREATE_PASSWORD = "/createPassword";
private static final String ACTION_RESET_PASSWORD = "/resetPassword";
private static final String ACTION_MY_ACCOUNT = "/myAccount";
@Override
protected Actions requiredActions(VitroRequest vreq) {
String action = vreq.getPathInfo();
if (ACTION_MY_ACCOUNT.equals(action)) {
return new Actions(new EditOwnAccount());
} else {
return Actions.AUTHORIZED;
}
}
@Override
protected ResponseValues processRequest(VitroRequest vreq) {
if (log.isDebugEnabled()) {
dumpRequestParameters(vreq);
}
String action = vreq.getPathInfo();
log.debug("action = '" + action + "'");
if (ACTION_MY_ACCOUNT.equals(action)) {
return handleMyAccountRequest(vreq);
} else if (ACTION_CREATE_PASSWORD.equals(action)) {
return handleCreatePasswordRequest(vreq);
} else if (ACTION_RESET_PASSWORD.equals(action)) {
return handleResetPasswordRequest(vreq);
} else {
return handleInvalidRequest(vreq);
}
}
private ResponseValues handleMyAccountRequest(VitroRequest vreq) {
UserAccountsMyAccountPage page = new UserAccountsMyAccountPage(vreq);
if (page.isSubmit() && page.isValid()) {
page.updateAccount();
}
return page.showPage();
}
private ResponseValues handleCreatePasswordRequest(VitroRequest vreq) {
UserAccountsCreatePasswordPage page = new UserAccountsCreatePasswordPage(
vreq);
if (page.isBogus()) {
return showHomePage(vreq, page.getBogusMessage());
} else if (page.isSubmit() && page.isValid()) {
page.createPassword();
return showHomePage(vreq,
"Your password has been saved. Please log in.");
} else {
return page.showPage();
}
}
private ResponseValues handleResetPasswordRequest(VitroRequest vreq) {
UserAccountsResetPasswordPage page = new UserAccountsResetPasswordPage(
vreq);
if (page.isBogus()) {
return showHomePage(vreq, page.getBogusMessage());
} else if (page.isSubmit() && page.isValid()) {
page.resetPassword();
return showHomePage(vreq,
"Your password has been saved. Please log in.");
} else {
return page.showPage();
}
}
private ResponseValues handleInvalidRequest(VitroRequest vreq) {
return showHomePage(vreq, BOGUS_STANDARD_MESSAGE);
}
private ResponseValues showHomePage(VitroRequest vreq, String message) {
DisplayMessage.setMessage(vreq, message);
return new RedirectResponseValues("/");
}
}

View file

@ -0,0 +1,104 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.admin;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.ActiveIdentifierBundleFactories;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasAssociatedIndividual;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjPropStmt;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
/**
* Show a summary of who is logged in and how they are to be treated by the
* authorization system.
*/
public class ShowAuthController extends FreemarkerHttpServlet {
@Override
protected Actions requiredActions(VitroRequest vreq) {
return Actions.AUTHORIZED;
}
@Override
protected ResponseValues processRequest(VitroRequest vreq) {
Map<String, Object> body = new HashMap<String, Object>();
body.put("identifiers", RequestIdentifiers.getIdBundleForRequest(vreq));
body.put("currentUser", LoginStatusBean.getCurrentUser(vreq));
body.put("associatedIndividuals", getAssociatedIndividuals(vreq));
body.put("factories", getIdentifierFactoryNames(vreq));
body.put("policies", ServletPolicyList.getPolicies(vreq));
body.put("matchingProperty", getMatchingProperty(vreq));
return new TemplateResponseValues("admin-showAuth.ftl", body);
}
private List<String> getIdentifierFactoryNames(VitroRequest vreq) {
ServletContext ctx = vreq.getSession().getServletContext();
return ActiveIdentifierBundleFactories.getFactoryNames(ctx);
}
private String getMatchingProperty(VitroRequest vreq) {
return ConfigurationProperties.getBean(vreq).getProperty(
"selfEditing.idMatchingProperty", "");
}
private List<AssociatedIndividual> getAssociatedIndividuals(
VitroRequest vreq) {
List<AssociatedIndividual> list = new ArrayList<AssociatedIndividual>();
IdentifierBundle ids = RequestIdentifiers.getIdBundleForRequest(vreq);
for (String uri : HasAssociatedIndividual.getIndividualUris(ids)) {
list.add(new AssociatedIndividual(uri, mayEditIndividual(vreq, uri)));
}
return list;
}
/**
* Is the current user authorized to edit an arbitrary object property on
* this individual?
*/
private boolean mayEditIndividual(VitroRequest vreq, String individualUri) {
RequestedAction action = new EditObjPropStmt(individualUri,
RequestActionConstants.SOME_URI,
RequestActionConstants.SOME_URI);
return PolicyHelper.isAuthorizedForActions(vreq, action);
}
public class AssociatedIndividual {
private final String uri;
private final boolean editable;
public AssociatedIndividual(String uri, boolean editable) {
this.uri = uri;
this.editable = editable;
}
public String getUri() {
return uri;
}
public boolean isEditable() {
return editable;
}
}
}

View file

@ -3,6 +3,8 @@
package edu.cornell.mannlib.vitro.webapp.controller.authenticate; package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
import static edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource.INTERNAL; import static edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource.INTERNAL;
import static edu.cornell.mannlib.vitro.webapp.beans.UserAccount.MAX_PASSWORD_LENGTH;
import static edu.cornell.mannlib.vitro.webapp.beans.UserAccount.MIN_PASSWORD_LENGTH;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -11,7 +13,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.beans.User; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
@ -30,7 +32,7 @@ public class AdminLoginController extends FreemarkerHttpServlet {
private static final Log log = LogFactory private static final Log log = LogFactory
.getLog(AdminLoginController.class); .getLog(AdminLoginController.class);
public static final String PARAMETER_USERNAME = "username"; public static final String PARAMETER_EMAIL_ADDRESS = "email";
public static final String PARAMETER_PASSWORD = "password"; public static final String PARAMETER_PASSWORD = "password";
public static final String PARAMETER_NEW_PASSWORD = "newPassword"; public static final String PARAMETER_NEW_PASSWORD = "newPassword";
public static final String PARAMETER_CONFIRM_PASSWORD = "confirmPassword"; public static final String PARAMETER_CONFIRM_PASSWORD = "confirmPassword";
@ -40,7 +42,7 @@ public class AdminLoginController extends FreemarkerHttpServlet {
public static final String TEMPLATE_NAME = "adminLogin.ftl"; public static final String TEMPLATE_NAME = "adminLogin.ftl";
private static final String MESSAGE_NO_USERNAME = "errorNoUser"; private static final String MESSAGE_NO_EMAIL_ADDRESS = "errorNoEmail";
private static final String MESSAGE_NO_PASSWORD = "errorNoPassword"; private static final String MESSAGE_NO_PASSWORD = "errorNoPassword";
private static final String MESSAGE_LOGIN_FAILED = "errorLoginFailed"; private static final String MESSAGE_LOGIN_FAILED = "errorLoginFailed";
private static final String MESSAGE_NEW_PASSWORD_REQUIRED = "newPasswordRequired"; private static final String MESSAGE_NEW_PASSWORD_REQUIRED = "newPasswordRequired";
@ -64,32 +66,37 @@ public class AdminLoginController extends FreemarkerHttpServlet {
private static class Core { private static class Core {
private final Authenticator auth; private final Authenticator auth;
private final String username; private final String emailAddress;
private final String password; private final String password;
private final String newPassword; private final String newPassword;
private final String confirmPassword; private final String confirmPassword;
private final UserAccount userAccount;
public Core(VitroRequest vreq) { public Core(VitroRequest vreq) {
this.auth = Authenticator.getInstance(vreq); this.auth = Authenticator.getInstance(vreq);
this.username = nonNull(vreq.getParameter(PARAMETER_USERNAME)); this.emailAddress = nonNull(vreq
.getParameter(PARAMETER_EMAIL_ADDRESS));
this.password = nonNull(vreq.getParameter(PARAMETER_PASSWORD)); this.password = nonNull(vreq.getParameter(PARAMETER_PASSWORD));
this.newPassword = nonNull(vreq this.newPassword = nonNull(vreq
.getParameter(PARAMETER_NEW_PASSWORD)); .getParameter(PARAMETER_NEW_PASSWORD));
this.confirmPassword = nonNull(vreq this.confirmPassword = nonNull(vreq
.getParameter(PARAMETER_CONFIRM_PASSWORD)); .getParameter(PARAMETER_CONFIRM_PASSWORD));
log.debug("Parameters: username='" + username + "', password='" log.debug("Parameters: email='" + emailAddress + "', password='"
+ password + "', newPassword='" + newPassword + password + "', newPassword='" + newPassword
+ "', confirmPassword='" + confirmPassword + "'"); + "', confirmPassword='" + confirmPassword + "'");
this.userAccount = this.auth
.getAccountForInternalAuth(emailAddress);
} }
public ResponseValues process() { public ResponseValues process() {
if (username.isEmpty() && password.isEmpty()) { if (emailAddress.isEmpty() && password.isEmpty()) {
return showForm(); return showForm();
} }
if (username.isEmpty()) { if (emailAddress.isEmpty()) {
return showForm(MESSAGE_NO_USERNAME); return showForm(MESSAGE_NO_EMAIL_ADDRESS);
} }
if (password.isEmpty()) { if (password.isEmpty()) {
return showForm(MESSAGE_NO_PASSWORD); return showForm(MESSAGE_NO_PASSWORD);
@ -121,21 +128,21 @@ public class AdminLoginController extends FreemarkerHttpServlet {
} }
private boolean newPasswordRequired() { private boolean newPasswordRequired() {
return auth.isCurrentPassword(username, password) return auth.isCurrentPassword(userAccount, password)
&& auth.isPasswordChangeRequired(username); && (userAccount.isPasswordChangeRequired());
} }
private boolean isPasswordValidLength(String pw) { private boolean isPasswordValidLength(String pw) {
return (pw.length() >= User.MIN_PASSWORD_LENGTH) return (pw.length() >= MIN_PASSWORD_LENGTH)
&& (pw.length() <= User.MAX_PASSWORD_LENGTH); && (pw.length() <= MAX_PASSWORD_LENGTH);
} }
private boolean tryToLogin() { private boolean tryToLogin() {
if (auth.isCurrentPassword(username, password)) { if (auth.isCurrentPassword(userAccount, password)) {
auth.recordLoginAgainstUserAccount(username, INTERNAL); auth.recordLoginAgainstUserAccount(userAccount, INTERNAL);
if (!newPassword.isEmpty()) { if (!newPassword.isEmpty()) {
auth.recordNewPassword(username, newPassword); auth.recordNewPassword(userAccount, newPassword);
} }
return true; return true;
@ -147,7 +154,7 @@ public class AdminLoginController extends FreemarkerHttpServlet {
private ResponseValues showForm(String... codes) { private ResponseValues showForm(String... codes) {
Map<String, Object> body = new HashMap<String, Object>(); Map<String, Object> body = new HashMap<String, Object>();
body.put("controllerUrl", UrlBuilder.getUrl(URL_THIS)); body.put("controllerUrl", UrlBuilder.getUrl(URL_THIS));
body.put("username", username); body.put("email", emailAddress);
body.put("password", password); body.put("password", password);
body.put("newPassword", newPassword); body.put("newPassword", newPassword);
body.put("confirmPassword", confirmPassword); body.put("confirmPassword", confirmPassword);

View file

@ -6,12 +6,14 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.List; import java.util.List;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.binary.Hex;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource; import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource;
import edu.cornell.mannlib.vitro.webapp.beans.User; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
/** /**
* The tool that a login process will use to interface with the user records in * The tool that a login process will use to interface with the user records in
@ -55,37 +57,40 @@ public abstract class Authenticator {
public static final int PRIVILEGED_TIMEOUT_INTERVAL = 32000; public static final int PRIVILEGED_TIMEOUT_INTERVAL = 32000;
/** /**
* Does a user by this name exist? * Get the UserAccount for this external ID, or null if there is none.
*/ */
public abstract boolean isExistingUser(String username); public abstract UserAccount getAccountForExternalAuth(String externalAuthId);
/** /**
* Does a user by this name have this password? * Get the UserAccount for this email address, or null if there is none.
*/ */
public abstract boolean isCurrentPassword(String username, public abstract UserAccount getAccountForInternalAuth(String emailAddress);
/**
* Internal: does this UserAccount have this password? False if the
* userAccount is null.
*/
public abstract boolean isCurrentPassword(UserAccount userAccount,
String clearTextPassword); String clearTextPassword);
/** /**
* Get the user with this name, or null if no such user exists. * Internal: record a new password for the user. Takes no action if the
* userAccount is null.
*/ */
public abstract User getUserByUsername(String username); public abstract void recordNewPassword(UserAccount userAccount,
String newClearTextPassword);
/**
* Is a change in name or email required when the user logs in?
*/
public abstract boolean accountRequiresEditing(UserAccount userAccount);
/** /**
* Get the URIs of all individuals associated with this user, whether by a * Get the URIs of all individuals associated with this user, whether by a
* self-editing property like cornellEmailNetid, or by mayEditAs. * self-editing property like cornellEmailNetid, or by mayEditAs.
*/ */
public abstract List<String> getAssociatedIndividualUris(String username); public abstract List<String> getAssociatedIndividualUris(
UserAccount userAccount);
/**
* Is a password change needed when the user logs in?
*/
public abstract boolean isPasswordChangeRequired(String username);
/**
* Record a new password for the user.
*/
public abstract void recordNewPassword(String username,
String newClearTextPassword);
/** /**
* <pre> * <pre>
@ -97,7 +102,7 @@ public abstract class Authenticator {
* - notify other users of the model * - notify other users of the model
* </pre> * </pre>
*/ */
public abstract void recordLoginAgainstUserAccount(String username, public abstract void recordLoginAgainstUserAccount(UserAccount userAccount,
AuthenticationSource authSource); AuthenticationSource authSource);
/** /**
@ -106,9 +111,10 @@ public abstract class Authenticator {
* info, so no internal user account. * info, so no internal user account.
* - this involves everything except updating the user record. * - this involves everything except updating the user record.
* </pre> * </pre>
*
* TODO JB This goes away.
*/ */
public abstract void recordLoginWithoutUserAccount(String username, public abstract void recordLoginWithoutUserAccount(String individualUri);
String individualUri, AuthenticationSource authSource);
/** /**
* <pre> * <pre>
@ -140,4 +146,30 @@ public abstract class Authenticator {
} }
} }
/**
* Check whether the form of the emailAddress is syntactically correct. Does
* not allow multiple addresses. Does not allow local addresses (without a
* hostname).
*
* Does not confirm that the host actually exists, or has a mailbox by that
* name.
*/
public static boolean isValidEmailAddress(String emailAddress) {
try {
// InternetAddress constructor will throw an exception if the
// address does not have valid format (if "strict" is true).
@SuppressWarnings("unused")
InternetAddress a = new InternetAddress(emailAddress, true);
// InternetAddress permits a localname without hostname.
// Guard against that.
if (emailAddress.indexOf('@') == -1) {
return false;
}
return true;
} catch (AddressException e) {
return false;
}
}
} }

View file

@ -4,7 +4,6 @@ package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -15,15 +14,15 @@ import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.LoginFormBean;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean; import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource; import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource;
import edu.cornell.mannlib.vitro.webapp.auth.policy.RoleBasedPolicy.AuthRole; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration; import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration;
import edu.cornell.mannlib.vitro.webapp.beans.User; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.controller.edit.Authenticate; import edu.cornell.mannlib.vitro.webapp.controller.edit.Authenticate;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.dao.UserDao; import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.LoginEvent; import edu.cornell.mannlib.vitro.webapp.dao.jena.LoginEvent;
import edu.cornell.mannlib.vitro.webapp.dao.jena.LogoutEvent; import edu.cornell.mannlib.vitro.webapp.dao.jena.LogoutEvent;
@ -32,9 +31,6 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.LogoutEvent;
* The "standard" implementation of Authenticator. * The "standard" implementation of Authenticator.
*/ */
public class BasicAuthenticator extends Authenticator { public class BasicAuthenticator extends Authenticator {
/** User roles are recorded in the model like "role:/50", etc. */
private static final String ROLE_NAMESPACE = "role:/";
private static final Log log = LogFactory.getLog(BasicAuthenticator.class); private static final Log log = LogFactory.getLog(BasicAuthenticator.class);
private final HttpServletRequest request; private final HttpServletRequest request;
@ -44,91 +40,104 @@ public class BasicAuthenticator extends Authenticator {
} }
@Override @Override
public boolean isExistingUser(String username) { public UserAccount getAccountForInternalAuth(String emailAddress) {
return getUserByUsername(username) != null; UserAccountsDao userAccountsDao = getUserAccountsDao();
} if (userAccountsDao == null) {
@Override
public User getUserByUsername(String username) {
UserDao userDao = getUserDao();
if (userDao == null) {
return null; return null;
} }
return userDao.getUserByUsername(username); return userAccountsDao.getUserAccountByEmail(emailAddress);
} }
@Override @Override
public boolean isCurrentPassword(String username, String clearTextPassword) { public UserAccount getAccountForExternalAuth(String externalAuthId) {
User user = getUserDao().getUserByUsername(username); UserAccountsDao userAccountsDao = getUserAccountsDao();
if (user == null) { if (userAccountsDao == null) {
log.trace("Checking password '" + clearTextPassword return null;
+ "' for user '" + username + "', but user doesn't exist."); }
return userAccountsDao.getUserAccountByExternalAuthId(externalAuthId);
}
@Override
public boolean isCurrentPassword(UserAccount userAccount,
String clearTextPassword) {
if (userAccount == null) {
return false; return false;
} }
if (clearTextPassword == null) {
String md5NewPassword = applyMd5Encoding(clearTextPassword); return false;
return md5NewPassword.equals(user.getMd5password()); }
String encodedPassword = applyMd5Encoding(clearTextPassword);
return encodedPassword.equals(userAccount.getMd5Password());
} }
@Override @Override
public boolean isPasswordChangeRequired(String username) { public void recordNewPassword(UserAccount userAccount,
User user = getUserDao().getUserByUsername(username); String newClearTextPassword) {
if ((user != null) && (user.getLoginCount() == 0)) { if (userAccount == null) {
log.error("Trying to change password on null user.");
return;
}
userAccount.setMd5Password(applyMd5Encoding(newClearTextPassword));
userAccount.setPasswordChangeRequired(false);
userAccount.setPasswordLinkExpires(0L);
getUserAccountsDao().updateUserAccount(userAccount);
}
@Override
public boolean accountRequiresEditing(UserAccount userAccount) {
if (userAccount == null) {
log.error("Trying to check for valid fields on a null user.");
return false;
}
if (userAccount.getFirstName().isEmpty()) {
return true; return true;
} else {
return false;
} }
if (userAccount.getLastName().isEmpty()) {
return true;
}
if (userAccount.getEmailAddress().isEmpty()) {
return true;
}
if (!isValidEmailAddress(userAccount.getEmailAddress())) {
return true;
}
return false;
} }
@Override @Override
public void recordNewPassword(String username, String newClearTextPassword) { public List<String> getAssociatedIndividualUris(UserAccount userAccount) {
User user = getUserByUsername(username); List<String> uris = new ArrayList<String>();
if (user == null) { if (userAccount == null) {
log.error("Trying to change password on non-existent user: " return uris;
+ username);
return;
} }
user.setOldPassword(user.getMd5password()); uris.addAll(getUrisAssociatedBySelfEditorConfig(userAccount));
user.setMd5password(applyMd5Encoding(newClearTextPassword)); return uris;
getUserDao().updateUser(user);
} }
@Override @Override
public void recordLoginAgainstUserAccount(String username, public void recordLoginAgainstUserAccount(UserAccount userAccount,
AuthenticationSource authSource) { AuthenticationSource authSource) {
User user = getUserByUsername(username); if (userAccount == null) {
if (user == null) { log.error("Trying to record the login of a null user. ");
log.error("Trying to record the login of a non-existent user: "
+ username);
return; return;
} }
recordLoginOnUserRecord(user); recordLoginOnUserRecord(userAccount);
recordLoginWithOrWithoutUserAccount(userAccount.getUri(), authSource);
String userUri = user.getURI();
String roleUri = user.getRoleURI();
int securityLevel = parseUserSecurityLevel(user);
recordLoginWithOrWithoutUserAccount(username, userUri, roleUri,
securityLevel, authSource);
} }
// TODO JB This goes away.
@Override @Override
public void recordLoginWithoutUserAccount(String username, public void recordLoginWithoutUserAccount(String individualUri) {
String individualUri, AuthenticationSource authSource) { recordLoginWithOrWithoutUserAccount(individualUri,
String roleUri = AuthRole.USER.roleUri(); AuthenticationSource.EXTERNAL);
int securityLevel = LoginStatusBean.NON_EDITOR;
recordLoginWithOrWithoutUserAccount(username, individualUri, roleUri,
securityLevel, authSource);
} }
/** This much is in common on login, whether or not you have a user account. */ /** This much is in common on login, whether or not you have a user account. */
private void recordLoginWithOrWithoutUserAccount(String username, private void recordLoginWithOrWithoutUserAccount(String userUri,
String userUri, String roleUri, int securityLevel,
AuthenticationSource authSource) { AuthenticationSource authSource) {
HttpSession session = request.getSession(); HttpSession session = request.getSession();
createLoginFormBean(username, userUri, roleUri, session); createLoginStatusBean(userUri, authSource, session);
createLoginStatusBean(username, userUri, securityLevel, authSource,
session);
setSessionTimeoutLimit(session); setSessionTimeoutLimit(session);
recordInUserSessionMap(userUri, session); recordInUserSessionMap(userUri, session);
notifyOtherUsers(userUri, session); notifyOtherUsers(userUri, session);
@ -137,41 +146,17 @@ public class BasicAuthenticator extends Authenticator {
/** /**
* Update the user record to record the login. * Update the user record to record the login.
*/ */
private void recordLoginOnUserRecord(User user) { private void recordLoginOnUserRecord(UserAccount userAccount) {
user.setLoginCount(user.getLoginCount() + 1); userAccount.setLoginCount(userAccount.getLoginCount() + 1);
if (user.getFirstTime() == null) { // first login getUserAccountsDao().updateUserAccount(userAccount);
user.setFirstTime(new Date());
}
getUserDao().updateUser(user);
} }
/** /**
* Put the login bean into the session. * Put the login bean into the session.
*
* TODO The LoginFormBean is being phased out.
*/ */
private void createLoginFormBean(String username, String userUri, private void createLoginStatusBean(String userUri,
String roleUri, HttpSession session) { AuthenticationSource authSource, HttpSession session) {
LoginFormBean lfb = new LoginFormBean(); LoginStatusBean lsb = new LoginStatusBean(userUri, authSource);
lfb.setUserURI(userUri);
lfb.setLoginStatus("authenticated");
lfb.setSessionId(session.getId());
lfb.setLoginRole(roleUri);
lfb.setLoginRemoteAddr(request.getRemoteAddr());
lfb.setLoginName(username);
session.setAttribute("loginHandler", lfb);
}
/**
* Put the login bean into the session.
*
* TODO this should eventually replace the LoginFormBean.
*/
private void createLoginStatusBean(String username, String userUri,
int securityLevel, AuthenticationSource authSource,
HttpSession session) {
LoginStatusBean lsb = new LoginStatusBean(userUri, username,
securityLevel, authSource);
LoginStatusBean.setBean(session, lsb); LoginStatusBean.setBean(session, lsb);
log.debug("Adding status bean: " + lsb); log.debug("Adding status bean: " + lsb);
} }
@ -180,8 +165,9 @@ public class BasicAuthenticator extends Authenticator {
* Editors and other privileged users get a longer timeout interval. * Editors and other privileged users get a longer timeout interval.
*/ */
private void setSessionTimeoutLimit(HttpSession session) { private void setSessionTimeoutLimit(HttpSession session) {
if (LoginStatusBean.getBean(session).isLoggedInAtLeast( RoleLevel role = RoleLevel.getRoleFromLoginStatus(request);
LoginStatusBean.EDITOR)) { if (role == RoleLevel.EDITOR || role == RoleLevel.CURATOR
|| role == RoleLevel.DB_ADMIN) {
session.setMaxInactiveInterval(PRIVILEGED_TIMEOUT_INTERVAL); session.setMaxInactiveInterval(PRIVILEGED_TIMEOUT_INTERVAL);
} else { } else {
session.setMaxInactiveInterval(LOGGED_IN_TIMEOUT_INTERVAL); session.setMaxInactiveInterval(LOGGED_IN_TIMEOUT_INTERVAL);
@ -208,54 +194,23 @@ public class BasicAuthenticator extends Authenticator {
session.getServletContext(), session); session.getServletContext(), session);
} }
@Override private List<String> getUrisAssociatedBySelfEditorConfig(UserAccount user) {
public List<String> getAssociatedIndividualUris(String username) {
List<String> uris = new ArrayList<String>(); List<String> uris = new ArrayList<String>();
uris.addAll(getUrisAssociatedBySelfEditorConfig(username)); if (user == null) {
uris.addAll(getUrisAssociatedByMayEditAs(username)); return uris;
return uris;
}
private List<String> getUrisAssociatedBySelfEditorConfig(String username) {
if (username == null) {
return Collections.emptyList();
} }
IndividualDao iDao = getIndividualDao(); IndividualDao iDao = getIndividualDao();
if (iDao == null) { if (iDao == null) {
return Collections.emptyList(); return uris;
} }
String selfEditorUri = SelfEditingConfiguration.getBean(request) List<Individual> associatedIndividuals = SelfEditingConfiguration
.getIndividualUriFromUsername(iDao, username); .getBean(request).getAssociatedIndividuals(iDao, user);
if (selfEditorUri == null) { for (Individual ind : associatedIndividuals) {
return Collections.emptyList(); uris.add(ind.getURI());
} else {
return Collections.singletonList(selfEditorUri);
} }
} return uris;
private List<String> getUrisAssociatedByMayEditAs(String username) {
if (username == null) {
return Collections.emptyList();
}
UserDao userDao = getUserDao();
if (userDao == null) {
return Collections.emptyList();
}
User user = userDao.getUserByUsername(username);
if (user == null) {
return Collections.emptyList();
}
String userUri = user.getURI();
if (userUri == null) {
return Collections.emptyList();
}
return userDao.getIndividualsUserMayEditAs(userUri);
} }
@Override @Override
@ -266,42 +221,30 @@ public class BasicAuthenticator extends Authenticator {
} }
private void notifyOtherUsersOfLogout(HttpSession session) { private void notifyOtherUsersOfLogout(HttpSession session) {
LoginStatusBean loginBean = LoginStatusBean.getBean(session); String userUri = LoginStatusBean.getBean(session).getUserURI();
if (!loginBean.isLoggedIn()) { if ((userUri == null) || userUri.isEmpty()) {
return; return;
} }
UserDao userDao = getUserDao(); Authenticate.sendLoginNotifyEvent(new LogoutEvent(userUri),
if (userDao == null) {
return;
}
String username = loginBean.getUsername();
User user = userDao.getUserByUsername(username);
if (user == null) {
log.error("Unable to retrieve user " + username + " from model");
return;
}
Authenticate.sendLoginNotifyEvent(new LogoutEvent(user.getURI()),
session.getServletContext(), session); session.getServletContext(), session);
} }
/** /**
* Get a reference to the UserDao, or null. * Get a reference to the UserAccountsDao, or null.
*/ */
private UserDao getUserDao() { private UserAccountsDao getUserAccountsDao() {
WebappDaoFactory wadf = getWebappDaoFactory(); WebappDaoFactory wadf = getWebappDaoFactory();
if (wadf == null) { if (wadf == null) {
return null; return null;
} }
UserDao userDao = wadf.getUserDao(); UserAccountsDao userAccountsDao = wadf.getUserAccountsDao();
if (userDao == null) { if (userAccountsDao == null) {
log.error("getUserDao: no UserDao"); log.error("getUserAccountsDao: no UserAccountsDao");
} }
return userDao; return userAccountsDao;
} }
/** /**
@ -341,23 +284,4 @@ public class BasicAuthenticator extends Authenticator {
return wadf; return wadf;
} }
/**
* Parse the role URI from User. Don't crash if it is not valid.
*/
private int parseUserSecurityLevel(User user) {
String roleURI = user.getRoleURI();
try {
if (roleURI.startsWith(ROLE_NAMESPACE)) {
String roleLevel = roleURI.substring(ROLE_NAMESPACE.length());
return Integer.parseInt(roleLevel);
} else {
return Integer.parseInt(roleURI);
}
} catch (NumberFormatException e) {
log.warn("Invalid RoleURI '" + roleURI + "' for user '"
+ user.getURI() + "'");
return 1;
}
}
} }

View file

@ -34,8 +34,8 @@ public class ExternalAuthHelper {
/** This configuration property points to the external authorization server. */ /** This configuration property points to the external authorization server. */
private static final String PROPERTY_EXTERNAL_AUTH_SERVER_URL = "externalAuth.serverUrl"; private static final String PROPERTY_EXTERNAL_AUTH_SERVER_URL = "externalAuth.serverUrl";
/** This configuration property says which HTTP header holds the username. */ /** This configuration property says which HTTP header holds the auth ID. */
public static final String PROPERTY_EXTERNAL_AUTH_USERNAME_HEADER = "externalAuth.netIdHeaderName"; public static final String PROPERTY_EXTERNAL_AUTH_ID_HEADER = "externalAuth.netIdHeaderName";
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// static methods // static methods
@ -82,7 +82,7 @@ public class ExternalAuthHelper {
String externalAuthServerUrl = ConfigurationProperties.getBean(ctx) String externalAuthServerUrl = ConfigurationProperties.getBean(ctx)
.getProperty(PROPERTY_EXTERNAL_AUTH_SERVER_URL); .getProperty(PROPERTY_EXTERNAL_AUTH_SERVER_URL);
String externalAuthHeaderName = ConfigurationProperties.getBean(ctx) String externalAuthHeaderName = ConfigurationProperties.getBean(ctx)
.getProperty(PROPERTY_EXTERNAL_AUTH_USERNAME_HEADER); .getProperty(PROPERTY_EXTERNAL_AUTH_ID_HEADER);
return new ExternalAuthHelper(externalAuthServerUrl, return new ExternalAuthHelper(externalAuthServerUrl,
externalAuthHeaderName); externalAuthHeaderName);
@ -134,7 +134,7 @@ public class ExternalAuthHelper {
} }
} }
public String getExternalUsername(HttpServletRequest request) { public String getExternalAuthId(HttpServletRequest request) {
if (request == null) { if (request == null) {
log.error("request is null."); log.error("request is null.");
return null; return null;
@ -143,13 +143,13 @@ public class ExternalAuthHelper {
if (externalAuthHeaderName == null) { if (externalAuthHeaderName == null) {
log.error("User asked for external authentication, " log.error("User asked for external authentication, "
+ "but deploy.properties doesn't contain a value for '" + "but deploy.properties doesn't contain a value for '"
+ PROPERTY_EXTERNAL_AUTH_USERNAME_HEADER + "'"); + PROPERTY_EXTERNAL_AUTH_ID_HEADER + "'");
return null; return null;
} }
String username = request.getHeader(externalAuthHeaderName); String externalAuthId = request.getHeader(externalAuthHeaderName);
log.debug("username=" + username); log.debug("externalAuthId=" + externalAuthId);
return username; return externalAuthId;
} }
@Override @Override

View file

@ -117,7 +117,7 @@ public class FakeExternalAuthController extends FreemarkerHttpServlet {
} }
@Override @Override
public String getExternalUsername(HttpServletRequest request) { public String getExternalAuthId(HttpServletRequest request) {
log.debug("external username is '" + username + "'"); log.debug("external username is '" + username + "'");
return username; return username;
} }

View file

@ -15,6 +15,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource; import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
/** /**
* Handle the return from the external authorization login server. If we are * Handle the return from the external authorization login server. If we are
@ -40,36 +41,44 @@ public class LoginExternalAuthReturn extends BaseLoginServlet {
@Override @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException { throws ServletException, IOException {
String username = ExternalAuthHelper.getHelper(req) String externalAuthId = ExternalAuthHelper.getHelper(req)
.getExternalUsername(req); .getExternalAuthId(req);
List<String> associatedUris = getAuthenticator(req) if (externalAuthId == null) {
.getAssociatedIndividualUris(username); log.debug("No externalAuthId.");
if (username == null) {
log.debug("No username.");
complainAndReturnToReferrer(req, resp, ATTRIBUTE_REFERRER, complainAndReturnToReferrer(req, resp, ATTRIBUTE_REFERRER,
MESSAGE_LOGIN_FAILED); MESSAGE_LOGIN_FAILED);
} else if (getAuthenticator(req).isExistingUser(username)) { return;
log.debug("Logging in as " + username); }
getAuthenticator(req).recordLoginAgainstUserAccount(username,
UserAccount userAccount = getAuthenticator(req)
.getAccountForExternalAuth(externalAuthId);
if (userAccount != null) {
log.debug("Logging in as " + userAccount.getUri());
getAuthenticator(req).recordLoginAgainstUserAccount(userAccount,
AuthenticationSource.EXTERNAL); AuthenticationSource.EXTERNAL);
removeLoginProcessArtifacts(req); removeLoginProcessArtifacts(req);
new LoginRedirector(req, resp).redirectLoggedInUser(); new LoginRedirector(req, resp).redirectLoggedInUser();
} else if (!associatedUris.isEmpty()) { return;
log.debug("Recognize '" + username + "' as self-editor for " }
List<String> associatedUris = getAuthenticator(req)
.getAssociatedIndividualUris(userAccount);
// TODO JB - this case should lead to creating a new account.
if (!associatedUris.isEmpty()) {
log.debug("Recognize '" + externalAuthId + "' as self-editor for "
+ associatedUris); + associatedUris);
String uri = associatedUris.get(0); String uri = associatedUris.get(0);
getAuthenticator(req).recordLoginWithoutUserAccount(username, uri, getAuthenticator(req).recordLoginWithoutUserAccount(uri);
AuthenticationSource.EXTERNAL);
removeLoginProcessArtifacts(req); removeLoginProcessArtifacts(req);
new LoginRedirector(req, resp).redirectLoggedInUser(); new LoginRedirector(req, resp).redirectLoggedInUser();
} else { return;
log.debug("User is not recognized: " + username);
removeLoginProcessArtifacts(req);
new LoginRedirector(req, resp)
.redirectUnrecognizedExternalUser(username);
} }
log.debug("User is not recognized: " + externalAuthId);
removeLoginProcessArtifacts(req);
new LoginRedirector(req, resp)
.redirectUnrecognizedExternalUser(externalAuthId);
} }
private void removeLoginProcessArtifacts(HttpServletRequest req) { private void removeLoginProcessArtifacts(HttpServletRequest req) {

View file

@ -0,0 +1,24 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
/**
* Handle the first login from an external authentication.
*/
public class LoginExternalNewAccount extends FreemarkerHttpServlet {
@Override
protected ResponseValues processRequest(VitroRequest vreq) {
String externalAuthId = ExternalAuthHelper.getHelper(vreq)
.getExternalAuthId(vreq);
// TODO Auto-generated method stub
throw new RuntimeException(
"LoginExternalNewAccount.processRequest() not implemented.");
}
}

View file

@ -11,12 +11,14 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean; import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage; import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
import edu.cornell.mannlib.vitro.webapp.beans.User; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean; import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean;
@ -48,22 +50,22 @@ public class LoginRedirector {
/** Is there an Individual associated with this user? */ /** Is there an Individual associated with this user? */
private String getAssociatedIndividualUri() { private String getAssociatedIndividualUri() {
String username = LoginStatusBean.getBean(request).getUsername(); UserAccount userAccount = LoginStatusBean.getCurrentUser(request);
if (username == null) { if (userAccount == null) {
log.warn("Not logged in? How did we get here?"); log.debug("Not logged in? Must be cancelling the password change");
return null; return null;
} }
List<String> uris = Authenticator.getInstance(request) List<String> uris = Authenticator.getInstance(request)
.getAssociatedIndividualUris(username); .getAssociatedIndividualUris(userAccount);
if (uris.isEmpty()) { if (uris.isEmpty()) {
log.debug("'" + username log.debug("'" + userAccount.getEmailAddress()
+ "' is not associated with an individual."); + "' is not associated with an individual.");
return null; return null;
} else { } else {
String uri = uris.get(0); String uri = uris.get(0);
log.debug("'" + username + "' is associated with an individual: " log.debug("'" + userAccount.getEmailAddress()
+ uri); + "' is associated with an individual: " + uri);
return uri; return uri;
} }
} }
@ -104,19 +106,17 @@ public class LoginRedirector {
+ "but the system contains no profile for you."; + "but the system contains no profile for you.";
} }
LoginStatusBean bean = LoginStatusBean.getBean(request);
Authenticator auth = Authenticator.getInstance(request);
User user = auth.getUserByUsername(bean.getUsername());
String backString = ""; String backString = "";
String greeting = bean.getUsername(); String greeting = "";
if (user != null) { UserAccount userAccount = LoginStatusBean.getCurrentUser(request);
if (user.getLoginCount() > 1) { if (userAccount != null) {
greeting = userAccount.getEmailAddress();
if (userAccount.getLoginCount() > 1) {
backString = " back"; backString = " back";
} }
String name = user.getFirstName(); String name = userAccount.getFirstName();
if ((name != null) && (name.length() > 0)) { if (!StringUtils.isEmpty(name)) {
greeting = name; greeting = name;
} }
} }
@ -152,8 +152,8 @@ public class LoginRedirector {
} }
private boolean isMerelySelfEditor() { private boolean isMerelySelfEditor() {
return LoginStatusBean.getBean(session).isLoggedInExactly( RoleLevel role = RoleLevel.getRoleFromLoginStatus(request);
LoginStatusBean.NON_EDITOR); return role == RoleLevel.PUBLIC || role == RoleLevel.SELF;
} }
private boolean isLoginPage(String page) { private boolean isLoginPage(String page) {

View file

@ -0,0 +1,20 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
/**
* TODO
*/
public class LoginRepairAccountInfo extends FreemarkerHttpServlet {
@Override
protected ResponseValues processRequest(VitroRequest vreq) {
// TODO Auto-generated method stub
throw new RuntimeException("LoginRepairAccountInfo.processRequest() not implemented.");
}
}

View file

@ -3,8 +3,8 @@
package edu.cornell.mannlib.vitro.webapp.controller.authenticate; package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
import static edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource.INTERNAL; import static edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource.INTERNAL;
import static edu.cornell.mannlib.vitro.webapp.beans.User.MAX_PASSWORD_LENGTH; import static edu.cornell.mannlib.vitro.webapp.beans.UserAccount.MAX_PASSWORD_LENGTH;
import static edu.cornell.mannlib.vitro.webapp.beans.User.MIN_PASSWORD_LENGTH; import static edu.cornell.mannlib.vitro.webapp.beans.UserAccount.MIN_PASSWORD_LENGTH;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
@ -14,13 +14,18 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import edu.cornell.mannlib.vitro.webapp.beans.User; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
/** /**
* Provide a means for programmatic login If they provide the right parameters, * Provide a means for programmatic login If they provide the right parameters,
* log them in and send 200. Otherwise, send 403 error. * log them in and send 200. Otherwise, send 403 error.
*/ */
public class ProgramLogin extends HttpServlet { public class ProgramLogin extends HttpServlet {
private static final Log log = LogFactory.getLog(ProgramLogin.class);
@Override @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException { throws ServletException, IOException {
@ -34,16 +39,16 @@ public class ProgramLogin extends HttpServlet {
} }
static class ProgramLoginCore { static class ProgramLoginCore {
public static final String PARAM_USERNAME = "username"; public static final String PARAM_EMAIL_ADDRESS = "email";
public static final String PARAM_PASSWORD = "password"; public static final String PARAM_PASSWORD = "password";
public static final String PARAM_NEW_PASSWORD = "newPassword"; public static final String PARAM_NEW_PASSWORD = "newPassword";
public static final int ERROR_CODE = 403; public static final int ERROR_CODE = 403;
private static final String MESSAGE_NEED_USERNAME = PARAM_USERNAME private static final String MESSAGE_NEED_EMAIL_ADDRESS = PARAM_EMAIL_ADDRESS
+ " parameter is required."; + " parameter is required.";
private static final String MESSAGE_NEED_PASSWORD = PARAM_PASSWORD private static final String MESSAGE_NEED_PASSWORD = PARAM_PASSWORD
+ " parameter is required."; + " parameter is required.";
private static final String MESSAGE_WRONG_USER_OR_PASSWORD = PARAM_USERNAME private static final String MESSAGE_WRONG_USER_OR_PASSWORD = PARAM_EMAIL_ADDRESS
+ " or " + PARAM_PASSWORD + " is incorrect."; + " or " + PARAM_PASSWORD + " is incorrect.";
private static final String MESSAGE_NEED_NEW_PASSWORD = "first-time login: " private static final String MESSAGE_NEED_NEW_PASSWORD = "first-time login: "
+ PARAM_NEW_PASSWORD + " parameter is required."; + PARAM_NEW_PASSWORD + " parameter is required.";
@ -63,24 +68,31 @@ public class ProgramLogin extends HttpServlet {
private final HttpServletResponse resp; private final HttpServletResponse resp;
private final Authenticator auth; private final Authenticator auth;
private final String username; private final String emailAddress;
private final String password; private final String password;
private final String newPassword; private final String newPassword;
private final UserAccount userAccount;
ProgramLoginCore(HttpServletRequest req, HttpServletResponse resp) { ProgramLoginCore(HttpServletRequest req, HttpServletResponse resp) {
this.req = req; this.req = req;
this.resp = resp; this.resp = resp;
this.username = getParameter(PARAM_USERNAME); this.emailAddress = getParameter(PARAM_EMAIL_ADDRESS);
this.password = getParameter(PARAM_PASSWORD); this.password = getParameter(PARAM_PASSWORD);
this.newPassword = getParameter(PARAM_NEW_PASSWORD); this.newPassword = getParameter(PARAM_NEW_PASSWORD);
log.debug("request: email='" + emailAddress + "', password='"
+ password + "', newPassword='" + newPassword + "'");
this.auth = Authenticator.getInstance(req); this.auth = Authenticator.getInstance(req);
this.userAccount = auth
.getAccountForInternalAuth(this.emailAddress);
} }
void process() throws IOException { void process() throws IOException {
if (username.isEmpty()) { if (emailAddress.isEmpty()) {
sendError(MESSAGE_NEED_USERNAME); sendError(MESSAGE_NEED_EMAIL_ADDRESS);
return; return;
} }
if (password.isEmpty()) { if (password.isEmpty()) {
@ -92,9 +104,7 @@ public class ProgramLogin extends HttpServlet {
return; return;
} }
boolean passwordChangeRequired = isFirstTimeLogin(); if (!isPasswordChangeRequired()) {
if (!passwordChangeRequired) {
if (!newPassword.isEmpty()) { if (!newPassword.isEmpty()) {
sendError(MESSAGE_NEW_PASSWORD_NOT_NEEDED); sendError(MESSAGE_NEW_PASSWORD_NOT_NEEDED);
return; return;
@ -104,7 +114,7 @@ public class ProgramLogin extends HttpServlet {
return; return;
} }
if (passwordChangeRequired) { if (isPasswordChangeRequired()) {
if (newPassword.isEmpty()) { if (newPassword.isEmpty()) {
sendError(MESSAGE_NEED_NEW_PASSWORD); sendError(MESSAGE_NEED_NEW_PASSWORD);
return; return;
@ -134,8 +144,7 @@ public class ProgramLogin extends HttpServlet {
} }
private boolean usernameAndPasswordAreValid() { private boolean usernameAndPasswordAreValid() {
return auth.isExistingUser(username) return auth.isCurrentPassword(userAccount, password);
&& auth.isCurrentPassword(username, password);
} }
private boolean newPasswordIsValidPasswordLength() { private boolean newPasswordIsValidPasswordLength() {
@ -147,18 +156,17 @@ public class ProgramLogin extends HttpServlet {
return newPassword.equals(password); return newPassword.equals(password);
} }
private boolean isFirstTimeLogin() { private boolean isPasswordChangeRequired() {
User user = auth.getUserByUsername(username); return (userAccount.isPasswordChangeRequired());
return (user.getLoginCount() == 0);
} }
private void recordLogin() { private void recordLogin() {
auth.recordLoginAgainstUserAccount(username, INTERNAL); auth.recordLoginAgainstUserAccount(userAccount, INTERNAL);
} }
private void recordLoginWithPasswordChange() { private void recordLoginWithPasswordChange() {
auth.recordNewPassword(username, newPassword); auth.recordNewPassword(userAccount, newPassword);
auth.recordLoginAgainstUserAccount(username, INTERNAL); auth.recordLoginAgainstUserAccount(userAccount, INTERNAL);
} }
private void sendError(String message) throws IOException { private void sendError(String message) throws IOException {

View file

@ -2,6 +2,8 @@
package edu.cornell.mannlib.vitro.webapp.controller.edit; package edu.cornell.mannlib.vitro.webapp.controller.edit;
import static edu.cornell.mannlib.vitro.webapp.beans.UserAccount.MAX_PASSWORD_LENGTH;
import static edu.cornell.mannlib.vitro.webapp.beans.UserAccount.MIN_PASSWORD_LENGTH;
import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State.FORCED_PASSWORD_CHANGE; import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State.FORCED_PASSWORD_CHANGE;
import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State.LOGGED_IN; import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State.LOGGED_IN;
import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State.LOGGING_IN; import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State.LOGGING_IN;
@ -10,8 +12,6 @@ import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -21,7 +21,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -29,7 +28,7 @@ import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean; import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource; import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource;
import edu.cornell.mannlib.vitro.webapp.beans.User; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet; import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
@ -85,6 +84,7 @@ public class Authenticate extends VitroHttpServlet {
* Find out where they are in the login process, process any input, record * Find out where they are in the login process, process any input, record
* the new state, and show the next page. * the new state, and show the next page.
*/ */
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) { public void doPost(HttpServletRequest request, HttpServletResponse response) {
VitroRequest vreq = new VitroRequest(request); VitroRequest vreq = new VitroRequest(request);
@ -313,8 +313,9 @@ public class Authenticate extends VitroHttpServlet {
bean.setUsername(username); bean.setUsername(username);
User user = getAuthenticator(request).getUserByUsername(username); UserAccount user = getAuthenticator(request).getAccountForInternalAuth(
log.trace("User is " + (user == null ? "null" : user.getURI())); username);
log.trace("User is " + (user == null ? "null" : user.getUri()));
if (user == null) { if (user == null) {
bean.setMessage(Message.UNKNOWN_USERNAME, username); bean.setMessage(Message.UNKNOWN_USERNAME, username);
@ -326,16 +327,16 @@ public class Authenticate extends VitroHttpServlet {
return; return;
} }
if (!getAuthenticator(request).isCurrentPassword(username, password)) { if (!getAuthenticator(request).isCurrentPassword(user, password)) {
bean.setMessage(Message.INCORRECT_PASSWORD); bean.setMessage(Message.INCORRECT_PASSWORD);
return; return;
} }
// Username and password are correct. What next? // Username and password are correct. What next?
if (isFirstTimeLogin(user)) { if (user.isPasswordChangeRequired()) {
transitionToForcedPasswordChange(request); transitionToForcedPasswordChange(request);
} else { } else {
transitionToLoggedIn(request, username); transitionToLoggedIn(request, user);
} }
} }
@ -374,40 +375,32 @@ public class Authenticate extends VitroHttpServlet {
return; return;
} }
if ((newPassword.length() < User.MIN_PASSWORD_LENGTH) if ((newPassword.length() < MIN_PASSWORD_LENGTH)
|| (newPassword.length() > User.MAX_PASSWORD_LENGTH)) { || (newPassword.length() > MAX_PASSWORD_LENGTH)) {
bean.setMessage(Message.PASSWORD_LENGTH, User.MIN_PASSWORD_LENGTH, bean.setMessage(Message.PASSWORD_LENGTH, MIN_PASSWORD_LENGTH,
User.MAX_PASSWORD_LENGTH); MAX_PASSWORD_LENGTH);
return; return;
} }
String username = bean.getUsername(); String username = bean.getUsername();
if (getAuthenticator(request).isCurrentPassword(username, newPassword)) { UserAccount user = getAuthenticator(request).getAccountForInternalAuth(
username);
if (getAuthenticator(request).isCurrentPassword(user, newPassword)) {
bean.setMessage(Message.USING_OLD_PASSWORD); bean.setMessage(Message.USING_OLD_PASSWORD);
return; return;
} }
// New password is acceptable. Store it and go on. // New password is acceptable. Store it and go on.
transitionToLoggedIn(request, username, newPassword); transitionToLoggedIn(request, user, newPassword);
} }
/** /**
* They are already logged in. There's nothing to do; no transition. * They are already logged in.
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
private void processInputLoggedIn(HttpServletRequest request) { private void processInputLoggedIn(HttpServletRequest request) {
} // Nothing to do. No transition.
/**
* Has this user ever logged in before?
*/
private boolean isFirstTimeLogin(User user) {
if (user.getLoginCount() == 0) {
return true;
} else {
return false;
}
} }
/** /**
@ -431,9 +424,9 @@ public class Authenticate extends VitroHttpServlet {
* State change: all requirements are satisfied. Log them in. * State change: all requirements are satisfied. Log them in.
*/ */
private void transitionToLoggedIn(HttpServletRequest request, private void transitionToLoggedIn(HttpServletRequest request,
String username) { UserAccount user) {
log.debug("Completed login: " + username); log.debug("Completed login: " + user.getEmailAddress());
getAuthenticator(request).recordLoginAgainstUserAccount(username, getAuthenticator(request).recordLoginAgainstUserAccount(user,
AuthenticationSource.INTERNAL); AuthenticationSource.INTERNAL);
} }
@ -442,10 +435,11 @@ public class Authenticate extends VitroHttpServlet {
* log them in. * log them in.
*/ */
private void transitionToLoggedIn(HttpServletRequest request, private void transitionToLoggedIn(HttpServletRequest request,
String username, String newPassword) { UserAccount user, String newPassword) {
log.debug("Completed login: " + username + ", password changed."); log.debug("Completed login: " + user.getEmailAddress()
getAuthenticator(request).recordNewPassword(username, newPassword); + ", password changed.");
getAuthenticator(request).recordLoginAgainstUserAccount(username, getAuthenticator(request).recordNewPassword(user, newPassword);
getAuthenticator(request).recordLoginAgainstUserAccount(user,
AuthenticationSource.INTERNAL); AuthenticationSource.INTERNAL);
} }

View file

@ -25,6 +25,7 @@ import edu.cornell.mannlib.vedit.forwarder.impl.UrlForwarder;
import edu.cornell.mannlib.vedit.util.FormUtils; import edu.cornell.mannlib.vedit.util.FormUtils;
import edu.cornell.mannlib.vedit.validator.impl.IntValidator; import edu.cornell.mannlib.vedit.validator.impl.IntValidator;
import edu.cornell.mannlib.vedit.validator.impl.XMLNameValidator; import edu.cornell.mannlib.vedit.validator.impl.XMLNameValidator;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionListener;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOntology; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOntology;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
@ -121,7 +122,7 @@ public class DatapropRetryController extends BaseEditController {
//set up any listeners //set up any listeners
List changeListenerList = new ArrayList(); List changeListenerList = new ArrayList();
//changeListenerList.add(new PropertyRestrictionListener(getServletContext())); changeListenerList.add(new PropertyRestrictionListener(getServletContext()));
epo.setChangeListenerList(changeListenerList); epo.setChangeListenerList(changeListenerList);

View file

@ -33,10 +33,9 @@ import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.shared.Lock;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean; import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet; import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.UserDao;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent; import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.Field; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.Field;
@ -507,12 +506,14 @@ public class N3MultiPartUpload extends VitroHttpServlet {
} }
public void sendUserEmail(HttpServletRequest request, HttpSession session, String uploadFileName) { public void sendUserEmail(HttpServletRequest request, HttpSession session, String uploadFileName) {
LoginStatusBean loginBean = LoginStatusBean.getBean(request); UserAccount userAccount = LoginStatusBean.getCurrentUser(request);
String userURI = loginBean.getUserURI(); if (userAccount == null) {
return;
}
try{ try{
System.out.println("User URI is " + userURI); System.out.println("User URI is " + userAccount.getUri());
UserDao uDao = (new VitroRequest(request)).getFullWebappDaoFactory().getUserDao(); String email = userAccount.getEmailAddress();
String email = uDao.getUserEmailAddress(userURI);
String deliveryFrom = "hjk54@cornell.edu";//TO DO: replace with email address to be used String deliveryFrom = "hjk54@cornell.edu";//TO DO: replace with email address to be used
//Now send message //Now send message
MailUtil mu = new MailUtil(request); MailUtil mu = new MailUtil(request);

View file

@ -28,6 +28,7 @@ import edu.cornell.mannlib.vedit.forwarder.PageForwarder;
import edu.cornell.mannlib.vedit.forwarder.impl.UrlForwarder; import edu.cornell.mannlib.vedit.forwarder.impl.UrlForwarder;
import edu.cornell.mannlib.vedit.util.FormUtils; import edu.cornell.mannlib.vedit.util.FormUtils;
import edu.cornell.mannlib.vedit.validator.impl.XMLNameValidator; import edu.cornell.mannlib.vedit.validator.impl.XMLNameValidator;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionListener;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOntology; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOntology;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
@ -117,8 +118,7 @@ public class PropertyRetryController extends BaseEditController {
//set up any listeners //set up any listeners
List changeListenerList = new ArrayList(); List changeListenerList = new ArrayList();
//changeListenerList.add(new HiddenFromDisplayListener(getServletContext())); changeListenerList.add(new PropertyRestrictionListener(getServletContext()));
//changeListenerList.add(new PropertyRestrictionListener(getServletContext()));
epo.setChangeListenerList(changeListenerList); epo.setChangeListenerList(changeListenerList);
//make a postinsert pageforwarder that will send us to a new class's fetch screen //make a postinsert pageforwarder that will send us to a new class's fetch screen

View file

@ -1,138 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.edit;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.controller.BaseEditController;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageUserAccounts;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatementImpl;
import edu.cornell.mannlib.vitro.webapp.beans.User;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.UserDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
public class UserEditController extends BaseEditController {
private String[] roleNameStr = new String[51];
private static final Log log = LogFactory.getLog(UserEditController.class.getName());
public UserEditController() {
roleNameStr[1] = "self editor";
roleNameStr[4] = "editor";
roleNameStr[5] = "curator";
roleNameStr[50] = "system administrator";
}
@Override
public void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException {
if (!isAuthorizedToDisplayPage(request, response, new Actions(new ManageUserAccounts()))) {
return;
}
VitroRequest vreq = new VitroRequest(request);
UserDao uDao = vreq.getFullWebappDaoFactory().getUserDao();
String userURIStr = request.getParameter("uri");
User u = null;
if (userURIStr == null) {
throw new ServletException(this.getClass().getName()+" expects user URI in 'uri' request parameter");
} else {
u = uDao.getUserByURI(userURIStr);
}
if (u == null) {
throw new ServletException(this.getClass().getName()+" could not find user "+userURIStr);
}
ArrayList<String> results = new ArrayList<String>();
results.add("Email address");
results.add("first name");
results.add("last name");
results.add("login count");
results.add("role");
String EMPTY = "";
String usernameStr = (u.getUsername() != null) ? u.getUsername() : "";
results.add(usernameStr);
String firstNameStr = (u.getFirstName() != null) ? u.getFirstName() : EMPTY;
results.add(firstNameStr);
String lastNameStr = (u.getLastName() != null) ? u.getLastName() : EMPTY;
results.add(lastNameStr);
String loginCountStr = Integer.toString(u.getLoginCount());
results.add(loginCountStr);
String roleStr = "";
try {
roleStr = roleNameStr[Integer.decode(u.getRoleURI())];
} catch (Exception e) {}
results.add(roleStr);
request.setAttribute("results",results);
List<String> mayEditAsUris = uDao.getIndividualsUserMayEditAs(u.getURI());
if( mayEditAsUris != null && mayEditAsUris.size() > 0 ){
List<ObjectPropertyStatement> mayEditAsStmts =
new ArrayList<ObjectPropertyStatement>(mayEditAsUris.size());
for(String objURI: mayEditAsUris){
Individual editAs = vreq.getFullWebappDaoFactory().getIndividualDao().getIndividualByURI(objURI);
ObjectPropertyStatement stmt = new ObjectPropertyStatementImpl();
stmt.setSubjectURI(u.getURI());
stmt.setPropertyURI(VitroVocabulary.MAY_EDIT_AS);
stmt.setObjectURI(objURI);
stmt.setObject(editAs);
mayEditAsStmts.add(stmt);
}
request.setAttribute("mayEditAsStmts", mayEditAsStmts);
}
/* these are set so that we can use the PropertyEditLinks jsp tags */
ObjectProperty prop = new ObjectProperty();
prop.setURI(VitroVocabulary.MAY_EDIT_AS);
request.setAttribute("mayEditObjProp",prop);
Individual entity = new IndividualImpl();
entity.setURI(u.getURI());
request.setAttribute("entity", entity);
request.setAttribute("results", results);
request.setAttribute("columncount", new Integer(5));
request.setAttribute("suppressquery", "true");
RequestDispatcher rd = request.getRequestDispatcher(Controllers.BASIC_JSP);
request.setAttribute("user", u);
request.setAttribute("bodyJsp","/templates/edit/specific/user_edit.jsp");
request.setAttribute("title","User Account Control Panel");
request.setAttribute("css", "<link rel=\"stylesheet\" type=\"text/css\" href=\""+vreq.getAppBean().getThemeDir()+"css/edit.css\"/>");
try {
rd.forward(request, response);
} catch (Exception e) {
log.error(this.getClass().getName()+" could not forward to view.");
log.error(e.getMessage());
log.error(e.getStackTrace());
}
}
public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException {
doPost(request,response);
}
}

View file

@ -1,375 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.edit;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.EditProcessObject;
import edu.cornell.mannlib.vedit.beans.FormObject;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vedit.beans.Option;
import edu.cornell.mannlib.vedit.controller.BaseEditController;
import edu.cornell.mannlib.vedit.forwarder.PageForwarder;
import edu.cornell.mannlib.vedit.forwarder.impl.UrlForwarder;
import edu.cornell.mannlib.vedit.listener.ChangeListener;
import edu.cornell.mannlib.vedit.util.FormUtils;
import edu.cornell.mannlib.vedit.validator.ValidationObject;
import edu.cornell.mannlib.vedit.validator.Validator;
import edu.cornell.mannlib.vitro.webapp.auth.policy.setup.SelfEditingPolicySetup;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageUserAccounts;
import edu.cornell.mannlib.vitro.webapp.beans.User;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
import edu.cornell.mannlib.vitro.webapp.dao.UserDao;
public class UserRetryController extends BaseEditController {
private static final String ROLE_PROTOCOL = "role:/"; // this is weird; need to revisit
private static final Log log = LogFactory.getLog(UserRetryController.class.getName());
@Override
public void doPost (HttpServletRequest req, HttpServletResponse response) {
if (!isAuthorizedToDisplayPage(req, response, new Actions(new ManageUserAccounts()))) {
return;
}
VitroRequest request = new VitroRequest(req);
//create an EditProcessObject for this and put it in the session
EditProcessObject epo = super.createEpo(request);
epo.setDataAccessObject(request.getFullWebappDaoFactory().getVClassDao());
String action = null;
if (epo.getAction() == null) {
action = "insert";
epo.setAction("insert");
} else {
action = epo.getAction();
}
UserDao uDao = request.getFullWebappDaoFactory().getUserDao();
epo.setDataAccessObject(uDao);
User userForEditing = null;
if (!epo.getUseRecycledBean()){
if (request.getParameter("uri") != null) {
try {
userForEditing = uDao.getUserByURI(request.getParameter("uri"));
userForEditing.setRoleURI(ROLE_PROTOCOL+userForEditing.getRoleURI());
action = "update";
epo.setAction("udpate");
} catch (NullPointerException e) {
log.error("Need to implement 'record not found' error message.");
}
} else {
userForEditing = new User();
userForEditing.setRoleURI(ROLE_PROTOCOL+"1");
}
epo.setOriginalBean(userForEditing);
} else {
userForEditing = (User) epo.getNewBean();
}
populateBeanFromParams(userForEditing, request);
//validators
Validator v = new PairedPasswordValidator();
HashMap<String, List<Validator>> validatorMap = new HashMap<String, List<Validator>>();
List<Validator> vList = Collections.singletonList(v);
validatorMap.put("Md5password", vList);
validatorMap.put("passwordConfirmation", vList);
epo.setValidatorMap(validatorMap);
//preprocessors
//set up any listeners
epo.setChangeListenerList(Collections.singletonList(new UserPasswordChangeListener()));
//make a postinsert pageforwarder that will send us to a new class's fetch screen
epo.setPostInsertPageForwarder(new UserInsertPageForwarder());
//make a postdelete pageforwarder that will send us to the list of classes
epo.setPostDeletePageForwarder(new UrlForwarder("listUsers"));
//set the getMethod so we can retrieve a new bean after we've inserted it
try {
Class<?>[] args = new Class[] {String.class};
epo.setGetMethod(uDao.getClass().getDeclaredMethod("getUserByURI",args));
} catch (NoSuchMethodException e) {
log.error(this.getClass().getName()+" could not find the getVClassByURI method");
}
HashMap<String, List<Option>> optionMap = new HashMap<String, List<Option>>();
LoginStatusBean loginBean = LoginStatusBean.getBean(request);
List<Option> roleOptionList = new LinkedList<Option>();
/* bdc34: Datastar needs non-backend-editing users for logging in non-Cornell people*/
/* SelfEditingPolicySetup.SELF_EDITING_POLICY_WAS_SETUP is set by the SelfEditingPolicySetup context listener */
boolean selfEditing = (Boolean)getServletContext().getAttribute(SelfEditingPolicySetup.SELF_EDITING_POLICY_WAS_SETUP) == Boolean.TRUE;
Option nonEditor = new Option(ROLE_PROTOCOL+LoginStatusBean.NON_EDITOR, "self editor");
/* self editing should be displayed if we are editing a user account that is already
* self-editing even if self editing is off. */
if( selfEditing ||
( !"insert".equals(action) && userForEditing.getRoleURI().equals(nonEditor.getValue()) )){
nonEditor.setSelected(userForEditing.getRoleURI().equals(nonEditor.getValue()));
if (nonEditor.getSelected() || loginBean.isLoggedInAtLeast(LoginStatusBean.NON_EDITOR))
roleOptionList.add(nonEditor);
}
Option editor = new Option(ROLE_PROTOCOL+LoginStatusBean.EDITOR, "editor");
editor.setSelected(userForEditing.getRoleURI().equals(editor.getValue()));
Option curator = new Option(ROLE_PROTOCOL+LoginStatusBean.CURATOR, "curator");
curator.setSelected(userForEditing.getRoleURI().equals(curator.getValue()));
Option administrator = new Option (ROLE_PROTOCOL+LoginStatusBean.DBA, "system administrator");
administrator.setSelected(userForEditing.getRoleURI().equals(administrator.getValue()));
if (editor.getSelected() || loginBean.isLoggedInAtLeast(LoginStatusBean.EDITOR))
roleOptionList.add(editor);
if (curator.getSelected() || loginBean.isLoggedInAtLeast(LoginStatusBean.CURATOR))
roleOptionList.add(curator);
if (administrator.getSelected() || loginBean.isLoggedInAtLeast(LoginStatusBean.DBA))
roleOptionList.add(administrator);
optionMap.put("Role", roleOptionList);
FormObject foo = new FormObject();
foo.setErrorMap(epo.getErrMsgMap());
foo.setOptionLists(optionMap);
epo.setFormObject(foo);
request.setAttribute("formValue",foo.getValues());
String html = FormUtils.htmlFormFromBean(userForEditing,action,foo,epo.getBadValueMap());
RequestDispatcher rd = request.getRequestDispatcher(Controllers.BASIC_JSP);
request.setAttribute("formHtml",html);
request.setAttribute("user",userForEditing);
request.setAttribute("bodyJsp","/templates/edit/formBasic.jsp");
if (userForEditing.getMd5password()==null || userForEditing.getMd5password().equals("")) {
request.setAttribute("formOnSubmit", "return validatePw(this);");
request.setAttribute("formOnCancel", "forceCancel(this.form);");
}
else {
request.setAttribute("formOnSubmit", "return validateUserFields(this);");
request.setAttribute("formOnCancel", "forceCancelTwo(this.form);");
}
request.setAttribute("formJsp","/templates/edit/specific/user_retry.jsp");
request.setAttribute("scripts","/templates/edit/specific/user_retry_head.jsp");
request.setAttribute("title","User Account Editing Form");
request.setAttribute("_action",action);
request.setAttribute("unqualifiedClassName","User");
setRequestAttributes(request,epo);
try {
rd.forward(request, response);
} catch (Exception e) {
log.error(this.getClass().getName()+" could not forward to view.");
log.error(e.getMessage());
log.error(e.getStackTrace());
}
}
@Override
public void doGet (HttpServletRequest request, HttpServletResponse response) {
doPost(request, response);
}
class UserInsertPageForwarder implements PageForwarder {
@Override
public void doForward(HttpServletRequest request, HttpServletResponse response, EditProcessObject epo){
String newUserUrl = "userEdit?uri=";
User u = (User) epo.getNewBean();
try {
newUserUrl += URLEncoder.encode(u.getURI(),"UTF-8");
} catch (Exception e) {
log.error(this.getClass().getName()+" could not use UTF-8 encoding to encode new URL");
}
try {
response.sendRedirect(newUserUrl);
} catch (IOException ioe) {
log.error(this.getClass().getName()+" could not send redirect.");
}
}
}
/**
* Create one of these and assign it to both password fields.
*/
class PairedPasswordValidator implements Validator {
private String otherValue;
/**
* Validate the length of this password, and stash it for the other
* validator to compare to.
*
* This relies on the fact that {@link #validate(Object)} will be called
* once for each of the password fields.
*/
@Override
public ValidationObject validate(Object value)
throws IllegalArgumentException {
log.trace("validate password pair: " + value + ", " + otherValue);
// Must be a non-null String
if (!(value instanceof String)) {
log.trace("not a string: " + value);
return ValidationObject.failure(value, "Please enter a value");
}
// Must be within the length limits.
String string = (String) value;
if ((string.length() < User.MIN_PASSWORD_LENGTH)
|| (string.length() > User.MAX_PASSWORD_LENGTH)) {
log.trace("bad length: " + value);
return ValidationObject.failure(value,
"Please enter a password between "
+ User.MIN_PASSWORD_LENGTH + " and "
+ User.MAX_PASSWORD_LENGTH
+ " characters long.");
}
// If we haven't validate the other yet, just store this value.
if (otherValue == null) {
log.trace("first of the pair: " + value);
otherValue = string;
return ValidationObject.success(value);
}
// Compare this value to the stored one.
String otherString = otherValue;
otherValue = null;
if (string.equals(otherString)) {
log.trace("values are equal: " + value);
return ValidationObject.success(value);
} else {
log.trace("values are not equal: " + value + ", " + otherValue);
return ValidationObject.failure(value,
"The passwords do not match.");
}
}
}
/**
* When a new password is created, encode it.
*/
class UserPasswordChangeListener implements ChangeListener {
/**
* Encode the password for a new user.
*/
@Override
public void doInserted(Object newObj, EditProcessObject epo) {
try {
User newUser = convertToUser(newObj);
UserDao userDao = getUserDaoFromEPO(epo);
encodePasswordAndUpdateUser("insert", newUser, userDao);
} catch (PwException e) {
log.error(e.getMessage());
}
}
/**
* Encode the password for an updated user, if it has changed.
*/
@Override
public void doUpdated(Object oldObj, Object newObj,
EditProcessObject epo) {
try {
User newUser = convertToUser(newObj);
User oldUser = convertToUser(oldObj);
UserDao userDao = getUserDaoFromEPO(epo);
if (passwordHasChanged(newUser, oldUser)) {
encodePasswordAndUpdateUser("update", newUser, userDao);
} else {
log.debug("update: password has not changed.");
}
} catch (PwException e) {
log.error(e.getMessage());
}
}
/**
* Do nothing for a deleted user.
*/
@Override
public void doDeleted(Object oldObj, EditProcessObject epo) {
log.debug("delete: nothing to do");
}
private User convertToUser(Object o) throws PwException {
if (o instanceof User) {
return (User) o;
} else {
throw new PwException("Can't apply password encoding without a "
+ "User object: " + o);
}
}
private UserDao getUserDaoFromEPO(EditProcessObject epo)
throws PwException {
if (epo == null) {
throw new PwException(
"Can't apply password encoding without an "
+ "EditProcessObject");
}
Object dao = epo.getDataAccessObject();
if (dao instanceof UserDao) {
return (UserDao) dao;
} else {
throw new PwException(
"Can't apply password encoding without a "
+ "UserDao object: " + dao);
}
}
private boolean passwordHasChanged(User newUser, User oldUser)
throws PwException {
String newPw = newUser.getMd5password();
String oldPw = oldUser.getMd5password();
if (newPw == null) {
throw new PwException("Can't encode a null password");
}
return !newPw.equals(oldPw);
}
private void encodePasswordAndUpdateUser(String action, User user, UserDao userDao) {
String rawPassword = user.getMd5password();
if (rawPassword == null) {
log.error("Can't encode a null password");
}
String encodedPassword = Authenticator.applyMd5Encoding(rawPassword);
log.trace(action + ": Raw password '" + rawPassword
+ "', encoded '" + encodedPassword + "'");
user.setMd5password(encodedPassword);
userDao.updateUser(user);
}
}
class PwException extends Exception {
public PwException(String message) {
super(message);
}
}
}

View file

@ -1,122 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.edit.listing;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import edu.cornell.mannlib.vedit.controller.BaseEditController;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageUserAccounts;
import edu.cornell.mannlib.vitro.webapp.beans.User;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.UserDao;
public class UsersListingController extends BaseEditController {
public static final Actions REQUIRED_ACTIONS = new Actions(new ManageUserAccounts());
private String[] roleNameStr = new String[51];
public UsersListingController() {
roleNameStr[1] = "self editor";
roleNameStr[4] = "editor";
roleNameStr[5] = "curator";
roleNameStr[50] = "system administrator";
}
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) {
if (!isAuthorizedToDisplayPage(request, response, REQUIRED_ACTIONS)) {
return;
}
VitroRequest vrequest = new VitroRequest(request);
UserDao dao = vrequest.getFullWebappDaoFactory().getUserDao();
List<User> users = dao.getAllUsers();
Collections.sort(users);
ArrayList<String> results = new ArrayList<String>();
results.add("XX");
results.add("User");
results.add("first name");
results.add("last name");
results.add("role");
results.add("first login");
results.add("login count");
//results.add("recent edits"); // 2010-01-21 not currently supporting
Integer width = results.size();
String EMPTY = "";
if (users != null) {
Iterator<User> userIt = users.iterator();
while (userIt.hasNext()) {
User user = userIt.next();
results.add("XX");
if (user.getUsername() != null) {
try {
results.add("<a href=\"./userEdit?uri="+URLEncoder.encode(user.getURI(),"UTF-8")+"\">"+user.getUsername()+"</a>");
} catch (Exception e) {
results.add(user.getUsername());
}
} else {
results.add("");
}
String firstNameStr = (user.getFirstName() != null) ? user.getFirstName() : EMPTY;
results.add(firstNameStr);
String lastNameStr = (user.getLastName() != null) ? user.getLastName() : EMPTY;
results.add(lastNameStr);
String roleStr = "";
try {
roleStr = roleNameStr[Integer.decode(user.getRoleURI())];
} catch (Exception e) {}
results.add(roleStr);
String firstLoginStr = "";
try {
firstLoginStr = (DISPLAY_DATE_FORMAT.format(user.getFirstTime()));
} catch (Exception e) {}
results.add(firstLoginStr);
String loginCountStr = Integer.toString(user.getLoginCount());
results.add(loginCountStr);
// 2010-01-21 not currently supporting "recent edits"
// try {
// results.add("<a href=\"statementHistory?userURI="+URLEncoder.encode(user.getURI(),"UTF-8")+"\">recent edits</a>");
// } catch (Exception e) {}
}
request.setAttribute("results",results);
}
request.setAttribute("columncount", width);
request.setAttribute("suppressquery","true");
request.setAttribute("title","User Accounts");
request.setAttribute("bodyJsp", Controllers.HORIZONTAL_JSP);
request.setAttribute("horizontalJspAddButtonUrl", Controllers.RETRY_URL);
request.setAttribute("horizontalJspAddButtonText", "Add new user account");
request.setAttribute("horizontalJspAddButtonControllerParam", "User");
RequestDispatcher rd = request.getRequestDispatcher(Controllers.BASIC_JSP);
try {
rd.forward(request,response);
} catch (Throwable t) {
t.printStackTrace();
}
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) {
doGet(request,response);
}
}

View file

@ -8,7 +8,6 @@ import java.util.List;
import edu.cornell.mannlib.vedit.beans.Option; import edu.cornell.mannlib.vedit.beans.Option;
import edu.cornell.mannlib.vitro.webapp.beans.ResourceBean; import edu.cornell.mannlib.vitro.webapp.beans.ResourceBean;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean;
import edu.cornell.mannlib.vitro.webapp.filters.VitroRequestPrep;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -44,7 +43,6 @@ public class RoleLevelOptionsSetup {
} }
public static List<Option> getUpdateOptionsList(ResourceBean b) { public static List<Option> getUpdateOptionsList(ResourceBean b) {
// if make changes here, make sure to change SelfEditingPolicySetup and CuratorEditingPolicySetup
List<Option> prohibitedFromUpdateList = new LinkedList<Option>(); List<Option> prohibitedFromUpdateList = new LinkedList<Option>();
try { try {
BaseResourceBean.RoleLevel currentLevel = b.getProhibitedFromUpdateBelowRoleLevel(); BaseResourceBean.RoleLevel currentLevel = b.getProhibitedFromUpdateBelowRoleLevel();

View file

@ -10,10 +10,10 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.controller.ContactMailServlet;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
/** /**
* Controller for comments ("contact us") page * Controller for comments ("contact us") page
@ -40,10 +40,10 @@ public class ContactFormController extends FreemarkerHttpServlet {
String templateName; String templateName;
Map<String, Object> body = new HashMap<String, Object>(); Map<String, Object> body = new HashMap<String, Object>();
if (!ContactMailServlet.isSmtpHostConfigured(vreq)) { if (!FreemarkerEmailFactory.isConfigured(vreq)) {
body.put("errorMessage", body.put("errorMessage",
"This application has not yet been configured to send mail. " + "This application has not yet been configured to send mail. " +
"An smtp host has not been specified in the configuration properties file."); "Email properties must be specified in the configuration properties file.");
templateName = TEMPLATE_ERROR; templateName = TEMPLATE_ERROR;
} }

View file

@ -10,7 +10,6 @@ import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import javax.mail.Message; import javax.mail.Message;
import javax.mail.MessagingException; import javax.mail.MessagingException;
@ -26,12 +25,11 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.ContactMailServlet;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper.TemplateProcessingException; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper.TemplateProcessingException;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
import freemarker.template.Configuration; import freemarker.template.Configuration;
public class ContactMailController extends FreemarkerHttpServlet { public class ContactMailController extends FreemarkerHttpServlet {
@ -51,19 +49,6 @@ public class ContactMailController extends FreemarkerHttpServlet {
private final static String TEMPLATE_BACKUP = "contactForm-backup.ftl"; private final static String TEMPLATE_BACKUP = "contactForm-backup.ftl";
private final static String TEMPLATE_ERROR = "contactForm-error.ftl"; private final static String TEMPLATE_ERROR = "contactForm-error.ftl";
private static String smtpHost = "";
@Override
public void init() {
smtpHost = ConfigurationProperties.getBean(getServletContext())
.getProperty(ContactMailServlet.SMTPHOST_PROPERTY, "");
if (smtpHost.isEmpty()) {
log.debug("No Vitro.smtpHost specified");
} else {
log.debug("Found Vitro.smtpHost value of " + smtpHost);
}
}
@Override @Override
protected String getTitle(String siteName, VitroRequest vreq) { protected String getTitle(String siteName, VitroRequest vreq) {
return siteName + " Feedback Form"; return siteName + " Feedback Form";
@ -71,154 +56,116 @@ public class ContactMailController extends FreemarkerHttpServlet {
@Override @Override
protected ResponseValues processRequest(VitroRequest vreq) { protected ResponseValues processRequest(VitroRequest vreq) {
if (!FreemarkerEmailFactory.isConfigured(vreq)) {
return errorNoSmtpServer();
}
String templateName = null; String[] recipients = figureRecipients(vreq);
Map<String, Object> body = new HashMap<String, Object>(); if (recipients.length == 0) {
return errorNoRecipients();
}
ApplicationBean appBean = vreq.getAppBean(); String webusername = nonNullAndTrim(vreq, WEB_USERNAME_PARAM);
String webuseremail = nonNullAndTrim(vreq, WEB_USEREMAIL_PARAM);
String comments = nonNullAndTrim(vreq, COMMENTS_PARAM);
String formType = nonNullAndTrim(vreq, "DeliveryType");
String statusMsg = null; // holds the error status if (validateInput(webusername, webuseremail, comments) != null) {
return errorParametersNotValid();
}
if (smtpHost.isEmpty()) { String spamReason = checkForSpam(comments, formType);
body.put("errorMessage", if (spamReason != null) {
"This application has not yet been configured to send mail. " + return errorSpam();
"An smtp host has not been specified in the configuration properties file."); }
templateName = TEMPLATE_ERROR;
}
else { return processValidRequest(vreq, webusername, webuseremail, recipients, comments);
}
String webusername = vreq.getParameter(WEB_USERNAME_PARAM); private String[] figureRecipients(VitroRequest vreq) {
String webuseremail = vreq.getParameter(WEB_USEREMAIL_PARAM); String contactMailAddresses = vreq.getAppBean().getContactMail().trim();
String comments = vreq.getParameter(COMMENTS_PARAM); if ((contactMailAddresses == null) || contactMailAddresses.isEmpty()) {
return new String[0];
}
String validationMessage = validateInput(webusername, webuseremail, return contactMailAddresses.split(",");
comments); }
if (validationMessage != null) { private ResponseValues processValidRequest(VitroRequest vreq,
// rjy7 We should reload the form, not go to the error page! String webusername, String webuseremail, String[] recipients,
body.put("errorMessage", String comments) throws Error {
"Invalid submission"); String statusMsg = null; // holds the error status
templateName = TEMPLATE_ERROR;
}
else { ApplicationBean appBean = vreq.getAppBean();
webusername = webusername.trim(); String deliveryfrom = "Message from the " + appBean.getApplicationName() + " Contact Form";
webuseremail = webuseremail.trim();
comments = comments.trim();
String spamReason = null; String originalReferer = getOriginalRefererFromSession(vreq);
String originalReferer = (String) vreq.getSession().getAttribute("contactFormReferer"); Configuration config = (Configuration) vreq.getAttribute("freemarkerConfig");
if (originalReferer != null) { String msgText = composeEmail(webusername, webuseremail, comments,
vreq.getSession().removeAttribute("contactFormReferer"); deliveryfrom, originalReferer, vreq.getRemoteAddr(), config, vreq);
/* does not support legitimate clients that don't send the Referer header
String referer = request.getHeader("Referer");
if (referer == null ||
(referer.indexOf("comments") <0
&& referer.indexOf("correction") <0) ) {
spamReason = "The form was not submitted from the " +
"Contact Us or Corrections page.";
statusMsg = SPAM_MESSAGE;
}
*/
} else {
originalReferer = "none";
}
if (spamReason == null) { try {
spamReason = checkForSpam(comments); // Write the email to a backup file
if (spamReason != null) { FileWriter fw = new FileWriter(getServletContext().getRealPath(EMAIL_BACKUP_FILE_PATH),true);
statusMsg = SPAM_MESSAGE; PrintWriter outFile = new PrintWriter(fw);
} writeBackupCopy(outFile, msgText, config, vreq);
}
String formType = vreq.getParameter("DeliveryType"); Session s = FreemarkerEmailFactory.getEmailSession(vreq);
String[] deliverToArray = null;
int recipientCount = 0;
String deliveryfrom = null;
if ("contact".equals(formType)) { try {
if (appBean.getContactMail() == null || appBean.getContactMail().trim().length()==0) { sendMessage(s, webuseremail, webusername, recipients, deliveryfrom, msgText);
log.error("No contact mail address defined"); } catch (AddressException e) {
throw new Error( statusMsg = "Please supply a valid email address.";
"To establish the Contact Us mail capability the system administrators must " outFile.println( statusMsg );
+ "specify an email address."); outFile.println( e.getMessage() );
} else { } catch (SendFailedException e) {
deliverToArray = appBean.getContactMail().split(","); statusMsg = "The system was unable to deliver your mail. Please try again later. [SEND FAILED]";
} outFile.println( statusMsg );
deliveryfrom = "Message from the " + appBean.getApplicationName() + " Contact Form"; outFile.println( e.getMessage() );
} else { } catch (MessagingException e) {
deliverToArray = appBean.getContactMail().split(","); statusMsg = "The system was unable to deliver your mail. Please try again later. [MESSAGING]";
statusMsg = SPAM_MESSAGE ; outFile.println( statusMsg );
spamReason = "The form specifies no delivery type."; outFile.println( e.getMessage() );
} e.printStackTrace();
recipientCount=(deliverToArray == null) ? 0 : deliverToArray.length; }
if (recipientCount == 0) {
log.error("recipientCount is 0 when DeliveryType specified as \""+formType+"\"");
throw new Error(
"To establish the Contact Us mail capability the system administrators must "
+ "specify at least one email address.");
}
Configuration config = (Configuration) vreq.getAttribute("freemarkerConfig"); outFile.close();
String msgText = composeEmail(webusername, webuseremail, comments, }
deliveryfrom, originalReferer, vreq.getRemoteAddr(), config, vreq); catch (IOException e){
log.error("Can't open file to write email backup");
}
// Write the email to a backup file if (statusMsg == null) {
try { // Message was sent successfully
FileWriter fw = new FileWriter(getServletContext().getRealPath(EMAIL_BACKUP_FILE_PATH),true); return new TemplateResponseValues(TEMPLATE_CONFIRMATION);
PrintWriter outFile = new PrintWriter(fw); } else {
writeBackupCopy(outFile, msgText, spamReason, config, vreq); Map<String, Object> body = new HashMap<String, Object>();
body.put("errorMessage", statusMsg);
return new TemplateResponseValues(TEMPLATE_ERROR, body);
}
}
// Set the smtp host private String getOriginalRefererFromSession(VitroRequest vreq) {
Properties props = System.getProperties(); String originalReferer = (String) vreq.getSession().getAttribute("contactFormReferer");
props.put("mail.smtp.host", smtpHost); if (originalReferer != null) {
Session s = Session.getDefaultInstance(props,null); // was Session.getInstance(props,null); vreq.getSession().removeAttribute("contactFormReferer");
//s.setDebug(true); /* does not support legitimate clients that don't send the Referer header
try { String referer = request.getHeader("Referer");
if (referer == null ||
if (spamReason == null) { (referer.indexOf("comments") <0
sendMessage(s, webuseremail, webusername, deliverToArray, deliveryfrom, && referer.indexOf("correction") <0) ) {
recipientCount, msgText); spamReason = "The form was not submitted from the " +
} "Contact Us or Corrections page.";
statusMsg = SPAM_MESSAGE;
} catch (AddressException e) { }
statusMsg = "Please supply a valid email address."; */
outFile.println( statusMsg ); } else {
outFile.println( e.getMessage() ); originalReferer = "none";
} catch (SendFailedException e) { }
statusMsg = "The system was unable to deliver your mail. Please try again later. [SEND FAILED]"; return originalReferer;
outFile.println( statusMsg ); }
outFile.println( e.getMessage() );
} catch (MessagingException e) {
statusMsg = "The system was unable to deliver your mail. Please try again later. [MESSAGING]";
outFile.println( statusMsg );
outFile.println( e.getMessage() );
e.printStackTrace();
}
outFile.flush();
outFile.close();
}
catch (IOException e){
log.error("Can't open file to write email backup");
}
// Message was sent successfully
if (statusMsg == null && spamReason == null) {
templateName = TEMPLATE_CONFIRMATION;
} else {
body.put("errorMessage", statusMsg);
templateName = TEMPLATE_ERROR;
}
}
}
return new TemplateResponseValues(templateName, body);
}
/** Intended to mangle url so it can get through spam filtering /** Intended to mangle url so it can get through spam filtering
* http://host/dir/servlet?param=value -> host: dir/servlet?param=value */ * http://host/dir/servlet?param=value -> host: dir/servlet?param=value */
@ -255,18 +202,13 @@ public class ContactMailController extends FreemarkerHttpServlet {
} }
private void writeBackupCopy(PrintWriter outFile, String msgText, private void writeBackupCopy(PrintWriter outFile, String msgText,
String spamReason, Configuration config, HttpServletRequest request) { Configuration config, HttpServletRequest request) {
Map<String, Object> backup = new HashMap<String, Object>(); Map<String, Object> backup = new HashMap<String, Object>();
String template = TEMPLATE_BACKUP; String template = TEMPLATE_BACKUP;
Calendar cal = Calendar.getInstance(); Calendar cal = Calendar.getInstance();
backup.put("datetime", cal.getTime().toString()); backup.put("datetime", cal.getTime().toString());
if (spamReason != null) {
backup.put("spamReason", spamReason);
}
backup.put("msgText", msgText); backup.put("msgText", msgText);
try { try {
@ -280,8 +222,7 @@ public class ContactMailController extends FreemarkerHttpServlet {
} }
private void sendMessage(Session s, String webuseremail, String webusername, private void sendMessage(Session s, String webuseremail, String webusername,
String[] deliverToArray, String deliveryfrom, int recipientCount, String[] recipients, String deliveryfrom, String msgText)
String msgText)
throws AddressException, SendFailedException, MessagingException { throws AddressException, SendFailedException, MessagingException {
// Construct the message // Construct the message
MimeMessage msg = new MimeMessage( s ); MimeMessage msg = new MimeMessage( s );
@ -297,14 +238,11 @@ public class ContactMailController extends FreemarkerHttpServlet {
} }
// Set the recipient address // Set the recipient address
InternetAddress[] address=new InternetAddress[recipients.length];
if (recipientCount>0){ for (int i=0; i<recipients.length; i++){
InternetAddress[] address=new InternetAddress[recipientCount]; address[i] = new InternetAddress(recipients[i]);
for (int i=0; i<recipientCount; i++){
address[i] = new InternetAddress(deliverToArray[i]);
}
msg.setRecipients( Message.RecipientType.TO, address );
} }
msg.setRecipients( Message.RecipientType.TO, address );
// Set the subject and text // Set the subject and text
msg.setSubject( deliveryfrom ); msg.setSubject( deliveryfrom );
@ -319,18 +257,23 @@ public class ContactMailController extends FreemarkerHttpServlet {
} }
private String nonNullAndTrim(HttpServletRequest req, String key) {
String value = req.getParameter(key);
return (value == null) ? "" : value.trim();
}
private String validateInput(String webusername, String webuseremail, private String validateInput(String webusername, String webuseremail,
String comments) { String comments) {
if( webusername == null || "".equals(webusername.trim()) ){ if( webusername.isEmpty() ){
return "A proper webusername field was not found in the form submitted."; return "A proper webusername field was not found in the form submitted.";
} }
if( webuseremail == null || "".equals(webuseremail.trim()) ){ if( webuseremail.isEmpty() ){
return "A proper webuser email field was not found in the form submitted."; return "A proper webuser email field was not found in the form submitted.";
} }
if (comments==null || "".equals(comments.trim())) { if (comments.isEmpty()) {
return "The proper comments field was not found in the form submitted."; return "The proper comments field was not found in the form submitted.";
} }
@ -338,11 +281,14 @@ public class ContactMailController extends FreemarkerHttpServlet {
} }
/** /**
* @param request
* @return null if message not judged to be spam, otherwise a String * @return null if message not judged to be spam, otherwise a String
* containing the reason the message was flagged as spam. * containing the reason the message was flagged as spam.
*/ */
private String checkForSpam(String comments) { private String checkForSpam(String comments, String formType) {
/* If the form doesn't specify a delivery type, treat as spam. */
if (!"contact".equals(formType)) {
return "The form specifies no delivery type.";
}
/* if this blog markup is found, treat comment as blog spam */ /* if this blog markup is found, treat comment as blog spam */
if ( if (
@ -361,4 +307,34 @@ public class ContactMailController extends FreemarkerHttpServlet {
return null; return null;
} }
private ResponseValues errorNoSmtpServer() {
Map<String, Object> body = new HashMap<String, Object>();
body.put("errorMessage",
"This application has not yet been configured to send mail. " +
"Email properties must be specified in the configuration properties file.");
return new TemplateResponseValues(TEMPLATE_ERROR, body);
}
private ResponseValues errorNoRecipients() {
Map<String, Object> body = new HashMap<String, Object>();
body.put("errorMessage", "To establish the Contact Us mail capability "
+ "the system administrators must specify "
+ "at least one email address.");
return new TemplateResponseValues(TEMPLATE_ERROR, body);
}
private ResponseValues errorParametersNotValid() {
// rjy7 We should reload the form, not go to the error page!
Map<String, Object> body = new HashMap<String, Object>();
body.put("errorMessage", "Invalid submission");
return new TemplateResponseValues(TEMPLATE_ERROR, body);
}
private ResponseValues errorSpam() {
Map<String, Object> body = new HashMap<String, Object>();
body.put("errorMessage", SPAM_MESSAGE);
return new TemplateResponseValues(TEMPLATE_ERROR, body);
}
} }

View file

@ -22,7 +22,6 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage; import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
import edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean; import edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean;
import edu.cornell.mannlib.vitro.webapp.controller.ContactMailServlet;
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet; import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper.TemplateProcessingException; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper.TemplateProcessingException;
@ -33,6 +32,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Rdf
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.RedirectResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.RedirectResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.Tags; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.Tags;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.User; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.User;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.MainMenu; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.MainMenu;
@ -247,13 +247,14 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
urls.put("base", UrlBuilder.contextPath); urls.put("base", UrlBuilder.contextPath);
urls.put("about", urlBuilder.getPortalUrl(Route.ABOUT)); urls.put("about", urlBuilder.getPortalUrl(Route.ABOUT));
if (ContactMailServlet.isSmtpHostConfigured(vreq)) { if (FreemarkerEmailFactory.isConfigured(vreq)) {
urls.put("contact", urlBuilder.getPortalUrl(Route.CONTACT)); urls.put("contact", urlBuilder.getPortalUrl(Route.CONTACT));
} }
urls.put("search", urlBuilder.getPortalUrl(Route.SEARCH)); urls.put("search", urlBuilder.getPortalUrl(Route.SEARCH));
urls.put("termsOfUse", urlBuilder.getPortalUrl(Route.TERMS_OF_USE)); urls.put("termsOfUse", urlBuilder.getPortalUrl(Route.TERMS_OF_USE));
urls.put("login", urlBuilder.getLoginUrl()); urls.put("login", urlBuilder.getLoginUrl());
urls.put("logout", urlBuilder.getLogoutUrl()); urls.put("logout", urlBuilder.getLogoutUrl());
urls.put("myAccount", UrlBuilder.getUrl("/accounts/myAccount"));
urls.put("siteAdmin", urlBuilder.getPortalUrl(Route.SITE_ADMIN)); urls.put("siteAdmin", urlBuilder.getPortalUrl(Route.SITE_ADMIN));
urls.put("themeImages", urlBuilder.getPortalUrl(themeDir + "/images")); urls.put("themeImages", urlBuilder.getPortalUrl(themeDir + "/images"));
urls.put("images", UrlBuilder.getUrl("/images")); urls.put("images", UrlBuilder.getUrl("/images"));

View file

@ -41,6 +41,7 @@ public class HomePageController extends FreemarkerHttpServlet {
if(pageData != null) if(pageData != null)
body.putAll(pageData); body.putAll(pageData);
} }
body.put("dataServiceUrlVClassesForVClassGroup", UrlBuilder.getUrl("/dataservice?getVClassesForVClassGroup=1&classgroupUri="));
return new TemplateResponseValues(BODY_TEMPLATE, body); return new TemplateResponseValues(BODY_TEMPLATE, body);
} }

View file

@ -56,6 +56,7 @@ import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
import edu.cornell.mannlib.vitro.webapp.reasoner.SimpleReasoner; import edu.cornell.mannlib.vitro.webapp.reasoner.SimpleReasoner;
import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapper; import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapper;
import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapperFactory; import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapperFactory;
import edu.cornell.mannlib.vitro.webapp.utils.jena.ExtendedLinkedDataUtils;
import edu.cornell.mannlib.vitro.webapp.web.ContentType; import edu.cornell.mannlib.vitro.webapp.web.ContentType;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.IndividualTemplateModel; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.IndividualTemplateModel;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ListedIndividualTemplateModel; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ListedIndividualTemplateModel;
@ -72,6 +73,9 @@ public class IndividualController extends FreemarkerHttpServlet {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(IndividualController.class); private static final Log log = LogFactory.getLog(IndividualController.class);
private static final String RICH_EXPORT_ROOT = "/WEB-INF/rich-export/";
private static final String PERSON_CLASS_URI = "http://xmlns.com/foaf/0.1/Person";
private static final String INCLUDE_ALL = "all";
private static final Map<String, String> namespaces = new HashMap<String, String>() {{ private static final Map<String, String> namespaces = new HashMap<String, String>() {{
put("vitro", VitroVocabulary.vitroURI); put("vitro", VitroVocabulary.vitroURI);
@ -337,7 +341,9 @@ public class IndividualController extends FreemarkerHttpServlet {
if( ontModel == null) if( ontModel == null)
ontModel = (OntModel)getServletContext().getAttribute("jenaOntModel"); ontModel = (OntModel)getServletContext().getAttribute("jenaOntModel");
Model newModel = getRDF(individual, ontModel, ModelFactory.createDefaultModel(),0);
String[] includes = vreq.getParameterValues("include");
Model newModel = getRDF(individual,ontModel,ModelFactory.createDefaultModel(),0,includes);
return new RdfResponseValues(rdfFormat, newModel); return new RdfResponseValues(rdfFormat, newModel);
} }
@ -449,8 +455,10 @@ public class IndividualController extends FreemarkerHttpServlet {
netIdStr = vreq.getParameter("netid"); netIdStr = vreq.getParameter("netid");
if ( netIdStr != null ){ if ( netIdStr != null ){
SelfEditingConfiguration sec = SelfEditingConfiguration.getBean(vreq); SelfEditingConfiguration sec = SelfEditingConfiguration.getBean(vreq);
uri = sec.getIndividualUriFromUsername(iwDao, netIdStr); List<Individual> assocInds = sec.getAssociatedIndividuals(iwDao, netIdStr);
return iwDao.getIndividualByURI(uri); if (!assocInds.isEmpty()) {
return assocInds.get(0);
}
} }
return null; return null;
@ -597,7 +605,7 @@ public class IndividualController extends FreemarkerHttpServlet {
return "enabled".equals(property); return "enabled".equals(property);
} }
private Model getRDF(Individual entity, OntModel contextModel, Model newModel, int recurseDepth) { private Model getRDF(Individual entity, OntModel contextModel, Model newModel, int recurseDepth, String[] includes) {
Resource subj = newModel.getResource(entity.getURI()); Resource subj = newModel.getResource(entity.getURI());
@ -625,7 +633,7 @@ public class IndividualController extends FreemarkerHttpServlet {
Resource obj = newModel.getResource(os.getObjectURI()); Resource obj = newModel.getResource(os.getObjectURI());
newModel.add(newModel.createStatement(subj, prop, obj)); newModel.add(newModel.createStatement(subj, prop, obj));
if ( includeInLinkedData(obj, contextModel)) { if ( includeInLinkedData(obj, contextModel)) {
newModel.add(getRDF(os.getObject(), contextModel, newModel, recurseDepth + 1)); newModel.add(getRDF(os.getObject(), contextModel, newModel, recurseDepth + 1, includes));
} else { } else {
contextModel.enterCriticalSection(Lock.READ); contextModel.enterCriticalSection(Lock.READ);
try { try {
@ -640,7 +648,7 @@ public class IndividualController extends FreemarkerHttpServlet {
newModel = getLabelAndTypes(entity, contextModel, newModel ); newModel = getLabelAndTypes(entity, contextModel, newModel );
// get all the statements not covered by the object property / datatype property code above // get all the statements not covered by the object property / datatype property code above
// note implication that extendedLinkedData individuals will only be evaulated for the // note implication that extendedLinkedData individuals will only be evaluated for the
// recognized object properties. // recognized object properties.
contextModel.enterCriticalSection(Lock.READ); contextModel.enterCriticalSection(Lock.READ);
try { try {
@ -655,6 +663,26 @@ public class IndividualController extends FreemarkerHttpServlet {
contextModel.leaveCriticalSection(); contextModel.leaveCriticalSection();
} }
if (recurseDepth == 0 && includes != null && entity.isVClass(PERSON_CLASS_URI)) {
for (String include : includes) {
String rootDir = null;
if (INCLUDE_ALL.equals(include)) {
rootDir = RICH_EXPORT_ROOT;
} else {
rootDir = RICH_EXPORT_ROOT + include + "/";
}
long start = System.currentTimeMillis();
Model extendedModel = ExtendedLinkedDataUtils.createModelFromQueries(getServletContext(), rootDir, contextModel, entity.getURI());
long elapsedTimeMillis = System.currentTimeMillis()-start;
log.info("Time to create rich export model: msecs = " + elapsedTimeMillis);
newModel.add(extendedModel);
}
}
return newModel; return newModel;
} }

View file

@ -62,7 +62,6 @@ public class IndividualListController extends FreemarkerHttpServlet {
String templateName = TEMPLATE_DEFAULT; String templateName = TEMPLATE_DEFAULT;
Map<String, Object> body = new HashMap<String, Object>(); Map<String, Object> body = new HashMap<String, Object>();
String errorMessage = null; String errorMessage = null;
String message = null;
try { try {
Object obj = vreq.getAttribute("vclass"); Object obj = vreq.getAttribute("vclass");
@ -125,8 +124,8 @@ public class IndividualListController extends FreemarkerHttpServlet {
body.put("subtitle", vclass.getName()); body.put("subtitle", vclass.getName());
} }
body.put("title", title); body.put("title", title);
body.put("rdfUrl", vreq.getContextPath()+"/listrdf/"); body.put("rdfUrl", UrlBuilder.getUrl("/listrdf", "vclass", vclass.getURI()));
getServletContext().setAttribute("classuri", vclass.getURI());
} }
} catch (HelpException help){ } catch (HelpException help){
@ -138,8 +137,6 @@ public class IndividualListController extends FreemarkerHttpServlet {
if (errorMessage != null) { if (errorMessage != null) {
templateName = Template.ERROR_MESSAGE.toString(); templateName = Template.ERROR_MESSAGE.toString();
body.put("errorMessage", errorMessage); body.put("errorMessage", errorMessage);
} else if (message != null) {
body.put("message", message);
} }
return new TemplateResponseValues(templateName, body); return new TemplateResponseValues(templateName, body);
@ -177,10 +174,29 @@ public class IndividualListController extends FreemarkerHttpServlet {
*/ */
public static Map<String,Object> getResultsForVClass(String vclassURI, int page, String alpha, IndividualDao indDao, ServletContext context) public static Map<String,Object> getResultsForVClass(String vclassURI, int page, String alpha, IndividualDao indDao, ServletContext context)
throws CorruptIndexException, IOException, ServletException{ throws CorruptIndexException, IOException, ServletException{
Map<String,Object> rvMap = new HashMap<String,Object>(); Map<String,Object> rvMap = new HashMap<String,Object>();
try{
//make lucene query for this rdf:type
List<String> classUris = new ArrayList<String>();
classUris.add(vclassURI);
Query query = getQuery(classUris, alpha);
rvMap = getResultsForVClassQuery(query, page, alpha, indDao, context);
List<Individual> individuals = (List<Individual>) rvMap.get("entities");
if (individuals == null)
log.debug("entities list is null for vclass " + vclassURI );
} catch(Throwable th) {
log.error("An error occurred retrieving results for vclass query", th);
}
return rvMap;
}
//make lucene query for this rdf:type /*
Query query = getQuery(vclassURI, alpha); * This method includes what was formerly a part of the method above, allowing for refactoring of code
* to use for a different number fo classes
*/
public static Map<String,Object> getResultsForVClassQuery(Query query, int page, String alpha, IndividualDao indDao, ServletContext context)
throws CorruptIndexException, IOException, ServletException{
Map<String,Object> rvMap = new HashMap<String,Object>();
//execute lucene query for individuals of the specified type //execute lucene query for individuals of the specified type
IndexSearcher index = LuceneIndexFactory.getIndexSearcher(context); IndexSearcher index = LuceneIndexFactory.getIndexSearcher(context);
@ -240,20 +256,43 @@ public class IndividualListController extends FreemarkerHttpServlet {
rvMap.put("totalCount", size); rvMap.put("totalCount", size);
rvMap.put("entities",individuals); rvMap.put("entities",individuals);
if (individuals == null)
log.debug("entities list is null for vclass " + vclassURI );
return rvMap; return rvMap;
} }
private static BooleanQuery getQuery(String vclassUri, String alpha){
public static Map<String,Object> getResultsForVClassIntersections(List<String> vclassURIs, int page, String alpha, IndividualDao indDao, ServletContext context)
throws CorruptIndexException, IOException, ServletException{
Map<String,Object> rvMap = new HashMap<String,Object>();
try{
//make lucene query for multiple rdf types
Query query = getQuery(vclassURIs, alpha);
//get results corresponding to this query
rvMap = getResultsForVClassQuery(query, page, alpha, indDao, context);
List<Individual> individuals = (List<Individual>) rvMap.get("entities");
if (individuals == null)
log.debug("entities list is null for vclass " + vclassURIs.toString() );
} catch(Throwable th) {
log.error("Error retrieving individuals corresponding to intersection multiple classes." + vclassURIs.toString());
}
return rvMap;
}
/*
* This method creates a query to search for terms with rdf type corresponding to vclass Uri.
* The original version allowed only for one class URI but needed to be extended to enable multiple
* vclass Uris to be passed
*/
private static BooleanQuery getQuery(List<String>vclassUris, String alpha){
BooleanQuery query = new BooleanQuery(); BooleanQuery query = new BooleanQuery();
try{ try{
//query term for rdf:type //query term for rdf:type - multiple types possible
query.add( for(String vclassUri: vclassUris) {
new TermQuery( new Term(Entity2LuceneDoc.term.RDFTYPE, vclassUri)), query.add(
BooleanClause.Occur.MUST ); new TermQuery( new Term(Entity2LuceneDoc.term.RDFTYPE, vclassUri)),
BooleanClause.Occur.MUST );
}
//Add alpha filter if it is needed //Add alpha filter if it is needed
Query alphaQuery = null; Query alphaQuery = null;
if( alpha != null && !"".equals(alpha) && alpha.length() == 1){ if( alpha != null && !"".equals(alpha) && alpha.length() == 1){

View file

@ -23,7 +23,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Tem
import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.BrowseDataGetter; import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.BrowseDataGetter;
import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.PageDataGetter; import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.PageDataGetter;
import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.ClassGroupPageData; import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.ClassGroupPageData;
import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.ClassIntersectionDataGetter;
/** /**
* Controller for getting data for pages defined in the display model. * Controller for getting data for pages defined in the display model.
* *
@ -56,6 +56,7 @@ public class PageController extends FreemarkerHttpServlet{
if( page.containsKey("title") ){ if( page.containsKey("title") ){
mapForTemplate.put("title", page.get("title")); mapForTemplate.put("title", page.get("title"));
} }
mapForTemplate.put("dataServiceUrlIndividualsByVClass", UrlBuilder.getUrl("/dataservice?getSolrIndividualsByVClass=1&vclassId="));
} catch (Throwable th) { } catch (Throwable th) {
return doNotFound(vreq); return doNotFound(vreq);
} }
@ -111,7 +112,10 @@ public class PageController extends FreemarkerHttpServlet{
return Collections.emptyMap(); return Collections.emptyMap();
PageDataGetter getter = getPageDataGetterMap(getServletContext()).get(type); PageDataGetter getter = getPageDataGetterMap(getServletContext()).get(type);
//For now hardcoding, check to see if data getter included within
if((String)page.get("datagetter") != null) {
getter = new ClassIntersectionDataGetter();
}
if( getter != null ){ if( getter != null ){
try{ try{
return getter.getData(getServletContext(), vreq, pageUri, page, type); return getter.getData(getServletContext(), vreq, pageUri, page, type);
@ -176,6 +180,12 @@ public class PageController extends FreemarkerHttpServlet{
getPageDataGetterMap(context).put(cgpd.getType(), cgpd); getPageDataGetterMap(context).put(cgpd.getType(), cgpd);
BrowseDataGetter bdg = new BrowseDataGetter(); BrowseDataGetter bdg = new BrowseDataGetter();
getPageDataGetterMap(context).put(bdg.getType(), bdg); getPageDataGetterMap(context).put(bdg.getType(), bdg);
//TODO: Check if can include by type here
ClassIntersectionDataGetter cidg = new ClassIntersectionDataGetter();
getPageDataGetterMap(context).put(cidg.getType(), cidg);
} }
} }
} }

View file

@ -1,130 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.sdb.Store;
import com.hp.hpl.jena.sdb.StoreDesc;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.UseMiscellaneousAdminPages;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ExceptionResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupSDB;
public class SDBSetupController extends FreemarkerHttpServlet {
private static final Log log = LogFactory.getLog(
SDBSetupController.class);
private static final String SDB_SETUP_FTL = "sdbSetup.ftl";
@Override
protected Actions requiredActions(VitroRequest vreq) {
return new Actions(new UseMiscellaneousAdminPages());
}
protected ResponseValues processRequest(VitroRequest vreq) {
Map<String, Object> body = new HashMap<String, Object>();
String messageStr = "";
try {
JenaDataSourceSetupSDB jenaDataSourceSetupSDB = new JenaDataSourceSetupSDB();
Boolean done = (Boolean)getServletContext().getAttribute("done");
String setupsignal = (String) vreq.getParameter("setupsignal");
if (done!=null && done) {
messageStr = "SDB is currently being set up.";
} else{
String sdbsetup = (String)getServletContext().getAttribute("sdbsetup");
if(sdbsetup == null || sdbsetup.equals("showButton") || setupsignal == null){
body.put("link", "show");
messageStr = null;
getServletContext().setAttribute("sdbsetup", "yes");
if(getServletContext().getAttribute("sdbstatus")!=null)
body.put("sdbstatus",getServletContext().getAttribute("sdbstatus"));
else
body.put("sdbstatus"," ");
}
else if(setupsignal!=null && setupsignal.equals("setup")){
new Thread(new SDBSetupRunner(jenaDataSourceSetupSDB, vreq)).start();
messageStr = "SDB setup started.";
getServletContext().setAttribute("sdbsetup", "showButton");
}
}
} catch (Exception e) {
log.error("Error setting up SDB store", e);
body.put("errorMessage",
"Error setting up SDB store: " +
e.getMessage());
return new ExceptionResponseValues(
SDB_SETUP_FTL, body, e);
}
body.put("message", messageStr);
return new TemplateResponseValues(SDB_SETUP_FTL, body);
}
private class SDBSetupRunner implements Runnable {
private JenaDataSourceSetupSDB jenaDataSourceSetupSDB;
final OntModelSpec MEM_ONT_MODEL_SPEC = OntModelSpec.OWL_MEM;
private final ServletContext ctx;
public SDBSetupRunner(JenaDataSourceSetupSDB jenaDataSourceSetupSDB, HttpServletRequest req) {
this.jenaDataSourceSetupSDB = jenaDataSourceSetupSDB;
this.ctx = req.getSession().getServletContext();
}
@Override
public void run() {
Boolean done = true;
getServletContext().setAttribute("done",done);
StoreDesc storeDesc = jenaDataSourceSetupSDB.makeStoreDesc(ctx);
BasicDataSource bds = jenaDataSourceSetupSDB.makeDataSourceFromConfigurationProperties(getServletContext());
Store store = null;
try {
store = JenaDataSourceSetupSDB.connectStore(bds, storeDesc);
} catch (SQLException e) {
log.error("Error while getting the sdb store with given store description and basic data source", e);
}
OntModel memModel = (OntModel)getServletContext().getAttribute("jenaOntModel");
if (memModel == null) {
memModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC);
log.warn("WARNING: no database connected. Changes will disappear after context restart.");
}
OntModel inferenceModel = (OntModel)getServletContext().getAttribute("inferenceOntModel");
if(inferenceModel == null){
inferenceModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC);
}
if (store!=null) {
log.info("Setting up SDB store.");
try{
jenaDataSourceSetupSDB.setupSDB(getServletContext(), store, memModel, inferenceModel);
getServletContext().setAttribute("sdbstatus","SDB setup done successfully");
}
catch(Exception e){
getServletContext().setAttribute("sdbstatus",e.getMessage());
}
log.info("SDB setup complete.");
}
done = false;
getServletContext().setAttribute("done",done);
}
}
}

View file

@ -24,7 +24,6 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.SeeSiteAdm
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.UseAdvancedDataToolsPages; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.UseAdvancedDataToolsPages;
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.edit.listing.UsersListingController;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
@ -119,12 +118,8 @@ public class SiteAdminController extends FreemarkerHttpServlet {
Map<String, Object> map = new HashMap<String, Object>(); Map<String, Object> map = new HashMap<String, Object>();
Map<String, String> urls = new HashMap<String, String>(); Map<String, String> urls = new HashMap<String, String>();
// TODO remove this when the UserAccounts are fully implemented. -- jblake
if (PolicyHelper.isAuthorizedForActions(vreq, UsersListingController.REQUIRED_ACTIONS)) {
urls.put("users", urlBuilder.getPortalUrl("/listUsers"));
}
if (PolicyHelper.isAuthorizedForActions(vreq, new ManageUserAccounts())) { if (PolicyHelper.isAuthorizedForActions(vreq, new ManageUserAccounts())) {
urls.put("userList", urlBuilder.getPortalUrl("/userAccounts")); urls.put("userList", urlBuilder.getPortalUrl("/accountsAdmin"));
} }
if (PolicyHelper.isAuthorizedForActions(vreq, new EditSiteInformation())) { if (PolicyHelper.isAuthorizedForActions(vreq, new EditSiteInformation())) {

View file

@ -120,8 +120,7 @@ public class SolrIndividualListController extends FreemarkerHttpServlet {
body.put("subtitle", vclass.getName()); body.put("subtitle", vclass.getName());
} }
body.put("title", title); body.put("title", title);
body.put("rdfUrl", vreq.getContextPath() + "/listrdf/" + vclass.getLocalName() + ".rdf"); body.put("rdfUrl", UrlBuilder.getUrl("/listrdf", "vclass", vclass.getURI()));
getServletContext().setAttribute("classuri", vclass.getURI());
} }
} catch (HelpException help){ } catch (HelpException help){

View file

@ -270,6 +270,12 @@ public class UrlBuilder {
public static String getPath(Route route, ParamMap params) { public static String getPath(Route route, ParamMap params) {
return getPath(route.path(), params); return getPath(route.path(), params);
} }
//Adding method to allow for checking for special parameters
public static String getIndividualProfileUrl(String individualUri, VitroRequest vreq) {
Individual individual = new IndividualImpl(individualUri);
return getIndividualProfileUrl(individual, individualUri, vreq);
}
public static String getIndividualProfileUrl(String individualUri, WebappDaoFactory wadf) { public static String getIndividualProfileUrl(String individualUri, WebappDaoFactory wadf) {
Individual individual = new IndividualImpl(individualUri); Individual individual = new IndividualImpl(individualUri);
@ -281,6 +287,19 @@ public class UrlBuilder {
return getIndividualProfileUrl(individual, individualUri, wadf); return getIndividualProfileUrl(individual, individualUri, wadf);
} }
//Trying first with using a form of the method that includes the vitro request
private static String getIndividualProfileUrl(Individual individual, String individualUri, VitroRequest vreq) {
WebappDaoFactory wadf = vreq.getWebappDaoFactory();
String profileUrl = getIndividualProfileUrl(individual, individualUri, wadf);
if(profileUrl != null) {
HashMap<String, String> specialParams = getSpecialParams(vreq);
if(specialParams.size() != 0) {
profileUrl = addParams(profileUrl, new ParamMap(specialParams));
}
}
return profileUrl;
}
private static String getIndividualProfileUrl(Individual individual, String individualUri, WebappDaoFactory wadf) { private static String getIndividualProfileUrl(Individual individual, String individualUri, WebappDaoFactory wadf) {
String profileUrl = null; String profileUrl = null;
try { try {
@ -346,4 +365,32 @@ public class UrlBuilder {
return decodedUrl; return decodedUrl;
} }
//To be used in different property templates so placing method for reuse here
//Check if special params included, specifically for menu management and other models
public static HashMap<String,String> getSpecialParams(VitroRequest vreq) {
HashMap<String,String> specialParams = new HashMap<String, String>();
if(vreq != null) {
//this parameter is sufficient to switch to menu model
String useMenuModelParam = vreq.getParameter("usemenumodel");
//the parameters below allow for using a different model
String useMainModelUri = vreq.getParameter("usemodel");
String useTboxModelUri = vreq.getParameter("usetboxmodel");
String useDisplayModelUri = vreq.getParameter("usedisplaymodel");
if(useMenuModelParam != null && !useMenuModelParam.isEmpty()) {
specialParams.put("usemenumodel", useMenuModelParam);
}
else if(useMainModelUri != null && !useMainModelUri.isEmpty()) {
specialParams.put("usemodel", useMainModelUri);
if(useTboxModelUri != null && !useTboxModelUri.isEmpty()){
specialParams.put("usetboxmodel", useTboxModelUri);
}
if(useDisplayModelUri != null && !useDisplayModelUri.isEmpty()) {
specialParams.put("usedisplaymodel", useDisplayModelUri);
}
}
}
return specialParams;
}
} }

View file

@ -93,7 +93,9 @@ public class JenaExportController extends BaseEditController {
Model model = null; Model model = null;
OntModel ontModel = ModelFactory.createOntologyModel(); OntModel ontModel = ModelFactory.createOntologyModel();
if(!subgraphParam.equalsIgnoreCase("tbox") && !subgraphParam.equalsIgnoreCase("abox") && !subgraphParam.equalsIgnoreCase("full")){ if(!subgraphParam.equalsIgnoreCase("tbox")
&& !subgraphParam.equalsIgnoreCase("abox")
&& !subgraphParam.equalsIgnoreCase("full")){
ontologyURI = subgraphParam; ontologyURI = subgraphParam;
subgraphParam = "tbox"; subgraphParam = "tbox";
char[] uri = ontologyURI.toCharArray(); char[] uri = ontologyURI.toCharArray();
@ -102,37 +104,19 @@ public class JenaExportController extends BaseEditController {
ontologyURI = ontologyURI + uri[i]; ontologyURI = ontologyURI + uri[i];
} }
String mode = (JenaDataSourceSetupBase.isSDBActive(vreq)) ? "SDB" : "RDB";
if( "abox".equals(subgraphParam)){ if( "abox".equals(subgraphParam)){
model = ModelFactory.createDefaultModel(); model = ModelFactory.createDefaultModel();
if("inferred".equals(assertedOrInferredParam)){ if("inferred".equals(assertedOrInferredParam)){
if(mode.equals("RDB")){ model = ModelContext.getInferenceOntModelSelector(
Dataset jenaDataset = DatasetFactory.create((OntModel)getServletContext().getAttribute("jenaOntModel")); getServletContext()).getABoxModel();
Dataset inferenceDataset = DatasetFactory.create((OntModel)getServletContext().getAttribute("inferenceOntModel"));
model = xutil.extractABox(jenaDataset,inferenceDataset,null);
}
else{
model = ModelContext.getInferenceOntModelSelector(getServletContext()).getABoxModel();
}
} }
else if("full".equals(assertedOrInferredParam)){ else if("full".equals(assertedOrInferredParam)){
if(mode.equals("RDB")){ model = ModelContext.getUnionOntModelSelector(
model = xutil.extractABox((OntModel)getServletContext().getAttribute("jenaOntModel")); getServletContext()).getABoxModel();
}
else{
model = ModelContext.getUnionOntModelSelector(getServletContext()).getABoxModel();
}
} }
else if("asserted".equals(assertedOrInferredParam)){ else if("asserted".equals(assertedOrInferredParam)){
if(mode.equals("RDB")){ model = ModelContext.getBaseOntModelSelector(
Dataset jenaDataset = DatasetFactory.create((OntModel)getServletContext().getAttribute("jenaOntModel")); getServletContext()).getABoxModel();
Dataset baseDataset = DatasetFactory.create((OntModel)getServletContext().getAttribute("baseOntModel"));
model = xutil.extractABox(jenaDataset,baseDataset,null);
}
else{
model = ModelContext.getBaseOntModelSelector(getServletContext()).getABoxModel();
}
} }
} }
else if("tbox".equals(subgraphParam)){ else if("tbox".equals(subgraphParam)){
@ -160,53 +144,35 @@ public class JenaExportController extends BaseEditController {
ModelContext.getBaseOntModelSelector( ModelContext.getBaseOntModelSelector(
getServletContext()).getTBoxModel(), ontologyURI); getServletContext()).getTBoxModel(), ontologyURI);
} }
// if("inferred".equals(assertedOrInferredParam)){
// model = xutil.extractTBox(dataset, ontologyURI,INFERENCE_GRAPH);
// }
// else if("full".equals(assertedOrInferredParam)){
// model = xutil.extractTBox(dataset, ontologyURI, FULL_GRAPH);
// }
// else{
// model = xutil.extractTBox(dataset, ontologyURI, ASSERTIONS_GRAPH);
// }
} }
else if("full".equals(subgraphParam)){ else if("full".equals(subgraphParam)){
if("inferred".equals(assertedOrInferredParam)){ if("inferred".equals(assertedOrInferredParam)){
ontModel = xutil.extractTBox(dataset, ontologyURI,INFERENCE_GRAPH); ontModel = xutil.extractTBox(
if(mode.equals("RDB")){ dataset, ontologyURI, INFERENCE_GRAPH);
Dataset jenaDataset = DatasetFactory.create((OntModel)getServletContext().getAttribute("jenaOntModel")); ontModel.addSubModel(ModelContext.getInferenceOntModelSelector(
Dataset inferenceDataset = DatasetFactory.create((OntModel)getServletContext().getAttribute("inferenceOntModel")); getServletContext()).getABoxModel());
ontModel.addSubModel(xutil.extractABox(jenaDataset, inferenceDataset, null)); ontModel.addSubModel(ModelContext.getInferenceOntModelSelector(
} getServletContext()).getTBoxModel());
else{
ontModel.addSubModel(ModelContext.getInferenceOntModelSelector(getServletContext()).getABoxModel());
ontModel.addSubModel(ModelContext.getInferenceOntModelSelector(getServletContext()).getTBoxModel());
}
} }
else if("full".equals(assertedOrInferredParam)){ else if("full".equals(assertedOrInferredParam)){
ontModel = xutil.extractTBox(dataset, ontologyURI, FULL_GRAPH); ontModel = xutil.extractTBox(dataset, ontologyURI, FULL_GRAPH);
if(mode.equals("RDB")){ ontModel.addSubModel(ModelContext.getUnionOntModelSelector(
ontModel.addSubModel(xutil.extractABox((OntModel)getServletContext().getAttribute("jenaOntModel"))); getServletContext()).getABoxModel());
} ontModel.addSubModel(ModelContext.getUnionOntModelSelector(
else{ getServletContext()).getTBoxModel());
ontModel.addSubModel(ModelContext.getUnionOntModelSelector(getServletContext()).getABoxModel()); ontModel.addSubModel(ModelContext.getUnionOntModelSelector(
ontModel.addSubModel(ModelContext.getUnionOntModelSelector(getServletContext()).getTBoxModel()); getServletContext()).getApplicationMetadataModel());
ontModel.addSubModel(ModelContext.getUnionOntModelSelector(getServletContext()).getApplicationMetadataModel());
}
} }
else{ else{
ontModel = xutil.extractTBox(dataset, ontologyURI, ASSERTIONS_GRAPH); ontModel = xutil.extractTBox(
if(mode.equals("RDB")){ dataset, ontologyURI, ASSERTIONS_GRAPH);
Dataset jenaDataset = DatasetFactory.create((OntModel)getServletContext().getAttribute("jenaOntModel")); ontModel.addSubModel(ModelContext.getBaseOntModelSelector(
Dataset baseDataset = DatasetFactory.create((OntModel)getServletContext().getAttribute("baseOntModel")); getServletContext()).getABoxModel());
ontModel.addSubModel(xutil.extractABox(jenaDataset,baseDataset,null)); ontModel.addSubModel(ModelContext.getBaseOntModelSelector(
} getServletContext()).getTBoxModel());
else{ ontModel.addSubModel(ModelContext.getBaseOntModelSelector(
ontModel.addSubModel(ModelContext.getBaseOntModelSelector(getServletContext()).getABoxModel()); getServletContext()).getApplicationMetadataModel());
ontModel.addSubModel(ModelContext.getBaseOntModelSelector(getServletContext()).getTBoxModel());
ontModel.addSubModel(ModelContext.getBaseOntModelSelector(getServletContext()).getApplicationMetadataModel());
}
} }
} }

View file

@ -126,7 +126,7 @@ public class JenaIngestController extends BaseEditController {
String modelT = (String)getServletContext().getAttribute("modelT"); String modelT = (String)getServletContext().getAttribute("modelT");
String info = (String)getServletContext().getAttribute("info"); String info = (String)getServletContext().getAttribute("info");
if(modelT == null){ if(modelT == null){
boolean initialSwitch = JenaDataSourceSetupBase.isSDBActive(vreq); boolean initialSwitch = true; // SDB mode initially
if(initialSwitch){ if(initialSwitch){
VitroJenaSDBModelMaker vsmm = (VitroJenaSDBModelMaker) getServletContext().getAttribute("vitroJenaSDBModelMaker"); VitroJenaSDBModelMaker vsmm = (VitroJenaSDBModelMaker) getServletContext().getAttribute("vitroJenaSDBModelMaker");
vreq.getSession().setAttribute("vitroJenaModelMaker", vsmm); vreq.getSession().setAttribute("vitroJenaModelMaker", vsmm);

View file

@ -31,10 +31,12 @@ public class DisplayVocabulary {
public static final String PAGE_TYPE = NS + "Page"; public static final String PAGE_TYPE = NS + "Page";
public static final String HOME_PAGE_TYPE = NS + "HomePage"; public static final String HOME_PAGE_TYPE = NS + "HomePage";
public static final String CLASSGROUP_PAGE_TYPE = NS + "ClassGroupPage"; public static final String CLASSGROUP_PAGE_TYPE = NS + "ClassGroupPage";
//Including for now, can take out later
public static final String CLASSINTERSECTION_PAGE_TYPE = NS + "ClassIntersectionPage";
/* Object Properties */ /* Object Properties */
public static final String FOR_CLASSGROUP = NS + "forClassGroup"; public static final String FOR_CLASSGROUP = NS + "forClassGroup";
public static final String CLASS_INTERSECTION = NS + "intersectsWithClass";
/* Data Properties */ /* Data Properties */
public static final DatatypeProperty URL_MAPPING = m_model.createDatatypeProperty(NS + "urlMapping"); public static final DatatypeProperty URL_MAPPING = m_model.createDatatypeProperty(NS + "urlMapping");
public static final String TITLE = NS + "title"; public static final String TITLE = NS + "title";

View file

@ -108,10 +108,6 @@ public interface IndividualDao extends ObjectSourceIface {
/** /**
* Returns a list of individuals with the given value for the given dataProperty. If * Returns a list of individuals with the given value for the given dataProperty. If
* there are no Indiviuals that fit the criteria then an empty list is returned. * there are no Indiviuals that fit the criteria then an empty list is returned.
*
* @param dataPropertyUri
* @param value
* @return
*/ */
public List<Individual> getIndividualsByDataProperty(String dataPropertyUri, String value); public List<Individual> getIndividualsByDataProperty(String dataPropertyUri, String value);
@ -128,9 +124,6 @@ public interface IndividualDao extends ObjectSourceIface {
List<Keyword> getKeywordObjectsForIndividual(String individualURI); List<Keyword> getKeywordObjectsForIndividual(String individualURI);
/** In most cases, it's best to let ExternalAuthHelper call this for you. */
String getIndividualURIFromNetId(String netIdStr, String netidMatchingPropertyUri);
String getNetId(String entityURI); String getNetId(String entityURI);
String getStatus(String entityURI); String getStatus(String entityURI);

Some files were not shown because too many files have changed in this diff Show more