Skip to content
12 changes: 12 additions & 0 deletions auto-configure/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>com.codeyapa</groupId>
<artifactId>core</artifactId>
Expand All @@ -40,6 +46,12 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.junit.Test;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;

import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.autoconfigure.AutoConfigurations.of;

public class SecurityAutoConfigurationTest {
Expand All @@ -15,7 +16,21 @@ public void shouldCreateAutoConfiguredBeanIfStarterIsEnabled() {
.withPropertyValues(properties(true))
.withConfiguration(of(SecurityAutoConfiguration.class));

this.applicationContextRunner.run(context -> {});
this.applicationContextRunner.run(
context -> {
});
}

@Test
public void shouldNotCreateAutoConfiguredBeanIfStarterIsNotEnabled() {
applicationContextRunner =
new WebApplicationContextRunner()
.withPropertyValues(properties(false))
.withConfiguration(of(SecurityAutoConfiguration.class));

this.applicationContextRunner.run(
context -> {
});
}

private String[] properties(boolean enabled) {
Expand Down
55 changes: 55 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@

<artifactId>core</artifactId>

<properties>
<sonar.jacoco.reportPaths>${project.build.directory}/jacoco.exec</sonar.jacoco.reportPaths>
<sonar.exclusions>
src/main/java/com/codeyapa/rest/secured/core/domain/*
</sonar.exclusions>
<sonar.coverage.exclusions>
src/main/java/com/codeyapa/rest/secured/core/domain/*
</sonar.coverage.exclusions>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
Expand All @@ -24,11 +34,56 @@
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-suite-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.codeyapa.rest.secured.core.domain;

import com.fasterxml.jackson.annotation.JsonProperty;

public enum GrantType {
@JsonProperty("password")
PASSWORD,

@JsonProperty("refresh_token")
REFRESH_TOKEN,

@JsonProperty("client_credentials")
CLIENT_CREDENTIALS
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.codeyapa.rest.secured.core.domain;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;

@JsonInclude(JsonInclude.Include.NON_NULL)
@AllArgsConstructor
@Getter
@EqualsAndHashCode
public class IssueTokenRequest {
@JsonProperty("client_id")
private String clientId;

@JsonProperty("grant_type")
private GrantType grantType;

private String scope;
private String username;
private String password;
private int confidenceLevel;

@JsonProperty("refresh_token")
private String refreshToken;

public IssueTokenRequest(String clientId, String username, String password, String scope) {
this.clientId = clientId;
this.grantType = GrantType.PASSWORD;

this.username = username;
this.password = password;
this.scope = scope;
}

public IssueTokenRequest(String clientId, String refreshToken) {
this.clientId = clientId;
this.grantType = GrantType.REFRESH_TOKEN;
this.refreshToken = refreshToken;
}

public IssueTokenRequest(String clientId, String scope, int confidenceLevel) {
this.clientId = clientId;
this.scope = scope;
this.confidenceLevel = confidenceLevel;
this.grantType = GrantType.CLIENT_CREDENTIALS;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.codeyapa.rest.secured.core.domain;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class IssueTokenResponse {
@JsonProperty("access_token")
String accessToken;

@JsonProperty("refresh_token")
String refreshToken;

@JsonProperty("expires_in")
Integer expiresIn;

@JsonProperty("token_type")
String tokenType;

@JsonProperty("scope")
String scope;

@JsonProperty("confidence_level")
Integer confidenceLevel;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.codeyapa.rest.secured.core.domain;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Value;

import java.time.Instant;
import java.util.Set;

@Builder
@Value
@AllArgsConstructor
@EqualsAndHashCode
public class Token {
String tokenId;
String userId;
String clientId;
Instant validFrom;
Instant expiresAt;
Instant issuedAt;
String issuer;
String scope;
Integer confidenceLevel;
Set<String> audience;

public boolean isFutureToken() {
return !validFrom.isBefore(Instant.now());
}

public boolean isExpired() {
return expiresAt.isBefore(Instant.now());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.codeyapa.rest.secured.core.domain;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;

@JsonInclude(JsonInclude.Include.NON_NULL)
@Getter
@AllArgsConstructor
public class ValidateTokenRequest {
@JsonProperty("access_token")
private String accessToken;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.codeyapa.rest.secured.core.domain;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;

import static java.time.Instant.ofEpochSecond;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Slf4j
public class ValidateTokenResponse {
@JsonProperty("active")
private boolean active;

@JsonProperty("jti")
private String tokenId;

@JsonProperty("iss")
private String issuer;

@JsonProperty("sub")
private String subject;

@JsonProperty("aud")
private Collection<String> audience;

@JsonProperty("iat")
private Long issuedAt;

@JsonProperty("nbf")
private Long notBefore;

@JsonProperty("exp")
private Long expirationTime;

@JsonProperty("scope")
private String scope;

@JsonProperty("confidence_level")
private Integer confidenceLevel;

@JsonProperty("client_id")
private String clientId;

@JsonProperty("token_type")
private String tokenType;

public Optional<Token> toToken() {
if (!active || subject == null) {
return Optional.empty();
}
try {
return Optional.of(
Token.builder()
.userId(subject)
.clientId(clientId)
.issuedAt(ofEpochSecond(issuedAt))
.expiresAt(ofEpochSecond(expirationTime))
.validFrom(ofEpochSecond(notBefore))
.confidenceLevel(confidenceLevel)
.audience(audience == null ? Collections.emptySet() : new HashSet<>(audience))
.scope(scope)
.tokenId(tokenId)
.build());
} catch (IllegalArgumentException | NullPointerException e) {
log.error("The token could not be parsed as a valid JWT.", e);
return Optional.empty();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package com.codeyapa.rest.secured.core.properties;

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "rest.security")
@Getter
@Setter
public class SecurityProperties {
private boolean enabled = true;
}
Loading