Skip to content

Commit

Permalink
Merge pull request #53 from Gepardec/feature/10Security
Browse files Browse the repository at this point in the history
PR: API Auth
  • Loading branch information
Jaroslav380 authored Feb 20, 2025
2 parents 59ed2ce + 6b5d59e commit f47833a
Show file tree
Hide file tree
Showing 32 changed files with 1,499 additions and 47 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ on:
jobs:
build-test-push:
runs-on: ubuntu-latest
env:
SECRET_JWT_HASH: ${{ secrets.SECRET_JWT_HASH }}
SECRET_DEFAULT_PW: ${{ secrets.SECRET_DEFAULT_PW }}

outputs:
branch_name: ${{ steps.branch.outputs.branch_name }}
Expand Down Expand Up @@ -39,7 +42,7 @@ jobs:
- name: Run integrationTests
run: |
docker run -d --name gamertrack-test-container -p 8080:8080 gamertrack-war:latest
docker run -d --name gamertrack-test-container -p 8080:8080 -e SECRET_JWT_HASH=${{ secrets.SECRET_JWT_HASH }} -e SECRET_DEFAULT_PW=${{ secrets.SECRET_DEFAULT_PW }} gamertrack-war:latest
until curl -s http://localhost:8080/gepardec-gamertrack/api/v1/health | grep -q "running"; do
echo "Waiting for the Application..."
Expand Down Expand Up @@ -95,4 +98,4 @@ jobs:
with:
sarif_file: 'trivy-results.sarif'
category: 'code'
wait-for-processing: true
wait-for-processing: true
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@ build/
.DS_Store

### WILDFLY PROVISIONED
/wildfly
/wildfly

secret.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package com.gepardec.rest.impl;

import com.gepardec.rest.model.command.AuthCredentialCommand;
import com.gepardec.rest.model.command.CreateUserCommand;
import io.github.cdimascio.dotenv.Dotenv;
import io.restassured.RestAssured;
import io.restassured.filter.log.LogDetail;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;

import static io.restassured.RestAssured.enableLoggingOfRequestAndResponseIfValidationFails;
import static io.restassured.RestAssured.with;
import static org.hamcrest.Matchers.equalTo;

