This commit is contained in:
commit
e5f73e181c
82 changed files with 1842 additions and 1072 deletions
|
@ -1020,18 +1020,6 @@
|
||||||
<url-pattern>/dwr/*</url-pattern>
|
<url-pattern>/dwr/*</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
<!-- Deprecated servlet (still used in Datastar) - retain temporarily for testing and comparison. -->
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>sendmail</servlet-name>
|
|
||||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.ContactMailServlet</servlet-class>
|
|
||||||
<load-on-startup>5</load-on-startup>
|
|
||||||
</servlet>
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>sendmail</servlet-name>
|
|
||||||
<url-pattern>/sendmail</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
<!-- end deprecated servlet -->
|
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>sendMail</servlet-name>
|
<servlet-name>sendMail</servlet-name>
|
||||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.freemarker.ContactMailController</servlet-class>
|
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.freemarker.ContactMailController</servlet-class>
|
||||||
|
|
|
@ -46,4 +46,11 @@ public class RequestIdentifiers {
|
||||||
return (IdentifierBundle) obj;
|
return (IdentifierBundle) obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The login status has changed, so discard the cached Identifiers.
|
||||||
|
*/
|
||||||
|
public static void resetIdentifiers(ServletRequest request) {
|
||||||
|
request.removeAttribute(ATTRIBUTE_ID_BUNDLE);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ 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.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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,7 +72,7 @@ public class CommonIdentifierBundleFactory implements IdentifierBundleFactory {
|
||||||
private Collection<? extends Identifier> createRootUserIdentifiers(
|
private Collection<? extends Identifier> createRootUserIdentifiers(
|
||||||
HttpServletRequest req) {
|
HttpServletRequest req) {
|
||||||
UserAccount user = LoginStatusBean.getCurrentUser(req);
|
UserAccount user = LoginStatusBean.getCurrentUser(req);
|
||||||
if (isRootUser(user)) {
|
if ((user != null) && user.isRootUser()) {
|
||||||
return Collections.singleton(new IsRootUser());
|
return Collections.singleton(new IsRootUser());
|
||||||
} else {
|
} else {
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
|
@ -143,25 +142,6 @@ public class CommonIdentifierBundleFactory implements IdentifierBundleFactory {
|
||||||
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return this.getClass().getSimpleName() + " - " + hashCode();
|
return this.getClass().getSimpleName() + " - " + hashCode();
|
||||||
|
|
|
@ -9,11 +9,6 @@ import javax.servlet.ServletContextListener;
|
||||||
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 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.IdentifierBundle;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsRootUser;
|
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.Authorization;
|
||||||
|
@ -25,9 +20,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
|
||||||
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
|
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao;
|
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.WebappDaoFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.servlet.setup.AbortStartup;
|
import edu.cornell.mannlib.vitro.webapp.servlet.setup.AbortStartup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,10 +66,11 @@ public class RootUserPolicy implements PolicyIface {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
UserAccountsDao uaDao = getUserAccountsDao(ctx);
|
UserAccountsDao uaDao = getUserAccountsDao(ctx);
|
||||||
OntModel userAccountsModel = getUserAccountsModel(ctx);
|
|
||||||
|
checkForWrongRootUser(ctx, uaDao);
|
||||||
|
|
||||||
if (!rootUserExists(uaDao)) {
|
if (!rootUserExists(uaDao)) {
|
||||||
createRootUser(ctx, uaDao, userAccountsModel);
|
createRootUser(ctx, uaDao);
|
||||||
}
|
}
|
||||||
|
|
||||||
ServletPolicyList.addPolicy(ctx, new RootUserPolicy());
|
ServletPolicyList.addPolicy(ctx, new RootUserPolicy());
|
||||||
|
@ -98,26 +92,41 @@ public class RootUserPolicy implements PolicyIface {
|
||||||
return wadf.getUserAccountsDao();
|
return wadf.getUserAccountsDao();
|
||||||
}
|
}
|
||||||
|
|
||||||
private OntModel getUserAccountsModel(ServletContext ctx) {
|
private void checkForWrongRootUser(ServletContext ctx,
|
||||||
return ModelContext.getBaseOntModelSelector(ctx)
|
UserAccountsDao uaDao) {
|
||||||
.getUserAccountsModel();
|
UserAccount root = getRootUser(uaDao);
|
||||||
|
if (root == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String actualRootEmail = root.getEmailAddress();
|
||||||
|
|
||||||
|
String configRootEmail = ConfigurationProperties.getBean(ctx)
|
||||||
|
.getProperty(PROPERTY_ROOT_USER_EMAIL);
|
||||||
|
if (actualRootEmail.equals(configRootEmail)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.warn("Root user '" + actualRootEmail + "' already exists.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean rootUserExists(UserAccountsDao uaDao) {
|
private boolean rootUserExists(UserAccountsDao uaDao) {
|
||||||
|
return (getRootUser(uaDao) != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserAccount getRootUser(UserAccountsDao uaDao) {
|
||||||
for (UserAccount ua : uaDao.getAllUserAccounts()) {
|
for (UserAccount ua : uaDao.getAllUserAccounts()) {
|
||||||
if (uaDao.isRootUser(ua)) {
|
if (ua.isRootUser()) {
|
||||||
return true;
|
return ua;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO The first and last name should be left blank, so the user will
|
* 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.
|
* be forced to edit them. However, that's not in place yet.
|
||||||
*/
|
*/
|
||||||
private void createRootUser(ServletContext ctx, UserAccountsDao uaDao,
|
private void createRootUser(ServletContext ctx, UserAccountsDao uaDao) {
|
||||||
OntModel userAccountsModel) {
|
|
||||||
String emailAddress = ConfigurationProperties.getBean(ctx)
|
String emailAddress = ConfigurationProperties.getBean(ctx)
|
||||||
.getProperty(PROPERTY_ROOT_USER_EMAIL);
|
.getProperty(PROPERTY_ROOT_USER_EMAIL);
|
||||||
if (emailAddress == null) {
|
if (emailAddress == null) {
|
||||||
|
@ -147,19 +156,10 @@ public class RootUserPolicy implements PolicyIface {
|
||||||
.applyMd5Encoding(ROOT_USER_INITIAL_PASSWORD));
|
.applyMd5Encoding(ROOT_USER_INITIAL_PASSWORD));
|
||||||
ua.setPasswordChangeRequired(true);
|
ua.setPasswordChangeRequired(true);
|
||||||
ua.setStatus(Status.ACTIVE);
|
ua.setStatus(Status.ACTIVE);
|
||||||
|
ua.setRootUser(true);
|
||||||
|
|
||||||
uaDao.insertUserAccount(ua);
|
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 + "'");
|
log.info("Created root user as '" + emailAddress + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,8 @@ public class UserAccount {
|
||||||
/** This may be empty, but should never be null. */
|
/** This may be empty, but should never be null. */
|
||||||
private Set<String> permissionSetUris = Collections.emptySet();
|
private Set<String> permissionSetUris = Collections.emptySet();
|
||||||
|
|
||||||
|
private boolean rootUser = false;
|
||||||
|
|
||||||
public String getUri() {
|
public String getUri() {
|
||||||
return uri;
|
return uri;
|
||||||
}
|
}
|
||||||
|
@ -172,6 +174,14 @@ public class UserAccount {
|
||||||
this.permissionSetUris = new HashSet<String>(permissionSetUris);
|
this.permissionSetUris = new HashSet<String>(permissionSetUris);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isRootUser() {
|
||||||
|
return rootUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRootUser(boolean rootUser) {
|
||||||
|
this.rootUser = rootUser;
|
||||||
|
}
|
||||||
|
|
||||||
private <T> T nonNull(T value, T defaultValue) {
|
private <T> T nonNull(T value, T defaultValue) {
|
||||||
return (value == null) ? defaultValue : value;
|
return (value == null) ? defaultValue : value;
|
||||||
}
|
}
|
||||||
|
@ -196,6 +206,7 @@ public class UserAccount {
|
||||||
+ (", passwordChangeRequired=" + passwordChangeRequired)
|
+ (", passwordChangeRequired=" + passwordChangeRequired)
|
||||||
+ (", loginCount=" + loginCount) + (", status=" + status)
|
+ (", loginCount=" + loginCount) + (", status=" + status)
|
||||||
+ (", externalAuthId=" + externalAuthId)
|
+ (", externalAuthId=" + externalAuthId)
|
||||||
|
+ (", rootUser=" + rootUser)
|
||||||
+ (", permissionSetUris=" + permissionSetUris) + "]";
|
+ (", permissionSetUris=" + permissionSetUris) + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,352 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.controller;
|
|
||||||
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import javax.mail.Message;
|
|
||||||
import javax.mail.MessagingException;
|
|
||||||
import javax.mail.SendFailedException;
|
|
||||||
import javax.mail.Session;
|
|
||||||
import javax.mail.Transport;
|
|
||||||
import javax.mail.internet.AddressException;
|
|
||||||
import javax.mail.internet.InternetAddress;
|
|
||||||
import javax.mail.internet.MimeMessage;
|
|
||||||
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.vitro.webapp.beans.ApplicationBean;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
|
|
||||||
|
|
||||||
public class ContactMailServlet extends VitroHttpServlet {
|
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(ContactMailServlet.class);
|
|
||||||
|
|
||||||
private final static String CONFIRM_PAGE = "/templates/parts/thankyou.jsp";
|
|
||||||
private final static String ERR_PAGE = "/templates/parts/contact_err.jsp";
|
|
||||||
private final static String SPAM_MESSAGE = "Your message was flagged as spam.";
|
|
||||||
private final static String EMAIL_BACKUP_FILE_PATH = "/WEB-INF/LatestMessage.html";
|
|
||||||
|
|
||||||
private final static String WEB_USERNAME_PARAM = "webusername";
|
|
||||||
private final static String WEB_USEREMAIL_PARAM = "webuseremail";
|
|
||||||
private final static String COMMENTS_PARAM = "s34gfd88p9x1";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doGet( HttpServletRequest request, HttpServletResponse response )
|
|
||||||
throws ServletException, IOException {
|
|
||||||
|
|
||||||
VitroRequest vreq = new VitroRequest(request);
|
|
||||||
|
|
||||||
ApplicationBean appBean = vreq.getAppBean();
|
|
||||||
|
|
||||||
String statusMsg = null; // holds the error status
|
|
||||||
|
|
||||||
if (!FreemarkerEmailFactory.isConfigured(vreq)) {
|
|
||||||
statusMsg = "This application has not yet been configured to send mail. "
|
|
||||||
+ "Email properties must be specified in the configuration properties file.";
|
|
||||||
redirectToError(response, statusMsg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String webusername = vreq.getParameter(WEB_USERNAME_PARAM);
|
|
||||||
String webuseremail = vreq.getParameter(WEB_USEREMAIL_PARAM);
|
|
||||||
String comments = vreq.getParameter(COMMENTS_PARAM);
|
|
||||||
|
|
||||||
String validationMessage = validateInput(webusername, webuseremail,
|
|
||||||
comments);
|
|
||||||
if (validationMessage != null) {
|
|
||||||
redirectToError(response, validationMessage);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
webusername = webusername.trim();
|
|
||||||
webuseremail = webuseremail.trim();
|
|
||||||
comments = comments.trim();
|
|
||||||
|
|
||||||
String spamReason = null;
|
|
||||||
|
|
||||||
String originalReferer = (String) request.getSession()
|
|
||||||
.getAttribute("commentsFormReferer");
|
|
||||||
if (originalReferer != null) {
|
|
||||||
request.getSession().removeAttribute("commentsFormReferer");
|
|
||||||
/* 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) {
|
|
||||||
spamReason = checkForSpam(comments);
|
|
||||||
if (spamReason != null) {
|
|
||||||
statusMsg = SPAM_MESSAGE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String formType = vreq.getParameter("DeliveryType");
|
|
||||||
String[] deliverToArray = null;
|
|
||||||
int recipientCount = 0;
|
|
||||||
String deliveryfrom = null;
|
|
||||||
|
|
||||||
if ("comment".equals(formType)) {
|
|
||||||
if (appBean.getContactMail() == null || appBean.getContactMail().trim().length()==0) {
|
|
||||||
log.error("No contact mail address defined in current application");
|
|
||||||
throw new Error(
|
|
||||||
"To establish the Contact Us mail capability the system administrators must "
|
|
||||||
+ "specify an email address in the current portal.");
|
|
||||||
} else {
|
|
||||||
deliverToArray = appBean.getContactMail().split(",");
|
|
||||||
}
|
|
||||||
deliveryfrom = "Message from the "+appBean.getApplicationName()+" Contact Form";
|
|
||||||
} else if ("correction".equals(formType)) {
|
|
||||||
if (appBean.getCorrectionMail() == null || appBean.getCorrectionMail().trim().length()==0) {
|
|
||||||
log.error("Expecting one or more correction email addresses to be specified in current application; will attempt to use contact mail address");
|
|
||||||
if (appBean.getContactMail() == null || appBean.getContactMail().trim().length()==0) {
|
|
||||||
log.error("No contact mail address or correction mail address defined in current application");
|
|
||||||
} else {
|
|
||||||
deliverToArray = appBean.getContactMail().split(",");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
deliverToArray = appBean.getCorrectionMail().split(",");
|
|
||||||
}
|
|
||||||
deliveryfrom = "Message from the "+appBean.getApplicationName()+" Correction Form (ARMANN-nospam)";
|
|
||||||
} else {
|
|
||||||
deliverToArray = appBean.getContactMail().split(",");
|
|
||||||
statusMsg = SPAM_MESSAGE ;
|
|
||||||
spamReason = "The form specifies no delivery type.";
|
|
||||||
}
|
|
||||||
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 in the current portal.");
|
|
||||||
}
|
|
||||||
|
|
||||||
String msgText = composeEmail(webusername, webuseremail, comments,
|
|
||||||
deliveryfrom, originalReferer, request.getRemoteAddr());
|
|
||||||
|
|
||||||
// debugging
|
|
||||||
PrintWriter outFile = new PrintWriter
|
|
||||||
(new FileWriter(request.getSession().getServletContext()
|
|
||||||
.getRealPath(EMAIL_BACKUP_FILE_PATH),true)); //autoflush
|
|
||||||
writeBackupCopy(outFile, msgText, spamReason);
|
|
||||||
|
|
||||||
Session s = FreemarkerEmailFactory.getEmailSession(vreq);
|
|
||||||
//s.setDebug(true);
|
|
||||||
try {
|
|
||||||
|
|
||||||
if (spamReason == null) {
|
|
||||||
sendMessage(s, webuseremail, deliverToArray, deliveryfrom,
|
|
||||||
recipientCount, msgText);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (AddressException e) {
|
|
||||||
statusMsg = "Please supply a valid email address.";
|
|
||||||
outFile.println( statusMsg );
|
|
||||||
outFile.println( e.getMessage() );
|
|
||||||
} catch (SendFailedException e) {
|
|
||||||
statusMsg = "The system was unable to deliver your mail. Please try again later. [SEND FAILED]";
|
|
||||||
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();
|
|
||||||
|
|
||||||
// Redirect to the appropriate confirmation page
|
|
||||||
if (statusMsg == null && spamReason == null) {
|
|
||||||
// message was sent successfully
|
|
||||||
redirectToConfirmation(response, statusMsg);
|
|
||||||
} else {
|
|
||||||
// exception occurred
|
|
||||||
redirectToError( response, statusMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doPost( HttpServletRequest request, HttpServletResponse response )
|
|
||||||
throws ServletException, IOException
|
|
||||||
{
|
|
||||||
doGet( request, response );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void redirectToConfirmation(HttpServletResponse response,
|
|
||||||
String statusMsg) throws IOException {
|
|
||||||
response.sendRedirect( "test?bodyJsp=" + CONFIRM_PAGE + "&home=" );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void redirectToError(HttpServletResponse response, String statusMsg)
|
|
||||||
throws IOException {
|
|
||||||
response.sendRedirect("test?bodyJsp=" + ERR_PAGE + "&ERR=" + statusMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Intended to mangle url so it can get through spam filtering
|
|
||||||
* http://host/dir/servlet?param=value -> host: dir/servlet?param=value */
|
|
||||||
public String stripProtocol( String in ){
|
|
||||||
if( in == null )
|
|
||||||
return "";
|
|
||||||
else
|
|
||||||
return in.replaceAll("http://", "host: " );
|
|
||||||
}
|
|
||||||
|
|
||||||
private String composeEmail(String webusername, String webuseremail,
|
|
||||||
String comments, String deliveryfrom,
|
|
||||||
String originalReferer, String ipAddr) {
|
|
||||||
|
|
||||||
StringBuffer msgBuf = new StringBuffer();
|
|
||||||
// contains the intro copy for the body of the email message
|
|
||||||
|
|
||||||
String lineSeparator = System.getProperty("line.separator");
|
|
||||||
// \r\n on windows, \n on unix
|
|
||||||
|
|
||||||
// from MyLibrary
|
|
||||||
msgBuf.setLength(0);
|
|
||||||
msgBuf.append("Content-Type: text/html; charset='us-ascii'" + lineSeparator);
|
|
||||||
msgBuf.append("<html>" + lineSeparator );
|
|
||||||
msgBuf.append("<head>" + lineSeparator );
|
|
||||||
msgBuf.append("<style>a {text-decoration: none}</style>" + lineSeparator );
|
|
||||||
msgBuf.append("<title>" + deliveryfrom + "</title>" + lineSeparator );
|
|
||||||
msgBuf.append("</head>" + lineSeparator );
|
|
||||||
msgBuf.append("<body>" + lineSeparator );
|
|
||||||
msgBuf.append("<h4>" + deliveryfrom + "</h4>" + lineSeparator );
|
|
||||||
msgBuf.append("<h4>From: "+webusername +" (" + webuseremail + ")" +
|
|
||||||
" at IP address " + ipAddr + "</h4>"+lineSeparator);
|
|
||||||
|
|
||||||
if (!(originalReferer == null || originalReferer.equals("none"))){
|
|
||||||
//The spam filter that is being used by the listsrv is rejecting <a href="...
|
|
||||||
//so try with out the markup, if that sill doesn't work,
|
|
||||||
//uncomment the following line to strip the http://
|
|
||||||
//msgBuf.append("<p><i>likely viewing page " + stripProtocol(originalReferer) );
|
|
||||||
msgBuf.append("<p><i>likely viewing page " + originalReferer );
|
|
||||||
}
|
|
||||||
|
|
||||||
msgBuf.append(lineSeparator + "</i></p><h3>Comments:</h3>" + lineSeparator );
|
|
||||||
if (comments==null || comments.equals("")) {
|
|
||||||
msgBuf.append("<p>BLANK MESSAGE</p>");
|
|
||||||
} else {
|
|
||||||
msgBuf.append("<p>"+comments+"</p>");
|
|
||||||
}
|
|
||||||
msgBuf.append("</body>" + lineSeparator );
|
|
||||||
msgBuf.append("</html>" + lineSeparator );
|
|
||||||
|
|
||||||
return msgBuf.toString();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeBackupCopy(PrintWriter outFile, String msgText,
|
|
||||||
String spamReason) {
|
|
||||||
Calendar cal = Calendar.getInstance();
|
|
||||||
outFile.println("<hr/>");
|
|
||||||
outFile.println();
|
|
||||||
outFile.println("<p>"+cal.getTime()+"</p>");
|
|
||||||
outFile.println();
|
|
||||||
if (spamReason != null) {
|
|
||||||
outFile.println("<p>REJECTED - SPAM</p>");
|
|
||||||
outFile.println("<p>"+spamReason+"</p>");
|
|
||||||
outFile.println();
|
|
||||||
}
|
|
||||||
outFile.print( msgText );
|
|
||||||
outFile.println();
|
|
||||||
outFile.println();
|
|
||||||
outFile.flush();
|
|
||||||
// outFile.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendMessage(Session s, String webuseremail,
|
|
||||||
String[] deliverToArray, String deliveryfrom, int recipientCount,
|
|
||||||
String msgText)
|
|
||||||
throws AddressException, SendFailedException, MessagingException {
|
|
||||||
// Construct the message
|
|
||||||
MimeMessage msg = new MimeMessage( s );
|
|
||||||
//System.out.println("trying to send message from servlet");
|
|
||||||
|
|
||||||
// Set the from address
|
|
||||||
msg.setFrom( new InternetAddress( webuseremail ));
|
|
||||||
|
|
||||||
// Set the recipient address
|
|
||||||
|
|
||||||
if (recipientCount>0){
|
|
||||||
InternetAddress[] address=new InternetAddress[recipientCount];
|
|
||||||
for (int i=0; i<recipientCount; i++){
|
|
||||||
address[i] = new InternetAddress(deliverToArray[i]);
|
|
||||||
}
|
|
||||||
msg.setRecipients( Message.RecipientType.TO, address );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the subject and text
|
|
||||||
msg.setSubject( deliveryfrom );
|
|
||||||
|
|
||||||
// add the multipart to the message
|
|
||||||
msg.setContent(msgText,"text/html");
|
|
||||||
|
|
||||||
// set the Date: header
|
|
||||||
msg.setSentDate( new Date() );
|
|
||||||
|
|
||||||
Transport.send( msg ); // try to send the message via smtp - catch error exceptions
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private String validateInput(String webusername, String webuseremail,
|
|
||||||
String comments) {
|
|
||||||
|
|
||||||
if( webusername == null || "".equals(webusername.trim()) ){
|
|
||||||
return "A proper webusername field was not found in the form submitted.";
|
|
||||||
}
|
|
||||||
|
|
||||||
if( webuseremail == null || "".equals(webuseremail.trim()) ){
|
|
||||||
return "A proper webuser email field was not found in the form submitted.";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (comments==null || "".equals(comments.trim())) {
|
|
||||||
return "The proper comments field was not found in the form submitted.";
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param request
|
|
||||||
* @return null if message not judged to be spam, otherwise a String
|
|
||||||
* containing the reason the message was flagged as spam.
|
|
||||||
*/
|
|
||||||
private String checkForSpam(String comments) {
|
|
||||||
|
|
||||||
/* if this blog markup is found, treat comment as blog spam */
|
|
||||||
if (
|
|
||||||
(comments.indexOf("[/url]") > -1
|
|
||||||
|| comments.indexOf("[/URL]") > -1
|
|
||||||
|| comments.indexOf("[url=") > -1
|
|
||||||
|| comments.indexOf("[URL=") > -1)) {
|
|
||||||
return "The message contained blog link markup.";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if message is absurdly short, treat as blog spam */
|
|
||||||
if (comments.length()<15) {
|
|
||||||
return "The message was too short.";
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,753 @@
|
||||||
|
/* $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.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
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.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.search.WildcardQuery;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import com.hp.hpl.jena.vocabulary.OWL;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.Datatype;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
|
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 Google Refine's
|
||||||
|
* "Add columns from VIVO" requests.
|
||||||
|
*
|
||||||
|
* @author Eliza Chan (elc2013@med.cornell.edu)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class GrefinePropertyListServlet extends VitroHttpServlet {
|
||||||
|
|
||||||
|
private int MAXDEPTH = 7;
|
||||||
|
private int NUM_COLS = 9;
|
||||||
|
private static String QUERY_PARAMETER_NAME = "term";
|
||||||
|
public static final int MAX_QUERY_LENGTH = 500;
|
||||||
|
private static final Log log = LogFactory.getLog(GrefinePropertyListServlet.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);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
String callbackStr = (vreq.getParameter("callback") == null) ? ""
|
||||||
|
: vreq.getParameter("callback");
|
||||||
|
ServletOutputStream out = resp.getOutputStream();
|
||||||
|
|
||||||
|
|
||||||
|
// *******
|
||||||
|
// methodology adopted from DatatypePropertiesListingController and ClassHierarchyListingController
|
||||||
|
// *******
|
||||||
|
VClassDao vcDao = vreq.getFullWebappDaoFactory().getVClassDao();
|
||||||
|
DataPropertyDao dao = vreq.getFullWebappDaoFactory().getDataPropertyDao();
|
||||||
|
String topUri = vreq.getParameter("type");
|
||||||
|
VClass topClass = vcDao.getVClassByURI(topUri);
|
||||||
|
HashSet<String> propURIs = new HashSet<String>();
|
||||||
|
HashMap<VClass, List<DataProperty>> classPropertiesMap =
|
||||||
|
populateClassPropertiesMap(vcDao, dao, topUri, propURIs);
|
||||||
|
|
||||||
|
|
||||||
|
// Construct json String
|
||||||
|
JSONObject completeJson = new JSONObject();
|
||||||
|
JSONArray propertiesJsonArr = new JSONArray();
|
||||||
|
if (classPropertiesMap.size() > 0) {
|
||||||
|
for (Iterator<VClass> iter = classPropertiesMap.keySet().iterator(); iter.hasNext();) { // add results to schema
|
||||||
|
VClass vc = (VClass) iter.next();
|
||||||
|
System.out.println("vc uri: " + vc.getURI());
|
||||||
|
System.out.println("vc name: " + vc.getName());
|
||||||
|
|
||||||
|
ArrayList<DataProperty> vcProps = (ArrayList<DataProperty>)classPropertiesMap.get(vc);
|
||||||
|
for (DataProperty prop: vcProps) {
|
||||||
|
String nameStr = prop.getPublicName()==null ? prop.getName()==null ? null : prop.getName() : prop.getPublicName();
|
||||||
|
System.out.println("--- uri: " + prop.getURI());
|
||||||
|
System.out.println("--- name: " + nameStr);
|
||||||
|
// top level
|
||||||
|
JSONObject propertiesItemJson = new JSONObject();
|
||||||
|
JSONObject rootSchemaJson = new JSONObject();
|
||||||
|
rootSchemaJson.put("id", vc.getURI());
|
||||||
|
rootSchemaJson.put("name", vc.getName());
|
||||||
|
rootSchemaJson.put("alias", new JSONArray());
|
||||||
|
propertiesItemJson.put("schema", rootSchemaJson);
|
||||||
|
// second level
|
||||||
|
propertiesItemJson.put("id", prop.getURI());
|
||||||
|
propertiesItemJson.put("name", nameStr);
|
||||||
|
propertiesItemJson.put("alias", new JSONArray());
|
||||||
|
|
||||||
|
JSONObject expectsJson = new JSONObject();
|
||||||
|
expectsJson.put("id", prop.getURI());
|
||||||
|
expectsJson.put("name", nameStr);
|
||||||
|
expectsJson.put("alias", new JSONArray());
|
||||||
|
propertiesItemJson.put("expects", expectsJson);
|
||||||
|
|
||||||
|
propertiesJsonArr.put(propertiesItemJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// get data properties from subclasses
|
||||||
|
List<VClass> lvl2Classes = new ArrayList<VClass>();
|
||||||
|
List roots = null;
|
||||||
|
String requestType = vreq.getParameter("type");
|
||||||
|
if (requestType != null) {
|
||||||
|
roots = new LinkedList<VClass>();
|
||||||
|
roots.add(vcDao.getVClassByURI(requestType));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (roots != null) {
|
||||||
|
String ontologyUri = null;
|
||||||
|
Collections.sort(roots);
|
||||||
|
Iterator rootIt = roots.iterator();
|
||||||
|
if (rootIt.hasNext()) {
|
||||||
|
while (rootIt.hasNext()) {
|
||||||
|
VClass root = (VClass) rootIt.next();
|
||||||
|
if (root != null) {
|
||||||
|
List<VClass> lvl2ChildClasses = new ArrayList<VClass>();
|
||||||
|
addChildren(vcDao, vreq.getFullWebappDaoFactory(), root, lvl2ChildClasses, 0, ontologyUri);
|
||||||
|
lvl2Classes.addAll(lvl2ChildClasses);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (VClass lvl2Class: lvl2Classes) {
|
||||||
|
HashMap<VClass, List<DataProperty>> lvl2ClassPropertiesMap =
|
||||||
|
populateClassPropertiesMap(vcDao, dao, lvl2Class.getURI(), propURIs);
|
||||||
|
if (lvl2ClassPropertiesMap.size() > 0) {
|
||||||
|
for (Iterator<VClass> iter = lvl2ClassPropertiesMap.keySet().iterator(); iter.hasNext();) { // add results to schema
|
||||||
|
VClass vc = (VClass) iter.next();
|
||||||
|
ArrayList<DataProperty> vcProps = (ArrayList<DataProperty>)lvl2ClassPropertiesMap.get(vc);
|
||||||
|
for (DataProperty prop: vcProps) {
|
||||||
|
String nameStr = prop.getPublicName()==null ? prop.getName()==null ? null : prop.getName() : prop.getPublicName();
|
||||||
|
// top level
|
||||||
|
JSONObject propertiesItemJson = new JSONObject();
|
||||||
|
|
||||||
|
JSONObject rootSchemaJson = new JSONObject();
|
||||||
|
rootSchemaJson.put("id", topClass.getURI());
|
||||||
|
rootSchemaJson.put("name", topClass.getName());
|
||||||
|
rootSchemaJson.put("alias", new JSONArray());
|
||||||
|
propertiesItemJson.put("schema", rootSchemaJson);
|
||||||
|
|
||||||
|
// second level
|
||||||
|
propertiesItemJson.put("id", vc.getURI());
|
||||||
|
propertiesItemJson.put("name", vc.getName());
|
||||||
|
propertiesItemJson.put("alias", new JSONArray());
|
||||||
|
|
||||||
|
propertiesItemJson.put("id2", prop.getURI());
|
||||||
|
propertiesItemJson.put("name2", nameStr);
|
||||||
|
propertiesItemJson.put("alias2", new JSONArray());
|
||||||
|
|
||||||
|
JSONObject expectsJson = new JSONObject();
|
||||||
|
expectsJson.put("id", prop.getURI());
|
||||||
|
expectsJson.put("name", nameStr);
|
||||||
|
expectsJson.put("alias", new JSONArray());
|
||||||
|
propertiesItemJson.put("expects", expectsJson);
|
||||||
|
|
||||||
|
propertiesJsonArr.put(propertiesItemJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
completeJson.put("properties", propertiesJsonArr);
|
||||||
|
out.print(callbackStr + "(" + completeJson.toString() + ")");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.warn(ex, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private HashMap<VClass, List<DataProperty>> populateClassPropertiesMap (
|
||||||
|
VClassDao vcDao,
|
||||||
|
DataPropertyDao dao,
|
||||||
|
String uri,
|
||||||
|
HashSet<String> propURIs) {
|
||||||
|
|
||||||
|
HashMap<VClass, List<DataProperty>> classPropertiesMap = new HashMap<VClass, List<DataProperty>>();
|
||||||
|
List<DataProperty> props = new ArrayList<DataProperty>();
|
||||||
|
VClass topVc = vcDao.getVClassByURI(uri);
|
||||||
|
Collection <DataProperty> dataProps = dao.getDataPropertiesForVClass(uri);
|
||||||
|
Iterator<DataProperty> dataPropIt = dataProps.iterator();
|
||||||
|
while (dataPropIt.hasNext()) {
|
||||||
|
DataProperty dp = dataPropIt.next();
|
||||||
|
if (!(propURIs.contains(dp.getURI()))) {
|
||||||
|
propURIs.add(dp.getURI());
|
||||||
|
DataProperty prop = dao.getDataPropertyByURI(dp.getURI());
|
||||||
|
if (prop != null) {
|
||||||
|
props.add(prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (props.size() > 0) {
|
||||||
|
|
||||||
|
Collections.sort(props);
|
||||||
|
for (DataProperty prop: props) {
|
||||||
|
String nameStr = prop.getPublicName()==null ? prop.getName()==null ? null : prop.getName() : prop.getPublicName();
|
||||||
|
if (nameStr != null) {
|
||||||
|
if (prop.getDomainClassURI() != null) {
|
||||||
|
VClass vc = vcDao.getVClassByURI(prop.getDomainClassURI());
|
||||||
|
if (classPropertiesMap.get(vc) != null) {
|
||||||
|
ArrayList<DataProperty> existingList = (ArrayList<DataProperty>)classPropertiesMap.get(vc);
|
||||||
|
existingList.add(prop);
|
||||||
|
} else {
|
||||||
|
ArrayList<DataProperty> newList = new ArrayList<DataProperty>();
|
||||||
|
newList.add(prop);
|
||||||
|
classPropertiesMap.put(vc, newList);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { // some properties have no domain, belong to top vc by default
|
||||||
|
if (classPropertiesMap.get(topVc) != null) {
|
||||||
|
ArrayList<DataProperty> existingList = (ArrayList<DataProperty>)classPropertiesMap.get(topVc);
|
||||||
|
existingList.add(prop);
|
||||||
|
} else {
|
||||||
|
ArrayList<DataProperty> newList = new ArrayList<DataProperty>();
|
||||||
|
newList.add(prop);
|
||||||
|
classPropertiesMap.put(topVc, newList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return classPropertiesMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addChildren(VClassDao vcDao, WebappDaoFactory wadf, VClass parent, List<VClass> list, int position, String ontologyUri) {
|
||||||
|
List<VClass> rowElts = addVClassDataToResultsList(wadf, parent, position, ontologyUri);
|
||||||
|
int childShift = (rowElts.size() > 0) ? 1 : 0; // if addVClassDataToResultsList filtered out the result, don't shift the children over
|
||||||
|
list.addAll(rowElts);
|
||||||
|
List childURIstrs = vcDao.getSubClassURIs(parent.getURI());
|
||||||
|
if ((childURIstrs.size()>0) && position<MAXDEPTH) {
|
||||||
|
List childClasses = new ArrayList();
|
||||||
|
Iterator childURIstrIt = childURIstrs.iterator();
|
||||||
|
while (childURIstrIt.hasNext()) {
|
||||||
|
String URIstr = (String) childURIstrIt.next();
|
||||||
|
try {
|
||||||
|
VClass child = (VClass) vcDao.getVClassByURI(URIstr);
|
||||||
|
if (!child.getURI().equals(OWL.Nothing.getURI())) {
|
||||||
|
childClasses.add(child);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {}
|
||||||
|
}
|
||||||
|
Collections.sort(childClasses);
|
||||||
|
Iterator childClassIt = childClasses.iterator();
|
||||||
|
while (childClassIt.hasNext()) {
|
||||||
|
VClass child = (VClass) childClassIt.next();
|
||||||
|
addChildren(vcDao, wadf, child, list, position + childShift, ontologyUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<VClass> addVClassDataToResultsList(WebappDaoFactory wadf, VClass vcw, int position, String ontologyUri) {
|
||||||
|
List<VClass> results = new ArrayList<VClass>();
|
||||||
|
if (ontologyUri == null || ( (vcw.getNamespace()!=null) && (vcw.getNamespace().equals(ontologyUri)) ) ) {
|
||||||
|
results.add(vcw);
|
||||||
|
|
||||||
|
/*
|
||||||
|
for (int i=0; i<position; i++) {
|
||||||
|
results.add("@@entities");
|
||||||
|
}
|
||||||
|
if (position==0)
|
||||||
|
results.add("XX"); // column 1
|
||||||
|
Integer numCols = (NUM_COLS-1)-position;
|
||||||
|
|
||||||
|
try {
|
||||||
|
numCols = addColToResults(((vcw.getLocalNameWithPrefix() == null) ? "" : "<a href=\"vclassEdit?uri="+URLEncoder.encode(vcw.getURI(),"UTF-8")+"\">"+vcw.getLocalNameWithPrefix()+"</a>"), results, numCols);
|
||||||
|
} catch (Exception e) {
|
||||||
|
numCols = addColToResults(((vcw.getLocalNameWithPrefix() == null) ? "" : vcw.getLocalNameWithPrefix()), results, numCols); // column 2
|
||||||
|
}
|
||||||
|
numCols = addColToResults(((vcw.getShortDef() == null) ? "" : vcw.getShortDef()), results, numCols); // column 3
|
||||||
|
numCols = addColToResults(((vcw.getExample() == null) ? "" : vcw.getExample()), results, numCols); // column 4
|
||||||
|
|
||||||
|
// Get group name if it exists
|
||||||
|
VClassGroupDao groupDao= wadf.getVClassGroupDao();
|
||||||
|
String groupURI = vcw.getGroupURI();
|
||||||
|
String groupName = null;
|
||||||
|
VClassGroup classGroup = null;
|
||||||
|
if(groupURI != null) {
|
||||||
|
classGroup = groupDao.getGroupByURI(groupURI);
|
||||||
|
if (classGroup != null) {
|
||||||
|
groupName = classGroup.getPublicName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
numCols = addColToResults(((groupName == null) ? "" : groupName), results, numCols); // column 5
|
||||||
|
|
||||||
|
// Get ontology name
|
||||||
|
String ontName = null;
|
||||||
|
try {
|
||||||
|
OntologyDao ontDao = wadf.getOntologyDao();
|
||||||
|
Ontology ont = ontDao.getOntologyByURI(vcw.getNamespace());
|
||||||
|
ontName = ont.getName();
|
||||||
|
} catch (Exception e) {}
|
||||||
|
numCols = addColToResults(((ontName == null) ? "" : ontName), results, numCols); // column 6
|
||||||
|
|
||||||
|
numCols = addColToResults(vcw.getHiddenFromDisplayBelowRoleLevel() == null ? "unspecified" : vcw.getHiddenFromDisplayBelowRoleLevel().getShorthand(), results, numCols); // column 7
|
||||||
|
numCols = addColToResults(vcw.getProhibitedFromUpdateBelowRoleLevel() == null ? "unspecified" : vcw.getProhibitedFromUpdateBelowRoleLevel().getShorthand(), results, numCols); // column 8
|
||||||
|
|
||||||
|
results.add("XX"); // column 9
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer addColToResults (String value, List results, Integer colIndex) {
|
||||||
|
if (colIndex>0) {
|
||||||
|
results.add(value);
|
||||||
|
}
|
||||||
|
return colIndex-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
System.err.println("JSONReconcileServlet 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) {
|
||||||
|
System.err.println("JSONReconcileServlet JSONException: " + ex);
|
||||||
|
throw new ServletException("JSONReconcileServlet JSONException: "
|
||||||
|
+ ex);
|
||||||
|
} catch (SearchException ex) {
|
||||||
|
System.err.println("JSONReconcileServlet SearchException: " + ex);
|
||||||
|
throw new ServletException("JSONReconcileServlet SearchException: "
|
||||||
|
+ ex);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
System.err.println("JSONReconcileServlet 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) {
|
||||||
|
|
||||||
|
/* Original code
|
||||||
|
String tokenizeParam = (String) request.getParameter("tokenize");
|
||||||
|
boolean tokenize = "true".equals(tokenizeParam);
|
||||||
|
|
||||||
|
// Note: Stemming is only relevant if we are tokenizing: an untokenized name
|
||||||
|
// query will not be stemmed. So we don't look at the stem parameter until we get to
|
||||||
|
// makeTokenizedNameQuery().
|
||||||
|
if (tokenize) {
|
||||||
|
return makeTokenizedNameQuery(querystr, analyzer, request);
|
||||||
|
} else {
|
||||||
|
return makeUntokenizedNameQuery(querystr);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// modified code for reconciliation service
|
||||||
|
request.setAttribute("stem", true);
|
||||||
|
return makeTokenizedNameQuery(querystr, analyzer, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Query makeTokenizedNameQuery(String querystr, Analyzer analyzer, HttpServletRequest request) {
|
||||||
|
|
||||||
|
String stemParam = (String) request.getParameter("stem");
|
||||||
|
boolean stem = "true".equals(stemParam);
|
||||||
|
String termName = stem ? VitroLuceneTermNames.NAME_STEMMED : VitroLuceneTermNames.NAME_UNSTEMMED;
|
||||||
|
|
||||||
|
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 Query makeUntokenizedNameQuery(String querystr) {
|
||||||
|
|
||||||
|
querystr = querystr.toLowerCase();
|
||||||
|
String termName = VitroLuceneTermNames.NAME_LOWERCASE;
|
||||||
|
BooleanQuery query = new BooleanQuery();
|
||||||
|
log.debug("Adding wildcard query on unanalyzed name");
|
||||||
|
query.add(
|
||||||
|
new WildcardQuery(new Term(termName, querystr + "*")),
|
||||||
|
BooleanClause.Occur.MUST);
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(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 (!"".equals(pvPair[0]) && pvPair[0] != null) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import javax.servlet.ServletOutputStream;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
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 org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
|
@ -53,7 +54,8 @@ import edu.cornell.mannlib.vitro.webapp.search.lucene.LuceneSetup;
|
||||||
*/
|
*/
|
||||||
public class JSONReconcileServlet extends VitroHttpServlet {
|
public class JSONReconcileServlet extends VitroHttpServlet {
|
||||||
|
|
||||||
private static String QUERY_PARAMETER_NAME = "term";
|
private static final long serialVersionUID = 1L;
|
||||||
|
private static String QUERY_PARAMETER_NAME = "term";
|
||||||
public static final int MAX_QUERY_LENGTH = 500;
|
public static final int MAX_QUERY_LENGTH = 500;
|
||||||
private static final Log log = LogFactory.getLog(JSONReconcileServlet.class.getName());
|
private static final Log log = LogFactory.getLog(JSONReconcileServlet.class.getName());
|
||||||
|
|
||||||
|
@ -70,14 +72,14 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
||||||
super.doGet(req, resp);
|
super.doGet(req, resp);
|
||||||
resp.setContentType("application/json");
|
resp.setContentType("application/json");
|
||||||
VitroRequest vreq = new VitroRequest(req);
|
VitroRequest vreq = new VitroRequest(req);
|
||||||
System.out.println("vreq");
|
//log.debug("vreq");
|
||||||
System.out.println(vreq.getWebappDaoFactory());
|
//log.debug(vreq.getWebappDaoFactory());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (vreq.getParameter("query") != null
|
if (vreq.getParameter("query") != null
|
||||||
|| vreq.getParameter("queries") != null) {
|
|| vreq.getParameter("queries") != null) {
|
||||||
JSONObject qJson = getResult(vreq, req, resp);
|
JSONObject qJson = getResult(vreq, req, resp);
|
||||||
System.out.println("result: " + qJson.toString());
|
log.debug("result: " + qJson.toString());
|
||||||
String responseStr = (vreq.getParameter("callback") == null) ? qJson
|
String responseStr = (vreq.getParameter("callback") == null) ? qJson
|
||||||
.toString() : vreq.getParameter("callback") + "("
|
.toString() : vreq.getParameter("callback") + "("
|
||||||
+ qJson.toString() + ")";
|
+ qJson.toString() + ")";
|
||||||
|
@ -124,8 +126,7 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
||||||
// "q2":{"query":"Dina","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;
|
String qStr = (String) qObj;
|
||||||
queries.add(qStr);
|
queries.add(qStr);
|
||||||
System.out.println();
|
log.debug("\nquery: " + qStr + "\n");
|
||||||
System.out.println("query: " + qStr + "\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -158,7 +159,7 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (JSONException ex) {
|
} catch (JSONException ex) {
|
||||||
System.err.println("JSONReconcileServlet JSONException: " + ex);
|
log.error("JSONException: " + ex);
|
||||||
throw new ServletException("JSONReconcileServlet JSONException: "
|
throw new ServletException("JSONReconcileServlet JSONException: "
|
||||||
+ ex);
|
+ ex);
|
||||||
}
|
}
|
||||||
|
@ -327,15 +328,15 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (JSONException ex) {
|
} catch (JSONException ex) {
|
||||||
System.err.println("JSONReconcileServlet JSONException: " + ex);
|
log.error("JSONException: " + ex);
|
||||||
throw new ServletException("JSONReconcileServlet JSONException: "
|
throw new ServletException("JSONReconcileServlet JSONException: "
|
||||||
+ ex);
|
+ ex);
|
||||||
} catch (SearchException ex) {
|
} catch (SearchException ex) {
|
||||||
System.err.println("JSONReconcileServlet SearchException: " + ex);
|
log.error("SearchException: " + ex);
|
||||||
throw new ServletException("JSONReconcileServlet SearchException: "
|
throw new ServletException("JSONReconcileServlet SearchException: "
|
||||||
+ ex);
|
+ ex);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
System.err.println("JSONReconcileServlet IOException: " + ex);
|
log.error("IOException: " + ex);
|
||||||
throw new ServletException("JSONReconcileServlet IOException: "
|
throw new ServletException("JSONReconcileServlet IOException: "
|
||||||
+ ex);
|
+ ex);
|
||||||
}
|
}
|
||||||
|
@ -354,30 +355,12 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
||||||
|
|
||||||
private Query makeReconcileNameQuery(String querystr, Analyzer analyzer, HttpServletRequest request) {
|
private Query makeReconcileNameQuery(String querystr, Analyzer analyzer, HttpServletRequest request) {
|
||||||
|
|
||||||
/* Original code
|
|
||||||
String tokenizeParam = (String) request.getParameter("tokenize");
|
|
||||||
boolean tokenize = "true".equals(tokenizeParam);
|
|
||||||
|
|
||||||
// Note: Stemming is only relevant if we are tokenizing: an untokenized name
|
|
||||||
// query will not be stemmed. So we don't look at the stem parameter until we get to
|
|
||||||
// makeTokenizedNameQuery().
|
|
||||||
if (tokenize) {
|
|
||||||
return makeTokenizedNameQuery(querystr, analyzer, request);
|
|
||||||
} else {
|
|
||||||
return makeUntokenizedNameQuery(querystr);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// modified code for reconciliation service
|
|
||||||
request.setAttribute("stem", true);
|
|
||||||
return makeTokenizedNameQuery(querystr, analyzer, request);
|
return makeTokenizedNameQuery(querystr, analyzer, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Query makeTokenizedNameQuery(String querystr, Analyzer analyzer, HttpServletRequest request) {
|
private Query makeTokenizedNameQuery(String querystr, Analyzer analyzer, HttpServletRequest request) {
|
||||||
|
|
||||||
String stemParam = (String) request.getParameter("stem");
|
String termName = VitroLuceneTermNames.NAME_STEMMED;
|
||||||
boolean stem = "true".equals(stemParam);
|
|
||||||
String termName = stem ? VitroLuceneTermNames.NAME_STEMMED : VitroLuceneTermNames.NAME_UNSTEMMED;
|
|
||||||
|
|
||||||
BooleanQuery boolQuery = new BooleanQuery();
|
BooleanQuery boolQuery = new BooleanQuery();
|
||||||
|
|
||||||
|
@ -408,23 +391,9 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
||||||
log.warn(e, e);
|
log.warn(e, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return boolQuery;
|
return boolQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Query makeUntokenizedNameQuery(String querystr) {
|
|
||||||
|
|
||||||
querystr = querystr.toLowerCase();
|
|
||||||
String termName = VitroLuceneTermNames.NAME_LOWERCASE;
|
|
||||||
BooleanQuery query = new BooleanQuery();
|
|
||||||
log.debug("Adding wildcard query on unanalyzed name");
|
|
||||||
query.add(
|
|
||||||
new WildcardQuery(new Term(termName, querystr + "*")),
|
|
||||||
BooleanClause.Occur.MUST);
|
|
||||||
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
private QueryParser getQueryParser(String searchField, Analyzer analyzer){
|
private QueryParser getQueryParser(String searchField, Analyzer analyzer){
|
||||||
// searchField indicates which field to search against when there is no term
|
// searchField indicates which field to search against when there is no term
|
||||||
// indicated in the query string.
|
// indicated in the query string.
|
||||||
|
@ -451,10 +420,8 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
query = makeReconcileNameQuery(querystr, analyzer, request);
|
query = makeReconcileNameQuery(querystr, analyzer, request);
|
||||||
|
|
||||||
|
|
||||||
// filter by type
|
// filter by type
|
||||||
if (typeParam != null) {
|
if (typeParam != null) {
|
||||||
BooleanQuery boolQuery = new BooleanQuery();
|
BooleanQuery boolQuery = new BooleanQuery();
|
||||||
|
@ -471,7 +438,7 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
String[] pvPair = it.next();
|
String[] pvPair = it.next();
|
||||||
Query extraQuery = makeReconcileNameQuery(pvPair[1], analyzer, request);
|
Query extraQuery = makeReconcileNameQuery(pvPair[1], analyzer, request);
|
||||||
if (!"".equals(pvPair[0]) && pvPair[0] != null) {
|
if ( ! StringUtils.isEmpty(pvPair[0]) ) {
|
||||||
BooleanQuery boolQuery = new BooleanQuery();
|
BooleanQuery boolQuery = new BooleanQuery();
|
||||||
boolQuery.add(new TermQuery(new Term(
|
boolQuery.add(new TermQuery(new Term(
|
||||||
VitroLuceneTermNames.RDFTYPE, pvPair[0])),
|
VitroLuceneTermNames.RDFTYPE, pvPair[0])),
|
||||||
|
@ -489,3 +456,4 @@ public class JSONReconcileServlet extends VitroHttpServlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class UserAccountsSelector {
|
||||||
+ "PREFIX fn: <http://www.w3.org/2005/xpath-functions#> \n"
|
+ "PREFIX fn: <http://www.w3.org/2005/xpath-functions#> \n"
|
||||||
+ "PREFIX auth: <http://vitro.mannlib.cornell.edu/ns/vitro/authorization#> \n";
|
+ "PREFIX auth: <http://vitro.mannlib.cornell.edu/ns/vitro/authorization#> \n";
|
||||||
|
|
||||||
private static final String ALL_VARIABLES = "?uri ?email ?firstName ?lastName ?pwd ?expire ?count ?status";
|
private static final String ALL_VARIABLES = "?uri ?email ?firstName ?lastName ?pwd ?expire ?count ?status ?isRoot";
|
||||||
|
|
||||||
private static final String COUNT_VARIABLE = "?uri";
|
private static final String COUNT_VARIABLE = "?uri";
|
||||||
|
|
||||||
|
@ -169,7 +169,8 @@ public class UserAccountsSelector {
|
||||||
+ " OPTIONAL { ?uri auth:md5password ?pwd } \n"
|
+ " OPTIONAL { ?uri auth:md5password ?pwd } \n"
|
||||||
+ " OPTIONAL { ?uri auth:passwordChangeExpires ?expire } \n"
|
+ " OPTIONAL { ?uri auth:passwordChangeExpires ?expire } \n"
|
||||||
+ " OPTIONAL { ?uri auth:loginCount ?count } \n"
|
+ " OPTIONAL { ?uri auth:loginCount ?count } \n"
|
||||||
+ " OPTIONAL { ?uri auth:status ?status }";
|
+ " OPTIONAL { ?uri auth:status ?status } \n"
|
||||||
|
+ " OPTIONAL { ?uri ?isRoot auth:RootUserAccount }";
|
||||||
}
|
}
|
||||||
|
|
||||||
private String filterClauses() {
|
private String filterClauses() {
|
||||||
|
@ -203,9 +204,8 @@ public class UserAccountsSelector {
|
||||||
/**
|
/**
|
||||||
* Escape any regex special characters in the string.
|
* Escape any regex special characters in the string.
|
||||||
*
|
*
|
||||||
* Note that the SPARQL
|
* Note that the SPARQL parser requires two backslashes, in order to pass a
|
||||||
* parser requires two backslashes, in order to pass a single backslash to
|
* single backslash to the REGEX function.
|
||||||
* the REGEX function.
|
|
||||||
*/
|
*/
|
||||||
private String escapeForRegex(String raw) {
|
private String escapeForRegex(String raw) {
|
||||||
StringBuilder clean = new StringBuilder();
|
StringBuilder clean = new StringBuilder();
|
||||||
|
@ -327,6 +327,7 @@ public class UserAccountsSelector {
|
||||||
user.setPasswordLinkExpires(ifLongPresent(solution, "expire", 0L));
|
user.setPasswordLinkExpires(ifLongPresent(solution, "expire", 0L));
|
||||||
user.setLoginCount(ifIntPresent(solution, "count", 0));
|
user.setLoginCount(ifIntPresent(solution, "count", 0));
|
||||||
user.setStatus(parseStatus(solution, "status", null));
|
user.setStatus(parseStatus(solution, "status", null));
|
||||||
|
user.setRootUser(solution.contains("isRoot"));
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Tem
|
||||||
public class UserAccountsAddPage extends UserAccountsPage {
|
public class UserAccountsAddPage extends UserAccountsPage {
|
||||||
private static final String PARAMETER_SUBMIT = "submitAdd";
|
private static final String PARAMETER_SUBMIT = "submitAdd";
|
||||||
private static final String PARAMETER_EMAIL_ADDRESS = "emailAddress";
|
private static final String PARAMETER_EMAIL_ADDRESS = "emailAddress";
|
||||||
|
private static final String PARAMETER_EXTERNAL_AUTH_ID = "externalAuthId";
|
||||||
private static final String PARAMETER_FIRST_NAME = "firstName";
|
private static final String PARAMETER_FIRST_NAME = "firstName";
|
||||||
private static final String PARAMETER_LAST_NAME = "lastName";
|
private static final String PARAMETER_LAST_NAME = "lastName";
|
||||||
private static final String PARAMETER_ROLE = "role";
|
private static final String PARAMETER_ROLE = "role";
|
||||||
|
@ -30,6 +31,7 @@ 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_EMAIL_INVALID_FORMAT = "errorEmailInvalidFormat";
|
||||||
|
private static final String ERROR_EXTERNAL_AUTH_ID_IN_USE = "errorExternalAuthIdInUse";
|
||||||
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";
|
||||||
|
@ -41,6 +43,7 @@ public class UserAccountsAddPage extends UserAccountsPage {
|
||||||
/* The request parameters */
|
/* The request parameters */
|
||||||
private boolean submit;
|
private boolean submit;
|
||||||
private String emailAddress = "";
|
private String emailAddress = "";
|
||||||
|
private String externalAuthId = "";
|
||||||
private String firstName = "";
|
private String firstName = "";
|
||||||
private String lastName = "";
|
private String lastName = "";
|
||||||
private String selectedRoleUri = "";
|
private String selectedRoleUri = "";
|
||||||
|
@ -68,6 +71,7 @@ public class UserAccountsAddPage extends UserAccountsPage {
|
||||||
private void parseRequestParameters() {
|
private void parseRequestParameters() {
|
||||||
submit = isFlagOnRequest(PARAMETER_SUBMIT);
|
submit = isFlagOnRequest(PARAMETER_SUBMIT);
|
||||||
emailAddress = getStringParameter(PARAMETER_EMAIL_ADDRESS, "");
|
emailAddress = getStringParameter(PARAMETER_EMAIL_ADDRESS, "");
|
||||||
|
externalAuthId = getStringParameter(PARAMETER_EXTERNAL_AUTH_ID, "");
|
||||||
firstName = getStringParameter(PARAMETER_FIRST_NAME, "");
|
firstName = getStringParameter(PARAMETER_FIRST_NAME, "");
|
||||||
lastName = getStringParameter(PARAMETER_LAST_NAME, "");
|
lastName = getStringParameter(PARAMETER_LAST_NAME, "");
|
||||||
selectedRoleUri = getStringParameter(PARAMETER_ROLE, "");
|
selectedRoleUri = getStringParameter(PARAMETER_ROLE, "");
|
||||||
|
@ -88,6 +92,8 @@ public class UserAccountsAddPage extends UserAccountsPage {
|
||||||
errorCode = ERROR_EMAIL_IN_USE;
|
errorCode = ERROR_EMAIL_IN_USE;
|
||||||
} else if (!isEmailValidFormat()) {
|
} else if (!isEmailValidFormat()) {
|
||||||
errorCode = ERROR_EMAIL_INVALID_FORMAT;
|
errorCode = ERROR_EMAIL_INVALID_FORMAT;
|
||||||
|
} else if (isExternalAuthIdInUse()) {
|
||||||
|
errorCode = ERROR_EXTERNAL_AUTH_ID_IN_USE;
|
||||||
} 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()) {
|
||||||
|
@ -103,6 +109,13 @@ public class UserAccountsAddPage extends UserAccountsPage {
|
||||||
return userAccountsDao.getUserAccountByEmail(emailAddress) != null;
|
return userAccountsDao.getUserAccountByEmail(emailAddress) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isExternalAuthIdInUse() {
|
||||||
|
if (externalAuthId.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return userAccountsDao.getUserAccountByExternalAuthId(externalAuthId) != null;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isEmailValidFormat() {
|
private boolean isEmailValidFormat() {
|
||||||
return Authenticator.isValidEmailAddress(emailAddress);
|
return Authenticator.isValidEmailAddress(emailAddress);
|
||||||
}
|
}
|
||||||
|
@ -116,7 +129,7 @@ public class UserAccountsAddPage extends UserAccountsPage {
|
||||||
u.setEmailAddress(emailAddress);
|
u.setEmailAddress(emailAddress);
|
||||||
u.setFirstName(firstName);
|
u.setFirstName(firstName);
|
||||||
u.setLastName(lastName);
|
u.setLastName(lastName);
|
||||||
u.setExternalAuthId("");
|
u.setExternalAuthId(externalAuthId);
|
||||||
|
|
||||||
u.setMd5Password("");
|
u.setMd5Password("");
|
||||||
u.setOldPassword("");
|
u.setOldPassword("");
|
||||||
|
@ -139,6 +152,7 @@ public class UserAccountsAddPage extends UserAccountsPage {
|
||||||
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("externalAuthId", externalAuthId);
|
||||||
body.put("firstName", firstName);
|
body.put("firstName", firstName);
|
||||||
body.put("lastName", lastName);
|
body.put("lastName", lastName);
|
||||||
body.put("selectedRole", selectedRoleUri);
|
body.put("selectedRole", selectedRoleUri);
|
||||||
|
|
|
@ -57,6 +57,7 @@ public abstract class UserAccountsAddPageStrategy extends UserAccountsPage {
|
||||||
|
|
||||||
private static class EmailStrategy extends UserAccountsAddPageStrategy {
|
private static class EmailStrategy extends UserAccountsAddPageStrategy {
|
||||||
public static final String CREATE_PASSWORD_URL = "/accounts/createPassword";
|
public static final String CREATE_PASSWORD_URL = "/accounts/createPassword";
|
||||||
|
private static final String EMAIL_TEMPLATE = "userAccounts-acctCreatedEmail.ftl";
|
||||||
|
|
||||||
private boolean sentEmail;
|
private boolean sentEmail;
|
||||||
|
|
||||||
|
@ -91,15 +92,14 @@ public abstract class UserAccountsAddPageStrategy extends UserAccountsPage {
|
||||||
Map<String, Object> body = new HashMap<String, Object>();
|
Map<String, Object> body = new HashMap<String, Object>();
|
||||||
body.put("userAccount", page.getAddedAccount());
|
body.put("userAccount", page.getAddedAccount());
|
||||||
body.put("passwordLink", buildCreatePasswordLink());
|
body.put("passwordLink", buildCreatePasswordLink());
|
||||||
body.put("subjectLine", "Your VIVO account has been created.");
|
|
||||||
|
|
||||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||||
.createNewMessage(vreq);
|
.createNewMessage(vreq);
|
||||||
email.addRecipient(TO, page.getAddedAccount().getEmailAddress());
|
email.addRecipient(TO, page.getAddedAccount().getEmailAddress());
|
||||||
email.setSubject("Your VIVO account has been created.");
|
email.setSubject("Your VIVO account has been created.");
|
||||||
email.setHtmlTemplate("userAccounts-acctCreatedEmail-html.ftl");
|
email.setTemplate(EMAIL_TEMPLATE);
|
||||||
email.setTextTemplate("userAccounts-acctCreatedEmail-text.ftl");
|
|
||||||
email.setBodyMap(body);
|
email.setBodyMap(body);
|
||||||
|
email.processTemplate();
|
||||||
email.send();
|
email.send();
|
||||||
|
|
||||||
sentEmail = true;
|
sentEmail = true;
|
||||||
|
|
|
@ -57,9 +57,9 @@ public class UserAccountsAdminController extends FreemarkerHttpServlet {
|
||||||
if (page.isSubmit() && page.isValid()) {
|
if (page.isSubmit() && page.isValid()) {
|
||||||
page.createNewAccount();
|
page.createNewAccount();
|
||||||
|
|
||||||
UserAccountsListPage listPage = new UserAccountsListPage(vreq);
|
UserAccountsListPage.Message.showNewAccount(vreq,
|
||||||
return listPage.showPageWithNewAccount(page.getAddedAccount(),
|
page.getAddedAccount(), page.wasPasswordEmailSent());
|
||||||
page.wasPasswordEmailSent());
|
return redirectToList();
|
||||||
} else {
|
} else {
|
||||||
return page.showPage();
|
return page.showPage();
|
||||||
}
|
}
|
||||||
|
@ -71,9 +71,10 @@ public class UserAccountsAdminController extends FreemarkerHttpServlet {
|
||||||
return showHomePage(vreq, page.getBogusMessage());
|
return showHomePage(vreq, page.getBogusMessage());
|
||||||
} else if (page.isSubmit() && page.isValid()) {
|
} else if (page.isSubmit() && page.isValid()) {
|
||||||
page.updateAccount();
|
page.updateAccount();
|
||||||
UserAccountsListPage listPage = new UserAccountsListPage(vreq);
|
|
||||||
return listPage.showPageWithUpdatedAccount(
|
UserAccountsListPage.Message.showUpdatedAccount(vreq,
|
||||||
page.getUpdatedAccount(), page.wasPasswordEmailSent());
|
page.getUpdatedAccount(), page.wasPasswordEmailSent());
|
||||||
|
return redirectToList();
|
||||||
} else {
|
} else {
|
||||||
return page.showPage();
|
return page.showPage();
|
||||||
}
|
}
|
||||||
|
@ -83,8 +84,8 @@ public class UserAccountsAdminController extends FreemarkerHttpServlet {
|
||||||
UserAccountsDeleter deleter = new UserAccountsDeleter(vreq);
|
UserAccountsDeleter deleter = new UserAccountsDeleter(vreq);
|
||||||
Collection<String> deletedUris = deleter.delete();
|
Collection<String> deletedUris = deleter.delete();
|
||||||
|
|
||||||
return new UserAccountsListPage(vreq)
|
UserAccountsListPage.Message.showDeletions(vreq, deletedUris);
|
||||||
.showPageWithDeletions(deletedUris);
|
return redirectToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseValues handleListRequest(VitroRequest vreq) {
|
private ResponseValues handleListRequest(VitroRequest vreq) {
|
||||||
|
@ -92,6 +93,14 @@ public class UserAccountsAdminController extends FreemarkerHttpServlet {
|
||||||
return page.showPage();
|
return page.showPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After an successful change, redirect to the list instead of forwarding.
|
||||||
|
* That way, a browser "refresh" won't try to repeat the operation.
|
||||||
|
*/
|
||||||
|
private ResponseValues redirectToList() {
|
||||||
|
return new RedirectResponseValues("/accountsAdmin/list");
|
||||||
|
}
|
||||||
|
|
||||||
private ResponseValues showHomePage(VitroRequest vreq, String message) {
|
private ResponseValues showHomePage(VitroRequest vreq, String message) {
|
||||||
DisplayMessage.setMessage(vreq, message);
|
DisplayMessage.setMessage(vreq, message);
|
||||||
return new RedirectResponseValues("/");
|
return new RedirectResponseValues("/");
|
||||||
|
|
|
@ -28,6 +28,7 @@ public class UserAccountsEditPage extends UserAccountsPage {
|
||||||
private static final String PARAMETER_SUBMIT = "submitEdit";
|
private static final String PARAMETER_SUBMIT = "submitEdit";
|
||||||
private static final String PARAMETER_USER_URI = "editAccount";
|
private static final String PARAMETER_USER_URI = "editAccount";
|
||||||
private static final String PARAMETER_EMAIL_ADDRESS = "emailAddress";
|
private static final String PARAMETER_EMAIL_ADDRESS = "emailAddress";
|
||||||
|
private static final String PARAMETER_EXTERNAL_AUTH_ID = "externalAuthId";
|
||||||
private static final String PARAMETER_FIRST_NAME = "firstName";
|
private static final String PARAMETER_FIRST_NAME = "firstName";
|
||||||
private static final String PARAMETER_LAST_NAME = "lastName";
|
private static final String PARAMETER_LAST_NAME = "lastName";
|
||||||
private static final String PARAMETER_ROLE = "role";
|
private static final String PARAMETER_ROLE = "role";
|
||||||
|
@ -36,6 +37,7 @@ public class UserAccountsEditPage 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_EMAIL_INVALID_FORMAT = "errorEmailInvalidFormat";
|
||||||
|
private static final String ERROR_EXTERNAL_AUTH_ID_IN_USE = "errorExternalAuthIdInUse";
|
||||||
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";
|
||||||
|
@ -48,6 +50,7 @@ public class UserAccountsEditPage extends UserAccountsPage {
|
||||||
private boolean submit;
|
private boolean submit;
|
||||||
private String userUri = "";
|
private String userUri = "";
|
||||||
private String emailAddress = "";
|
private String emailAddress = "";
|
||||||
|
private String externalAuthId = "";
|
||||||
private String firstName = "";
|
private String firstName = "";
|
||||||
private String lastName = "";
|
private String lastName = "";
|
||||||
private String selectedRoleUri = "";
|
private String selectedRoleUri = "";
|
||||||
|
@ -79,6 +82,7 @@ public class UserAccountsEditPage extends UserAccountsPage {
|
||||||
submit = isFlagOnRequest(PARAMETER_SUBMIT);
|
submit = isFlagOnRequest(PARAMETER_SUBMIT);
|
||||||
userUri = getStringParameter(PARAMETER_USER_URI, "");
|
userUri = getStringParameter(PARAMETER_USER_URI, "");
|
||||||
emailAddress = getStringParameter(PARAMETER_EMAIL_ADDRESS, "");
|
emailAddress = getStringParameter(PARAMETER_EMAIL_ADDRESS, "");
|
||||||
|
externalAuthId = getStringParameter(PARAMETER_EXTERNAL_AUTH_ID, "");
|
||||||
firstName = getStringParameter(PARAMETER_FIRST_NAME, "");
|
firstName = getStringParameter(PARAMETER_FIRST_NAME, "");
|
||||||
lastName = getStringParameter(PARAMETER_LAST_NAME, "");
|
lastName = getStringParameter(PARAMETER_LAST_NAME, "");
|
||||||
selectedRoleUri = getStringParameter(PARAMETER_ROLE, "");
|
selectedRoleUri = getStringParameter(PARAMETER_ROLE, "");
|
||||||
|
@ -117,11 +121,13 @@ public class UserAccountsEditPage extends UserAccountsPage {
|
||||||
errorCode = ERROR_EMAIL_IN_USE;
|
errorCode = ERROR_EMAIL_IN_USE;
|
||||||
} else if (!isEmailValidFormat()) {
|
} else if (!isEmailValidFormat()) {
|
||||||
errorCode = ERROR_EMAIL_INVALID_FORMAT;
|
errorCode = ERROR_EMAIL_INVALID_FORMAT;
|
||||||
|
} else if (externalAuthIdIsChanged() && isExternalAuthIdInUse()) {
|
||||||
|
errorCode = ERROR_EXTERNAL_AUTH_ID_IN_USE;
|
||||||
} 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 (!isRootUser() && selectedRoleUri.isEmpty()) {
|
||||||
errorCode = ERROR_NO_ROLE;
|
errorCode = ERROR_NO_ROLE;
|
||||||
} else {
|
} else {
|
||||||
errorCode = strategy.additionalValidations();
|
errorCode = strategy.additionalValidations();
|
||||||
|
@ -140,6 +146,21 @@ public class UserAccountsEditPage extends UserAccountsPage {
|
||||||
return Authenticator.isValidEmailAddress(emailAddress);
|
return Authenticator.isValidEmailAddress(emailAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean externalAuthIdIsChanged() {
|
||||||
|
return !externalAuthId.equals(userAccount.getExternalAuthId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isExternalAuthIdInUse() {
|
||||||
|
if (externalAuthId.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return userAccountsDao.getUserAccountByExternalAuthId(externalAuthId) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isRootUser() {
|
||||||
|
return ((userAccount != null) && userAccount.isRootUser());
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
return errorCode.isEmpty();
|
return errorCode.isEmpty();
|
||||||
}
|
}
|
||||||
|
@ -149,16 +170,22 @@ public class UserAccountsEditPage extends UserAccountsPage {
|
||||||
|
|
||||||
if (isSubmit()) {
|
if (isSubmit()) {
|
||||||
body.put("emailAddress", emailAddress);
|
body.put("emailAddress", emailAddress);
|
||||||
|
body.put("externalAuthId", externalAuthId);
|
||||||
body.put("firstName", firstName);
|
body.put("firstName", firstName);
|
||||||
body.put("lastName", lastName);
|
body.put("lastName", lastName);
|
||||||
body.put("selectedRole", selectedRoleUri);
|
body.put("selectedRole", selectedRoleUri);
|
||||||
} else {
|
} else {
|
||||||
body.put("emailAddress", userAccount.getEmailAddress());
|
body.put("emailAddress", userAccount.getEmailAddress());
|
||||||
|
body.put("externalAuthId", userAccount.getExternalAuthId());
|
||||||
body.put("firstName", userAccount.getFirstName());
|
body.put("firstName", userAccount.getFirstName());
|
||||||
body.put("lastName", userAccount.getLastName());
|
body.put("lastName", userAccount.getLastName());
|
||||||
body.put("selectedRole", getExistingRoleUri());
|
body.put("selectedRole", getExistingRoleUri());
|
||||||
}
|
}
|
||||||
body.put("roles", buildRolesList());
|
|
||||||
|
if (!isRootUser()) {
|
||||||
|
body.put("roles", buildRolesList());
|
||||||
|
}
|
||||||
|
|
||||||
if (associateWithProfile) {
|
if (associateWithProfile) {
|
||||||
body.put("associate", Boolean.TRUE);
|
body.put("associate", Boolean.TRUE);
|
||||||
}
|
}
|
||||||
|
@ -192,9 +219,14 @@ public class UserAccountsEditPage extends UserAccountsPage {
|
||||||
userAccount.setEmailAddress(emailAddress);
|
userAccount.setEmailAddress(emailAddress);
|
||||||
userAccount.setFirstName(firstName);
|
userAccount.setFirstName(firstName);
|
||||||
userAccount.setLastName(lastName);
|
userAccount.setLastName(lastName);
|
||||||
|
userAccount.setExternalAuthId(externalAuthId);
|
||||||
|
|
||||||
userAccount
|
if (isRootUser()) {
|
||||||
.setPermissionSetUris(Collections.singleton(selectedRoleUri));
|
userAccount.setPermissionSetUris(Collections.<String> emptySet());
|
||||||
|
} else {
|
||||||
|
userAccount.setPermissionSetUris(Collections
|
||||||
|
.singleton(selectedRoleUri));
|
||||||
|
}
|
||||||
|
|
||||||
strategy.setAdditionalProperties(userAccount);
|
strategy.setAdditionalProperties(userAccount);
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@ import java.net.URL;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
|
||||||
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.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.accounts.UserAccountsPage;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
|
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
|
||||||
|
@ -57,6 +57,7 @@ public abstract class UserAccountsEditPageStrategy extends UserAccountsPage {
|
||||||
|
|
||||||
private static class EmailStrategy extends UserAccountsEditPageStrategy {
|
private static class EmailStrategy extends UserAccountsEditPageStrategy {
|
||||||
private static final String PARAMETER_RESET_PASSWORD = "resetPassword";
|
private static final String PARAMETER_RESET_PASSWORD = "resetPassword";
|
||||||
|
private static final String EMAIL_TEMPLATE = "userAccounts-resetPasswordEmail.ftl";
|
||||||
|
|
||||||
public static final String RESET_PASSWORD_URL = "/accounts/resetPassword";
|
public static final String RESET_PASSWORD_URL = "/accounts/resetPassword";
|
||||||
|
|
||||||
|
@ -102,20 +103,24 @@ public abstract class UserAccountsEditPageStrategy extends UserAccountsPage {
|
||||||
Map<String, Object> body = new HashMap<String, Object>();
|
Map<String, Object> body = new HashMap<String, Object>();
|
||||||
body.put("userAccount", page.getUpdatedAccount());
|
body.put("userAccount", page.getUpdatedAccount());
|
||||||
body.put("passwordLink", buildResetPasswordLink());
|
body.put("passwordLink", buildResetPasswordLink());
|
||||||
body.put("subjectLine", "Reset password request");
|
body.put("siteName", getSiteName());
|
||||||
|
|
||||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||||
.createNewMessage(vreq);
|
.createNewMessage(vreq);
|
||||||
email.addRecipient(TO, page.getUpdatedAccount().getEmailAddress());
|
email.addRecipient(TO, page.getUpdatedAccount().getEmailAddress());
|
||||||
email.setSubject("Reset password request");
|
email.setTemplate(EMAIL_TEMPLATE);
|
||||||
email.setHtmlTemplate("userAccounts-resetPasswordEmail-html.ftl");
|
|
||||||
email.setTextTemplate("userAccounts-resetPasswordEmail-text.ftl");
|
|
||||||
email.setBodyMap(body);
|
email.setBodyMap(body);
|
||||||
|
email.processTemplate();
|
||||||
email.send();
|
email.send();
|
||||||
|
|
||||||
sentEmail = true;
|
sentEmail = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getSiteName() {
|
||||||
|
ApplicationBean appBean = vreq.getAppBean();
|
||||||
|
return appBean.getApplicationName();
|
||||||
|
}
|
||||||
|
|
||||||
private String buildResetPasswordLink() {
|
private String buildResetPasswordLink() {
|
||||||
try {
|
try {
|
||||||
String email = page.getUpdatedAccount().getEmailAddress();
|
String email = page.getUpdatedAccount().getEmailAddress();
|
||||||
|
|
|
@ -11,6 +11,9 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@ -19,12 +22,12 @@ 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.UserAccountsOrdering;
|
||||||
|
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.UserAccountsPage;
|
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.UserAccountsSelection;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsSelectionCriteria;
|
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.UserAccountsSelector;
|
||||||
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.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;
|
||||||
|
|
||||||
|
@ -91,55 +94,7 @@ public class UserAccountsListPage extends UserAccountsPage {
|
||||||
UserAccountsSelection selection = UserAccountsSelector.select(
|
UserAccountsSelection selection = UserAccountsSelector.select(
|
||||||
userAccountsModel, criteria);
|
userAccountsModel, criteria);
|
||||||
Map<String, Object> body = buildTemplateBodyMap(selection);
|
Map<String, Object> body = buildTemplateBodyMap(selection);
|
||||||
return new TemplateResponseValues(TEMPLATE_NAME, body);
|
Message.applyToBodyMap(vreq, body);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We just came from adding a new account. Show the list with a message.
|
|
||||||
*/
|
|
||||||
public ResponseValues showPageWithNewAccount(UserAccount userAccount,
|
|
||||||
boolean emailWasSent) {
|
|
||||||
UserAccountsSelection selection = UserAccountsSelector.select(
|
|
||||||
userAccountsModel, criteria);
|
|
||||||
Map<String, Object> body = buildTemplateBodyMap(selection);
|
|
||||||
|
|
||||||
body.put("newUserAccount", new UserAccountWrapper(userAccount,
|
|
||||||
Collections.<String> emptyList()));
|
|
||||||
if (emailWasSent) {
|
|
||||||
body.put("emailWasSent", Boolean.TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new TemplateResponseValues(TEMPLATE_NAME, body);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We just came from editing an account. Show the list with a message.
|
|
||||||
*/
|
|
||||||
public ResponseValues showPageWithUpdatedAccount(UserAccount userAccount,
|
|
||||||
boolean emailWasSent) {
|
|
||||||
UserAccountsSelection selection = UserAccountsSelector.select(
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We just came from deleting accounts. Show the list with a message.
|
|
||||||
*/
|
|
||||||
public ResponseValues showPageWithDeletions(Collection<String> deletedUris) {
|
|
||||||
UserAccountsSelection selection = UserAccountsSelector.select(
|
|
||||||
userAccountsModel, criteria);
|
|
||||||
Map<String, Object> body = buildTemplateBodyMap(selection);
|
|
||||||
|
|
||||||
body.put("deletedAccountCount", deletedUris.size());
|
|
||||||
|
|
||||||
return new TemplateResponseValues(TEMPLATE_NAME, body);
|
return new TemplateResponseValues(TEMPLATE_NAME, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,10 +193,15 @@ public class UserAccountsListPage extends UserAccountsPage {
|
||||||
|
|
||||||
private List<String> findPermissionSetLabels(UserAccount account) {
|
private List<String> findPermissionSetLabels(UserAccount account) {
|
||||||
List<String> labels = new ArrayList<String>();
|
List<String> labels = new ArrayList<String>();
|
||||||
for (String uri : account.getPermissionSetUris()) {
|
|
||||||
PermissionSet pSet = userAccountsDao.getPermissionSetByUri(uri);
|
if (account.isRootUser()) {
|
||||||
if (pSet != null) {
|
labels.add("ROOT");
|
||||||
labels.add(pSet.getLabel());
|
} else {
|
||||||
|
for (String uri : account.getPermissionSetUris()) {
|
||||||
|
PermissionSet pSet = userAccountsDao.getPermissionSetByUri(uri);
|
||||||
|
if (pSet != null) {
|
||||||
|
labels.add(pSet.getLabel());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return labels;
|
return labels;
|
||||||
|
@ -301,4 +261,84 @@ public class UserAccountsListPage extends UserAccountsPage {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message info that lives in the session. Another request can store this,
|
||||||
|
* and it will be displayed (once) by the list page.
|
||||||
|
*/
|
||||||
|
public static class Message {
|
||||||
|
private static final String ATTRIBUTE = Message.class.getName();
|
||||||
|
private static final Collection<String> EMPTY = Collections.emptySet();
|
||||||
|
|
||||||
|
public static void showNewAccount(HttpServletRequest req,
|
||||||
|
UserAccount userAccount, boolean emailWasSent) {
|
||||||
|
Message message = new Message(Type.NEW_ACCOUNT, userAccount,
|
||||||
|
emailWasSent, EMPTY);
|
||||||
|
setMessage(req, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void showUpdatedAccount(HttpServletRequest req,
|
||||||
|
UserAccount userAccount, boolean emailWasSent) {
|
||||||
|
Message message = new Message(Type.UPDATED_ACCOUNT, userAccount,
|
||||||
|
emailWasSent, EMPTY);
|
||||||
|
setMessage(req, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void showDeletions(HttpServletRequest req,
|
||||||
|
Collection<String> deletedUris) {
|
||||||
|
Message message = new Message(Type.DELETIONS, null, false,
|
||||||
|
deletedUris);
|
||||||
|
setMessage(req, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setMessage(HttpServletRequest req, Message message) {
|
||||||
|
req.getSession().setAttribute(ATTRIBUTE, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void applyToBodyMap(HttpServletRequest req,
|
||||||
|
Map<String, Object> body) {
|
||||||
|
HttpSession session = req.getSession();
|
||||||
|
Object o = session.getAttribute(ATTRIBUTE);
|
||||||
|
session.removeAttribute(ATTRIBUTE);
|
||||||
|
|
||||||
|
if (o instanceof Message) {
|
||||||
|
((Message) o).applyToBodyMap(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
NEW_ACCOUNT, UPDATED_ACCOUNT, DELETIONS
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Type type;
|
||||||
|
private final UserAccount userAccount;
|
||||||
|
private final boolean emailWasSent;
|
||||||
|
private final Collection<String> deletedUris;
|
||||||
|
|
||||||
|
public Message(Type type, UserAccount userAccount,
|
||||||
|
boolean emailWasSent, Collection<String> deletedUris) {
|
||||||
|
this.type = type;
|
||||||
|
this.userAccount = userAccount;
|
||||||
|
this.emailWasSent = emailWasSent;
|
||||||
|
this.deletedUris = deletedUris;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyToBodyMap(Map<String, Object> body) {
|
||||||
|
if (type == Type.NEW_ACCOUNT) {
|
||||||
|
body.put("newUserAccount", new UserAccountWrapper(userAccount,
|
||||||
|
Collections.<String> emptyList()));
|
||||||
|
if (emailWasSent) {
|
||||||
|
body.put("emailWasSent", Boolean.TRUE);
|
||||||
|
}
|
||||||
|
} else if (type == Type.UPDATED_ACCOUNT) {
|
||||||
|
body.put("updatedUserAccount", new UserAccountWrapper(
|
||||||
|
userAccount, Collections.<String> emptyList()));
|
||||||
|
if (emailWasSent) {
|
||||||
|
body.put("emailWasSent", Boolean.TRUE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
body.put("deletedAccountCount", deletedUris.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ public class UserAccountsCreatePasswordPage extends
|
||||||
.getLog(UserAccountsCreatePasswordPage.class);
|
.getLog(UserAccountsCreatePasswordPage.class);
|
||||||
|
|
||||||
private static final String TEMPLATE_NAME = "userAccounts-createPassword.ftl";
|
private static final String TEMPLATE_NAME = "userAccounts-createPassword.ftl";
|
||||||
|
private static final String EMAIL_TEMPLATE = "userAccounts-passwordCreatedEmail.ftl";
|
||||||
|
|
||||||
public UserAccountsCreatePasswordPage(VitroRequest vreq) {
|
public UserAccountsCreatePasswordPage(VitroRequest vreq) {
|
||||||
super(vreq);
|
super(vreq);
|
||||||
|
@ -56,15 +57,14 @@ public class UserAccountsCreatePasswordPage extends
|
||||||
private void notifyUser() {
|
private void notifyUser() {
|
||||||
Map<String, Object> body = new HashMap<String, Object>();
|
Map<String, Object> body = new HashMap<String, Object>();
|
||||||
body.put("userAccount", userAccount);
|
body.put("userAccount", userAccount);
|
||||||
body.put("subjectLine", "Password successfully created.");
|
|
||||||
|
|
||||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||||
.createNewMessage(vreq);
|
.createNewMessage(vreq);
|
||||||
email.addRecipient(TO, userAccount.getEmailAddress());
|
email.addRecipient(TO, userAccount.getEmailAddress());
|
||||||
email.setSubject("Password successfully created.");
|
email.setSubject("Password successfully created.");
|
||||||
email.setHtmlTemplate("userAccounts-passwordCreatedEmail-html.ftl");
|
email.setTemplate(EMAIL_TEMPLATE);
|
||||||
email.setTextTemplate("userAccounts-passwordCreatedEmail-text.ftl");
|
|
||||||
email.setBodyMap(body);
|
email.setBodyMap(body);
|
||||||
|
email.processTemplate();
|
||||||
email.send();
|
email.send();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ import java.util.Map;
|
||||||
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 edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSetsLoader;
|
import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSetsLoader;
|
||||||
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;
|
||||||
|
@ -22,13 +24,14 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Tem
|
||||||
* Handle the first-time login of an Externally Authenticated user who has no
|
* Handle the first-time login of an Externally Authenticated user who has no
|
||||||
* UserAccount - let's create one!
|
* UserAccount - let's create one!
|
||||||
*
|
*
|
||||||
* If they get here from the login, there should an externalAuthId waiting in
|
* If they get here from the login, there should be an ExternalLoginInfo waiting
|
||||||
* the session. Otherwise, they should get here by submitting the form, which
|
* in the session. Otherwise, they should get here by submitting the form, which
|
||||||
* will have the externalAuthId as a hidden field.
|
* will have the info in hidden fields.
|
||||||
*/
|
*/
|
||||||
public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
||||||
private static final String PARAMETER_SUBMIT = "submit";
|
private static final String PARAMETER_SUBMIT = "submit";
|
||||||
private static final String PARAMETER_EXTERNAL_AUTH_ID = "externalAuthId";
|
private static final String PARAMETER_EXTERNAL_AUTH_ID = "externalAuthId";
|
||||||
|
private static final String PARAMETER_AFTER_LOGIN_URL = "afterLoginUrl";
|
||||||
private static final String PARAMETER_EMAIL_ADDRESS = "emailAddress";
|
private static final String PARAMETER_EMAIL_ADDRESS = "emailAddress";
|
||||||
private static final String PARAMETER_FIRST_NAME = "firstName";
|
private static final String PARAMETER_FIRST_NAME = "firstName";
|
||||||
private static final String PARAMETER_LAST_NAME = "lastName";
|
private static final String PARAMETER_LAST_NAME = "lastName";
|
||||||
|
@ -41,23 +44,25 @@ public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
||||||
|
|
||||||
private static final String TEMPLATE_NAME = "userAccounts-firstTimeExternal.ftl";
|
private static final String TEMPLATE_NAME = "userAccounts-firstTimeExternal.ftl";
|
||||||
|
|
||||||
private static final String ATTRIBUTE_EXTERNAL_AUTH_ID = UserAccountsFirstTimeExternalPage.class
|
private static final String ATTRIBUTE_EXTERNAL_LOGIN_INFO = UserAccountsFirstTimeExternalPage.class
|
||||||
.getName();
|
.getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Let some other request set the External Auth ID before redirecting to
|
* Let some other request set the External Auth ID and the afterLogin URL
|
||||||
* here.
|
* before redirecting to here.
|
||||||
*/
|
*/
|
||||||
public static void setExternalAuthId(HttpServletRequest req,
|
public static void setExternalLoginInfo(HttpServletRequest req,
|
||||||
String externalAuthId) {
|
String externalAuthId, String afterLoginUrl) {
|
||||||
req.getSession().setAttribute(ATTRIBUTE_EXTERNAL_AUTH_ID,
|
req.getSession().setAttribute(ATTRIBUTE_EXTERNAL_LOGIN_INFO,
|
||||||
externalAuthId);
|
new ExternalLoginInfo(externalAuthId, afterLoginUrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
private final UserAccountsFirstTimeExternalPageStrategy strategy;
|
private final UserAccountsFirstTimeExternalPageStrategy strategy;
|
||||||
|
|
||||||
private boolean submit = false;
|
|
||||||
private String externalAuthId = "";
|
private String externalAuthId = "";
|
||||||
|
private String afterLoginUrl = "";
|
||||||
|
|
||||||
|
private boolean submit = false;
|
||||||
private String emailAddress = "";
|
private String emailAddress = "";
|
||||||
private String firstName = "";
|
private String firstName = "";
|
||||||
private String lastName = "";
|
private String lastName = "";
|
||||||
|
@ -71,7 +76,7 @@ public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
||||||
this.strategy = UserAccountsFirstTimeExternalPageStrategy.getInstance(
|
this.strategy = UserAccountsFirstTimeExternalPageStrategy.getInstance(
|
||||||
vreq, this, isEmailEnabled());
|
vreq, this, isEmailEnabled());
|
||||||
|
|
||||||
checkSessionForExternalAuthId();
|
checkSessionForExternalLoginInfo();
|
||||||
if (externalAuthId.isEmpty()) {
|
if (externalAuthId.isEmpty()) {
|
||||||
parseRequestParameters();
|
parseRequestParameters();
|
||||||
}
|
}
|
||||||
|
@ -83,20 +88,26 @@ public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkSessionForExternalAuthId() {
|
private void checkSessionForExternalLoginInfo() {
|
||||||
HttpSession session = vreq.getSession();
|
HttpSession session = vreq.getSession();
|
||||||
|
|
||||||
Object o = session.getAttribute(ATTRIBUTE_EXTERNAL_AUTH_ID);
|
Object o = session.getAttribute(ATTRIBUTE_EXTERNAL_LOGIN_INFO);
|
||||||
session.removeAttribute(ATTRIBUTE_EXTERNAL_AUTH_ID);
|
session.removeAttribute(ATTRIBUTE_EXTERNAL_LOGIN_INFO);
|
||||||
|
|
||||||
if (o instanceof String) {
|
if (o instanceof ExternalLoginInfo) {
|
||||||
externalAuthId = (String) o;
|
externalAuthId = ((ExternalLoginInfo) o).externalAuthId;
|
||||||
|
afterLoginUrl = ((ExternalLoginInfo) o).afterLoginUrl;
|
||||||
|
if (afterLoginUrl == null) {
|
||||||
|
afterLoginUrl = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseRequestParameters() {
|
private void parseRequestParameters() {
|
||||||
submit = isFlagOnRequest(PARAMETER_SUBMIT);
|
|
||||||
externalAuthId = getStringParameter(PARAMETER_EXTERNAL_AUTH_ID, "");
|
externalAuthId = getStringParameter(PARAMETER_EXTERNAL_AUTH_ID, "");
|
||||||
|
afterLoginUrl = getStringParameter(PARAMETER_AFTER_LOGIN_URL, "");
|
||||||
|
|
||||||
|
submit = isFlagOnRequest(PARAMETER_SUBMIT);
|
||||||
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, "");
|
||||||
|
@ -156,10 +167,12 @@ public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
||||||
public final ResponseValues showPage() {
|
public final ResponseValues showPage() {
|
||||||
Map<String, Object> body = new HashMap<String, Object>();
|
Map<String, Object> body = new HashMap<String, Object>();
|
||||||
|
|
||||||
|
body.put("externalAuthId", externalAuthId);
|
||||||
|
body.put("afterLoginUrl", afterLoginUrl);
|
||||||
|
|
||||||
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("externalAuthId", externalAuthId);
|
|
||||||
body.put("formUrls", buildUrlsMap());
|
body.put("formUrls", buildUrlsMap());
|
||||||
|
|
||||||
if (!errorCode.isEmpty()) {
|
if (!errorCode.isEmpty()) {
|
||||||
|
@ -191,4 +204,25 @@ public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the afterLoginUrl is missing, go to the home page. If it is relative,
|
||||||
|
* make sure it doesn't start with the cotext path.
|
||||||
|
*/
|
||||||
|
public String getAfterLoginUrl() {
|
||||||
|
if (StringUtils.isEmpty(afterLoginUrl)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return afterLoginUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ExternalLoginInfo {
|
||||||
|
final String externalAuthId;
|
||||||
|
final String afterLoginUrl;
|
||||||
|
|
||||||
|
public ExternalLoginInfo(String externalAuthId, String afterLoginUrl) {
|
||||||
|
this.externalAuthId = externalAuthId;
|
||||||
|
this.afterLoginUrl = afterLoginUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,8 @@ public abstract class UserAccountsFirstTimeExternalPageStrategy extends
|
||||||
public static class EmailStrategy extends
|
public static class EmailStrategy extends
|
||||||
UserAccountsFirstTimeExternalPageStrategy {
|
UserAccountsFirstTimeExternalPageStrategy {
|
||||||
|
|
||||||
|
private static final String EMAIL_TEMPLATE = "userAccounts-firstTimeExternalEmail.ftl";
|
||||||
|
|
||||||
public EmailStrategy(VitroRequest vreq,
|
public EmailStrategy(VitroRequest vreq,
|
||||||
UserAccountsFirstTimeExternalPage page) {
|
UserAccountsFirstTimeExternalPage page) {
|
||||||
super(vreq, page);
|
super(vreq, page);
|
||||||
|
@ -66,15 +68,14 @@ public abstract class UserAccountsFirstTimeExternalPageStrategy extends
|
||||||
public void notifyUser(UserAccount ua) {
|
public void notifyUser(UserAccount ua) {
|
||||||
Map<String, Object> body = new HashMap<String, Object>();
|
Map<String, Object> body = new HashMap<String, Object>();
|
||||||
body.put("userAccount", ua);
|
body.put("userAccount", ua);
|
||||||
body.put("subjectLine", "Your VIVO account has been created.");
|
|
||||||
|
|
||||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||||
.createNewMessage(vreq);
|
.createNewMessage(vreq);
|
||||||
email.addRecipient(TO, ua.getEmailAddress());
|
email.addRecipient(TO, ua.getEmailAddress());
|
||||||
email.setSubject("Your VIVO account has been created.");
|
email.setSubject("Your VIVO account has been created.");
|
||||||
email.setHtmlTemplate("userAccounts-firstTimeExternalEmail-html.ftl");
|
email.setTemplate(EMAIL_TEMPLATE);
|
||||||
email.setTextTemplate("userAccounts-firstTimeExternalEmail-text.ftl");
|
|
||||||
email.setBodyMap(body);
|
email.setBodyMap(body);
|
||||||
|
email.processTemplate();
|
||||||
email.send();
|
email.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,8 @@ public abstract class UserAccountsMyAccountPageStrategy extends
|
||||||
private static final String ERROR_WRONG_PASSWORD_LENGTH = "errorPasswordIsWrongLength";
|
private static final String ERROR_WRONG_PASSWORD_LENGTH = "errorPasswordIsWrongLength";
|
||||||
private static final String ERROR_PASSWORDS_DONT_MATCH = "errorPasswordsDontMatch";
|
private static final String ERROR_PASSWORDS_DONT_MATCH = "errorPasswordsDontMatch";
|
||||||
|
|
||||||
|
private static final String EMAIL_TEMPLATE = "userAccounts-confirmEmailChangedEmail.ftl";
|
||||||
|
|
||||||
private final String originalEmail;
|
private final String originalEmail;
|
||||||
|
|
||||||
private String newPassword;
|
private String newPassword;
|
||||||
|
@ -167,15 +169,14 @@ public abstract class UserAccountsMyAccountPageStrategy extends
|
||||||
|
|
||||||
Map<String, Object> body = new HashMap<String, Object>();
|
Map<String, Object> body = new HashMap<String, Object>();
|
||||||
body.put("userAccount", page.getUserAccount());
|
body.put("userAccount", page.getUserAccount());
|
||||||
body.put("subjectLine", "Your VIVO email account has been changed.");
|
|
||||||
|
|
||||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||||
.createNewMessage(vreq);
|
.createNewMessage(vreq);
|
||||||
email.addRecipient(TO, page.getUserAccount().getEmailAddress());
|
email.addRecipient(TO, page.getUserAccount().getEmailAddress());
|
||||||
email.setSubject("Your VIVO email account has been changed.");
|
email.setSubject("Your VIVO email account has been changed.");
|
||||||
email.setHtmlTemplate("userAccounts-confirmEmailChangedEmail-html.ftl");
|
email.setTemplate(EMAIL_TEMPLATE);
|
||||||
email.setTextTemplate("userAccounts-confirmEmailChangedEmail-text.ftl");
|
|
||||||
email.setBodyMap(body);
|
email.setBodyMap(body);
|
||||||
|
email.processTemplate();
|
||||||
email.send();
|
email.send();
|
||||||
|
|
||||||
emailSent = true;
|
emailSent = true;
|
||||||
|
|
|
@ -26,6 +26,8 @@ public class UserAccountsResetPasswordPage extends UserAccountsPasswordBasePage
|
||||||
|
|
||||||
private static final String TEMPLATE_NAME = "userAccounts-resetPassword.ftl";
|
private static final String TEMPLATE_NAME = "userAccounts-resetPassword.ftl";
|
||||||
|
|
||||||
|
private static final String EMAIL_TEMPLATE = "userAccounts-passwordResetEmail.ftl";
|
||||||
|
|
||||||
protected UserAccountsResetPasswordPage(VitroRequest vreq) {
|
protected UserAccountsResetPasswordPage(VitroRequest vreq) {
|
||||||
super(vreq);
|
super(vreq);
|
||||||
}
|
}
|
||||||
|
@ -55,15 +57,14 @@ public class UserAccountsResetPasswordPage extends UserAccountsPasswordBasePage
|
||||||
private void notifyUser() {
|
private void notifyUser() {
|
||||||
Map<String, Object> body = new HashMap<String, Object>();
|
Map<String, Object> body = new HashMap<String, Object>();
|
||||||
body.put("userAccount", userAccount);
|
body.put("userAccount", userAccount);
|
||||||
body.put("subjectLine", "Password changed.");
|
|
||||||
|
|
||||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||||
.createNewMessage(vreq);
|
.createNewMessage(vreq);
|
||||||
email.addRecipient(TO, userAccount.getEmailAddress());
|
email.addRecipient(TO, userAccount.getEmailAddress());
|
||||||
email.setSubject("Password changed.");
|
email.setSubject("Password changed.");
|
||||||
email.setHtmlTemplate("userAccounts-passwordResetEmail-html.ftl");
|
email.setTemplate(EMAIL_TEMPLATE);
|
||||||
email.setTextTemplate("userAccounts-passwordResetEmail-text.ftl");
|
|
||||||
email.setBodyMap(body);
|
email.setBodyMap(body);
|
||||||
|
email.processTemplate();
|
||||||
email.send();
|
email.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,10 @@ package edu.cornell.mannlib.vitro.webapp.controller.accounts.user;
|
||||||
|
|
||||||
import static edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource.EXTERNAL;
|
import static edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource.EXTERNAL;
|
||||||
|
|
||||||
|
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.AuthenticationSource;
|
|
||||||
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.EditOwnAccount;
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOwnAccount;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
|
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
|
||||||
|
@ -115,9 +115,7 @@ public class UserAccountsUserController extends FreemarkerHttpServlet {
|
||||||
UserAccount userAccount = page.createAccount();
|
UserAccount userAccount = page.createAccount();
|
||||||
Authenticator auth = Authenticator.getInstance(vreq);
|
Authenticator auth = Authenticator.getInstance(vreq);
|
||||||
auth.recordLoginAgainstUserAccount(userAccount, EXTERNAL);
|
auth.recordLoginAgainstUserAccount(userAccount, EXTERNAL);
|
||||||
LoginProcessBean.removeBean(vreq);
|
return showLoginRedirection(vreq, page.getAfterLoginUrl());
|
||||||
|
|
||||||
return showLoginRedirection(vreq);
|
|
||||||
} else {
|
} else {
|
||||||
return page.showPage();
|
return page.showPage();
|
||||||
}
|
}
|
||||||
|
@ -132,10 +130,31 @@ public class UserAccountsUserController extends FreemarkerHttpServlet {
|
||||||
return new RedirectResponseValues("/");
|
return new RedirectResponseValues("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseValues showLoginRedirection(VitroRequest vreq) {
|
private ResponseValues showLoginRedirection(VitroRequest vreq,
|
||||||
LoginRedirector lr = new LoginRedirector(vreq);
|
String afterLoginUrl) {
|
||||||
|
LoginRedirector lr = new LoginRedirector(vreq, afterLoginUrl);
|
||||||
DisplayMessage.setMessage(vreq, lr.assembleWelcomeMessage());
|
DisplayMessage.setMessage(vreq, lr.assembleWelcomeMessage());
|
||||||
String uri = lr.getRedirectionUriForLoggedInUser();
|
String uri = lr.getRedirectionUriForLoggedInUser();
|
||||||
return new RedirectResponseValues(uri);
|
return new RedirectResponseValues(stripContextPath(vreq, uri));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO The LoginRedirector gives a URI that includes the context path. But
|
||||||
|
* the RedirectResponseValues wants a URI that does not include the context
|
||||||
|
* path.
|
||||||
|
*
|
||||||
|
* Bridge the gap.
|
||||||
|
*/
|
||||||
|
private String stripContextPath(VitroRequest vreq, String uri) {
|
||||||
|
if ((uri == null) || uri.isEmpty() || uri.equals(vreq.getContextPath())) {
|
||||||
|
return "/";
|
||||||
|
}
|
||||||
|
if (uri.contains("://")) {
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
if (uri.startsWith(vreq.getContextPath() + '/')) {
|
||||||
|
return uri.substring(vreq.getContextPath().length());
|
||||||
|
}
|
||||||
|
return uri;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,10 +51,10 @@ public abstract class Authenticator {
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
/** Maximum inactive interval for a ordinary logged-in session, in seconds. */
|
/** Maximum inactive interval for a ordinary logged-in session, in seconds. */
|
||||||
public static final int LOGGED_IN_TIMEOUT_INTERVAL = 300;
|
public static final int LOGGED_IN_TIMEOUT_INTERVAL = 60 * 60;
|
||||||
|
|
||||||
/** Maximum inactive interval for a editor (or better) session, in seconds. */
|
/** Maximum inactive interval for a editor (or better) session, in seconds. */
|
||||||
public static final int PRIVILEGED_TIMEOUT_INTERVAL = 32000;
|
public static final int PRIVILEGED_TIMEOUT_INTERVAL = 60 * 60 * 8;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the UserAccount for this external ID, or null if there is none.
|
* Get the UserAccount for this external ID, or null if there is none.
|
||||||
|
@ -96,8 +96,9 @@ public abstract class Authenticator {
|
||||||
* <pre>
|
* <pre>
|
||||||
* Record that the user has logged in, with all of the housekeeping that
|
* Record that the user has logged in, with all of the housekeeping that
|
||||||
* goes with it:
|
* goes with it:
|
||||||
* - updating the user record
|
* - update the user record
|
||||||
* - setting login status and timeout limit in the session
|
* - set login status and timeout limit in the session
|
||||||
|
* - refresh the Identifiers on the request
|
||||||
* - record the user in the session map
|
* - record the user in the session map
|
||||||
* - notify other users of the model
|
* - notify other users of the model
|
||||||
* </pre>
|
* </pre>
|
||||||
|
@ -105,17 +106,6 @@ public abstract class Authenticator {
|
||||||
public abstract void recordLoginAgainstUserAccount(UserAccount userAccount,
|
public abstract void recordLoginAgainstUserAccount(UserAccount userAccount,
|
||||||
AuthenticationSource authSource);
|
AuthenticationSource authSource);
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* Record that the user has logged in but with only external authentication
|
|
||||||
* info, so no internal user account.
|
|
||||||
* - this involves everything except updating the user record.
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* TODO JB This goes away.
|
|
||||||
*/
|
|
||||||
public abstract void recordLoginWithoutUserAccount(String individualUri);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
* Record that the current user has logged out: - notify other users of the
|
* Record that the current user has logged out: - notify other users of the
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
|
package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -16,6 +15,7 @@ import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
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.identifier.RequestIdentifiers;
|
||||||
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;
|
||||||
|
@ -123,24 +123,13 @@ public class BasicAuthenticator extends Authenticator {
|
||||||
}
|
}
|
||||||
|
|
||||||
recordLoginOnUserRecord(userAccount);
|
recordLoginOnUserRecord(userAccount);
|
||||||
recordLoginWithOrWithoutUserAccount(userAccount.getUri(), authSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO JB This goes away.
|
|
||||||
@Override
|
|
||||||
public void recordLoginWithoutUserAccount(String individualUri) {
|
|
||||||
recordLoginWithOrWithoutUserAccount(individualUri,
|
|
||||||
AuthenticationSource.EXTERNAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This much is in common on login, whether or not you have a user account. */
|
|
||||||
private void recordLoginWithOrWithoutUserAccount(String userUri,
|
|
||||||
AuthenticationSource authSource) {
|
|
||||||
HttpSession session = request.getSession();
|
HttpSession session = request.getSession();
|
||||||
createLoginStatusBean(userUri, authSource, session);
|
createLoginStatusBean(userAccount.getUri(), authSource, session);
|
||||||
setSessionTimeoutLimit(session);
|
RequestIdentifiers.resetIdentifiers(request);
|
||||||
recordInUserSessionMap(userUri, session);
|
setSessionTimeoutLimit(userAccount, session);
|
||||||
notifyOtherUsers(userUri, session);
|
recordInUserSessionMap(userAccount.getUri(), session);
|
||||||
|
notifyOtherUsers(userAccount.getUri(), session);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -164,11 +153,14 @@ 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(UserAccount userAccount,
|
||||||
|
HttpSession session) {
|
||||||
RoleLevel role = RoleLevel.getRoleFromLoginStatus(request);
|
RoleLevel role = RoleLevel.getRoleFromLoginStatus(request);
|
||||||
if (role == RoleLevel.EDITOR || role == RoleLevel.CURATOR
|
if (role == RoleLevel.EDITOR || role == RoleLevel.CURATOR
|
||||||
|| role == RoleLevel.DB_ADMIN) {
|
|| role == RoleLevel.DB_ADMIN) {
|
||||||
session.setMaxInactiveInterval(PRIVILEGED_TIMEOUT_INTERVAL);
|
session.setMaxInactiveInterval(PRIVILEGED_TIMEOUT_INTERVAL);
|
||||||
|
} else if (userAccount.isRootUser()) {
|
||||||
|
session.setMaxInactiveInterval(PRIVILEGED_TIMEOUT_INTERVAL);
|
||||||
} else {
|
} else {
|
||||||
session.setMaxInactiveInterval(LOGGED_IN_TIMEOUT_INTERVAL);
|
session.setMaxInactiveInterval(LOGGED_IN_TIMEOUT_INTERVAL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
|
||||||
import static edu.cornell.mannlib.vitro.webapp.controller.authenticate.LoginExternalAuthSetup.ATTRIBUTE_REFERRER;
|
import static edu.cornell.mannlib.vitro.webapp.controller.authenticate.LoginExternalAuthSetup.ATTRIBUTE_REFERRER;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
@ -16,6 +15,9 @@ 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;
|
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.accounts.user.UserAccountsFirstTimeExternalPage;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the return from the external authorization login server. If we are
|
* Handle the return from the external authorization login server. If we are
|
||||||
|
@ -36,6 +38,13 @@ public class LoginExternalAuthReturn extends BaseLoginServlet {
|
||||||
* - User corresponds to a User acocunt. Record the login.
|
* - User corresponds to a User acocunt. Record the login.
|
||||||
* - User corresponds to an Individual (self-editor).
|
* - User corresponds to an Individual (self-editor).
|
||||||
* - User is not recognized.
|
* - User is not recognized.
|
||||||
|
*
|
||||||
|
* On entry, we expect to find:
|
||||||
|
* - A LoginProcessBean, which will give us the afterLoginUrl if the login
|
||||||
|
* succeeds.
|
||||||
|
* - A referrer URL, to which we will redirect if the login fails.
|
||||||
|
* TODO: is this equal to LoginProcessBean.getLoginPageUrl()?
|
||||||
|
* These are removed on exit.
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -50,39 +59,30 @@ public class LoginExternalAuthReturn extends BaseLoginServlet {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String afterLoginUrl = LoginProcessBean.getBean(req).getAfterLoginUrl();
|
||||||
|
removeLoginProcessArtifacts(req);
|
||||||
|
|
||||||
UserAccount userAccount = getAuthenticator(req)
|
UserAccount userAccount = getAuthenticator(req)
|
||||||
.getAccountForExternalAuth(externalAuthId);
|
.getAccountForExternalAuth(externalAuthId);
|
||||||
if (userAccount != null) {
|
if (userAccount == null) {
|
||||||
|
log.debug("Creating new account for " + externalAuthId
|
||||||
|
+ ", return to '" + afterLoginUrl + "'");
|
||||||
|
UserAccountsFirstTimeExternalPage.setExternalLoginInfo(req,
|
||||||
|
externalAuthId, afterLoginUrl);
|
||||||
|
resp.sendRedirect(UrlBuilder.getUrl("/accounts/firstTimeExternal"));
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
log.debug("Logging in as " + userAccount.getUri());
|
log.debug("Logging in as " + userAccount.getUri());
|
||||||
getAuthenticator(req).recordLoginAgainstUserAccount(userAccount,
|
getAuthenticator(req).recordLoginAgainstUserAccount(userAccount,
|
||||||
AuthenticationSource.EXTERNAL);
|
AuthenticationSource.EXTERNAL);
|
||||||
removeLoginProcessArtifacts(req);
|
new LoginRedirector(req, afterLoginUrl).redirectLoggedInUser(resp);
|
||||||
new LoginRedirector(req).redirectLoggedInUser(resp);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
String uri = associatedUris.get(0);
|
|
||||||
|
|
||||||
getAuthenticator(req).recordLoginWithoutUserAccount(uri);
|
|
||||||
removeLoginProcessArtifacts(req);
|
|
||||||
new LoginRedirector(req).redirectLoggedInUser(resp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
log.debug("User is not recognized: " + externalAuthId);
|
|
||||||
removeLoginProcessArtifacts(req);
|
|
||||||
new LoginRedirector(req).redirectUnrecognizedExternalUser(resp,
|
|
||||||
externalAuthId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeLoginProcessArtifacts(HttpServletRequest req) {
|
private void removeLoginProcessArtifacts(HttpServletRequest req) {
|
||||||
req.getSession().removeAttribute(ATTRIBUTE_REFERRER);
|
req.getSession().removeAttribute(ATTRIBUTE_REFERRER);
|
||||||
|
LoginProcessBean.removeBean(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -16,11 +16,14 @@ 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.auth.identifier.IdentifierBundle;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasRoleLevel;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsRootUser;
|
||||||
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.DisplayMessage;
|
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A user has just completed the login process. What page do we direct them to?
|
* A user has just completed the login process. What page do we direct them to?
|
||||||
|
@ -34,15 +37,12 @@ public class LoginRedirector {
|
||||||
private final String uriOfAssociatedIndividual;
|
private final String uriOfAssociatedIndividual;
|
||||||
private final String afterLoginPage;
|
private final String afterLoginPage;
|
||||||
|
|
||||||
public LoginRedirector(HttpServletRequest request) {
|
public LoginRedirector(HttpServletRequest request, String afterLoginPage) {
|
||||||
this.request = request;
|
this.request = request;
|
||||||
this.session = request.getSession();
|
this.session = request.getSession();
|
||||||
|
this.afterLoginPage = afterLoginPage;
|
||||||
|
|
||||||
uriOfAssociatedIndividual = getAssociatedIndividualUri();
|
uriOfAssociatedIndividual = getAssociatedIndividualUri();
|
||||||
|
|
||||||
LoginProcessBean processBean = LoginProcessBean.getBean(request);
|
|
||||||
log.debug("process bean is: " + processBean);
|
|
||||||
afterLoginPage = processBean.getAfterLoginUrl();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Is there an Individual associated with this user? */
|
/** Is there an Individual associated with this user? */
|
||||||
|
@ -106,7 +106,6 @@ public class LoginRedirector {
|
||||||
try {
|
try {
|
||||||
DisplayMessage.setMessage(request, assembleWelcomeMessage());
|
DisplayMessage.setMessage(request, assembleWelcomeMessage());
|
||||||
response.sendRedirect(getRedirectionUriForLoggedInUser());
|
response.sendRedirect(getRedirectionUriForLoggedInUser());
|
||||||
LoginProcessBean.removeBean(request);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.debug("Problem with re-direction", e);
|
log.debug("Problem with re-direction", e);
|
||||||
response.sendRedirect(getApplicationHomePageUrl());
|
response.sendRedirect(getApplicationHomePageUrl());
|
||||||
|
@ -142,7 +141,6 @@ public class LoginRedirector {
|
||||||
throws IOException {
|
throws IOException {
|
||||||
try {
|
try {
|
||||||
response.sendRedirect(getRedirectionUriForCancellingUser());
|
response.sendRedirect(getRedirectionUriForCancellingUser());
|
||||||
LoginProcessBean.removeBean(request);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.debug("Problem with re-direction", e);
|
log.debug("Problem with re-direction", e);
|
||||||
response.sendRedirect(getApplicationHomePageUrl());
|
response.sendRedirect(getApplicationHomePageUrl());
|
||||||
|
@ -158,7 +156,12 @@ public class LoginRedirector {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isMerelySelfEditor() {
|
private boolean isMerelySelfEditor() {
|
||||||
RoleLevel role = RoleLevel.getRoleFromLoginStatus(request);
|
IdentifierBundle ids = RequestIdentifiers.getIdBundleForRequest(request);
|
||||||
|
if (IsRootUser.isRootUser(ids)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RoleLevel role = HasRoleLevel.getUsersRoleLevel(ids);
|
||||||
return role == RoleLevel.PUBLIC || role == RoleLevel.SELF;
|
return role == RoleLevel.PUBLIC || role == RoleLevel.SELF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@ public class Authenticate extends VitroHttpServlet {
|
||||||
// Send them on their way.
|
// Send them on their way.
|
||||||
switch (exitState) {
|
switch (exitState) {
|
||||||
case NOWHERE:
|
case NOWHERE:
|
||||||
new LoginRedirector(vreq).redirectCancellingUser(response);
|
showLoginCanceled(response, vreq);
|
||||||
break;
|
break;
|
||||||
case LOGGING_IN:
|
case LOGGING_IN:
|
||||||
showLoginScreen(vreq, response);
|
showLoginScreen(vreq, response);
|
||||||
|
@ -133,7 +133,7 @@ public class Authenticate extends VitroHttpServlet {
|
||||||
showLoginScreen(vreq, response);
|
showLoginScreen(vreq, response);
|
||||||
break;
|
break;
|
||||||
default: // LOGGED_IN:
|
default: // LOGGED_IN:
|
||||||
new LoginRedirector(vreq).redirectLoggedInUser(response);
|
showLoginComplete(response, vreq);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -478,6 +478,31 @@ public class Authenticate extends VitroHttpServlet {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exit: user has completed the login. Redirect appropriately and clear the bean.
|
||||||
|
*/
|
||||||
|
private void showLoginComplete(HttpServletResponse response,
|
||||||
|
VitroRequest vreq) throws IOException {
|
||||||
|
getLoginRedirector(vreq).redirectLoggedInUser(response);
|
||||||
|
LoginProcessBean.removeBean(vreq);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exit: user has canceled. Redirect and clear the bean.
|
||||||
|
*/
|
||||||
|
private void showLoginCanceled(HttpServletResponse response,
|
||||||
|
VitroRequest vreq) throws IOException {
|
||||||
|
getLoginRedirector(vreq).redirectCancellingUser(response);
|
||||||
|
LoginProcessBean.removeBean(vreq);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LoginRedirector getLoginRedirector(VitroRequest vreq) {
|
||||||
|
String afterLoginUrl = LoginProcessBean.getBean(vreq).getAfterLoginUrl();
|
||||||
|
return new LoginRedirector(vreq, afterLoginUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Get a reference to the Authenticator. */
|
/** Get a reference to the Authenticator. */
|
||||||
private Authenticator getAuthenticator(HttpServletRequest request) {
|
private Authenticator getAuthenticator(HttpServletRequest request) {
|
||||||
return Authenticator.getInstance(request);
|
return Authenticator.getInstance(request);
|
||||||
|
|
|
@ -185,15 +185,23 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
||||||
|
|
||||||
// Tell the template and any directives it uses that we're processing a page template.
|
// Tell the template and any directives it uses that we're processing a page template.
|
||||||
templateDataModel.put("templateType", PAGE_TEMPLATE_TYPE);
|
templateDataModel.put("templateType", PAGE_TEMPLATE_TYPE);
|
||||||
writePage(templateDataModel, config, vreq, response);
|
|
||||||
|
writePage(templateDataModel, config, vreq, response, values.getStatusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doRedirect(HttpServletRequest request, HttpServletResponse response, ResponseValues values)
|
protected void doRedirect(HttpServletRequest request, HttpServletResponse response, ResponseValues values)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
String redirectUrl = values.getRedirectUrl();
|
String redirectUrl = values.getRedirectUrl();
|
||||||
|
setResponseStatus(response, values.getStatusCode());
|
||||||
response.sendRedirect(redirectUrl);
|
response.sendRedirect(redirectUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setResponseStatus(HttpServletResponse response, int statusCode) {
|
||||||
|
if (statusCode > 0) {
|
||||||
|
response.setStatus(statusCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void doForward(HttpServletRequest request, HttpServletResponse response, ResponseValues values)
|
protected void doForward(HttpServletRequest request, HttpServletResponse response, ResponseValues values)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
String forwardUrl = values.getForwardUrl();
|
String forwardUrl = values.getForwardUrl();
|
||||||
|
@ -305,12 +313,19 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
||||||
* the transition from JSP to Freemarker.
|
* the transition from JSP to Freemarker.
|
||||||
*/
|
*/
|
||||||
public static Map<String, Object> getDirectives() {
|
public static Map<String, Object> getDirectives() {
|
||||||
|
Map<String, Object> map = new HashMap<String, Object>();
|
||||||
|
map.putAll(getDirectivesForAllEnvironments());
|
||||||
|
map.put("url", new edu.cornell.mannlib.vitro.webapp.web.directives.UrlDirective());
|
||||||
|
map.put("widget", new edu.cornell.mannlib.vitro.webapp.web.directives.WidgetDirective());
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, Object> getDirectivesForAllEnvironments() {
|
||||||
Map<String, Object> map = new HashMap<String, Object>();
|
Map<String, Object> map = new HashMap<String, Object>();
|
||||||
map.put("dump", new freemarker.ext.dump.DumpDirective());
|
map.put("dump", new freemarker.ext.dump.DumpDirective());
|
||||||
map.put("dumpAll", new freemarker.ext.dump.DumpAllDirective());
|
map.put("dumpAll", new freemarker.ext.dump.DumpAllDirective());
|
||||||
map.put("help", new freemarker.ext.dump.HelpDirective());
|
map.put("help", new freemarker.ext.dump.HelpDirective());
|
||||||
map.put("url", new edu.cornell.mannlib.vitro.webapp.web.directives.UrlDirective());
|
|
||||||
map.put("widget", new edu.cornell.mannlib.vitro.webapp.web.directives.WidgetDirective());
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,9 +345,6 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
||||||
Map<String, Object> map = new HashMap<String, Object>();
|
Map<String, Object> map = new HashMap<String, Object>();
|
||||||
|
|
||||||
ApplicationBean appBean = vreq.getAppBean();
|
ApplicationBean appBean = vreq.getAppBean();
|
||||||
// Ideally, templates wouldn't need portal id. Currently used as a hidden input value
|
|
||||||
// in the site search box, so needed for now.
|
|
||||||
|
|
||||||
String siteName = appBean.getApplicationName();
|
String siteName = appBean.getApplicationName();
|
||||||
map.put("siteName", siteName);
|
map.put("siteName", siteName);
|
||||||
|
|
||||||
|
@ -365,11 +377,6 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
||||||
// This value is used only in stylesheets.ftl and already contains the context path.
|
// This value is used only in stylesheets.ftl and already contains the context path.
|
||||||
map.put("stylesheetPath", UrlBuilder.getUrl(themeDir + "/css"));
|
map.put("stylesheetPath", UrlBuilder.getUrl(themeDir + "/css"));
|
||||||
|
|
||||||
// String bannerImage = portal.getBannerImage();
|
|
||||||
// if ( ! StringUtils.isEmpty(bannerImage)) {
|
|
||||||
// map.put("bannerImage", UrlBuilder.getUrl(themeDir + "site_icons/" + bannerImage));
|
|
||||||
// }
|
|
||||||
|
|
||||||
String flashMessage = DisplayMessage.getMessageAndClear(vreq);
|
String flashMessage = DisplayMessage.getMessageAndClear(vreq);
|
||||||
if (! flashMessage.isEmpty()) {
|
if (! flashMessage.isEmpty()) {
|
||||||
map.put("flash", flashMessage);
|
map.put("flash", flashMessage);
|
||||||
|
@ -448,18 +455,24 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void writePage(Map<String, Object> root, Configuration config,
|
protected void writePage(Map<String, Object> root, Configuration config,
|
||||||
HttpServletRequest request, HttpServletResponse response) throws TemplateProcessingException {
|
HttpServletRequest request, HttpServletResponse response, int statusCode) throws TemplateProcessingException {
|
||||||
writeTemplate(getPageTemplateName(), root, config, request, response);
|
writeTemplate(getPageTemplateName(), root, config, request, response, statusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void writeTemplate(String templateName, Map<String, Object> map, Configuration config,
|
protected void writeTemplate(String templateName, Map<String, Object> map, Configuration config,
|
||||||
HttpServletRequest request, HttpServletResponse response) throws TemplateProcessingException {
|
HttpServletRequest request, HttpServletResponse response) throws TemplateProcessingException {
|
||||||
StringWriter sw = processTemplate(templateName, map, config, request);
|
writeTemplate(templateName, map, config, request, response, 0);
|
||||||
write(sw, response);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void write(StringWriter sw, HttpServletResponse response) {
|
protected void writeTemplate(String templateName, Map<String, Object> map, Configuration config,
|
||||||
|
HttpServletRequest request, HttpServletResponse response, int statusCode) throws TemplateProcessingException {
|
||||||
|
StringWriter sw = processTemplate(templateName, map, config, request);
|
||||||
|
write(sw, response, statusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void write(StringWriter sw, HttpServletResponse response, int statusCode) {
|
||||||
try {
|
try {
|
||||||
|
setResponseStatus(response, statusCode);
|
||||||
PrintWriter out = response.getWriter();
|
PrintWriter out = response.getWriter();
|
||||||
out.print(sw);
|
out.print(sw);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
@ -100,7 +100,7 @@ public class IndividualController extends FreemarkerHttpServlet {
|
||||||
// Check to see if the request is for a non-information resource, redirect if it is.
|
// Check to see if the request is for a non-information resource, redirect if it is.
|
||||||
String redirectURL = checkForRedirect ( url, vreq );
|
String redirectURL = checkForRedirect ( url, vreq );
|
||||||
if( redirectURL != null ){
|
if( redirectURL != null ){
|
||||||
return new RedirectResponseValues(redirectURL);
|
return new RedirectResponseValues(redirectURL, HttpServletResponse.SC_SEE_OTHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
Individual individual = null;
|
Individual individual = null;
|
||||||
|
@ -464,11 +464,18 @@ public class IndividualController extends FreemarkerHttpServlet {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
private static Pattern URI_PATTERN = Pattern.compile("^/individual/([^/]*)$");
|
* Following recipe 3 from "Best Practice Recipes for Publishing RDF Vocabularies."
|
||||||
//Redirect if the request is for http://hostname/individual/localname
|
* See http://www.w3.org/TR/swbp-vocab-pub/#recipe3.
|
||||||
// if accept is nothing or text/html redirect to ???
|
* The basic idea is that a URI like http://vivo.cornell.edu/individual/n1234
|
||||||
// if accept is some RDF thing redirect to the URL for RDF
|
* identifies a real world individual. HTTP cannot send that as the response
|
||||||
|
* to a GET request because it can only send bytes and not things. The server
|
||||||
|
* sends a 303, to mean "you asked for something I cannot send you, but I can
|
||||||
|
* send you this other stream of bytes about that thing."
|
||||||
|
* In the case of a request like http://vivo.cornell.edu/individual/n1234/n1234.rdf,
|
||||||
|
* the request is for a set of bytes rather than an individual, so no 303 is needed.
|
||||||
|
*/
|
||||||
|
private static Pattern URI_PATTERN = Pattern.compile("^/individual/([^/]*)$");
|
||||||
private String checkForRedirect(String url, VitroRequest vreq) {
|
private String checkForRedirect(String url, VitroRequest vreq) {
|
||||||
Matcher m = URI_PATTERN.matcher(url);
|
Matcher m = URI_PATTERN.matcher(url);
|
||||||
if( m.matches() && m.groupCount() == 1 ){
|
if( m.matches() && m.groupCount() == 1 ){
|
||||||
|
@ -506,7 +513,11 @@ public class IndividualController extends FreemarkerHttpServlet {
|
||||||
protected ContentType checkForLinkedDataRequest(String url, VitroRequest vreq ) {
|
protected ContentType checkForLinkedDataRequest(String url, VitroRequest vreq ) {
|
||||||
try {
|
try {
|
||||||
Matcher m;
|
Matcher m;
|
||||||
// Check for url param specifying format
|
/*
|
||||||
|
* Check for url param specifying format.
|
||||||
|
* Example: http://vivo.cornell.edu/individual/n23?format=rdfxml
|
||||||
|
* This request will trigger a redirect with a 303.
|
||||||
|
*/
|
||||||
String formatParam = (String) vreq.getParameter("format");
|
String formatParam = (String) vreq.getParameter("format");
|
||||||
if (formatParam != null) {
|
if (formatParam != null) {
|
||||||
m = RDFXML_FORMAT.matcher(formatParam);
|
m = RDFXML_FORMAT.matcher(formatParam);
|
||||||
|
@ -523,7 +534,11 @@ public class IndividualController extends FreemarkerHttpServlet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//check the accept header
|
/*
|
||||||
|
* Check the accept header. This request will trigger a
|
||||||
|
* redirect with a 303, because the request is for an individual
|
||||||
|
* but the server can only provide a set of bytes.
|
||||||
|
*/
|
||||||
String acceptHeader = vreq.getHeader("accept");
|
String acceptHeader = vreq.getHeader("accept");
|
||||||
if (acceptHeader != null) {
|
if (acceptHeader != null) {
|
||||||
String ctStr = ContentType.getBestContentType(
|
String ctStr = ContentType.getBestContentType(
|
||||||
|
@ -538,10 +553,12 @@ public class IndividualController extends FreemarkerHttpServlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check for parts of URL that indicate request for RDF
|
* Check for parts of URL that indicate request for RDF
|
||||||
http://vivo.cornell.edu/individual/n23/n23.rdf
|
* http://vivo.cornell.edu/individual/n23/n23.rdf
|
||||||
http://vivo.cornell.edu/individual/n23/n23.n3
|
* http://vivo.cornell.edu/individual/n23/n23.n3
|
||||||
http://vivo.cornell.edu/individual/n23/n23.ttl
|
* http://vivo.cornell.edu/individual/n23/n23.ttl
|
||||||
|
* This request will not trigger a redirect and 303, because
|
||||||
|
* the request is for a set of bytes rather than an individual.
|
||||||
*/
|
*/
|
||||||
m = RDF_REQUEST.matcher(url);
|
m = RDF_REQUEST.matcher(url);
|
||||||
if( m.matches() ) {
|
if( m.matches() ) {
|
||||||
|
@ -556,7 +573,6 @@ public class IndividualController extends FreemarkerHttpServlet {
|
||||||
return ContentType.TURTLE;
|
return ContentType.TURTLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} catch (Throwable th) {
|
} catch (Throwable th) {
|
||||||
log.error("problem while checking accept header " , th);
|
log.error("problem while checking accept header " , th);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,11 @@ public abstract class BaseResponseValues implements ResponseValues {
|
||||||
this.contentType = contentType;
|
this.contentType = contentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BaseResponseValues(ContentType contentType, int statusCode) {
|
||||||
|
this.contentType = contentType;
|
||||||
|
this.statusCode = statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getStatusCode() {
|
public int getStatusCode() {
|
||||||
return statusCode;
|
return statusCode;
|
||||||
|
@ -38,6 +43,7 @@ public abstract class BaseResponseValues implements ResponseValues {
|
||||||
return contentType;
|
return contentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setContentType(ContentType contentType) {
|
public void setContentType(ContentType contentType) {
|
||||||
this.contentType = contentType;
|
this.contentType = contentType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,11 @@ public class RdfResponseValues extends BaseResponseValues {
|
||||||
this.model = model;
|
this.model = model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RdfResponseValues(ContentType contentType, Model model, int statusCode) {
|
||||||
|
super(contentType, statusCode);
|
||||||
|
this.model = model;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Model getModel() {
|
public Model getModel() {
|
||||||
return model;
|
return model;
|
||||||
|
|
|
@ -28,6 +28,8 @@ public interface ResponseValues {
|
||||||
|
|
||||||
public ContentType getContentType();
|
public ContentType getContentType();
|
||||||
|
|
||||||
|
public void setContentType(ContentType contentType);
|
||||||
|
|
||||||
public Model getModel();
|
public Model getModel();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,9 @@ public class TemplateResponseValues extends BaseResponseValues {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TemplateResponseValues getTemplateResponseValuesFromException(ExceptionResponseValues responseValues) {
|
public static TemplateResponseValues getTemplateResponseValuesFromException(ExceptionResponseValues responseValues) {
|
||||||
return new TemplateResponseValues(responseValues.getTemplateName(), responseValues.getMap());
|
return new TemplateResponseValues(responseValues.getTemplateName(),
|
||||||
|
responseValues.getMap(),
|
||||||
|
responseValues.getStatusCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,14 @@ import org.apache.commons.logging.LogFactory;
|
||||||
/**
|
/**
|
||||||
* Where are we in the process of logging on? What message should we show to the
|
* Where are we in the process of logging on? What message should we show to the
|
||||||
* user?
|
* user?
|
||||||
|
*
|
||||||
|
* TODO: the contents loginPageUrl is not explicitly defined, but it is assumed
|
||||||
|
* to be either null, absolute, or relative to the host. It would be better if
|
||||||
|
* it were explicitly defined, and either null, absolute or relative to the
|
||||||
|
* context path. Then, the context path could be applied when the URL is used.
|
||||||
|
* Later for that.
|
||||||
|
*
|
||||||
|
* TODO: similar for afterLoginUrl, I presume.
|
||||||
*/
|
*/
|
||||||
public class LoginProcessBean {
|
public class LoginProcessBean {
|
||||||
private static final Log log = LogFactory.getLog(LoginProcessBean.class);
|
private static final Log log = LogFactory.getLog(LoginProcessBean.class);
|
||||||
|
|
|
@ -40,11 +40,6 @@ public interface UserAccountsDao {
|
||||||
*/
|
*/
|
||||||
UserAccount getUserAccountByExternalAuthId(String externalAuthId);
|
UserAccount getUserAccountByExternalAuthId(String externalAuthId);
|
||||||
|
|
||||||
/**
|
|
||||||
* Is this UserAccount a root user?
|
|
||||||
*/
|
|
||||||
boolean isRootUser(UserAccount userAccount);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new UserAccount in the model.
|
* Create a new UserAccount in the model.
|
||||||
*
|
*
|
||||||
|
|
|
@ -47,11 +47,6 @@ public class UserAccountsDaoFiltering extends BaseFiltering implements
|
||||||
return innerDao.getUserAccountByExternalAuthId(externalAuthId);
|
return innerDao.getUserAccountByExternalAuthId(externalAuthId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRootUser(UserAccount userAccount) {
|
|
||||||
return innerDao.isRootUser(userAccount);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String insertUserAccount(UserAccount userAccount) {
|
public String insertUserAccount(UserAccount userAccount) {
|
||||||
return innerDao.insertUserAccount(userAccount);
|
return innerDao.insertUserAccount(userAccount);
|
||||||
|
|
|
@ -57,15 +57,13 @@ public class DataPropertyStatementDaoSDB extends DataPropertyStatementDaoJena
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
String[] graphVars = { "?g" };
|
|
||||||
String query =
|
String query =
|
||||||
"CONSTRUCT { \n" +
|
"CONSTRUCT { \n" +
|
||||||
" <" + entity.getURI() + "> ?p ?o . \n" +
|
" <" + entity.getURI() + "> ?p ?o . \n" +
|
||||||
"} WHERE { GRAPH ?g { \n" +
|
"} WHERE { \n" +
|
||||||
" <" + entity.getURI() + "> ?p ?o . \n" +
|
" <" + entity.getURI() + "> ?p ?o . \n" +
|
||||||
" FILTER(isLiteral(?o)) \n" +
|
" FILTER(isLiteral(?o)) \n" +
|
||||||
WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode) +
|
"}" ;
|
||||||
"} }" ;
|
|
||||||
Model results = null;
|
Model results = null;
|
||||||
DatasetWrapper w = dwf.getDatasetWrapper();
|
DatasetWrapper w = dwf.getDatasetWrapper();
|
||||||
Dataset dataset = w.getDataset();
|
Dataset dataset = w.getDataset();
|
||||||
|
|
|
@ -781,7 +781,7 @@ public class IndividualJena extends IndividualImpl implements Individual {
|
||||||
if (stmt.getObject().isURIResource()) {
|
if (stmt.getObject().isURIResource()) {
|
||||||
String typeURI = ((Resource)stmt.getObject()).getURI();
|
String typeURI = ((Resource)stmt.getObject()).getURI();
|
||||||
if (pfs.isClassProhibitedFromSearch(typeURI)) {
|
if (pfs.isClassProhibitedFromSearch(typeURI)) {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -395,8 +395,8 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
||||||
String[] graphVars = { "?g" };
|
String[] graphVars = { "?g" };
|
||||||
String queryStr =
|
String queryStr =
|
||||||
"CONSTRUCT { <"+ind.getURI()+"> <" + propertyURI + "> ?value } \n" +
|
"CONSTRUCT { <"+ind.getURI()+"> <" + propertyURI + "> ?value } \n" +
|
||||||
"WHERE { GRAPH ?g { \n" +
|
"WHERE { \n" +
|
||||||
"<" + ind.getURI() +"> <" + propertyURI + "> ?value } \n" +
|
"<" + ind.getURI() +"> <" + propertyURI + "> ?value \n" +
|
||||||
WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode) +
|
WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode) +
|
||||||
"\n} ";
|
"\n} ";
|
||||||
Query query = QueryFactory.create(queryStr);
|
Query query = QueryFactory.create(queryStr);
|
||||||
|
@ -456,12 +456,12 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
||||||
if (this.mainImageUri != NOT_INITIALIZED) {
|
if (this.mainImageUri != NOT_INITIALIZED) {
|
||||||
return mainImageUri;
|
return mainImageUri;
|
||||||
} else {
|
} else {
|
||||||
for (ObjectPropertyStatement stmt : getObjectPropertyStatements()) {
|
List<ObjectPropertyStatement> mainImgStmts =
|
||||||
if (stmt.getPropertyURI()
|
getObjectPropertyStatements(VitroVocabulary.IND_MAIN_IMAGE);
|
||||||
.equals(VitroVocabulary.IND_MAIN_IMAGE)) {
|
if (mainImgStmts != null && mainImgStmts.size() > 0) {
|
||||||
mainImageUri = stmt.getObjectURI();
|
// arbitrarily return the first value in the list
|
||||||
return mainImageUri;
|
mainImageUri = mainImgStmts.get(0).getObjectURI();
|
||||||
}
|
return mainImageUri;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -502,14 +502,11 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
||||||
if( _hasThumb != null ){
|
if( _hasThumb != null ){
|
||||||
return _hasThumb;
|
return _hasThumb;
|
||||||
}else{
|
}else{
|
||||||
String[] graphVars = { "?g" };
|
|
||||||
String ask =
|
String ask =
|
||||||
"ASK { GRAPH ?g " +
|
"ASK { " +
|
||||||
" { <" + individualURI + "> <http://vitro.mannlib.cornell.edu/ns/vitro/public#mainImage> ?mainImage . \n" +
|
" <" + individualURI + "> <http://vitro.mannlib.cornell.edu/ns/vitro/public#mainImage> ?mainImage . \n" +
|
||||||
" ?mainImage <http://vitro.mannlib.cornell.edu/ns/vitro/public#thumbnailImage> ?thumbImage . }\n" +
|
" ?mainImage <http://vitro.mannlib.cornell.edu/ns/vitro/public#thumbnailImage> ?thumbImage . }\n" ;
|
||||||
WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode) +
|
DatasetWrapper w = getDatasetWrapper();
|
||||||
"}";
|
|
||||||
DatasetWrapper w = getDatasetWrapper();
|
|
||||||
Dataset dataset = w.getDataset();
|
Dataset dataset = w.getDataset();
|
||||||
dataset.getLock().enterCriticalSection(Lock.READ);
|
dataset.getLock().enterCriticalSection(Lock.READ);
|
||||||
try{
|
try{
|
||||||
|
@ -552,10 +549,8 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
||||||
Dataset dataset = w.getDataset();
|
Dataset dataset = w.getDataset();
|
||||||
dataset.getLock().enterCriticalSection(Lock.READ);
|
dataset.getLock().enterCriticalSection(Lock.READ);
|
||||||
try {
|
try {
|
||||||
String graphVars[] = { "?g" };
|
|
||||||
StringBuffer selectPrimaryLinkQueryBuff = new StringBuffer().append(
|
StringBuffer selectPrimaryLinkQueryBuff = new StringBuffer().append(
|
||||||
"SELECT ?url ?anchor \n" ).append(
|
"SELECT ?url ?anchor \n" ).append(" WHERE { \n").append(
|
||||||
"WHERE{ GRAPH ?g { \n " ).append(
|
|
||||||
" <" + this.individualURI + "> ").append(
|
" <" + this.individualURI + "> ").append(
|
||||||
"<" + VitroVocabulary.PRIMARY_LINK + "> " ).append(
|
"<" + VitroVocabulary.PRIMARY_LINK + "> " ).append(
|
||||||
"?link . \n").append(
|
"?link . \n").append(
|
||||||
|
@ -563,9 +558,7 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
||||||
).append(
|
).append(
|
||||||
" ?link <" + VitroVocabulary.LINK_ANCHOR + "> ?anchor . \n"
|
" ?link <" + VitroVocabulary.LINK_ANCHOR + "> ?anchor . \n"
|
||||||
).append(
|
).append(
|
||||||
"} \n")
|
"} \n");
|
||||||
.append(WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode))
|
|
||||||
.append("}");
|
|
||||||
QueryExecution qexec = QueryExecutionFactory.create(
|
QueryExecution qexec = QueryExecutionFactory.create(
|
||||||
QueryFactory.create(selectPrimaryLinkQueryBuff.toString())
|
QueryFactory.create(selectPrimaryLinkQueryBuff.toString())
|
||||||
, dataset);
|
, dataset);
|
||||||
|
@ -678,12 +671,9 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
||||||
Dataset dataset = w.getDataset();
|
Dataset dataset = w.getDataset();
|
||||||
dataset.getLock().enterCriticalSection(Lock.READ);
|
dataset.getLock().enterCriticalSection(Lock.READ);
|
||||||
try {
|
try {
|
||||||
String[] graphVars = { "?g" };
|
|
||||||
String valuesOfProperty =
|
String valuesOfProperty =
|
||||||
"CONSTRUCT{<" + this.individualURI + "> <" + propertyURI + "> ?object}" +
|
"CONSTRUCT{ <" + this.individualURI + "> <" + propertyURI + "> ?object }" +
|
||||||
"WHERE{ GRAPH ?g { <" + this.individualURI + "> <" + propertyURI + "> ?object} \n" +
|
"WHERE{ <" + this.individualURI + "> <" + propertyURI + "> ?object } \n";
|
||||||
WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode) +
|
|
||||||
"}";
|
|
||||||
tempModel = QueryExecutionFactory.create(QueryFactory.create(valuesOfProperty), dataset).execConstruct();
|
tempModel = QueryExecutionFactory.create(QueryFactory.create(valuesOfProperty), dataset).execConstruct();
|
||||||
ontModel.add(tempModel.listStatements());
|
ontModel.add(tempModel.listStatements());
|
||||||
Resource ontRes = ontModel.getResource(this.individualURI);
|
Resource ontRes = ontModel.getResource(this.individualURI);
|
||||||
|
@ -727,13 +717,10 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
||||||
Dataset dataset = w.getDataset();
|
Dataset dataset = w.getDataset();
|
||||||
dataset.getLock().enterCriticalSection(Lock.READ);
|
dataset.getLock().enterCriticalSection(Lock.READ);
|
||||||
try {
|
try {
|
||||||
String[] graphVars = { "?g" };
|
|
||||||
String valuesOfProperty =
|
String valuesOfProperty =
|
||||||
"SELECT ?object" +
|
"SELECT ?object" +
|
||||||
"WHERE{ GRAPH ?g { <" + this.individualURI + "> <" +
|
"WHERE{ <" + this.individualURI + "> <" +
|
||||||
propertyURI + "> ?object} \n" +
|
propertyURI + "> ?object } \n";
|
||||||
WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode) +
|
|
||||||
"}";
|
|
||||||
ResultSet values = QueryExecutionFactory.create(
|
ResultSet values = QueryExecutionFactory.create(
|
||||||
QueryFactory.create(valuesOfProperty), dataset)
|
QueryFactory.create(valuesOfProperty), dataset)
|
||||||
.execSelect();
|
.execSelect();
|
||||||
|
@ -767,13 +754,10 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
||||||
Dataset dataset = w.getDataset();
|
Dataset dataset = w.getDataset();
|
||||||
dataset.getLock().enterCriticalSection(Lock.READ);
|
dataset.getLock().enterCriticalSection(Lock.READ);
|
||||||
try {
|
try {
|
||||||
String[] graphVars = { "?g" };
|
|
||||||
String valueOfProperty =
|
String valueOfProperty =
|
||||||
"SELECT ?object " +
|
"SELECT ?object " +
|
||||||
"WHERE{ GRAPH ?g { <" + this.individualURI + "> <" +
|
"WHERE{ <" + this.individualURI + "> <" +
|
||||||
propertyURI + "> ?object} \n" +
|
propertyURI + "> ?object } \n";
|
||||||
WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode) +
|
|
||||||
"}";
|
|
||||||
QueryExecution qe = QueryExecutionFactory.create(
|
QueryExecution qe = QueryExecutionFactory.create(
|
||||||
QueryFactory.create(valueOfProperty), dataset);
|
QueryFactory.create(valueOfProperty), dataset);
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -103,6 +103,7 @@ public class UserAccountsDaoJena extends JenaBaseDao implements UserAccountsDao
|
||||||
USERACCOUNT_EXTERNAL_AUTH_ID));
|
USERACCOUNT_EXTERNAL_AUTH_ID));
|
||||||
u.setPermissionSetUris(getPropertyResourceURIValues(r,
|
u.setPermissionSetUris(getPropertyResourceURIValues(r,
|
||||||
USERACCOUNT_HAS_PERMISSION_SET));
|
USERACCOUNT_HAS_PERMISSION_SET));
|
||||||
|
u.setRootUser(isResourceOfType(r, USERACCOUNT_ROOT_USER));
|
||||||
return u;
|
return u;
|
||||||
} finally {
|
} finally {
|
||||||
getOntModel().leaveCriticalSection();
|
getOntModel().leaveCriticalSection();
|
||||||
|
@ -157,21 +158,6 @@ public class UserAccountsDaoJena extends JenaBaseDao implements UserAccountsDao
|
||||||
return getUserAccountByUri(userUri);
|
return getUserAccountByUri(userUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRootUser(UserAccount userAccount) {
|
|
||||||
if (userAccount == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
getOntModel().enterCriticalSection(Lock.READ);
|
|
||||||
try {
|
|
||||||
OntResource r = getOntModel().getOntResource(userAccount.getUri());
|
|
||||||
return isResourceOfType(r, USERACCOUNT_ROOT_USER);
|
|
||||||
} finally {
|
|
||||||
getOntModel().leaveCriticalSection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String insertUserAccount(UserAccount userAccount) {
|
public String insertUserAccount(UserAccount userAccount) {
|
||||||
if (userAccount == null) {
|
if (userAccount == null) {
|
||||||
|
@ -214,6 +200,10 @@ public class UserAccountsDaoJena extends JenaBaseDao implements UserAccountsDao
|
||||||
USERACCOUNT_HAS_PERMISSION_SET,
|
USERACCOUNT_HAS_PERMISSION_SET,
|
||||||
userAccount.getPermissionSetUris(), model);
|
userAccount.getPermissionSetUris(), model);
|
||||||
|
|
||||||
|
if (userAccount.isRootUser()) {
|
||||||
|
model.add(res, RDF.type, USERACCOUNT_ROOT_USER);
|
||||||
|
}
|
||||||
|
|
||||||
userAccount.setUri(userUri);
|
userAccount.setUri(userUri);
|
||||||
return userUri;
|
return userUri;
|
||||||
} catch (InsertException e) {
|
} catch (InsertException e) {
|
||||||
|
@ -268,6 +258,13 @@ public class UserAccountsDaoJena extends JenaBaseDao implements UserAccountsDao
|
||||||
updatePropertyResourceURIValues(res,
|
updatePropertyResourceURIValues(res,
|
||||||
USERACCOUNT_HAS_PERMISSION_SET,
|
USERACCOUNT_HAS_PERMISSION_SET,
|
||||||
userAccount.getPermissionSetUris(), model);
|
userAccount.getPermissionSetUris(), model);
|
||||||
|
|
||||||
|
if (userAccount.isRootUser()) {
|
||||||
|
model.add(res, RDF.type, USERACCOUNT_ROOT_USER);
|
||||||
|
} else {
|
||||||
|
model.remove(res, RDF.type, USERACCOUNT_ROOT_USER);
|
||||||
|
}
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
model.leaveCriticalSection();
|
model.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.email;
|
package edu.cornell.mannlib.vitro.webapp.email;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -21,22 +23,30 @@ import javax.mail.internet.InternetAddress;
|
||||||
import javax.mail.internet.MimeBodyPart;
|
import javax.mail.internet.MimeBodyPart;
|
||||||
import javax.mail.internet.MimeMessage;
|
import javax.mail.internet.MimeMessage;
|
||||||
import javax.mail.internet.MimeMultipart;
|
import javax.mail.internet.MimeMultipart;
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
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;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper.TemplateProcessingException;
|
import edu.cornell.mannlib.vitro.webapp.web.directives.EmailDirective;
|
||||||
|
import freemarker.core.Environment;
|
||||||
import freemarker.template.Configuration;
|
import freemarker.template.Configuration;
|
||||||
|
import freemarker.template.Template;
|
||||||
|
import freemarker.template.TemplateException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A framework that makes it simpler to send email messages with a body built
|
* A framework that makes it simpler to send email messages with a body built
|
||||||
* from a Freemarker template.
|
* from a Freemarker template.
|
||||||
*
|
*
|
||||||
* In fact, the body can be plain text from a template, HTML from a template, or
|
* The template must contain the @email directive, which may provide the subject
|
||||||
* both.
|
* line, the HTML content, and the plain text content. If these values are not
|
||||||
|
* provided by the directive, they default to empty strings, or to values that
|
||||||
|
* were set by the controller.
|
||||||
|
*
|
||||||
|
* The directive also calls the send() method here.
|
||||||
|
*
|
||||||
|
* @see EmailDirective
|
||||||
*/
|
*/
|
||||||
public class FreemarkerEmailMessage {
|
public class FreemarkerEmailMessage {
|
||||||
private static final Log log = LogFactory
|
private static final Log log = LogFactory
|
||||||
|
@ -47,15 +57,15 @@ public class FreemarkerEmailMessage {
|
||||||
private final HttpServletRequest req;
|
private final HttpServletRequest req;
|
||||||
private final Session session;
|
private final Session session;
|
||||||
private final Configuration config;
|
private final Configuration config;
|
||||||
private final ServletContext ctx;
|
|
||||||
|
|
||||||
private final List<Recipient> recipients = new ArrayList<Recipient>();
|
private final List<Recipient> recipients = new ArrayList<Recipient>();
|
||||||
private final InternetAddress replyToAddress;
|
private final InternetAddress replyToAddress;
|
||||||
|
|
||||||
private InternetAddress fromAddress = null;
|
private InternetAddress fromAddress = null;
|
||||||
private String subject = "";
|
private String subject = "";
|
||||||
private String htmlTemplateName;
|
private String templateName = "";
|
||||||
private String textTemplateName;
|
private String htmlContent = "";
|
||||||
|
private String textContent = "";
|
||||||
private Map<String, Object> bodyMap = Collections.emptyMap();
|
private Map<String, Object> bodyMap = Collections.emptyMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,8 +77,6 @@ public class FreemarkerEmailMessage {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.replyToAddress = replyToAddress;
|
this.replyToAddress = replyToAddress;
|
||||||
|
|
||||||
this.ctx = req.getSession().getServletContext();
|
|
||||||
|
|
||||||
Object o = req.getAttribute(ATTRIBUTE_NAME);
|
Object o = req.getAttribute(ATTRIBUTE_NAME);
|
||||||
if (!(o instanceof Configuration)) {
|
if (!(o instanceof Configuration)) {
|
||||||
String oClass = (o == null) ? "null" : o.getClass().getName();
|
String oClass = (o == null) ? "null" : o.getClass().getName();
|
||||||
|
@ -115,10 +123,6 @@ public class FreemarkerEmailMessage {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
recipients.add(new Recipient(type, emailAddress, personalName));
|
recipients.add(new Recipient(type, emailAddress, personalName));
|
||||||
} catch (AddressException e) {
|
|
||||||
log.warn("invalid recipient address: " + type + ", '"
|
|
||||||
+ emailAddress + "', personal name '" + personalName + "'");
|
|
||||||
return;
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
log.warn("invalid recipient address: " + type + ", '"
|
log.warn("invalid recipient address: " + type + ", '"
|
||||||
+ emailAddress + "', personal name '" + personalName + "'");
|
+ emailAddress + "', personal name '" + personalName + "'");
|
||||||
|
@ -130,27 +134,41 @@ public class FreemarkerEmailMessage {
|
||||||
this.subject = nonNull(subject, "");
|
this.subject = nonNull(subject, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHtmlTemplate(String templateName) {
|
public void setHtmlContent(String htmlContent) {
|
||||||
this.htmlTemplateName = nonNull(templateName, "");
|
this.htmlContent = nonNull(htmlContent, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTextTemplate(String templateName) {
|
public void setTextContent(String textContent) {
|
||||||
this.textTemplateName = nonNull(templateName, "");
|
this.textContent = nonNull(textContent, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTemplate(String templateName) {
|
||||||
|
this.templateName = nonNull(templateName, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBodyMap(Map<String, Object> body) {
|
public void setBodyMap(Map<String, Object> body) {
|
||||||
if (body == null) {
|
if (body == null) {
|
||||||
this.bodyMap = Collections.emptyMap();
|
this.bodyMap = Collections.emptyMap();
|
||||||
} else {
|
} else {
|
||||||
this.bodyMap = Collections
|
this.bodyMap = new HashMap<String, Object>(body);
|
||||||
.unmodifiableMap(new HashMap<String, Object>(body));
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processTemplate() {
|
||||||
|
bodyMap.putAll(FreemarkerHttpServlet.getDirectivesForAllEnvironments());
|
||||||
|
bodyMap.put("email", new EmailDirective(this));
|
||||||
|
|
||||||
|
try {
|
||||||
|
Template template = config.getTemplate(templateName);
|
||||||
|
template.process(bodyMap, new StringWriter());
|
||||||
|
} catch (TemplateException e) {
|
||||||
|
log.error(e, e);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(e, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void send() {
|
public void send() {
|
||||||
String textBody = figureMessageBody(textTemplateName);
|
|
||||||
String htmlBody = figureMessageBody(htmlTemplateName);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
MimeMessage msg = new MimeMessage(session);
|
MimeMessage msg = new MimeMessage(session);
|
||||||
msg.setReplyTo(new Address[] { replyToAddress });
|
msg.setReplyTo(new Address[] { replyToAddress });
|
||||||
|
@ -167,19 +185,19 @@ public class FreemarkerEmailMessage {
|
||||||
|
|
||||||
msg.setSubject(subject);
|
msg.setSubject(subject);
|
||||||
|
|
||||||
if (textBody.isEmpty()) {
|
if (textContent.isEmpty()) {
|
||||||
if (htmlBody.isEmpty()) {
|
if (htmlContent.isEmpty()) {
|
||||||
log.error("Message has neither text body nor HTML body");
|
log.error("Message has neither text body nor HTML body");
|
||||||
} else {
|
} else {
|
||||||
msg.setContent(htmlBody, "text/html");
|
msg.setContent(htmlContent, "text/html");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (htmlBody.isEmpty()) {
|
if (htmlContent.isEmpty()) {
|
||||||
msg.setContent(textBody, "text/plain");
|
msg.setContent(textContent, "text/plain");
|
||||||
} else {
|
} else {
|
||||||
MimeMultipart content = new MimeMultipart("alternative");
|
MimeMultipart content = new MimeMultipart("alternative");
|
||||||
addBodyPart(content, textBody, "text/plain");
|
addBodyPart(content, textContent, "text/plain");
|
||||||
addBodyPart(content, htmlBody, "text/html");
|
addBodyPart(content, htmlContent, "text/html");
|
||||||
msg.setContent(content);
|
msg.setContent(content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,26 +211,6 @@ public class FreemarkerEmailMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Process the template. If there is no template name or if there is a
|
|
||||||
* problem with the process, return an empty string.
|
|
||||||
*/
|
|
||||||
private String figureMessageBody(String templateName) {
|
|
||||||
if (templateName.isEmpty()) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
TemplateProcessingHelper helper = new TemplateProcessingHelper(
|
|
||||||
config, req, ctx);
|
|
||||||
return helper.processTemplate(templateName, bodyMap).toString();
|
|
||||||
} catch (TemplateProcessingException e) {
|
|
||||||
log.warn("Exception while processing email template '"
|
|
||||||
+ templateName + "'", e);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addBodyPart(MimeMultipart content, String textBody, String type)
|
private void addBodyPart(MimeMultipart content, String textBody, String type)
|
||||||
throws MessagingException {
|
throws MessagingException {
|
||||||
MimeBodyPart bodyPart = new MimeBodyPart();
|
MimeBodyPart bodyPart = new MimeBodyPart();
|
||||||
|
@ -235,7 +233,7 @@ public class FreemarkerEmailMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Recipient(RecipientType type, String address, String personalName)
|
public Recipient(RecipientType type, String address, String personalName)
|
||||||
throws AddressException, UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.address = new InternetAddress(address, personalName);
|
this.address = new InternetAddress(address, personalName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.web.directives;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailMessage;
|
||||||
|
import freemarker.core.Environment;
|
||||||
|
import freemarker.template.SimpleScalar;
|
||||||
|
import freemarker.template.TemplateDirectiveBody;
|
||||||
|
import freemarker.template.TemplateException;
|
||||||
|
import freemarker.template.TemplateModel;
|
||||||
|
import freemarker.template.TemplateModelException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the inputs for a FreemarkerEmailMessage.
|
||||||
|
*
|
||||||
|
* @see FreemarkerEmailMessage
|
||||||
|
*/
|
||||||
|
public class EmailDirective extends BaseTemplateDirectiveModel {
|
||||||
|
|
||||||
|
private static final Log log = LogFactory.getLog(EmailDirective.class);
|
||||||
|
|
||||||
|
private final FreemarkerEmailMessage message;
|
||||||
|
|
||||||
|
public EmailDirective(FreemarkerEmailMessage message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Environment env, Map params, TemplateModel[] loopVars,
|
||||||
|
TemplateDirectiveBody body) throws TemplateException, IOException {
|
||||||
|
|
||||||
|
String subject = getOptionalSimpleScalarParameter(params, "subject");
|
||||||
|
if (subject != null) {
|
||||||
|
message.setSubject(subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
String htmlContent = getOptionalSimpleScalarParameter(params, "html");
|
||||||
|
if (htmlContent != null) {
|
||||||
|
message.setHtmlContent(htmlContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
String textContent = getOptionalSimpleScalarParameter(params, "text");
|
||||||
|
if (textContent != null) {
|
||||||
|
message.setTextContent(textContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((htmlContent == null) && (textContent == null)) {
|
||||||
|
throw new TemplateModelException("The email directive must have "
|
||||||
|
+ "either a 'html' parameter or a 'text' parameter.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getOptionalSimpleScalarParameter(Map<?, ?> params,
|
||||||
|
String name) throws TemplateModelException {
|
||||||
|
Object o = params.get(name);
|
||||||
|
if (o == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(o instanceof SimpleScalar)) {
|
||||||
|
throw new TemplateModelException("The '" + name + "' parameter "
|
||||||
|
+ "for the email directive must be a string value.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> help(String name) {
|
||||||
|
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||||
|
|
||||||
|
map.put("effect",
|
||||||
|
"Create an email message from the parameters set in the invoking template.");
|
||||||
|
|
||||||
|
Map<String, String> params = new HashMap<String, String>();
|
||||||
|
params.put("subject", "email subject (optional)");
|
||||||
|
params.put("html", "HTML version of email message (optional)");
|
||||||
|
params.put("text", "Plain text version of email message (optional)");
|
||||||
|
map.put("parameters", params);
|
||||||
|
|
||||||
|
List<String> examples = new ArrayList<String>();
|
||||||
|
examples.add("<email subject=\"Password reset confirmation\" html=html text=text>");
|
||||||
|
examples.add("<email html=html text=text>");
|
||||||
|
map.put("examples", examples);
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||||
import freemarker.core.Environment;
|
import freemarker.core.Environment;
|
||||||
|
import freemarker.template.SimpleScalar;
|
||||||
import freemarker.template.TemplateDirectiveBody;
|
import freemarker.template.TemplateDirectiveBody;
|
||||||
import freemarker.template.TemplateException;
|
import freemarker.template.TemplateException;
|
||||||
import freemarker.template.TemplateModel;
|
import freemarker.template.TemplateModel;
|
||||||
|
@ -44,12 +45,19 @@ public class UrlDirective extends BaseTemplateDirectiveModel {
|
||||||
"The url directive doesn't allow nested content.");
|
"The url directive doesn't allow nested content.");
|
||||||
}
|
}
|
||||||
|
|
||||||
String path = params.get("path").toString();
|
Object o = params.get("path");
|
||||||
if (path == null) {
|
if (o == null) {
|
||||||
throw new TemplateModelException(
|
throw new TemplateModelException(
|
||||||
"The url directive requires a value for parameter 'path'.");
|
"The url directive requires a value for parameter 'path'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! ( o instanceof SimpleScalar)) {
|
||||||
|
throw new TemplateModelException(
|
||||||
|
"The url directive requires a string value for parameter 'path'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
String path = o.toString();
|
||||||
|
|
||||||
if (!path.startsWith("/")) {
|
if (!path.startsWith("/")) {
|
||||||
throw new TemplateModelException(
|
throw new TemplateModelException(
|
||||||
"The url directive requires that the value of parameter 'path' is an absolute path starting with '/'.");
|
"The url directive requires that the value of parameter 'path' is an absolute path starting with '/'.");
|
||||||
|
@ -60,6 +68,7 @@ public class UrlDirective extends BaseTemplateDirectiveModel {
|
||||||
out.write(url);
|
out.write(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Map<String, Object> help(String name) {
|
public Map<String, Object> help(String name) {
|
||||||
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||||
|
|
||||||
|
@ -78,5 +87,4 @@ public class UrlDirective extends BaseTemplateDirectiveModel {
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,6 +94,7 @@ public class WidgetDirective extends BaseTemplateDirectiveModel {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Map<String, Object> help(String name) {
|
public Map<String, Object> help(String name) {
|
||||||
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||||
|
|
||||||
|
|
|
@ -32,13 +32,27 @@ public class User extends BaseTemplateModel {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
String firstName = currentUser.getFirstName();
|
if (currentUser.getFirstName().isEmpty()) {
|
||||||
String lastName = currentUser.getLastName();
|
return currentUser.getEmailAddress();
|
||||||
if (firstName.isEmpty() && lastName.isEmpty()) {
|
}
|
||||||
return currentUser.getEmailAddress();
|
|
||||||
}
|
|
||||||
|
|
||||||
return firstName + " " + lastName;
|
return currentUser.getFirstName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
if (currentUser == null) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
return currentUser.getFirstName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
if (currentUser == null) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
return currentUser.getLastName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getHasSiteAdminAccess() {
|
public boolean getHasSiteAdminAccess() {
|
||||||
|
|
|
@ -6,6 +6,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.beans.VClass;
|
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
|
||||||
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.UrlBuilder.Route;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
|
||||||
|
|
||||||
|
@ -36,7 +37,8 @@ public class VClassTemplateModel extends BaseTemplateModel {
|
||||||
return vclass.getEntityCount();
|
return vclass.getEntityCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
public VClassGroupTemplateModel getGroup(){
|
public VClassGroupTemplateModel getGroup() {
|
||||||
return new VClassGroupTemplateModel(vclass.getGroup());
|
VClassGroup group = vclass.getGroup();
|
||||||
|
return (group == null) ? null : new VClassGroupTemplateModel(vclass.getGroup());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,26 +2,19 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
|
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
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 org.openrdf.model.URI;
|
import org.openrdf.model.URI;
|
||||||
import org.openrdf.model.impl.URIImpl;
|
import org.openrdf.model.impl.URIImpl;
|
||||||
|
|
||||||
import com.hp.hpl.jena.rdf.model.Literal;
|
|
||||||
|
|
||||||
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.propstmt.DropDataPropStmt;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPropStmt;
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPropStmt;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
|
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl;
|
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.edit.EditLiteral;
|
import edu.cornell.mannlib.vitro.webapp.edit.EditLiteral;
|
||||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.RdfLiteralHash;
|
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.RdfLiteralHash;
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -91,6 +90,27 @@ public class UserAccountsSelectorTest extends AbstractTestClass {
|
||||||
Collections
|
Collections
|
||||||
.singleton("http://vivo.mydomain.edu/individual/role2"),
|
.singleton("http://vivo.mydomain.edu/individual/role2"),
|
||||||
acct.getPermissionSetUris());
|
acct.getPermissionSetUris());
|
||||||
|
assertEquals("rootUser", false, acct.isRootUser());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkFieldsForRootUser() {
|
||||||
|
selectOnCriteria(1, 8, DEFAULT_ORDERING, "", "");
|
||||||
|
assertSelectedUris(10, "user08");
|
||||||
|
|
||||||
|
UserAccount acct = selection.getUserAccounts().get(0);
|
||||||
|
assertEquals("uri", "http://vivo.mydomain.edu/individual/user08",
|
||||||
|
acct.getUri());
|
||||||
|
assertEquals("email", "email@henry.edu", acct.getEmailAddress());
|
||||||
|
assertEquals("firstName", "Mary", acct.getFirstName());
|
||||||
|
assertEquals("lastName", "McInerney", acct.getLastName());
|
||||||
|
assertEquals("password", "garbage", acct.getMd5Password());
|
||||||
|
assertEquals("expires", 0L, acct.getPasswordLinkExpires());
|
||||||
|
assertEquals("loginCount", 7, acct.getLoginCount());
|
||||||
|
assertEquals("status", UserAccount.Status.ACTIVE, acct.getStatus());
|
||||||
|
assertEqualSets("permissions", Collections.<String> emptySet(),
|
||||||
|
acct.getPermissionSetUris());
|
||||||
|
assertEquals("rootUser", true, acct.isRootUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
|
@ -101,6 +101,7 @@ mydomain:user07
|
||||||
|
|
||||||
mydomain:user08
|
mydomain:user08
|
||||||
a auth:UserAccount ;
|
a auth:UserAccount ;
|
||||||
|
a auth:RootUserAccount ;
|
||||||
auth:emailAddress "email@henry.edu" ;
|
auth:emailAddress "email@henry.edu" ;
|
||||||
auth:firstName "Mary" ;
|
auth:firstName "Mary" ;
|
||||||
auth:lastName "McInerney" ;
|
auth:lastName "McInerney" ;
|
||||||
|
|
|
@ -182,10 +182,4 @@ public class AuthenticatorStub extends Authenticator {
|
||||||
"AuthenticatorStub.accountRequiresEditing() not implemented.");
|
"AuthenticatorStub.accountRequiresEditing() not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void recordLoginWithoutUserAccount(String individualUri) {
|
|
||||||
throw new RuntimeException(
|
|
||||||
"AuthenticatorStub.recordLoginWithoutUserAccount() not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,13 @@ import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.log4j.Level;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import stubs.edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesStub;
|
||||||
|
import stubs.edu.cornell.mannlib.vitro.webapp.dao.IndividualDaoStub;
|
||||||
import stubs.edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDaoStub;
|
import stubs.edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDaoStub;
|
||||||
import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub;
|
import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub;
|
||||||
import stubs.javax.servlet.ServletConfigStub;
|
import stubs.javax.servlet.ServletConfigStub;
|
||||||
|
@ -32,7 +35,10 @@ import stubs.javax.servlet.http.HttpSessionStub;
|
||||||
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.testing.AbstractTestClass;
|
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.identifier.ActiveIdentifierBundleFactories;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.CommonIdentifierBundleFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
|
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.AuthenticatorStub;
|
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.AuthenticatorStub;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean;
|
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean;
|
||||||
|
@ -46,6 +52,7 @@ public class AuthenticateTest extends AbstractTestClass {
|
||||||
private ServletContextStub servletContext;
|
private ServletContextStub servletContext;
|
||||||
private WebappDaoFactoryStub webappDaoFactory;
|
private WebappDaoFactoryStub webappDaoFactory;
|
||||||
private UserAccountsDaoStub userAccountsDao;
|
private UserAccountsDaoStub userAccountsDao;
|
||||||
|
private IndividualDaoStub individualDao;
|
||||||
private ServletConfigStub servletConfig;
|
private ServletConfigStub servletConfig;
|
||||||
private HttpSessionStub session;
|
private HttpSessionStub session;
|
||||||
private HttpServletRequestStub request;
|
private HttpServletRequestStub request;
|
||||||
|
@ -122,8 +129,11 @@ public class AuthenticateTest extends AbstractTestClass {
|
||||||
userAccountsDao.addUser(createUserFromUserInfo(OLD_SELF));
|
userAccountsDao.addUser(createUserFromUserInfo(OLD_SELF));
|
||||||
userAccountsDao.addUser(createUserFromUserInfo(OLD_STRANGER));
|
userAccountsDao.addUser(createUserFromUserInfo(OLD_STRANGER));
|
||||||
|
|
||||||
|
individualDao = new IndividualDaoStub();
|
||||||
|
|
||||||
webappDaoFactory = new WebappDaoFactoryStub();
|
webappDaoFactory = new WebappDaoFactoryStub();
|
||||||
webappDaoFactory.setUserAccountsDao(userAccountsDao);
|
webappDaoFactory.setUserAccountsDao(userAccountsDao);
|
||||||
|
webappDaoFactory.setIndividualDao(individualDao);
|
||||||
|
|
||||||
servletContext = new ServletContextStub();
|
servletContext = new ServletContextStub();
|
||||||
servletContext.setAttribute("webappDaoFactory", webappDaoFactory);
|
servletContext.setAttribute("webappDaoFactory", webappDaoFactory);
|
||||||
|
@ -143,6 +153,12 @@ public class AuthenticateTest extends AbstractTestClass {
|
||||||
|
|
||||||
auth = new Authenticate();
|
auth = new Authenticate();
|
||||||
auth.init(servletConfig);
|
auth.init(servletConfig);
|
||||||
|
|
||||||
|
setLoggerLevel(ConfigurationProperties.class, Level.WARN);
|
||||||
|
new ConfigurationPropertiesStub().setBean(servletContext);
|
||||||
|
|
||||||
|
ActiveIdentifierBundleFactories.addFactory(servletContext,
|
||||||
|
new CommonIdentifierBundleFactory(servletContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
private UserAccount createUserFromUserInfo(UserInfo userInfo) {
|
private UserAccount createUserFromUserInfo(UserInfo userInfo) {
|
||||||
|
|
|
@ -48,11 +48,6 @@ public class UserAccountsDaoStub implements UserAccountsDao {
|
||||||
"UserAccountsDaoStub.getUserAccountByEmail() not implemented.");
|
"UserAccountsDaoStub.getUserAccountByEmail() not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRootUser(UserAccount userAccount) {
|
|
||||||
throw new RuntimeException("UserAccountsDao.isRootUser() not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String insertUserAccount(UserAccount userAccount) {
|
public String insertUserAccount(UserAccount userAccount) {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
|
|
|
@ -359,4 +359,5 @@ div.sparqlform .parenthetical {
|
||||||
.note {
|
.note {
|
||||||
font-size: .8em;
|
font-size: .8em;
|
||||||
line-height: 1.3em;
|
line-height: 1.3em;
|
||||||
|
color: #7f8993;
|
||||||
}
|
}
|
|
@ -193,14 +193,14 @@ ul#browse-classes a {
|
||||||
ul#alpha-browse-individuals {
|
ul#alpha-browse-individuals {
|
||||||
float: left;
|
float: left;
|
||||||
width: 619px;
|
width: 619px;
|
||||||
padding-left: 10px;
|
/* padding-left: 10px; */
|
||||||
list-style: none;
|
list-style: none;
|
||||||
margin-left: 1px;
|
/* margin-left: 1px; */
|
||||||
}
|
}
|
||||||
ul#alpha-browse-individuals li {
|
ul#alpha-browse-individuals li {
|
||||||
float: left;
|
float: left;
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
padding-top: 8px;
|
padding-top: 0px;
|
||||||
}
|
}
|
||||||
ul#alpha-browse-individuals li:last-child {
|
ul#alpha-browse-individuals li:last-child {
|
||||||
border-bottom: 0;
|
border-bottom: 0;
|
||||||
|
@ -212,6 +212,11 @@ ul#alpha-browse-individuals a {
|
||||||
padding-left: 8px;
|
padding-left: 8px;
|
||||||
width: 10px;
|
width: 10px;
|
||||||
}
|
}
|
||||||
|
h4#selectedClassHeading {
|
||||||
|
margin-left:4px;
|
||||||
|
margin-top:-5px;
|
||||||
|
margin-bottom:-10px;
|
||||||
|
}
|
||||||
/* BROWSE INDIVIDUALS------> */
|
/* BROWSE INDIVIDUALS------> */
|
||||||
#individuals-in-class {
|
#individuals-in-class {
|
||||||
float: right;
|
float: right;
|
||||||
|
|
|
@ -74,3 +74,42 @@
|
||||||
height:620px;
|
height:620px;
|
||||||
overflow:visible;
|
overflow:visible;
|
||||||
}
|
}
|
||||||
|
/* <------ SEARCH RESULTS PAGE*/
|
||||||
|
.searchTOC {
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
float:right;
|
||||||
|
margin-right:35px;
|
||||||
|
margin-left:45px;
|
||||||
|
width:182px;
|
||||||
|
text-align:center;
|
||||||
|
/* border: 1px solid #dde4e3;*/
|
||||||
|
padding-top:4px;
|
||||||
|
color: #fff;
|
||||||
|
background: #5e6363;
|
||||||
|
}
|
||||||
|
.searchTOC h4 {
|
||||||
|
color: #fff;
|
||||||
|
padding: 0 0 0 0;
|
||||||
|
}
|
||||||
|
.searchTOC ul {
|
||||||
|
width: 160px;
|
||||||
|
border: 1px solid #dde4e3;
|
||||||
|
background: #f1f2ee;
|
||||||
|
padding: 0 10px 0px 10px;
|
||||||
|
margin-top: 4px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.searchTOC ul li {
|
||||||
|
display: block;
|
||||||
|
border-bottom: 1px solid #dde4e3;
|
||||||
|
font-size: 14px;
|
||||||
|
height: 35px;
|
||||||
|
line-height: 35px;
|
||||||
|
}
|
||||||
|
.searchTOC ul li:last-child {
|
||||||
|
border-bottom: none
|
||||||
|
}
|
||||||
|
.searchTOC ul a {
|
||||||
|
display: block;
|
||||||
|
padding-left: 15px;
|
||||||
|
}
|
|
@ -119,10 +119,10 @@
|
||||||
Model model = (Model)application.getAttribute("jenaOntModel");
|
Model model = (Model)application.getAttribute("jenaOntModel");
|
||||||
editConfig.prepareForDataPropUpdate(model,dps);
|
editConfig.prepareForDataPropUpdate(model,dps);
|
||||||
formTitle = "Change text for: <em>"+prop.getPublicName()+"</em>";
|
formTitle = "Change text for: <em>"+prop.getPublicName()+"</em>";
|
||||||
submitLabel = "save change";
|
submitLabel = "Save change";
|
||||||
} else {
|
} else {
|
||||||
formTitle = "Add new entry for: <em>"+prop.getPublicName()+"</em>";
|
formTitle = "Add new entry for: <em>"+prop.getPublicName()+"</em>";
|
||||||
submitLabel = "save entry";
|
submitLabel = "Save entry";
|
||||||
}
|
}
|
||||||
%>
|
%>
|
||||||
|
|
||||||
|
|
|
@ -111,10 +111,10 @@
|
||||||
if ( prop.getOfferCreateNewOption() ) {
|
if ( prop.getOfferCreateNewOption() ) {
|
||||||
log.debug("property set to offer \"create new\" option; custom form: ["+prop.getCustomEntryForm()+"]");
|
log.debug("property set to offer \"create new\" option; custom form: ["+prop.getCustomEntryForm()+"]");
|
||||||
formTitle = "Select an existing "+rangeClass.getName()+" for "+subject.getName();
|
formTitle = "Select an existing "+rangeClass.getName()+" for "+subject.getName();
|
||||||
submitLabel = "select existing";
|
submitLabel = "Select existing";
|
||||||
} else {
|
} else {
|
||||||
formTitle = "Add an entry to: <em>"+prop.getDomainPublic()+"</em>";
|
formTitle = "Add an entry to: <em>"+prop.getDomainPublic()+"</em>";
|
||||||
submitLabel = "save entry";
|
submitLabel = "Save entry";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
%>
|
%>
|
||||||
|
@ -174,7 +174,7 @@ $(document).ready(function() {
|
||||||
<v:input type="submit" id="submit" value="<%=submitLabel%>" cancel="true"/>
|
<v:input type="submit" id="submit" value="<%=submitLabel%>" cancel="true"/>
|
||||||
<c:if test="${predicate.offerCreateNewOption == true}">
|
<c:if test="${predicate.offerCreateNewOption == true}">
|
||||||
<p>If you don't find the appropriate entry on the selection list,
|
<p>If you don't find the appropriate entry on the selection list,
|
||||||
<button type="button" onclick="javascript:document.location.href='${createNewUrl}'">add a new item to this list</button>
|
<button type="button" onclick="javascript:document.location.href='${createNewUrl}'">Add a new item to this list</button>
|
||||||
</p>
|
</p>
|
||||||
</c:if>
|
</c:if>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -137,10 +137,10 @@
|
||||||
Model model = (Model)application.getAttribute("jenaOntModel");
|
Model model = (Model)application.getAttribute("jenaOntModel");
|
||||||
editConfig.prepareForDataPropUpdate(model,dps);
|
editConfig.prepareForDataPropUpdate(model,dps);
|
||||||
formTitle = "Change text for: <em>"+prop.getPublicName()+"</em>";
|
formTitle = "Change text for: <em>"+prop.getPublicName()+"</em>";
|
||||||
submitLabel = "save change";
|
submitLabel = "Save change";
|
||||||
} else {
|
} else {
|
||||||
formTitle ="Add new entry for: <em>"+prop.getPublicName()+"</em>";
|
formTitle ="Add new entry for: <em>"+prop.getPublicName()+"</em>";
|
||||||
submitLabel ="save entry";
|
submitLabel ="Save entry";
|
||||||
}
|
}
|
||||||
%>
|
%>
|
||||||
|
|
||||||
|
|
|
@ -128,10 +128,10 @@
|
||||||
|
|
||||||
log.debug("property set to offer \"create new\" option; custom form: ["+prop.getCustomEntryForm()+"]");
|
log.debug("property set to offer \"create new\" option; custom form: ["+prop.getCustomEntryForm()+"]");
|
||||||
formTitle = "Select an existing "+classOfObjectFillers.getName()+" for "+subject.getName();
|
formTitle = "Select an existing "+classOfObjectFillers.getName()+" for "+subject.getName();
|
||||||
submitLabel = "select existing";
|
submitLabel = "Select existing";
|
||||||
} else {
|
} else {
|
||||||
formTitle = "Add an entry to: <em>"+prop.getDomainPublic()+"</em>";
|
formTitle = "Add an entry to: <em>"+prop.getDomainPublic()+"</em>";
|
||||||
submitLabel = "save entry";
|
submitLabel = "Save entry";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@
|
||||||
<input type="hidden" value="${param.objectUri}" name="objectUri"/>
|
<input type="hidden" value="${param.objectUri}" name="objectUri"/>
|
||||||
<input type="hidden" value="create" name="cmd"/>
|
<input type="hidden" value="create" name="cmd"/>
|
||||||
<v:input type="typesForCreateNew" id="typeOfNew" />
|
<v:input type="typesForCreateNew" id="typeOfNew" />
|
||||||
<v:input type="submit" id="submit" value="add a new item of this type" cancel="${offerCancel}"/>
|
<v:input type="submit" id="submit" value="Add a new item of this type" cancel="${offerCancel}"/>
|
||||||
</form>
|
</form>
|
||||||
</c:if>
|
</c:if>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ function changeAction(form, url) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
|
|
||||||
//Accounts per page
|
//Accounts per page
|
||||||
|
|
|
@ -140,8 +140,9 @@ var browseByVClass = {
|
||||||
browseByVClass.pagination(pages, page);
|
browseByVClass.pagination(pages, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedClassHeading = '<h3 class="selected-class">'+ results.vclass.name +'</h3>';
|
// selectedClassHeading = '<h3 class="selected-class">'+ results.vclass.name +'</h3>'; NIHVIVO-2483 tlw72
|
||||||
browseByVClass.individualsContainer.prepend(selectedClassHeading);
|
// browseByVClass.individualsContainer.prepend(selectedClassHeading);
|
||||||
|
$('h4#selectedClassHeading').text(results.vclass.name); // NIHVIVO-2483 tlw72
|
||||||
|
|
||||||
// Set selected class, alpha and page
|
// Set selected class, alpha and page
|
||||||
browseByVClass.selectedVClass(results.vclass.URI);
|
browseByVClass.selectedVClass(results.vclass.URI);
|
||||||
|
|
|
@ -34,13 +34,13 @@
|
||||||
<c:set var="query"
|
<c:set var="query"
|
||||||
value="PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
value="PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
||||||
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
||||||
SELECT ?pred ?predLabel ?obj ?objLabel
|
SELECT ?pred ?predLabel ?obj ?objLabel ?graph
|
||||||
WHERE
|
WHERE
|
||||||
{
|
{
|
||||||
{ GRAPH ?g { <${entity.URI}> ?pred ?obj} }
|
{ GRAPH ?graph { <${entity.URI}> ?pred ?obj} }
|
||||||
OPTIONAL { GRAPH ?h { ?obj rdfs:label ?objLabel } }
|
OPTIONAL { GRAPH ?h { ?obj rdfs:label ?objLabel } }
|
||||||
OPTIONAL { GRAPH ?i { ?pred rdfs:label ?predLabel } }
|
OPTIONAL { GRAPH ?i { ?pred rdfs:label ?predLabel } }
|
||||||
}
|
} ORDER BY ?graph ?pred
|
||||||
limit 10000"/>
|
limit 10000"/>
|
||||||
<form action="admin/sparqlquery" method="get">
|
<form action="admin/sparqlquery" method="get">
|
||||||
<input type="hidden" name="query" value="${query}"/>
|
<input type="hidden" name="query" value="${query}"/>
|
||||||
|
@ -51,13 +51,13 @@
|
||||||
<c:set var="query"
|
<c:set var="query"
|
||||||
value="PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
value="PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
||||||
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
||||||
SELECT ?sub ?subL ?pred ?predLabel
|
SELECT ?sub ?subL ?pred ?predLabel ?graph
|
||||||
WHERE
|
WHERE
|
||||||
{
|
{
|
||||||
{ GRAPH ?g { ?sub ?pred <${entity.URI}> } }
|
{ GRAPH ?graph { ?sub ?pred <${entity.URI}> } }
|
||||||
OPTIONAL { GRAPH ?h { ?sub rdfs:label ?subL } }
|
OPTIONAL { GRAPH ?h { ?sub rdfs:label ?subL } }
|
||||||
OPTIONAL { GRAPH ?i { ?pred rdfs:label ?predLabel } }
|
OPTIONAL { GRAPH ?i { ?pred rdfs:label ?predLabel } }
|
||||||
}
|
} ORDER BY ?graph ?pred
|
||||||
limit 10000"/>
|
limit 10000"/>
|
||||||
<form action="admin/sparqlquery" method="get">
|
<form action="admin/sparqlquery" method="get">
|
||||||
<input type="hidden" name="query" value="${query}"/>
|
<input type="hidden" name="query" value="${query}"/>
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
|
||||||
|
|
||||||
<#-- Confirmation that an account has been created. -->
|
|
||||||
|
|
||||||
${userAccount.firstName} ${userAccount.lastName}
|
|
||||||
|
|
||||||
Congratulations!
|
|
||||||
|
|
||||||
We have created your new VIVO account associated with
|
|
||||||
${userAccount.emailAddress}.
|
|
||||||
|
|
||||||
If you did not request this new account you can safely ignore this email.
|
|
||||||
This request will expire if not acted upon for 30 days.
|
|
||||||
|
|
||||||
Paste the link below into your browser's address bar to create your password
|
|
||||||
for your new account using our secure server.
|
|
||||||
|
|
||||||
${passwordLink}
|
|
||||||
|
|
||||||
Thanks!
|
|
|
@ -2,9 +2,12 @@
|
||||||
|
|
||||||
<#-- Confirmation that an account has been created. -->
|
<#-- Confirmation that an account has been created. -->
|
||||||
|
|
||||||
|
<#assign subject = "Your VIVO account has been created." />
|
||||||
|
|
||||||
|
<#assign html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>${subjectLine}</title>
|
<title>${subject}</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
|
@ -41,3 +44,25 @@
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
</#assign>
|
||||||
|
|
||||||
|
<#assign text>
|
||||||
|
${userAccount.firstName} ${userAccount.lastName}
|
||||||
|
|
||||||
|
Congratulations!
|
||||||
|
|
||||||
|
We have created your new VIVO account associated with
|
||||||
|
${userAccount.emailAddress}.
|
||||||
|
|
||||||
|
If you did not request this new account you can safely ignore this email.
|
||||||
|
This request will expire if not acted upon for 30 days.
|
||||||
|
|
||||||
|
Paste the link below into your browser's address bar to create your password
|
||||||
|
for your new account using our secure server.
|
||||||
|
|
||||||
|
${passwordLink}
|
||||||
|
|
||||||
|
Thanks!
|
||||||
|
</#assign>
|
||||||
|
|
||||||
|
<@email subject=subject html=html text=text />
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<#-- Template for adding a user account -->
|
<#-- Template for adding a user account -->
|
||||||
|
|
||||||
<h3>Add new account</h3>
|
<h3><a class="account-menu" href="accountsAdmin">User accounts</a> > Add new account</h3>
|
||||||
|
|
||||||
<#if errorEmailIsEmpty??>
|
<#if errorEmailIsEmpty??>
|
||||||
<#assign errorMessage = "You must supply an email address." />
|
<#assign errorMessage = "You must supply an email address." />
|
||||||
|
@ -16,6 +16,10 @@
|
||||||
<#assign errorMessage = "'${emailAddress}' is not a valid email address." />
|
<#assign errorMessage = "'${emailAddress}' is not a valid email address." />
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
|
<#if errorExternalAuthIdInUse??>
|
||||||
|
<#assign errorMessage = "An account with that external authorization ID already exists." />
|
||||||
|
</#if>
|
||||||
|
|
||||||
<#if errorFirstNameIsEmpty??>
|
<#if errorFirstNameIsEmpty??>
|
||||||
<#assign errorMessage = "You must supply a first name." />
|
<#assign errorMessage = "You must supply a first name." />
|
||||||
</#if>
|
</#if>
|
||||||
|
@ -61,9 +65,12 @@
|
||||||
<label for="last-name">Last name<span class="requiredHint"> *</span></label>
|
<label for="last-name">Last name<span class="requiredHint"> *</span></label>
|
||||||
<input type="text" name="lastName" value="${lastName}" id="last-name" role="input "/>
|
<input type="text" name="lastName" value="${lastName}" id="last-name" role="input "/>
|
||||||
|
|
||||||
|
<label for="external-auth-id">External authorization ID (optional)</label>
|
||||||
|
<input type="text" name="externalAuthId" value="${externalAuthId}" id="external-auth-id" role="input "/>
|
||||||
|
|
||||||
<p>Roles<span class="requiredHint"> *</span> </p>
|
<p>Roles<span class="requiredHint"> *</span> </p>
|
||||||
<#list roles as role>
|
<#list roles as role>
|
||||||
<input type="radio" name="role" value="${role.uri}" role="radio" <#if selectedRole = role.uri>selected</#if> />
|
<input type="radio" name="role" value="${role.uri}" role="radio" <#if selectedRole = role.uri>checked</#if> />
|
||||||
<label class="inline" for="${role.label}"> ${role.label}</label>
|
<label class="inline" for="${role.label}"> ${role.label}</label>
|
||||||
<br />
|
<br />
|
||||||
</#list>
|
</#list>
|
||||||
|
@ -93,7 +100,7 @@
|
||||||
</p>
|
</p>
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
<input type="submit" name="submitAdd" value="Add new account" class="submit"/> or <a href="${formUrls.list}">Cancel</a>
|
<input type="submit" name="submitAdd" value="Add new account" class="submit"/> or <a class="cancel" href="${formUrls.list}">Cancel</a>
|
||||||
|
|
||||||
<p class="requiredHint">* required fields</p>
|
<p class="requiredHint">* required fields</p>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
|
||||||
|
|
||||||
<#-- Confirmation that the user has changed his email account. -->
|
|
||||||
|
|
||||||
Hi, ${userAccount.firstName} ${userAccount.lastName}
|
|
||||||
|
|
||||||
You recently changed the email address associated with
|
|
||||||
${userAccount.firstName} ${userAccount.lastName}
|
|
||||||
|
|
||||||
Thank you.
|
|
|
@ -2,9 +2,12 @@
|
||||||
|
|
||||||
<#-- Confirmation that the user has changed his email account. -->
|
<#-- Confirmation that the user has changed his email account. -->
|
||||||
|
|
||||||
|
<#assign subject = "Your VIVO email account has been changed." />
|
||||||
|
|
||||||
|
<#assign html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>${subjectLine}</title>
|
<title>${subject}</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
|
@ -21,3 +24,15 @@
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
</#assign>
|
||||||
|
|
||||||
|
<#assign text>
|
||||||
|
Hi, ${userAccount.firstName} ${userAccount.lastName}
|
||||||
|
|
||||||
|
You recently changed the email address associated with
|
||||||
|
${userAccount.firstName} ${userAccount.lastName}
|
||||||
|
|
||||||
|
Thank you.
|
||||||
|
</#assign>
|
||||||
|
|
||||||
|
<@email subject=subject html=html text=text />
|
|
@ -3,7 +3,6 @@
|
||||||
<#-- Template for adding a user account -->
|
<#-- Template for adding a user account -->
|
||||||
|
|
||||||
<h3>Create your Password</h3>
|
<h3>Create your Password</h3>
|
||||||
|
|
||||||
<#if errorPasswordIsEmpty??>
|
<#if errorPasswordIsEmpty??>
|
||||||
<#assign errorMessage = "No password supplied." />
|
<#assign errorMessage = "No password supplied." />
|
||||||
</#if>
|
</#if>
|
||||||
|
@ -24,26 +23,24 @@
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
<section id="create-password" role="region">
|
<section id="create-password" role="region">
|
||||||
<fieldset>
|
<p>Please enter your new password for ${userAccount.emailAddress}</p>
|
||||||
<legend>Please enter your new password for ${userAccount.emailAddress}</legend>
|
|
||||||
|
|
||||||
<form method="POST" action="${formUrls.createPassword}" class="customForm" role="create password">
|
<form method="POST" action="${formUrls.createPassword}" class="customForm" role="create password">
|
||||||
<input type="hidden" name="user" value="${userAccount.emailAddress}" />
|
<input type="hidden" name="user" value="${userAccount.emailAddress}" role="input" />
|
||||||
<input type="hidden" name="key" value="${userAccount.passwordLinkExpiresHash}" />
|
<input type="hidden" name="key" value="${userAccount.passwordLinkExpiresHash}" role="input" />
|
||||||
|
|
||||||
<label for="new-password">Password<span class="requiredHint"> *</span></label>
|
<label for="new-password">Password<span class="requiredHint"> *</span></label>
|
||||||
<input type="password" name="newPassword" value="${newPassword}" id="new-password" role="input "/>
|
<input type="password" name="newPassword" value="${newPassword}" id="new-password" role="input" />
|
||||||
|
|
||||||
<p>Minimum of ${minimumLength} characters in length.</p>
|
<p class="note">Minimum of ${minimumLength} characters in length.</p>
|
||||||
|
|
||||||
<label for="confirm-password">Confirm Password<span class="requiredHint"> *</span></label>
|
<label for="confirm-password">Confirm Password<span class="requiredHint"> *</span></label>
|
||||||
<input type="password" name="confirmPassword" value="${confirmPassword}" id="confirm-password" role="input "/>
|
<input type="password" name="confirmPassword" value="${confirmPassword}" id="confirm-password" role="input" />
|
||||||
|
|
||||||
<input type="submit" name="submit" value="Save changes" class="submit"/>
|
<p><input type="submit" name="submit" value="Save changes" class="submit"/></p>
|
||||||
|
|
||||||
<p class="requiredHint">* required fields</p>
|
<p class="requiredHint">* required fields</p>
|
||||||
</form>
|
</form>
|
||||||
</fieldset>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/edit/forms/css/customForm.css" />')}
|
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/edit/forms/css/customForm.css" />')}
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<#-- Template for editing a user account -->
|
<#-- Template for editing a user account -->
|
||||||
|
|
||||||
<h3>Edit account</h3>
|
<h3><a class="account-menu" href="accountsAdmin">User accounts</a> > Edit account</h3>
|
||||||
|
|
||||||
<#if errorEmailIsEmpty??>
|
<#if errorEmailIsEmpty??>
|
||||||
<#assign errorMessage = "You must supply an email address." />
|
<#assign errorMessage = "You must supply an email address." />
|
||||||
|
@ -16,6 +16,10 @@
|
||||||
<#assign errorMessage = "'${emailAddress}' is not a valid email address." />
|
<#assign errorMessage = "'${emailAddress}' is not a valid email address." />
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
|
<#if errorExternalAuthIdInUse??>
|
||||||
|
<#assign errorMessage = "An account with that external authorization ID already exists." />
|
||||||
|
</#if>
|
||||||
|
|
||||||
<#if errorFirstNameIsEmpty??>
|
<#if errorFirstNameIsEmpty??>
|
||||||
<#assign errorMessage = "You must supply a first name." />
|
<#assign errorMessage = "You must supply a first name." />
|
||||||
</#if>
|
</#if>
|
||||||
|
@ -53,30 +57,35 @@
|
||||||
|
|
||||||
<form method="POST" action="${formUrls.edit}" class="customForm" role="edit account">
|
<form method="POST" action="${formUrls.edit}" class="customForm" role="edit account">
|
||||||
<label for="email-address">Email address<span class="requiredHint"> *</span></label>
|
<label for="email-address">Email address<span class="requiredHint"> *</span></label>
|
||||||
<input type="text" name="emailAddress" value="${emailAddress}" id="email-address" role="input "/>
|
<input type="text" name="emailAddress" value="${emailAddress}" id="email-address" role="input" />
|
||||||
|
|
||||||
<label for="first-name">First name<span class="requiredHint"> *</span></label>
|
<label for="first-name">First name<span class="requiredHint"> *</span></label>
|
||||||
<input type="text" name="firstName" value="${firstName}" id="first-name" role="input "/>
|
<input type="text" name="firstName" value="${firstName}" id="first-name" role="input" />
|
||||||
|
|
||||||
<label for="last-name">Last name<span class="requiredHint"> *</span></label>
|
<label for="last-name">Last name<span class="requiredHint"> *</span></label>
|
||||||
<input type="text" name="lastName" value="${lastName}" id="last-name" role="input "/>
|
<input type="text" name="lastName" value="${lastName}" id="last-name" role="input" />
|
||||||
|
|
||||||
<p>Roles<span class="requiredHint"> *</span> </p>
|
<label for="external-auth-id">External authorization ID (optional)</label>
|
||||||
<#list roles as role>
|
<input type="text" name="externalAuthId" value="${externalAuthId}" id="external-auth-id" role="input "/>
|
||||||
<input type="radio" name="role" value="${role.uri}" role="radio" <#if selectedRole = role.uri>selected</#if> />
|
|
||||||
<label class="inline" for="${role.label}"> ${role.label}</label>
|
<#if roles?has_content>
|
||||||
<br />
|
<p>Roles<span class="requiredHint"> *</span> </p>
|
||||||
</#list>
|
<#list roles as role>
|
||||||
|
<input type="radio" name="role" value="${role.uri}" role="radio" <#if selectedRole = role.uri>checked</#if> />
|
||||||
|
<label class="inline" for="${role.label}"> ${role.label}</label>
|
||||||
|
<br />
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
|
||||||
<#if !emailIsEnabled??>
|
<#if !emailIsEnabled??>
|
||||||
<label for="new-password">New password<span class="requiredHint"> *</span></label>
|
<label for="new-password">New password<span class="requiredHint"> *</span></label>
|
||||||
<input type="password" name="newPassword" value="${newPassword}" id="new-password" role="input "/>
|
<input type="password" name="newPassword" value="${newPassword}" id="new-password" role="input" />
|
||||||
|
|
||||||
<p>Minimum of ${minimumLength} characters in length.</p>
|
<p>Minimum of ${minimumLength} characters in length.</p>
|
||||||
<p>Leaving this blank means that the password will not be changed.</p>
|
<p>Leaving this blank means that the password will not be changed.</p>
|
||||||
|
|
||||||
<label for="confirm-password">Confirm initial password<span class="requiredHint"> *</span></label>
|
<label for="confirm-password">Confirm initial password<span class="requiredHint"> *</span></label>
|
||||||
<input type="text" name="confirmPassword" value="${confirmPassword}" id="confirm-password" role="input "/>
|
<input type="text" name="confirmPassword" value="${confirmPassword}" id="confirm-password" role="input" />
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
<p>Associate a profile with this account</p>
|
<p>Associate a profile with this account</p>
|
||||||
|
@ -87,18 +96,18 @@
|
||||||
<label class="inline" for="no-associate"> No</label>
|
<label class="inline" for="no-associate"> No</label>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<input type="checkbox" name="resetPassword" value="" id="reset-password" role="checkbox" />
|
<input type="checkbox" name="resetPassword" value="" id="reset-password" role="checkbox" <#if resetPassword??>checked</#if> />
|
||||||
<label class="inline" for="reset-password"> Reset password</label>
|
<label class="inline" for="reset-password"> Reset password</label>
|
||||||
|
|
||||||
<#if emailIsEnabled??>
|
<#if emailIsEnabled??>
|
||||||
<p class="note">
|
<p class="note">
|
||||||
Note: A confirmation email with instructions for resetting a password
|
Note: Instructions for resetting the password will
|
||||||
will be sent to the address entered above.
|
be emailed to the address entered above. The password will not
|
||||||
The password will not be reset until the user follows the link provided in this email.
|
be reset until the user follows the link provided in this email.
|
||||||
</p>
|
</p>
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
<input type="submit" name="submitEdit" value="Save changes" class="submit"/> or <a href="${formUrls.list}">Cancel</a>
|
<input type="submit" name="submitEdit" value="Save changes" class="submit" /> or <a class="cancel" href="${formUrls.list}">Cancel</a>
|
||||||
|
|
||||||
<p class="requiredHint">* required fields</p>
|
<p class="requiredHint">* required fields</p>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -38,16 +38,17 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<form method="POST" action="${formUrls.firstTimeExternal}" class="customForm" role="my account">
|
<form method="POST" action="${formUrls.firstTimeExternal}" class="customForm" role="my account">
|
||||||
<input type="hidden" name="externalAuthId" value="${externalAuthId}" />
|
<input type="hidden" name="externalAuthId" value="${externalAuthId}" role="input" />
|
||||||
|
<input type="hidden" name="afterLoginUrl" value="${afterLoginUrl}" role="input" />
|
||||||
|
|
||||||
<label for="first-name">First name<span class="requiredHint"> *</span></label>
|
<label for="first-name">First name<span class="requiredHint"> *</span></label>
|
||||||
<input type="text" name="firstName" value="${firstName}" id="first-name" role="input "/>
|
<input type="text" name="firstName" value="${firstName}" id="first-name" role="input" />
|
||||||
|
|
||||||
<label for="last-name">Last name<span class="requiredHint"> *</span></label>
|
<label for="last-name">Last name<span class="requiredHint"> *</span></label>
|
||||||
<input type="text" name="lastName" value="${lastName}" id="last-name" role="input "/>
|
<input type="text" name="lastName" value="${lastName}" id="last-name" role="input" />
|
||||||
|
|
||||||
<label for="email-address">Email address<span class="requiredHint"> *</span></label>
|
<label for="email-address">Email address<span class="requiredHint"> *</span></label>
|
||||||
<input type="text" name="emailAddress" value="${emailAddress}" id="email-address" role="input "/>
|
<input type="text" name="emailAddress" value="${emailAddress}" id="email-address" role="input" />
|
||||||
|
|
||||||
<#if emailIsEnabled??>
|
<#if emailIsEnabled??>
|
||||||
<p class="note">
|
<p class="note">
|
||||||
|
@ -56,7 +57,7 @@
|
||||||
</p>
|
</p>
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
<input type="submit" name="submit" value="Create account" class="submit"/> or <a href="${urls.home}">Cancel</a>
|
<input type="submit" name="submit" value="Create account" class="submit"/> or <a class="cancel" href="${urls.home}">Cancel</a>
|
||||||
</form>
|
</form>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
|
||||||
|
|
||||||
<#-- Confirmation that an account has been created for an externally-authenticated user. -->
|
|
||||||
|
|
||||||
${userAccount.firstName} ${userAccount.lastName}
|
|
||||||
|
|
||||||
Congratulations!
|
|
||||||
|
|
||||||
We have created your new VIVO account associated with
|
|
||||||
${userAccount.emailAddress}.
|
|
||||||
|
|
||||||
Thanks!
|
|
|
@ -2,9 +2,12 @@
|
||||||
|
|
||||||
<#-- Confirmation that an account has been created for an externally-authenticated user. -->
|
<#-- Confirmation that an account has been created for an externally-authenticated user. -->
|
||||||
|
|
||||||
|
<#assign subject = "Your VIVO account has been created." />
|
||||||
|
|
||||||
|
<#assign html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>${subjectLine}</title>
|
<title>${subject}</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
|
@ -24,3 +27,17 @@
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
</#assign>
|
||||||
|
|
||||||
|
<#assign text>
|
||||||
|
${userAccount.firstName} ${userAccount.lastName}
|
||||||
|
|
||||||
|
Congratulations!
|
||||||
|
|
||||||
|
We have created your new VIVO account associated with
|
||||||
|
${userAccount.emailAddress}.
|
||||||
|
|
||||||
|
Thanks!
|
||||||
|
</#assign>
|
||||||
|
|
||||||
|
<@email subject=subject html=html text=text />
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<#-- Template for editing a user account -->
|
<#-- Template for editing a user account -->
|
||||||
|
|
||||||
<h3>Edit account</h3>
|
<h3>My account</h3>
|
||||||
|
|
||||||
<#if errorEmailIsEmpty??>
|
<#if errorEmailIsEmpty??>
|
||||||
<#assign errorMessage = "You must supply an email address." />
|
<#assign errorMessage = "You must supply an email address." />
|
||||||
|
@ -43,7 +43,6 @@
|
||||||
</section>
|
</section>
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
|
|
||||||
<#if confirmChange??>
|
<#if confirmChange??>
|
||||||
<#assign confirmMessage = "Your changes have been saved." />
|
<#assign confirmMessage = "Your changes have been saved." />
|
||||||
</#if>
|
</#if>
|
||||||
|
@ -65,28 +64,27 @@
|
||||||
|
|
||||||
<form method="POST" action="${formUrls.myAccount}" class="customForm" role="my account">
|
<form method="POST" action="${formUrls.myAccount}" class="customForm" role="my account">
|
||||||
<label for="email-address">Email address<span class="requiredHint"> *</span></label>
|
<label for="email-address">Email address<span class="requiredHint"> *</span></label>
|
||||||
<input type="text" name="emailAddress" value="${emailAddress}" id="email-address" role="input "/>
|
<input type="text" name="emailAddress" value="${emailAddress}" id="email-address" role="input" />
|
||||||
|
|
||||||
<p>Note: if email changes, a confirmation email will be sent to the new email address entered above.</p>
|
<p class="note">Note: if email changes, a confirmation email will be sent to the new email address entered above.</p>
|
||||||
|
|
||||||
<label for="first-name">First name<span class="requiredHint"> *</span></label>
|
<label for="first-name">First name<span class="requiredHint"> *</span></label>
|
||||||
<input type="text" name="firstName" value="${firstName}" id="first-name" role="input "/>
|
<input type="text" name="firstName" value="${firstName}" id="first-name" role="input" />
|
||||||
|
|
||||||
<label for="last-name">Last name<span class="requiredHint"> *</span></label>
|
<label for="last-name">Last name<span class="requiredHint"> *</span></label>
|
||||||
<input type="text" name="lastName" value="${lastName}" id="last-name" role="input "/>
|
<input type="text" name="lastName" value="${lastName}" id="last-name" role="input" />
|
||||||
|
|
||||||
<#if !externalAuth??>
|
<#if !externalAuth??>
|
||||||
<label for="new-password">New password<span class="requiredHint"> *</span></label>
|
<label for="new-password">New password</label>
|
||||||
<input type="password" name="newPassword" value="${newPassword}" id="new-password" role="input "/>
|
<input type="password" name="newPassword" value="${newPassword}" id="new-password" role="input" />
|
||||||
|
|
||||||
<p>Minimum of ${minimumLength} characters in length.</p>
|
<p class="note">Minimum of ${minimumLength} characters in length. Leaving this blank means that the password will not be changed.</p>
|
||||||
<p>Leaving this blank means that the password will not be changed.</p>
|
|
||||||
|
|
||||||
<label for="confirm-password">Confirm initial password<span class="requiredHint"> *</span></label>
|
<label for="confirm-password">Confirm new password</label>
|
||||||
<input type="text" name="confirmPassword" value="${confirmPassword}" id="confirm-password" role="input "/>
|
<input type="password" name="confirmPassword" value="${confirmPassword}" id="confirm-password" role="input" />
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
<input type="submit" name="submitMyAccount" value="Save changes" class="submit"/>
|
<p><input type="submit" name="submitMyAccount" value="Save changes" class="submit" /></p>
|
||||||
|
|
||||||
<p class="requiredHint">* required fields</p>
|
<p class="requiredHint">* required fields</p>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
|
||||||
|
|
||||||
<#-- Confirmation that a password has been created. -->
|
|
||||||
|
|
||||||
${userAccount.firstName} ${userAccount.lastName}
|
|
||||||
|
|
||||||
Password successfully created.
|
|
||||||
|
|
||||||
Your new password associated with ${userAccount.emailAddress}
|
|
||||||
has been created.
|
|
||||||
|
|
||||||
Thank you.
|
|
|
@ -2,9 +2,12 @@
|
||||||
|
|
||||||
<#-- Confirmation that an password has been created. -->
|
<#-- Confirmation that an password has been created. -->
|
||||||
|
|
||||||
|
<#assign subject = "Password successfully created." />
|
||||||
|
|
||||||
|
<#assign html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>${subjectLine}</title>
|
<title>${subject}</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
|
@ -24,3 +27,17 @@
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
</#assign>
|
||||||
|
|
||||||
|
<#assign text>
|
||||||
|
${userAccount.firstName} ${userAccount.lastName}
|
||||||
|
|
||||||
|
Password successfully created.
|
||||||
|
|
||||||
|
Your new password associated with ${userAccount.emailAddress}
|
||||||
|
has been created.
|
||||||
|
|
||||||
|
Thank you.
|
||||||
|
</#assign>
|
||||||
|
|
||||||
|
<@email subject=subject html=html text=text />
|
|
@ -1,12 +0,0 @@
|
||||||
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
|
||||||
|
|
||||||
<#-- Confirmation that a password has been reset. -->
|
|
||||||
|
|
||||||
${userAccount.firstName} ${userAccount.lastName}
|
|
||||||
|
|
||||||
Password successfully changed.
|
|
||||||
|
|
||||||
Your new password associated with ${userAccount.emailAddress}
|
|
||||||
has been changed.
|
|
||||||
|
|
||||||
Thank you.
|
|
|
@ -1,10 +1,13 @@
|
||||||
<#-- $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$ -->
|
||||||
|
|
||||||
<#-- Confirmation that an password has been reset. -->
|
<#-- Confirmation that a password has been reset. -->
|
||||||
|
|
||||||
|
<#assign subject = "Password changed." />
|
||||||
|
|
||||||
|
<#assign html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>${subjectLine}</title>
|
<title>${subject}</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
|
@ -24,3 +27,17 @@
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
</#assign>
|
||||||
|
|
||||||
|
<#assign text>
|
||||||
|
${userAccount.firstName} ${userAccount.lastName}
|
||||||
|
|
||||||
|
Password successfully changed.
|
||||||
|
|
||||||
|
Your new password associated with ${userAccount.emailAddress}
|
||||||
|
has been changed.
|
||||||
|
|
||||||
|
Thank you.
|
||||||
|
</#assign>
|
||||||
|
|
||||||
|
<@email subject=subject html=html text=text />
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
<h3>Reset your Password</h3>
|
<h3>Reset your Password</h3>
|
||||||
|
|
||||||
|
<p>Please enter your new password for ${userAccount.emailAddress}</p>
|
||||||
|
|
||||||
<#if errorPasswordIsEmpty??>
|
<#if errorPasswordIsEmpty??>
|
||||||
<#assign errorMessage = "No password supplied." />
|
<#assign errorMessage = "No password supplied." />
|
||||||
</#if>
|
</#if>
|
||||||
|
@ -24,26 +26,22 @@
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
<section id="reset-password" role="region">
|
<section id="reset-password" role="region">
|
||||||
<fieldset>
|
<form method="POST" action="${formUrls.resetPassword}" class="customForm" role="create password">
|
||||||
<legend>Please enter your new password for ${userAccount.emailAddress}</legend>
|
<input type="hidden" name="user" value="${userAccount.emailAddress}" />
|
||||||
|
<input type="hidden" name="key" value="${userAccount.passwordLinkExpiresHash}" />
|
||||||
|
|
||||||
<form method="POST" action="${formUrls.resetPassword}" class="customForm" role="create password">
|
<label for="new-password">Password<span class="requiredHint"> *</span></label>
|
||||||
<input type="hidden" name="user" value="${userAccount.emailAddress}" />
|
<input type="password" name="newPassword" value="${newPassword}" id="new-password" role="input" />
|
||||||
<input type="hidden" name="key" value="${userAccount.passwordLinkExpiresHash}" />
|
|
||||||
|
|
||||||
<label for="new-password">Password<span class="requiredHint"> *</span></label>
|
<p class="note">Minimum of ${minimumLength} characters in length.</p>
|
||||||
<input type="password" name="newPassword" value="${newPassword}" id="new-password" role="input "/>
|
|
||||||
|
|
||||||
<p>Minimum of ${minimumLength} characters in length.</p>
|
<label for="confirm-password">Confirm Password<span class="requiredHint"> *</span></label>
|
||||||
|
<input type="password" name="confirmPassword" value="${confirmPassword}" id="confirm-password" role="input" />
|
||||||
|
|
||||||
<label for="confirm-password">Confirm Password<span class="requiredHint"> *</span></label>
|
<p><input type="submit" name="submit" value="Save changes" class="submit" /></p>
|
||||||
<input type="password" name="confirmPassword" value="${confirmPassword}" id="confirm-password" role="input "/>
|
|
||||||
|
|
||||||
<input type="submit" name="submit" value="Save changes" class="submit"/>
|
<p class="requiredHint">* required fields</p>
|
||||||
|
</form>
|
||||||
<p class="requiredHint">* required fields</p>
|
|
||||||
</form>
|
|
||||||
</fieldset>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/edit/forms/css/customForm.css" />')}
|
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/edit/forms/css/customForm.css" />')}
|
|
@ -1,40 +0,0 @@
|
||||||
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
|
||||||
|
|
||||||
<#-- Notification that your password has been reset. -->
|
|
||||||
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>${subjectLine}</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p>
|
|
||||||
${userAccount.firstName} ${userAccount.lastName}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
We received a request to reset the password for your account (${userAccount.emailAddress}).
|
|
||||||
Please follow the instructions below to proceed with your password reset.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If you did not request this new account you can safely ignore this email.
|
|
||||||
This request will expire if not acted upon for 30 days.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Click the link below to reset your password using our secure server.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="${passwordLink}">${passwordLink}</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If the link above doesn't work, you can copy and paste the link directly into your browser's address bar.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Thank you!
|
|
||||||
</p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,19 +0,0 @@
|
||||||
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
|
||||||
|
|
||||||
<#-- Notification that your password has been reset. -->
|
|
||||||
|
|
||||||
${userAccount.firstName} ${userAccount.lastName}
|
|
||||||
|
|
||||||
We received a request to reset the password for your account
|
|
||||||
(${userAccount.emailAddress}).
|
|
||||||
Please follow the instructions below to proceed with your password reset.
|
|
||||||
|
|
||||||
If you did not request this new account you can safely ignore this email.
|
|
||||||
This request will expire if not acted upon for 30 days.
|
|
||||||
|
|
||||||
Paste the link below into your browser's address bar to reset your password
|
|
||||||
using our secure server.
|
|
||||||
|
|
||||||
${passwordLink}
|
|
||||||
|
|
||||||
Thank you!
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
||||||
|
|
||||||
|
<#-- Confirmation email for user account password reset -->
|
||||||
|
|
||||||
|
<#assign subject = "${siteName} reset password request" />
|
||||||
|
|
||||||
|
<#assign html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>${subject}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
Dear ${userAccount.firstName} ${userAccount.lastName}:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
We have received a request to reset the password for your ${siteName} account (${userAccount.emailAddress}).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Please follow the instructions below to proceed with your password reset.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If you did not request this new account you can safely ignore this email.
|
||||||
|
This request will expire if not acted upon within 30 days.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Click on the link below or paste it into your browser's address bar to reset your password
|
||||||
|
using our secure server.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>${passwordLink}</p>
|
||||||
|
|
||||||
|
<p>Thank you!</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</#assign>
|
||||||
|
|
||||||
|
<#assign text>
|
||||||
|
Dear ${userAccount.firstName} ${userAccount.lastName}:
|
||||||
|
|
||||||
|
We have received a request to reset the password for your ${siteName} account
|
||||||
|
(${userAccount.emailAddress}).
|
||||||
|
|
||||||
|
Please follow the instructions below to proceed with your password reset.
|
||||||
|
|
||||||
|
If you did not request this new account you can safely ignore this email.
|
||||||
|
This request will expire if not acted upon within 30 days.
|
||||||
|
|
||||||
|
Paste the link below into your browser's address bar to reset your password
|
||||||
|
using our secure server.
|
||||||
|
|
||||||
|
${passwordLink}
|
||||||
|
|
||||||
|
Thank you!
|
||||||
|
</#assign>
|
||||||
|
|
||||||
|
<@email subject=subject html=html text=text />
|
|
@ -20,7 +20,8 @@
|
||||||
</#if>
|
</#if>
|
||||||
</#list>
|
</#list>
|
||||||
</ul>
|
</ul>
|
||||||
<nav role="navigation">
|
<nav id="alpha-browse-container" role="navigation">
|
||||||
|
<h4 id="selectedClassHeading"></h4>
|
||||||
<#assign alphabet = ["A", "B", "C", "D", "E", "F", "G" "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] />
|
<#assign alphabet = ["A", "B", "C", "D", "E", "F", "G" "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] />
|
||||||
<ul id="alpha-browse-individuals">
|
<ul id="alpha-browse-individuals">
|
||||||
<li><a href="#" class="selected" data-alpha="all">All</a></li>
|
<li><a href="#" class="selected" data-alpha="all">All</a></li>
|
||||||
|
|
|
@ -13,19 +13,23 @@
|
||||||
<#-- Refinement links -->
|
<#-- Refinement links -->
|
||||||
<#if classGroupLinks?has_content>
|
<#if classGroupLinks?has_content>
|
||||||
<div class="searchTOC">
|
<div class="searchTOC">
|
||||||
<span class="jumpText">Show only results of this <b>type</b>:</span>
|
<h4>Display only</h4>
|
||||||
|
<ul>
|
||||||
<#list classGroupLinks as link>
|
<#list classGroupLinks as link>
|
||||||
<a href="${link.url}">${link.text}</a>
|
<li><a href="${link.url}">${link.text}</a></li>
|
||||||
</#list>
|
</#list>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
<#if classLinks?has_content>
|
<#if classLinks?has_content>
|
||||||
<div class="searchTOC">
|
<div class="searchTOC">
|
||||||
<span class="jumpText">Show only results of this <b>subtype</b>:</span>
|
<h4>Limit ${classGroupName} to</h4>
|
||||||
|
<ul>
|
||||||
<#list classLinks as link>
|
<#list classLinks as link>
|
||||||
<a href="${link.url}">${link.text}</a>
|
<li><a href="${link.url}">${link.text}</a></li>
|
||||||
</#list>
|
</#list>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue