Adding email password method to PolicyHelper. Adding getClientAddr to VitroRequest

This commit is contained in:
Brian Caruso 2013-08-20 11:40:23 -04:00
parent e6a7ad34d3
commit 34af3c202a
5 changed files with 73 additions and 32 deletions

View file

@ -17,8 +17,10 @@ import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.rdf.model.StmtIterator;
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.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers; import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; 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.auth.requestedAction.ifaces.RequestedAction; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
@ -26,6 +28,9 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPro
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropDataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.BasicAuthenticator;
/** /**
* A collection of static methods to help determine whether requested actions * A collection of static methods to help determine whether requested actions
@ -53,7 +58,7 @@ public class PolicyHelper {
IdentifierBundle ids = RequestIdentifiers.getIdBundleForRequest(req); IdentifierBundle ids = RequestIdentifiers.getIdBundleForRequest(req);
return isAuthorizedForActions(ids, policy, actions); return isAuthorizedForActions(ids, policy, actions);
} }
/** /**
* Are these actions authorized for these identifiers by these policies? * Are these actions authorized for these identifiers by these policies?
*/ */
@ -62,6 +67,48 @@ public class PolicyHelper {
return Actions.notNull(actions).isAuthorized(policy, ids); return Actions.notNull(actions).isAuthorized(policy, ids);
} }
/**
* Is the email/password authorized for these actions?
* This should be used when a controller or something needs allow
* actions if the user passes in their email and password.
*
* It may be better to check this as part of a servlet Filter and
* add an identifier bundle.
*/
public static boolean isAuthorizedForActions( HttpServletRequest req,
String email, String password,
Actions actions){
if( password == null || email == null ||
password.isEmpty() || email.isEmpty()){
return false;
}
try{
Authenticator basicAuth = new BasicAuthenticator(req);
UserAccount user = basicAuth.getAccountForInternalAuth( email );
log.debug("userAccount is " + user==null?"null":user.getUri() );
if( ! basicAuth.isCurrentPassword( user, password ) ){
log.debug(String.format("UNAUTHORIZED, password not accepted for %s, account URI: %s",
user.getEmailAddress(), user.getUri()));
return false;
}else{
log.debug(String.format("password accepted for %s, account URI: %s",
user.getEmailAddress(), user.getUri() ));
// figure out if that account can do the actions
IdentifierBundle ids =
ActiveIdentifierBundleFactories.getUserIdentifierBundle(req,user);
PolicyIface policy = ServletPolicyList.getPolicies(req);
return PolicyHelper.isAuthorizedForActions( ids, policy, actions );
}
}catch(Exception ex){
log.error("Error while attempting to authorize actions " + actions.toString(), ex);
return false;
}
}
/** /**
* Do the current policies authorize the current user to add this statement * Do the current policies authorize the current user to add this statement
* to this model? * to this model?
@ -260,6 +307,7 @@ public class PolicyHelper {
+ stmt.getObject() + ">"; + stmt.getObject() + ">";
} }
/** /**
* No need to instantiate this helper class - all methods are static. * No need to instantiate this helper class - all methods are static.
*/ */

View file