public class AuthResourceImplIT {
static List<String> usedUserTokens = new ArrayList<>();
String bearerToken;

static Dotenv dotenv = Dotenv.configure().directory("../").filename("secret.env").ignoreIfMissing().load();
private static final String SECRET_DEFAULT_PW = dotenv.get("SECRET_DEFAULT_PW", System.getenv("SECRET_DEFAULT_PW"));
private static final String SECRET_ADMIN_NAME = dotenv.get("SECRET_ADMIN_NAME", System.getenv("SECRET_ADMIN_NAME"));


@BeforeAll
public static void setup() {
RestAssured.baseURI = "http://localhost:8080/gepardec-gamertrack/api/v1";
enableLoggingOfRequestAndResponseIfValidationFails(LogDetail.ALL);
}

@AfterEach
public void tearDown() {
for (String token : usedUserTokens) {
with()
.headers(
"Authorization",
"Bearer " + bearerToken,
"Content-Type",
ContentType.JSON,
"Accept",
ContentType.JSON)
.when()
.contentType("application/json")
.pathParam("token", token)
.request("DELETE", "/users/{token}")
;
}
}

@Test
public void createTestUserWithoutAuthHeader() {
with().when()
.contentType("application/json")
.body(new CreateUserCommand("max","Muster"))
.request("POST", "/users")
.then()
.statusCode(401);
}

@Test
public void createTestUserWithAuthHeader() {
String authHeader = with().when()
.contentType("application/json")
.body(new AuthCredentialCommand(SECRET_ADMIN_NAME,SECRET_DEFAULT_PW))
.headers("Content-Type", ContentType.JSON,
"Accept", ContentType.JSON)
.request("POST", "/auth/login")
.then()
.statusCode(200)
.extract()
.header("Authorization");

bearerToken = authHeader.replace("Bearer ", "");

String token = with().when()
.contentType("application/json")
.body(new CreateUserCommand("max","Muster"))
.headers(
"Authorization",
"Bearer " + bearerToken,
"Content-Type",
ContentType.JSON,
"Accept",
ContentType.JSON)
.request("POST", "/users")
.then()
.statusCode(201)
.assertThat()
.body("firstname", equalTo("max"))
.extract()
.path("token");
usedUserTokens.add(token);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.gepardec.rest.impl;

import com.gepardec.rest.model.command.AuthCredentialCommand;
import com.gepardec.rest.model.command.CreateGameCommand;
import com.gepardec.rest.model.command.UpdateGameCommand;
import com.gepardec.rest.model.dto.GameRestDto;
import io.github.cdimascio.dotenv.Dotenv;
import io.restassured.filter.log.LogDetail;
import io.restassured.http.ContentType;
import jakarta.ws.rs.core.Response.Status;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
Expand All @@ -21,18 +24,50 @@ public class GameResourceImplIT {

ArrayList<String> usesTokens = new ArrayList<>();

static String authHeader;
String bearerToken = authHeader.replace("Bearer ", "");

static Dotenv dotenv = Dotenv.configure().directory("../").filename("secret.env").ignoreIfMissing().load();
private static final String SECRET_DEFAULT_PW = dotenv.get("SECRET_DEFAULT_PW", System.getenv("SECRET_DEFAULT_PW"));
private static final String SECRET_ADMIN_NAME = dotenv.get("SECRET_ADMIN_NAME", System.getenv("SECRET_ADMIN_NAME"));



@BeforeAll
public static void setup() {
reset();
port = 8080;
basePath = "gepardec-gamertrack/api/v1/games";
basePath = "gepardec-gamertrack/api/v1";
enableLoggingOfRequestAndResponseIfValidationFails(LogDetail.ALL);

authHeader = with().when()
.contentType("application/json")
.body(new AuthCredentialCommand(SECRET_ADMIN_NAME,SECRET_DEFAULT_PW))
.headers("Content-Type", ContentType.JSON,
"Accept", ContentType.JSON)
.request("POST", "/auth/login")
.then()
.statusCode(200)
.extract()
.header("Authorization");
}

@AfterEach
public void after() {
for (String token : usesTokens) {
delete("/%s".formatted(token));
with()
.headers(
"Authorization",
"Bearer " + bearerToken,
"Content-Type",
ContentType.JSON,
"Accept",
ContentType.JSON)
.when()
.contentType("application/json")
.pathParam("token", token)
.request("DELETE", "/games/{token}")
;
}
}

Expand All @@ -49,7 +84,7 @@ void ensureGetGamesWithExistingGameReturns200OkWithListContainingGame() {
//WHEN THEN
var foundGames =
when()
.get()
.get("/games")
.then()
.statusCode(200)
.extract()
Expand All @@ -66,7 +101,7 @@ void ensureGetGameWithExistingGameReturnsGame() {

var foundGame =
when()
.get("/%s".formatted(existingGame.token()))
.get("/games/%s".formatted(existingGame.token()))
.then()
.statusCode(Status.OK.getStatusCode())
.extract()
Expand All @@ -80,7 +115,7 @@ void ensureGetGameWithExistingGameReturnsGame() {
@Test
void ensureGetGameWithNoExistingGameReturns404() {
when()
.get("askjfaskl1230qqis")
.get("/games/askjfaskl1230qqis")
.then()
.statusCode(Status.NOT_FOUND.getStatusCode());
}
Expand All @@ -91,10 +126,17 @@ void ensureCreateGameReturnsCreatedGameForValidGame() {

var responeObjectFromRequest =
with()
.headers(
"Authorization",
"Bearer " + bearerToken,
"Content-Type",
ContentType.JSON,
"Accept",
ContentType.JSON)
.body(gameToBeCreated)
.contentType("application/json")
.when()
.post()
.post("/games")
.then()
.statusCode(Status.CREATED.getStatusCode())
.body("token", notNullValue())
Expand All @@ -108,9 +150,16 @@ void ensureCreateGameReturnsCreatedGameForValidGame() {
void ensureCreateGameWithInvalidGameReturns400BadRequest() {

with()
.headers(
"Authorization",
"Bearer " + bearerToken,
"Content-Type",
ContentType.JSON,
"Accept",
ContentType.JSON)
.body(new CreateGameCommand("", "invalid game"))
.contentType("application/json")
.post()
.post("/games")
.then()
.statusCode(Status.BAD_REQUEST.getStatusCode());
}
Expand All @@ -122,9 +171,16 @@ void ensureUpdateGameReturnsForValidGameUpdatedGame() {
UpdateGameCommand gameToBeUpdated = new UpdateGameCommand("UpatedTestGame", "still no rules");

with()
.headers(
"Authorization",
"Bearer " + bearerToken,
"Content-Type",
ContentType.JSON,
"Accept",
ContentType.JSON)
.body(gameToBeUpdated)
.contentType("application/json")
.put("/%s".formatted(existingGame.token()))
.put("/games/%s".formatted(existingGame.token()))
.then()
.statusCode(Status.OK.getStatusCode())
.body("token", samePropertyValuesAs(existingGame.token()))
Expand All @@ -140,9 +196,16 @@ void ensureUpdateGameWithNotExistingGameReturns404NotFound() {
UpdateGameCommand gameToBeUpdated = new UpdateGameCommand("UpatedTestGame", "still no rules");

with()
.headers(
"Authorization",
"Bearer " + bearerToken,
"Content-Type",
ContentType.JSON,
"Accept",
ContentType.JSON)
.body(gameToBeUpdated)
.contentType("application/json")
.put("/asdaskjfalsfj")
.put("/games/asdaskjfalsfj")
.then()
.statusCode(Status.NOT_FOUND.getStatusCode());
}
Expand All @@ -168,11 +231,18 @@ void ensureDeleteExistingGameReturns200OkWithDeletedGame() {
public GameRestDto createGame() {
GameRestDto gameRestDto =
with()
.headers(
"Authorization",
"Bearer " + bearerToken,
"Content-Type",
ContentType.JSON,
"Accept",
ContentType.JSON)
.body(new CreateGameCommand("news game", "no rules"))
.contentType("application/json")
.accept("application/json")
.when()
.post()
.post("/games")
.then()
.statusCode(Status.CREATED.getStatusCode())
.extract()
Expand Down
Loading

0 comments on commit f47833a

Please sign in to comment.