Skip to content

Commit

Permalink
Upgrading Spring Boot to 1.1.3 (#55)
Browse files Browse the repository at this point in the history
* Upgraded Spring Boot to version 1.1.3
* Cleanup after updating Spring Boot
* Fixed SonarLint smells
  • Loading branch information
massenz authored Oct 26, 2023
1 parent 6d96f5b commit 2132428
Show file tree
Hide file tree
Showing 11 changed files with 69 additions and 69 deletions.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
20 changes: 11 additions & 9 deletions jwt-opa/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
*/

plugins {
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'io.spring.dependency-management' version '1.1.3'
id 'java'
id 'jacoco'
id 'org.springframework.boot' version '2.5.7'
id 'org.springframework.boot' version '3.1.5'

// To upload the Artifact to Maven Central
// See: https://docs.gradle.org/current/userguide/publishing_maven.html
Expand All @@ -38,7 +38,7 @@ ext {
}

group 'com.alertavert'
version '0.9.0'
version '0.10.0'

// OpenJDK 17 LTS is the only Java version supported
sourceCompatibility = JavaVersion.VERSION_17
Expand Down Expand Up @@ -78,24 +78,27 @@ dependencies {
// See: https://stackoverflow.com/questions/29805622/could-not-find-or-load-main-class-org-gradle-wrapper-gradlewrappermain/31622432
implementation group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.2'

annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
annotationProcessor "org.projectlombok:lombok:${lombokVersion}"
compileOnly "org.projectlombok:lombok:${lombokVersion}"

implementation 'com.auth0:java-jwt:3.10.3'
implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
implementation 'commons-codec:commons-codec:1.13'

testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}

annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-webflux'

// AWS SDK for Secrets Manager, see: https://docs.aws.amazon.com/code-samples/latest/catalog/code-catalog-javav2-example_code-secretsmanager.html
implementation "software.amazon.awssdk:secretsmanager:${awsSdkVersion}"

// For the @PostConstruct annotation
implementation 'javax.annotation:javax.annotation-api:1.3.2'

testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}

testImplementation "com.jayway.jsonpath:json-path-assert:$jsonpathVersion"
testImplementation "org.mockito:mockito-core:$mockitoVersion"

Expand All @@ -104,7 +107,6 @@ dependencies {
testImplementation "org.testcontainers:junit-jupiter:$tcVersion"
testImplementation "org.testcontainers:localstack:$tcVersion"
testImplementation group: 'com.amazonaws', name: 'aws-java-sdk-core', version: '1.12.326'

}

jacocoTestCoverageVerification {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@
@Service @Slf4j
public class ApiTokenAuthenticationFactory {

@Autowired
JwtTokenProvider provider;
private final JwtTokenProvider provider;

public ApiTokenAuthenticationFactory(JwtTokenProvider provider) {
this.provider = provider;
}

/**
* Creates an implementation of the {@link Authentication} interface which implements the
Expand All @@ -62,7 +65,7 @@ public Mono<Authentication> createAuthentication(String token) {
log.debug("Authenticating token {}...", token.substring(0, Math.min(MAX_TOKEN_LEN_LOG, token.length())));
try {
DecodedJWT jwt = provider.decode(token);
List<? extends GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(
List<? extends GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(
jwt.getClaim(JwtTokenProvider.ROLES).asArray(String.class));
String subject = jwt.getSubject();

Expand All @@ -72,6 +75,12 @@ public Mono<Authentication> createAuthentication(String token) {
} catch (JWTVerificationException exception) {
log.warn("Cannot validate API Token: {}", exception.getMessage());
return Mono.error(new BadCredentialsException("API Token invalid", exception));
} catch (IllegalArgumentException exception) {
log.warn("The Token is malformed: {}", exception.getMessage());
return Mono.error(new BadCredentialsException("API Token malformed", exception));
} catch (Exception ex) {
log.error("Unexpected error while validating token: {}", ex.getMessage());
return Mono.error(new BadCredentialsException("API Token malformed"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public Mono<AuthorizationDecision> check(
String path = request.getPath().toString();
for (String pattern : authRoutes) {
if (pathMatcher.match(pattern, path)) {
log.debug("Route is allowed to bypass authorization");
log.debug("Route {} is allowed to bypass authorization (matches: {})", path, pattern);
return Mono.just(new AuthorizationDecision(true));
}
}
Expand Down
16 changes: 12 additions & 4 deletions webapp-example/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@
plugins {
id 'java'
id 'jacoco'
id 'org.springframework.boot' version '2.5.7'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'org.springframework.boot' version '3.1.5'
id 'io.spring.dependency-management' version '1.1.3'
}

group 'com.alertavert.opademo'
version = "0.3.0"
version = "0.4.0"

repositories {
// Adding local repository for Gradle to find jwt-opa before it gets published.
Expand All @@ -36,7 +36,7 @@ repositories {
ext {
// This can be changed to an yet-unpublished version by using mavenLocal()
// for local tests.
jwtOpaVersion = "0.9.0"
jwtOpaVersion = "0.10.0"
lombokVersion = "1.18.22"
tcVersion = "1.15.1"
}
Expand All @@ -48,9 +48,14 @@ bootJar {
dependencies {
// We use the actual dependency here, instead of depending on the module in the repository so
// as to emulate an actual project using jwt-opa externally.
// Uncomment the following line (and comment out the one below) to use the local version
// while developing.
implementation project (':jwt-opa')
// implementation "com.alertavert:jwt-opa:${jwtOpaVersion}"

// For the @PostConstruct annotation
implementation 'javax.annotation:javax.annotation-api:1.3.2'

compileOnly "org.projectlombok:lombok:${lombokVersion}"
annotationProcessor "org.projectlombok:lombok:${lombokVersion}"

Expand All @@ -64,6 +69,9 @@ dependencies {
implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
implementation 'commons-codec:commons-codec:1.13'

// For the @PostConstruct annotation
implementation 'javax.annotation:javax.annotation-api:1.3.2'

// Swagger 2 API & UI
// "Raw" JSON at http://localhost:8081/v2/api-docs
// UI at http://localhost:8081/swagger-ui/ (trailing slash matters)
Expand Down
15 changes: 8 additions & 7 deletions webapp-example/src/main/java/com/alertavert/opademo/DbInit.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@
import com.alertavert.opademo.api.UserController;
import com.alertavert.opademo.data.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
Expand All @@ -35,19 +33,21 @@
/**
* Initializes the DB with a seed `admin` user and a random password, if it doesn't already exist.
*/
@Profile("debug")
@Slf4j
@Component
public class DbInit {
@Autowired
UserController controller;
private final UserController controller;

@Value("${db.admin.username:admin}")
String adminUsername;

@Value("${db.admin.password}")
String adminPassword;

public DbInit(UserController controller) {
this.controller = controller;
}


@PostConstruct
public void initDb() {
Expand All @@ -57,7 +57,7 @@ public void initDb() {
adminUsername, adminPassword);
}
User admin = new User(adminUsername, adminPassword, "SYSTEM");

log.info("Creating admin user: {}", adminUsername);
controller.create(admin)
.doOnSuccess(responseEntity -> {
if (!responseEntity.getStatusCode().equals(HttpStatus.CREATED)) {
Expand All @@ -68,14 +68,15 @@ public void initDb() {
}
})
.doOnError(ResponseStatusException.class, ex -> {
if (ex.getStatus().equals(HttpStatus.CONFLICT)) {
if (ex.getStatusCode().equals(HttpStatus.CONFLICT)) {
log.info("User [{}] already exists in database, use existing credentials",
adminUsername);
} else {
log.error("Unexpected error when creating SYSTEM user", ex);
System.exit(1);
}
})
.onErrorComplete()
.subscribe();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.jackson.Jacksonized;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
Expand Down Expand Up @@ -54,14 +56,7 @@ public JwtController(JwtTokenProvider provider, ReactiveUsersRepository reposito
this.repository = repository;
}

@Data
@AllArgsConstructor
static class ApiToken {
String username;
List<String> roles;
@JsonProperty(API_TOKEN)
String apiToken;
}
record ApiToken(String username, List<String> roles, @JsonProperty(API_TOKEN) String apiToken) { }

@GetMapping(path = "/token/{user}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
public Mono<ResponseEntity<ApiToken>> getToken(@PathVariable String user) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,12 @@

package com.alertavert.opademo.api;

import com.alertavert.opademo.DbInit;
import com.alertavert.opademo.data.ReactiveUsersRepository;
import com.alertavert.opa.jwt.JwtTokenProvider;
import com.alertavert.opademo.data.ReactiveUsersRepository;
import com.alertavert.opademo.data.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.Base64Utils;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
Expand All @@ -38,6 +34,7 @@
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.UUID;

import static com.alertavert.opa.Constants.BASIC_AUTH;
Expand All @@ -56,14 +53,13 @@
consumes = MimeTypeUtils.ALL_VALUE)
public class LoginController {

@Autowired
JwtTokenProvider provider;
private final JwtTokenProvider provider;
private final ReactiveUsersRepository repository;

@Autowired
ReactiveUsersRepository repository;

@Autowired
PasswordEncoder encoder;
public LoginController(JwtTokenProvider provider, ReactiveUsersRepository repository) {
this.provider = provider;
this.repository = repository;
}


@GetMapping
Expand All @@ -82,7 +78,7 @@ Mono<JwtController.ApiToken> login(
})
.doOnNext(apiToken ->
log.debug("User authenticated, user = {}, token = {}...",
apiToken.getUsername(), apiToken.getApiToken().substring(0, MAX_TOKEN_LEN_LOG)));
apiToken.username(), apiToken.apiToken().substring(0, MAX_TOKEN_LEN_LOG)));
}

@GetMapping("/reset/{username}")
Expand Down Expand Up @@ -114,7 +110,7 @@ public static Mono<String> usernameFromHeader(String credentials) {
log.debug("Extracting username from Authorization header");
if (credentials.startsWith(BASIC_AUTH)) {
return Mono.just(credentials.substring(BASIC_AUTH.length() + 1))
.map(enc -> Base64Utils.decode(enc.getBytes(StandardCharsets.UTF_8)))
.map(enc -> Base64.getDecoder().decode(enc.getBytes(StandardCharsets.UTF_8)))
.map(String::new)
.map(creds -> {
String[] userPass = creds.split(":");
Expand All @@ -126,7 +122,7 @@ public static Mono<String> usernameFromHeader(String credentials) {
}

public static Mono<String> credentialsToHeader(String credentials) {
String encoded = Base64Utils.encodeToString(credentials.getBytes(StandardCharsets.UTF_8));
String encoded = Base64.getEncoder().encodeToString(credentials.getBytes(StandardCharsets.UTF_8));
return Mono.just(String.format("%s %s", BASIC_AUTH, encoded));
}
}
4 changes: 2 additions & 2 deletions webapp-example/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ keys:
# For a PASSPHRASE, the secret is simply read from SecretsManager/Vault
# The keypair is stored as a JSON-formatted secret, with two keys: "priv" and "pub".
location: keypair
name: ../private/ec-key
name: private/ec-key

logging:
level:
Expand Down Expand Up @@ -131,7 +131,7 @@ routes:
- "/health"
- "/demo"
- "/favicon.ico"
- "/login/reset/*"
#- "/login/reset/*"

# These will require the user to authenticate, but will not
# be subject to OPA Policies authorization check.
Expand Down
Loading

0 comments on commit 2132428

Please sign in to comment.