package com.github.windbender.auth; import java.lang.reflect.Type; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.github.windbender.core.SessionFilteredAuthorization; import com.github.windbender.domain.Project; import com.github.windbender.domain.User; import com.github.windbender.domain.UserProject; import com.sun.jersey.api.core.HttpContext; import com.sun.jersey.core.spi.component.ComponentContext; import com.sun.jersey.core.spi.component.ComponentScope; import com.sun.jersey.server.impl.inject.AbstractHttpContextInjectable; import com.sun.jersey.spi.inject.Injectable; import com.sun.jersey.spi.inject.InjectableProvider; public class SessionAuthProvider implements InjectableProvider<SessionAuth, Type> { private static class SessionPrivInjectable extends AbstractHttpContextInjectable<SessionFilteredAuthorization> { Logger log = LoggerFactory.getLogger(SessionAuthProvider.class); private Priv[] required; HttpServletRequest request; private SessionPrivInjectable(HttpServletRequest request, Priv[] required2) { this.required = required2; this.request = request; } @Override public SessionFilteredAuthorization getValue(HttpContext c) { Project curProject = (Project) request.getSession().getAttribute("current_project"); User user = (User) request.getSession().getAttribute("user"); if(curProject == null) { throw new WebApplicationException(Response.Status.UNAUTHORIZED); } if(user == null) { throw new WebApplicationException(Response.Status.UNAUTHORIZED); } if(curProject.getPrimaryAdmin().equals(user)) { // this means the user is the primary admin, so don't test the rest of stuff } else { //find the current projects user_project record @SuppressWarnings("unchecked") List<UserProject> upls = (List<UserProject>) request.getSession().getAttribute("user_projects"); UserProject curUP = null; if ((curProject != null) && (upls != null)) { for (UserProject up : upls) { if (up.getProject().getId().equals(curProject.getId())) { curUP = up; } } } Set<Priv> requiredSetOR= new HashSet<Priv>(Arrays.asList(required)); // the user must have at least ONE of the required roles listed here. boolean foundEnoughPriv = false; for(Priv reqRole: requiredSetOR) { if(curProject != null) { if(reqRole.equals(Priv.CATEGORIZE) && curProject.getPublicCategorize()) foundEnoughPriv = true; if(reqRole.equals(Priv.REPORT) && curProject.getPublicReport()) foundEnoughPriv = true; } if(curUP != null) { if(reqRole.equals(Priv.CATEGORIZE) && curUP.getCanCategorize()) foundEnoughPriv = true; if(reqRole.equals(Priv.REPORT) && curUP.getCanReport()) foundEnoughPriv = true; if(reqRole.equals(Priv.UPLOAD) && curUP.getCanUpload()) foundEnoughPriv = true; if(reqRole.equals(Priv.ADMIN) && curUP.getCanAdmin()) foundEnoughPriv = true; } } if(!foundEnoughPriv) { log.info("not enough privs for "+user.getUsername()+" against "+curProject); throw new WebApplicationException(Response.Status.FORBIDDEN); } } SessionFilteredAuthorization out = new SessionFilteredAuthorization(); out.setProject(curProject); out.setProjectId(curProject.getId()); return out; } } private final HttpServletRequest request; private Priv[] required; public SessionAuthProvider(@Context HttpServletRequest request) { this.request = request; } @Override public Injectable<SessionFilteredAuthorization> getInjectable(ComponentContext cc, SessionAuth a, Type c) { required = a.required(); if (c.equals(SessionFilteredAuthorization.class)) { return new SessionPrivInjectable(request,required); } return null; } @Override public ComponentScope getScope() { return ComponentScope.PerRequest; } }