From fb46e64725b1a86b93f4cc52232b04801d62eb11 Mon Sep 17 00:00:00 2001
From: Brian Caruso
Date: Tue, 16 Jul 2013 12:28:24 -0400
Subject: [PATCH] Adding login via email/password parameters
---
.../controller/SearchServiceController.java | 67 ++++++++++++++++++-
.../search/controller/UpdateUrisInIndex.java | 58 ++++++++++------
.../body/search/searchService-help.ftl | 40 ++++++++---
3 files changed, 134 insertions(+), 31 deletions(-)
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/SearchServiceController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/SearchServiceController.java
index 22116f3e6..61c23afc2 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/SearchServiceController.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/SearchServiceController.java
@@ -10,9 +10,17 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import edu.cornell.mannlib.vitro.webapp.auth.identifier.ActiveIdentifierBundleFactories;
+import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
+import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
+import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList;
+import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
+import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
+import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
+import edu.cornell.mannlib.vitro.webapp.controller.authenticate.BasicAuthenticator;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ExceptionResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
@@ -27,11 +35,64 @@ import edu.cornell.mannlib.vitro.webapp.search.indexing.IndexBuilder;
public class SearchServiceController extends FreemarkerHttpServlet {
private static final Log log = LogFactory.getLog(SearchServiceController.class);
+ /**
+ * Attempt to check if there is a email and password in the request parameters.
+ * If there is not, fall back on the normal usage pattern of requestedAction().
+ * If there is, then try to authenticate and authorize the
+ * userAccount associated with the email.
+ */
@Override
protected Actions requiredActions(VitroRequest vreq) {
- return SimplePermission.MANAGE_SEARCH_INDEX.ACTIONS;
+ try{
+ // Works by side effect: parse the multi-part request and stash FileItems in request
+ new MultipartHttpServletRequest( vreq );
+
+ //first figure out if the password and email login to an account with a password
+ String pw = vreq.getParameter("password");
+ String email = vreq.getParameter("email");
+
+ log.debug(String.format("email: '%s' password: '%s' ",email,pw));
+
+ if( pw == null || email == null || pw.isEmpty() || email.isEmpty()){
+ return SimplePermission.MANAGE_SEARCH_INDEX.ACTIONS;
+ }
+
+ Authenticator basicAuth = new BasicAuthenticator(vreq);
+ UserAccount user = basicAuth.getAccountForInternalAuth( email );
+ log.debug("userAccount is " + user==null?"null":user.getUri() );
+
+ if( ! basicAuth.isCurrentPassword( user, pw ) ){
+ log.debug(String.format("UNAUTHORIZED, password not accepted for %s, account URI: %s",
+ user.getEmailAddress(), user.getUri()));
+ return Actions.UNAUTHORIZED;
+ }else{
+ log.debug(String.format("password accepted for %s, account URI: %s",
+ user.getEmailAddress(), user.getUri() ));
+ }
+
+ //then figure out if that account can manage the search index.
+ IdentifierBundle ids =
+ ActiveIdentifierBundleFactories.getUserIdentifierBundle(vreq,user);
+ PolicyIface policy = ServletPolicyList.getPolicies(vreq);
+ boolean canManageSearchIndex =
+ PolicyHelper.isAuthorizedForActions( ids, policy,
+ SimplePermission.MANAGE_SEARCH_INDEX.ACTIONS );
+ if( canManageSearchIndex ){
+ return Actions.AUTHORIZED;
+ }else{
+ log.debug(String.format("userAccount is unauthorized to" +
+ " manage the search index.",user.getUri()));
+ return Actions.UNAUTHORIZED;
+ }
+
+ }catch(Exception ex){
+ log.error("Error while attempting to log in " +
+ "to SearchServiceController: " + ex.getMessage());
+ return Actions.UNAUTHORIZED;
+ }
}
+
/**
* Handle the different actions. If not specified, the default action is to
* show the help page.
@@ -39,8 +100,6 @@ public class SearchServiceController extends FreemarkerHttpServlet {
@Override
protected ResponseValues processRequest(VitroRequest req) {
try {
- // Works by side effect: parse the multi-part request and stash FileItems in request
- new MultipartHttpServletRequest( req );
//figure out what action to perform
String pathInfo = req.getPathInfo();
@@ -62,6 +121,8 @@ public class SearchServiceController extends FreemarkerHttpServlet {
}
+ /**
+ * Process requests to the web service to update a list of URIs in the search index. */
public ResponseValues doUpdateUrisInSearch(HttpServletRequest req )
throws IOException, ServletException {
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/UpdateUrisInIndex.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/UpdateUrisInIndex.java
index 9f8689021..94998759d 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/UpdateUrisInIndex.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/UpdateUrisInIndex.java
@@ -41,33 +41,39 @@ public class UpdateUrisInIndex {
protected void doUpdateUris(HttpServletRequest req, IndexBuilder builder)
throws ServletException, IOException{
-
- boolean isMultipart = ServletFileUpload.isMultipartContent(req);
- if( ! isMultipart )
+ if( ! ServletFileUpload.isMultipartContent(req) )
throw new ServletException("Expected Multipart Content");
-
- String charEncoding = getEncoding(req);
+ String enc = getEncoding(req);
try{
- int count = 0;
+ //loop over the fileds and add any URIs to the IndexBuilder queue
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iter = upload.getItemIterator(req);
while( iter.hasNext()){
FileItemStream item = iter.next();
String name = item.getFieldName();
+ if( "email".equals(name) || "password".equals(name) )
+ continue; //skip the password and email fields
+
InputStream stream = item.openStream();
try{
- count = count + addToSearchQueue(builder, new InputStreamReader(stream, charEncoding));
+ addToSearchQueue(builder, stream, enc);
}finally{
stream.close();
- builder.doUpdateIndex();
}
}
}catch (FileUploadException fex){
throw new ServletException("Could not upload file to SearchServiceController", fex);
+ }finally{
+ builder.doUpdateIndex();
}
}
+ /**
+ * Get the encoding of the request, default to UTF-8
+ * since that is in the vitro install instructions
+ * to put on the connector.
+ */
private String getEncoding(HttpServletRequest req){
String enc = req.getCharacterEncoding();
if( enc == null || enc.isEmpty() ){
@@ -83,22 +89,26 @@ public class UpdateUrisInIndex {
return enc;
}
- private int addToSearchQueue( IndexBuilder builder, Reader in )
+ /**
+ * Adds URIs from Reader to search queue.
+ */
+ private void addToSearchQueue( IndexBuilder builder, InputStream stream , String charEncoding )
throws IOException{
- int addedUriCount = 0;
- Iterator uris = new UrisFromInputIterator( in );
+ Iterator uris =
+ new UrisFromInputIterator( new InputStreamReader(stream, charEncoding) );
+
while(uris.hasNext()){
String uri = uris.next();
log.debug("Request to index uri '" + uri + "'");
builder.addToChanged( uri );
- addedUriCount++;
}
-
- return addedUriCount;
}
+ /**
+ * Iterator for URIs in a reader to make top level methods simpler.
+ */
public static class UrisFromInputIterator implements Iterator {
BufferedReader reader;
Iterator uris;
@@ -148,11 +158,16 @@ public class UpdateUrisInIndex {
return false;
}
}
-
-
-
- private static List removeNullAndEmpty(List in ){
+
+ /**
+ * Removes null and empty elements from in.
+ * Returned list will not be null.
+ */
+ private static List removeNullAndEmpty(List in ){
ArrayList out = new ArrayList();
+ if( in == null )
+ return out;
+
for( String s : in ){
if( s != null && !s.trim().isEmpty() ){
out.add(s);
@@ -161,12 +176,17 @@ public class UpdateUrisInIndex {
return out;
}
+ /**
+ * Parses a line to a list of URIs.
+ * Retruned list will not be null.
+ * No elements in returned list will be empty or null.
+ */
protected static List lineToUris(String line){
List parts = removeNullAndEmpty( Arrays.asList(commaAndWhitespace.split( line ) ));
return parts;
}
- //split uris on whitespace and commas
+ /** Pattern to split URIs on whitespace and commas. */
private static final Pattern commaAndWhitespace = Pattern.compile("[,\\s]");
}
diff --git a/webapp/web/templates/freemarker/body/search/searchService-help.ftl b/webapp/web/templates/freemarker/body/search/searchService-help.ftl
index 6101e000b..d1e61061c 100644
--- a/webapp/web/templates/freemarker/body/search/searchService-help.ftl
+++ b/webapp/web/templates/freemarker/body/search/searchService-help.ftl
@@ -1,18 +1,40 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
-Search Web Service
+Search Web Service
-Add information here about how to use the Search Web Service.
+<#if msg?has_content >
+ Message:
+ ${msg}
+#if>
-*** FOLLOWING FORM IS TOTALLY MESSED UP WITH A HARDCODED URL ***
+Update Search Index for URIs
-
+
+The request parameters email and password allow the form to be submitted
+for a user account. Only internal accounts are supported, external authentication
+is not supported.
+
+Example form for Update Search Index for URIs
+The following form will post to the Update URIs in search service.
+
+
-
+
\ No newline at end of file