diff --git a/.gitea/workflows/cleanup-branch.yaml b/.gitea/workflows/cleanup-branch.yaml new file mode 100644 index 0000000..fee5035 --- /dev/null +++ b/.gitea/workflows/cleanup-branch.yaml @@ -0,0 +1,21 @@ +name: Clean up branch.dsv.su.se +on: + pull_request: + types: + - closed +jobs: + Cleanup-branch: + runs-on: ubuntu-latest + steps: + - name: Generate mangled vhost name + id: mangled-name + run: | + MANGLED_BRANCH_NAME="$(echo ${{ gitea.headref}} | sed -r -e 's%/%-%g' -e 's/[^0-9a-z\-]//g')" + echo $MANGLED_BRANCH_NAME + echo "MANGLED_NAME=$MANGLED_BRANCH_NAME" >> "$GITHUB_OUTPUT" + - name: Set up SSH key + run: | + echo "${{ secrets.BRANCH_CLEANUP_KEY }}" >> ssh_key + chmod 0600 ssh_key + - name: Execute clean up script + run: echo "${{ gitea.serverurl }}/${{ gitea.repository }}.git ${{ gitea.headref }} ${{ steps.mangled-name.outputs.MANGLED_NAME }}" | ssh -o StrictHostKeyChecking=accept-new -i ssh_key branch.dsv.su.se diff --git a/.gitea/workflows/deploy-branch.yaml b/.gitea/workflows/deploy-branch.yaml new file mode 100644 index 0000000..00ec299 --- /dev/null +++ b/.gitea/workflows/deploy-branch.yaml @@ -0,0 +1,37 @@ +name: Deploy to branch.dsv.su.se +on: + pull_request: + types: + - opened + - reopened + - ready_for_review +jobs: + Deploy-branch: + runs-on: ubuntu-latest + steps: + - name: Generate mangled vhost name + id: mangled-name + run: | + MANGLED_BRANCH_NAME="$(echo ${{ gitea.headref}} | sed -r -e 's%/%-%g' -e 's/[^0-9a-z\-]//g')" + echo $MANGLED_BRANCH_NAME + echo "MANGLED_NAME=$MANGLED_BRANCH_NAME" >> "$GITHUB_OUTPUT" + - name: Set up SSH key + run: | + echo "${{ secrets.BRANCH_DEPLOY_KEY }}" >> ssh_key + chmod 0600 ssh_key + - name: Execute deploy script + run: echo "${{ gitea.serverurl }}/${{ gitea.repository }}.git ${{ gitea.headref }} ${{ steps.mangled-name.outputs.MANGLED_NAME }}" | ssh -o StrictHostKeyChecking=accept-new -i ssh_key branch.dsv.su.se + - name: Post URL to deployment as comment + uses: actions/github-script@v7 + env: + MANGLED_BRANCH_NAME: ${{ steps.mangled-name.outputs.MANGLED_NAME }} + with: + script: | + const repositoryName = context.repo.repo; + const mangledBranchName = process.env.MANGLED_BRANCH_NAME; + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `https://${repositoryName}-${mangledBranchName}.branch.dsv.su.se` + }) diff --git a/Dockerfile b/Dockerfile index 21df69f..54eef71 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,3 +17,5 @@ FROM tomcat:10-jdk21-openjdk-bookworm as run LABEL authors="thuning" COPY --from=build /build/target/*.war /usr/local/tomcat/webapps/ROOT.war + +EXPOSE 8080 diff --git a/docker-compose-branch.yml b/docker-compose-branch.yml new file mode 100644 index 0000000..6ecc964 --- /dev/null +++ b/docker-compose-branch.yml @@ -0,0 +1,57 @@ +services: + whisper-api: + build: + context: . + environment: + - DBHOST=jdbc:mariadb://whisper-api-db:3306/whisper_api + - DBUSER=root + - DBPASS=mariadb + - OAUTH2_CLIENT_ID=whisper-frontend + - OAUTH2_CLIENT_SECRET=s3cr3t + - OAUTH2_AUTH_URI=https://oauth2-${VHOST}/authorize + - OAUTH2_TOKEN_URI=https://oauth2-${VHOST}/exchange + - OAUTH2_USER_INFO_URI=https://oauth2-${VHOST}/verify + depends_on: + - whisper-api-db + - whisper-api-oauth2 + networks: + - whisper-network + - traefik + labels: + - "traefik.enable=true" + - "traefik.http.routers.${COMPOSE_PROJECT_NAME}.rule=Host(`${VHOST}`)" + - "traefik.http.routers.${COMPOSE_PROJECT_NAME}.entrypoints=secure" + - "traefik.http.routers.${COMPOSE_PROJECT_NAME}.tls.certresolver=letsencrypt" + + whisper-api-db: + image: mariadb + restart: on-failure + networks: + - whisper-network + environment: + - MARIADB_ROOT_PASSWORD=mariadb + - MARIADB_DATABASE=whisper_api + - MYSQL_ROOT_HOST=% + + whisper-api-oauth2: + build: + context: https://github.com/dsv-su/toker.git + dockerfile: embedded.Dockerfile + restart: on-failure + networks: + - traefik + environment: + CLIENT_ID: whisper-frontend + CLIENT_SECRET: s3cr3t + CLIENT_REDIRECT_URI: https://${VHOST}/login/oauth2/code/su + labels: + - "traefik.enable=true" + - "traefik.http.routers.${COMPOSE_PROJECT_NAME}-oauth2.rule=Host(`oauth2-${VHOST}`)" + - "traefik.http.routers.${COMPOSE_PROJECT_NAME}-oauth2.entrypoints=secure" + - "traefik.http.routers.${COMPOSE_PROJECT_NAME}-oauth2.tls.certresolver=letsencrypt" + +networks: + whisper-network: + traefik: + name: traefik + external: true diff --git a/src/main/java/se/su/dsv/whisperapi/WhisperApiApplication.java b/src/main/java/se/su/dsv/whisperapi/WhisperApiApplication.java index 0e652dd..078b689 100644 --- a/src/main/java/se/su/dsv/whisperapi/WhisperApiApplication.java +++ b/src/main/java/se/su/dsv/whisperapi/WhisperApiApplication.java @@ -2,10 +2,13 @@ package se.su.dsv.whisperapi; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; +import org.springframework.core.Ordered; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.web.filter.ForwardedHeaderFilter; @SpringBootApplication public class WhisperApiApplication { @@ -21,4 +24,11 @@ public class WhisperApiApplication { .oauth2Login(Customizer.withDefaults()); return http.build(); } + + @Bean + public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() { + var filterRegistrationBean = new FilterRegistrationBean<>(new ForwardedHeaderFilter()); + filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE); + return filterRegistrationBean; + } }