Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: CI/CD Pipeline

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
build:
name: Build and Test
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: 17
distribution: 'temurin'

- name: Cache Maven dependencies
uses: actions/cache@v3
with:
path: ~/.m2
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-

- name: Build with Maven
run: mvn clean package

- name: Run tests
run: mvn test

docker:
name: Build and Push Docker Image
runs-on: ubuntu-latest
needs: build

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Build Docker image
run: docker build -t ${{ secrets.DOCKER_USERNAME }}/webgoat-legacy:latest .

- name: Push Docker image
run: docker push ${{ secrets.DOCKER_USERNAME }}/webgoat-legacy:latest

deploy:
name: Deploy to Server
runs-on: ubuntu-latest
needs: docker

steps:
- name: SSH and Deploy
uses: appleboy/[email protected]
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SERVER_SSH_KEY }}
script: |
docker pull ${{ secrets.DOCKER_USERNAME }}/webgoat-legacy:latest
docker stop webgoat || true
docker rm webgoat || true
docker run -d --name webgoat -p 8080:8080 ${{ secrets.DOCKER_USERNAME }}/webgoat-legacy:latest
23 changes: 23 additions & 0 deletions AuthController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.webgoat.controller;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;

@RestController
public class AuthController {

@PostMapping("/login")
public String login(@RequestBody Map<String, String> credentials) {
String username = credentials.get("username");
String password = credentials.get("password");

// Validate username and password (replace with actual validation logic)
if ("user".equals(username) && "password".equals(password)) {
return JwtUtil.generateToken(username);
} else {
return "Invalid credentials";
}
}
}
14 changes: 14 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Use an official OpenJDK runtime as a parent image
FROM openjdk:17-jdk-slim

# Set the working directory in the container
WORKDIR /app

# Copy the current directory contents into the container at /app
COPY . /app

# Expose the port the app runs on
EXPOSE 8080

# Run the application
CMD ["java", "-jar", "target/WebGoat-6.0-exec-war.jar"]
33 changes: 33 additions & 0 deletions JwtFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.webgoat.security;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;
import io.jsonwebtoken.Claims;
import java.io.IOException;

public class JwtFilter extends OncePerRequestFilter {

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
}

String token = authHeader.substring(7);
try {
Claims claims = JwtUtil.validateToken(token);
request.setAttribute("claims", claims);
} catch (Exception e) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
}

filterChain.doFilter(request, response);
}
}
28 changes: 28 additions & 0 deletions JwtUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.webgoat.security;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;

public class JwtUtil {

private static final String SECRET_KEY = "your-secret-key";
private static final long EXPIRATION_TIME = 86400000; // 1 day in milliseconds

public static String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}

public static Claims validateToken(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
}
}
31 changes: 31 additions & 0 deletions LessonContent.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';

const LessonContent = ({ userId, firstName, lastName, ssn, salary }) => {
return (
<div>
<h1>Lesson Content</h1>
<table style={{ width: '90%', border: '1px solid black', textAlign: 'center' }}>
<thead>
<tr>
<th>UserID</th>
<th>First Name</th>
<th>Last Name</th>
<th>SSN</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr>
<td>{userId}</td>
<td>{firstName}</td>
<td>{lastName}</td>
<td>{ssn}</td>
<td>{salary}</td>
</tr>
</tbody>
</table>
</div>
);
};

export default LessonContent;
27 changes: 27 additions & 0 deletions OAuth2Controller.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.webgoat.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class OAuth2Controller {

@GetMapping("/oauth2/authorize")
public String authorize() {
// Redirect to the OAuth2 provider's authorization endpoint
return "redirect:https://auth-server.com/oauth/authorize?client_id=your-client-id&response_type=code&redirect_uri=http://localhost:8080/oauth2/callback&scope=read,write";
}

@GetMapping("/oauth2/callback")
public String callback(@RequestParam("code") String code) {
// Exchange the authorization code for an access token
String accessToken = exchangeCodeForToken(code);
return "Access Token: " + accessToken;
}

private String exchangeCodeForToken(String code) {
// Logic to exchange the authorization code for an access token
return "dummy-access-token"; // Replace with actual token exchange logic
}
}
37 changes: 37 additions & 0 deletions OAuth2Filter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.webgoat.security;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;

public class OAuth2Filter extends OncePerRequestFilter {

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// Extract and validate OAuth2 token from the request
String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
}

String token = authHeader.substring(7);
// Validate the token (implementation depends on your OAuth2 provider)
boolean isValid = validateToken(token);
if (!isValid) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
}

filterChain.doFilter(request, response);
}

private boolean validateToken(String token) {
// Token validation logic (e.g., call the OAuth2 provider's introspection endpoint)
return true; // Replace with actual validation
}
}
Loading