diff --git a/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/FacilitiesManager.java b/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/FacilitiesManager.java new file mode 100644 index 0000000..8d9ea45 --- /dev/null +++ b/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/FacilitiesManager.java @@ -0,0 +1,62 @@ +package cz.metacentrum.perun.oidc.client; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import javax.activation.UnsupportedDataTypeException; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Facility Manager from Perun system. + * + * @author Jiri Mauritz + */ +public class FacilitiesManager extends Manager { + + private static FacilitiesManager manager; + + private FacilitiesManager() { + } + + public static synchronized FacilitiesManager getInstance() { + if (manager == null) { + manager = new FacilitiesManager(); + } + return manager; + } + + public List getFacilitiesByAttribute(String attributeName, String attributeValue) { + try { + Map params = new HashMap<>(); + params.put("attributeName", attributeName); + params.put("attributeValue", attributeValue); + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(get("getFacilitiesByAttribute", params), new TypeReference>(){}); + } catch (UnsupportedDataTypeException e) { + return null; + } catch (IOException e) { + throw new IllegalStateException("IO Error while calling getFacilitiesByAttribute", e); + } + } + + public List getAssignedResources(int facilityId) { + try { + Map params = new HashMap<>(); + params.put("facility", facilityId); + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(get("getAssignedResources", params), new TypeReference>(){}); + } catch (UnsupportedDataTypeException e) { + return null; + } catch (IOException e) { + throw new IllegalStateException("IO Error while calling getAssignedResources", e); + } + } + + @Override + protected String getManagerName() { + return "facilitiesManager"; + } +} diff --git a/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/Manager.java b/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/Manager.java index 04d7f28..12e4728 100644 --- a/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/Manager.java +++ b/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/Manager.java @@ -5,6 +5,7 @@ import org.apache.commons.codec.binary.Base64; import org.springframework.stereotype.Service; +import javax.activation.UnsupportedDataTypeException; import javax.annotation.Resource; import java.io.*; import java.net.HttpURLConnection; @@ -99,8 +100,8 @@ private String getString(HttpURLConnection c) throws IOException { br.close(); String response = sb.toString(); - throw new IOException("UnsupportedDataTypeException: Fail while reading error response from Perun. Response data: " + response); - } + throw new UnsupportedDataTypeException("Fail while reading error response from Perun. Response data: " + response); + } } finally { if (c != null) { diff --git a/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/PerunFacility.java b/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/PerunFacility.java new file mode 100644 index 0000000..55715e9 --- /dev/null +++ b/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/PerunFacility.java @@ -0,0 +1,68 @@ +package cz.metacentrum.perun.oidc.client; + +/** + * Class represents facility from Perun system. + * + * @author Jiri Mauritz + */ +public class PerunFacility extends PerunBean { + + private int id; + private String name; + private String description; + + public PerunFacility() { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @Override + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + @Override + public String toString() { + StringBuilder str = new StringBuilder(); + + return str.append(getClass().getSimpleName()).append( ":[id='").append(getId()).append("', name='").append(name).append( + "', description='").append(description).append("']").toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + PerunFacility facility = (PerunFacility) o; + + return id == facility.id; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + id; + return result; + } +} + diff --git a/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/PerunResource.java b/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/PerunResource.java new file mode 100644 index 0000000..a714a33 --- /dev/null +++ b/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/PerunResource.java @@ -0,0 +1,111 @@ +package cz.metacentrum.perun.oidc.client; + +/** + * Represents resource from Perun system. + * + * @author Jiri Mauritz + */ +public class PerunResource extends PerunBean { + + private int id; + private int facilityId; + private int voId; + private String name; + private String description; + + /** + * Constructs a new instance. + */ + public PerunResource() { + } + + /** + * Gets the name for this instance. + * + * @return The name. + */ + public String getName() { + return this.name; + } + + /** + * Sets the name for this instance. + * + * @param name The name. + */ + public void setName(String name) { + this.name = name; + } + + /** + * Gets the description for this instance. + * + * @return The description. + */ + public String getDescription() { + return this.description; + } + + /** + * Sets the description for this instance. + * + * @param description The description. + */ + public void setDescription(String description) { + this.description = description; + } + + public int getFacilityId() { + return facilityId; + } + + public void setFacilityId(int facilityId) { + this.facilityId = facilityId; + } + + public int getVoId() { + return voId; + } + + public void setVoId(int voId) { + this.voId = voId; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + @Override + public String toString() { + StringBuilder str = new StringBuilder(); + + return str.append(getClass().getSimpleName()).append(":[id='").append(getId() + ).append("', voId='").append(voId + ).append("', facilityId='").append(facilityId + ).append("', name='").append(name + ).append("', description='").append(description).append("']").toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + PerunResource that = (PerunResource) o; + + return id == that.id; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + id; + return result; + } +} + diff --git a/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/PerunUtils.java b/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/PerunUtils.java index 542a9d1..023db30 100644 --- a/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/PerunUtils.java +++ b/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/PerunUtils.java @@ -237,8 +237,12 @@ else if (extLogin == null && req.getAttribute("SSL_CLIENT_VERIFY") != null && (( } + public static String getClientId(HttpServletRequest req) { + return req.getParameter("client_id"); + } - public static boolean isWrapperType(Class clazz) { + public static boolean isWrapperType(Class clazz) + { Set> ret = new HashSet>(); ret.add(Boolean.class); ret.add(Character.class); diff --git a/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/UsersManager.java b/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/UsersManager.java index bbae521..9034469 100644 --- a/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/UsersManager.java +++ b/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/client/UsersManager.java @@ -1,9 +1,12 @@ package cz.metacentrum.perun.oidc.client; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import javax.activation.UnsupportedDataTypeException; import java.io.IOException; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -11,47 +14,62 @@ */ public class UsersManager extends Manager { - private static UsersManager manager; - - private UsersManager() { - } - - public static synchronized UsersManager getInstance() { - if (manager == null) { - manager = new UsersManager(); - } - return manager; - } - - public PerunUser getUserById(Integer id) { - - try { - Map params = new HashMap<>(); - params.put("id", id); - ObjectMapper mapper = new ObjectMapper(); - return mapper.readValue(get("getUserById", params), PerunUser.class); - } catch (IOException e) { - throw new IllegalStateException("IO Error while getting user from perun", e); - } - - } - - public PerunUser getUserByExtSourceNameAndExtLogin(String extSourceName, String extLogin) { - - try { - Map params = new HashMap<>(); - params.put("extSourceName", extSourceName); - params.put("extLogin", extLogin); - ObjectMapper mapper = new ObjectMapper(); - return mapper.readValue(get("getUserByExtSourceNameAndExtLogin", params), PerunUser.class); - } catch (IOException e) { - throw new IllegalStateException("IO Error while getting user from perun", e); - } - - } - - @Override - protected String getManagerName() { - return "usersManager"; - } + private static UsersManager manager; + + private UsersManager() { + } + + public static synchronized UsersManager getInstance() { + if (manager == null) { + manager = new UsersManager(); + } + return manager; + } + + public PerunUser getUserById(Integer id) { + + try { + Map params = new HashMap<>(); + params.put("id", id); + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(get("getUserById", params), PerunUser.class); + } catch (IOException e) { + throw new IllegalStateException("IO Error while getting user from perun", e); + } + + } + + public PerunUser getUserByExtSourceNameAndExtLogin(String extSourceName, String extLogin) { + + try { + Map params = new HashMap<>(); + params.put("extSourceName", extSourceName); + params.put("extLogin", extLogin); + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(get("getUserByExtSourceNameAndExtLogin", params), PerunUser.class); + } catch (UnsupportedDataTypeException e) { + return null; + } catch (IOException e) { + throw new IllegalStateException("IO Error while getting user from perun", e); + } + + } + + public List getAllowedResourcesIds(int userId) { + try { + Map params = new HashMap<>(); + params.put("user", userId); + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(get("getAllowedResources", params), new TypeReference>(){}); + } catch (UnsupportedDataTypeException e) { + return null; + } catch (IOException e) { + throw new IllegalStateException("IO Error while calling getAllowedResourcesIds", e); + } + } + + @Override + protected String getManagerName() { + return "usersManager"; + } } diff --git a/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/overlay/PerunAuthenticationFilter.java b/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/overlay/PerunAuthenticationFilter.java index abf67e2..a3b83ce 100644 --- a/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/overlay/PerunAuthenticationFilter.java +++ b/perun-oidc-server-overlay/src/main/java/cz/metacentrum/perun/oidc/overlay/PerunAuthenticationFilter.java @@ -1,30 +1,66 @@ package cz.metacentrum.perun.oidc.overlay; +import cz.metacentrum.perun.oidc.client.FacilitiesManager; +import cz.metacentrum.perun.oidc.client.PerunFacility; import cz.metacentrum.perun.oidc.client.PerunPrincipal; +import cz.metacentrum.perun.oidc.client.PerunResource; import cz.metacentrum.perun.oidc.client.PerunUser; import cz.metacentrum.perun.oidc.client.PerunUtils; import cz.metacentrum.perun.oidc.client.UsersManager; import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter; import javax.servlet.http.HttpServletRequest; +import java.util.HashSet; +import java.util.List; +import java.util.Set; /** * @author Ondrej Velisek + * @author Jiri Mauritz */ public class PerunAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter { - @Override - protected Object getPreAuthenticatedPrincipal(HttpServletRequest httpServletRequest) { - PerunPrincipal pp = PerunUtils.parsePrincipal(httpServletRequest); + private final String OIDCClientAttributeName = "urn:perun:facility:attribute-def:def:OIDCClientID"; - PerunUser user = UsersManager.getInstance().getUserByExtSourceNameAndExtLogin(pp.getExtSourceName(), pp.getUserExtSourceLogin()); + @Override + protected Object getPreAuthenticatedPrincipal(HttpServletRequest httpServletRequest) { + PerunPrincipal pp = PerunUtils.parsePrincipal(httpServletRequest); - return user.getId(); - } + // get user from request + PerunUser user = UsersManager.getInstance().getUserByExtSourceNameAndExtLogin(pp.getExtSourceName(), pp.getUserExtSourceLogin()); - @Override - protected Object getPreAuthenticatedCredentials(HttpServletRequest httpServletRequest) { - return "N/A"; - } + // get OIDCClientID value + String OIDCClientID = PerunUtils.getClientId(httpServletRequest); + + // get priviledged resources + List facilities = FacilitiesManager.getInstance().getFacilitiesByAttribute(OIDCClientAttributeName, OIDCClientID); + Set allowedResources = new HashSet<>(); + for (PerunFacility facility : facilities) { + allowedResources.addAll(FacilitiesManager.getInstance().getAssignedResources(facility.getId())); + } + + // get user resources + Set userResources = new HashSet<>(UsersManager.getInstance().getAllowedResourcesIds(user.getId())); + + // retain only allowed resources + userResources.retainAll(allowedResources); + + // if there is no allowed user resource, the user is not allowed + if (userResources.isEmpty()) { + return null; + } + + + if (user == null) { + return null; + } else { + return user.getId(); + } + } + + @Override + protected Object getPreAuthenticatedCredentials(HttpServletRequest httpServletRequest) { + return "N/A"; + } }