Commit c7625c6a authored by Francesco Chicchiricco's avatar Francesco Chicchiricco
Browse files

[CRV-19] Added endpoint for setting Federation Server URL into Security Filter instances

parent a98aa6a2
......@@ -61,6 +61,11 @@ limitations under the License.
<artifactId>jackson-jaxrs-json-provider</artifactId>
</dependency>
<dependency>
<groupId>eu.chorevolution.securityfilter</groupId>
<artifactId>sf-provision-data</artifactId>
</dependency>
<dependency>
<groupId>eu.chorevolution.idm.ext.choreography</groupId>
<artifactId>syncope-ext-choreography-common-lib</artifactId>
......
......@@ -27,10 +27,12 @@ import eu.chorevolution.idm.common.types.ChoreographyOperation;
import eu.chorevolution.idm.common.types.SecurityFilterInfo;
import eu.chorevolution.idm.common.types.SecurityFilterStatus;
import eu.chorevolution.idm.common.types.ServiceAction;
import eu.chorevolution.securityfilter.api.SecurityFilterConfiguration;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
......@@ -182,11 +184,24 @@ public class ChoreographyLogic extends AbstractLogic<AbstractBaseBean> {
accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_XML_TYPE);
}
private WebClient getSFWebClient(final String baseURL, final String endpoint) {
private WebClient getSFWebClient(final GroupTO choreography, final AnyObjectTO service, final String endpoint) {
MembershipTO membership = service.getMembershipMap().get(choreography.getKey());
if (membership == null) {
throw new NotFoundException(
"Service " + service.getName() + " not involved in choreography " + choreography.getName());
}
AttrTO securityFilterEndpoint = membership.getPlainAttrMap().get(SECURITY_FILTER_ENDPOINT_SCHEMA);
if (securityFilterEndpoint == null || securityFilterEndpoint.getValues().isEmpty()) {
throw new NotFoundException(
"No security filter for " + service.getName() + " in choreography " + choreography.getName());
}
List<Object> providers = new ArrayList<>();
providers.add(new JacksonJaxbJsonProvider());
return WebClient.create(
StringUtils.removeEndIgnoreCase(baseURL, "/") + "/management/" + endpoint, providers).
StringUtils.removeEndIgnoreCase(securityFilterEndpoint.getValues().get(0), "/")
+ "/management/" + endpoint, providers).
accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE);
}
......@@ -624,31 +639,25 @@ public class ChoreographyLogic extends AbstractLogic<AbstractBaseBean> {
throw new RuntimeException("While replacing service", e);
}
} else {
AttrTO securityFilterEndpoint = membership.getPlainAttrMap().get(SECURITY_FILTER_ENDPOINT_SCHEMA);
if (securityFilterEndpoint == null || securityFilterEndpoint.getValues().isEmpty()) {
throw new NotFoundException(
"No security filter for " + service.getName() + " in choreography " + choreography.getName());
}
WebClient webClient;
Response response = null;
try {
switch (action) {
case ENABLE_SECURITY_FILTER:
webClient = getSFWebClient(
securityFilterEndpoint.getValues().get(0), SecurityFilterStatus.ENABLED.name());
choreography, service, SecurityFilterStatus.ENABLED.name());
response = webClient.put(null);
break;
case DISABLE_SECURITY_FILTER:
webClient = getSFWebClient(
securityFilterEndpoint.getValues().get(0), SecurityFilterStatus.DISABLED.name());
choreography, service, SecurityFilterStatus.DISABLED.name());
response = webClient.put(null);
break;
case ENFORCE_SECURITY_CONTEXT:
webClient = getSFWebClient(
securityFilterEndpoint.getValues().get(0), "securityContext");
choreography, service, "securityContext");
response = webClient.post(argument);
break;
......@@ -671,20 +680,8 @@ public class ChoreographyLogic extends AbstractLogic<AbstractBaseBean> {
GroupTO choreography = choreographyExists(id);
AnyObjectTO service = anyObjectExists(serviceId);
MembershipTO membership = service.getMembershipMap().get(choreography.getKey());
if (membership == null) {
throw new NotFoundException(
"Service " + service.getName() + " not involved in choreography " + choreography.getName());
}
AttrTO securityFilterEndpoint = membership.getPlainAttrMap().get(SECURITY_FILTER_ENDPOINT_SCHEMA);
if (securityFilterEndpoint == null || securityFilterEndpoint.getValues().isEmpty()) {
throw new NotFoundException(
"No security filter for " + service.getName() + " in choreography " + choreography.getName());
}
try {
WebClient webClient = getSFWebClient(securityFilterEndpoint.getValues().get(0), "info");
WebClient webClient = getSFWebClient(choreography, service, "info");
Response response = webClient.get();
if (response.getStatus() != Response.Status.OK.getStatusCode()) {
throw new WebApplicationException(response);
......@@ -692,7 +689,26 @@ public class ChoreographyLogic extends AbstractLogic<AbstractBaseBean> {
return response.readEntity(SecurityFilterInfo.class);
} catch (WebApplicationException e) {
throw new RuntimeException("While reading security filter information for " + service.getName()
+ " in choreography " + choreography.getName(), e);
+ " in choreography " + id, e);
}
}
@PreAuthorize("hasRole('" + ChorevolutionEntitlement.ON_CHOREOGRAPHY_SERVICE + "')")
public void configureSecurityFilter(final String id, final String serviceId, final URL federationServerURL) {
GroupTO choreography = choreographyExists(id);
AnyObjectTO service = anyObjectExists(serviceId);
try {
WebClient webClient = getSFWebClient(choreography, service, "federationServerURL");
SecurityFilterConfiguration sfc = new SecurityFilterConfiguration();
sfc.setURL(federationServerURL.toExternalForm());
Response response = webClient.put(sfc);
if (response.getStatus() != Response.Status.OK.getStatusCode()) {
throw new WebApplicationException(response);
}
} catch (WebApplicationException e) {
throw new RuntimeException("While setting the Federation Server UTL into the Security Filter instance for "
+ service.getName() + " in choreography " + id, e);
}
}
......
......@@ -20,6 +20,7 @@ import eu.chorevolution.idm.common.types.ChoreographyOperation;
import eu.chorevolution.idm.common.types.SecurityFilterInfo;
import eu.chorevolution.idm.common.types.ServiceAction;
import java.io.InputStream;
import java.net.URL;
import javax.validation.constraints.NotNull;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
......@@ -156,4 +157,19 @@ public interface ChoreographyService extends JAXRSService {
SecurityFilterInfo readSecurityFilterInfo(
@NotNull @PathParam("id") String id,
@NotNull @PathParam("serviceId") String serviceId);
/**
* Configure the Federation Server URL into the security filter instance associated to the given service,
* in the given choreography (if available).
*
* @param id choreography id
* @param serviceId choreography service id
* @param federationServerURL Federation Server URL to configure
*/
@PUT
@Path("{id}/{serviceId}/securityFilter")
void configureSecurityFilter(
@NotNull @PathParam("id") String id,
@NotNull @PathParam("serviceId") String serviceId,
URL federationServerURL);
}
......@@ -21,6 +21,7 @@ import eu.chorevolution.idm.common.types.SecurityFilterInfo;
import eu.chorevolution.idm.common.types.ServiceAction;
import org.apache.syncope.core.logic.ChoreographyLogic;
import java.io.InputStream;
import java.net.URL;
import javax.ws.rs.core.Response;
import org.apache.syncope.common.rest.api.service.ChoreographyService;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -86,4 +87,9 @@ public class ChoreographyServiceImpl extends AbstractServiceImpl implements Chor
return logic.readSecurityFilterInfo(id, serviceId);
}
@Override
public void configureSecurityFilter(final String id, final String serviceId, final URL federationServerURL) {
logic.configureSecurityFilter(id, serviceId, federationServerURL);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment