Adding login via email/password parameters
This commit is contained in:
parent
7905b80df4
commit
fb46e64725
3 changed files with 134 additions and 31 deletions
|
@ -10,9 +10,17 @@ 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.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.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.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.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.FreemarkerHttpServlet;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ExceptionResponseValues;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ExceptionResponseValues;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||||
|
@ -27,11 +35,64 @@ import edu.cornell.mannlib.vitro.webapp.search.indexing.IndexBuilder;
|
||||||
public class SearchServiceController extends FreemarkerHttpServlet {
|
public class SearchServiceController extends FreemarkerHttpServlet {
|
||||||
private static final Log log = LogFactory.getLog(SearchServiceController.class);
|
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
|
@Override
|
||||||
protected Actions requiredActions(VitroRequest vreq) {
|
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
|
* Handle the different actions. If not specified, the default action is to
|
||||||
* show the help page.
|
* show the help page.
|
||||||
|
@ -39,8 +100,6 @@ public class SearchServiceController extends FreemarkerHttpServlet {
|
||||||
@Override
|
@Override
|
||||||
protected ResponseValues processRequest(VitroRequest req) {
|
protected ResponseValues processRequest(VitroRequest req) {
|
||||||
try {
|
try {
|
||||||
// Works by side effect: parse the multi-part request and stash FileItems in request
|
|
||||||
new MultipartHttpServletRequest( req );
|
|
||||||
|
|
||||||
//figure out what action to perform
|
//figure out what action to perform
|
||||||
String pathInfo = req.getPathInfo();
|
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 )
|
public ResponseValues doUpdateUrisInSearch(HttpServletRequest req )
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
|
|
||||||
|
|
|
@ -41,33 +41,39 @@ public class UpdateUrisInIndex {
|
||||||
protected void doUpdateUris(HttpServletRequest req, IndexBuilder builder)
|
protected void doUpdateUris(HttpServletRequest req, IndexBuilder builder)
|
||||||
throws ServletException, IOException{
|
throws ServletException, IOException{
|
||||||
|
|
||||||
|
if( ! ServletFileUpload.isMultipartContent(req) )
|
||||||
boolean isMultipart = ServletFileUpload.isMultipartContent(req);
|
|
||||||
if( ! isMultipart )
|
|
||||||
throw new ServletException("Expected Multipart Content");
|
throw new ServletException("Expected Multipart Content");
|
||||||
|
|
||||||
|
String enc = getEncoding(req);
|
||||||
String charEncoding = getEncoding(req);
|
|
||||||
try{
|
try{
|
||||||
int count = 0;
|
//loop over the fileds and add any URIs to the IndexBuilder queue
|
||||||
ServletFileUpload upload = new ServletFileUpload();
|
ServletFileUpload upload = new ServletFileUpload();
|
||||||
FileItemIterator iter = upload.getItemIterator(req);
|
FileItemIterator iter = upload.getItemIterator(req);
|
||||||
while( iter.hasNext()){
|
while( iter.hasNext()){
|
||||||
FileItemStream item = iter.next();
|
FileItemStream item = iter.next();
|
||||||
String name = item.getFieldName();
|
String name = item.getFieldName();
|
||||||
|
if( "email".equals(name) || "password".equals(name) )
|
||||||
|
continue; //skip the password and email fields
|
||||||
|
|
||||||
InputStream stream = item.openStream();
|
InputStream stream = item.openStream();
|
||||||
try{
|
try{
|
||||||
count = count + addToSearchQueue(builder, new InputStreamReader(stream, charEncoding));
|
addToSearchQueue(builder, stream, enc);
|
||||||
}finally{
|
}finally{
|
||||||
stream.close();
|
stream.close();
|
||||||
builder.doUpdateIndex();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch (FileUploadException fex){
|
}catch (FileUploadException fex){
|
||||||
throw new ServletException("Could not upload file to SearchServiceController", 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){
|
private String getEncoding(HttpServletRequest req){
|
||||||
String enc = req.getCharacterEncoding();
|
String enc = req.getCharacterEncoding();
|
||||||
if( enc == null || enc.isEmpty() ){
|
if( enc == null || enc.isEmpty() ){
|
||||||
|
@ -83,22 +89,26 @@ public class UpdateUrisInIndex {
|
||||||
return enc;
|
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{
|
throws IOException{
|
||||||
int addedUriCount = 0;
|
|
||||||
|
|
||||||
Iterator<String> uris = new UrisFromInputIterator( in );
|
Iterator<String> uris =
|
||||||
|
new UrisFromInputIterator( new InputStreamReader(stream, charEncoding) );
|
||||||
|
|
||||||
while(uris.hasNext()){
|
while(uris.hasNext()){
|
||||||
String uri = uris.next();
|
String uri = uris.next();
|
||||||
log.debug("Request to index uri '" + uri + "'");
|
log.debug("Request to index uri '" + uri + "'");
|
||||||
builder.addToChanged( 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<String> {
|
public static class UrisFromInputIterator implements Iterator<String> {
|
||||||
BufferedReader reader;
|
BufferedReader reader;
|
||||||
Iterator<String> uris;
|
Iterator<String> uris;
|
||||||
|
@ -148,11 +158,16 @@ public class UpdateUrisInIndex {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes null and empty elements from in.
|
||||||
private static List<String> removeNullAndEmpty(List<String> in ){
|
* Returned list will not be null.
|
||||||
|
*/
|
||||||
|
private static List<String> removeNullAndEmpty(List<String> in ){
|
||||||
ArrayList<String> out = new ArrayList<String>();
|
ArrayList<String> out = new ArrayList<String>();
|
||||||
|
if( in == null )
|
||||||
|
return out;
|
||||||
|
|
||||||
for( String s : in ){
|
for( String s : in ){
|
||||||
if( s != null && !s.trim().isEmpty() ){
|
if( s != null && !s.trim().isEmpty() ){
|
||||||
out.add(s);
|
out.add(s);
|
||||||
|
@ -161,12 +176,17 @@ public class UpdateUrisInIndex {
|
||||||
return out;
|
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<String> lineToUris(String line){
|
protected static List<String> lineToUris(String line){
|
||||||
List<String> parts = removeNullAndEmpty( Arrays.asList(commaAndWhitespace.split( line ) ));
|
List<String> parts = removeNullAndEmpty( Arrays.asList(commaAndWhitespace.split( line ) ));
|
||||||
return parts;
|
return parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
//split uris on whitespace and commas
|
/** Pattern to split URIs on whitespace and commas. */
|
||||||
private static final Pattern commaAndWhitespace = Pattern.compile("[,\\s]");
|
private static final Pattern commaAndWhitespace = Pattern.compile("[,\\s]");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,40 @@
|
||||||
<#-- $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$ -->
|
||||||
|
|
||||||
<h2>Search Web Service</h2>
|
<h1>Search Web Service</h1>
|
||||||
|
|
||||||
<p>Add information here about how to use the Search Web Service.</p>
|
<#if msg?has_content >
|
||||||
|
<h2>Message:</h2>
|
||||||
|
<p>${msg}</p>
|
||||||
|
</#if>
|
||||||
|
|
||||||
<p>*** FOLLOWING FORM IS TOTALLY MESSED UP WITH A HARDCODED URL ***</p>
|
<h2>Update Search Index for URIs</h2>
|
||||||
|
|
||||||
<form
|
<p>This service will update the search index for the list of URIs it
|
||||||
action="http://localhost:8080/vivo/searchService/updateUrisInSearch"
|
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.</p>
|
||||||
|
|
||||||
|
<p>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.</p>
|
||||||
|
|
||||||
|
<h2>Example form for Update Search Index for URIs</h2>
|
||||||
|
<p>The following form will post to the Update URIs in search service.</p>
|
||||||
|
|
||||||
|
<form action="${urls.base}/searchService/updateUrisInSearch"
|
||||||
enctype="multipart/form-data"
|
enctype="multipart/form-data"
|
||||||
method="post">
|
method="post">
|
||||||
|
|
||||||
|
<label for="email">Account email</label>
|
||||||
|
<input type="text" name="email" id="email"/>
|
||||||
|
|
||||||
|
<label for="password">Account password</label>
|
||||||
|
<input type="text" name="password" id="password"/>
|
||||||
|
|
||||||
|
<label for="urisToUpdate">List of URIs to update in the search index</label>
|
||||||
|
<textarea name="urisToUpdate" id="urisToUpdate" rows="4" cols="50" ></textarea>
|
||||||
|
|
||||||
<input type="textarea" name="urisToUpdate"/>
|
|
||||||
<button type="submit">submit</button>
|
<button type="submit">submit</button>
|
||||||
|
</form>
|
||||||
</form>
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue