initial version
This commit is contained in:
parent
dccfe2c742
commit
566606b000
30
.classpath
Normal file
30
.classpath
Normal file
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/test" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="test"/>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer">
|
||||
<attributes>
|
||||
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/.gradle/
|
||||
/bin/
|
||||
/build/
|
41
.project
Normal file
41
.project
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>JFileCloud</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.springframework.ide.eclipse.boot.validation.springbootbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
|
||||
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
13
.settings/org.eclipse.buildship.core.prefs
Normal file
13
.settings/org.eclipse.buildship.core.prefs
Normal file
@ -0,0 +1,13 @@
|
||||
arguments=
|
||||
auto.sync=false
|
||||
build.scans.enabled=false
|
||||
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
|
||||
connection.project.dir=
|
||||
eclipse.preferences.version=1
|
||||
gradle.user.home=
|
||||
java.home=
|
||||
jvm.arguments=
|
||||
offline.mode=false
|
||||
override.workspace.settings=false
|
||||
show.console.view=true
|
||||
show.executions.view=true
|
4
.settings/org.eclipse.jdt.core.prefs
Normal file
4
.settings/org.eclipse.jdt.core.prefs
Normal file
@ -0,0 +1,4 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=21
|
||||
org.eclipse.jdt.core.compiler.compliance=21
|
||||
org.eclipse.jdt.core.compiler.source=21
|
16
.settings/org.eclipse.wst.common.component
Normal file
16
.settings/org.eclipse.wst.common.component
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
|
||||
|
||||
<wb-module deploy-name="JFileCloud">
|
||||
|
||||
<property name="context-root" value="JFileCloud"/>
|
||||
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/resources"/>
|
||||
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/java"/>
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/test/java"/>
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
|
||||
|
||||
</wb-module>
|
||||
|
||||
</project-modules>
|
7
.settings/org.eclipse.wst.common.project.facet.core.xml
Normal file
7
.settings/org.eclipse.wst.common.project.facet.core.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<faceted-project>
|
||||
<fixed facet="jst.java"/>
|
||||
<fixed facet="jst.web"/>
|
||||
<installed facet="jst.web" version="2.4"/>
|
||||
<installed facet="jst.java" version="21"/>
|
||||
</faceted-project>
|
2
.settings/org.springframework.ide.eclipse.prefs
Normal file
2
.settings/org.springframework.ide.eclipse.prefs
Normal file
@ -0,0 +1,2 @@
|
||||
boot.validation.initialized=true
|
||||
eclipse.preferences.version=1
|
76
build.gradle
Normal file
76
build.gradle
Normal file
@ -0,0 +1,76 @@
|
||||
plugins {
|
||||
id 'org.springframework.boot' version '3.4.3'
|
||||
id 'java'
|
||||
id 'war'
|
||||
}
|
||||
|
||||
apply plugin: 'io.spring.dependency-management'
|
||||
|
||||
group = 'de.jottyfan'
|
||||
version = '0.0.0'
|
||||
|
||||
description = """JFileCloud"""
|
||||
|
||||
sourceCompatibility = 21
|
||||
targetCompatibility = 21
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
maven { url "https://www.jottyfan.de/libs" }
|
||||
maven { url "https://repo.maven.apache.org/maven2" }
|
||||
// maven { url "https://gitlab.com/jottyfan/libs/-/raw/main" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'org.apache.logging.log4j:log4j-api:2.24.3'
|
||||
implementation 'org.apache.logging.log4j:log4j-core:2.24.3'
|
||||
implementation 'org.apache.logging.log4j:log4j-to-slf4j:2.24.3'
|
||||
|
||||
implementation 'org.webjars:bootstrap:5.3.3'
|
||||
implementation 'org.webjars:font-awesome:6.7.2'
|
||||
implementation 'org.webjars:jquery:3.7.1'
|
||||
implementation 'org.webjars:popper.js:2.11.7'
|
||||
implementation 'org.webjars:datatables:2.1.8'
|
||||
implementation 'org.webjars:jquery-ui:1.14.1'
|
||||
|
||||
implementation 'com.google.code.gson:gson:2.12.1';
|
||||
|
||||
implementation 'org.springframework.boot:spring-boot-starter-jooq'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-security'
|
||||
implementation "org.springframework.boot:spring-boot-starter-oauth2-client"
|
||||
implementation 'org.springframework.security:spring-security-oauth2-authorization-server:1.4.2'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
|
||||
|
||||
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:3.4.0'
|
||||
|
||||
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
||||
runtimeOnly 'org.postgresql:postgresql'
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
testImplementation 'org.springframework.security:spring-security-test'
|
||||
}
|
||||
|
||||
war {
|
||||
doFirst {
|
||||
manifest {
|
||||
attributes("Implementation-Title": project.name,
|
||||
"Implementation-Version": version,
|
||||
"Implementation-Timestamp": new Date())
|
||||
}
|
||||
}
|
||||
archiveBaseName = project.name
|
||||
archiveVersion = version
|
||||
archiveFileName = 'JFileCloud.war'
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
// add version to manifest
|
||||
springBoot {
|
||||
buildInfo()
|
||||
}
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
172
gradlew
vendored
Executable file
172
gradlew
vendored
Executable file
@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS --illegal-access=permit $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
84
gradlew.bat
vendored
Normal file
84
gradlew.bat
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
1
settings.gradle
Normal file
1
settings.gradle
Normal file
@ -0,0 +1 @@
|
||||
rootProject.name = 'JFileCloud'
|
32
src/main/java/de/jottyfan/jfilecloud/Main.java
Normal file
32
src/main/java/de/jottyfan/jfilecloud/Main.java
Normal file
@ -0,0 +1,32 @@
|
||||
package de.jottyfan.jfilecloud;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jotty
|
||||
*
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableTransactionManagement
|
||||
public class Main extends SpringBootServletInitializer {
|
||||
|
||||
public static final Logger LOGGER = LogManager.getLogger(Main.class);
|
||||
|
||||
@Override
|
||||
protected SpringApplicationBuilder configure(
|
||||
SpringApplicationBuilder application) {
|
||||
return application.sources(Main.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Main.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package de.jottyfan.jfilecloud.config;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
|
||||
import org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority;
|
||||
import org.springframework.security.oauth2.core.user.OAuth2UserAuthority;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jotty
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
public class AuthorizationConfiguration {
|
||||
|
||||
private static final String REALM_ACCESS_CLAIM = "realm_access";
|
||||
private static final String ROLES_CLAIM = "roles";
|
||||
private static final String RESOURCE_ACCESS_CLAIM = "resource_access";
|
||||
|
||||
@Value("${spring.security.oauth2.client.registration.keycloak.client-id}")
|
||||
private String clientId;
|
||||
|
||||
@Bean
|
||||
GrantedAuthoritiesMapper userAuthoritiesMapperForKeycloak() {
|
||||
return authorities -> {
|
||||
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
|
||||
var authority = authorities.iterator().next();
|
||||
boolean isOidc = authority instanceof OidcUserAuthority;
|
||||
|
||||
if (isOidc) {
|
||||
var oidcUserAuthority = (OidcUserAuthority) authority;
|
||||
var userInfo = oidcUserAuthority.getUserInfo();
|
||||
|
||||
if (userInfo.hasClaim(REALM_ACCESS_CLAIM)) {
|
||||
var realmAccess = userInfo.getClaimAsMap(REALM_ACCESS_CLAIM);
|
||||
@SuppressWarnings("unchecked")
|
||||
var roles = (Collection<String>) realmAccess.get(ROLES_CLAIM);
|
||||
mappedAuthorities.addAll(generateAuthoritiesFromClaim(roles));
|
||||
}
|
||||
if (userInfo.hasClaim(RESOURCE_ACCESS_CLAIM)) {
|
||||
var resourceAccess = userInfo.getClaimAsMap(RESOURCE_ACCESS_CLAIM);
|
||||
if (resourceAccess.containsKey(clientId)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
var roles = (Collection<String>) ((Map<?, ?>) resourceAccess.get(clientId)).get(ROLES_CLAIM);
|
||||
mappedAuthorities.addAll(generateAuthoritiesFromClaim(roles));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var oauth2UserAuthority = (OAuth2UserAuthority) authority;
|
||||
Map<String, Object> userAttributes = oauth2UserAuthority.getAttributes();
|
||||
|
||||
if (userAttributes.containsKey(REALM_ACCESS_CLAIM)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
var realmAccess = (Map<String, Object>) userAttributes.get(REALM_ACCESS_CLAIM);
|
||||
@SuppressWarnings("unchecked")
|
||||
var roles = (Collection<String>) realmAccess.get(ROLES_CLAIM);
|
||||
mappedAuthorities.addAll(generateAuthoritiesFromClaim(roles));
|
||||
}
|
||||
}
|
||||
|
||||
return mappedAuthorities;
|
||||
};
|
||||
}
|
||||
|
||||
private Collection<GrantedAuthority> generateAuthoritiesFromClaim(Collection<String> roles) {
|
||||
return roles.stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role)).collect(Collectors.toList());
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package de.jottyfan.jfilecloud.config;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.impl.DataSourceConnectionProvider;
|
||||
import org.jooq.impl.DefaultConfiguration;
|
||||
import org.jooq.impl.DefaultDSLContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jotty
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
public class InitialConfiguration {
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
@Bean
|
||||
public DataSourceConnectionProvider connectionProvider() {
|
||||
return new DataSourceConnectionProvider(new TransactionAwareDataSourceProxy(dataSource));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DefaultDSLContext dsl() {
|
||||
return new DefaultDSLContext(configuration());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public String disableLogo() {
|
||||
System.setProperty("org.jooq.no-logo", "true");
|
||||
return null;
|
||||
}
|
||||
|
||||
public DefaultConfiguration configuration() {
|
||||
DefaultConfiguration jooqConfiguration = new DefaultConfiguration();
|
||||
jooqConfiguration.set(connectionProvider());
|
||||
jooqConfiguration.set(SQLDialect.POSTGRES);
|
||||
return jooqConfiguration;
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package de.jottyfan.jfilecloud.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.oauth2.client.oidc.web.logout.OidcClientInitiatedLogoutSuccessHandler;
|
||||
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
|
||||
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jotty
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@EnableMethodSecurity
|
||||
public class SecurityConfiguration {
|
||||
|
||||
@Bean
|
||||
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
|
||||
return new NullAuthenticatedSessionStrategy();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain securityFilterChain(HttpSecurity sec, InMemoryClientRegistrationRepository crr)
|
||||
throws Exception {
|
||||
sec.csrf(o -> o.disable()).anonymous(o -> o.disable())
|
||||
// @formatter:off
|
||||
.oauth2Login(o -> o.defaultSuccessUrl("/"))
|
||||
.logout(o -> o.logoutSuccessHandler(new OidcClientInitiatedLogoutSuccessHandler(crr)))
|
||||
.authorizeHttpRequests(o -> o.requestMatchers(
|
||||
AntPathRequestMatcher.antMatcher("/public/**"),
|
||||
AntPathRequestMatcher.antMatcher("/theme/**")
|
||||
).permitAll().anyRequest().authenticated())
|
||||
.oauth2ResourceServer(o -> o.jwt(Customizer.withDefaults()))
|
||||
.sessionManagement(o -> o.init(sec));
|
||||
// @formatter:on
|
||||
return sec.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package de.jottyfan.jfilecloud.modules;
|
||||
|
||||
import org.springframework.ui.Model;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jotty
|
||||
*
|
||||
*/
|
||||
public abstract class CommonController {
|
||||
|
||||
public void setStandardAttributes(final Model model) {
|
||||
model.addAttribute("theme", "dark");
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package de.jottyfan.jfilecloud.modules.dashboard;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
import de.jottyfan.jfilecloud.modules.CommonController;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jotty
|
||||
*
|
||||
*/
|
||||
@Controller
|
||||
public class DashboardController extends CommonController {
|
||||
|
||||
@GetMapping("/")
|
||||
public String getIndex() {
|
||||
return "redirect:/dashboard";
|
||||
}
|
||||
|
||||
@GetMapping("/dashboard")
|
||||
public String getDashboard(final Model model) {
|
||||
super.setStandardAttributes(model);
|
||||
// TODO: implement
|
||||
return "/dashboard";
|
||||
}
|
||||
}
|
24
src/main/resources/application.properties
Normal file
24
src/main/resources/application.properties
Normal file
@ -0,0 +1,24 @@
|
||||
# include properties file from /etc
|
||||
spring.config.import = /etc/jfilecloud.properties
|
||||
|
||||
# jooq
|
||||
spring.datasource.driver-class-name = org.postgresql.Driver
|
||||
spring.datasource.url = ${db.url}
|
||||
spring.datasource.username = ${db.username}
|
||||
spring.datasource.password = ${db.password}
|
||||
|
||||
# security
|
||||
spring.security.oauth2.client.registration.keycloak.client-id = ${keycloak.client-id}
|
||||
spring.security.oauth2.client.registration.keycloak.scope = openid
|
||||
spring.security.oauth2.client.registration.keycloak.authorization-grant-type = authorization_code
|
||||
spring.security.oauth2.client.registration.keycloak.redirect-uri = ${keycloak.redirect-uri}
|
||||
spring.security.oauth2.client.provider.keycloak.issuer-uri = ${keycloak.issuer-uri}
|
||||
spring.security.oauth2.client.provider.keycloak.authorization-uri = ${keycloak.openid-url}/auth
|
||||
spring.security.oauth2.client.provider.keycloak.token-uri = ${keycloak.openid-url}/token
|
||||
spring.security.oauth2.client.provider.keycloak.user-info-uri = ${keycloak.openid-url}/userinfo
|
||||
spring.security.oauth2.client.provider.keycloak.jwk-set-uri = ${keycloak.openid-url}/certs
|
||||
spring.security.oauth2.client.provider.keycloak.user-name-attribute = preferred_username
|
||||
|
||||
# application
|
||||
server.port = 9002
|
||||
server.servlet.context-path = /jfilecloud
|
13
src/main/resources/static/css/style.css
Normal file
13
src/main/resources/static/css/style.css
Normal file
@ -0,0 +1,13 @@
|
||||
.header {
|
||||
padding-top: 4px;
|
||||
border-bottom: 1px solid gray;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
max-height: 32px;
|
||||
border-top: 1px solid gray;
|
||||
min-width: 100%;
|
||||
padding-left: 8px;
|
||||
}
|
21
src/main/resources/templates/dashboard.html
Normal file
21
src/main/resources/templates/dashboard.html
Normal file
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
xmlns:sec="http://www.thymeleaf.org/extras/spring-security" layout:decorate="~{template.html}">
|
||||
|
||||
<head>
|
||||
<title>JFileCloud</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div layout:fragment="left">
|
||||
</div>
|
||||
<div layout:fragment="body">
|
||||
<div class="alert alert-success">
|
||||
Hier entsteht meine eigene Cloud. Ich habe zwar schon verschiedene Systeme probiert, aber alle haben mir nicht so recht gefallen. Deswegen baue ich mir hier meine eigene Lösung.
|
||||
</div>
|
||||
</div>
|
||||
<div layout:fragment="footer">
|
||||
JFileCloud - Version 0.0.0 - keine Funktionalität bisher
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
43
src/main/resources/templates/template.html
Normal file
43
src/main/resources/templates/template.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" th:data-bs-theme="${theme}">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<title>JFileCloud</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" th:href="@{/webjars/bootstrap/5.3.3/css/bootstrap.min.css}" />
|
||||
<link rel="stylesheet" type="text/css" th:href="@{/webjars/datatables/2.1.8/css/dataTables.dataTables.min.css}" />
|
||||
<link rel="stylesheet" type="text/css" th:href="@{/webjars/font-awesome/6.7.2/css/all.min.css}" />
|
||||
<link rel="stylesheet" type="text/css" th:href="@{/css/style.css}" />
|
||||
|
||||
<script th:src="@{/webjars/jquery/3.7.1/jquery.min.js}"></script>
|
||||
<script th:src="@{/webjars/bootstrap/5.3.3/js/bootstrap.bundle.min.js}"></script>
|
||||
<script th:src="@{/webjars/datatables/2.1.8/js/dataTables.dataTables.min.js}"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="container-fluid header">
|
||||
<button class="btn btn-outline-secondary me-2 mb-2" data-bs-toggle="offcanvas" href="#sidebar" role="button">
|
||||
<i class="fas fa-wrench"></i>
|
||||
</button>
|
||||
<div layout:fragment="headline"></div>
|
||||
</div>
|
||||
<div id="sidebar" class="offcanvas offcanvas-start" tabindex="-1" aria-labelledby="sidebarLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="sidebarLabel">Navigation</h5>
|
||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Schließen"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<nav class="navbar-light">
|
||||
<ul class="navbar-nav">
|
||||
<li><a class="nav-link active" th:href="@{/dashboard}">Startseite</a></li>
|
||||
<li layout:fragment="left" class="left">TODO: left menu integration</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<div layout:fragment="body" class="body m-2">body</div>
|
||||
<div layout:fragment="footer" class="footer">footer</div>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user