diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b69987c6c1f252ebf824bd2a39bfe891fc4bedc6..3bd9ce007392a0dfe31ca6b87ebd268b3d516ede 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,28 +19,16 @@ variables: P_NAME: "app.access-token-provider" P_APP_TYPE: "java" P_CODE_SRC_PATH: "." + P_MAVEN_IMAGE_TAG: "3.6.3" # Define jobs code: stage: build extends: - - .codeForJava - variables: - P_MAVEN_IMAGE_TAG: "3.6.3" + - .buildCodeForJava quality: stage: tests extends: - - .sonarqubeForJava - variables: - P_MAVEN_IMAGE_TAG: "3.6.3" - P_CODE_BINARIES: "target/classes/" - P_CODE_JACOCO_REPORT_PATH: "target/jacoco.exec" - P_CODE_JUNIT_REPORTS_PATH: "target/surefire-reports" - P_CODE_DYNAMIC_ANALYSIS: "reuseReports" - P_CODE_COVERAGE_PLUGIN: "jacoco" - P_CODE_SOURCE_ENCODING: "UTF-8" - P_CODE_LANGUAGE: "java" - P_CODE_DEVELOPER_EDITION: "true" - + - .testQualityForJavaWithSonarqube \ No newline at end of file diff --git a/access-token-provider-api/pom.xml b/access-token-provider-api/pom.xml index 14535327c1b9cbc66ec5cb0519b429eff66fd508..040333cb44eaff7cd4009ac2965ceeb2d478d8f2 100644 --- a/access-token-provider-api/pom.xml +++ b/access-token-provider-api/pom.xml @@ -11,8 +11,58 @@ </parent> <groupId>net.ihe.gazelle</groupId> - <artifactId>lib.access-token-provider-api</artifactId> + <artifactId>app.access-token-provider-api</artifactId> <name>Access Token Provider Api</name> <version>1.0.0-SNAPSHOT</version> -</project> \ No newline at end of file + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <configuration> + <archive> + <manifest> + <mainClass>fully.qualified.MainClass</mainClass> + </manifest> + </archive> + <descriptorRefs> + <descriptorRef>jar-with-dependencies</descriptorRef> + </descriptorRefs> + </configuration> + <executions> + <execution> + <id>make-assembly</id> <!-- this is used for inheritance merges --> + <phase>package</phase> <!-- bind to the packaging phase --> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + + + <dependencies> + <dependency> + <groupId>net.ihe.gazelle</groupId> + <artifactId>lib.annotations</artifactId> + <version>1.0.0</version> + </dependency> + <dependency> + <groupId>net.ihe.gazelle</groupId> + <artifactId>sb.iua-standard-block</artifactId> + <version>1.0.0</version> + </dependency> + <dependency> + <groupId>net.ihe.gazelle</groupId> + <artifactId>sb.jwt-standard-block</artifactId> + <version>1.0.0</version> + </dependency> + <dependency> + <groupId>net.ihe.gazelle</groupId> + <artifactId>app.audience-retriever</artifactId> + </dependency> + </dependencies> + +</project> diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/AudienceRegistry.java b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/AudienceRegistry.java new file mode 100644 index 0000000000000000000000000000000000000000..cb34775e4990c31ed073f8bb311cbffccb6929fa --- /dev/null +++ b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/AudienceRegistry.java @@ -0,0 +1,17 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.application; + +import net.ihe.gazelle.app.accesstokenproviderapi.business.Credential; + +/** + * Interface to interact with the audience registry where is store all known audience with their credential + */ +public interface AudienceRegistry { + + /** + * Get credential's audience + * @param audienceId + * @return credential + */ + Credential getAudienceCredentials(String audienceId); + +} diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/DummyAuthzServer.java b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/DummyAuthzServer.java new file mode 100644 index 0000000000000000000000000000000000000000..a63a7601576b8953a01a6999be167f8b70c6a9f8 --- /dev/null +++ b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/DummyAuthzServer.java @@ -0,0 +1,18 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.application; + +/** + * For SoapUI integration need, a simplified Authorization Server (or IDP) is required. + */ +public interface DummyAuthzServer { + + /** + * get a dummy access token + * @param userId + * @param audienceId + * @param purposeOfUse + * @param resourceId + * @return an access token + */ + byte[] getAccessToken(String userId, String audienceId, String purposeOfUse, String resourceId); + +} diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/DummyAuthzServerSoapui.java b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/DummyAuthzServerSoapui.java new file mode 100644 index 0000000000000000000000000000000000000000..907deacf605a3970c72c385332b4ac9fa09cb461 --- /dev/null +++ b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/DummyAuthzServerSoapui.java @@ -0,0 +1,97 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.application; + +import net.ihe.gazelle.app.accesstokenproviderapi.business.AccessTokenRequest; +import net.ihe.gazelle.app.accesstokenproviderapi.business.SymmetricSignature; +import net.ihe.gazelle.app.audienceretriever.adapter.AudienceSecretRetrieverForSoapui; +import net.ihe.gazelle.app.audienceretriever.application.AudienceSecretRetriever; +import net.ihe.gazelle.framework.loggerservice.application.GazelleLogger; +import net.ihe.gazelle.framework.loggerservice.application.GazelleLoggerFactory; +import net.ihe.gazelle.modelapi.sb.business.EncodingException; +import net.ihe.gazelle.sb.iua.business.TokenType; + +import java.time.Duration; + +/** + * Dummy soapui authorization server + */ +public class DummyAuthzServerSoapui implements DummyAuthzServer { + + private static final GazelleLogger LOGGER = GazelleLoggerFactory.getInstance().getLogger(DummyAuthzServerSoapui.class); + + private static final String ALGORITHM = "HS256"; + private static final String ISSUER = "https://ehealthsuisse.ihe-europe.net/access-token-provider"; + private static final TokenType TOKEN_TYPE = TokenType.JWT; + private static final Duration DURATION = Duration.ofHours(1); + private AudienceSecretRetriever audienceSecretRetriever; + + /** + * Default constructor for the class. + */ + public DummyAuthzServerSoapui() { + //Empty + } + + /** + * Constructor with the path for the class. + */ + public DummyAuthzServerSoapui(String path) { + audienceSecretRetriever = new AudienceSecretRetrieverForSoapui(path); + } + + /** + * Setter for the audienceSecretRetriever property. + * + * @param audienceSecretRetriever value to set to the property. + */ + public void setAudienceSecretRetriever(AudienceSecretRetriever audienceSecretRetriever) { + this.audienceSecretRetriever = audienceSecretRetriever; + } + + /** + * {@inheritDoc} + */ + @Override + public byte[] getAccessToken(String userId, String audienceId, String purposeOfUse, String resourceId) { + //todo purposeOfUse and resourceId are not yet implemented + + TokenGenerator tokenGenerator = new TokenGenerator(); + tokenGenerator.setAudienceSecretRetriever(this.audienceSecretRetriever); + + return getTokenGenerator(userId, audienceId, tokenGenerator); + } + + + /** + * get the access token + * + * @param userId String parameter + * @param audienceId String parameter + * @return AccessTokenRequest Element + */ + public AccessTokenRequest getAccessTokenRequest(String userId, String audienceId){ + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, userId, audienceId, DURATION, TOKEN_TYPE); + accessTokenRequest.setSignature(new SymmetricSignature(ALGORITHM, "secret")); + return accessTokenRequest; + } + + + /** + * get the generated token + * + * @param userId String element + * @param audienceId String element + * @param tokenGenerator TokenGenerator object + * @return The token as byte + */ + public byte[] getTokenGenerator(String userId, String audienceId, TokenGenerator tokenGenerator){ + byte[] token = null; + try { + token = tokenGenerator.generateAccessToken(getAccessTokenRequest(userId, audienceId)).getToken(); + } catch (EncodingException | TokenRequestException e) { + LOGGER.error("Error generating Access Token", e); + } + return token; + } + + +} diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/TestUserRegistry.java b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/TestUserRegistry.java new file mode 100644 index 0000000000000000000000000000000000000000..290fdf5520bb7a78214f1b484b483bec119647c0 --- /dev/null +++ b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/TestUserRegistry.java @@ -0,0 +1,16 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.application; + +import net.ihe.gazelle.app.accesstokenproviderapi.business.testuser.TestUser; + +/** + * Interface to interact with the test-users’ database for authentication step and token content + */ +public interface TestUserRegistry { + + /** + * @param userId + * @return TestUser + */ + TestUser getTestUser(String userId); + +} diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/TokenGenerator.java b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/TokenGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..3bd9b28b25f470cc6b81a3099380cbbe1185375c --- /dev/null +++ b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/TokenGenerator.java @@ -0,0 +1,115 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.application; + +import net.ihe.gazelle.app.accesstokenproviderapi.business.AccessTokenRequest; +import net.ihe.gazelle.app.audienceretriever.application.AudienceSecretRetriever; +import net.ihe.gazelle.modelapi.sb.business.EncodingException; +import net.ihe.gazelle.sb.iua.business.EncodedIUAToken; +import net.ihe.gazelle.sb.iua.business.TokenType; +import net.ihe.gazelle.sb.jwtstandardblock.adapter.JJWTAdapter; +import net.ihe.gazelle.sb.jwtstandardblock.application.JWSEncoderDecoder; +import net.ihe.gazelle.sb.jwtstandardblock.business.jose.JOSEHeader; +import net.ihe.gazelle.sb.jwtstandardblock.business.jwk.JSONWebKey; +import net.ihe.gazelle.sb.jwtstandardblock.business.jwk.KeyAlgorithm; +import net.ihe.gazelle.sb.jwtstandardblock.business.jwk.SymmetricalKey; +import net.ihe.gazelle.sb.jwtstandardblock.business.jwt.JSONWebSignature; +import net.ihe.gazelle.sb.jwtstandardblock.business.jwt.JSONWebToken; +import net.ihe.gazelle.sb.jwtstandardblock.business.jwt.JSONWebTokenClaimSet; + +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +/** + * Class to generate the token + */ +public class TokenGenerator { + + private static final String ALGORITHM = "HS256"; + private static final String ISSUER = "https://ehealthsuisse.ihe-europe.net/access-token-provider"; + private static final TokenType TOKEN_TYPE = TokenType.JWT; + private static final Duration DEFAULT_DURATION = Duration.ofMinutes(5); + private static final List<String> SUBJECTS = Arrays.asList("aamrein", "aerne"); + + private AudienceSecretRetriever audienceSecretRetriever; + + /** + * Set an audience secret + * + * @param audienceSecretRetriever AudienceSecretRetriever element + */ + public void setAudienceSecretRetriever(AudienceSecretRetriever audienceSecretRetriever) { + this.audienceSecretRetriever = audienceSecretRetriever; + } + + /** + * Encode the IUA token + * + * @param accessTokenRequest AccessTokenRequest element + * @return The EncodedIUAToken + * @throws EncodingException + * @throws TokenRequestException + */ + public EncodedIUAToken generateAccessToken(AccessTokenRequest accessTokenRequest) throws EncodingException, TokenRequestException { + if (accessTokenRequest.getSignature() == null) { + throw new TokenRequestException("Missing signature information"); + } + + if (accessTokenRequest.getSignature().getAlgorithm() == null || !accessTokenRequest.getSignature().getAlgorithm().equals(ALGORITHM)) { + throw new TokenRequestException("Unsupported Algorithm"); + } + + Duration duration = accessTokenRequest.getValidityTime() != null ? accessTokenRequest.getValidityTime() : DEFAULT_DURATION; + + if (accessTokenRequest.getTokenType() == null || !accessTokenRequest.getTokenType().equals(TOKEN_TYPE)) { + throw new TokenRequestException("Unsupported token type"); + } + + if (accessTokenRequest.getIssuer() == null || !accessTokenRequest.getIssuer().equals(ISSUER)) { + throw new TokenRequestException("Unsupported issuer"); + } + + if (accessTokenRequest.getAudience() == null || accessTokenRequest.getAudience().isEmpty()) { + throw new TokenRequestException("Audience is null or empty"); + } + + if (accessTokenRequest.getSubject() == null || !SUBJECTS.contains(accessTokenRequest.getSubject())) { + throw new TokenRequestException("Unsupported subject"); + } + + String secret = audienceSecretRetriever.retrieveSecretForAudience(accessTokenRequest.getAudience()); + if (secret == null || secret.isEmpty()) { + throw new TokenRequestException("Audience is not known"); + } + + JSONWebTokenClaimSet claimSet = new JSONWebTokenClaimSet(); + + claimSet.setSubject(accessTokenRequest.getSubject()); + claimSet.setIssuer(ISSUER); + claimSet.setAudience(accessTokenRequest.getAudience()); + + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")); + claimSet.setIssuedAt(String.valueOf(now.toEpochSecond())); + claimSet.setExpiration(String.valueOf(now.plus(duration).toEpochSecond())); + + claimSet.setJwtId(UUID.randomUUID().toString()); + + JOSEHeader joseHeader = new JOSEHeader(false, null, KeyAlgorithm.HS256); + JSONWebKey jsonWebKey = new SymmetricalKey(secret, null, KeyAlgorithm.HS256); + JSONWebSignature jose = new JSONWebSignature(jsonWebKey, joseHeader); + + JSONWebToken token = new JSONWebToken(UUID.randomUUID().toString(), "IUA", jose, claimSet); //Verify standard keyword + + JWSEncoderDecoder jwsEncoderDecoder = new JWSEncoderDecoder(new JJWTAdapter()); + + EncodedIUAToken encodedIUAToken = new EncodedIUAToken(jwsEncoderDecoder.encode(token).getCompletePayload().getBytes(StandardCharsets.UTF_8)); + encodedIUAToken.setTokenType(TokenType.JWT); + + return encodedIUAToken; + } + + +} diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/TokenRequestException.java b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/TokenRequestException.java new file mode 100644 index 0000000000000000000000000000000000000000..a22ea5ce4a77509c16a7ea1bc778ec739761cbc9 --- /dev/null +++ b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/TokenRequestException.java @@ -0,0 +1,63 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.application; + +/** + * Class to manage token request exception + */ +public class TokenRequestException extends Exception { + + /** + * Constructs a new exception with null as its detail message. The cause is not initialized, and may subsequently be initialized by a call to + * {@link Throwable#initCause(Throwable)}. + */ + public TokenRequestException() { + } + + /** + * Constructs a new exception with the specified detail message. The cause is not initialized, and may subsequently be initialized by a call to + * {@link Throwable#initCause(Throwable)}. + * + * @param message the detail message. Can be retrieved by a later call of {@link Throwable#getMessage()} method. + */ + public TokenRequestException(String message) { + super(message); + } + + /** + * Constructs a new exception with the specified detail message and cause. Note that the detail/TransactionRecordingDAO message associated with + * cause is not automatically incorporated in this exception's detail message. + * + * @param message the detail message. Can be retrieved by a later call of {@link Throwable#getMessage()} method. + * @param cause the cause. Can be retrieved by a lter call to {@link Throwable#getCause()}. A null value is permitted, and indicates that the + * cause is nonexistent or unknown. + */ + public TokenRequestException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new exception with the specified detail message, cause, suppression enabled or disabled, and writable stack trace enabled or + * disabled. + * + * @param cause the cause. Can be retrieved by a lter call to {@link Throwable#getCause()}. A null value is permitted, and indicates + * that the cause is nonexistent or unknown. + */ + public TokenRequestException(Throwable cause) { + super(cause); + } + + /** + * Constructs a new exception with the specified detail message, cause, suppression enabled or disabled, and writable stack trace enabled or + * disabled. + * + * @param message the detail message. Can be retrieved by a later call of {@link Throwable#getMessage()} method. + * @param cause the cause. Can be retrieved by a lter call to {@link Throwable#getCause()}. A null value is permitted, and indicates + * that the cause is nonexistent or unknown. + * @param enableSuppression whether or not suppression is enabled or disabled + * @param writableStackTrace whether or not the stack trace should be writable + */ + public TokenRequestException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + +} diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/exception/UnsupportedAlgorithmException.java b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/exception/UnsupportedAlgorithmException.java new file mode 100644 index 0000000000000000000000000000000000000000..789d9bcce78ad572d22700014805356dfb4daf1f --- /dev/null +++ b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/exception/UnsupportedAlgorithmException.java @@ -0,0 +1,61 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.application.exception; + +/** + * Class to manage unsupported algorithm exception + */ +public class UnsupportedAlgorithmException extends Exception { + + /** + * Constructs a new exception with null as its detail message. The cause is not initialized, and may subsequently be initialized by a call to + * {@link Throwable#initCause(Throwable)}. + */ + public UnsupportedAlgorithmException() { + } + + /** + * Constructs a new exception with the specified detail message. The cause is not initialized, and may subsequently be initialized by a call to + * {@link Throwable#initCause(Throwable)}. + * + * @param message the detail message. Can be retrieved by a later call of {@link Throwable#getMessage()} method. + */ + public UnsupportedAlgorithmException(String message) { + super(message); + } + + /** + * Constructs a new exception with the specified detail message and cause. Note that the detail/TransactionRecordingDAO message associated with + * cause is not automatically incorporated in this exception's detail message. + * + * @param message the detail message. Can be retrieved by a later call of {@link Throwable#getMessage()} method. + * @param cause the cause. Can be retrieved by a lter call to {@link Throwable#getCause()}. A null value is permitted, and indicates that the + * cause is nonexistent or unknown. + */ + public UnsupportedAlgorithmException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new exception with the specified detail message, cause, suppression enabled or disabled, and writable stack trace enabled or + * disabled. + * + * @param cause the cause. Can be retrieved by a lter call to {@link Throwable#getCause()}. A null value is permitted, and indicates + * that the cause is nonexistent or unknown. + */ + public UnsupportedAlgorithmException(Throwable cause) { + super(cause); + } + + /** + * Constructs a new exception with the specified detail message, cause, suppression enabled or disabled, and writable stack trace enabled or + * disabled. + * + * @param message the detail message. Can be retrieved by a later call of {@link Throwable#getMessage()} method. + * @param cause the cause. Can be retrieved by a lter call to {@link Throwable#getCause()}. A null value is permitted, and indicates + * that the cause is nonexistent or unknown. + * @param enableSuppression whether or not suppression is enabled or disabled + * @param writableStackTrace whether or not the stack trace should be writable + */ + public UnsupportedAlgorithmException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/exception/UnsupportedTokenTypeException.java b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/exception/UnsupportedTokenTypeException.java new file mode 100644 index 0000000000000000000000000000000000000000..adea3058e9fcdbebc865d5b991eefad5cfcaaa7c --- /dev/null +++ b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/application/exception/UnsupportedTokenTypeException.java @@ -0,0 +1,62 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.application.exception; + +/** + * Class to manage unsupported token exception + */ +public class UnsupportedTokenTypeException extends Exception { + + /** + * Constructs a new exception with null as its detail message. The cause is not initialized, and may subsequently be initialized by a call to + * {@link Throwable#initCause(Throwable)}. + */ + public UnsupportedTokenTypeException() { + } + + /** + * Constructs a new exception with the specified detail message. The cause is not initialized, and may subsequently be initialized by a call to + * {@link Throwable#initCause(Throwable)}. + * + * @param message the detail message. Can be retrieved by a later call of {@link Throwable#getMessage()} method. + */ + public UnsupportedTokenTypeException(String message) { + super(message); + } + + /** + * Constructs a new exception with the specified detail message and cause. Note that the detail/TransactionRecordingDAO message associated with + * cause is not automatically incorporated in this exception's detail message. + * + * @param message the detail message. Can be retrieved by a later call of {@link Throwable#getMessage()} method. + * @param cause the cause. Can be retrieved by a lter call to {@link Throwable#getCause()}. A null value is permitted, and indicates that the + * cause is nonexistent or unknown. + */ + public UnsupportedTokenTypeException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new exception with the specified detail message, cause, suppression enabled or disabled, and writable stack trace enabled or + * disabled. + * + * @param cause the cause. Can be retrieved by a lter call to {@link Throwable#getCause()}. A null value is permitted, and indicates + * that the cause is nonexistent or unknown. + */ + public UnsupportedTokenTypeException(Throwable cause) { + super(cause); + } + + /** + * Constructs a new exception with the specified detail message, cause, suppression enabled or disabled, and writable stack trace enabled or + * disabled. + * + * @param message the detail message. Can be retrieved by a later call of {@link Throwable#getMessage()} method. + * @param cause the cause. Can be retrieved by a lter call to {@link Throwable#getCause()}. A null value is permitted, and indicates + * that the cause is nonexistent or unknown. + * @param enableSuppression whether or not suppression is enabled or disabled + * @param writableStackTrace whether or not the stack trace should be writable + */ + public UnsupportedTokenTypeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +} diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/AccessTokenExtension.java b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/AccessTokenExtension.java new file mode 100644 index 0000000000000000000000000000000000000000..cd92b50c67f8c55d80175dad59ebba560cb60c1e --- /dev/null +++ b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/AccessTokenExtension.java @@ -0,0 +1,256 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.business; + +import java.util.ArrayList; +import java.util.List; + +/** + * Extensions for the Access Token + */ +public class AccessTokenExtension { + + private String subjectId; + private List<String> subjectOrganizations = new ArrayList<>(); + private List<String> subjectOrganizationIds = new ArrayList<>(); + private String homeCommunityId; + private String nationalProviderIdentifier; + private List<String> providerIds = new ArrayList<>(); + private CodedValue subjectRole; + private CodedValue purposeOfUse; + private String resourceId; + private String onBehalfOf; + + /** + * constructor + */ + public AccessTokenExtension() { + // Constructor is empty because all variables are optionals. + } + + /** + * get the subjectId + * @return subjectId + */ + public String getSubjectId() { + return subjectId; + } + + /** + * set the subjectId + * @param subjectId the subjectId + */ + public void setSubjectId(String subjectId) { + this.subjectId = subjectId; + } + + /** + * get subjectOrganizations list + * @return subjectOrganizations + */ + public List<String> getSubjectOrganizations() { + return subjectOrganizations; + } + + /** + * add a subjectOrganization in the subjectOrganizations list + * @param subjectOrganization a nationalProviderIdentifier + */ + public void addSubjectOrganization(String subjectOrganization) { + this.subjectOrganizations.add(subjectOrganization); + } + + /** + * remove a subjectOrganization from the subjectOrganizations list + * @param subjectOrganization a nationalProviderIdentifier + */ + public void removeSubjectOrganization(String subjectOrganization) { + this.subjectOrganizations.remove(subjectOrganization); + } + + /** + * get subjectOrganizationIds list + * @return subjectOrganizationIds + */ + public List<String> getSubjectOrganizationIds() { + return subjectOrganizationIds; + } + + /** + * add a subjectOrganizationId in the subjectOrganizationIds list + * @param subjectOrganizationId a subjectOrganizationId + */ + public void addSubjectOrganizationId(String subjectOrganizationId) { + this.subjectOrganizationIds.add(subjectOrganizationId); + } + + /** + * remove a subjectOrganizationId from the subjectOrganizationIds list + * @param subjectOrganizationId a subjectOrganizationId + */ + public void removeSubjectOrganizationId(String subjectOrganizationId) { + this.subjectOrganizationIds.remove(subjectOrganizationId); + } + + /** + * get the homeCommunityId + * @return homeCommunityId + */ + public String getHomeCommunityId() { + return homeCommunityId; + } + + /** + * set the homeCommunityId + * @param homeCommunityId the homeCommunityId + */ + public void setHomeCommunityId(String homeCommunityId) { + this.homeCommunityId = homeCommunityId; + } + + /** + * get the nationalProviderIdentifier + * @return nationalProviderIdentifier + */ + public String getNationalProviderIdentifier() { + return nationalProviderIdentifier; + } + + /** + * set the nationalProviderIdentifier + * @param nationalProviderIdentifier the nationalProviderIdentifier + */ + public void setNationalProviderIdentifier(String nationalProviderIdentifier) { + this.nationalProviderIdentifier = nationalProviderIdentifier; + } + + /** + * get providerIds list + * @return providerIds + */ + public List<String> getProviderIds() { + return providerIds; + } + + /** + * add a providerId in the providerIds list + * @param providerId a providerId + */ + public void addProviderId(String providerId) { + this.providerIds.add(providerId); + } + + /** + * remove a providerId in the providerIds list + * @param providerId a providerId + */ + public void removeProviderId(String providerId) { + this.providerIds.remove(providerId); + } + + /** + * get the subjectRole + * @return subjectRole + */ + public CodedValue getSubjectRole() { + return subjectRole; + } + + /** + * set the subjectRole + * @param subjectRole the subjectRole + */ + public void setSubjectRole(CodedValue subjectRole) { + this.subjectRole = subjectRole; + } + + /** + * get the purposeOfUse + * @return purposeOfUse + */ + public CodedValue getPurposeOfUse() { + return purposeOfUse; + } + + /** + * set the purposeOfUse + * @param purposeOfUse the purposeOfUse + */ + public void setPurposeOfUse(CodedValue purposeOfUse) { + this.purposeOfUse = purposeOfUse; + } + + /** + * get the resourceId + * @return resourceId + */ + public String getResourceId() { + return resourceId; + } + + /** + * set the resourceId + * @param resourceId the resourceId + */ + public void setResourceId(String resourceId) { + this.resourceId = resourceId; + } + + /** + * get the onBehalfOf + * @return onBehalfOf + */ + public String getOnBehalfOf() { + return onBehalfOf; + } + + /** + * set the onBehalfOf + * @param onBehalfOf the onBehalfOf + */ + public void setOnBehalfOf(String onBehalfOf) { + this.onBehalfOf = onBehalfOf; + } + + @Override + /** + * {@inheritDoc} + */ + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + AccessTokenExtension that = (AccessTokenExtension) o; + + if (subjectId != null ? !subjectId.equals(that.subjectId) : that.subjectId != null) return false; + if (subjectOrganizations != null ? !subjectOrganizations.equals(that.subjectOrganizations) : that.subjectOrganizations != null) + return false; + if (subjectOrganizationIds != null ? !subjectOrganizationIds.equals(that.subjectOrganizationIds) : that.subjectOrganizationIds != null) + return false; + if (homeCommunityId != null ? !homeCommunityId.equals(that.homeCommunityId) : that.homeCommunityId != null) + return false; + if (nationalProviderIdentifier != null ? !nationalProviderIdentifier.equals(that.nationalProviderIdentifier) : that.nationalProviderIdentifier != null) + return false; + if (providerIds != null ? !providerIds.equals(that.providerIds) : that.providerIds != null) return false; + if (subjectRole != null ? !subjectRole.equals(that.subjectRole) : that.subjectRole != null) return false; + if (purposeOfUse != null ? !purposeOfUse.equals(that.purposeOfUse) : that.purposeOfUse != null) return false; + if (resourceId != null ? !resourceId.equals(that.resourceId) : that.resourceId != null) return false; + return onBehalfOf != null ? onBehalfOf.equals(that.onBehalfOf) : that.onBehalfOf == null; + } + + @Override + /** + * {@inheritDoc} + */ + public int hashCode() { + int result = subjectId != null ? subjectId.hashCode() : 0; + result = 31 * result + (subjectOrganizations != null ? subjectOrganizations.hashCode() : 0); + result = 31 * result + (subjectOrganizationIds != null ? subjectOrganizationIds.hashCode() : 0); + result = 31 * result + (homeCommunityId != null ? homeCommunityId.hashCode() : 0); + result = 31 * result + (nationalProviderIdentifier != null ? nationalProviderIdentifier.hashCode() : 0); + result = 31 * result + (providerIds != null ? providerIds.hashCode() : 0); + result = 31 * result + (subjectRole != null ? subjectRole.hashCode() : 0); + result = 31 * result + (purposeOfUse != null ? purposeOfUse.hashCode() : 0); + result = 31 * result + (resourceId != null ? resourceId.hashCode() : 0); + result = 31 * result + (onBehalfOf != null ? onBehalfOf.hashCode() : 0); + return result; + } +} diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/AccessTokenRequest.java b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/AccessTokenRequest.java new file mode 100644 index 0000000000000000000000000000000000000000..d1dfad1ed718c4a314453a92814d3f0d84e246b3 --- /dev/null +++ b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/AccessTokenRequest.java @@ -0,0 +1,145 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.business; + +import net.ihe.gazelle.sb.iua.business.TokenType; + +import java.time.Duration; + +/** + * The Access Token request + */ +public class AccessTokenRequest { + + private String issuer; + private String subject; + private String audience; + private Duration validityTime; + private TokenType tokenType; + private Signature signature; + private AccessTokenExtension extension; + + /** + * constructor + */ + public AccessTokenRequest(String issuer, String subject, String audience, Duration validityTime, TokenType tokenType) { + this.issuer = issuer; + this.subject = subject; + this.audience = audience; + this.validityTime = validityTime; + this.tokenType = tokenType; + } + + /** + * get the issuer + * + * @return issuer + */ + public String getIssuer() { + return issuer; + } + + /** + * get the subject + * + * @return subject + */ + public String getSubject() { + return subject; + } + + /** + * get the audience + * + * @return audience + */ + public String getAudience() { + return audience; + } + + /** + * get the validityTime + * + * @return validityTime + */ + public Duration getValidityTime() { + return validityTime; + } + + /** + * get the tokenType + * + * @return tokenType + */ + public TokenType getTokenType() { + return tokenType; + } + + /** + * get the signature + * + * @return signature + */ + public Signature getSignature() { + return signature; + } + + /** + * set the signature + * + * @param signature the signature + */ + public void setSignature(Signature signature) { + this.signature = signature; + } + + /** + * get the extension + * + * @return extension + */ + public AccessTokenExtension getExtension() { + return extension; + } + + /** + * set the extension + * + * @param extension the extension + */ + public void setExtension(AccessTokenExtension extension) { + this.extension = extension; + } + + @Override + /** + * {@inheritDoc} + */ + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + AccessTokenRequest that = (AccessTokenRequest) o; + + if (!issuer.equals(that.issuer)) return false; + if (!subject.equals(that.subject)) return false; + if (!audience.equals(that.audience)) return false; + if (!validityTime.equals(that.validityTime)) return false; + if (tokenType != that.tokenType) return false; + if (signature != null ? !signature.equals(that.signature) : that.signature != null) return false; + return extension != null ? extension.equals(that.extension) : that.extension == null; + } + + @Override + /** + * {@inheritDoc} + */ + public int hashCode() { + int result = issuer.hashCode(); + result = 31 * result + subject.hashCode(); + result = 31 * result + audience.hashCode(); + result = 31 * result + validityTime.hashCode(); + result = 31 * result + tokenType.hashCode(); + result = 31 * result + (signature != null ? signature.hashCode() : 0); + result = 31 * result + (extension != null ? extension.hashCode() : 0); + return result; + } +} diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/AsymmetricSignature.java b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/AsymmetricSignature.java new file mode 100644 index 0000000000000000000000000000000000000000..93cb4a39f52d6faeda98d989d0809bb047399177 --- /dev/null +++ b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/AsymmetricSignature.java @@ -0,0 +1,62 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.business; + +import java.util.Arrays; + +/** + * Asymmetric signature information of the access token + */ +public class AsymmetricSignature extends Signature { + + private byte[] privateKey; + private String privateKeyPassword; + + /** + * constructor + */ + public AsymmetricSignature(String algorithm, byte[] privateKey, String privateKeyPassword) { + super(algorithm); + this.privateKey = privateKey.clone(); + this.privateKeyPassword = privateKeyPassword; + } + + /** + * get the privateKey + * @return privateKey + */ + public byte[] getPrivateKey() { + return privateKey.clone(); + } + + /** + * get the privateKeyPassword + * @return privateKeyPassword + */ + public String getPrivateKeyPassword() { + return privateKeyPassword; + } + + @Override + /** + * {@inheritDoc} + */ + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + AsymmetricSignature that = (AsymmetricSignature) o; + + if (!Arrays.equals(privateKey, that.privateKey)) return false; + return privateKeyPassword.equals(that.privateKeyPassword); + } + + @Override + /** + * {@inheritDoc} + */ + public int hashCode() { + int result = Arrays.hashCode(privateKey); + result = 31 * result + privateKeyPassword.hashCode(); + return result; + } +} diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/CodedValue.java b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/CodedValue.java new file mode 100644 index 0000000000000000000000000000000000000000..ebd7e365c497b4eab5b7444c4af6ff0fd195e9bc --- /dev/null +++ b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/CodedValue.java @@ -0,0 +1,74 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.business; + +/** + * A Coded value + */ +public class CodedValue { + + private String code; + private String codeSystem; + private String codeSystemName; + private String displayName; + + /** + * constructor + */ + public CodedValue(String code, String codeSystem) { + this.code = code; + this.codeSystem = codeSystem; + } + + /** + * get the code + * + * @return code + */ + public String getCode() { + return code; + } + + /** + * get the codeSystem + * + * @return codeSystem + */ + public String getCodeSystem() { + return codeSystem; + } + + /** + * get the codeSystemName + * + * @return codeSystemName + */ + public String getCodeSystemName() { + return codeSystemName; + } + + /** + * set the codeSystemName + * + * @param codeSystemName the codeSystemName + */ + public void setCodeSystemName(String codeSystemName) { + this.codeSystemName = codeSystemName; + } + + /** + * get the displayName + * + * @return displayName + */ + public String getDisplayName() { + return displayName; + } + + /** + * set the displayName + * + * @param displayName the displayName + */ + public void setDisplayName(String displayName) { + this.displayName = displayName; + } +} diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/Credential.java b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/Credential.java new file mode 100644 index 0000000000000000000000000000000000000000..3e26d29844ec890430f55aaeecab12ae0ca58b25 --- /dev/null +++ b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/Credential.java @@ -0,0 +1,7 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.business; + +/** + * Credential for an audience + */ +public interface Credential { +} diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/Password.java b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/Password.java new file mode 100644 index 0000000000000000000000000000000000000000..c0143af4f813a794e08b8e2dd73302b5d9f58532 --- /dev/null +++ b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/Password.java @@ -0,0 +1,47 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.business; + +import java.util.Arrays; + +/** + * A password + */ +public class Password implements Credential { + + private byte[] value; + + /** + * constructor + */ + public Password(byte[] value) { + this.value = value.clone(); + } + + /** + * get the value + * @return value + */ + public byte[] getValue() { + return value.clone(); + } + + @Override + /** + * {@inheritDoc} + */ + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Password password = (Password) o; + + return Arrays.equals(value, password.value); + } + + @Override + /** + * {@inheritDoc} + */ + public int hashCode() { + return Arrays.hashCode(value); + } +} diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/PublicKey.java b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/PublicKey.java new file mode 100644 index 0000000000000000000000000000000000000000..2ba2fe7b76d739648fc5236505daf1b307bd44c5 --- /dev/null +++ b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/PublicKey.java @@ -0,0 +1,46 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.business; + +import java.util.Arrays; + +/** + * A public key + */ +public class PublicKey implements Credential { + private byte[] key; + + /** + * constructor + */ + public PublicKey(byte[] key) { + this.key = key.clone(); + } + + /** + * get the key + * @return key + */ + public byte[] getKey() { + return key.clone(); + } + + @Override + /** + * {@inheritDoc} + */ + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PublicKey publicKey = (PublicKey) o; + + return Arrays.equals(key, publicKey.key); + } + + @Override + /** + * {@inheritDoc} + */ + public int hashCode() { + return Arrays.hashCode(key); + } +} diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/Signature.java b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/Signature.java new file mode 100644 index 0000000000000000000000000000000000000000..ec065fc59c883571956776052d626bda93d4663f --- /dev/null +++ b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/Signature.java @@ -0,0 +1,46 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.business; + + +/** + * Signature information of the access token + */ +public abstract class Signature { + + private String algorithm; + + /** + * constructor + */ + public Signature(String algorithm) { + this.algorithm = algorithm; + } + + /** + * get the algorithm + * @return algorithm + */ + public String getAlgorithm() { + return algorithm; + } + + @Override + /** + * {@inheritDoc} + */ + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Signature signature = (Signature) o; + + return algorithm.equals(signature.algorithm); + } + + @Override + /** + * {@inheritDoc} + */ + public int hashCode() { + return algorithm.hashCode(); + } +} diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/SymmetricSignature.java b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/SymmetricSignature.java new file mode 100644 index 0000000000000000000000000000000000000000..31628baae5de12ccbdcb0762a2f4e4f778af00db --- /dev/null +++ b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/SymmetricSignature.java @@ -0,0 +1,47 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.business; + +/** + * Symmetric signature information of the access token + */ +public class SymmetricSignature extends Signature { + + private String secret; + + /** + * constructor + */ + public SymmetricSignature(String algorithm, String secret) { + super(algorithm); + this.secret = secret; + } + + /** + * get the secret + * @return secret + */ + public String getSecret() { + return secret; + } + + @Override + /** + * {@inheritDoc} + */ + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + SymmetricSignature that = (SymmetricSignature) o; + + return secret.equals(that.secret); + } + + @Override + /** + * {@inheritDoc} + */ + public int hashCode() { + return secret.hashCode(); + } +} diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/testuser/TestUser.java b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/testuser/TestUser.java new file mode 100644 index 0000000000000000000000000000000000000000..2585df370d0834ed20191591beec7a3ad2b3e9f9 --- /dev/null +++ b/access-token-provider-api/src/main/java/net/ihe/gazelle/app/accesstokenproviderapi/business/testuser/TestUser.java @@ -0,0 +1,140 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.business.testuser; + +import java.util.*; + +/** + * Test user used for authentication and token content + */ +public class TestUser { + + private String userId; + private List<String> givenNames = new ArrayList<>(); + private String lastName; + private Date birthDate; + private String gender; + private Map<String, String> extensions = new HashMap<>(); + + /** + * Constructor + */ + public TestUser(String userId, List<String> givenNames, String lastName) { + this.userId = userId; + this.givenNames = givenNames; + this.lastName = lastName; + } + + /** + * get the userId + * @return userId + */ + public String getUserId() { + return userId; + } + + /** + * get the givenNames + * @return givenNames + */ + public List<String> getGivenNames() { + return givenNames; + } + + /** + * get the lastName + * @return lastName + */ + public String getLastName() { + return lastName; + } + + /** + * get the birthDate + * @return birthDate + */ + public Date getBirthDate() { + return (Date) birthDate.clone(); + } + + /** + * set the birthDate + * + * @param birthDate the birthDate + */ + public void setBirthDate(Date birthDate) { + this.birthDate = (Date) birthDate.clone(); + } + + /** + * get the gender + * @return gender + */ + public String getGender() { + return gender; + } + + /** + * set the gender + * + * @param gender the gender + */ + public void setGender(String gender) { + this.gender = gender; + } + + /** + * get the extensions + * @return extensions + */ + public Map<String, String> getExtensions() { + return extensions; + } + + /** + * add an extension in the extensions map + * @param key key of the extension + * @param value value of the extension + */ + public void addExtension(String key, String value) { + extensions.put(key, value); + } + + /** + * remove an extension in the extensions map + * @param key key of the extension + */ + public void removeExtension(String key) { + extensions.remove(key); + } + + @Override + /** + * {@inheritDoc} + */ + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + TestUser testUser = (TestUser) o; + + if (!userId.equals(testUser.userId)) return false; + if (!givenNames.equals(testUser.givenNames)) return false; + if (!lastName.equals(testUser.lastName)) return false; + if (birthDate != null ? !birthDate.equals(testUser.birthDate) : testUser.birthDate != null) return false; + if (gender != null ? !gender.equals(testUser.gender) : testUser.gender != null) return false; + return extensions != null ? extensions.equals(testUser.extensions) : testUser.extensions == null; + } + + @Override + /** + * {@inheritDoc} + */ + public int hashCode() { + int result = userId.hashCode(); + result = 31 * result + givenNames.hashCode(); + result = 31 * result + lastName.hashCode(); + result = 31 * result + (birthDate != null ? birthDate.hashCode() : 0); + result = 31 * result + (gender != null ? gender.hashCode() : 0); + result = 31 * result + (extensions != null ? extensions.hashCode() : 0); + return result; + } +} diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/lib/net.ihe.gazelle.app.accesstokenproviderapi/adapter/README.txt b/access-token-provider-api/src/main/java/net/ihe/gazelle/lib/net.ihe.gazelle.app.accesstokenproviderapi/adapter/README.txt deleted file mode 100644 index f9f3a064a8060a6fac7ac2caba057ac521732a1d..0000000000000000000000000000000000000000 --- a/access-token-provider-api/src/main/java/net/ihe/gazelle/lib/net.ihe.gazelle.app.accesstokenproviderapi/adapter/README.txt +++ /dev/null @@ -1,5 +0,0 @@ -Put here classes from adapter layer : -Data transformers, adapters, presenters or DAO. Abstraction of external libraries for -application or business use. -Web-services point, sockets, database connection and pool, GUI, file system, framework, -external libraries. \ No newline at end of file diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/lib/net.ihe.gazelle.app.accesstokenproviderapi/application/README.txt b/access-token-provider-api/src/main/java/net/ihe/gazelle/lib/net.ihe.gazelle.app.accesstokenproviderapi/application/README.txt deleted file mode 100644 index 13b8d86e92813836491d776f448dfd3f0a81628f..0000000000000000000000000000000000000000 --- a/access-token-provider-api/src/main/java/net/ihe/gazelle/lib/net.ihe.gazelle.app.accesstokenproviderapi/application/README.txt +++ /dev/null @@ -1,2 +0,0 @@ -Put here classes from application layer : -Use cases. Business elements applied in an application context or scenario. \ No newline at end of file diff --git a/access-token-provider-api/src/main/java/net/ihe/gazelle/lib/net.ihe.gazelle.app.accesstokenproviderapi/business/README.txt b/access-token-provider-api/src/main/java/net/ihe/gazelle/lib/net.ihe.gazelle.app.accesstokenproviderapi/business/README.txt deleted file mode 100644 index 277b09a0363f09d1d11ebcc56460392a69e4b60b..0000000000000000000000000000000000000000 --- a/access-token-provider-api/src/main/java/net/ihe/gazelle/lib/net.ihe.gazelle.app.accesstokenproviderapi/business/README.txt +++ /dev/null @@ -1,2 +0,0 @@ -Put here classes from business layer : -Business model, rules and constraints. Always true. Independent from the application. \ No newline at end of file diff --git a/access-token-provider-api/src/main/resources/getToken-soapui-project.xml b/access-token-provider-api/src/main/resources/getToken-soapui-project.xml new file mode 100644 index 0000000000000000000000000000000000000000..1b910e1f165102fbb24cbf8975bf3e8413b843d6 --- /dev/null +++ b/access-token-provider-api/src/main/resources/getToken-soapui-project.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<con:soapui-project id="4527283c-83fc-419a-9fa3-d9c072053eac" activeEnvironment="Default" name="getToken" resourceRoot="" soapui-version="5.6.0" abortOnError="false" runType="SEQUENTIAL" xmlns:con="http://eviware.com/soapui/config"><con:settings/><con:testSuite id="a7dd34e8-2441-4bf8-b2bc-3ea43c3b0f42" name="getToken"><con:settings/><con:runType>SEQUENTIAL</con:runType><con:testCase id="f8ac5a96-e7e9-4a60-9e9c-84f80664db91" failOnError="true" failTestCaseOnErrors="true" keepSession="false" maxResults="0" name="getToken" searchProperties="true"><con:settings/><con:testStep type="groovy" name="exemple" id="c65c443d-1476-4c4a-b9e6-b63eac62939f"><con:settings/><con:config><script>import net.ihe.gazelle.app.accesstokenproviderapi.application.DummyAuthzServerSoapui + + def server = new DummyAuthzServerSoapui("/opt/simulators/audience.properties"); + def token = server.getAccessToken("aamrein", "audience", null, null ); + log.info new String(token) +</script> +</con:config> +</con:testStep> + <con:properties/> +</con:testCase> + <con:properties/> +</con:testSuite> + <con:properties/> + <con:wssContainer/> + <con:oAuth2ProfileContainer/> + <con:oAuth1ProfileContainer/> + <con:sensitiveInformation/> +</con:soapui-project> \ No newline at end of file diff --git a/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/application/AudienceSecretRetrieverTestImpl.java b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/application/AudienceSecretRetrieverTestImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..3922a0928e8909cd898c9efad298d5fe9c327353 --- /dev/null +++ b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/application/AudienceSecretRetrieverTestImpl.java @@ -0,0 +1,38 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.application; + +import net.ihe.gazelle.app.audienceretriever.application.AudienceSecretRetriever; + +import java.util.HashMap; +import java.util.Map; + +/** + * Class to test the retriever of the audience secret + */ +public class AudienceSecretRetrieverTestImpl implements AudienceSecretRetriever { + + private Map<String, String> registry = new HashMap<>(); + + /** + * Constructor + */ + public AudienceSecretRetrieverTestImpl() { + } + + /** + * Add a new audience + * + * @param audience String element + * @param secret String element + */ + public void addAudience(String audience, String secret){ + registry.put(audience, secret); + } + + /** + * {@inheritDoc} + */ + @Override + public String retrieveSecretForAudience(String audience) { + return registry.get(audience); + } +} diff --git a/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/application/DummyAuthzServerSoapuiTest.java b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/application/DummyAuthzServerSoapuiTest.java new file mode 100644 index 0000000000000000000000000000000000000000..8f0042970e738ad14662d2393003be6f17cc51c8 --- /dev/null +++ b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/application/DummyAuthzServerSoapuiTest.java @@ -0,0 +1,47 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.application; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +/** + * Class to test the soapui authorization server + */ +class DummyAuthzServerSoapuiTest { + + private static final String SUBJECT = "aamrein"; + private static final String AUDIENCE = "audience"; + + /** + * get access token with an Audience path defined + */ + @Test + public void getAccessTokenWithPathAudienceTest() { + DummyAuthzServerSoapui dummyAuthzServer = new DummyAuthzServerSoapui(); + dummyAuthzServer.setAudienceSecretRetriever((String audience) -> "myBeautifulKeyWhichIsAJWTSecretSoSecret"); + + + assertNotNull(dummyAuthzServer.getAccessToken(SUBJECT, AUDIENCE, null, null), "check that the access token is not null"); + } + + /** + * get access token without an Audience path defined (we keep the default Audience path in this case) + */ + @Test + public void getAccessTokenWithDefaultPathAudienceTest() { + DummyAuthzServerSoapui dummyAuthzServer = new DummyAuthzServerSoapui(); + dummyAuthzServer.setAudienceSecretRetriever((String audience) -> "myBeautifulKeyWhichIsAJWTSecretSoSecret"); + + assertNotNull(dummyAuthzServer.getAccessToken(SUBJECT, AUDIENCE, null, null), "check that the access token is not null"); + } + + /** + * get access token with an invalid audience path provide + */ + @Test + public void getAccessTokenWithBadPathAudienceTest() { + DummyAuthzServerSoapui dummyAuthzServer = new DummyAuthzServerSoapui("test.properties"); + assertNull(dummyAuthzServer.getAccessToken(SUBJECT, AUDIENCE, null, null), "check that the access token is null"); + } +} diff --git a/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/application/TokenGeneratorTest.java b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/application/TokenGeneratorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..702ef7417b58654e9ee408642fcfcc9b81d9292b --- /dev/null +++ b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/application/TokenGeneratorTest.java @@ -0,0 +1,280 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.application; + +import net.ihe.gazelle.app.accesstokenproviderapi.business.AccessTokenRequest; +import net.ihe.gazelle.app.accesstokenproviderapi.business.SymmetricSignature; +import net.ihe.gazelle.modelapi.sb.business.EncodingException; +import net.ihe.gazelle.sb.iua.business.EncodedIUAToken; +import net.ihe.gazelle.sb.iua.business.TokenType; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.time.Duration; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * Tests for {@link TokenGenerator} + */ +class TokenGeneratorTest { + + private static final String ALGORITHM = "HS256"; + private static final String SUBJECT = "aamrein"; + private static final String AUDIENCE = "audience"; + private static final String ISSUER = "https://ehealthsuisse.ihe-europe.net/access-token-provider"; + private static final TokenType TOKEN_TYPE = TokenType.JWT; + private static final Duration DURATION = Duration.ofMinutes(5); + private static AudienceSecretRetrieverTestImpl AUDIENCE_RETRIEVER = new AudienceSecretRetrieverTestImpl(); + + /** + * Init audience available to generate token. + */ + @BeforeEach + public void initAudience() { + AUDIENCE_RETRIEVER.addAudience(AUDIENCE, "myBeautifulKeyWhichIsAJWTSecretSoSecret"); + } + + /** + * Default generation of a token + * + * @throws EncodingException if something wrong happens during encoding + * @throws TokenRequestException if the token request is not valid + */ + @Test + public void generateAccessTokenTest() throws EncodingException, TokenRequestException { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + accessTokenRequest.setSignature(new SymmetricSignature(ALGORITHM, "myBeautifulKeyWhichIsAJWTSecretSoSecret")); + + + TokenGenerator tokenGenerator = new TokenGenerator(); + tokenGenerator.setAudienceSecretRetriever(AUDIENCE_RETRIEVER); + + EncodedIUAToken encodedIUAToken = tokenGenerator.generateAccessToken(accessTokenRequest); + assertNotNull(encodedIUAToken); + } + + /** + * Test with a null signature. + */ + @Test + public void generateAccessTokenNullSignatureTest() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(null, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + accessTokenRequest.setSignature(null); + + + TokenGenerator tokenGenerator = new TokenGenerator(); + tokenGenerator.setAudienceSecretRetriever(AUDIENCE_RETRIEVER); + + assertThrows(TokenRequestException.class, () -> tokenGenerator.generateAccessToken(accessTokenRequest), "Unsupported issuer"); + } + + /** + * Test generating token with unsupported issuer. + */ + @Test + public void generateAccessTokenUnsupportedIssuerTest() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest("blabla", SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + accessTokenRequest.setSignature(new SymmetricSignature(ALGORITHM, "secret")); + + + TokenGenerator tokenGenerator = new TokenGenerator(); + tokenGenerator.setAudienceSecretRetriever(AUDIENCE_RETRIEVER); + + assertThrows(TokenRequestException.class, () -> tokenGenerator.generateAccessToken(accessTokenRequest), "Unsupported issuer"); + } + + /** + * Test generating a token with a null subject. + */ + @Test + public void generateAccessTokenNullIssuerTest() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(null, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + accessTokenRequest.setSignature(new SymmetricSignature(ALGORITHM, "secret")); + + + TokenGenerator tokenGenerator = new TokenGenerator(); + tokenGenerator.setAudienceSecretRetriever(AUDIENCE_RETRIEVER); + + assertThrows(TokenRequestException.class, () -> tokenGenerator.generateAccessToken(accessTokenRequest), "Unsupported issuer"); + } + + /** + * Test generating a token with unsupported subject. + */ + @Test + public void generateAccessTokenUnsupportedSubjectTest() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, "subject", AUDIENCE, DURATION, TOKEN_TYPE); + accessTokenRequest.setSignature(new SymmetricSignature(ALGORITHM, "secret")); + + + TokenGenerator tokenGenerator = new TokenGenerator(); + tokenGenerator.setAudienceSecretRetriever(AUDIENCE_RETRIEVER); + + assertThrows(TokenRequestException.class, () -> tokenGenerator.generateAccessToken(accessTokenRequest), "Unsupported issuer"); + } + + /** + * Test generating a token with null subject. + */ + @Test + public void generateAccessTokenNullSubjectTest() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, null, AUDIENCE, DURATION, TOKEN_TYPE); + accessTokenRequest.setSignature(new SymmetricSignature(ALGORITHM, "secret")); + + + TokenGenerator tokenGenerator = new TokenGenerator(); + tokenGenerator.setAudienceSecretRetriever(AUDIENCE_RETRIEVER); + + assertThrows(TokenRequestException.class, () -> tokenGenerator.generateAccessToken(accessTokenRequest), "Unsupported issuer"); + } + + /** + * Test generating a token with unsupported token type. + */ + @Test + public void generateAccessTokenUnsupportedTokenTypeTest() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TokenType.SAML); + accessTokenRequest.setSignature(new SymmetricSignature(ALGORITHM, "secret")); + + + TokenGenerator tokenGenerator = new TokenGenerator(); + tokenGenerator.setAudienceSecretRetriever(AUDIENCE_RETRIEVER); + + assertThrows(TokenRequestException.class, () -> tokenGenerator.generateAccessToken(accessTokenRequest), "Unsupported issuer"); + } + + /** + * Test generating a token with null token type. + */ + @Test + public void generateAccessTokenNullTokenTypeTest() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, null); + accessTokenRequest.setSignature(new SymmetricSignature(ALGORITHM, "secret")); + + + TokenGenerator tokenGenerator = new TokenGenerator(); + tokenGenerator.setAudienceSecretRetriever(AUDIENCE_RETRIEVER); + + assertThrows(TokenRequestException.class, () -> tokenGenerator.generateAccessToken(accessTokenRequest), "Unsupported issuer"); + } + + /** + * Test generating a token with unsupported algo. + */ + @Test + public void generateAccessTokenUnsupportedAlgoTest() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + accessTokenRequest.setSignature(new SymmetricSignature("algo", "secret")); + + + TokenGenerator tokenGenerator = new TokenGenerator(); + tokenGenerator.setAudienceSecretRetriever(AUDIENCE_RETRIEVER); + + assertThrows(TokenRequestException.class, () -> tokenGenerator.generateAccessToken(accessTokenRequest), "Unsupported issuer"); + } + + /** + * Test generating a token with null algo. + */ + @Test + public void generateAccessTokenNullAlgoTest() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + accessTokenRequest.setSignature(new SymmetricSignature(null, "secret")); + + + TokenGenerator tokenGenerator = new TokenGenerator(); + tokenGenerator.setAudienceSecretRetriever(AUDIENCE_RETRIEVER); + + assertThrows(TokenRequestException.class, () -> tokenGenerator.generateAccessToken(accessTokenRequest), "Unsupported issuer"); + } + + /** + * Test generating a token with null audience. + */ + @Test + public void generateAccessTokenNullAudienceTest() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, null, DURATION, TOKEN_TYPE); + accessTokenRequest.setSignature(new SymmetricSignature(ALGORITHM, "secret")); + + + TokenGenerator tokenGenerator = new TokenGenerator(); + tokenGenerator.setAudienceSecretRetriever(AUDIENCE_RETRIEVER); + + assertThrows(TokenRequestException.class, () -> tokenGenerator.generateAccessToken(accessTokenRequest), "Unsupported issuer"); + } + + /** + * Test generating a token with unsupported audience. + */ + @Test + public void generateAccessTokenUnknownAudienceTest() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, "pouet", DURATION, TOKEN_TYPE); + accessTokenRequest.setSignature(new SymmetricSignature(ALGORITHM, "secret")); + + + TokenGenerator tokenGenerator = new TokenGenerator(); + tokenGenerator.setAudienceSecretRetriever(AUDIENCE_RETRIEVER); + + assertThrows(TokenRequestException.class, () -> tokenGenerator.generateAccessToken(accessTokenRequest), "Unsupported issuer"); + } + + /** + * Test generating a token with empty audience. + */ + @Test + public void generateAccessTokenEmptyAudienceTest() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, "", DURATION, TOKEN_TYPE); + accessTokenRequest.setSignature(new SymmetricSignature(ALGORITHM, "secret")); + + + TokenGenerator tokenGenerator = new TokenGenerator(); + tokenGenerator.setAudienceSecretRetriever(AUDIENCE_RETRIEVER); + + assertThrows(TokenRequestException.class, () -> tokenGenerator.generateAccessToken(accessTokenRequest), "Unsupported issuer"); + } + + /** + * Test generating a token with empty secret. + */ + @Test + public void generateAccessTokenEmptySecretTest() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, "pouet", DURATION, TOKEN_TYPE); + accessTokenRequest.setSignature(new SymmetricSignature(ALGORITHM, "secret")); + + + TokenGenerator tokenGenerator = new TokenGenerator(); + tokenGenerator.setAudienceSecretRetriever(audience -> ""); + + assertThrows(TokenRequestException.class, () -> tokenGenerator.generateAccessToken(accessTokenRequest), "Unsupported issuer"); + } + + /** + * Test generating a token with null secret. + */ + @Test + public void generateAccessTokenNullSecretTest() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, "pouet", DURATION, TOKEN_TYPE); + accessTokenRequest.setSignature(new SymmetricSignature(ALGORITHM, "secret")); + + + TokenGenerator tokenGenerator = new TokenGenerator(); + tokenGenerator.setAudienceSecretRetriever(audience -> null); + + assertThrows(TokenRequestException.class, () -> tokenGenerator.generateAccessToken(accessTokenRequest), "Unsupported issuer"); + } + + /** + * Test generating a token with null Duration. + */ + @Test + public void generateAccessTokenDurationNullTest() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, "pouet", null, TOKEN_TYPE); + accessTokenRequest.setSignature(new SymmetricSignature(ALGORITHM, "secret")); + + + TokenGenerator tokenGenerator = new TokenGenerator(); + tokenGenerator.setAudienceSecretRetriever(audience -> null); + + assertThrows(TokenRequestException.class, () -> tokenGenerator.generateAccessToken(accessTokenRequest), "Unsupported issuer"); + } +} diff --git a/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/AccessTokenExtensionTest.java b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/AccessTokenExtensionTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c0bfb297bb2a588776d32b2456581d710afa704f --- /dev/null +++ b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/AccessTokenExtensionTest.java @@ -0,0 +1,305 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.business; + +import net.ihe.gazelle.lib.annotations.Covers; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class AccessTokenExtensionTest { + + /** + * Test subjectId getter and setter. + */ + @Test + @Covers(requirements = "TOKENPROV-012") + void getSetSubjectId(){ + String subjectId = "id"; + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.setSubjectId(subjectId); + assertEquals(subjectId, accessTokenExtension.getSubjectId(), "Getter shall return the value of subjectId !"); + } + + /** + * Test addSubjectOrganization and removeSubjectOrganization. + */ + @Test + @Covers(requirements = "TOKENPROV-013") + void subjectOrganization(){ + String orga1 = "orga1"; + String orga2 = "orga2"; + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.addSubjectOrganization(orga1); + assertEquals(1, accessTokenExtension.getSubjectOrganizations().size()); + accessTokenExtension.addSubjectOrganization(orga2); + assertEquals(2, accessTokenExtension.getSubjectOrganizations().size()); + accessTokenExtension.removeSubjectOrganization(orga1); + assertEquals(1, accessTokenExtension.getSubjectOrganizations().size()); + assertEquals(orga2, accessTokenExtension.getSubjectOrganizations().get(0)); + } + + /** + * Test addSubjectOrganizationId and removeSubjectOrganizationId. + */ + @Test + @Covers(requirements = "TOKENPROV-014") + void subjectOrganizationId(){ + String orgaId1 = "orgaId1"; + String orgaId2 = "orgaId2"; + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.addSubjectOrganizationId(orgaId1); + assertEquals(1, accessTokenExtension.getSubjectOrganizationIds().size()); + accessTokenExtension.addSubjectOrganizationId(orgaId2); + assertEquals(2, accessTokenExtension.getSubjectOrganizationIds().size()); + accessTokenExtension.removeSubjectOrganizationId(orgaId1); + assertEquals(1, accessTokenExtension.getSubjectOrganizationIds().size()); + assertEquals(orgaId2, accessTokenExtension.getSubjectOrganizationIds().get(0)); + } + + /** + * Test subjectId getter and setter. + */ + @Test + @Covers(requirements = "TOKENPROV-015") + void homeCommunityId(){ + String homeCommunityId = "id"; + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.setHomeCommunityId(homeCommunityId); + assertEquals(homeCommunityId, accessTokenExtension.getHomeCommunityId()); + } + + /** + * Test subjectId getter and setter. + */ + @Test + @Covers(requirements = "TOKENPROV-016") + void nationalProviderIdentifier(){ + String nationalProviderIdentifier = "id"; + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.setNationalProviderIdentifier(nationalProviderIdentifier); + assertEquals(nationalProviderIdentifier, accessTokenExtension.getNationalProviderIdentifier()); + } + + /** + * Test addProviderId and removeProviderId. + */ + @Test + @Covers(requirements = "TOKENPROV-017") + void providerId(){ + String providerId1 = "provId1"; + String providerId2 = "provId2"; + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.addProviderId(providerId1); + assertEquals(1, accessTokenExtension.getProviderIds().size()); + accessTokenExtension.addProviderId(providerId2); + assertEquals(2, accessTokenExtension.getProviderIds().size()); + accessTokenExtension.removeProviderId(providerId1); + assertEquals(1, accessTokenExtension.getProviderIds().size()); + assertEquals(providerId2, accessTokenExtension.getProviderIds().get(0)); + } + + /** + * Test subjectRole getter and setter. + */ + @Test + @Covers(requirements = "TOKENPROV-018") + void subjectRole(){ + CodedValue codedValue = new CodedValue("a", "b"); + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.setSubjectRole(codedValue); + assertEquals(codedValue, accessTokenExtension.getSubjectRole()); + } + + /** + * Test purposeOfUse getter and setter. + */ + @Test + @Covers(requirements = "TOKENPROV-019") + void purposeOfUse(){ + CodedValue codedValue = new CodedValue("a", "b"); + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.setPurposeOfUse(codedValue); + assertEquals(codedValue, accessTokenExtension.getPurposeOfUse()); + } + + /** + * Test resourceId getter and setter. + */ + @Test + @Covers(requirements = "TOKENPROV-020") + void resourceId(){ + String resourceId = "id"; + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.setResourceId(resourceId); + assertEquals(resourceId, accessTokenExtension.getResourceId()); + } + + /** + * Test onBehalfOf getter and setter. + */ + @Test + @Covers(requirements = "TOKENPROV-021") + void onBehalfOf(){ + String onBehalfOf = "toto"; + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.setOnBehalfOf(onBehalfOf); + assertEquals(onBehalfOf, accessTokenExtension.getOnBehalfOf()); + } + + /** + * Test equals with null. + */ + @Test + void equalsNull() { + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + assertFalse(accessTokenExtension.equals(null), "Object shall not be equal to null !"); + } + + /** + * Test equals with itself. + */ + @Test + void equalsItself() { + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + assertTrue(accessTokenExtension.equals(accessTokenExtension), "Object shall be equal to itself !"); + } + + /** + * Test equals with another class instance. + */ + @Test + void equalsOtherClass() { + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + assertFalse(accessTokenExtension.equals(34), "Object shall not be equal to an instance of another class !"); + } + + /** + * Test equals with different subjectId + */ + @Test + void equalsDifferentSubjectId() { + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.setSubjectId("1"); + AccessTokenExtension accessTokenExtension2 = new AccessTokenExtension(); + accessTokenExtension.setSubjectId("2"); + assertFalse(accessTokenExtension.equals(accessTokenExtension2), "Objects shall not be equal if they have different subjectId !"); + } + + /** + * Test equals with different subjectOrganization + */ + @Test + void equalsDifferentSubjectOrganization() { + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.addSubjectOrganization("1"); + AccessTokenExtension accessTokenExtension2 = new AccessTokenExtension(); + accessTokenExtension.addSubjectOrganization("2"); + assertFalse(accessTokenExtension.equals(accessTokenExtension2), "Objects shall not be equal if they have different subjectOrganization !"); + } + + /** + * Test equals with different subjectOrganizationId + */ + @Test + void equalsDifferentSubjectOrganizationId() { + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.addSubjectOrganizationId("1"); + AccessTokenExtension accessTokenExtension2 = new AccessTokenExtension(); + accessTokenExtension.addSubjectOrganizationId("2"); + assertFalse(accessTokenExtension.equals(accessTokenExtension2), "Objects shall not be equal if they have different subjectOrganizationId !"); + } + + /** + * Test equals with different homeCommunityId + */ + @Test + void equalsDifferentHomeCommunityId() { + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.setHomeCommunityId("1"); + AccessTokenExtension accessTokenExtension2 = new AccessTokenExtension(); + accessTokenExtension.setHomeCommunityId("2"); + assertFalse(accessTokenExtension.equals(accessTokenExtension2), "Objects shall not be equal if they have different homeCommunityId !"); + } + + /** + * Test equals with different nationalProviderIdentifier + */ + @Test + void equalsDifferentNationalProviderIdentifier() { + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.setNationalProviderIdentifier("1"); + AccessTokenExtension accessTokenExtension2 = new AccessTokenExtension(); + accessTokenExtension.setNationalProviderIdentifier("2"); + assertFalse(accessTokenExtension.equals(accessTokenExtension2), "Objects shall not be equal if they have different nationalProviderIdentifier !"); + } + + /** + * Test equals with different providerId + */ + @Test + void equalsDifferentProviderId() { + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.addProviderId("1"); + AccessTokenExtension accessTokenExtension2 = new AccessTokenExtension(); + accessTokenExtension.addProviderId("2"); + assertFalse(accessTokenExtension.equals(accessTokenExtension2), "Objects shall not be equal if they have different providerId !"); + } + + /** + * Test equals with different purposeOfUse + */ + @Test + void equalsDifferentPurposeOfUse() { + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.setPurposeOfUse(new CodedValue("1", "1")); + AccessTokenExtension accessTokenExtension2 = new AccessTokenExtension(); + accessTokenExtension.setPurposeOfUse(new CodedValue("2", "2")); + assertFalse(accessTokenExtension.equals(accessTokenExtension2), "Objects shall not be equal if they have different purposeOfUse !"); + } + + /** + * Test equals with different subjectRole + */ + @Test + void equalsDifferentSubjectRole() { + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.setSubjectRole(new CodedValue("1", "1")); + AccessTokenExtension accessTokenExtension2 = new AccessTokenExtension(); + accessTokenExtension.setSubjectRole(new CodedValue("2", "2")); + assertFalse(accessTokenExtension.equals(accessTokenExtension2), "Objects shall not be equal if they have different subjectRole !"); + } + + /** + * Test equals with different resourceId + */ + @Test + void equalsDifferentResourceId() { + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.setResourceId("1"); + AccessTokenExtension accessTokenExtension2 = new AccessTokenExtension(); + accessTokenExtension.setResourceId("2"); + assertFalse(accessTokenExtension.equals(accessTokenExtension2), "Objects shall not be equal if they have different resourceId !"); + } + + /** + * Test equals with different onBehalfOf + */ + @Test + void equalsDifferentOnBehalfOf() { + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + accessTokenExtension.setOnBehalfOf("1"); + AccessTokenExtension accessTokenExtension2 = new AccessTokenExtension(); + accessTokenExtension.setOnBehalfOf("2"); + assertFalse(accessTokenExtension.equals(accessTokenExtension2), "Objects shall not be equal if they have different onBehalfOf !"); + } + + /** + * Test for the hashcode method + */ + @Test + void testHashCode() { + AccessTokenExtension accessTokenExtension = new AccessTokenExtension(); + assertNotNull(accessTokenExtension.hashCode(), "Generated hashCode shall not be null !"); + } + + +} diff --git a/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/AccessTokenRequestTest.java b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/AccessTokenRequestTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7737a96d937f1941f9755de6cdc346646bd80188 --- /dev/null +++ b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/AccessTokenRequestTest.java @@ -0,0 +1,206 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.business; + +import net.ihe.gazelle.lib.annotations.Covers; +import net.ihe.gazelle.sb.iua.business.TokenType; +import org.junit.jupiter.api.Test; + +import java.time.Duration; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class AccessTokenRequestTest { + + private static final String ISSUER = "issuer"; + private static final String SUBJECT = "subject"; + private static final String AUDIENCE = "audience"; + private static final Duration DURATION = Duration.ofMinutes(1); + private static final TokenType TOKEN_TYPE = TokenType.JWT; + private static final SymmetricSignature SIGNATURE = new SymmetricSignature("RSALALA", "SECRET"); + private static final AccessTokenExtension EXTENSION = new AccessTokenExtension(); + + + /** + * Test issuer getter. + */ + @Test + @Covers(requirements = "TOKENPROV-001") + void getIssuer() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + assertEquals(ISSUER, accessTokenRequest.getIssuer(), "Getter shall return the value of issuer !"); + } + + /** + * Test subject getter. + */ + @Test + @Covers(requirements = "TOKENPROV-002") + void getSubject() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + assertEquals(SUBJECT, accessTokenRequest.getSubject(), "Getter shall return the value of subject !"); + } + + /** + * Test audience getter. + */ + @Test + @Covers(requirements = "TOKENPROV-003") + void getAudience() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + assertEquals(AUDIENCE, accessTokenRequest.getAudience(), "Getter shall return the value of audience !"); + } + + /** + * Test validityTime getter. + */ + @Test + @Covers(requirements = "TOKENPROV-004") + void getValidityTime() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + assertEquals(DURATION, accessTokenRequest.getValidityTime(), "Getter shall return the value of validityTime !"); + } + + /** + * Test tokenType getter. + */ + @Test + @Covers(requirements = "TOKENPROV-007") + void getTokenType() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + assertEquals(TOKEN_TYPE, accessTokenRequest.getTokenType(), "Getter shall return the value of tokenType !"); + } + + /** + * Test signature getter and setter. + */ + @Test + @Covers(requirements = "TOKENPROV-005") + void signature() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + accessTokenRequest.setSignature(SIGNATURE); + assertEquals(SIGNATURE, accessTokenRequest.getSignature(), "Setter shall change the value of signature !"); + } + + /** + * Test extension getter and setter. + */ + @Test + @Covers(requirements = "TOKENPROV-005") + void extension() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + accessTokenRequest.setExtension(EXTENSION); + assertEquals(EXTENSION, accessTokenRequest.getExtension(), "Setter shall change the value of extension !"); + } + + /** + * Test equals with null. + */ + @Test + void equalsNull() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + assertFalse(accessTokenRequest.equals(null), "Object shall not be equal to null !"); + } + + /** + * Test equals with itself. + */ + @Test + void equalsItself() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + assertTrue(accessTokenRequest.equals(accessTokenRequest), "Object shall be equal to itself !"); + } + + /** + * Test equals with another class instance. + */ + @Test + void equalsOtherClass() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + assertFalse(accessTokenRequest.equals(34), "Object shall not be equal to an instance of another class !"); + } + + /** + * Test equals with different issuer + */ + @Test + void equalsDifferentIssuer() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + AccessTokenRequest accessTokenRequest2 = new AccessTokenRequest("ISSUER2", SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + assertFalse(accessTokenRequest.equals(accessTokenRequest2), "Objects shall not be equal if they have different issuer !"); + } + + /** + * Test equals with different subject + */ + @Test + void equalsDifferentSubject() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + AccessTokenRequest accessTokenRequest2 = new AccessTokenRequest(ISSUER, "SUBJECT2", AUDIENCE, DURATION, TOKEN_TYPE); + assertFalse(accessTokenRequest.equals(accessTokenRequest2), "Objects shall not be equal if they have different subject !"); + } + + /** + * Test equals with different audience + */ + @Test + void equalsDifferentAudience() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + AccessTokenRequest accessTokenRequest2 = new AccessTokenRequest(ISSUER, SUBJECT, "AUDIENCE2", DURATION, TOKEN_TYPE); + assertFalse(accessTokenRequest.equals(accessTokenRequest2), "Objects shall not be equal if they have different audience !"); + } + + /** + * Test equals with different validityTime + */ + @Test + void equalsDifferentValidityTime() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + AccessTokenRequest accessTokenRequest2 = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, Duration.ofDays(3), TOKEN_TYPE); + assertFalse(accessTokenRequest.equals(accessTokenRequest2), "Objects shall not be equal if they have different validityTime !"); + } + + /** + * Test equals with different tokenType + */ + @Test + void equalsDifferentTokenType() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + AccessTokenRequest accessTokenRequest2 = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TokenType.SAML); + assertFalse(accessTokenRequest.equals(accessTokenRequest2), "Objects shall not be equal if they have different tokenType !"); + } + + /** + * Test equals with different signature + */ + @Test + void equalsDifferentSignature() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + AccessTokenRequest accessTokenRequest2 = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + accessTokenRequest2.setSignature(new SymmetricSignature("RSA", "secret")); + assertFalse(accessTokenRequest.equals(accessTokenRequest2), "Objects shall not be equal if they have different signature !"); + } + + /** + * Test equals with different extension + */ + @Test + void equalsDifferentExtension() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + AccessTokenRequest accessTokenRequest2 = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + accessTokenRequest2.setExtension(new AccessTokenExtension()); + assertFalse(accessTokenRequest.equals(accessTokenRequest2), "Objects shall not be equal if they have different extension !"); + } + + /** + * Test for the hashcode method + */ + @Test + void testHashCode() { + AccessTokenRequest accessTokenRequest = new AccessTokenRequest(ISSUER, SUBJECT, AUDIENCE, DURATION, TOKEN_TYPE); + assertNotNull(accessTokenRequest.hashCode(), "Generated hashCode shall not be null !"); + } + + +} diff --git a/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/AsymmetricSignatureTest.java b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/AsymmetricSignatureTest.java new file mode 100644 index 0000000000000000000000000000000000000000..835451669733a76f7bbfa6bf325d8f7212ae3217 --- /dev/null +++ b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/AsymmetricSignatureTest.java @@ -0,0 +1,101 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.business; + +import net.ihe.gazelle.lib.annotations.Covers; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class AsymmetricSignatureTest { + + private static final byte[] KEY = "key".getBytes(); + private static final String PASSWORD = "password"; + private static final String ALGORITHM = "RSAPOUETPOUET"; + + /** + * Test privateKey getter. + */ + @Test + @Covers(requirements = "TOKENPROV-010") + void getPrivateKey(){ + AsymmetricSignature signature = new AsymmetricSignature(ALGORITHM, KEY, PASSWORD); + assertArrayEquals(KEY, signature.getPrivateKey(), "Getter shall return the value of privateKey !"); + } + + /** + * Test privateKeyPassword getter. + */ + @Test + @Covers(requirements = "TOKENPROV-011") + void getPrivateKeyPassword(){ + AsymmetricSignature signature = new AsymmetricSignature(ALGORITHM, KEY, PASSWORD); + assertEquals(PASSWORD, signature.getPrivateKeyPassword(), "Getter shall return the value of privateKeyPassword !"); + } + + /** + * Test equals with null. + */ + @Test + void equalsNull() { + AsymmetricSignature signature = new AsymmetricSignature(ALGORITHM, KEY, PASSWORD); + assertFalse(signature.equals(null), "Object shall not be equal to null !"); + } + + /** + * Test equals with itself. + */ + @Test + void equalsItself() { + AsymmetricSignature signature = new AsymmetricSignature(ALGORITHM, KEY, PASSWORD); + assertTrue(signature.equals(signature), "Object shall be equal to itself !"); + } + + /** + * Test equals with another class instance. + */ + @Test + void equalsOtherClass() { + AsymmetricSignature signature = new AsymmetricSignature(ALGORITHM, KEY, PASSWORD); + assertFalse(signature.equals(34), "Object shall not be equal to an instance of another class !"); + } + + /** + * Test equals with different algorithm + */ + @Test + void equalsDifferentAlgorithm() { + AsymmetricSignature signature = new AsymmetricSignature(ALGORITHM, KEY, PASSWORD); + AsymmetricSignature signature2 = new AsymmetricSignature("ALGORITHM", KEY, PASSWORD); + assertFalse(signature.equals(signature2), "Objects shall not be equal if they have different algorithm !"); + } + + /** + * Test equals with different privateKey + */ + @Test + void equalsDifferentPrivateKey() { + AsymmetricSignature signature = new AsymmetricSignature(ALGORITHM, KEY, PASSWORD); + AsymmetricSignature signature2 = new AsymmetricSignature(ALGORITHM, "KEY".getBytes(), PASSWORD); + assertFalse(signature.equals(signature2), "Objects shall not be equal if they have different privateKey !"); + } + + /** + * Test equals with different privateKeyPassword + */ + @Test + void equalsDifferentPrivateKeyPassword() { + AsymmetricSignature signature = new AsymmetricSignature(ALGORITHM, KEY, PASSWORD); + AsymmetricSignature signature2 = new AsymmetricSignature(ALGORITHM, KEY, "PASSWORD"); + assertFalse(signature.equals(signature2), "Objects shall not be equal if they have different privateKeyPassword !"); + } + + /** + * Test for the hashcode method + */ + @Test + void testHashCode() { + AsymmetricSignature signature = new AsymmetricSignature(ALGORITHM, KEY, PASSWORD); + assertNotNull(signature.hashCode(), "Generated hashCode shall not be null !"); + } + + +} diff --git a/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/CodedValueTest.java b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/CodedValueTest.java new file mode 100644 index 0000000000000000000000000000000000000000..1125c461192b6d9bf167b0b3df242a2ccfa6c1bf --- /dev/null +++ b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/CodedValueTest.java @@ -0,0 +1,52 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.business; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class CodedValueTest { + + private static final String CODE = "100000007"; + private static final String CODE_SYSTEM = "2.16.840.1.113883.3.3478.6.1"; + private static final String CODE_SYSTEM_NAME = "ACC-Internal"; + private static final String DISPLAY_NAME = "Hematoma Size"; + + /** + * Test code getter. + */ + @Test + void getCode(){ + CodedValue codedValue = new CodedValue(CODE, CODE_SYSTEM); + assertEquals(CODE, codedValue.getCode(), "Getter shall return the value of code !"); + } + + /** + * Test codeSystem getter. + */ + @Test + void getCodeSystem(){ + CodedValue codedValue = new CodedValue(CODE, CODE_SYSTEM); + assertEquals(CODE_SYSTEM, codedValue.getCodeSystem(), "Getter shall return the value of codeSystem !"); + } + + /** + * Test codeSystemName getter and setter. + */ + @Test + void codeSystemName(){ + CodedValue codedValue = new CodedValue(CODE, CODE_SYSTEM); + codedValue.setCodeSystemName(CODE_SYSTEM_NAME); + assertEquals(CODE_SYSTEM_NAME, codedValue.getCodeSystemName()); + } + + /** + * Test displayName getter and setter. + */ + @Test + void codeDisplayName(){ + CodedValue codedValue = new CodedValue(CODE, CODE_SYSTEM); + codedValue.setDisplayName(DISPLAY_NAME); + assertEquals(DISPLAY_NAME, codedValue.getDisplayName()); + } + +} diff --git a/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/PasswordTest.java b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/PasswordTest.java new file mode 100644 index 0000000000000000000000000000000000000000..67e84278a58ee28999f69e64f3e2f806c87db3e2 --- /dev/null +++ b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/PasswordTest.java @@ -0,0 +1,68 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.business; + +import net.ihe.gazelle.lib.annotations.Covers; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class PasswordTest { + + private static final byte[] VALUE = "value".getBytes(); + + /** + * Test value getter. + */ + @Test + @Covers(requirements = "TOKENPROV-031") + void getKey() { + Password publicKey = new Password(VALUE); + assertArrayEquals(VALUE, publicKey.getValue(), "Getter shall return the value of value !"); + } + + /** + * Test equals with null. + */ + @Test + void equalsNull() { + Password publicKey = new Password(VALUE); + assertFalse(publicKey.equals(null), "Object shall not be equal to null !"); + } + + /** + * Test equals with itself. + */ + @Test + void equalsItself() { + Password publicKey = new Password(VALUE); + assertTrue(publicKey.equals(publicKey), "Object shall be equal to itself !"); + } + + /** + * Test equals with another class instance. + */ + @Test + void equalsOtherClass() { + Password publicKey = new Password(VALUE); + assertFalse(publicKey.equals(34), "Object shall not be equal to an instance of another class !"); + } + + /** + * Test equals with different issuer + */ + @Test + void equalsDifferentIssuer() { + Password publicKey = new Password(VALUE); + Password publicKey2 = new Password("VALUE".getBytes()); + assertFalse(publicKey.equals(publicKey2), "Objects shall not be equal if they have different issuer !"); + } + + /** + * Test for the hashcode method + */ + @Test + void testHashCode() { + Password publicKey = new Password(VALUE); + assertNotNull(publicKey.hashCode(), "Generated hashCode shall not be null !"); + } + +} diff --git a/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/PublicKeyTest.java b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/PublicKeyTest.java new file mode 100644 index 0000000000000000000000000000000000000000..eb7796fabb03236d4b6681024876cd31e3ae7e79 --- /dev/null +++ b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/PublicKeyTest.java @@ -0,0 +1,68 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.business; + +import net.ihe.gazelle.lib.annotations.Covers; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class PublicKeyTest { + + private static final byte[] KEY = "key".getBytes(); + + /** + * Test key getter. + */ + @Test + @Covers(requirements = "TOKENPROV-031") + void getKey() { + PublicKey publicKey = new PublicKey(KEY); + assertArrayEquals(KEY, publicKey.getKey(), "Getter shall return the value of key !"); + } + + /** + * Test equals with null. + */ + @Test + void equalsNull() { + PublicKey publicKey = new PublicKey(KEY); + assertFalse(publicKey.equals(null), "Object shall not be equal to null !"); + } + + /** + * Test equals with itself. + */ + @Test + void equalsItself() { + PublicKey publicKey = new PublicKey(KEY); + assertTrue(publicKey.equals(publicKey), "Object shall be equal to itself !"); + } + + /** + * Test equals with another class instance. + */ + @Test + void equalsOtherClass() { + PublicKey publicKey = new PublicKey(KEY); + assertFalse(publicKey.equals(34), "Object shall not be equal to an instance of another class !"); + } + + /** + * Test equals with different issuer + */ + @Test + void equalsDifferentIssuer() { + PublicKey publicKey = new PublicKey(KEY); + PublicKey publicKey2 = new PublicKey("KEY".getBytes()); + assertFalse(publicKey.equals(publicKey2), "Objects shall not be equal if they have different issuer !"); + } + + /** + * Test for the hashcode method + */ + @Test + void testHashCode() { + PublicKey publicKey = new PublicKey(KEY); + assertNotNull(publicKey.hashCode(), "Generated hashCode shall not be null !"); + } + +} diff --git a/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/SignatureTest.java b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/SignatureTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3c69fe304d0f4b4d3bc252c020086b5c0632f964 --- /dev/null +++ b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/SignatureTest.java @@ -0,0 +1,31 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.business; + +import net.ihe.gazelle.lib.annotations.Covers; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class SignatureTest { + + private static final String ALGORITHM = "RSAPOUETPOUET"; + + /** + * Test algorithm getter. + */ + @Test + @Covers(requirements = "TOKENPROV-008") + void getAlgorithm(){ + Signature signature = new Signature(ALGORITHM) {}; + assertEquals(ALGORITHM, signature.getAlgorithm(), "Getter shall return the value of algorithm !"); + } + + /** + * Test for the hashcode method + */ + @Test + void testHashCode() { + Signature signature = new Signature(ALGORITHM) {}; + assertNotNull(signature.hashCode(), "Generated hashCode shall not be null !"); + } + +} diff --git a/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/SymmetricSignatureTest.java b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/SymmetricSignatureTest.java new file mode 100644 index 0000000000000000000000000000000000000000..4d42a0631d338bc7eb018cbe436fd4810dada4bb --- /dev/null +++ b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/SymmetricSignatureTest.java @@ -0,0 +1,82 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.business; + +import net.ihe.gazelle.lib.annotations.Covers; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class SymmetricSignatureTest { + + private static final String ALGO = "RSAPOUETPOUET"; + private static final String SECRET = "PSST"; + + /** + * Test privateKey getter. + */ + @Test + @Covers(requirements = "TOKENPROV-009") + void getPrivateKey() { + SymmetricSignature signature = new SymmetricSignature(ALGO, SECRET); + assertEquals(SECRET, signature.getSecret(), "Getter shall return the value of privateKey !"); + } + + /** + * Test equals with null. + */ + @Test + void equalsNull() { + SymmetricSignature signature = new SymmetricSignature(ALGO, SECRET); + assertFalse(signature.equals(null), "Object shall not be equal to null !"); + } + + /** + * Test equals with itself. + */ + @Test + void equalsItself() { + SymmetricSignature signature = new SymmetricSignature(ALGO, SECRET); + assertTrue(signature.equals(signature), "Object shall be equal to itself !"); + } + + /** + * Test equals with another class instance. + */ + @Test + void equalsOtherClass() { + SymmetricSignature signature = new SymmetricSignature(ALGO, SECRET); + assertFalse(signature.equals(34), "Object shall not be equal to an instance of another class !"); + } + + /** + * Test equals with different algorithm + */ + @Test + void equalsDifferentAlgorithm() { + SymmetricSignature signature = new SymmetricSignature(ALGO, SECRET); + SymmetricSignature signature2 = new SymmetricSignature("ALGO", SECRET); + assertFalse(signature.equals(signature2), "Objects shall not be equal if they have different algorithm !"); + } + + /** + * Test equals with different secret + */ + @Test + void equalsDifferentSecret() { + SymmetricSignature signature = new SymmetricSignature(ALGO, SECRET); + SymmetricSignature signature2 = new SymmetricSignature(ALGO, "SECRET"); + assertFalse(signature.equals(signature2), "Objects shall not be equal if they have different secret !"); + } + + /** + * Test for the hashcode method + */ + @Test + void testHashCode() { + SymmetricSignature signature = new SymmetricSignature(ALGO, SECRET); + assertNotNull(signature.hashCode(), "Generated hashCode shall not be null !"); + } + +} diff --git a/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/testuser/TestUserTest.java b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/testuser/TestUserTest.java new file mode 100644 index 0000000000000000000000000000000000000000..5b4ee79d9a2a0383410c9b2c3977c172ca1550c3 --- /dev/null +++ b/access-token-provider-api/src/test/java/net/ihe/gazelle/app/accesstokenproviderapi/business/testuser/TestUserTest.java @@ -0,0 +1,229 @@ +package net.ihe.gazelle.app.accesstokenproviderapi.business.testuser; + +import net.ihe.gazelle.lib.annotations.Covers; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class TestUserTest { + + private static final String USER_ID = "id"; + private static final String GIVEN_NAME = "given"; + private static final String LAST_NAME = "lastName"; + private static final Date BIRTH_DATE = new Date(); + private static final String GENDER = "gender"; + + /** + * Test userId getter. + */ + @Test + @Covers(requirements = "TOKENPROV-023") + void getUserId() { + List<String> givenNames = new ArrayList<>(); + givenNames.add(GIVEN_NAME); + TestUser testUser = new TestUser(USER_ID, givenNames, LAST_NAME); + assertEquals(USER_ID, testUser.getUserId(), "Getter shall return the value of userId !"); + } + + /** + * Test givenNames getter. + */ + @Test + @Covers(requirements = "TOKENPROV-024") + void getGivenNames() { + List<String> givenNames = new ArrayList<>(); + givenNames.add(GIVEN_NAME); + TestUser testUser = new TestUser(USER_ID, givenNames, LAST_NAME); + assertEquals(givenNames, testUser.getGivenNames(), "Getter shall return the value of givenNames !"); + } + + /** + * Test lastName getter. + */ + @Test + @Covers(requirements = "TOKENPROV-025") + void getlastName() { + List<String> givenNames = new ArrayList<>(); + givenNames.add(GIVEN_NAME); + TestUser testUser = new TestUser(USER_ID, givenNames, LAST_NAME); + assertEquals(LAST_NAME, testUser.getLastName(), "Getter shall return the value of lastName !"); + } + + /** + * Test birthDate getter. + */ + @Test + @Covers(requirements = "TOKENPROV-026") + void birthDate() { + List<String> givenNames = new ArrayList<>(); + givenNames.add(GIVEN_NAME); + TestUser testUser = new TestUser(USER_ID, givenNames, LAST_NAME); + testUser.setBirthDate(BIRTH_DATE); + assertEquals(BIRTH_DATE, testUser.getBirthDate(), "Getter shall return the value of birthDate !"); + } + + /** + * Test birthDate getter. + */ + @Test + @Covers(requirements = "TOKENPROV-027") + void gender() { + List<String> givenNames = new ArrayList<>(); + givenNames.add(GIVEN_NAME); + TestUser testUser = new TestUser(USER_ID, givenNames, LAST_NAME); + testUser.setGender(GENDER); + assertEquals(GENDER, testUser.getGender(), "Getter shall return the value of gender !"); + } + + /** + * Test addExtension and removeExtension. + */ + @Test + @Covers(requirements = "TOKENPROV-028") + void addExtension() { + List<String> givenNames = new ArrayList<>(); + givenNames.add(GIVEN_NAME); + TestUser testUser = new TestUser(USER_ID, givenNames, LAST_NAME); + testUser.addExtension("key1", "value1"); + assertEquals(1, testUser.getExtensions().size()); + testUser.addExtension("key2", "value2"); + assertEquals(2, testUser.getExtensions().size()); + testUser.removeExtension("key1"); + assertEquals(1, testUser.getExtensions().size()); + assertEquals("value2", testUser.getExtensions().get("key2")); + } + + /** + * Test equals with null. + */ + @Test + void equalsNull() { + List<String> givenNames = new ArrayList<>(); + givenNames.add(GIVEN_NAME); + TestUser testUser = new TestUser(USER_ID, givenNames, LAST_NAME); + assertFalse(testUser.equals(null), "Object shall not be equal to null !"); + } + + /** + * Test equals with itself. + */ + @Test + void equalsItself() { + List<String> givenNames = new ArrayList<>(); + givenNames.add(GIVEN_NAME); + TestUser testUser = new TestUser(USER_ID, givenNames, LAST_NAME); + assertTrue(testUser.equals(testUser), "Object shall be equal to itself !"); + } + + /** + * Test equals with another class instance. + */ + @Test + void equalsOtherClass() { + List<String> givenNames = new ArrayList<>(); + givenNames.add(GIVEN_NAME); + TestUser testUser = new TestUser(USER_ID, givenNames, LAST_NAME); + assertFalse(testUser.equals(34), "Object shall not be equal to an instance of another class !"); + } + + /** + * Test equals with different issuerId + */ + @Test + void equalsDifferentUserID() { + List<String> givenNames = new ArrayList<>(); + givenNames.add(GIVEN_NAME); + TestUser testUser = new TestUser(USER_ID, givenNames, LAST_NAME); + TestUser testUser2 = new TestUser("USER_ID", givenNames, LAST_NAME); + assertFalse(testUser.equals(testUser2), "Objects shall not be equal if they have different issuerId !"); + } + + /** + * Test equals with different givenNames + */ + @Test + void equalsDifferentGivenNames() { + List<String> givenNames = new ArrayList<>(); + givenNames.add(GIVEN_NAME); + TestUser testUser = new TestUser(USER_ID, givenNames, LAST_NAME); + List<String> givenNames2 = new ArrayList<>(); + givenNames2.add("given2"); + TestUser testUser2 = new TestUser(USER_ID, givenNames2, LAST_NAME); + assertFalse(testUser.equals(testUser2), "Objects shall not be equal if they have different givenNames !"); + } + + + /** + * Test equals with different lastName + */ + @Test + void equalsDifferentLastName() { + List<String> givenNames = new ArrayList<>(); + givenNames.add(GIVEN_NAME); + TestUser testUser = new TestUser(USER_ID, givenNames, LAST_NAME); + TestUser testUser2 = new TestUser(USER_ID, givenNames, "LAST_NAME"); + assertFalse(testUser.equals(testUser2), "Objects shall not be equal if they have different lastName !"); + } + + /** + * Test equals with different birthName + */ + @Test + void equalsDifferentBirthName() { + List<String> givenNames = new ArrayList<>(); + givenNames.add(GIVEN_NAME); + TestUser testUser = new TestUser(USER_ID, givenNames, LAST_NAME); + testUser.setBirthDate(BIRTH_DATE); + TestUser testUser2 = new TestUser(USER_ID, givenNames, LAST_NAME); + testUser2.setBirthDate(new Date()); + assertFalse(testUser.equals(testUser2), "Objects shall not be equal if they have different birthName !"); + } + + /** + * Test equals with different gender + */ + @Test + void equalsDifferentGender() { + List<String> givenNames = new ArrayList<>(); + givenNames.add(GIVEN_NAME); + TestUser testUser = new TestUser(USER_ID, givenNames, LAST_NAME); + testUser.setGender(GENDER); + TestUser testUser2 = new TestUser(USER_ID, givenNames, LAST_NAME); + testUser.setGender("GENDER"); + assertFalse(testUser.equals(testUser2), "Objects shall not be equal if they have different gender !"); + } + + /** + * Test equals with different extensions + */ + @Test + void equalsDifferentExtensions() { + List<String> givenNames = new ArrayList<>(); + givenNames.add(GIVEN_NAME); + TestUser testUser = new TestUser(USER_ID, givenNames, LAST_NAME); + testUser.addExtension("1", "1"); + TestUser testUser2 = new TestUser(USER_ID, givenNames, LAST_NAME); + testUser2.addExtension("1", "1"); + testUser2.addExtension("2", "2"); + assertFalse(testUser.equals(testUser2), "Objects shall not be equal if they have different extensions !"); + } + + /** + * Test for the hashcode method + */ + @Test + void testHashCode() { + List<String> givenNames = new ArrayList<>(); + givenNames.add(GIVEN_NAME); + TestUser testUser = new TestUser(USER_ID, givenNames, LAST_NAME); + assertNotNull(testUser.hashCode(), "Generated hashCode shall not be null !"); + } + +} diff --git a/access-token-provider-api/src/test/java/net/ihe/gazelle/lib/net.ihe.gazelle.app.accesstokenproviderapi/adapter/README.txt b/access-token-provider-api/src/test/java/net/ihe/gazelle/lib/net.ihe.gazelle.app.accesstokenproviderapi/adapter/README.txt deleted file mode 100644 index ddaf15eb40c83e30470f2655d8071850c8b5c610..0000000000000000000000000000000000000000 --- a/access-token-provider-api/src/test/java/net/ihe/gazelle/lib/net.ihe.gazelle.app.accesstokenproviderapi/adapter/README.txt +++ /dev/null @@ -1 +0,0 @@ -Put here test classes for adapter layer. \ No newline at end of file diff --git a/access-token-provider-api/src/test/java/net/ihe/gazelle/lib/net.ihe.gazelle.app.accesstokenproviderapi/application/README.txt b/access-token-provider-api/src/test/java/net/ihe/gazelle/lib/net.ihe.gazelle.app.accesstokenproviderapi/application/README.txt deleted file mode 100644 index fe1a7edcdb8e895cbfdcbfd15031c15da130d006..0000000000000000000000000000000000000000 --- a/access-token-provider-api/src/test/java/net/ihe/gazelle/lib/net.ihe.gazelle.app.accesstokenproviderapi/application/README.txt +++ /dev/null @@ -1 +0,0 @@ -Put here test classes for application layer. \ No newline at end of file diff --git a/access-token-provider-api/src/test/java/net/ihe/gazelle/lib/net.ihe.gazelle.app.accesstokenproviderapi/business/README.txt b/access-token-provider-api/src/test/java/net/ihe/gazelle/lib/net.ihe.gazelle.app.accesstokenproviderapi/business/README.txt deleted file mode 100644 index 9ab90c5deabdf0ede124604e6bb6d00ed83e7b8c..0000000000000000000000000000000000000000 --- a/access-token-provider-api/src/test/java/net/ihe/gazelle/lib/net.ihe.gazelle.app.accesstokenproviderapi/business/README.txt +++ /dev/null @@ -1 +0,0 @@ -Put here test classes for business layer. \ No newline at end of file diff --git a/access-token-provider-api/src/test/resources/audience.properties b/access-token-provider-api/src/test/resources/audience.properties new file mode 100644 index 0000000000000000000000000000000000000000..d77f01fec364a61f4d77be2e612d764d0f3757f2 --- /dev/null +++ b/access-token-provider-api/src/test/resources/audience.properties @@ -0,0 +1 @@ +audience:monpetitsecret \ No newline at end of file diff --git a/audience-retriever/pom.xml b/audience-retriever/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..df3b5e911c0a3c63d91769345822d9f8bcfb9d28 --- /dev/null +++ b/audience-retriever/pom.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <artifactId>app.access-token-provider</artifactId> + <groupId>net.ihe.gazelle</groupId> + <version>1.0.0-SNAPSHOT</version> + </parent> + + <groupId>net.ihe.gazelle</groupId> + <artifactId>app.audience-retriever</artifactId> + <name>Audience Retriever</name> + <version>1.0.0-SNAPSHOT</version> + + <dependencies> + <dependency> + <groupId>javax</groupId> + <artifactId>javaee-api</artifactId> + <version>8.0.1</version> + </dependency> + <dependency> + <groupId>net.ihe.gazelle</groupId> + <artifactId>framework.logger-service</artifactId> + <version>1.0.0</version> + </dependency> + <!-- Preferences API --> + <dependency> + <groupId>net.ihe.gazelle</groupId> + <artifactId>framework.preferences-model-api</artifactId> + <version>1.0.0</version> + </dependency> + + <!-- Implementation of Operational Preferences --> + <dependency> + <groupId>net.ihe.gazelle</groupId> + <artifactId>framework.operational-preferences-service</artifactId> + <version>1.0.0</version> + </dependency> + + </dependencies> + +</project> diff --git a/audience-retriever/src/main/java/net/ihe/gazelle/app/audienceretriever/adapter/AudienceSecretRetrieverForSoapui.java b/audience-retriever/src/main/java/net/ihe/gazelle/app/audienceretriever/adapter/AudienceSecretRetrieverForSoapui.java new file mode 100644 index 0000000000000000000000000000000000000000..544e903ac4ae75f960e84b0409355bbd04d6da78 --- /dev/null +++ b/audience-retriever/src/main/java/net/ihe/gazelle/app/audienceretriever/adapter/AudienceSecretRetrieverForSoapui.java @@ -0,0 +1,55 @@ +package net.ihe.gazelle.app.audienceretriever.adapter; + +import net.ihe.gazelle.app.audienceretriever.application.AudienceSecretRetriever; +import net.ihe.gazelle.framework.loggerservice.application.GazelleLogger; +import net.ihe.gazelle.framework.loggerservice.application.GazelleLoggerFactory; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Properties; + +/** + * {@link AudienceSecretRetriever} used by SoapUI project to retrieve secrets. + */ +public class AudienceSecretRetrieverForSoapui implements AudienceSecretRetriever { + + private static final GazelleLogger LOGGER = GazelleLoggerFactory.getInstance().getLogger(AudienceSecretRetrieverForSoapui.class); + + private String propertiesFile; + + + /** + * Constructor allowing to configure the properties file path. + * + * @param propertiesFile path to the properties file. + */ + public AudienceSecretRetrieverForSoapui(String propertiesFile) { + this.propertiesFile = propertiesFile; + } + + /** + * Read property file as {@link Properties}. + * + * @param filePath path to hte properties file. + * @return the {@link Properties} defined by the file. + */ + private static Properties readPropertiesFile(String filePath) { + Properties prop = null; + try (FileInputStream fis = new FileInputStream(filePath)) { + prop = new Properties(); + prop.load(fis); + } catch (IOException e) { + LOGGER.error("Error reading properties file !", e); + } + return prop; + } + + /** + * {@inheritDoc} + */ + @Override + public String retrieveSecretForAudience(String audience) { + Properties prop = readPropertiesFile(propertiesFile); + return prop != null ? prop.getProperty(audience) : null; + } +} diff --git a/audience-retriever/src/main/java/net/ihe/gazelle/app/audienceretriever/adapter/AudienceSecretRetrieverImpl.java b/audience-retriever/src/main/java/net/ihe/gazelle/app/audienceretriever/adapter/AudienceSecretRetrieverImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..6a906392190451b160708140268b04e372501cc0 --- /dev/null +++ b/audience-retriever/src/main/java/net/ihe/gazelle/app/audienceretriever/adapter/AudienceSecretRetrieverImpl.java @@ -0,0 +1,54 @@ +package net.ihe.gazelle.app.audienceretriever.adapter; + +import net.ihe.gazelle.app.audienceretriever.application.AudienceSecretRetriever; +import net.ihe.gazelle.framework.loggerservice.application.GazelleLogger; +import net.ihe.gazelle.framework.loggerservice.application.GazelleLoggerFactory; +import net.ihe.gazelle.framework.preferencesmodelapi.application.NamespaceException; +import net.ihe.gazelle.framework.preferencesmodelapi.application.OperationalPreferencesService; +import net.ihe.gazelle.framework.preferencesmodelapi.application.PreferenceException; + +import javax.inject.Inject; + +/** + * AudienceSecretRetriever implementation + */ +public class AudienceSecretRetrieverImpl implements AudienceSecretRetriever { + + private static final GazelleLogger LOGGER = GazelleLoggerFactory.getInstance().getLogger(AudienceSecretRetrieverImpl.class); + private static final String AUDIENCE_JNDI_NAMESPACE = "java:app/gazelle/chiua-validator-service/operational-preferences"; + + @Inject + private OperationalPreferencesService preferencesService; + + /** + * {@inheritDoc} + */ + public AudienceSecretRetrieverImpl() { + //Empty constructor for injection + } + + /** + * Setter for the preferencesService property. + * + * @param preferencesService value to set to the property. + */ + public void setPreferencesService(OperationalPreferencesService preferencesService) { + this.preferencesService = preferencesService; + } + + /** + * {@inheritDoc} + */ + @Override + public String retrieveSecretForAudience(String audience) { + try { + return preferencesService.getStringValue(AUDIENCE_JNDI_NAMESPACE, audience); + } catch (NamespaceException e) { + LOGGER.warn(e, "The JNDI namespace is not configured for Audiences !"); + } catch (PreferenceException e) { + LOGGER.warn(e, String.format("The Audience [%s] is not correctly defined in namespace !", audience)); + + } + return null; + } +} diff --git a/audience-retriever/src/main/java/net/ihe/gazelle/app/audienceretriever/application/AudienceSecretRetriever.java b/audience-retriever/src/main/java/net/ihe/gazelle/app/audienceretriever/application/AudienceSecretRetriever.java new file mode 100644 index 0000000000000000000000000000000000000000..5d0679fba5efee04c076372e9b51425e12d3ce21 --- /dev/null +++ b/audience-retriever/src/main/java/net/ihe/gazelle/app/audienceretriever/application/AudienceSecretRetriever.java @@ -0,0 +1,14 @@ +package net.ihe.gazelle.app.audienceretriever.application; + +/** + * classe to retrieve the audience secret + */ +public interface AudienceSecretRetriever { + + /** + * retrieve secret linked to an audience + * @param audience the audience + * @return the secret + */ + String retrieveSecretForAudience(String audience); +} diff --git a/audience-retriever/src/main/resources/META-INF/beans.xml b/audience-retriever/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000000000000000000000000000000000000..d29f9c2aedd99b79a8f82a7f18d27124c2e62358 --- /dev/null +++ b/audience-retriever/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans bean-discovery-mode="all" version="2.0" + xmlns="http://xmlns.jcp.org/xml/ns/javaee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee + http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"> +</beans> \ No newline at end of file diff --git a/audience-retriever/src/test/java/net/ihe/gazelle/app/audienceretriever/adapter/AudienceSecretRetrieverForSoapuiTest.java b/audience-retriever/src/test/java/net/ihe/gazelle/app/audienceretriever/adapter/AudienceSecretRetrieverForSoapuiTest.java new file mode 100644 index 0000000000000000000000000000000000000000..367b104ce2e757277a64688f6c88b2e5840a5f19 --- /dev/null +++ b/audience-retriever/src/test/java/net/ihe/gazelle/app/audienceretriever/adapter/AudienceSecretRetrieverForSoapuiTest.java @@ -0,0 +1,24 @@ +package net.ihe.gazelle.app.audienceretriever.adapter; + + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertNull; + +/** + * Class to test the retrieve of the audience secret + */ +class AudienceSecretRetrieverForSoapuiTest { + + /** + * Test the property set in the retriever secret audience method + */ + @Test + void retrieveSecretForAudienceWithPropertiesPathTest() { + AudienceSecretRetrieverForSoapui audienceSecretRetrieverForSoapui = new AudienceSecretRetrieverForSoapui("/opt/simulators/audience" + + ".properties"); + assertNull(audienceSecretRetrieverForSoapui.retrieveSecretForAudience("monpetitsecret")); + } + + +} diff --git a/audience-retriever/src/test/java/net/ihe/gazelle/app/audienceretriever/adapter/AudienceSecretRetrieverImplTest.java b/audience-retriever/src/test/java/net/ihe/gazelle/app/audienceretriever/adapter/AudienceSecretRetrieverImplTest.java new file mode 100644 index 0000000000000000000000000000000000000000..59d76347c044c4e5a96e1d31653a0935df9dbc41 --- /dev/null +++ b/audience-retriever/src/test/java/net/ihe/gazelle/app/audienceretriever/adapter/AudienceSecretRetrieverImplTest.java @@ -0,0 +1,92 @@ +package net.ihe.gazelle.app.audienceretriever.adapter; + +import net.ihe.gazelle.framework.preferencesmodelapi.application.NamespaceException; +import net.ihe.gazelle.framework.preferencesmodelapi.application.OperationalPreferencesService; +import net.ihe.gazelle.framework.preferencesmodelapi.application.PreferenceException; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class AudienceSecretRetrieverImplTest { + + AudienceSecretRetrieverImpl impl = new AudienceSecretRetrieverImpl(); + + @Test + public void defaultConstructorTest() { + AudienceSecretRetrieverImpl impl = new AudienceSecretRetrieverImpl(); + assertNotNull(impl); + } + + @Test + public void setPreferencesAndRetrieveAudienceTest() { + String myValue = "myValue"; + OperationalPreferencesService service = new OperationalPreferencesService() { + @Override + public boolean getBooleanValue(String s, String s1) throws PreferenceException, NamespaceException { + return false; + } + + @Override + public int getIntegerValue(String s, String s1) throws PreferenceException, NamespaceException { + return 0; + } + + @Override + public String getStringValue(String s, String s1) throws PreferenceException, NamespaceException { + return myValue; + } + }; + impl.setPreferencesService(service); + assertEquals(myValue, impl.retrieveSecretForAudience(null)); + + } + + @Test + public void setPreferencesAndRetrieveAudiencePreferenceExceptionTest() { + OperationalPreferencesService service = new OperationalPreferencesService() { + @Override + public boolean getBooleanValue(String s, String s1) throws PreferenceException, NamespaceException { + return false; + } + + @Override + public int getIntegerValue(String s, String s1) throws PreferenceException, NamespaceException { + return 0; + } + + @Override + public String getStringValue(String s, String s1) throws PreferenceException, NamespaceException { + throw new PreferenceException(); + } + }; + impl.setPreferencesService(service); + assertNull(impl.retrieveSecretForAudience(null)); + + } + + @Test + public void setPreferencesAndRetrieveAudienceNamespaceExceptionTest() { + OperationalPreferencesService service = new OperationalPreferencesService() { + @Override + public boolean getBooleanValue(String s, String s1) throws PreferenceException, NamespaceException { + return false; + } + + @Override + public int getIntegerValue(String s, String s1) throws PreferenceException, NamespaceException { + return 0; + } + + @Override + public String getStringValue(String s, String s1) throws PreferenceException, NamespaceException { + throw new NamespaceException(); + } + }; + impl.setPreferencesService(service); + assertNull(impl.retrieveSecretForAudience(null)); + + } + + + +} diff --git a/access-token-provider-api/src/test/resources/README.txt b/audience-retriever/src/test/resources/README.txt similarity index 100% rename from access-token-provider-api/src/test/resources/README.txt rename to audience-retriever/src/test/resources/README.txt diff --git a/dummy-authorization-server-service/README.md b/dummy-authorization-server-service/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6a1469b7c385b6b7a0805a4806582e711a52a3f4 --- /dev/null +++ b/dummy-authorization-server-service/README.md @@ -0,0 +1,40 @@ +# Dummy Authorization Server Service + +This service mock an Access Token Provider, giving a mocked token using one of available user id +and a secret that can be configured depending on the used audience. + +## Request examples + +```http://localhost:8780/authorization-server/mock-token?userId=aamrein&audienceId=audience``` + +| Parameter Name | Usage | +|-------------|-----------------------------------------------------------------------| +| userId | User for whom the token is generated | +| audienceId | ID of the audience used to retrieve secret in Gazelle configurations. | + +The response body to this request will be the content of the generated token. + +## Available user ID + +| User ID | +|----------| +| aamrein | +| aerne | + +## Install the tool + +Sources are available [here](https://gitlab.inria.fr/gazelle/applications/test-execution/simulator/access-token-provider) + +Deploy the `app.dummy-authorization-server-service-X.X.X.war` artifact in a wildfly 18 server. +No specific wildfly configuration is needed for the tool to work. + +## Configure Audiences + +Edit the file `/opt/simulators/audience.properties`, add a property for each audience that needs to be configured : + +``` +audience1=secret1 +audience2=secret2 +audience3=secret3 +... +``` \ No newline at end of file diff --git a/dummy-authorization-server-service/pom.xml b/dummy-authorization-server-service/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..b494a152864051db6b8c3bd11ccbbf2a36f97bc5 --- /dev/null +++ b/dummy-authorization-server-service/pom.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>app.access-token-provider</artifactId> + <groupId>net.ihe.gazelle</groupId> + <version>1.0.0-SNAPSHOT</version> + </parent> + + <groupId>net.ihe.gazelle</groupId> + <artifactId>app.dummy-authorization-server-service</artifactId> + <name>Dummy Authorization Server Service</name> + <version>1.0.0-SNAPSHOT</version> + <packaging>war</packaging> + + + <dependencies> + <dependency> + <groupId>javax</groupId> + <artifactId>javaee-api</artifactId> + <version>8.0.1</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>net.ihe.gazelle</groupId> + <artifactId>app.access-token-provider-api</artifactId> + <version>1.0.0-SNAPSHOT</version> + <scope>compile</scope> + </dependency> + </dependencies> +</project> \ No newline at end of file diff --git a/dummy-authorization-server-service/src/main/java/net/ihe/gazelle/app/dummyauthorizationserverservice/adapter/AuthorizationServerService.java b/dummy-authorization-server-service/src/main/java/net/ihe/gazelle/app/dummyauthorizationserverservice/adapter/AuthorizationServerService.java new file mode 100644 index 0000000000000000000000000000000000000000..a445982f1222feb810d2f21a74def8affcfb7fa7 --- /dev/null +++ b/dummy-authorization-server-service/src/main/java/net/ihe/gazelle/app/dummyauthorizationserverservice/adapter/AuthorizationServerService.java @@ -0,0 +1,52 @@ +package net.ihe.gazelle.app.dummyauthorizationserverservice.adapter; + + +import net.ihe.gazelle.app.accesstokenproviderapi.application.DummyAuthzServer; +import net.ihe.gazelle.app.accesstokenproviderapi.application.DummyAuthzServerSoapui; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.QueryParam; +import javax.ws.rs.ext.Provider; + +/** + * Service for Mock Access Token Provider. + */ +@Provider +@Path(value = "/mock-token") +public class AuthorizationServerService { + + private DummyAuthzServer dummyAuthzServer; + + /** + * Default constructor for the class. + */ + public AuthorizationServerService() { + dummyAuthzServer = new DummyAuthzServerSoapui(); + } + + /** + * Setter for the dummyAuthzServer property. + * + * @param dummyAuthzServer value to set to the property. + */ + public void setDummyAuthzServer(DummyAuthzServer dummyAuthzServer) { + this.dummyAuthzServer = dummyAuthzServer; + } + + /** + * get a dummy access token + * + * @param userId + * @param audienceId + * @param purposeOfUse + * @param resourceId + * @return an access token + */ + @GET + public byte[] getAccessToken(@QueryParam("userId") String userId, @QueryParam("audienceId") String audienceId, + @QueryParam("purposeOfUse") String purposeOfUse, @QueryParam("resourceId") String resourceId) { + return dummyAuthzServer.getAccessToken(userId, audienceId, purposeOfUse, resourceId); + } + +} diff --git a/dummy-authorization-server-service/src/main/java/net/ihe/gazelle/app/dummyauthorizationserverservice/adapter/DummyAuthorizationServerServiceApplication.java b/dummy-authorization-server-service/src/main/java/net/ihe/gazelle/app/dummyauthorizationserverservice/adapter/DummyAuthorizationServerServiceApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..90f6d456b3bdaf8c7aba3e1ca966b1388d6c72a4 --- /dev/null +++ b/dummy-authorization-server-service/src/main/java/net/ihe/gazelle/app/dummyauthorizationserverservice/adapter/DummyAuthorizationServerServiceApplication.java @@ -0,0 +1,23 @@ +package net.ihe.gazelle.app.dummyauthorizationserverservice.adapter; + +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.core.Application; +import java.util.HashSet; +import java.util.Set; + +/** + * Our Application + */ +@ApplicationPath("/") +public class DummyAuthorizationServerServiceApplication extends Application { + + /** + * {@inheritDoc} + */ + @Override + public Set<Class<?>> getClasses() { + Set<Class<?>> s = new HashSet<>(); + s.add(AuthorizationServerService.class); + return s; + } +} diff --git a/dummy-authorization-server-service/src/main/java/net/ihe/gazelle/app/dummyauthorizationserverservice/adapter/OperationalPreferencesDummy.java b/dummy-authorization-server-service/src/main/java/net/ihe/gazelle/app/dummyauthorizationserverservice/adapter/OperationalPreferencesDummy.java new file mode 100644 index 0000000000000000000000000000000000000000..34a7f6799fda60e08e126f2f99a1554a6f2a3d96 --- /dev/null +++ b/dummy-authorization-server-service/src/main/java/net/ihe/gazelle/app/dummyauthorizationserverservice/adapter/OperationalPreferencesDummy.java @@ -0,0 +1,21 @@ +package net.ihe.gazelle.app.dummyauthorizationserverservice.adapter; + +import net.ihe.gazelle.framework.preferencesmodelapi.application.OperationalPreferencesClientApplication; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Define mandatory preferences. + */ +public class OperationalPreferencesDummy implements OperationalPreferencesClientApplication { + + /** + * {@inheritDoc} + */ + @Override + public Map<String, List<String>> wantedMandatoryPreferences() { + return new HashMap<>(); + } +} diff --git a/dummy-authorization-server-service/src/main/resources/META-INF/beans.xml b/dummy-authorization-server-service/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000000000000000000000000000000000000..d29f9c2aedd99b79a8f82a7f18d27124c2e62358 --- /dev/null +++ b/dummy-authorization-server-service/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans bean-discovery-mode="all" version="2.0" + xmlns="http://xmlns.jcp.org/xml/ns/javaee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee + http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"> +</beans> \ No newline at end of file diff --git a/dummy-authorization-server-service/src/main/resources/soapui/DummyAccessTokenProvider.xml b/dummy-authorization-server-service/src/main/resources/soapui/DummyAccessTokenProvider.xml new file mode 100644 index 0000000000000000000000000000000000000000..93b4d01d9ac9641a639488d9e08c99a63e7a4945 --- /dev/null +++ b/dummy-authorization-server-service/src/main/resources/soapui/DummyAccessTokenProvider.xml @@ -0,0 +1,314 @@ +<?xml version="1.0" encoding="UTF-8"?> +<con:soapui-project id="511bc175-43ea-4daa-b8b0-8135770e4931" activeEnvironment="Default" name="REST Project 1" resourceRoot="" soapui-version="5.5.0" + xmlns:con="http://eviware.com/soapui/config"> + <con:settings/> + <con:interface xsi:type="con:RestService" id="a83dfcbb-6422-4e5a-a181-094eaf6314b0" wadlVersion="http://wadl.dev.java.net/2009/02" + name="http://localhost:8780" type="rest" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <con:settings/> + <con:definitionCache type="TEXT" rootPart=""/> + <con:endpoints> + <con:endpoint>http://localhost:8780</con:endpoint> + </con:endpoints> + <con:resource name="Mock-token" path="/authorization-server/mock-token" id="7270205e-e39c-4360-84e7-e29e05aad49b"> + <con:settings/> + <con:parameters> + <con:parameter> + <con:name>userId</con:name> + <con:value/> + <con:style>QUERY</con:style> + <con:default/> + <con:description xsi:nil="true"/> + </con:parameter> + <con:parameter> + <con:name>audienceId</con:name> + <con:value/> + <con:style>QUERY</con:style> + <con:default/> + <con:description xsi:nil="true"/> + </con:parameter> + <con:parameter> + <con:name>purposeOfUse</con:name> + <con:value/> + <con:style>QUERY</con:style> + <con:default/> + <con:description xsi:nil="true"/> + </con:parameter> + <con:parameter> + <con:name>resourceId</con:name> + <con:value/> + <con:style>QUERY</con:style> + <con:default/> + <con:description xsi:nil="true"/> + </con:parameter> + </con:parameters> + <con:method name="Mock-token 1" id="abfda5a1-8402-4e07-af8d-89b02e4d0c72" method="GET"> + <con:settings/> + <con:parameters/> + <con:representation type="RESPONSE"> + <con:mediaType>application/octet-stream</con:mediaType> + <con:status>200</con:status> + <con:params/> + <con:element>data</con:element> + </con:representation> + <con:representation type="RESPONSE"> + <con:mediaType xsi:nil="true"/> + <con:status>204</con:status> + <con:params/> + <con:element>data</con:element> + </con:representation> + <con:representation type="RESPONSE"> + <con:mediaType xsi:nil="true"/> + <con:status>204</con:status> + <con:params/> + <con:element>data</con:element> + </con:representation> + <con:representation type="RESPONSE"> + <con:mediaType xsi:nil="true"/> + <con:status>204</con:status> + <con:params/> + <con:element>data</con:element> + </con:representation> + <con:representation type="RESPONSE"> + <con:mediaType xsi:nil="true"/> + <con:status>204</con:status> + <con:params/> + <con:element>data</con:element> + </con:representation> + <con:representation type="RESPONSE"> + <con:mediaType xsi:nil="true"/> + <con:status>204</con:status> + <con:params/> + <con:element>data</con:element> + </con:representation> + <con:representation type="RESPONSE"> + <con:mediaType xsi:nil="true"/> + <con:status>0</con:status> + <con:params/> + <con:element>data</con:element> + </con:representation> + <con:representation type="RESPONSE"> + <con:mediaType xsi:nil="true"/> + <con:status>0</con:status> + <con:params/> + <con:element>data</con:element> + </con:representation> + <con:representation type="RESPONSE"> + <con:mediaType xsi:nil="true"/> + <con:status>204</con:status> + <con:params/> + <con:element>data</con:element> + </con:representation> + <con:representation type="RESPONSE"> + <con:mediaType xsi:nil="true"/> + <con:status>0</con:status> + <con:params/> + <con:element>data</con:element> + </con:representation> + <con:representation type="FAULT"> + <con:mediaType>text/html</con:mediaType> + <con:status>404</con:status> + <con:params/> + <con:element>html</con:element> + </con:representation> + <con:representation type="RESPONSE"> + <con:mediaType xsi:nil="true"/> + <con:status>204</con:status> + <con:params/> + <con:element>data</con:element> + </con:representation> + <con:representation type="RESPONSE"> + <con:mediaType xsi:nil="true"/> + <con:status>0</con:status> + <con:params/> + <con:element>data</con:element> + </con:representation> + <con:representation type="RESPONSE"> + <con:mediaType xsi:nil="true"/> + <con:status>204</con:status> + <con:params/> + <con:element>data</con:element> + </con:representation> + <con:representation type="RESPONSE"> + <con:mediaType xsi:nil="true"/> + <con:status>204</con:status> + <con:params/> + <con:element>data</con:element> + </con:representation> + <con:representation type="RESPONSE"> + <con:mediaType xsi:nil="true"/> + <con:status>0</con:status> + <con:params/> + <con:element>data</con:element> + </con:representation> + <con:representation type="RESPONSE"> + <con:mediaType xsi:nil="true"/> + <con:status>204</con:status> + <con:params/> + <con:element>data</con:element> + </con:representation> + <con:representation type="RESPONSE"> + <con:mediaType xsi:nil="true"/> + <con:status>204</con:status> + <con:params/> + <con:element>data</con:element> + </con:representation> + <con:representation type="RESPONSE"> + <con:mediaType xsi:nil="true"/> + <con:status>204</con:status> + <con:params/> + <con:element>data</con:element> + </con:representation> + <con:request name="Request 1" id="1039bbd9-95cf-452e-ad96-4cfb23827782" mediaType="application/json"> + <con:settings/> + <con:endpoint>http://localhost:8780</con:endpoint> + <con:request/> + <con:credentials> + <con:authType>No Authorization</con:authType> + </con:credentials> + <con:jmsConfig JMSDeliveryMode="PERSISTENT"/> + <con:jmsPropertyConfig/> + <con:parameters> + <con:entry key="resourceId" value="12"/> + <con:entry key="purposeOfUse" value="test"/> + <con:entry key="audienceId" value="audience"/> + <con:entry key="userId" value="test"/> + </con:parameters> + <con:parameterOrder> + <con:entry>userId</con:entry> + <con:entry>audienceId</con:entry> + <con:entry>purposeOfUse</con:entry> + <con:entry>resourceId</con:entry> + </con:parameterOrder> + </con:request> + </con:method> + </con:resource> + </con:interface> + <con:testSuite id="99a0a2d5-1bf9-4cd6-a66d-29830e75aef8" name="Test Mock Token Provider"> + <con:settings/> + <con:runType>SEQUENTIAL</con:runType> + <con:testCase id="f4ab98d6-051e-4e34-9dca-7aac5409f375" failOnError="true" failTestCaseOnErrors="true" keepSession="false" maxResults="0" + name="Request" searchProperties="true"> + <con:settings/> + <con:testStep type="restrequest" name="Valid request" id="fa834a0a-6dc7-4d84-a15a-f13224626c4e"> + <con:settings/> + <con:config service="http://localhost:8780" resourcePath="/authorization-server/mock-token" methodName="Mock-token 1" + xsi:type="con:RestRequestStep" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <con:restRequest name="Mock-token 1 - Request 1" id="1039bbd9-95cf-452e-ad96-4cfb23827782" mediaType="application/json"> + <con:settings> + <con:setting id="com.eviware.soapui.impl.wsdl.WsdlRequest@request-headers"><xml-fragment/></con:setting> + </con:settings> + <con:endpoint>http://localhost:8780</con:endpoint> + <con:request/> + <con:originalUri>http://localhost/authorization-server/mock-token</con:originalUri> + <con:assertion type="Simple Contains" id="eec24b99-0b19-4a1e-93f7-d791268e2f6d" name="Contains"> + <con:configuration> + <token>.+\..+\..+</token> + <ignoreCase>false</ignoreCase> + <useRegEx>true</useRegEx> + </con:configuration> + </con:assertion> + <con:credentials> + <con:authType>No Authorization</con:authType> + </con:credentials> + <con:jmsConfig JMSDeliveryMode="PERSISTENT"/> + <con:jmsPropertyConfig/> + <con:parameters> + <con:entry key="audienceId" value="audience"/> + <con:entry key="userId" value="aamrein"/> + </con:parameters> + <con:parameterOrder> + <con:entry>userId</con:entry> + <con:entry>audienceId</con:entry> + <con:entry>purposeOfUse</con:entry> + <con:entry>resourceId</con:entry> + </con:parameterOrder> + </con:restRequest> + </con:config> + </con:testStep> + <con:properties/> + </con:testCase> + <con:testCase id="81ffbff9-1a6a-4389-951a-3f8ed143f4e8" failOnError="true" failTestCaseOnErrors="true" keepSession="false" maxResults="0" + name="Unknown UserID" searchProperties="true"> + <con:settings/> + <con:testStep type="restrequest" name="Unknown userID" id="0821bbbe-9ed6-490b-88f5-c46be620eae6"> + <con:settings/> + <con:config service="http://localhost:8780" resourcePath="/authorization-server/mock-token" methodName="Mock-token 1" + xsi:type="con:RestRequestStep" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <con:restRequest name="Unknown userID" id="1039bbd9-95cf-452e-ad96-4cfb23827782" mediaType="application/json"> + <con:settings> + <con:setting id="com.eviware.soapui.impl.wsdl.WsdlRequest@request-headers"><xml-fragment/></con:setting> + </con:settings> + <con:endpoint>http://localhost:8780</con:endpoint> + <con:request/> + <con:originalUri>http://localhost/authorization-server/mock-token</con:originalUri> + <con:assertion type="Valid HTTP Status Codes" id="60be561e-c058-42cd-882f-0e60e9226c65" name="Valid HTTP Status Codes"> + <con:configuration> + <codes>204</codes> + </con:configuration> + </con:assertion> + <con:credentials> + <con:authType>No Authorization</con:authType> + </con:credentials> + <con:jmsConfig JMSDeliveryMode="PERSISTENT"/> + <con:jmsPropertyConfig/> + <con:parameters> + <con:entry key="audienceId" value="audience43"/> + <con:entry key="userId" value="aamrein"/> + </con:parameters> + <con:parameterOrder> + <con:entry>userId</con:entry> + <con:entry>audienceId</con:entry> + <con:entry>purposeOfUse</con:entry> + <con:entry>resourceId</con:entry> + </con:parameterOrder> + </con:restRequest> + </con:config> + </con:testStep> + <con:properties/> + </con:testCase> + <con:testCase id="0b0c480f-8389-40e2-83bf-1adfad6f874f" failOnError="true" failTestCaseOnErrors="true" keepSession="false" maxResults="0" + name="Unknown Audience" searchProperties="true"> + <con:settings/> + <con:testStep type="restrequest" name="Unknown audience" id="b3d2c1e7-36a2-43ad-8056-5ff54b75677b"> + <con:settings/> + <con:config service="http://localhost:8780" resourcePath="/authorization-server/mock-token" methodName="Mock-token 1" + xsi:type="con:RestRequestStep" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <con:restRequest name="Unknown audience" id="1039bbd9-95cf-452e-ad96-4cfb23827782" mediaType="application/json"> + <con:settings> + <con:setting id="com.eviware.soapui.impl.wsdl.WsdlRequest@request-headers"><xml-fragment/></con:setting> + </con:settings> + <con:endpoint>http://localhost:8780</con:endpoint> + <con:request/> + <con:originalUri>http://localhost/authorization-server/mock-token</con:originalUri> + <con:assertion type="Valid HTTP Status Codes" id="60be561e-c058-42cd-882f-0e60e9226c65" name="Valid HTTP Status Codes"> + <con:configuration> + <codes>204</codes> + </con:configuration> + </con:assertion> + <con:credentials> + <con:authType>No Authorization</con:authType> + </con:credentials> + <con:jmsConfig JMSDeliveryMode="PERSISTENT"/> + <con:jmsPropertyConfig/> + <con:parameters> + <con:entry key="audienceId" value="audience"/> + <con:entry key="userId" value="wbars"/> + </con:parameters> + <con:parameterOrder> + <con:entry>userId</con:entry> + <con:entry>audienceId</con:entry> + <con:entry>purposeOfUse</con:entry> + <con:entry>resourceId</con:entry> + </con:parameterOrder> + </con:restRequest> + </con:config> + </con:testStep> + <con:properties/> + </con:testCase> + <con:properties/> + </con:testSuite> + <con:properties/> + <con:wssContainer/> + <con:oAuth2ProfileContainer/> + <con:oAuth1ProfileContainer/> +</con:soapui-project> \ No newline at end of file diff --git a/dummy-authorization-server-service/src/main/webapp/WEB-INF/jboss-web.xml b/dummy-authorization-server-service/src/main/webapp/WEB-INF/jboss-web.xml new file mode 100644 index 0000000000000000000000000000000000000000..b832b6ea657c580d51bc40526ad9c4dbf3e568f5 --- /dev/null +++ b/dummy-authorization-server-service/src/main/webapp/WEB-INF/jboss-web.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<jboss-web> + <context-root>authorization-server</context-root> +</jboss-web> \ No newline at end of file diff --git a/dummy-authorization-server-service/src/main/webapp/WEB-INF/web.xml b/dummy-authorization-server-service/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000000000000000000000000000000000..e84277a95f80e2ed59f5518458b90b473057e968 --- /dev/null +++ b/dummy-authorization-server-service/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,7 @@ +<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee + http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" + version="3.1"> + +</web-app> diff --git a/dummy-authorization-server-service/src/test/java/net/ihe/gazelle/app/dummyauthorizationserverservice/adapter/AuthorizationServerServiceTest.java b/dummy-authorization-server-service/src/test/java/net/ihe/gazelle/app/dummyauthorizationserverservice/adapter/AuthorizationServerServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b0d55465d28b9e78a1a6c869c774169e3824f22c --- /dev/null +++ b/dummy-authorization-server-service/src/test/java/net/ihe/gazelle/app/dummyauthorizationserverservice/adapter/AuthorizationServerServiceTest.java @@ -0,0 +1,29 @@ +package net.ihe.gazelle.app.dummyauthorizationserverservice.adapter; + +import net.ihe.gazelle.app.accesstokenproviderapi.application.DummyAuthzServerSoapui; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * Tests for {@link AuthorizationServerService} + */ +class AuthorizationServerServiceTest { + + private static final String SUBJECT = "aamrein"; + private static final String AUDIENCE = "audience"; + + /** + * Test the generation of a token + */ + @Test + public void getAccessToken() { + AuthorizationServerService authorizationServerService = new AuthorizationServerService(); + DummyAuthzServerSoapui dummyAuthzServer = new DummyAuthzServerSoapui(); + dummyAuthzServer.setAudienceSecretRetriever((String audience) -> "myBeautifulKeyWhichIsAJWTSecretSoSecret"); + authorizationServerService.setDummyAuthzServer(dummyAuthzServer); + + assertNotNull(authorizationServerService.getAccessToken(SUBJECT, AUDIENCE, null, null), + "Provided access token shall not be null !"); + } +} \ No newline at end of file diff --git a/dummy-authorization-server-service/src/test/java/net/ihe/gazelle/app/dummyauthorizationserverservice/adapter/DummyAuthorizationServerServiceApplicationTest.java b/dummy-authorization-server-service/src/test/java/net/ihe/gazelle/app/dummyauthorizationserverservice/adapter/DummyAuthorizationServerServiceApplicationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..1abdbf9f2e380298181c80658ac2a8ab3cd33f52 --- /dev/null +++ b/dummy-authorization-server-service/src/test/java/net/ihe/gazelle/app/dummyauthorizationserverservice/adapter/DummyAuthorizationServerServiceApplicationTest.java @@ -0,0 +1,24 @@ +package net.ihe.gazelle.app.dummyauthorizationserverservice.adapter; + +import org.junit.jupiter.api.Test; + +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +class DummyAuthorizationServerServiceApplicationTest { + + /** + * Test class getter. + */ + @Test + void getClasses() { + DummyAuthorizationServerServiceApplication application = new DummyAuthorizationServerServiceApplication(); + + Set classes = application.getClasses(); + + assertNotNull(classes, "Classes map shall not be null !"); + assertEquals(1, classes.size(), "Classes map shall contain a single element !"); + } +} \ No newline at end of file diff --git a/dummy-authorization-server-service/src/test/java/net/ihe/gazelle/app/dummyauthorizationserverservice/adapter/OperationalPreferencesDummyTest.java b/dummy-authorization-server-service/src/test/java/net/ihe/gazelle/app/dummyauthorizationserverservice/adapter/OperationalPreferencesDummyTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3bd30b4de8262009eedfc15b106f13c970ccc9a7 --- /dev/null +++ b/dummy-authorization-server-service/src/test/java/net/ihe/gazelle/app/dummyauthorizationserverservice/adapter/OperationalPreferencesDummyTest.java @@ -0,0 +1,25 @@ +package net.ihe.gazelle.app.dummyauthorizationserverservice.adapter; + +import net.ihe.gazelle.framework.preferencesmodelapi.application.OperationalPreferencesClientApplication; +import net.ihe.gazelle.framework.preferencesmodelapi.application.OperationalPreferencesService; +import org.junit.jupiter.api.Test; + +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; + +class OperationalPreferencesDummyTest { + + /** + * Test wanted mandatroy preferences list. + */ + @Test + void wantedMandatoryPreferences() { + OperationalPreferencesClientApplication operationalPreferencesService = new OperationalPreferencesDummy(); + + Map wantedMandatoryPreferences = operationalPreferencesService.wantedMandatoryPreferences(); + + assertNotNull(wantedMandatoryPreferences, "Wanted Mandatory Preferences map shall not be null !"); + assertEquals(0, wantedMandatoryPreferences.entrySet().size(), "Wanted Mandatory Preferences map shall be empty"); + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 3218089b7a5615ff9bf56668ec3cf6c951bab5ac..88a3a45e97ca83d2883fd93549cd6351c8e8c355 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>net.ihe.gazelle</groupId> @@ -11,9 +12,9 @@ <url>http://gazelle.ihe.net</url> <scm> - <connection>scm:git:git@gitlab.inria.fr:gazelle/applications/test-execution/simulator/access-token-provider.git</connection> - <url>scm:git:git@gitlab.inria.fr:gazelle/applications/test-execution/simulator/access-token-provider.git</url> - <developerConnection>scm:git:git@gitlab.inria.fr:gazelle/applications/test-execution/simulator/access-token-provider.git</developerConnection> + <connection>${git.project.url}</connection> + <url>${git.project.url}</url> + <developerConnection>${git.project.url}</developerConnection> <tag>HEAD</tag> </scm> @@ -27,6 +28,11 @@ <cvss.score.level.tolerate>8</cvss.score.level.tolerate> <nexus.url>https://gazelle.ihe.net/nexus</nexus.url> <nexus.path>/content/groups/public/</nexus.path> + <git.user.name>git</git.user.name> + <git.user.token>git</git.user.token> + <git.project.url> + scm:${git.user.name}:${git.user.token}@gitlab.inria.fr/gazelle/applications/test-execution/simulator/access-token-provider.git + </git.project.url> </properties> <repositories> @@ -172,6 +178,17 @@ </profile> </profiles> + <dependencyManagement> + <dependencies> + <dependency> + <groupId>net.ihe.gazelle</groupId> + <artifactId>app.audience-retriever</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + </dependencyManagement> + + <dependencies> <dependency> <groupId>org.junit.jupiter</groupId> @@ -181,7 +198,9 @@ </dependency> </dependencies> - <modules> - <module>access-token-provider-api</module> + <modules> + <module>access-token-provider-api</module> + <module>audience-retriever</module> + <module>dummy-authorization-server-service</module> </modules> </project> \ No newline at end of file