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}

+ -

*** FOLLOWING FORM IS TOTALLY MESSED UP WITH A HARDCODED URL ***

+

Update Search Index for URIs

-
This service will update the search index for the list of URIs it +receives. It expectes a POST with an encoding of +multpart/form-data. The service inspect all parts of this POST for +lists of URIs to reindex. The URIs should be comma or space +seperated. If no information can be found for a URI it will be +ignored.

+ +

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