@ -171,6 +171,18 @@ public class VitroRequest extends HttpServletRequestWrapper {
return getWebappDaoFactory().getApplicationDao().getApplicationBean(); return getWebappDaoFactory().getApplicationDao().getApplicationBean();
} }
/**
* Gets the the ip of the client.
* This will be X-forwarded-for header or, if that header is not
* set, getRemoteAddr(). This still may not be the client's address
* as they may be using a proxy.
*
*/
public String getClientAddr(){
String xff = getHeader("x-forwarded-for");
return ( xff == null || xff.trim().isEmpty() ) ? getRemoteAddr() : xff;
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public Map<String, String[]> getParameterMap() { public Map<String, String[]> getParameterMap() {

View file

@ -2,7 +2,7 @@
package edu.cornell.mannlib.vitro.webapp.controller.freemarker; package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import static javax.mail.Message.RecipientType.TO; import static javax.mail.Message.RecipientType.*;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
@ -23,6 +23,7 @@ import org.apache.commons.logging.LogFactory;
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.PolicyHelper;
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.ifaces.RequiresActions;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage; import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet; import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
@ -48,7 +49,7 @@ import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException; import freemarker.template.TemplateModelException;
import freemarker.template.utility.DeepUnwrap; import freemarker.template.utility.DeepUnwrap;
public class FreemarkerHttpServlet extends VitroHttpServlet { public class FreemarkerHttpServlet extends VitroHttpServlet {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(FreemarkerHttpServlet.class); private static final Log log = LogFactory.getLog(FreemarkerHttpServlet.class);
@ -203,7 +204,8 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
* NB This method can't be static, because then the superclass method gets called rather than * NB This method can't be static, because then the superclass method gets called rather than
* the subclass method. For the same reason, it can't refer to a static or instance field * the subclass method. For the same reason, it can't refer to a static or instance field
* REQUIRED_ACTIONS which is overridden in the subclass. * REQUIRED_ACTIONS which is overridden in the subclass.
*/ *
*/
protected Actions requiredActions(VitroRequest vreq) { protected Actions requiredActions(VitroRequest vreq) {
return Actions.AUTHORIZED; return Actions.AUTHORIZED;
} }

View file

@ -43,7 +43,7 @@ public class SearchServiceController extends FreemarkerHttpServlet {
* userAccount associated with the email. * userAccount associated with the email.
*/ */
@Override @Override
protected Actions requiredActions(VitroRequest vreq) { public Actions requiredActions(VitroRequest vreq) {
try{ try{
// Works by side effect: parse the multi-part request and stash FileItems in request // Works by side effect: parse the multi-part request and stash FileItems in request
FileUploadServletRequest.parseRequest(vreq, 0); FileUploadServletRequest.parseRequest(vreq, 0);
@ -52,42 +52,21 @@ public class SearchServiceController extends FreemarkerHttpServlet {
String pw = vreq.getParameter("password"); String pw = vreq.getParameter("password");
String email = vreq.getParameter("email"); String email = vreq.getParameter("email");
log.debug(String.format("email: '%s' password: '%s' ",email,pw));
if( pw == null || email == null || pw.isEmpty() || email.isEmpty()){ if( pw == null || email == null || pw.isEmpty() || email.isEmpty()){
return SimplePermission.MANAGE_SEARCH_INDEX.ACTIONS; return SimplePermission.MANAGE_SEARCH_INDEX.ACTIONS;
} }
Authenticator basicAuth = new BasicAuthenticator(vreq); if( PolicyHelper.isAuthorizedForActions(vreq, email, pw,
UserAccount user = basicAuth.getAccountForInternalAuth( email ); SimplePermission.MANAGE_SEARCH_INDEX.ACTIONS ) ){
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; return Actions.AUTHORIZED;
}else{ }else{
log.debug(String.format("userAccount is unauthorized to" + log.debug(email + " is unauthorized to manage the search index. " +
" manage the search index.",user.getUri())); "client IP "+vreq.getClientAddr());
return Actions.UNAUTHORIZED; return Actions.UNAUTHORIZED;
} }
}catch(Exception ex){ }catch(Exception ex){
log.error("Error while attempting to log in " + log.error("Error while client IP "+ vreq.getClientAddr() + " attempting to log in " +
"to SearchServiceController: " + ex.getMessage()); "to SearchServiceController: " + ex.getMessage());
return Actions.UNAUTHORIZED; return Actions.UNAUTHORIZED;
} }

View file

@ -21,7 +21,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset;
/** /**
* Test to experement with Jena ARQ SPARQL update and the RDFServiceDataset. * Test to experiment with Jena ARQ SPARQL update and the RDFServiceDataset.
*/ */
public class SparqlUpdateTestDataGetter implements DataGetter{ public class SparqlUpdateTestDataGetter implements DataGetter{
private static final Log log = LogFactory.getLog(SparqlUpdateTestDataGetter.class); private static final Log log = LogFactory.getLog(SparqlUpdateTestDataGetter.class);