diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/UserAccount.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/UserAccount.java index 7b5581885..7b9d49792 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/UserAccount.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/UserAccount.java @@ -7,11 +7,17 @@ import java.util.Collections; import java.util.HashSet; import java.util.Set; -import org.apache.commons.lang3.RandomStringUtils; +import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator; /** * Information about the account of a user. URI, email, password, etc. * + * The "password link expires hash" is just a string that is derived from the + * value in the passwordLinkExpires field. It doesn't have to be a hash, and + * there is no need for it to be cryptographic, but it seems embarrassing to + * just send the value as a clear string. There is no real need for security + * here, except that a brute force attack would allow someone to change the + * password on an account that they know has a password change pending. */ public class UserAccount { public static final int MIN_PASSWORD_LENGTH = 6; @@ -46,7 +52,6 @@ public class UserAccount { private String md5Password = ""; // Never null. private String oldPassword = ""; // Never null. private long passwordLinkExpires = 0L; // Never negative. - private String emailKey = ""; private boolean passwordChangeRequired = false; private int loginCount = 0; // Never negative. @@ -128,25 +133,13 @@ public class UserAccount { return passwordLinkExpires; } - public void setPasswordLinkExpires(long passwordLinkExpires) { - this.passwordLinkExpires = Math.max(0, passwordLinkExpires); + public String getPasswordLinkExpiresHash() { + return limitStringLength(8, Authenticator.applyArgon2iEncoding(String + .valueOf(passwordLinkExpires))); } - public void generateEmailKey() { - boolean useLetters = true; - boolean useNumbers = true; - int length = 64; - emailKey = RandomStringUtils.random(length, useLetters, useNumbers); - } - - public void setEmailKey(String emailKey) { - if (emailKey != null) { - this.emailKey = emailKey; - } - } - - public String getEmailKey() { - return emailKey; + public void setPasswordLinkExpires(long passwordLinkExpires) { + this.passwordLinkExpires = Math.max(0, passwordLinkExpires); } public boolean isPasswordChangeRequired() { @@ -254,7 +247,6 @@ public class UserAccount { + (", oldPassword=" + oldPassword) + (", argon2password=" + argon2Password) + (", passwordLinkExpires=" + passwordLinkExpires) - + (", emailKey =" + emailKey) + (", passwordChangeRequired=" + passwordChangeRequired) + (", externalAuthOnly=" + externalAuthOnly) + (", loginCount=" + loginCount) + (", status=" + status) diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsSelector.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsSelector.java index d878ae315..6caadf24c 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsSelector.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsSelector.java @@ -249,7 +249,6 @@ public class UserAccountsSelector { user.setMd5Password(ifLiteralPresent(solution, "md5pwd", "")); user.setArgon2Password(ifLiteralPresent(solution, "a2pwd", "")); user.setPasswordLinkExpires(ifLongPresent(solution, "expire", 0L)); - user.setEmailKey(ifLiteralPresent(solution, "emailKey", "")); user.setLoginCount(ifIntPresent(solution, "count", 0)); user.setLastLoginTime(ifLongPresent(solution, "lastLogin", 0)); user.setStatus(parseStatus(solution, "status", null)); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPage.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPage.java index 7fc4181da..bdbc5dbce 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPage.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPage.java @@ -156,7 +156,6 @@ public class UserAccountsAddPage extends UserAccountsPage { u.setOldPassword(""); u.setPasswordChangeRequired(false); u.setPasswordLinkExpires(0); - u.setEmailKey(""); u.setLoginCount(0); u.setLastLoginTime(0L); u.setStatus(Status.INACTIVE); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPageStrategy.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPageStrategy.java index 036d314e2..307ccf9f6 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPageStrategy.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPageStrategy.java @@ -84,7 +84,6 @@ public abstract class UserAccountsAddPageStrategy extends UserAccountsPage { u.setStatus(Status.ACTIVE); } else { u.setPasswordLinkExpires(figureExpirationDate().getTime()); - u.generateEmailKey(); u.setStatus(Status.INACTIVE); } } @@ -120,8 +119,10 @@ public abstract class UserAccountsAddPageStrategy extends UserAccountsPage { private String buildCreatePasswordLink() { try { String email = page.getAddedAccount().getEmailAddress(); - String key = page.getAddedAccount().getEmailKey(); - String relativeUrl = UrlBuilder.getUrl(CREATE_PASSWORD_URL, "user", email, "key", key); + String hash = page.getAddedAccount() + .getPasswordLinkExpiresHash(); + String relativeUrl = UrlBuilder.getUrl(CREATE_PASSWORD_URL, + "user", email, "key", hash); URL context = new URL(vreq.getRequestURL().toString()); URL url = new URL(context, relativeUrl); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java index 13e1ab0dd..42dd4102d 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java @@ -274,7 +274,6 @@ public class UserAccountsEditPage extends UserAccountsPage { userAccount.setOldPassword(""); userAccount.setPasswordChangeRequired(false); userAccount.setPasswordLinkExpires(0L); - userAccount.setEmailKey(""); } if (isRootUser()) { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPageStrategy.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPageStrategy.java index d9ee8aa14..708f11e66 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPageStrategy.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPageStrategy.java @@ -82,7 +82,6 @@ public abstract class UserAccountsEditPageStrategy extends UserAccountsPage { protected void setAdditionalProperties(UserAccount u) { if (resetPassword && !page.isExternalAuthOnly()) { u.setPasswordLinkExpires(figureExpirationDate().getTime()); - u.generateEmailKey(); } } @@ -122,8 +121,10 @@ public abstract class UserAccountsEditPageStrategy extends UserAccountsPage { private String buildResetPasswordLink() { try { String email = page.getUpdatedAccount().getEmailAddress(); - String key = page.getUpdatedAccount().getEmailKey(); - String relativeUrl = UrlBuilder.getUrl(RESET_PASSWORD_URL, "user", email, "key", key); + String hash = page.getUpdatedAccount() + .getPasswordLinkExpiresHash(); + String relativeUrl = UrlBuilder.getUrl(RESET_PASSWORD_URL, + "user", email, "key", hash); URL context = new URL(vreq.getRequestURL().toString()); URL url = new URL(context, relativeUrl); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsCreatePasswordPage.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsCreatePasswordPage.java index 68daa2d67..b9515d4c7 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsCreatePasswordPage.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsCreatePasswordPage.java @@ -36,7 +36,6 @@ public class UserAccountsCreatePasswordPage extends userAccount.setArgon2Password(Authenticator.applyArgon2iEncoding(newPassword)); userAccount.setMd5Password(""); userAccount.setPasswordLinkExpires(0L); - userAccount.setEmailKey(""); userAccount.setPasswordChangeRequired(false); userAccount.setStatus(Status.ACTIVE); userAccountsDao.updateUserAccount(userAccount); @@ -54,11 +53,6 @@ public class UserAccountsCreatePasswordPage extends protected String passwordChangeNotPendingMessage() { return i18n.text("account_already_activated", userEmail); } - - @Override - protected String passwordChangeInavlidKeyMessage() { - return i18n.text("password_change_invalid_key", userEmail); - } @Override protected String templateName() { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsFirstTimeExternalPage.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsFirstTimeExternalPage.java index ffb34c754..fc11f665d 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsFirstTimeExternalPage.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsFirstTimeExternalPage.java @@ -195,7 +195,6 @@ public class UserAccountsFirstTimeExternalPage extends UserAccountsPage { u.setExternalAuthId(externalAuthId); u.setPasswordChangeRequired(false); u.setPasswordLinkExpires(0); - u.setEmailKey(""); u.setExternalAuthOnly(true); u.setLoginCount(0); u.setStatus(Status.ACTIVE); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsMyAccountPageStrategy.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsMyAccountPageStrategy.java index ca895cab8..057098eea 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsMyAccountPageStrategy.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsMyAccountPageStrategy.java @@ -159,7 +159,6 @@ public abstract class UserAccountsMyAccountPageStrategy extends userAccount.setMd5Password(""); userAccount.setPasswordChangeRequired(false); userAccount.setPasswordLinkExpires(0L); - userAccount.setEmailKey(""); } } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsPasswordBasePage.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsPasswordBasePage.java index d4cc56f03..3923c17b2 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsPasswordBasePage.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsPasswordBasePage.java @@ -103,12 +103,12 @@ public abstract class UserAccountsPasswordBasePage extends UserAccountsPage { return; } - String expectedKey = userAccount.getEmailKey(); - if (key.isEmpty() || !key.equals(expectedKey)) { + String expectedKey = userAccount.getPasswordLinkExpiresHash(); + if (!key.equals(expectedKey)) { log.warn("Password request for '" + userEmail + "' is bogus: key (" + key + ") doesn't match expected key (" + expectedKey + ")"); - bogusMessage = passwordChangeInavlidKeyMessage(); + bogusMessage = passwordChangeNotPendingMessage(); return; } @@ -153,7 +153,7 @@ public abstract class UserAccountsPasswordBasePage extends UserAccountsPage { body.put("minimumLength", UserAccount.MIN_PASSWORD_LENGTH); body.put("maximumLength", UserAccount.MAX_PASSWORD_LENGTH); body.put("userAccount", userAccount); - body.put("key", userAccount.getEmailKey()); + body.put("key", userAccount.getPasswordLinkExpiresHash()); body.put("newPassword", newPassword); body.put("confirmPassword", confirmPassword); body.put("formUrls", buildUrlsMap()); @@ -176,8 +176,6 @@ public abstract class UserAccountsPasswordBasePage extends UserAccountsPage { protected abstract String alreadyLoggedInMessage(String currentUserEmail); protected abstract String passwordChangeNotPendingMessage(); - - protected abstract String passwordChangeInavlidKeyMessage(); protected abstract String templateName(); } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsResetPasswordPage.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsResetPasswordPage.java index f865cbe94..712df1b40 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsResetPasswordPage.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsResetPasswordPage.java @@ -55,11 +55,6 @@ public class UserAccountsResetPasswordPage extends UserAccountsPasswordBasePage protected String passwordChangeNotPendingMessage() { return i18n.text("password_change_not_pending", userEmail); } - - @Override - protected String passwordChangeInavlidKeyMessage() { - return i18n.text("password_change_invalid_key", userEmail); - } @Override protected String templateName() { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/BasicAuthenticator.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/BasicAuthenticator.java index 34fc6a01d..f6f95081b 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/BasicAuthenticator.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/BasicAuthenticator.java @@ -134,7 +134,6 @@ public class BasicAuthenticator extends Authenticator { userAccount.setMd5Password(""); userAccount.setPasswordChangeRequired(false); userAccount.setPasswordLinkExpires(0L); - userAccount.setEmailKey(""); getUserAccountsDao().updateUserAccount(userAccount); } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/DeleteIndividualController.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/DeleteIndividualController.java index c6939fb77..1a61ef980 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/DeleteIndividualController.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/DeleteIndividualController.java @@ -154,14 +154,14 @@ public class DeleteIndividualController extends FreemarkerHttpServlet{ private byte[] getIndividualsToDelete(String targetIndividual, String deleteQuery,VitroRequest vreq) { ByteArrayOutputStream out = new ByteArrayOutputStream(); - try { - Query queryForTypeSpecificDeleteQuery = QueryFactory.create(deleteQuery); - QuerySolutionMap initialBindings = new QuerySolutionMap(); - initialBindings.add("individualURI", ResourceFactory.createResource( targetIndividual )); - Model ontModel = vreq.getJenaOntModel(); + Query queryForTypeSpecificDeleteQuery = QueryFactory.create(deleteQuery); + QuerySolutionMap initialBindings = new QuerySolutionMap(); + initialBindings.add("individualURI", ResourceFactory.createResource( targetIndividual )); + Model ontModel = vreq.getJenaOntModel(); + try { QueryExecution qexec = QueryExecutionFactory.create(queryForTypeSpecificDeleteQuery,ontModel,initialBindings ); - Model results = qexec.execDescribe(); - results.write(out,"N3"); + Model results = qexec.execDescribe(); + results.write(out,"N3"); } catch (Exception e) { log.error("Query raised an error \n" + deleteQuery); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java index fba900cad..fdd9387c0 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java @@ -155,7 +155,6 @@ public class VitroVocabulary { public static final String USERACCOUNT_LAST_LOGIN_TIME = VITRO_AUTH + "lastLoginTime"; public static final String USERACCOUNT_STATUS = VITRO_AUTH + "status"; public static final String USERACCOUNT_PASSWORD_LINK_EXPIRES = VITRO_AUTH + "passwordLinkExpires"; - public static final String USERACCOUNT_EMAIL_KEY = VITRO_AUTH + "emailKey"; public static final String USERACCOUNT_PASSWORD_CHANGE_REQUIRED = VITRO_AUTH + "passwordChangeRequired"; public static final String USERACCOUNT_EXTERNAL_AUTH_ID = VITRO_AUTH + "externalAuthId"; public static final String USERACCOUNT_EXTERNAL_AUTH_ONLY = VITRO_AUTH + "externalAuthOnly"; diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDaoCon.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDaoCon.java index 71fd6447a..d618ac804 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDaoCon.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDaoCon.java @@ -121,7 +121,6 @@ public class JenaBaseDaoCon { protected DatatypeProperty USERACCOUNT_LAST_LOGIN_TIME = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_LAST_LOGIN_TIME); protected DatatypeProperty USERACCOUNT_STATUS = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_STATUS); protected DatatypeProperty USERACCOUNT_PASSWORD_LINK_EXPIRES = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_PASSWORD_LINK_EXPIRES); - protected DatatypeProperty USERACCOUNT_EMAIL_KEY = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_EMAIL_KEY); protected DatatypeProperty USERACCOUNT_PASSWORD_CHANGE_REQUIRED = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_PASSWORD_CHANGE_REQUIRED); protected DatatypeProperty USERACCOUNT_EXTERNAL_AUTH_ID = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_EXTERNAL_AUTH_ID); protected DatatypeProperty USERACCOUNT_EXTERNAL_AUTH_ONLY = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_EXTERNAL_AUTH_ONLY); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraph.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraph.java index 9b6642c4d..491858453 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraph.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraph.java @@ -12,10 +12,10 @@ import java.util.function.Supplier; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.apache.jena.graph.Capabilities; import org.apache.jena.graph.Graph; import org.apache.jena.graph.GraphEventManager; -import org.apache.jena.graph.GraphListener; import org.apache.jena.graph.GraphStatisticsHandler; import org.apache.jena.graph.Node; import org.apache.jena.graph.TransactionHandler; @@ -23,6 +23,7 @@ import org.apache.jena.graph.Triple; import org.apache.jena.graph.impl.GraphWithPerform; import org.apache.jena.graph.impl.SimpleEventManager; import org.apache.jena.query.QuerySolution; +import org.apache.jena.rdf.listeners.StatementListener; import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.ModelFactory; import org.apache.jena.rdf.model.StmtIterator; @@ -403,18 +404,7 @@ public class RDFServiceGraph implements GraphWithPerform { @Override public GraphEventManager getEventManager() { if (eventManager == null) { - eventManager = new SimpleEventManager() { - @Override - public void notifyEvent(Graph g, Object event) { - ChangeSet changeSet = rdfService.manufactureChangeSet(); - changeSet.addPreChangeEvent(event); - try { - rdfService.changeSetUpdate(changeSet); - } catch (RDFServiceException e) { - throw new RuntimeException(e); - } - } - }; + eventManager = new SimpleEventManager(this); } return eventManager; } @@ -600,7 +590,21 @@ public class RDFServiceGraph implements GraphWithPerform { } public static Model createRDFServiceModel(final RDFServiceGraph g) { - return VitroModelFactory.createModelForGraph(g); + Model m = VitroModelFactory.createModelForGraph(g); + m.register(new StatementListener() { + @Override + public void notifyEvent(Model m, Object event) { + ChangeSet changeSet = g.getRDFService().manufactureChangeSet(); + changeSet.addPreChangeEvent(event); + try { + g.getRDFService().changeSetUpdate(changeSet); + } catch (RDFServiceException e) { + throw new RuntimeException(e); + } + } + + }); + return m; } @Override diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJena.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJena.java index 29c1d5a29..73557fd5c 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJena.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJena.java @@ -4,6 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Random; @@ -97,8 +98,6 @@ public class UserAccountsDaoJena extends JenaBaseDao implements UserAccountsDao u.setOldPassword(getPropertyStringValue(r, USERACCOUNT_OLD_PASSWORD)); u.setPasswordLinkExpires(getPropertyLongValue(r, USERACCOUNT_PASSWORD_LINK_EXPIRES)); - u.setEmailKey(getPropertyStringValue(r,USERACCOUNT_EMAIL_KEY)); - u.setPasswordChangeRequired(getPropertyBooleanValue(r, USERACCOUNT_PASSWORD_CHANGE_REQUIRED)); u.setExternalAuthOnly(getPropertyBooleanValue(r, @@ -241,8 +240,6 @@ public class UserAccountsDaoJena extends JenaBaseDao implements UserAccountsDao userAccount.getLoginCount(), model); addPropertyLongValue(res, USERACCOUNT_LAST_LOGIN_TIME, userAccount.getLastLoginTime(), model); - addPropertyStringValue(res, USERACCOUNT_EMAIL_KEY, - userAccount.getEmailKey(), model); if (userAccount.getStatus() != null) { addPropertyStringValue(res, USERACCOUNT_STATUS, userAccount .getStatus().toString(), model); @@ -309,8 +306,6 @@ public class UserAccountsDaoJena extends JenaBaseDao implements UserAccountsDao userAccount.getLoginCount(), model); updatePropertyLongValue(res, USERACCOUNT_LAST_LOGIN_TIME, userAccount.getLastLoginTime(), model); - updatePropertyStringValue(res, USERACCOUNT_EMAIL_KEY, - userAccount.getEmailKey(), model); if (userAccount.getStatus() == null) { updatePropertyStringValue(res, USERACCOUNT_STATUS, null, model); } else { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java index da3f9be3e..e72e172c1 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java @@ -61,10 +61,6 @@ public class EditConfigurationUtils { return vreq.getParameter("rangeUri"); } - public static String getTypeOfNew(VitroRequest vreq) { - return vreq.getParameter("typeOfNew"); - } - public static VClass getRangeVClass(VitroRequest vreq) { // This needs a WebappDaoFactory with no filtering/RDFService // funny business because it needs to be able to retrieve anonymous union diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultDeleteGenerator.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultDeleteGenerator.java index c329543fe..11ef2d455 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultDeleteGenerator.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultDeleteGenerator.java @@ -49,26 +49,18 @@ public class DefaultDeleteGenerator extends BaseEditConfigurationGenerator imple prepare(vreq, editConfiguration); if (editConfiguration.getPredicateUri() == null && editConfiguration.getSubjectUri() == null) { editConfiguration.setTemplate(individualTemplate); - addDeleteParams(vreq, editConfiguration); + addRedirectUrl(vreq, editConfiguration); }else { editConfiguration.setTemplate(propertyTemplate); } return editConfiguration; } - private void addDeleteParams(VitroRequest vreq, EditConfigurationVTwo editConfiguration) { + private void addRedirectUrl(VitroRequest vreq, EditConfigurationVTwo editConfiguration) { String redirectUrl = vreq.getParameter("redirectUrl"); if (redirectUrl != null) { editConfiguration.addFormSpecificData("redirectUrl", redirectUrl); } - String individualName = vreq.getParameter("individualName"); - if (redirectUrl != null) { - editConfiguration.addFormSpecificData("individualName", individualName); - } - String individualType = vreq.getParameter("individualType"); - if (redirectUrl != null) { - editConfiguration.addFormSpecificData("individualType", individualType); - } } private EditConfigurationVTwo setupEditConfiguration(VitroRequest vreq, HttpSession session) { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java index 20b894878..960f64add 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java @@ -11,7 +11,6 @@ import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.jena.ontology.OntModel; @@ -68,20 +67,10 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { //TODO: Create this generator final String RDFS_LABEL_FORM = "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.RDFSLabelGenerator"; final String DEFAULT_DELETE_FORM = "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.DefaultDeleteGenerator"; - final String MANAGE_MENUS_FORM = "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.ManagePageGenerator"; - - @Override - protected AuthorizationRequest requiredActions(VitroRequest vreq) { - // If request is for new individual, return simple do back end editing action permission - if (StringUtils.isNotEmpty(EditConfigurationUtils.getTypeOfNew(vreq))) { - return SimplePermission.DO_BACK_END_EDITING.ACTION; - } else if(MANAGE_MENUS_FORM.equals(vreq.getParameter("editForm"))) { - return SimplePermission.MANAGE_MENUS.ACTION; - } - if (isIndividualDeletion(vreq)) { - return SimplePermission.DO_BACK_END_EDITING.ACTION; - } - // Check if this statement can be edited here and return unauthorized if not + + @Override + protected AuthorizationRequest requiredActions(VitroRequest vreq) { + //Check if this statement can be edited here and return unauthorized if not String subjectUri = EditConfigurationUtils.getSubjectUri(vreq); String predicateUri = EditConfigurationUtils.getPredicateUri(vreq); String objectUri = EditConfigurationUtils.getObjectUri(vreq); @@ -109,16 +98,6 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { return isAuthorized? SimplePermission.DO_FRONT_END_EDITING.ACTION: AuthorizationRequest.UNAUTHORIZED; } - private boolean isIndividualDeletion(VitroRequest vreq) { - String subjectUri = EditConfigurationUtils.getSubjectUri(vreq); - String predicateUri = EditConfigurationUtils.getPredicateUri(vreq); - String objectUri = EditConfigurationUtils.getObjectUri(vreq); - if (objectUri != null && subjectUri == null && predicateUri == null && isDeleteForm(vreq)) { - return true; - } - return false; - } - @Override protected ResponseValues processRequest(VitroRequest vreq) { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/search/controller/CustomSearchController.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/search/controller/CustomSearchController.java index f58418f86..0575746ec 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/search/controller/CustomSearchController.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/search/controller/CustomSearchController.java @@ -5,14 +5,15 @@ package edu.cornell.mannlib.vitro.webapp.search.controller; import java.io.IOException; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Base64; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; @@ -40,6 +41,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.jena.QueryUtils; import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; import edu.cornell.mannlib.vitro.webapp.i18n.I18n; import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine; @@ -54,6 +56,9 @@ import edu.cornell.mannlib.vitro.webapp.web.templatemodels.LinkTemplateModel; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.searchresult.IndividualSearchResult; import edu.ucsf.vitro.opensocial.OpenSocialManager; +import org.apache.jena.query.QuerySolution; +import org.apache.jena.query.ResultSet; +import org.apache.jena.rdf.model.Literal; /** * Paged search controller that uses the search engine */ @@ -75,6 +80,18 @@ public class CustomSearchController extends FreemarkerHttpServlet { private static final String PARAM_RDFTYPE = "type"; private static final String PARAM_QUERY_TEXT = "querytext"; + private static String FILTERS_QUERY = "" + + "PREFIX rdf: " + + "PREFIX rdfs: " + + "PREFIX search: " + + "SELECT ?filterID ?fieldField ?filterLabel" + + "WHERE" + + "{ ?filterStatement rdf:type search:filter ." + + " ?filterStatement search:field ?fieldField ." + + " ?filterStatement search:id ?filterID ." + + " ?filterStatement rdfs:label ?filterLabel ." + + "} ORDER BY ?fileterLabel"; + protected static final Map> templateTable; protected enum Format { @@ -127,39 +144,6 @@ public class CustomSearchController extends FreemarkerHttpServlet { } } } - - @Override - public void doPost(HttpServletRequest request, HttpServletResponse response) - throws IOException, ServletException { - VitroRequest vreq = new VitroRequest(request); - boolean wasXmlRequested = isRequestedFormatXml(vreq); - boolean wasCSVRequested = isRequestedFormatCSV(vreq); - if( !wasXmlRequested && !wasCSVRequested){ - super.doGet(vreq,response); - }else if (wasXmlRequested){ - try { - ResponseValues rvalues = processRequest(vreq); - - response.setCharacterEncoding("UTF-8"); - response.setContentType("text/xml;charset=UTF-8"); - response.setHeader("Content-Disposition", "attachment; filename=search.xml"); - writeTemplate(rvalues.getTemplateName(), rvalues.getMap(), request, response); - } catch (Exception e) { - log.error(e, e); - } - }else if (wasCSVRequested){ - try { - ResponseValues rvalues = processRequest(vreq); - - response.setCharacterEncoding("UTF-8"); - response.setContentType("text/csv;charset=UTF-8"); - response.setHeader("Content-Disposition", "attachment; filename=search.csv"); - writeTemplate(rvalues.getTemplateName(), rvalues.getMap(), request, response); - } catch (Exception e) { - log.error(e, e); - } - } - } @Override protected ResponseValues processRequest(VitroRequest vreq) { @@ -190,8 +174,6 @@ public class CustomSearchController extends FreemarkerHttpServlet { int startIndex = getStartIndex(vreq); int hitsPerPage = getHitsPerPage( vreq ); - String queryBuilderRules = getQueryBuilderRules(vreq); - String queryText = vreq.getParameter(PARAM_QUERY_TEXT); log.debug("Query text is \""+ queryText + "\""); @@ -235,6 +217,10 @@ public class CustomSearchController extends FreemarkerHttpServlet { for (SearchResultDocument doc : docs) { try { String uri = doc.getStringValue(VitroSearchTermNames.URI); + /* + * if(possibleExcerpts.contains(uri)) { log.info("FOUND AVAILIBLE URI " + uri); + * } + */ Individual ind = iDao.getIndividualByURI(uri); if (ind != null) { ind.setSearchSnippet(getSnippet(doc, response)); @@ -317,11 +303,7 @@ public class CustomSearchController extends FreemarkerHttpServlet { body.put("nextPage", getNextPageLink(startIndex, hitsPerPage, vreq.getServletPath(), pagingLinkParams)); } - if (queryBuilderRules != null) { - body.put("queryBuilderRules", queryBuilderRules); - } - body.put(PARAM_HITS_PER_PAGE, hitsPerPage); - + // VIVO OpenSocial Extension by UCSF try { OpenSocialManager openSocialManager = new OpenSocialManager(vreq, "search"); @@ -354,16 +336,26 @@ public class CustomSearchController extends FreemarkerHttpServlet { } } - private String getQueryBuilderRules(VitroRequest vreq) { - String rules = null; + private Set getExistingExcerpts( VitroRequest vreq) { + Set labels = new HashSet(); try { - rules = vreq.getParameter("queryBuilderRules"); - } catch (Throwable e) { - log.error(e); + //We want to get the labels for all the languages, not just the display language + ResultSet results = QueryUtils.getLanguageNeutralQueryResults(FILTERS_QUERY, vreq); + while (results.hasNext()) { + QuerySolution solution = results.nextSolution(); + String nodeLiteral = solution.get("individualUri").toString(); + log.debug(nodeLiteral.toString()); + labels.add(nodeLiteral); + } + } catch (Exception e) { + log.error(e, e); } - return rules; - } + return labels; +} + + + private int getHitsPerPage(VitroRequest vreq) { int hitsPerPage = DEFAULT_HITS_PER_PAGE; try{ diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/BaseIndividualTemplateModel.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/BaseIndividualTemplateModel.java index efaa8396f..a4d3509a6 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/BaseIndividualTemplateModel.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/BaseIndividualTemplateModel.java @@ -157,12 +157,13 @@ public abstract class BaseIndividualTemplateModel extends BaseTemplateModel { ParamMap params = new ParamMap( "objectUri", individual.getURI(), "cmd", "delete", - "individualName",getNameStatement().getValue() + "statement_label",getNameStatement().getValue(), + "statement_object",individual.getURI() ); Iterator typesIterator = types.iterator(); if (types.iterator().hasNext()) { String type = typesIterator.next(); - params.put("individualType", type); + params.put("statement_type", type); } return UrlBuilder.getUrl(EDIT_PATH, params); diff --git a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraphTest.java b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraphTest.java deleted file mode 100644 index e5c8a65fa..000000000 --- a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraphTest.java +++ /dev/null @@ -1,62 +0,0 @@ -package edu.cornell.mannlib.vitro.webapp.dao.jena; - -import static org.junit.Assert.assertEquals; - -import org.apache.jena.rdf.model.Model; -import org.apache.jena.rdf.model.ModelFactory; -import org.junit.Test; - -import edu.cornell.mannlib.vitro.testing.AbstractTestClass; -import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener; -import edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model.RDFServiceModel; - - -public class RDFServiceGraphTest extends AbstractTestClass { - - @Test - /** - * Test that creating a new model with the same underlying RDFServiceGraph - * does not result in a new listener registered on that graph. No matter - * how many models have been created using a given RDFServiceGraph, an event - * sent to the last-created model should be heard only once by the - * RDFService. - * @throws RDFServiceException - */ - public void testEventListening() throws RDFServiceException { - Model m = ModelFactory.createDefaultModel(); - RDFService rdfService = new RDFServiceModel(m); - EventsCounter counter = new EventsCounter(); - rdfService.registerListener(counter); - RDFServiceGraph g = new RDFServiceGraph(rdfService); - Model model = null; - for (int i = 0; i < 100; i++) { - model = RDFServiceGraph.createRDFServiceModel(g); - } - model.notifyEvent("event"); - assertEquals(1, counter.getCount()); - } - - private class EventsCounter implements ChangeListener { - - private int count = 0; - - public int getCount() { - return count; - } - - @Override - public void notifyModelChange(ModelChange modelChange) { - // TODO Auto-generated method stub - } - - @Override - public void notifyEvent(String graphURI, Object event) { - count++; - } - - } - -} diff --git a/webapp/src/main/webapp/WEB-INF/resources/shortview_config.n3 b/webapp/src/main/webapp/WEB-INF/resources/shortview_config.n3 index 0d969074f..fa9bd654e 100644 --- a/webapp/src/main/webapp/WEB-INF/resources/shortview_config.n3 +++ b/webapp/src/main/webapp/WEB-INF/resources/shortview_config.n3 @@ -11,3 +11,31 @@ # Find out how to use this file at # https://wiki.duraspace.org/display/VIVO/Using+Short+Views+in+Release+1.5 # +@prefix ts_: . +@prefix display: . +@prefix mydomain: . + +ts_:elenphExcerpt display:hasCustomView mydomain:elenphExcerptShortView . + +mydomain:elenphExcerptShortView + a display:customViewForIndividual ; + display:appliesToContext "SEARCH" ; + display:hasTemplate "elenphExcerptShortView.ftl" ; + display:hasDataGetter mydomain:elenphExcerptShortViewDataGetter . + +mydomain:elenphExcerptShortViewDataGetter + a ; + display:saveToVar "excerptInfo"; + display:query + """ + PREFIX rdfs: + PREFIX vivo: + PREFIX rdf: + PREFIX ts_: + SELECT ?property ?value + WHERE { + ?individualUri ?property ?value . + ?individualUri rdf:type ts_:elenphExcerpt . + } + """ . + diff --git a/webapp/src/main/webapp/templates/freemarker/body/accounts/userAccounts-createPassword.ftl b/webapp/src/main/webapp/templates/freemarker/body/accounts/userAccounts-createPassword.ftl index 126a2626f..a3ba4273c 100644 --- a/webapp/src/main/webapp/templates/freemarker/body/accounts/userAccounts-createPassword.ftl +++ b/webapp/src/main/webapp/templates/freemarker/body/accounts/userAccounts-createPassword.ftl @@ -26,7 +26,7 @@
- + diff --git a/webapp/src/main/webapp/templates/freemarker/body/accounts/userAccounts-resetPassword.ftl b/webapp/src/main/webapp/templates/freemarker/body/accounts/userAccounts-resetPassword.ftl index 645908854..cf11f0a72 100644 --- a/webapp/src/main/webapp/templates/freemarker/body/accounts/userAccounts-resetPassword.ftl +++ b/webapp/src/main/webapp/templates/freemarker/body/accounts/userAccounts-resetPassword.ftl @@ -26,7 +26,7 @@
- + diff --git a/webapp/src/main/webapp/templates/freemarker/body/partials/menupage/menupage-browse.ftl b/webapp/src/main/webapp/templates/freemarker/body/partials/menupage/menupage-browse.ftl index bf9882b19..5f94bcdb3 100644 --- a/webapp/src/main/webapp/templates/freemarker/body/partials/menupage/menupage-browse.ftl +++ b/webapp/src/main/webapp/templates/freemarker/body/partials/menupage/menupage-browse.ftl @@ -26,7 +26,7 @@