Add Checkstyle and Prettier to BFF #65
21
.gitea/workflows/code-style.yaml
Normal file
21
.gitea/workflows/code-style.yaml
Normal file
@ -0,0 +1,21 @@
|
||||
name: Code style BFF
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: bff
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 25
|
||||
cache: maven
|
||||
- name: Run checkstyle and prettier
|
||||
run: ./mvnw validate --batch-mode
|
||||
1
bff/.gitignore
vendored
1
bff/.gitignore
vendored
@ -1 +1,2 @@
|
||||
target/
|
||||
node_modules
|
||||
|
||||
2
bff/.prettierrc.yaml
Normal file
2
bff/.prettierrc.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
plugins:
|
||||
- prettier-plugin-java
|
||||
203
bff/checkstyle-configuration.xml
Normal file
203
bff/checkstyle-configuration.xml
Normal file
@ -0,0 +1,203 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
|
||||
"https://checkstyle.org/dtds/configuration_1_3.dtd">
|
||||
|
||||
<!--
|
||||
|
||||
Checkstyle configuration that checks the sun coding conventions from:
|
||||
|
||||
- the Java Language Specification at
|
||||
https://docs.oracle.com/javase/specs/jls/se11/html/index.html
|
||||
|
||||
- the Sun Code Conventions at https://www.oracle.com/java/technologies/javase/codeconventions-contents.html
|
||||
|
||||
- the Javadoc guidelines at
|
||||
https://www.oracle.com/technical-resources/articles/java/javadoc-tool.html
|
||||
|
||||
- the JDK Api documentation https://docs.oracle.com/en/java/javase/11/
|
||||
|
||||
- some best practices
|
||||
|
||||
Checkstyle is very configurable. Be sure to read the documentation at
|
||||
https://checkstyle.org (or in your downloaded distribution).
|
||||
|
||||
Most Checks are configurable, be sure to consult the documentation.
|
||||
|
||||
To completely disable a check, just comment it out or delete it from the file.
|
||||
To suppress certain violations please review suppression filters.
|
||||
|
||||
Finally, it is worth reading the documentation.
|
||||
|
||||
-->
|
||||
|
||||
<module name="Checker">
|
||||
<!--
|
||||
If you set the basedir property below, then all reported file
|
||||
names will be relative to the specified directory. See
|
||||
https://checkstyle.org/config.html#Checker
|
||||
|
||||
<property name="basedir" value="${basedir}"/>
|
||||
-->
|
||||
<property name="severity" value="error"/>
|
||||
|
||||
<property name="fileExtensions" value="java, properties, xml"/>
|
||||
|
||||
<!-- Excludes all 'module-info.java' files -->
|
||||
<!-- See https://checkstyle.org/filefilters/index.html -->
|
||||
<module name="BeforeExecutionExclusionFileFilter">
|
||||
<property name="fileNamePattern" value="module\-info\.java$"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/filters/suppressionfilter.html -->
|
||||
<module name="SuppressionFilter">
|
||||
<property name="file" value="${org.checkstyle.sun.suppressionfilter.config}"
|
||||
default="checkstyle-suppressions.xml" />
|
||||
<property name="optional" value="true"/>
|
||||
</module>
|
||||
|
||||
<!-- Checks whether files end with a new line. -->
|
||||
<!-- See https://checkstyle.org/checks/misc/newlineatendoffile.html -->
|
||||
<module name="NewlineAtEndOfFile"/>
|
||||
|
||||
<!-- Checks that property files contain the same keys. -->
|
||||
<!-- See https://checkstyle.org/checks/misc/translation.html -->
|
||||
<module name="Translation"/>
|
||||
|
||||
<!-- Checks for Size Violations. -->
|
||||
<!-- See https://checkstyle.org/checks/sizes/index.html -->
|
||||
<module name="FileLength"/>
|
||||
<module name="LineLength">
|
||||
<property name="fileExtensions" value="java"/>
|
||||
<property name="max" value="120"/>
|
||||
</module>
|
||||
|
||||
<!-- Checks for whitespace -->
|
||||
<!-- See https://checkstyle.org/checks/whitespace/index.html -->
|
||||
<module name="FileTabCharacter"/>
|
||||
|
||||
<!-- Miscellaneous other checks. -->
|
||||
<!-- See https://checkstyle.org/checks/misc/index.html -->
|
||||
<module name="RegexpSingleline">
|
||||
<property name="format" value="\s+$"/>
|
||||
<property name="minimum" value="0"/>
|
||||
<property name="maximum" value="0"/>
|
||||
<property name="message" value="Line has trailing spaces."/>
|
||||
</module>
|
||||
|
||||
<module name="TreeWalker">
|
||||
|
||||
<!-- Checks for Javadoc comments. -->
|
||||
<!-- See https://checkstyle.org/checks/javadoc/index.html -->
|
||||
<module name="InvalidJavadocPosition"/>
|
||||
<module name="JavadocMethod">
|
||||
<property name="allowMissingParamTags" value="true"/>
|
||||
<property name="allowMissingReturnTag" value="true"/>
|
||||
</module>
|
||||
<module name="JavadocType">
|
||||
<property name="allowMissingParamTags" value="true"/>
|
||||
</module>
|
||||
<module name="JavadocStyle"/>
|
||||
|
||||
<!-- Checks for Naming Conventions. -->
|
||||
<!-- See https://checkstyle.org/checks/naming/index.html -->
|
||||
<module name="ConstantName"/>
|
||||
<module name="LocalFinalVariableName"/>
|
||||
<module name="LocalVariableName"/>
|
||||
<module name="MemberName"/>
|
||||
<module name="MethodName">
|
||||
<property name="format" value="^[a-z][a-zA-Z0-9_]*$"/>
|
||||
</module>
|
||||
<module name="PackageName"/>
|
||||
<module name="ParameterName"/>
|
||||
<module name="StaticVariableName"/>
|
||||
<module name="TypeName"/>
|
||||
|
||||
<!-- Checks for imports -->
|
||||
<!-- See https://checkstyle.org/checks/imports/index.html -->
|
||||
<module name="AvoidStarImport"/>
|
||||
<module name="IllegalImport"/> <!-- defaults to sun.* packages -->
|
||||
<module name="RedundantImport"/>
|
||||
<module name="UnusedImports"/>
|
||||
|
||||
<!-- Checks for Size Violations. -->
|
||||
<!-- See https://checkstyle.org/checks/sizes/index.html -->
|
||||
<module name="MethodLength"/>
|
||||
<module name="ParameterNumber">
|
||||
<property name="max" value="15"/>
|
||||
</module>
|
||||
|
||||
<!-- Checks for whitespace -->
|
||||
<!-- See https://checkstyle.org/checks/whitespace/index.html -->
|
||||
<module name="EmptyForIteratorPad"/>
|
||||
<module name="GenericWhitespace"/>
|
||||
<module name="MethodParamPad"/>
|
||||
<module name="NoWhitespaceAfter"/>
|
||||
<module name="NoWhitespaceBefore"/>
|
||||
<module name="OperatorWrap"/>
|
||||
<module name="ParenPad"/>
|
||||
<module name="TypecastParenPad"/>
|
||||
<module name="WhitespaceAfter"/>
|
||||
<module name="WhitespaceAround">
|
||||
<property name="allowEmptyConstructors" value="true"/>
|
||||
<property name="allowEmptyMethods" value="true"/>
|
||||
<property name="allowEmptyTypes" value="true"/>
|
||||
<property name="allowEmptyLambdas" value="true"/>
|
||||
</module>
|
||||
|
||||
<!-- Modifier Checks -->
|
||||
<!-- See https://checkstyle.org/checks/modifier/index.html -->
|
||||
<module name="ModifierOrder"/>
|
||||
<module name="RedundantModifier"/>
|
||||
|
||||
<!-- Checks for blocks. You know, those {}'s -->
|
||||
<!-- See https://checkstyle.org/checks/blocks/index.html -->
|
||||
<module name="AvoidNestedBlocks"/>
|
||||
<module name="EmptyBlock"/>
|
||||
<module name="LeftCurly">
|
||||
<property name="option" value="eol"/>
|
||||
</module>
|
||||
<module name="NeedBraces">
|
||||
<property name="allowSingleLineStatement" value="true"/>
|
||||
</module>
|
||||
<module name="RightCurly"/>
|
||||
|
||||
<!-- Checks for common coding problems -->
|
||||
<!-- See https://checkstyle.org/checks/coding/index.html -->
|
||||
<module name="EmptyStatement"/>
|
||||
<module name="EqualsHashCode"/>
|
||||
<module name="HiddenField">
|
||||
<property name="ignoreConstructorParameter" value="true"/>
|
||||
<property name="ignoreSetter" value="true"/>
|
||||
</module>
|
||||
<module name="IllegalInstantiation"/>
|
||||
<module name="InnerAssignment"/>
|
||||
<module name="MagicNumber"/>
|
||||
<module name="MissingSwitchDefault"/>
|
||||
<module name="MultipleVariableDeclarations"/>
|
||||
<module name="SimplifyBooleanExpression"/>
|
||||
<module name="SimplifyBooleanReturn"/>
|
||||
|
||||
<!-- Checks for class design -->
|
||||
<!-- See https://checkstyle.org/checks/design/index.html -->
|
||||
<module name="FinalClass"/>
|
||||
<module name="HideUtilityClassConstructor"/>
|
||||
<module name="InterfaceIsType"/>
|
||||
<module name="VisibilityModifier"/>
|
||||
|
||||
<!-- Miscellaneous other checks. -->
|
||||
<!-- See https://checkstyle.org/checks/misc/index.html -->
|
||||
<module name="ArrayTypeStyle"/>
|
||||
<module name="TodoComment"/>
|
||||
<module name="UpperEll"/>
|
||||
|
||||
<!-- https://checkstyle.org/filters/suppressionxpathfilter.html -->
|
||||
<module name="SuppressionXpathFilter">
|
||||
<property name="file" value="${org.checkstyle.sun.suppressionxpathfilter.config}"
|
||||
default="checkstyle-xpath-suppressions.xml" />
|
||||
<property name="optional" value="true"/>
|
||||
</module>
|
||||
|
||||
</module>
|
||||
|
||||
</module>
|
||||
9
bff/checkstyle-suppressions.xml
Normal file
9
bff/checkstyle-suppressions.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE suppressions PUBLIC
|
||||
"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
|
||||
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
|
||||
<suppressions>
|
||||
<suppress files=".*[\\/]target[\\/]generated-sources[\\/].*" checks=".*"/>
|
||||
<suppress checks="HideUtilityClassConstructor"
|
||||
files="Studentportalen\.java"/>
|
||||
</suppressions>
|
||||
140
bff/package-lock.json
generated
Normal file
140
bff/package-lock.json
generated
Normal file
@ -0,0 +1,140 @@
|
||||
{
|
||||
"name": "bff",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"devDependencies": {
|
||||
"prettier-plugin-java": "^2.8.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@chevrotain/cst-dts-gen": {
|
||||
"version": "11.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz",
|
||||
"integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@chevrotain/gast": "11.0.3",
|
||||
"@chevrotain/types": "11.0.3",
|
||||
"lodash-es": "4.17.21"
|
||||
}
|
||||
},
|
||||
"node_modules/@chevrotain/gast": {
|
||||
"version": "11.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz",
|
||||
"integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@chevrotain/types": "11.0.3",
|
||||
"lodash-es": "4.17.21"
|
||||
}
|
||||
},
|
||||
"node_modules/@chevrotain/regexp-to-ast": {
|
||||
"version": "11.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz",
|
||||
"integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@chevrotain/types": {
|
||||
"version": "11.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz",
|
||||
"integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@chevrotain/utils": {
|
||||
"version": "11.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz",
|
||||
"integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/chevrotain": {
|
||||
"version": "11.0.3",
|
||||
"resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz",
|
||||
"integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@chevrotain/cst-dts-gen": "11.0.3",
|
||||
"@chevrotain/gast": "11.0.3",
|
||||
"@chevrotain/regexp-to-ast": "11.0.3",
|
||||
"@chevrotain/types": "11.0.3",
|
||||
"@chevrotain/utils": "11.0.3",
|
||||
"lodash-es": "4.17.21"
|
||||
}
|
||||
},
|
||||
"node_modules/chevrotain-allstar": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz",
|
||||
"integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lodash-es": "^4.17.21"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"chevrotain": "^11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/java-parser": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/java-parser/-/java-parser-3.0.1.tgz",
|
||||
"integrity": "sha512-sDIR7u9b7O2JViNUxiZRhnRz7URII/eE7g2B+BmGxDeS6Ex3OYAcCyz5oh0H4LQ+hL/BS8OJTz8apMy9xtGmrQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"chevrotain": "11.0.3",
|
||||
"chevrotain-allstar": "0.3.1",
|
||||
"lodash": "4.17.21"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash-es": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
||||
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.7.4",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz",
|
||||
"integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier-plugin-java": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier-plugin-java/-/prettier-plugin-java-2.8.1.tgz",
|
||||
"integrity": "sha512-tkteH5OSCEb0E7wKnhhUSitr1pGUCUt9M//CwerSNhoalL/qv0jXTeSVBPZ36KC+kZl3nbq4dxh144NuGchACg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"java-parser": "3.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"prettier": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
5
bff/package.json
Normal file
5
bff/package.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"devDependencies": {
|
||||
"prettier-plugin-java": "^2.8.1"
|
||||
}
|
||||
}
|
||||
85
bff/pom.xml
85
bff/pom.xml
@ -20,6 +20,7 @@
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>25</java.version>
|
||||
<springdoc.version>2.8.6</springdoc.version>
|
||||
<checkstyle.version>10.21.4</checkstyle.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@ -60,8 +61,92 @@
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.puppycrawl.tools</groupId>
|
||||
<artifactId>checkstyle</artifactId>
|
||||
<version>${checkstyle.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<configuration>
|
||||
<configLocation>checkstyle-configuration.xml</configLocation>
|
||||
<consoleOutput>true</consoleOutput>
|
||||
<failsOnError>true</failsOnError>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.hubspot.maven.plugins</groupId>
|
||||
<artifactId>prettier-maven-plugin</artifactId>
|
||||
<version>0.22</version>
|
||||
<configuration>
|
||||
<prettierJavaVersion>2.8.1</prettierJavaVersion>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.github.eirslett</groupId>
|
||||
<artifactId>frontend-maven-plugin</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<configuration>
|
||||
<nodeVersion>v22.13.0</nodeVersion>
|
||||
<installDirectory>${project.build.directory}</installDirectory>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>validate</id>
|
||||
<phase>validate</phase>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.github.eirslett</groupId>
|
||||
<artifactId>frontend-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>install-node-and-npm</id>
|
||||
<phase>validate</phase>
|
||||
<goals>
|
||||
<goal>install-node-and-npm</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>npm-install</id>
|
||||
<phase>validate</phase>
|
||||
<goals>
|
||||
<goal>npm</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<arguments>install</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.hubspot.maven.plugins</groupId>
|
||||
<artifactId>prettier-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>validate</phase>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
|
||||
@ -3,5 +3,4 @@ package se.su.dsv.studentportalen.bff.config;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@ConfigurationProperties("se.su.dsv.backend-api")
|
||||
public record BackendApiConfiguration(String daisyUrl) {
|
||||
}
|
||||
public record BackendApiConfiguration(String daisyUrl) {}
|
||||
|
||||
@ -6,7 +6,9 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
public record FrontendConfiguration(String url) {
|
||||
public FrontendConfiguration {
|
||||
if (url == null || url.isBlank()) {
|
||||
throw new IllegalArgumentException("se.su.dsv.frontend.url must not be null or blank");
|
||||
throw new IllegalArgumentException(
|
||||
"se.su.dsv.frontend.url must not be null or blank"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package se.su.dsv.studentportalen.bff.config;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
@ -7,34 +8,42 @@ import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import se.su.dsv.studentportalen.bff.login.BFFAuthenticationEntryPoint;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Configuration
|
||||
public class SecurityConfiguration {
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain securityFilterChain(
|
||||
HttpSecurity http,
|
||||
FrontendConfiguration frontendConfiguration)
|
||||
throws Exception
|
||||
{
|
||||
http.exceptionHandling(exception -> exception
|
||||
.authenticationEntryPoint(new BFFAuthenticationEntryPoint()));
|
||||
http.oauth2Login(login -> login
|
||||
.defaultSuccessUrl(frontendConfiguration.url(), true));
|
||||
http.authorizeHttpRequests(authorize -> authorize
|
||||
.requestMatchers("/swagger", "/swagger-ui/**", "/v3/api-docs/**").permitAll()
|
||||
.anyRequest().authenticated());
|
||||
http.cors(cors -> cors
|
||||
.configurationSource(_ -> frontendOnlyCors(frontendConfiguration)));
|
||||
FrontendConfiguration frontendConfiguration
|
||||
) throws Exception {
|
||||
http.exceptionHandling(exception ->
|
||||
exception.authenticationEntryPoint(new BFFAuthenticationEntryPoint())
|
||||
);
|
||||
http.oauth2Login(login ->
|
||||
login.defaultSuccessUrl(frontendConfiguration.url(), true)
|
||||
);
|
||||
http.authorizeHttpRequests(authorize ->
|
||||
authorize
|
||||
.requestMatchers("/swagger", "/swagger-ui/**", "/v3/api-docs/**")
|
||||
.permitAll()
|
||||
.anyRequest()
|
||||
.authenticated()
|
||||
);
|
||||
http.cors(cors ->
|
||||
cors.configurationSource(_ -> frontendOnlyCors(frontendConfiguration))
|
||||
);
|
||||
http.csrf(csrf -> csrf.spa());
|
||||
return http.build();
|
||||
}
|
||||
|
||||
private static CorsConfiguration frontendOnlyCors(FrontendConfiguration frontendConfiguration) {
|
||||
private static CorsConfiguration frontendOnlyCors(
|
||||
FrontendConfiguration frontendConfiguration
|
||||
) {
|
||||
var corsConfiguration = new CorsConfiguration();
|
||||
corsConfiguration.setAllowedOrigins(List.of(frontendConfiguration.url()));
|
||||
corsConfiguration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));
|
||||
corsConfiguration.setAllowedMethods(
|
||||
List.of("GET", "POST", "PUT", "DELETE")
|
||||
);
|
||||
|
||||
// Allow the frontend to see the X-Authorization-Url header
|
||||
corsConfiguration.setExposedHeaders(List.of("X-Authorization-Url"));
|
||||
@ -45,7 +54,9 @@ public class SecurityConfiguration {
|
||||
// Content-Type is allowed by default but with a restriction on the value
|
||||
// The restriction does not allow "application/json" so we add it as an allowed header
|
||||
// X-XSRF-TOKEN is needed for CSRF protection
|
||||
corsConfiguration.setAllowedHeaders(List.of("Content-Type", "X-XSRF-TOKEN"));
|
||||
corsConfiguration.setAllowedHeaders(
|
||||
List.of("Content-Type", "X-XSRF-TOKEN")
|
||||
);
|
||||
return corsConfiguration;
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,8 +24,8 @@ public class ProfileController {
|
||||
|
||||
@GetMapping("/profile")
|
||||
public ProfileResponse getProfile(
|
||||
@AuthenticationPrincipal(errorOnInvalidType = true) OAuth2User currentUser)
|
||||
{
|
||||
@AuthenticationPrincipal(errorOnInvalidType = true) OAuth2User currentUser
|
||||
) {
|
||||
return service.getProfile(currentUser);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,15 +1,14 @@
|
||||
package se.su.dsv.studentportalen.bff.controller;
|
||||
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestClient;
|
||||
import se.su.dsv.studentportalen.bff.config.BackendApiConfiguration;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.StructuredTaskScope;
|
||||
import java.util.concurrent.StructuredTaskScope.Subtask;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestClient;
|
||||
import se.su.dsv.studentportalen.bff.config.BackendApiConfiguration;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/test")
|
||||
@ -34,7 +33,8 @@ public class TestController {
|
||||
// Pick the scope based on the desired behaviour
|
||||
try (var scope = StructuredTaskScope.open()) {
|
||||
Subtask<String> nameTask = scope.fork(() -> {
|
||||
String name = restClient.get()
|
||||
String name = restClient
|
||||
.get()
|
||||
.uri("/test/name")
|
||||
.retrieve()
|
||||
.body(String.class);
|
||||
@ -42,7 +42,8 @@ public class TestController {
|
||||
});
|
||||
|
||||
Subtask<String> emailTask = scope.fork(() -> {
|
||||
String email = restClient.get()
|
||||
String email = restClient
|
||||
.get()
|
||||
.uri("/test/email")
|
||||
.retrieve()
|
||||
.body(String.class);
|
||||
@ -50,10 +51,11 @@ public class TestController {
|
||||
});
|
||||
|
||||
Subtask<DaisyProfile> daisyProfile = scope.fork(() -> {
|
||||
DaisyProfile profile = restClient.get()
|
||||
.uri(backendApiConfiguration.daisyUrl(), builder -> builder
|
||||
.path("/profile")
|
||||
.build())
|
||||
DaisyProfile profile = restClient
|
||||
.get()
|
||||
.uri(backendApiConfiguration.daisyUrl(), builder ->
|
||||
builder.path("/profile").build()
|
||||
)
|
||||
.retrieve()
|
||||
.body(DaisyProfile.class);
|
||||
return profile;
|
||||
@ -65,7 +67,8 @@ public class TestController {
|
||||
return "Hello, I am %s and my email is %s. My Daisy profile is: %s".formatted(
|
||||
nameTask.get(),
|
||||
emailTask.get(),
|
||||
daisyProfile.get());
|
||||
daisyProfile.get()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,22 +1,21 @@
|
||||
package se.su.dsv.studentportalen.bff.dto.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* User profile information.
|
||||
*/
|
||||
public record ProfileResponse(
|
||||
@JsonProperty(value = "name", required = true)
|
||||
String name,
|
||||
@JsonProperty(value = "name", required = true) String name,
|
||||
|
||||
@JsonProperty(value = "language", required = true)
|
||||
Language language)
|
||||
{
|
||||
@JsonProperty(value = "language", required = true) Language language
|
||||
) {
|
||||
public enum Language {
|
||||
@JsonProperty("sv") SWEDISH,
|
||||
@JsonProperty("en") ENGLISH
|
||||
@JsonProperty("sv")
|
||||
SWEDISH,
|
||||
@JsonProperty("en")
|
||||
ENGLISH,
|
||||
}
|
||||
|
||||
public ProfileResponse {
|
||||
|
||||
@ -7,12 +7,13 @@ import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
|
||||
|
||||
public class BFFAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||
|
||||
@Override
|
||||
public void commence(
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
AuthenticationException authException)
|
||||
{
|
||||
AuthenticationException authException
|
||||
) {
|
||||
String loginUri = ServletUriComponentsBuilder.fromRequest(request)
|
||||
.replacePath("/oauth2/authorization/studentportalen")
|
||||
.build()
|
||||
|
||||
@ -5,6 +5,10 @@ WORKDIR /build
|
||||
COPY mvnw mvnw
|
||||
COPY .mvn/ .mvn/
|
||||
COPY pom.xml pom.xml
|
||||
COPY checkstyle-configuration.xml checkstyle-configuration.xml
|
||||
COPY checkstyle-suppressions.xml checkstyle-suppressions.xml
|
||||
COPY package.json package.json
|
||||
COPY package-lock.json package-lock.json
|
||||
|
||||
RUN ./mvnw dependency:go-offline \
|
||||
--batch-mode \
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user