Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide authentication endpoint for setting IDP's and SSO #149

Merged
merged 1 commit into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</parent>

<artifactId>confapi-commons</artifactId>
<version>0.4.1-SNAPSHOT</version>
<version>0.5.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>ConfAPI Commons</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ public class ConfAPI {
public static final String APPLICATIONS = "applications";
public static final String APPLICATION_LINK = "application-link";
public static final String APPLICATION_LINKS = "application-links";
public static final String AUTHENTICATION = "authentication";
public static final String AUTHENTICATION_IDP = "idp";
public static final String AUTHENTICATION_IDPS = "idps";
public static final String AUTHENTICATION_IDP_OIDC = "oidc";
public static final String AUTHENTICATION_IDP_SAML = "saml";
public static final String AUTHENTICATION_SSO = "sso";
public static final String BACKUP = "backup";
public static final String BACKUP_EXPORT = "export";
public static final String BACKUP_IMPORT = "import";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package de.aservo.confapi.commons.model;

import de.aservo.confapi.commons.constants.ConfAPI;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.codehaus.jackson.annotate.JsonSubTypes;
import org.codehaus.jackson.annotate.JsonTypeInfo;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@Data
@NoArgsConstructor
@XmlRootElement
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type"
)
// Note: New subtypes must also be registered in AuthenticationIdpsBean.java to be considered in the REST API documentation
@JsonSubTypes({
@JsonSubTypes.Type(value = AuthenticationIdpOidcBean.class, name = ConfAPI.AUTHENTICATION_IDP_OIDC),
@JsonSubTypes.Type(value = AuthenticationIdpSamlBean.class, name = ConfAPI.AUTHENTICATION_IDP_SAML),
})
public abstract class AbstractAuthenticationIdpBean {

@XmlElement
private Long id;

@XmlElement
private String name;

@XmlElement
private Boolean enabled;

@XmlElement
private String url;

@XmlElement
private Boolean enableRememberMe;

@XmlElement
private String buttonText;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package de.aservo.confapi.commons.model;

import de.aservo.confapi.commons.constants.ConfAPI;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Collections;
import java.util.List;

@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@XmlRootElement(name = ConfAPI.AUTHENTICATION + "-" + ConfAPI.AUTHENTICATION_IDP + "-" + ConfAPI.AUTHENTICATION_IDP_OIDC)
public class AuthenticationIdpOidcBean extends AbstractAuthenticationIdpBean {

@XmlElement
private String clientId;

@XmlElement
private String clientSecret;

@XmlElement
private String usernameClaim;

@XmlElement
private List<String> additionalScopes;

@XmlElement
private Boolean discoveryEnabled;

@XmlElement
private String authorizationEndpoint;

@XmlElement
private String tokenEndpoint;

@XmlElement
private String userInfoEndpoint;

// Just-in-time user provisioning is not implemented yet

// Example instances for documentation and tests

public static final AuthenticationIdpOidcBean EXAMPLE_1;

static {
EXAMPLE_1 = new AuthenticationIdpOidcBean();
EXAMPLE_1.setId(1L);
EXAMPLE_1.setName("OIDC");
EXAMPLE_1.setEnabled(true);
EXAMPLE_1.setUrl("https://oidc.example.com");
EXAMPLE_1.setEnableRememberMe(true);
EXAMPLE_1.setButtonText("Login with OIDC");
EXAMPLE_1.setClientId("oidc");
EXAMPLE_1.setClientSecret("s3cr3t");
EXAMPLE_1.setUsernameClaim("userName");
EXAMPLE_1.setAdditionalScopes(Collections.emptyList());
EXAMPLE_1.setDiscoveryEnabled(false);
EXAMPLE_1.setAuthorizationEndpoint("https://oidc.example.com/authorization");
EXAMPLE_1.setTokenEndpoint("https://oidc.example.com/token");
EXAMPLE_1.setUserInfoEndpoint("https://oidc.example.com/userinfo");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package de.aservo.confapi.commons.model;

import de.aservo.confapi.commons.constants.ConfAPI;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@XmlRootElement(name = ConfAPI.AUTHENTICATION + "-" + ConfAPI.AUTHENTICATION_IDP + "-" + ConfAPI.AUTHENTICATION_IDP_SAML)
public class AuthenticationIdpSamlBean extends AbstractAuthenticationIdpBean {

@XmlElement
private String certificate;

@XmlElement
private String usernameAttribute;

// Just-in-time user provisioning is not implemented yet

// Example instances for documentation and tests

public static final AuthenticationIdpSamlBean EXAMPLE_1;

static {
EXAMPLE_1 = new AuthenticationIdpSamlBean();
EXAMPLE_1.setId(1L);
EXAMPLE_1.setName("SAML");
EXAMPLE_1.setEnabled(true);
EXAMPLE_1.setUrl("https://saml.example.com");
EXAMPLE_1.setEnableRememberMe(true);
EXAMPLE_1.setButtonText("Login with SAML");
EXAMPLE_1.setCertificate("certificate");
EXAMPLE_1.setUsernameAttribute("username");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package de.aservo.confapi.commons.model;

import de.aservo.confapi.commons.constants.ConfAPI;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Collection;

@Data
@NoArgsConstructor
@AllArgsConstructor
@XmlRootElement(name = ConfAPI.AUTHENTICATION + "-" + ConfAPI.AUTHENTICATION_IDPS)
public class AuthenticationIdpsBean {

@XmlElement
@Schema(anyOf = {
AuthenticationIdpOidcBean.class,
})
private Collection<AbstractAuthenticationIdpBean> authenticationIdpBeans;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package de.aservo.confapi.commons.model;

import de.aservo.confapi.commons.constants.ConfAPI;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@Data
@NoArgsConstructor
@XmlRootElement(name = ConfAPI.AUTHENTICATION + "-" + ConfAPI.AUTHENTICATION_SSO)
public class AuthenticationSsoBean {

@XmlElement
private Boolean showOnLogin;

// Example instances for documentation and tests

public static final AuthenticationSsoBean EXAMPLE_1;

static {
EXAMPLE_1 = new AuthenticationSsoBean();
EXAMPLE_1.setShowOnLogin(true);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package de.aservo.confapi.commons.rest;

import de.aservo.confapi.commons.model.AuthenticationIdpsBean;
import de.aservo.confapi.commons.model.AuthenticationSsoBean;
import de.aservo.confapi.commons.rest.api.AuthenticationResource;
import de.aservo.confapi.commons.service.api.AuthenticationService;

import javax.ws.rs.core.Response;

public abstract class AbstractAuthenticationResourceImpl implements AuthenticationResource {

private final AuthenticationService authenticationService;

protected AbstractAuthenticationResourceImpl(
final AuthenticationService authenticationService) {

this.authenticationService = authenticationService;
}

@Override
public Response getAuthenticationIdps() {
final AuthenticationIdpsBean resultAuthenticationIdpsBean = authenticationService.getAuthenticationIdps();
return Response.ok(resultAuthenticationIdpsBean).build();
}

@Override
public Response setAuthenticationIdps(
final AuthenticationIdpsBean authenticationIdpsBean) {

final AuthenticationIdpsBean resultAuthenticationIdpsBean = authenticationService.setAuthenticationIdps(authenticationIdpsBean);
return Response.ok(resultAuthenticationIdpsBean).build();
}

@Override
public Response getAuthenticationSso() {
final AuthenticationSsoBean resultAuthenticationSsoBean = authenticationService.getAuthenticationSso();
return Response.ok(resultAuthenticationSsoBean).build();
}

@Override
public Response setAuthenticationSso(
final AuthenticationSsoBean authenticationSsoBean) {

final AuthenticationSsoBean resultAuthenticationSsoBean = authenticationService.setAuthenticationSso(authenticationSsoBean);
return Response.ok(resultAuthenticationSsoBean).build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package de.aservo.confapi.commons.rest.api;

import de.aservo.confapi.commons.constants.ConfAPI;
import de.aservo.confapi.commons.http.PATCH;
import de.aservo.confapi.commons.model.AuthenticationIdpsBean;
import de.aservo.confapi.commons.model.AuthenticationSsoBean;
import de.aservo.confapi.commons.model.ErrorCollection;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

public interface AuthenticationResource {

@GET
@Path(ConfAPI.AUTHENTICATION_IDPS)
@Produces(MediaType.APPLICATION_JSON)
@Operation(
tags = { ConfAPI.AUTHENTICATION },
summary = "Get all authentication identity providers",
responses = {
@ApiResponse(
responseCode = "200", content = @Content(schema = @Schema(implementation = AuthenticationIdpsBean.class)),
description = "Returns all authentication identity providers."),
@ApiResponse(
content = @Content(schema = @Schema(implementation = ErrorCollection.class)),
description = "Returns a list of error messages."
)
}
)
Response getAuthenticationIdps();

@PATCH
@Path(ConfAPI.AUTHENTICATION_IDPS)
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Operation(
tags = { ConfAPI.AUTHENTICATION },
summary = "Set all authentication identity providers",
responses = {
@ApiResponse(
responseCode = "200", content = @Content(schema = @Schema(implementation = AuthenticationIdpsBean.class)),
description = "Returns the set authentication identity providers."),
@ApiResponse(
content = @Content(schema = @Schema(implementation = ErrorCollection.class)),
description = "Returns a list of error messages."
)
}
)
Response setAuthenticationIdps(
final AuthenticationIdpsBean authenticationIdpsBean);

@GET
@Path(ConfAPI.AUTHENTICATION_SSO)
@Produces(MediaType.APPLICATION_JSON)
@Operation(
tags = { ConfAPI.AUTHENTICATION },
summary = "Get authentication SSO configuration",
responses = {
@ApiResponse(
responseCode = "200", content = @Content(schema = @Schema(implementation = AuthenticationSsoBean.class)),
description = "Returns the authentication SSO configuration."),
@ApiResponse(
content = @Content(schema = @Schema(implementation = ErrorCollection.class)),
description = "Returns a list of error messages."
)
}
)
Response getAuthenticationSso();

@PATCH
@Path(ConfAPI.AUTHENTICATION_SSO)
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Operation(
tags = { ConfAPI.AUTHENTICATION },
summary = "Set authentication SSO configuration",
responses = {
@ApiResponse(
responseCode = "200", content = @Content(schema = @Schema(implementation = AuthenticationSsoBean.class)),
description = "Returns the set authentication SSO configuration."),
@ApiResponse(
content = @Content(schema = @Schema(implementation = ErrorCollection.class)),
description = "Returns a list of error messages."
)
}
)
Response setAuthenticationSso(
final AuthenticationSsoBean authenticationSsoBean);

}
Loading
Loading