🎨feat:feat:v2.5,JDK17、Activiti7、Vue3、TS、Vite、ElementPlugs 的 全新版本
This commit is contained in:
commit
90d2dc971a
|
@ -0,0 +1,253 @@
|
|||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
.idea
|
||||
*.iml
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
/target/
|
||||
/.classpath
|
||||
/.project
|
||||
/.settings/
|
||||
web/WebContent/META-INF/MANIFEST.MF
|
||||
### Maven template
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
|
||||
.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
### Java template
|
||||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
### macOS template
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
### Windows template
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
Thumbs.db:encryptable
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
### Eclipse template
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.settings/
|
||||
.loadpath
|
||||
.recommenders
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# PyDev specific (Python IDE for Eclipse)
|
||||
*.pydevproject
|
||||
|
||||
# CDT-specific (C/C++ Development Tooling)
|
||||
.cproject
|
||||
|
||||
# CDT- autotools
|
||||
.autotools
|
||||
|
||||
# Java annotation processor (APT)
|
||||
.factorypath
|
||||
|
||||
# PDT-specific (PHP Development Tools)
|
||||
.buildpath
|
||||
|
||||
# sbteclipse plugin
|
||||
.target
|
||||
|
||||
# Tern plugin
|
||||
.tern-project
|
||||
|
||||
# TeXlipse plugin
|
||||
.texlipse
|
||||
|
||||
# STS (Spring Tool Suite)
|
||||
.springBeans
|
||||
|
||||
# Code Recommenders
|
||||
.recommenders/
|
||||
|
||||
# Annotation Processing
|
||||
.apt_generated/
|
||||
.apt_generated_test/
|
||||
|
||||
# Scala IDE specific (Scala & Java development for Eclipse)
|
||||
.cache-main
|
||||
.scala_dependencies
|
||||
.worksheet
|
||||
|
||||
### JetBrains template
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
*.classpath
|
||||
*.project
|
|
@ -0,0 +1 @@
|
|||
2efdb939520e48970404a46039a6bc23
|
|
@ -0,0 +1 @@
|
|||
572204f16e80c7b67a7f380c764d56f9336c785d
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>agile-bpm</artifactId>
|
||||
<groupId>com.dstz</groupId>
|
||||
<version>2.5.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>ab-biz-api</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.dstz</groupId>
|
||||
<artifactId>ab-base-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.dstz</groupId>
|
||||
<artifactId>ab-groovy-script-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1 @@
|
|||
d9e81975644473fe3a61d9cc9cc6dfb5
|
|
@ -0,0 +1 @@
|
|||
4ee89232266093c6b5eb97c9561b0d70f917beef
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<groupId>com.dstz</groupId>
|
||||
<artifactId>ab-biz-api</artifactId>
|
||||
<versioning>
|
||||
<release>2.5.0</release>
|
||||
<versions>
|
||||
<version>2.5.0</version>
|
||||
</versions>
|
||||
<lastUpdated>20230707093924</lastUpdated>
|
||||
</versioning>
|
||||
</metadata>
|
|
@ -0,0 +1 @@
|
|||
1d4edc3bf9ebfd416fda562389234e54
|
|
@ -0,0 +1 @@
|
|||
503883124f635090b03bdc30ce53478ad92dbd5b
|
|
@ -0,0 +1 @@
|
|||
406e7da48b390b19875c31c2df806486
|
|
@ -0,0 +1 @@
|
|||
e3e4765c3e6fde22c846d68886a7c193f2289a5c
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>agile-bpm</artifactId>
|
||||
<groupId>com.dstz</groupId>
|
||||
<version>2.5.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>ab-spring-boot-biz-starter</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jsoup</groupId>
|
||||
<artifactId>jsoup</artifactId>
|
||||
<version>1.8.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1 @@
|
|||
1569e1786d50c4c9b1f9d826f2b0a4ad
|
|
@ -0,0 +1 @@
|
|||
69f7e16e15a63ec94e7235414983e2ba6fa7f720
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<groupId>com.dstz</groupId>
|
||||
<artifactId>ab-spring-boot-biz-starter</artifactId>
|
||||
<versioning>
|
||||
<release>2.5.0</release>
|
||||
<versions>
|
||||
<version>2.5.0</version>
|
||||
</versions>
|
||||
<lastUpdated>20230707093928</lastUpdated>
|
||||
</versioning>
|
||||
</metadata>
|
|
@ -0,0 +1 @@
|
|||
cd98a9eb1f0e0c6e49ce6b6253d7bd31
|
|
@ -0,0 +1 @@
|
|||
96e83dde467a9ef5ef7aa6183ba0737dffcd0c03
|
|
@ -0,0 +1 @@
|
|||
419e1396338f89e13f2306304ec0ac4b
|
|
@ -0,0 +1 @@
|
|||
efb19679870e7f9a1559758b8074cb0ce800c602
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>agile-bpm</artifactId>
|
||||
<groupId>com.dstz</groupId>
|
||||
<version>2.5.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>ab-spring-boot-wf-starter</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.dstz</groupId>
|
||||
<artifactId>ab-spring-boot-starter</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.dstz</groupId>
|
||||
<artifactId>ab-wf-client</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.dstz</groupId>
|
||||
<artifactId>ab-biz-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.activiti</groupId>
|
||||
<artifactId>activiti-engine</artifactId>
|
||||
<classifier>AB</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.tinyjee.jgraphx</groupId>
|
||||
<artifactId>jgraphx</artifactId>
|
||||
<version>1.10.4.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.activiti</groupId>
|
||||
<artifactId>activiti-spring-boot-starter</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>activiti-spring-identity</artifactId>
|
||||
<groupId>org.activiti.core.common</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-common</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1 @@
|
|||
e4c50d12c28da9cecb6986fa7de7f8a5
|
|
@ -0,0 +1 @@
|
|||
ca4ebfca93b9a9883b10674f8f63275c03a8592d
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<groupId>com.dstz</groupId>
|
||||
<artifactId>ab-spring-boot-wf-starter</artifactId>
|
||||
<versioning>
|
||||
<release>2.5.0</release>
|
||||
<versions>
|
||||
<version>2.5.0</version>
|
||||
</versions>
|
||||
<lastUpdated>20230707093927</lastUpdated>
|
||||
</versioning>
|
||||
</metadata>
|
|
@ -0,0 +1 @@
|
|||
588a996704469002bf4239d9b54c6197
|
|
@ -0,0 +1 @@
|
|||
e44644199717e05b923ca4b9f2e45186deec4147
|
|
@ -0,0 +1 @@
|
|||
0221b2a2d4db6aa49b4d1c7f860a0c4a
|
|
@ -0,0 +1 @@
|
|||
6626ccfceedc097ba034252da13afef287555d66
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.dstz</groupId>
|
||||
<artifactId>agile-bpm</artifactId>
|
||||
<version>2.5.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>ab-wf-client</artifactId>
|
||||
<description>流程模块客户端包,主要是一些开放式的DTO</description>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.dstz</groupId>
|
||||
<artifactId>ab-base-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1 @@
|
|||
102d9afb8b4edb9fc373719657591d9d
|
|
@ -0,0 +1 @@
|
|||
7e212439a4ab5d70ed8a0e853685cd864c73ac12
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<groupId>com.dstz</groupId>
|
||||
<artifactId>ab-wf-client</artifactId>
|
||||
<versioning>
|
||||
<release>2.5.0</release>
|
||||
<versions>
|
||||
<version>2.5.0</version>
|
||||
</versions>
|
||||
<lastUpdated>20230707093926</lastUpdated>
|
||||
</versioning>
|
||||
</metadata>
|
|
@ -0,0 +1 @@
|
|||
bdcb916d3644499ffc650e3105aa2683
|
|
@ -0,0 +1 @@
|
|||
12e926824ba35439d90d66c07d8009d4a0f95a9d
|
|
@ -0,0 +1 @@
|
|||
40d8539bc56ef37c197a65b8208e4e87
|
|
@ -0,0 +1 @@
|
|||
e8faa8dcf42675d8d4873e7ad7a4837f26f763a5
|
|
@ -0,0 +1,187 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.activiti</groupId>
|
||||
<artifactId>activiti-core-dependencies</artifactId>
|
||||
<version>7.1.0.M6</version>
|
||||
<relativePath>../activiti-core-dependencies</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>activiti-engine</artifactId>
|
||||
<name>Activiti :: Engine</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.activiti.api</groupId>
|
||||
<artifactId>activiti-api-runtime-shared</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.activiti.core.common</groupId>
|
||||
<artifactId>activiti-project-model</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.activiti</groupId>
|
||||
<artifactId>activiti-bpmn-converter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.activiti</groupId>
|
||||
<artifactId>activiti-bpmn-model</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.activiti</groupId>
|
||||
<artifactId>activiti-process-validation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-email</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.odysseus.juel</groupId>
|
||||
<artifactId>juel-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.odysseus.juel</groupId>
|
||||
<artifactId>juel-impl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.odysseus.juel</groupId>
|
||||
<artifactId>juel-spi</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-jsr223</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.geronimo.specs</groupId>
|
||||
<artifactId>geronimo-jta_1.1_spec</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.enterprise.concurrent</groupId>
|
||||
<artifactId>javax.enterprise.concurrent-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.subethamail</groupId>
|
||||
<artifactId>subethasmtp-wiser</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.uuid</groupId>
|
||||
<artifactId>java-uuid-generator</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- Required for testing JTA -->
|
||||
<dependency>
|
||||
<groupId>org.codehaus.btm</groupId>
|
||||
<artifactId>btm</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-entitymanager</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/*TestCase.java</exclude>
|
||||
<exclude>**/RepeatingServiceTaskTest.java</exclude>
|
||||
</excludes>
|
||||
<runOrder>alphabetical</runOrder>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1 @@
|
|||
05dd48f439fb10c82b404b4ab49d9307
|
|
@ -0,0 +1 @@
|
|||
139f3281de2392871b0b72fc8905cd8f73bab96c
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<groupId>org.activiti</groupId>
|
||||
<artifactId>activiti-engine</artifactId>
|
||||
<versioning>
|
||||
<release>7.1.0.M6</release>
|
||||
<versions>
|
||||
<version>7.1.0.M6</version>
|
||||
</versions>
|
||||
<lastUpdated>20230707093922</lastUpdated>
|
||||
</versioning>
|
||||
</metadata>
|
|
@ -0,0 +1 @@
|
|||
a4aaae6503e712426acc7c2d33d5b19c
|
|
@ -0,0 +1 @@
|
|||
532fbdb905cd4585e0ffeb2953d94a4678e1e6cd
|
|
@ -0,0 +1,674 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. [http://fsf.org/]
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
{one line to give the program's name and a brief idea of what it does.}
|
||||
Copyright (C) {year} {fullname}
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
agile-bpm-basic Copyright (C) 2018 jeff
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
[http://www.gnu.org/licenses/].
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
[http://www.gnu.org/philosophy/why-not-lgpl.html].
|
|
@ -0,0 +1,58 @@
|
|||
AgileBPM 开源版本允许商用
|
||||
|
||||
除了遵循GPL开源协议外,请严格遵循以下协议。
|
||||
|
||||
该协议从2020年8月21日 起效,如果有违该协议的请于一月内改正,否则您将面临法律风险!
|
||||
该协议会在AgileBPM官方网站公告登出,任何涉事企业请勿抱侥幸心理,请勿把法律当儿戏!
|
||||
|
||||
## 禁止条款
|
||||
|
||||
### 国家法规
|
||||
|
||||
1、遵守《中华人民共和国计算机信息系统安全保护条例》,禁止侵犯计算机软件著作权。
|
||||
|
||||
2、任何组织或者个人、不得利用计算机信息系统从事危害国家利益、集体利益和公民合法利益的活动,不得危害计算机信息系统的安全。
|
||||
|
||||
3、任何单位和个人不得自行建立或者使用其他信道进行国际联网。
|
||||
|
||||
4、从事国际联网业务的单位和个人,应当遵守国家有关法律、行政法规,严格执行安全保密制度,不得利用国际联网从事危害国家安全、泄露国家秘密等违法犯罪活动,不得制作、查阅、复制和传播妨碍社会治安的信息和淫秽色情等信息。
|
||||
|
||||
5、任何组织或个人,不得利用计算机国际联网从事危害国家安全、泄露国家秘密等犯罪活动;不得利用计算机国际联网查阅、复制、制造和传播危害国家安全、妨碍社会治安和淫秽色情的信息。发现上述违法犯罪行为和有害信息,应及时向有关主管机关报告。
|
||||
|
||||
6、任何组织或个人,不得利用计算机国际联网从事危害他人信息系统和网络安全,侵犯他人合法权益的活动。
|
||||
|
||||
7、国际联网用户应当服从接入单位的管理,遵守用户守则;不得擅自进入未经许可的计算机系统,篡改他人信息;不得在网络上散发恶意信息,冒用他人名义发出信息,侵犯他人隐私;不得制造、传播计算机病毒及从事其他侵犯网络和他人合法权益的活动。
|
||||
|
||||
8、任何单位和个人发现计算机信息系统泄密后,应及时采取补救措施,并按有关规定及时向上级报告。
|
||||
|
||||
9、任何单位和个人不得利用国际联网危害国家安全、泄露国家秘密,不得侵犯国家的、社会的、集体的利益和公民的合法权益,不得从事违法犯罪活动。
|
||||
|
||||
10、任何单位和个人不得利用国际联网制作、复制、查阅和传播下列信息:
|
||||
|
||||
1. 煽动抗拒、破坏宪法和法律、行政法规实施的;
|
||||
2. 煽动颠覆国家政权,推翻社会主义制度的;
|
||||
3. 煽动分裂国家、破坏国家统一的;
|
||||
4. 煽动民族仇恨、民族歧视,破坏民族团结的;
|
||||
5. 捏造或者歪曲事实,散布谣言,扰乱社会秩序的;
|
||||
6. 宣扬封建迷信、淫秽、色情、赌博、暴力、凶杀、恐怖,教唆犯罪的;
|
||||
7. 公然侮辱他人或者捏造事实诽谤他人的;
|
||||
8. 损害国家机关信誉的;
|
||||
9. 其他违反宪法和法律、行政法规的。
|
||||
|
||||
### AgileBPM 补充协议
|
||||
11、禁止将AgileBPM以流程开发平台的形式二次出售。
|
||||
|
||||
12、基于AgileBPM二次开发的产品,或者应用了AgileBPM部分功能或者源代码块的产品,这些产品的名称、产品宣传词禁止 包含 “BPM”,“流程”,“开发平台”关键字。
|
||||
|
||||
13、不论何时通过任何渠道获得的AgileBPM开源源代码、或者部分功能源代码、或者代码片段均受该协议约束。
|
||||
|
||||
## 违约条款
|
||||
1、如果违背以上任何禁止条款,AgileBPM将禁止使用AgileBPM的任何功能以及源代码。
|
||||
|
||||
2、违背协议相关企业的产品、以及该产品的衍生产品,以及已经出售了的应用于客户公司的相关产品,均需要移除AgileBPM相关功能源代码,否则相关企业以及受众客户都同样面临侵权问题。
|
||||
|
||||
3、如果违背协议者应用了部分功能,需要在该协议生效一月内即2020年9月21日移除先关源代码功能。
|
||||
|
||||
4、如果违背国家相关法律条款的必须立即删除,并根据相关条款予以处罚。
|
||||
|
||||
5、如果违背“AgileBPM 补充协议”且2020年9月21日前不予改正的企业以及相关企业,我们将追究法律责任,每个侵权程序将处于500000RMB罚款并且缴纳相关违规所得。
|
|
@ -0,0 +1,77 @@
|
|||
# agilebpm-basic
|
||||
|
||||
## 敏捷开发平台
|
||||
|
||||
全新开源的 vue3 TS 的前后台分离的开发平台
|
||||
|
||||
前端基于 `Vue3` 组合式API, `TypeScript`, `Element-plus`,`Pinia`,`Axios`,支持三种布局, 自定义主题风格
|
||||
后端基于 `AgileBPM` 流程表单,`SpringBoot `,`MybatisPlus` ,`Activiti7` ,`Jackson` , `JDK17` ,`Hutool` 等主流技术栈
|
||||
|
||||
后端是 Maven模块化管理的SOA的 SpringBoot 单体架构,模块间低耦合,可选择模块组合成微服务架构。
|
||||
|
||||
|
||||
## 起步
|
||||
|
||||
1. 下载 `agile-bpm-basic`项目,以 maven 项目引入工程 并 根目录下 执行 `mvn clean install -DskipTests`
|
||||
|
||||
2. 执行数据库脚本创建数据库 `/doc/sql/mysql/full/agilebpm_full.sql`
|
||||
|
||||
3. 修改数据库、Redis 等配置文件`\ab-spring-boot\ab-spring-boot-app\src\main\resources\application.yml`,配置文件会有详细注释,请自行修改。
|
||||
|
||||
4. 通过 Main 方法启动后端服务 `\ab-spring-boot\ab-spring-boot-app\src\main\java\com\dstz\AbSpringBootApp.java`,默认端口为 `8080`
|
||||
|
||||
5. 下载 前端工程 `agilebpm-ui` ,并在根目录下 执行 命令 `yarn install`
|
||||
|
||||
6. 完成安装后,在 `vite.config.ts`中修改后台服务地址,如 `http://localhost:8080/` 然后执行 ` npm run dev ` 启动前端项目。
|
||||
|
||||
默认访问 前端地址 `http://127.0.0.1:8088/` 即可体验项目
|
||||
|
||||
|
||||
推荐 vscode 作为前端开发IDE,请务必安装一下插件
|
||||
- local-history (opens new window)local-history](可找回丢失代码)
|
||||
- eslint (opens new window)eslint(建议开启 Eslint 保存时自动修复)
|
||||
- stylelint (opens new window)stylelint
|
||||
- Prettier - Code formatter 代码自动格式化
|
||||
- volar (opens new window)vue3 开发必备
|
||||
|
||||
|
||||
## 目前 `2.5` 版本涵盖了以下功能
|
||||
|
||||
- 个人办公: 待办事项、抄送传阅、办理历史、发起申请、申请历史、我的草稿
|
||||
|
||||
- 内容管理: 公告、新闻
|
||||
|
||||
- 组织管理:组织管理、用户管理、角色管理、 岗位管理。笔者十多年研发见过无数组织架构,它堪称最精简最完美的设计。
|
||||
|
||||
- 流程管理: 表单表单设计、流程设计、流程实例管理、任务管理、系统对话框管理。(目前基于AgileBPM的商业组件,如果觉得不合适可切换为其他框架的流程模块,目前没有能入眼的)
|
||||
|
||||
- 系统管理:字典分类管理、异常日志、系统资源、系统属性、常用脚本、短信邮件通知
|
||||
|
||||
## 系统界面预览
|
||||
|
||||
|
||||
|
||||
## 开发计划
|
||||
|
||||
### v 2.6 计划新增 OA 人事模块
|
||||
|
||||
规划包含 招聘需求、招聘面试、员工档案、转正、调岗、离职、 等功能
|
||||
|
||||
### 规划中排期待定的事项
|
||||
|
||||
- 人事中 请假、加班、出差、外勤打卡
|
||||
|
||||
- 资产管理 的资产信息、资产领用、资产转移、采购申请
|
||||
|
||||
- 持续维护前端工具包,以及前端组件库,等组件库稳定后开放源码出来
|
||||
|
||||
- 维护系统中用的部分功能的 TS 类型定义,由于目前开发工作繁重,部分页面 暂未维护。
|
||||
|
||||
- 首页组件,如公告新闻、待办等
|
||||
|
||||
- 常用语,适配黑夜模式,全面支持国际化,站内消息通知
|
||||
|
||||
欢迎有兴趣的同学 pull request ,或者提需求
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>ab-auth</artifactId>
|
||||
<groupId>com.dstz</groupId>
|
||||
<version>2.5.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>ab-auth-api</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.dstz</groupId>
|
||||
<artifactId>ab-base-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.dstz</groupId>
|
||||
<artifactId>ab-org-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1,31 @@
|
|||
package com.dstz.auth.authentication.api;
|
||||
|
||||
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
/**
|
||||
* 多来源登录认证
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public interface MultipleFromAuthentication {
|
||||
|
||||
/**
|
||||
* 获取来源
|
||||
*
|
||||
* @return 来源
|
||||
*/
|
||||
String getFrom();
|
||||
|
||||
/**
|
||||
* 鉴权认证
|
||||
*
|
||||
* @param userDetails 登录用户详情
|
||||
* @param authentication 用户密码鉴权串
|
||||
* @throws AuthenticationException 鉴权异常
|
||||
*/
|
||||
void authentication(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException;
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.dstz.auth.authentication.api;
|
||||
|
||||
import com.dstz.auth.authentication.vo.SysApplicationVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 系统应用接口
|
||||
*
|
||||
* @author wacxhs
|
||||
*/
|
||||
public interface SysApplicationApi{
|
||||
|
||||
/**
|
||||
* 根据编码获取系统应用
|
||||
*
|
||||
* @param code 编码
|
||||
* @return 系统应用
|
||||
*/
|
||||
SysApplicationVO getByCode(String code);
|
||||
|
||||
/**
|
||||
* 获取所有应用编码
|
||||
*
|
||||
* @return 所有应用编码
|
||||
*/
|
||||
List<String> getAllCode();
|
||||
|
||||
/**
|
||||
* 获取当前可用的移动端主应用
|
||||
* @return
|
||||
*/
|
||||
SysApplicationVO getEnabledMobileApp();
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package com.dstz.auth.authentication.api;
|
||||
|
||||
import com.dstz.auth.authentication.api.model.ISysApplication;
|
||||
import com.dstz.auth.authentication.api.model.ISysResource;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
/**
|
||||
* 系统资源接口
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public interface SysResourceApi {
|
||||
|
||||
/**
|
||||
* 通过资源id获取资源对象
|
||||
* @param id 资源ID
|
||||
* @return ISysResource 资源对象
|
||||
*/
|
||||
ISysResource getResourceById(String id);
|
||||
|
||||
/**
|
||||
* 通过资源code集合删除资源对象
|
||||
* @param code 资源code集合
|
||||
*/
|
||||
void deleteResourceByCode(List<String> code);
|
||||
|
||||
/**
|
||||
* 获取当前用户拥有的系统
|
||||
* @return
|
||||
*/
|
||||
List<ISysApplication> getCurrentUserSystem();
|
||||
/**
|
||||
* 获取默认系统
|
||||
* @return
|
||||
*/
|
||||
ISysApplication getDefaultSystem(String currentUserId);
|
||||
/**
|
||||
* 根据id获取系统资源
|
||||
* @return
|
||||
*/
|
||||
List<ISysResource> getBySystemId(String systemId);
|
||||
/**
|
||||
* 根据systemId和userId获取系统资源
|
||||
* @return
|
||||
*/
|
||||
List<ISysResource> getByAppIdAndUser(String appId, String userId);
|
||||
/**
|
||||
* 根据url获取拥有资源
|
||||
* @return
|
||||
*/
|
||||
Set<String> getAccessRoleByUrl(String url);
|
||||
|
||||
/**
|
||||
* 根据url查询是url还是方法接口
|
||||
*/
|
||||
boolean isRoleByUrl(String url);
|
||||
|
||||
/**
|
||||
* 获取移动端办理事项的资源
|
||||
*/
|
||||
ISysResource getTodoResource();
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package com.dstz.auth.authentication.api.constant;
|
||||
|
||||
/**
|
||||
* auth模块常量
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public class AuthApiConstant {
|
||||
private AuthApiConstant() throws IllegalAccessException {
|
||||
throw new IllegalAccessException();
|
||||
}
|
||||
|
||||
/**
|
||||
* 来源-system
|
||||
*/
|
||||
public static final String SYSTEM = "system";
|
||||
/**
|
||||
* 系统别名
|
||||
*/
|
||||
public static final String AGILEBPM = "agilebpm";
|
||||
/**
|
||||
* 登录超时跳转url
|
||||
*/
|
||||
public static final String SSO_REDIRECTURL = "SSO_redirectUrl";
|
||||
|
||||
/**
|
||||
* 超管账户
|
||||
*/
|
||||
public static final String ADMIN = "admin";
|
||||
|
||||
//----------oauth2相关配置------------
|
||||
|
||||
/**
|
||||
* 令牌默认有效期2小时
|
||||
*/
|
||||
public static final Integer ACCESSTOKEN_VALIDITY_SECONDS = 7200;
|
||||
|
||||
/**
|
||||
* 刷新令牌默认有效期3天
|
||||
*/
|
||||
public static final Integer REFRESHTOKEN_VALIDITY_SECONDS = 259200;
|
||||
|
||||
|
||||
public static final String AUTHORIZATION = "Authorization";
|
||||
|
||||
public static final String BEARER = "Bearer";
|
||||
|
||||
/**
|
||||
* 配置令牌端点安全约束配置
|
||||
*/
|
||||
public static final String TOKEN_SERVER_SECURITY_CONFIGURER = "permitAll()";
|
||||
|
||||
/**
|
||||
* 定制授权页
|
||||
*/
|
||||
public static final String TOKEN_SERVER_AUTH_DEFAULTPATH = "/oauth/confirm_access";
|
||||
|
||||
/**
|
||||
* 定制授权页
|
||||
*/
|
||||
public static final String TOKEN_SERVER_AUTH_CUSTOMPATH = "/customer/confirm_access";
|
||||
|
||||
/**
|
||||
* oauth 客户端key
|
||||
*/
|
||||
public static final String OAUTH_TOKEN_CLIENT_KEY = "client_id";
|
||||
|
||||
public static final String OAUTH_TOKEN_CLIENT_SECRET = "client_secret";
|
||||
|
||||
|
||||
/**
|
||||
* oauth 客户端 refresh_token
|
||||
*/
|
||||
public static final String OAUTH_TOKEN_REFRESH_TOKEN = "refresh_token";
|
||||
|
||||
/**
|
||||
* oauth 客户端grant_type
|
||||
*/
|
||||
public static final String OAUTH_TOKEN_GRANT_TYPE = "grant_type";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* oauth 客户端username
|
||||
*/
|
||||
public static final String OAUTH_TOKEN_USER_NAME = "username";
|
||||
|
||||
/**
|
||||
* oauth 客户端password
|
||||
*/
|
||||
public static final String OAUTH_TOKEN_PASSWORD = "password";
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package com.dstz.auth.authentication.api.constant;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* 缓存key常量
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public class AuthCacheKeyConstant {
|
||||
|
||||
/**
|
||||
* auth_client 方法缓存key
|
||||
*/
|
||||
public static final String CACHE_REGION_AUTH_CLIENT = "OAUTH_REGION";
|
||||
/**
|
||||
* auth_client 方法缓存key SpEL表达式
|
||||
*/
|
||||
public static final String AUTH_CLIENT_RECEIVE_EL = "'authClientEl:'.concat(#root.args[0])";
|
||||
|
||||
public static final String AUTH_APP_LIST_EL = "'authAppListEl:";
|
||||
|
||||
/**
|
||||
* auth_client 方法缓存key SpEL表达式
|
||||
*/
|
||||
public static final String CACHE_EVICT_AUTH_CLIENT_RECEIVE_EL = "'authClientEl:'.concat(#root.args[0].getCode())";
|
||||
|
||||
/**
|
||||
* 根据url缓存权限映射
|
||||
*/
|
||||
public static final String URL_ROLE_MAPPING = "agilebpm:sys:resoucesUrlRoleMapping:";
|
||||
/**
|
||||
* 登录用户缓存key
|
||||
*/
|
||||
public static final String LOGIN_USER_CACHE_KEY = "agilebpm:loginUser:";
|
||||
|
||||
/**
|
||||
* 用户token缓存
|
||||
*/
|
||||
public static final String USER_TOKEN = "user:token:";
|
||||
|
||||
|
||||
/**
|
||||
* 用户登录次数统计
|
||||
*/
|
||||
public static final String USER_LOGIN_COUNT = "user:login:count:";
|
||||
|
||||
/**
|
||||
* 忽略鉴权列表
|
||||
*/
|
||||
public static final String IGNORE_AUTH_URL_LIST = "'ignore:auth:url'";
|
||||
|
||||
/**
|
||||
* 判断url是否需要方法鉴权
|
||||
*/
|
||||
public static final String IS_ROLE = "'isRole:'.concat(#root.args[0])";
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
package com.dstz.auth.authentication.api.constant;
|
||||
|
||||
import com.dstz.base.common.codes.IBaseCode;
|
||||
|
||||
/**
|
||||
* 鉴权接口响应码
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public enum AuthStatusCode implements IBaseCode {
|
||||
|
||||
/**
|
||||
* 必传参数为空
|
||||
*/
|
||||
PARAM_CLIENT_ID_IS_NOT_FOUND("param_client_id_is_not_found", "必传参数clientId为空"),
|
||||
/**
|
||||
* 账户或密码不对
|
||||
*/
|
||||
LOGIN_ERROR("login_error", "账户或密码不对"),
|
||||
|
||||
USER_NAME_OR_PASSORD_ERROR("user_name_or_passord_error", "{}"),
|
||||
/**
|
||||
* 应用配置错误
|
||||
*/
|
||||
APP_CONFIG_ERROR("app_config_error", "应用配置错误"),
|
||||
/**
|
||||
* 账户找不到
|
||||
*/
|
||||
ACCOUNT_NOT_FIND("account_not_find", "账户不存在"),
|
||||
/**
|
||||
* 账户不能为空
|
||||
*/
|
||||
ACCOUNT_CANNOT_BE_EMPTY("account_cannot_be_empty", "账户不能为空"),
|
||||
/**
|
||||
* 密码不能为空
|
||||
*/
|
||||
PASSWORD_CANNOT_BE_EMPTY("password_cannot_be_empty", "密码不能为空"),
|
||||
/**
|
||||
* 帐号已禁用
|
||||
*/
|
||||
ACCOUNT_DISABLED("account_disabled", "帐号已禁用"),
|
||||
/**
|
||||
* 帐号已锁定
|
||||
*/
|
||||
ACCOUNT_IS_LOCKED("account_is_locked", "帐号已锁定"),
|
||||
/**
|
||||
* 帐号已过期
|
||||
*/
|
||||
ACCOUNT_HAS_EXPIRED("account_has_expired", "帐号已过期"),
|
||||
/**
|
||||
* 账号或密码错误次数过多,将禁止登录
|
||||
*/
|
||||
DISABLE_LOGIN("disable_login", "账号或密码错误次数过多,将禁止登录{}"),
|
||||
|
||||
DISABLE_LOGIN_WARN("disable_login_warn","账户密码错误,已经失败 {} 次,若连续失败 {} 次将禁止登录{}"),
|
||||
/**
|
||||
* 验证码不能为空
|
||||
*/
|
||||
CAPTCHA_CANNOT_BE_EMPTY("captcha_cannot_be_empty", "验证码不能为空"),
|
||||
/**
|
||||
* 验证类型
|
||||
*/
|
||||
GRANTTYPE_CANNOT_BE_EMPTY("granttype_cannot_be_empty", "验证类型不能为空"),
|
||||
/**
|
||||
* 验证码错误
|
||||
*/
|
||||
CAPTCHA_ERROR("captcha_error", "验证码错误,请重试"),
|
||||
/**
|
||||
* 密码为初始密码
|
||||
*/
|
||||
PASSWORD_NEEDS_TO_BE_CHANGED("password_needs_to_be_changed", "密码为初始密码,请修改密码后登录"),
|
||||
/**
|
||||
* 当前用户尚未分配任何资源
|
||||
*/
|
||||
USER_HAS_NOT_ASSIGNED_ANY_RESOURCES("user_has_not_assigned_any_resources", "当前用户尚未分配任何资源"),
|
||||
|
||||
APPLICATION_NO_PERMISSIONS("application_no_permissions", "没有该应用的权限:{}"),
|
||||
|
||||
RESOURCES_CODE_REPEAT("resources_code_repeat", "别名已存在,请修改!:{}"),
|
||||
|
||||
DELETE_RESOURCES_ERROR("delete_resources_error", "删除子系统资源失败"),
|
||||
|
||||
SYS_IS_NOT_DEFINITION("sys_is_not_definition", "当前系统“{} ”不存在! 请添加子系统,并配置资源菜单!\" : \"您没有当前系统“{}”的访问权限!请联系管理员。"),
|
||||
|
||||
PARAM_IS_NULL("param_is_null", "必传参数 {} 为空"),
|
||||
|
||||
APPLICATION_GET_TOKEN_ERROR("application_get_token_error", "用户:{} 获取token异常 clientid:{}"),
|
||||
APPLICATION_REFRESH_TOKEN_ERROR("application_refresh_token_error", "刷新token异常 clientid:{}"),
|
||||
/**
|
||||
* 根据当前clientid未查到数据
|
||||
*/
|
||||
LOADCLIENT_BY_CLIENTID_ERROR("loadclient_by_clientid_error", "根据当前clientid未查到数据"),
|
||||
|
||||
/**
|
||||
* There is no client authentication. Try adding an appropriate authentication filter
|
||||
*/
|
||||
NO_CLIENT_AUTHENTICATION("no_client_authentication", "没有找到匹配的身份验证过滤器"),
|
||||
|
||||
LOGIN_TIMEOUT("LOGIN_TIMEOUT", "登录超时,请重新登录"),
|
||||
|
||||
NO_AUTH_TOKEN("no_auth_token", "请求未传入鉴权信息"),
|
||||
|
||||
TOKEN_INVALID("token_invalid", "登录超时"),
|
||||
|
||||
NOT_PERMISSION("not_permission", "权限不足"),
|
||||
|
||||
LOAD_CLIENT_BY_CLIENTID_ERROR("load_client_by_clientid_error", "加载应用信息异常:{}"),
|
||||
|
||||
NO_FIND_APP("no_find_app", "根据client_id:{} 找不到对应 应用"),
|
||||
|
||||
RESOUCE_TYPE_CONSTANT_ERROR("resouce_type_constant_error", "菜单类型的资源,上级资源 {} 也必须是菜单!"),
|
||||
|
||||
METHOD_NOT_ALLOWED("method_not_allowed", "方法未被允许"),
|
||||
|
||||
SERVICE_ERROR("service_error", "内部错误"),
|
||||
|
||||
LOGIN_AUTHORIZATION_FILTER_ERROR("login_authorization_filter_error", "鉴权过滤器AuthorizationTokenCheckFilter获取token异常"),
|
||||
|
||||
/**
|
||||
* 非法的当前用户组织,一般引起该错误,例如管理员分配了组织或者用户修改了请求参数
|
||||
*/
|
||||
ILLEGAL_CURRENT_ORG("IllegalCurrentOrg", "非法的当前用户组织, 非法组织编码:{}"),
|
||||
|
||||
/**
|
||||
* 用户未分配组织
|
||||
*/
|
||||
USER_UNABSORBED_ORG("UNABSORBED_ORG", "用户未分配组织"),
|
||||
|
||||
/**
|
||||
* 应用无菜单资源
|
||||
*/
|
||||
APP_NO_RESOURCE("AppNoResource", "切换系统失败,该系统下没有可访问的菜单资源"),
|
||||
|
||||
|
||||
/**
|
||||
* 该请求未分配给任何角色,或接口不存在
|
||||
*/
|
||||
API_NONEXISTENT_OR_NO_ACCESS("api_nonexistent_or_no_access", "该请求未分配给任何角色,或接口不存在:{}"),
|
||||
|
||||
|
||||
/**
|
||||
* 您没有该接口的访问权限
|
||||
*/
|
||||
API_NO_ACCESS("api_no_access", "您没有该接口的访问权限:"),
|
||||
|
||||
|
||||
APPCLICATION_ENABLE_DEFAULT_MOBILE_APP_NOT_FIND("appclication_enable_default_mobile_app_not_find", "系统找不到移动端默认应用,请先配置移动端默认应用"),
|
||||
|
||||
|
||||
;
|
||||
|
||||
private final String code;
|
||||
private final String desc;
|
||||
|
||||
AuthStatusCode(String code, String description) {
|
||||
this.code = code;
|
||||
this.desc = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return desc;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.dstz.auth.authentication.api.constant;
|
||||
|
||||
/**
|
||||
* 组织级别
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public enum ResouceTypeConstant {
|
||||
/**
|
||||
* 菜单
|
||||
*/
|
||||
MENU("menu", "菜单"),
|
||||
/**
|
||||
* 链接
|
||||
*/
|
||||
LINK("link", "链接"),
|
||||
/**
|
||||
* 按钮
|
||||
*/
|
||||
BUTTON("button", "按钮");
|
||||
|
||||
private final String key;
|
||||
private final String label;
|
||||
|
||||
|
||||
ResouceTypeConstant(String key, String label) {
|
||||
this.key = key;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package com.dstz.auth.authentication.api.model;
|
||||
|
||||
/**
|
||||
* 系统应用
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public interface ISysApplication {
|
||||
|
||||
/**
|
||||
* 返回 主键
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* 返回 系统名称
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* 返回 系统别名
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getCode();
|
||||
|
||||
|
||||
/**
|
||||
* 密匙
|
||||
*/
|
||||
String getSecret();
|
||||
|
||||
/**
|
||||
* 刷新秒数
|
||||
*/
|
||||
Integer getRefreshTokenValidity();
|
||||
|
||||
/**
|
||||
* 有效期
|
||||
*/
|
||||
Integer getAccessTokenValidity();
|
||||
|
||||
/**
|
||||
* 系统地址,空则为当前系统
|
||||
*/
|
||||
String getUrl();
|
||||
|
||||
|
||||
/**
|
||||
* 回调地址
|
||||
*/
|
||||
String getRedirectUri();
|
||||
|
||||
/**
|
||||
* 打开方式
|
||||
*/
|
||||
String getOpenType();
|
||||
|
||||
|
||||
/**
|
||||
* 返回 是否可用 1 可用,0 ,不可用
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Integer getEnabled();
|
||||
|
||||
/**
|
||||
* 是否默认
|
||||
*/
|
||||
Integer getIsDefault();
|
||||
|
||||
/**
|
||||
* 描述备注
|
||||
*/
|
||||
String getDesc();
|
||||
|
||||
/**
|
||||
* 扩展配置
|
||||
*/
|
||||
String getConfig();
|
||||
|
||||
/**
|
||||
* 是否可用app
|
||||
* @return
|
||||
*/
|
||||
Integer getAppType();
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
package com.dstz.auth.authentication.api.model;
|
||||
|
||||
import com.dstz.base.api.model.Tree;
|
||||
/**
|
||||
* 系统资源
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public interface ISysResource extends Tree {
|
||||
|
||||
|
||||
/**
|
||||
* 返回 主键
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getId();
|
||||
|
||||
/**
|
||||
* 返回 子系统ID
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getAppId();
|
||||
|
||||
/**
|
||||
* 返回 资源别名
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getCode();
|
||||
|
||||
|
||||
public String getPath();
|
||||
|
||||
/**
|
||||
* 返回 资源名
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
* 返回 默认地址
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getUrl();
|
||||
|
||||
/**
|
||||
* 返回 显示到菜单(1,显示,0 ,不显示)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Integer getEnable();
|
||||
|
||||
/**
|
||||
* 返回 OPENED_
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Integer getOpened();
|
||||
|
||||
/**
|
||||
* 是否API资源
|
||||
*/
|
||||
|
||||
Integer getIsApi();
|
||||
|
||||
/**
|
||||
* 返回 图标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getIcon();
|
||||
|
||||
/**
|
||||
* 返回类型
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getType();
|
||||
|
||||
/**
|
||||
* 返回 排序
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Integer getSn();
|
||||
|
||||
|
||||
public String getParentId();
|
||||
|
||||
Boolean getHidden();
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package com.dstz.auth.authentication.dto;
|
||||
|
||||
public class UserLoginDTO implements java.io.Serializable {
|
||||
|
||||
/**
|
||||
* 账户
|
||||
*/
|
||||
private String account;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 验证码
|
||||
*/
|
||||
private String captcha;
|
||||
|
||||
|
||||
/**
|
||||
* 接收方,pc/mobile/android"
|
||||
*/
|
||||
private String audience = "pc";
|
||||
|
||||
|
||||
/**
|
||||
* 记住账户
|
||||
*/
|
||||
private String rememberMe;
|
||||
|
||||
|
||||
public String getAudience() {
|
||||
return audience;
|
||||
}
|
||||
|
||||
public void setAudience(String audience) {
|
||||
this.audience = audience;
|
||||
}
|
||||
|
||||
public String getAccount() {
|
||||
return account;
|
||||
}
|
||||
|
||||
public void setAccount(String account) {
|
||||
this.account = account;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getCaptcha() {
|
||||
return captcha;
|
||||
}
|
||||
|
||||
public void setCaptcha(String captcha) {
|
||||
this.captcha = captcha;
|
||||
}
|
||||
|
||||
public String getRememberMe() {
|
||||
return rememberMe;
|
||||
}
|
||||
|
||||
public void setRememberMe(String rememberMe) {
|
||||
this.rememberMe = rememberMe;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
package com.dstz.auth.authentication.vo;
|
||||
|
||||
/**
|
||||
* 系统应用
|
||||
*
|
||||
* @author wacxhs
|
||||
*/
|
||||
public class SysApplicationVO implements java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = 5700878947689459575L;
|
||||
|
||||
/**
|
||||
* 编码
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 密匙
|
||||
*/
|
||||
private String secret;
|
||||
|
||||
/**
|
||||
* 授权范围
|
||||
*/
|
||||
private String scope;
|
||||
|
||||
/**
|
||||
* 资源集合
|
||||
*/
|
||||
private String resourceIds;
|
||||
|
||||
/**
|
||||
* 授权类型
|
||||
*/
|
||||
private String grantTypes;
|
||||
|
||||
/**
|
||||
* 回调地址
|
||||
*/
|
||||
private String redirectUri;
|
||||
|
||||
/**
|
||||
* 自动授权
|
||||
*/
|
||||
private Integer autoapprove;
|
||||
|
||||
/**
|
||||
* 有效期
|
||||
*/
|
||||
private Integer accessTokenValidity;
|
||||
|
||||
/**
|
||||
* 刷新秒数
|
||||
*/
|
||||
private Integer refreshTokenValidity;
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getSecret() {
|
||||
return secret;
|
||||
}
|
||||
|
||||
public void setSecret(String secret) {
|
||||
this.secret = secret;
|
||||
}
|
||||
|
||||
public String getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
public void setScope(String scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public String getResourceIds() {
|
||||
return resourceIds;
|
||||
}
|
||||
|
||||
public void setResourceIds(String resourceIds) {
|
||||
this.resourceIds = resourceIds;
|
||||
}
|
||||
|
||||
public String getGrantTypes() {
|
||||
return grantTypes;
|
||||
}
|
||||
|
||||
public void setGrantTypes(String grantTypes) {
|
||||
this.grantTypes = grantTypes;
|
||||
}
|
||||
|
||||
public String getRedirectUri() {
|
||||
return redirectUri;
|
||||
}
|
||||
|
||||
public void setRedirectUri(String redirectUri) {
|
||||
this.redirectUri = redirectUri;
|
||||
}
|
||||
|
||||
public Integer getAutoapprove() {
|
||||
return autoapprove;
|
||||
}
|
||||
|
||||
public void setAutoapprove(Integer autoapprove) {
|
||||
this.autoapprove = autoapprove;
|
||||
}
|
||||
|
||||
public Integer getAccessTokenValidity() {
|
||||
return accessTokenValidity;
|
||||
}
|
||||
|
||||
public void setAccessTokenValidity(Integer accessTokenValidity) {
|
||||
this.accessTokenValidity = accessTokenValidity;
|
||||
}
|
||||
|
||||
public Integer getRefreshTokenValidity() {
|
||||
return refreshTokenValidity;
|
||||
}
|
||||
|
||||
public void setRefreshTokenValidity(Integer refreshTokenValidity) {
|
||||
this.refreshTokenValidity = refreshTokenValidity;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>ab-auth</artifactId>
|
||||
<groupId>com.dstz</groupId>
|
||||
<version>2.5.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>ab-auth-core</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.dstz</groupId>
|
||||
<artifactId>ab-base-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.dstz</groupId>
|
||||
<artifactId>ab-auth-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.dstz</groupId>
|
||||
<artifactId>ab-sys-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,59 @@
|
|||
package com.dstz.auth.api;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.dstz.auth.authentication.api.SysApplicationApi;
|
||||
import com.dstz.auth.authentication.vo.SysApplicationVO;
|
||||
import com.dstz.auth.core.entity.SysApplication;
|
||||
import com.dstz.auth.core.manager.SysApplicationManager;
|
||||
import com.dstz.base.common.constats.NumberPool;
|
||||
import com.dstz.base.common.exceptions.BusinessMessage;
|
||||
import com.dstz.base.common.utils.BeanCopierUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.dstz.auth.authentication.api.constant.AuthStatusCode.APPCLICATION_ENABLE_DEFAULT_MOBILE_APP_NOT_FIND;
|
||||
|
||||
/**
|
||||
* 系统应用接口实现
|
||||
*
|
||||
* @author wacxhs
|
||||
*/
|
||||
@Service("sysApplicationApi")
|
||||
public class SysApplicationApiImpl implements SysApplicationApi {
|
||||
|
||||
private final SysApplicationManager sysApplicationManager;
|
||||
|
||||
public SysApplicationApiImpl(SysApplicationManager sysApplicationManager) {
|
||||
this.sysApplicationManager = sysApplicationManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysApplicationVO getByCode(String code) {
|
||||
SysApplication sysApplication = sysApplicationManager.getByAlias(code);
|
||||
return BeanCopierUtils.transformBean(sysApplication, SysApplicationVO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAllCode() {
|
||||
LambdaQueryWrapper<SysApplication> queryWrapper = Wrappers.lambdaQuery(SysApplication.class)
|
||||
.select(SysApplication::getCode);
|
||||
List<SysApplication> sysApplicationList = sysApplicationManager.selectByWrapper(queryWrapper);
|
||||
return CollUtil.map(sysApplicationList, SysApplication::getCode, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysApplicationVO getEnabledMobileApp() {
|
||||
LambdaQueryWrapper<SysApplication> queryWrapper = Wrappers.lambdaQuery(SysApplication.class)
|
||||
.eq(SysApplication::getEnabled, NumberPool.INTEGER_ONE)
|
||||
.eq(SysApplication::getIsDefault, NumberPool.INTEGER_ONE)
|
||||
.eq(SysApplication::getAppType, NumberPool.INTEGER_ONE);
|
||||
List<SysApplication> sysApplicationList = sysApplicationManager.selectByWrapper(queryWrapper);
|
||||
Assert.isTrue(CollUtil.isNotEmpty(sysApplicationList),()-> new BusinessMessage(APPCLICATION_ENABLE_DEFAULT_MOBILE_APP_NOT_FIND));
|
||||
return CollUtil.isNotEmpty(sysApplicationList) ? BeanCopierUtils.transformBean(sysApplicationList.get(0), SysApplicationVO.class) : null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package com.dstz.auth.api;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.dstz.auth.authentication.api.SysResourceApi;
|
||||
import com.dstz.auth.authentication.api.model.ISysApplication;
|
||||
import com.dstz.auth.authentication.api.model.ISysResource;
|
||||
import com.dstz.auth.core.entity.SysResource;
|
||||
import com.dstz.auth.core.manager.ResourceRoleManager;
|
||||
import com.dstz.auth.core.manager.SysApplicationManager;
|
||||
import com.dstz.auth.core.manager.SysResourceManager;
|
||||
import com.dstz.auth.rest.model.vo.SysResourceVO;
|
||||
import com.dstz.base.common.constats.AbCacheRegionConstant;
|
||||
import com.dstz.base.common.utils.BeanCopierUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.dstz.auth.authentication.api.constant.AuthCacheKeyConstant.IS_ROLE;
|
||||
|
||||
/**
|
||||
* 用户系统资源服务接口
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
@Service
|
||||
public class SysResourceApiImpl implements SysResourceApi {
|
||||
@Autowired
|
||||
SysResourceManager sysResourceManager;
|
||||
@Autowired
|
||||
SysApplicationManager sysApplicationManager;
|
||||
@Autowired
|
||||
ResourceRoleManager resourceRoleManager;
|
||||
|
||||
//办理事项的固定url地址
|
||||
private static final String TODO_RESOURCE = "/pages/bpm/definitionList";
|
||||
|
||||
/**
|
||||
* 通过资源id获取资源对象
|
||||
*
|
||||
* @param id 资源ID
|
||||
* @return ISysResource 资源对象
|
||||
*/
|
||||
@Override
|
||||
public ISysResource getResourceById(String id) {
|
||||
return BeanCopierUtils.transformBean(sysResourceManager.getById(id), SysResourceVO.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过资源code集合删除资源对象
|
||||
*
|
||||
* @param codeList 资源code集合
|
||||
*/
|
||||
@Override
|
||||
public void deleteResourceByCode(List<String> codeList) {
|
||||
sysResourceManager.deleteResourceByCode(codeList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ISysApplication> getCurrentUserSystem() {
|
||||
return (List) sysApplicationManager.getCurrentUserSystem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISysApplication getDefaultSystem(String currentUserId) {
|
||||
return sysApplicationManager.getDefaultSystem(currentUserId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ISysResource> getBySystemId(String systemId) {
|
||||
List<SysResource> bySystemId = sysResourceManager.getBySystemId(systemId);
|
||||
return (List) sysResourceManager.getBySystemId(systemId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ISysResource> getByAppIdAndUser(String appId, String userId) {
|
||||
List<SysResource> byAppIdAndUserId = sysResourceManager.getByAppIdAndUserId(appId, userId);
|
||||
return (List) sysResourceManager.getByAppIdAndUserId(appId, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAccessRoleByUrl(String url) {
|
||||
return resourceRoleManager.getAccessRoleByUrl(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = AbCacheRegionConstant.SYS_RESOURCE, key = IS_ROLE)
|
||||
public boolean isRoleByUrl(String url) {
|
||||
return CollUtil.isNotEmpty(sysResourceManager.selectByWrapper(Wrappers.lambdaQuery(SysResource.class).select(SysResource::getType).eq(SysResource::getType, "API").eq(SysResource::getUrl, url)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISysResource getTodoResource() {
|
||||
List<SysResource> resources = sysResourceManager.selectByWrapper(Wrappers.lambdaQuery(SysResource.class)
|
||||
.eq(SysResource::getUrl, TODO_RESOURCE));
|
||||
if (CollectionUtil.isEmpty(resources)) {
|
||||
return null;
|
||||
}
|
||||
return BeanCopierUtils.transformBean(resources.get(0), SysResourceVO.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,238 @@
|
|||
package com.dstz.auth.core.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.dstz.base.entity.AbModel;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 资源角色关联表
|
||||
* </p>
|
||||
*
|
||||
* @author lightning
|
||||
* @since 2022-02-07
|
||||
*/
|
||||
@TableName("sys_resource_role")
|
||||
public class ResourceRole extends AbModel<ResourceRole> {
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
@TableId(value = "id_", type = IdType.ASSIGN_ID)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 应用ID
|
||||
*/
|
||||
@TableField("app_id_")
|
||||
private String appId;
|
||||
|
||||
/**
|
||||
* 资源权限ID
|
||||
*/
|
||||
@TableField("resource_id_")
|
||||
private String resourceId;
|
||||
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
@TableField("role_id_")
|
||||
private String roleId;
|
||||
|
||||
/**
|
||||
* 半选中
|
||||
*/
|
||||
@TableField("half_checked_")
|
||||
private Integer halfChecked;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(value = "create_time_", fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 创建人ID
|
||||
*/
|
||||
@TableField(value = "create_by_", fill = FieldFill.INSERT)
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 角色别名。
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
protected String roleAlias;
|
||||
/**
|
||||
* 资源url连接。
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
protected String url;
|
||||
|
||||
/**
|
||||
* 资源别名。
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
protected String resAlias;
|
||||
|
||||
public String getRoleAlias() {
|
||||
return roleAlias;
|
||||
}
|
||||
|
||||
public void setRoleAlias(String roleAlias) {
|
||||
this.roleAlias = roleAlias;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getResAlias() {
|
||||
return resAlias;
|
||||
}
|
||||
|
||||
public void setResAlias(String resAlias) {
|
||||
this.resAlias = resAlias;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public void setResourceId(String resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
public String getRoleId() {
|
||||
return roleId;
|
||||
}
|
||||
|
||||
public void setRoleId(String roleId) {
|
||||
this.roleId = roleId;
|
||||
}
|
||||
|
||||
public Integer getHalfChecked() {
|
||||
return halfChecked;
|
||||
}
|
||||
|
||||
public void setHalfChecked(Integer halfChecked) {
|
||||
this.halfChecked = halfChecked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateBy() {
|
||||
return createBy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreateBy(String createBy) {
|
||||
this.createBy = createBy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable pkVal() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
|
||||
public static final class Builder {
|
||||
private String id;
|
||||
private String appId;
|
||||
private String resourceId;
|
||||
private String roleId;
|
||||
private Integer halfChecked;
|
||||
private Date createTime;
|
||||
private String createBy;
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
|
||||
public static Builder newBuilder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder withId(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withAppId(String appId) {
|
||||
this.appId = appId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withResourceId(String resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withRoleId(String roleId) {
|
||||
this.roleId = roleId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withHalfChecked(Integer halfChecked) {
|
||||
this.halfChecked = halfChecked;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withCreateBy(String createBy) {
|
||||
this.createBy = createBy;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ResourceRole build() {
|
||||
ResourceRole resourceRole = new ResourceRole();
|
||||
resourceRole.setId(id);
|
||||
resourceRole.setAppId(appId);
|
||||
resourceRole.setResourceId(resourceId);
|
||||
resourceRole.setRoleId(roleId);
|
||||
resourceRole.setHalfChecked(halfChecked);
|
||||
resourceRole.setCreateTime(createTime);
|
||||
resourceRole.setCreateBy(createBy);
|
||||
return resourceRole;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,394 @@
|
|||
package com.dstz.auth.core.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.dstz.auth.authentication.api.model.ISysApplication;
|
||||
import com.dstz.base.entity.AbModel;
|
||||
import java.util.Date;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 应用
|
||||
* </p>
|
||||
*
|
||||
* @author lightning
|
||||
* @since 2022-08-03
|
||||
*/
|
||||
@TableName("sys_application")
|
||||
public class SysApplication extends AbModel<SysApplication> implements ISysApplication {
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
@TableId(value = "id_", type = IdType.ASSIGN_ID)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 应用名
|
||||
*/
|
||||
@TableField("name_")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 编码
|
||||
*/
|
||||
@TableField("code_")
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 密匙
|
||||
*/
|
||||
@TableField("secret_")
|
||||
private String secret;
|
||||
|
||||
/**
|
||||
* 资源集合
|
||||
*/
|
||||
@TableField("resource_ids_")
|
||||
private String resourceIds;
|
||||
|
||||
/**
|
||||
* 授权范围
|
||||
*/
|
||||
@TableField("scope_")
|
||||
private String scope;
|
||||
|
||||
/**
|
||||
* 刷新秒数
|
||||
*/
|
||||
@TableField("refresh_token_validity_")
|
||||
private Integer refreshTokenValidity;
|
||||
|
||||
/**
|
||||
* 有效期
|
||||
*/
|
||||
@TableField("access_token_validity_")
|
||||
private Integer accessTokenValidity;
|
||||
|
||||
/**
|
||||
* 授权类型
|
||||
*/
|
||||
@TableField("grant_types_")
|
||||
private String grantTypes;
|
||||
|
||||
/**
|
||||
* 自动授权
|
||||
*/
|
||||
@TableField("autoapprove_")
|
||||
private Integer autoapprove;
|
||||
|
||||
/**
|
||||
* 权限
|
||||
*/
|
||||
@TableField("authorities_")
|
||||
private String authorities;
|
||||
|
||||
/**
|
||||
* 系统地址,空则为当前系统
|
||||
*/
|
||||
@TableField("url_")
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 回调地址
|
||||
*/
|
||||
@TableField("redirect_uri_")
|
||||
private String redirectUri;
|
||||
|
||||
/**
|
||||
* 打开方式
|
||||
*/
|
||||
@TableField("open_type_")
|
||||
private String openType;
|
||||
|
||||
/**
|
||||
* 是否可用
|
||||
*/
|
||||
@TableField("enabled_")
|
||||
private Integer enabled;
|
||||
|
||||
/**
|
||||
* 是否默认打开
|
||||
*/
|
||||
@TableField("is_default_")
|
||||
private Integer isDefault;
|
||||
|
||||
/**
|
||||
* 描述备注
|
||||
*/
|
||||
@TableField("desc_")
|
||||
private String desc;
|
||||
|
||||
/**
|
||||
* 扩展配置
|
||||
*/
|
||||
@TableField("config_")
|
||||
private String config;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(value = "create_time_", fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 创建人ID
|
||||
*/
|
||||
@TableField(value = "create_by_", fill = FieldFill.INSERT)
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 所属组织
|
||||
*/
|
||||
@TableField(value = "create_org_id_", fill = FieldFill.INSERT)
|
||||
private String createOrgId;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField(value = "update_time_", fill = FieldFill.INSERT_UPDATE)
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 更新人ID
|
||||
*/
|
||||
@TableField(value = "update_by_", fill = FieldFill.INSERT_UPDATE)
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 更新人
|
||||
*/
|
||||
@TableField(value = "updater_", fill = FieldFill.INSERT_UPDATE)
|
||||
private String updater;
|
||||
|
||||
|
||||
/**
|
||||
* 应用类型 0 web应用 1 移动端 2第三方应用
|
||||
*/
|
||||
@TableField("app_type_")
|
||||
private Integer appType;
|
||||
|
||||
@Override
|
||||
public Integer getAppType() {
|
||||
return appType;
|
||||
}
|
||||
|
||||
public void setAppType(Integer appType) {
|
||||
this.appType = appType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getSecret() {
|
||||
return secret;
|
||||
}
|
||||
|
||||
public void setSecret(String secret) {
|
||||
this.secret = secret;
|
||||
}
|
||||
|
||||
public String getResourceIds() {
|
||||
return resourceIds;
|
||||
}
|
||||
|
||||
public void setResourceIds(String resourceIds) {
|
||||
this.resourceIds = resourceIds;
|
||||
}
|
||||
|
||||
public String getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
public void setScope(String scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public Integer getRefreshTokenValidity() {
|
||||
return refreshTokenValidity;
|
||||
}
|
||||
|
||||
public void setRefreshTokenValidity(Integer refreshTokenValidity) {
|
||||
this.refreshTokenValidity = refreshTokenValidity;
|
||||
}
|
||||
|
||||
public Integer getAccessTokenValidity() {
|
||||
return accessTokenValidity;
|
||||
}
|
||||
|
||||
public void setAccessTokenValidity(Integer accessTokenValidity) {
|
||||
this.accessTokenValidity = accessTokenValidity;
|
||||
}
|
||||
|
||||
public String getGrantTypes() {
|
||||
return grantTypes;
|
||||
}
|
||||
|
||||
public void setGrantTypes(String grantTypes) {
|
||||
this.grantTypes = grantTypes;
|
||||
}
|
||||
|
||||
public Integer getAutoapprove() {
|
||||
return autoapprove;
|
||||
}
|
||||
|
||||
public void setAutoapprove(Integer autoapprove) {
|
||||
this.autoapprove = autoapprove;
|
||||
}
|
||||
|
||||
public String getAuthorities() {
|
||||
return authorities;
|
||||
}
|
||||
|
||||
public void setAuthorities(String authorities) {
|
||||
this.authorities = authorities;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getRedirectUri() {
|
||||
return redirectUri;
|
||||
}
|
||||
|
||||
public void setRedirectUri(String redirectUri) {
|
||||
this.redirectUri = redirectUri;
|
||||
}
|
||||
|
||||
public String getOpenType() {
|
||||
return openType;
|
||||
}
|
||||
|
||||
public void setOpenType(String openType) {
|
||||
this.openType = openType;
|
||||
}
|
||||
|
||||
public Integer getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(Integer enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public Integer getIsDefault() {
|
||||
return isDefault;
|
||||
}
|
||||
|
||||
public void setIsDefault(Integer isDefault) {
|
||||
this.isDefault = isDefault;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
|
||||
public void setDesc(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public String getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setConfig(String config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateBy() {
|
||||
return createBy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreateBy(String createBy) {
|
||||
this.createBy = createBy;
|
||||
}
|
||||
|
||||
public String getCreateOrgId() {
|
||||
return createOrgId;
|
||||
}
|
||||
|
||||
public void setCreateOrgId(String createOrgId) {
|
||||
this.createOrgId = createOrgId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUpdateBy() {
|
||||
return updateBy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUpdateBy(String updateBy) {
|
||||
this.updateBy = updateBy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUpdater() {
|
||||
return updater;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUpdater(String updater) {
|
||||
this.updater = updater;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable pkVal() {
|
||||
return this.id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,309 @@
|
|||
package com.dstz.auth.core.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.dstz.base.entity.AbModel;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 系统权限资源定义
|
||||
* </p>
|
||||
*
|
||||
* @author lightning
|
||||
* @since 2022-02-07
|
||||
*/
|
||||
@TableName("sys_resource")
|
||||
public class SysResource extends AbModel<SysResource> {
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
@TableId(value = "id_", type = IdType.ASSIGN_ID)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 应用ID
|
||||
*/
|
||||
@TableField("app_id_")
|
||||
private String appId;
|
||||
|
||||
/**
|
||||
* 权限编码
|
||||
*/
|
||||
@TableField("code_")
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 名字
|
||||
*/
|
||||
@TableField("name_")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 路由地址
|
||||
*/
|
||||
@TableField("url_")
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 是否启用
|
||||
*/
|
||||
@TableField("enable_")
|
||||
private Integer enable;
|
||||
|
||||
/**
|
||||
* 是否默认打开
|
||||
*/
|
||||
@TableField("opened_")
|
||||
private Integer opened;
|
||||
|
||||
/**
|
||||
* 是否API资源
|
||||
*/
|
||||
@TableField("is_api_")
|
||||
private Integer isApi;
|
||||
|
||||
/**
|
||||
* 图标
|
||||
*/
|
||||
@TableField("icon_")
|
||||
private String icon;
|
||||
|
||||
/**
|
||||
* menu,button,API
|
||||
*/
|
||||
@TableField("type_")
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
@TableField("sn_")
|
||||
private Integer sn;
|
||||
|
||||
/**
|
||||
* 父节点ID
|
||||
*/
|
||||
@TableField("parent_id_")
|
||||
private String parentId;
|
||||
|
||||
/**
|
||||
* 路径
|
||||
*/
|
||||
@TableField("path_")
|
||||
private String path;
|
||||
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(value = "create_time_", fill = FieldFill.INSERT)
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 创建人ID
|
||||
*/
|
||||
@TableField(value = "create_by_", fill = FieldFill.INSERT)
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 所属组织
|
||||
*/
|
||||
@TableField(value = "create_org_id_", fill = FieldFill.INSERT)
|
||||
private String createOrgId;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField(value = "update_time_", fill = FieldFill.INSERT_UPDATE)
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 更新人
|
||||
*/
|
||||
@TableField(value = "updater_", fill = FieldFill.INSERT_UPDATE)
|
||||
private String updater;
|
||||
|
||||
/**
|
||||
* 更新人ID
|
||||
*/
|
||||
@TableField(value = "update_by_", fill = FieldFill.INSERT_UPDATE)
|
||||
private String updateBy;
|
||||
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public Integer getEnable() {
|
||||
return enable;
|
||||
}
|
||||
|
||||
public void setEnable(Integer enable) {
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public Integer getOpened() {
|
||||
return opened;
|
||||
}
|
||||
|
||||
public void setOpened(Integer opened) {
|
||||
this.opened = opened;
|
||||
}
|
||||
|
||||
public Integer getIsApi() {
|
||||
return isApi;
|
||||
}
|
||||
|
||||
public void setIsApi(Integer isApi) {
|
||||
this.isApi = isApi;
|
||||
}
|
||||
|
||||
public String getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public void setIcon(String icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Integer getSn() {
|
||||
return sn;
|
||||
}
|
||||
|
||||
public void setSn(Integer sn) {
|
||||
this.sn = sn;
|
||||
}
|
||||
|
||||
public String getParentId() {
|
||||
return parentId;
|
||||
}
|
||||
|
||||
public void setParentId(String parentId) {
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateBy() {
|
||||
return createBy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreateBy(String createBy) {
|
||||
this.createBy = createBy;
|
||||
}
|
||||
|
||||
public String getCreateOrgId() {
|
||||
return createOrgId;
|
||||
}
|
||||
|
||||
public void setCreateOrgId(String createOrgId) {
|
||||
this.createOrgId = createOrgId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUpdater() {
|
||||
return updater;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUpdater(String updater) {
|
||||
this.updater = updater;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUpdateBy() {
|
||||
return updateBy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUpdateBy(String updateBy) {
|
||||
this.updateBy = updateBy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable pkVal() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.dstz.auth.core.manager;
|
||||
|
||||
import com.dstz.auth.core.entity.ResourceRole;
|
||||
import com.dstz.auth.rest.model.dto.GrantRoleResourceDTO;
|
||||
import com.dstz.auth.rest.model.vo.SysResourceTreeVO;
|
||||
import com.dstz.base.manager.AbBaseManager;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 资源角色关联表 通用业务类
|
||||
* </p>
|
||||
*
|
||||
* @author lightning
|
||||
* @since 2022-02-07
|
||||
*/
|
||||
public interface ResourceRoleManager extends AbBaseManager<ResourceRole> {
|
||||
/**
|
||||
* 根据id查询
|
||||
* @param roleId
|
||||
*/
|
||||
List<ResourceRole> getAllByRoleId(String roleId);
|
||||
|
||||
/**
|
||||
* 分配角色资源。
|
||||
*
|
||||
* @param dto grant dto
|
||||
*/
|
||||
void grantRoleResource(GrantRoleResourceDTO dto);
|
||||
|
||||
/**
|
||||
* 通过url 获取可访问的角色
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
Set<String> getAccessRoleByUrl(String url);
|
||||
|
||||
/**
|
||||
* 根据角色id和编码查询资源树
|
||||
* @param roleId
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
List<SysResourceTreeVO> getRoleResTreeData(String roleId, String code);
|
||||
|
||||
/**
|
||||
* 根据系统id和角色id查询资源树
|
||||
* @param systemId
|
||||
* @param roleId
|
||||
* @return
|
||||
*/
|
||||
List<SysResourceTreeVO> getRoleRes(String systemId, String roleId);
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package com.dstz.auth.core.manager;
|
||||
|
||||
import com.dstz.auth.core.entity.SysApplication;
|
||||
import com.dstz.auth.rest.model.vo.SysResourceTreeVO;
|
||||
import com.dstz.base.manager.AbBaseManager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 应用 通用业务类
|
||||
* </p>
|
||||
*
|
||||
* @author lightning
|
||||
* @since 2022-02-07
|
||||
*/
|
||||
public interface SysApplicationManager extends AbBaseManager<SysApplication> {
|
||||
/**
|
||||
* 判断别名是否存在。
|
||||
*
|
||||
* @param subsystem
|
||||
* @return
|
||||
*/
|
||||
boolean isExist(SysApplication subsystem);
|
||||
|
||||
/**
|
||||
* 获取默认子系统。
|
||||
* 1.获取用户有权限的系统,如果没有权限则返回空。
|
||||
* 2.如果权限子系统,判断是否有默认的子系统,有则返回。
|
||||
* 3.否则取第一个。
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
SysApplication getDefaultSystem(String userId);
|
||||
|
||||
/**
|
||||
* 设置默认子系统。
|
||||
* 1.如果是默认的则取消。
|
||||
* 2.非默认则设置默认。
|
||||
*
|
||||
* @param systemId
|
||||
*/
|
||||
void setDefaultSystem(String systemId);
|
||||
|
||||
/**
|
||||
* 通过应用系统对象获取资源树
|
||||
*
|
||||
* @param sysApplication 应用对象
|
||||
* @return 资源树对象
|
||||
*/
|
||||
List<SysResourceTreeVO> getTreeDataByApplication(SysApplication sysApplication);
|
||||
|
||||
/**
|
||||
* 获取当前用户可用系统
|
||||
* @return
|
||||
*/
|
||||
List<SysApplication> getCurrentUserSystem();
|
||||
/**
|
||||
* 根据userId获取系统
|
||||
* @return
|
||||
*/
|
||||
List<SysApplication> getSystemByUser(String userId);
|
||||
/**
|
||||
* 根据code获取系统
|
||||
* @return
|
||||
*/
|
||||
SysApplication getByAlias(String code);
|
||||
|
||||
|
||||
/**
|
||||
* 根据id更新应用
|
||||
*/
|
||||
|
||||
int updateById(SysApplication subsystem);
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package com.dstz.auth.core.manager;
|
||||
|
||||
import com.dstz.auth.authentication.api.model.ISysResource;
|
||||
import com.dstz.auth.core.entity.SysResource;
|
||||
import com.dstz.auth.rest.model.dto.SysResourceDTO;
|
||||
import com.dstz.auth.rest.model.vo.SysResourceVO;
|
||||
import com.dstz.base.manager.AbBaseManager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 系统权限资源定义 通用业务类
|
||||
* </p>
|
||||
*
|
||||
* @author lightning
|
||||
* @since 2022-02-07
|
||||
*/
|
||||
public interface SysResourceManager extends AbBaseManager<SysResource> {
|
||||
|
||||
/**
|
||||
* 根据子系统ID获取实体列表。
|
||||
*/
|
||||
List<SysResource> getBySystemId(String id);
|
||||
|
||||
|
||||
/**
|
||||
* 根据系统和角色ID获取资源。
|
||||
*
|
||||
* @param systemId
|
||||
* @param roleId
|
||||
* @return
|
||||
*/
|
||||
List<SysResource> getBySystemAndRole(String systemId, String roleId);
|
||||
|
||||
/**
|
||||
* 判断资源是否存在。
|
||||
*
|
||||
* @param resource
|
||||
* @return
|
||||
*/
|
||||
boolean isExist(SysResource resource);
|
||||
|
||||
/**
|
||||
* 根据资源id递归删除资源数据。
|
||||
*
|
||||
* @param resId
|
||||
*/
|
||||
void removeByResId(String resId);
|
||||
|
||||
/**
|
||||
* 根据系统id和用户id获取资源。
|
||||
*
|
||||
* @param appId 应用ID
|
||||
* @param userId 用户ID
|
||||
* @return 资源列表
|
||||
*/
|
||||
List<SysResource> getByAppIdAndUserId(String appId, String userId);
|
||||
|
||||
/**
|
||||
* 根据id获取资源明细信息
|
||||
*
|
||||
* @param id
|
||||
* @param systemId
|
||||
* @param parentId
|
||||
* @return
|
||||
*/
|
||||
SysResourceVO getResourceDetailById(String id, String parentId, String systemId);
|
||||
|
||||
|
||||
/**
|
||||
* 保存树结构
|
||||
* @param sysResource
|
||||
*/
|
||||
void saveTree(SysResourceDTO sysResource);
|
||||
|
||||
/**
|
||||
* 保存单条资源
|
||||
* @param sysResource
|
||||
*/
|
||||
String saveSysResource(SysResource sysResource);
|
||||
|
||||
/**
|
||||
* 通过资源code集合删除资源对象
|
||||
* @param codeList 资源code集合
|
||||
*/
|
||||
void deleteResourceByCode(List<String> codeList);
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
package com.dstz.auth.core.manager.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.collection.IterUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.dstz.auth.authentication.api.constant.AuthStatusCode;
|
||||
import com.dstz.auth.core.entity.ResourceRole;
|
||||
import com.dstz.auth.core.entity.SysApplication;
|
||||
import com.dstz.auth.core.entity.SysResource;
|
||||
import com.dstz.auth.core.manager.ResourceRoleManager;
|
||||
import com.dstz.auth.core.manager.SysApplicationManager;
|
||||
import com.dstz.auth.core.manager.SysResourceManager;
|
||||
import com.dstz.auth.core.mapper.ResourceRoleMapper;
|
||||
import com.dstz.auth.rest.model.dto.GrantRoleResourceDTO;
|
||||
import com.dstz.auth.rest.model.vo.SysResourceTreeVO;
|
||||
import com.dstz.base.common.cache.ICache;
|
||||
import com.dstz.base.common.constats.AbCacheRegionConstant;
|
||||
import com.dstz.base.common.constats.NumberPool;
|
||||
import com.dstz.base.common.constats.StrPool;
|
||||
import com.dstz.base.common.exceptions.BusinessMessage;
|
||||
import com.dstz.base.common.utils.BeanConversionUtils;
|
||||
import com.dstz.base.common.utils.BeanCopierUtils;
|
||||
import com.dstz.base.manager.impl.AbBaseManagerImpl;
|
||||
import com.dstz.org.api.GroupApi;
|
||||
import com.dstz.org.api.enums.GroupType;
|
||||
import com.dstz.org.api.model.IGroup;
|
||||
import com.google.common.collect.Streams;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 资源角色关联表 通用服务实现类
|
||||
*
|
||||
* @author lightning
|
||||
* @since 2022-02-07
|
||||
*/
|
||||
@Service("resourceRoleManager")
|
||||
public class ResourceRoleManagerImpl extends AbBaseManagerImpl<ResourceRole> implements ResourceRoleManager {
|
||||
|
||||
@Autowired
|
||||
ResourceRoleMapper resourceRoleMapper;
|
||||
|
||||
@Autowired
|
||||
ICache iCache;
|
||||
|
||||
@Autowired
|
||||
ThreadPoolTaskExecutor threadPoolTaskExecutor;
|
||||
|
||||
@Autowired
|
||||
SysApplicationManager sysApplicationManager;
|
||||
|
||||
@Autowired
|
||||
SysResourceManager sysResourceManager;
|
||||
|
||||
@Autowired
|
||||
private GroupApi groupApi;
|
||||
|
||||
@Override
|
||||
public List<ResourceRole> getAllByRoleId(String roleId) {
|
||||
return resourceRoleMapper.getByRoleId(roleId);
|
||||
}
|
||||
|
||||
|
||||
@CacheEvict(cacheNames = AbCacheRegionConstant.SYS_RESOURCE, allEntries = true)
|
||||
@Override
|
||||
public void grantRoleResource(GrantRoleResourceDTO dto) {
|
||||
resourceRoleMapper.removeByRoleAndSystem(dto.getRoleId(), dto.getAppId());
|
||||
|
||||
Stream<String> resIdStream = Stream.empty();
|
||||
ResourceRole.Builder builder = ResourceRole.Builder.newBuilder().withRoleId(dto.getRoleId()).withAppId(dto.getAppId()).withHalfChecked(NumberPool.BOOLEAN_FALSE);
|
||||
if (CollUtil.isNotEmpty(dto.getResIds())) {
|
||||
resIdStream = Stream.concat(resIdStream, dto.getResIds().stream());
|
||||
}
|
||||
// 设置半选中
|
||||
resIdStream = Stream.concat(resIdStream, Stream.of(StrUtil.EMPTY).peek(o -> builder.withHalfChecked(NumberPool.BOOLEAN_TRUE)));
|
||||
if (CollUtil.isNotEmpty(dto.getHalfResIds())) {
|
||||
resIdStream = Stream.concat(resIdStream, dto.getHalfResIds().stream());
|
||||
}
|
||||
|
||||
Iterator<ResourceRole> iterator = resIdStream
|
||||
.filter(resId -> !StrPool.NUMBER_ZERO.equals(resId) && StrUtil.isNotEmpty(resId))
|
||||
.map(resId -> builder.withResourceId(resId).build())
|
||||
.iterator();
|
||||
|
||||
// 批量入库
|
||||
bulkCreate(IterUtil.asIterable(iterator));
|
||||
}
|
||||
|
||||
@Cacheable(cacheNames = AbCacheRegionConstant.SYS_RESOURCE, key = "#url")
|
||||
@Override
|
||||
public Set<String> getAccessRoleByUrl(String url) {
|
||||
url = StrUtil.trimToNull(url);
|
||||
if (StrUtil.isEmpty(url)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
// 根据资源地址获取角色ID
|
||||
Set<String> roleIds = resourceRoleMapper.getRoleIdByResourceUrl(url);
|
||||
if (CollUtil.isEmpty(roleIds)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
// 获取角色编码
|
||||
return Optional.ofNullable(groupApi.getByGroupIds(GroupType.ROLE.getType(), roleIds))
|
||||
.map(Streams::stream)
|
||||
.orElseGet(Stream::empty)
|
||||
.filter(o -> o.getAttrValue("enabled", Boolean.class))
|
||||
.map(IGroup::getGroupCode)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysResourceTreeVO> getRoleResTreeData(String roleId, String code) {
|
||||
SysApplication system = sysApplicationManager.getByAlias(code);
|
||||
Assert.notNull(system,()->new BusinessMessage(AuthStatusCode.SYS_IS_NOT_DEFINITION.formatDefaultMessage(code)));
|
||||
return BeanConversionUtils.listToTree(getRoleRes(system.getId(), roleId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysResourceTreeVO> getRoleRes(String systemId, String roleId) {
|
||||
|
||||
List<SysResource> roleResourceList = sysResourceManager.getBySystemAndRole(systemId, roleId);
|
||||
Set<String> userResourceId = new HashSet<>(roleResourceList.size(), 1);
|
||||
roleResourceList.forEach(resouces -> userResourceId.add(resouces.getId()));
|
||||
List<SysResource> resourceList = sysResourceManager.getBySystemId(systemId);
|
||||
List<SysResourceTreeVO> sysResourceTreeVOS = BeanCopierUtils.transformList(resourceList,SysResourceTreeVO.class);
|
||||
for (SysResourceTreeVO sysResource : sysResourceTreeVOS) {
|
||||
if (userResourceId.contains(sysResource.getId())) {
|
||||
sysResource.setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (CollectionUtil.isEmpty(resourceList)) {
|
||||
resourceList = new ArrayList<>();
|
||||
}
|
||||
|
||||
SysResource rootRes = new SysResource();
|
||||
String rootName = sysApplicationManager.getById(systemId).getName();
|
||||
rootRes.setName(rootName);
|
||||
rootRes.setId(NumberPool.INTEGER_ZERO.toString());
|
||||
rootRes.setCode("root");
|
||||
// 根节点
|
||||
rootRes.setAppId(systemId);
|
||||
resourceList.add(rootRes);
|
||||
return sysResourceTreeVOS;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
package com.dstz.auth.core.manager.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.collection.IterUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.dstz.auth.core.entity.SysApplication;
|
||||
import com.dstz.auth.core.entity.SysResource;
|
||||
import com.dstz.auth.core.manager.SysApplicationManager;
|
||||
import com.dstz.auth.core.manager.SysResourceManager;
|
||||
import com.dstz.auth.core.mapper.ResourceRoleMapper;
|
||||
import com.dstz.auth.core.mapper.SysApplicationMapper;
|
||||
import com.dstz.auth.rest.model.vo.SysResourceTreeVO;
|
||||
import com.dstz.base.common.constats.AbCacheRegionConstant;
|
||||
import com.dstz.base.common.constats.NumberPool;
|
||||
import com.dstz.base.common.context.UserContext;
|
||||
import com.dstz.base.common.utils.BeanConversionUtils;
|
||||
import com.dstz.base.common.utils.BeanCopierUtils;
|
||||
import com.dstz.base.common.utils.UserContextUtils;
|
||||
import com.dstz.base.manager.impl.AbBaseManagerImpl;
|
||||
import com.dstz.org.api.GroupApi;
|
||||
import com.dstz.org.api.enums.GroupType;
|
||||
import com.dstz.org.api.model.IGroup;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 应用 通用服务实现类
|
||||
*
|
||||
* @author lightning
|
||||
* @since 2022-02-07
|
||||
*/
|
||||
@Service("sysApplicationManager")
|
||||
public class SysApplicationManagerImpl extends AbBaseManagerImpl<SysApplication> implements SysApplicationManager {
|
||||
@Autowired
|
||||
SysApplicationMapper sysApplicationMapper;
|
||||
@Autowired
|
||||
SysResourceManager sysResourceManager;
|
||||
@Autowired
|
||||
private ResourceRoleMapper resourceRoleMapper;
|
||||
@Autowired
|
||||
private GroupApi groupApi;
|
||||
|
||||
@Override
|
||||
public boolean isExist(SysApplication subsystem) {
|
||||
return sysApplicationMapper.isExist(subsystem) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过应用系统对象获取资源树
|
||||
*
|
||||
* @param sysApplication 应用对象
|
||||
* @return 资源树对象
|
||||
*/
|
||||
@Override
|
||||
public List<SysResourceTreeVO> getTreeDataByApplication(SysApplication sysApplication) {
|
||||
List<SysResource> resourceList = sysResourceManager.getBySystemId(sysApplication.getId());
|
||||
List<SysResourceTreeVO> groupList = BeanCopierUtils.transformList(resourceList, SysResourceTreeVO.class);
|
||||
if (CollectionUtil.isEmpty(groupList)) {
|
||||
groupList = new ArrayList<>();
|
||||
}
|
||||
SysResourceTreeVO rootResource = new SysResourceTreeVO();
|
||||
rootResource.setName(sysApplication.getName());
|
||||
rootResource.setId(NumberPool.INTEGER_ZERO.toString());
|
||||
// 根节点
|
||||
rootResource.setAppId(sysApplication.getId());
|
||||
groupList.add(rootResource);
|
||||
return BeanConversionUtils.listToTree(groupList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysApplication getDefaultSystem(String userId) {
|
||||
List<SysApplication> sysApplications = getSystemByUser(userId);
|
||||
if (CollectionUtil.isEmpty(sysApplications)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Optional.ofNullable(CollUtil.findOne(sysApplications, app -> NumberPool.BOOLEAN_TRUE.equals(app.getIsDefault())))
|
||||
.orElseGet(() -> CollUtil.getFirst(sysApplications));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaultSystem(String systemId) {
|
||||
SysApplication subSystem = sysApplicationMapper.selectById(systemId);
|
||||
if (subSystem.getIsDefault() == NumberPool.BOOLEAN_TRUE) {
|
||||
subSystem.setIsDefault(NumberPool.BOOLEAN_FALSE);
|
||||
} else {
|
||||
sysApplicationMapper.updNoDefault();
|
||||
subSystem.setIsDefault(NumberPool.BOOLEAN_TRUE);
|
||||
}
|
||||
sysApplicationMapper.updateById(subSystem);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<SysApplication> getCurrentUserSystem() {
|
||||
UserContext userContext = UserContextUtils.getUserContext();
|
||||
if (userContext.isSuperAdmin()) {
|
||||
LambdaQueryWrapper<SysApplication> queryWrapper = Wrappers.lambdaQuery(SysApplication.class).eq(SysApplication::getEnabled, NumberPool.BOOLEAN_TRUE);
|
||||
return sysApplicationMapper.selectList(queryWrapper);
|
||||
}
|
||||
|
||||
// 获取用户角色编码
|
||||
Collection<String> authorities = userContext.getAuthorities();
|
||||
if (CollUtil.isEmpty(authorities)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 获取当前用户角色列表
|
||||
List<String> roleIds = Optional.ofNullable(groupApi.getByGroupCodes(GroupType.ROLE.getType(), authorities))
|
||||
.map(IterUtil::asIterable)
|
||||
.map(iter -> CollUtil.map(iter, IGroup::getGroupId, true))
|
||||
.orElse(null);
|
||||
|
||||
// 角色ID未获取到返回空列表
|
||||
if (CollUtil.isEmpty(roleIds)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 角色ID获取关联的应用ID
|
||||
Set<String> appIds = resourceRoleMapper.selectAppIdByRoleIds(roleIds);
|
||||
if (CollUtil.isEmpty(appIds)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 查询应用列表
|
||||
LambdaQueryWrapper<SysApplication> queryWrapper = Wrappers.lambdaQuery(SysApplication.class).in(SysApplication::getId, appIds).eq(SysApplication::getEnabled, NumberPool.BOOLEAN_TRUE);
|
||||
return sysApplicationMapper.selectList(queryWrapper);
|
||||
}
|
||||
|
||||
@Cacheable(cacheNames = AbCacheRegionConstant.SYS_APPLICATION, key = "#code")
|
||||
@Override
|
||||
public SysApplication getByAlias(String code) {
|
||||
return sysApplicationMapper.getByAlias(code);
|
||||
}
|
||||
|
||||
@CacheEvict(cacheNames = AbCacheRegionConstant.SYS_APPLICATION, key = "#subsystem.code", allEntries = true)
|
||||
@Override
|
||||
public int updateById(SysApplication subsystem) {
|
||||
return sysApplicationMapper.updateById(subsystem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysApplication> getSystemByUser(String userId) {
|
||||
List<String> roleIds = CollUtil.map(groupApi.getByGroupTypeAndUserId(GroupType.ROLE.getType(), userId), IGroup::getGroupId, true);
|
||||
if (CollUtil.isEmpty(roleIds)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
Set<String> appIds = resourceRoleMapper.selectAppIdByRoleIds(roleIds);
|
||||
if (CollUtil.isNotEmpty(appIds)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 查询应用列表
|
||||
LambdaQueryWrapper<SysApplication> queryWrapper = Wrappers.lambdaQuery(SysApplication.class).in(SysApplication::getId, appIds).eq(SysApplication::getEnabled, NumberPool.BOOLEAN_TRUE);
|
||||
return sysApplicationMapper.selectList(queryWrapper);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,182 @@
|
|||
package com.dstz.auth.core.manager.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.dstz.auth.authentication.api.constant.AuthStatusCode;
|
||||
import com.dstz.auth.authentication.api.constant.ResouceTypeConstant;
|
||||
import com.dstz.auth.core.entity.SysResource;
|
||||
import com.dstz.auth.core.manager.SysResourceManager;
|
||||
import com.dstz.auth.core.mapper.SysResourceMapper;
|
||||
import com.dstz.auth.rest.model.dto.SysResourceDTO;
|
||||
import com.dstz.auth.rest.model.vo.SysResourceVO;
|
||||
import com.dstz.base.common.constats.NumberPool;
|
||||
import com.dstz.base.common.exceptions.BusinessException;
|
||||
import com.dstz.base.common.exceptions.BusinessMessage;
|
||||
import com.dstz.base.common.utils.BeanCopierUtils;
|
||||
import com.dstz.base.manager.impl.AbBaseManagerImpl;
|
||||
import com.dstz.org.api.GroupApi;
|
||||
import com.dstz.org.api.enums.GroupType;
|
||||
import com.dstz.org.api.model.IGroup;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 系统权限资源定义 通用服务实现类
|
||||
*
|
||||
* @author lightning
|
||||
* @since 2022-02-07
|
||||
*/
|
||||
@Service("sysResourceManager")
|
||||
public class SysResourceManagerImpl extends AbBaseManagerImpl<SysResource> implements SysResourceManager {
|
||||
|
||||
@Autowired
|
||||
SysResourceMapper sysResourceMapper;
|
||||
@Autowired
|
||||
private GroupApi groupApi;
|
||||
|
||||
|
||||
@Override
|
||||
public List<SysResource> getBySystemId(String id) {
|
||||
return sysResourceMapper.getBySystemId(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysResource> getBySystemAndRole(String systemId, String roleId) {
|
||||
return sysResourceMapper.getBySystemAndRole(systemId, roleId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExist(SysResource resource) {
|
||||
return sysResourceMapper.isExist(resource) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeByResId(String resId) {
|
||||
SysResource resource = sysResourceMapper.selectById(resId);
|
||||
if (resource == null) {
|
||||
return;
|
||||
}
|
||||
List<SysResource> relatedResouces = new ArrayList<>();
|
||||
|
||||
getChildList(relatedResouces, resource.getId());
|
||||
if (CollectionUtil.isNotEmpty(relatedResouces)) {
|
||||
sysResourceMapper.deleteBatchIds(relatedResouces.stream().map(SysResource::getId).collect(Collectors.toList()));
|
||||
}
|
||||
sysResourceMapper.deleteById(resId);
|
||||
}
|
||||
|
||||
|
||||
private void getChildList(List<SysResource> relatedResouces, String id) {
|
||||
List<SysResource> children = sysResourceMapper.getByParentId(id);
|
||||
if (CollectionUtil.isEmpty(children)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (SysResource r : children) {
|
||||
getChildList(relatedResouces, r.getId());
|
||||
}
|
||||
relatedResouces.addAll(children);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysResource> getByAppIdAndUserId(String appId, String userId) {
|
||||
List<String> roleIds = CollUtil.map(groupApi.getByGroupTypeAndUserId(GroupType.ROLE.getType(), userId), IGroup::getGroupId, true);
|
||||
if (CollUtil.isEmpty(roleIds)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return sysResourceMapper.getByAppIdAndRoleIds(appId, roleIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysResourceVO getResourceDetailById(String id, String parentId, String systemId) {
|
||||
SysResourceVO sysResourceVO = new SysResourceVO();
|
||||
if (StrUtil.isEmpty(id)) {
|
||||
SysResource parent = this.getById(parentId);
|
||||
if (parent != null) {
|
||||
sysResourceVO.setAppId(parent.getAppId());
|
||||
sysResourceVO.setParentName(parent.getName());
|
||||
sysResourceVO.setParentId(parentId);
|
||||
} else {
|
||||
sysResourceVO.setAppId(systemId);
|
||||
sysResourceVO.setParentId(parentId);
|
||||
}
|
||||
|
||||
sysResourceVO.setOpened(NumberPool.BOOLEAN_TRUE);
|
||||
return sysResourceVO;
|
||||
} else {
|
||||
SysResource sysResource = this.getById(id);
|
||||
|
||||
BeanCopierUtils.copyProperties(sysResource, sysResourceVO);
|
||||
SysResource parent = this.getById(sysResource.getParentId());
|
||||
if (parent != null) {
|
||||
sysResourceVO.setParentName(parent.getName());
|
||||
}
|
||||
}
|
||||
return sysResourceVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveTree(SysResourceDTO sysResource) {
|
||||
if (CollUtil.isNotEmpty(sysResource.getChildren())) {
|
||||
saveTreeList(sysResource.getChildren(), sysResource.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String saveSysResource(SysResource sysResource) {
|
||||
checkResouce(sysResource);
|
||||
|
||||
if (StrUtil.isEmpty(sysResource.getId())) {
|
||||
List<SysResource> list = sysResourceMapper.getByParentId(sysResource.getParentId());
|
||||
sysResource.setSn(list.size() + 1);
|
||||
Assert.isFalse(this.isExist(sysResource), () -> new BusinessMessage(AuthStatusCode.RESOURCES_CODE_REPEAT.formatDefaultMessage(sysResource.getName()+" "+sysResource.getCode())));
|
||||
this.create(sysResource);
|
||||
} else {
|
||||
this.update(sysResource);
|
||||
}
|
||||
return sysResource.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteResourceByCode(List<String> codeList) {
|
||||
remove(Wrappers.lambdaQuery(SysResource.class)
|
||||
.in(CollectionUtil.isNotEmpty(codeList), SysResource::getCode, codeList));
|
||||
}
|
||||
|
||||
private void checkResouce(SysResource sysResource) {
|
||||
if (StrUtil.isEmpty(sysResource.getId())) {
|
||||
Assert.isFalse(this.isExist(sysResource), () -> new BusinessMessage(AuthStatusCode.RESOURCES_CODE_REPEAT));
|
||||
}
|
||||
// 如果是菜单、那上级也必须是菜单、防止按钮下面配置菜单
|
||||
if (ResouceTypeConstant.MENU.getKey().equals(sysResource.getType())) {
|
||||
SysResource parent = this.getById(sysResource.getParentId());
|
||||
if (parent == null) return;
|
||||
|
||||
Assert.isTrue(ResouceTypeConstant.MENU.getKey().equals(parent.getType()), () -> new BusinessException(AuthStatusCode.RESOUCE_TYPE_CONSTANT_ERROR.formatDefaultMessage(parent.getName())));
|
||||
}
|
||||
|
||||
sysResource.setUrl(StrUtil.isNotEmpty(sysResource.getUrl()) ? sysResource.getUrl().trim() : "");
|
||||
}
|
||||
|
||||
private void saveTreeList(List<SysResourceDTO> sysResourceList, String parentId) {
|
||||
|
||||
for (int i = 0; i < sysResourceList.size(); i++) {
|
||||
SysResourceDTO resource = sysResourceList.get(i);
|
||||
resource.setParentId(parentId);
|
||||
resource.setSn(i + 1);
|
||||
Assert.isFalse(this.isExist(resource), () -> new BusinessMessage(AuthStatusCode.RESOURCES_CODE_REPEAT.formatDefaultMessage(resource.getName()+" "+resource.getCode())));
|
||||
this.createOrUpdate(resource);
|
||||
if (CollUtil.isNotEmpty(resource.getChildren())) {
|
||||
saveTreeList(resource.getChildren(), resource.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package com.dstz.auth.core.mapper;
|
||||
|
||||
import com.dstz.auth.core.entity.ResourceRole;
|
||||
import com.dstz.base.mapper.AbBaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 资源角色关联表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author lightning
|
||||
* @since 2022-02-07
|
||||
*/
|
||||
@Mapper
|
||||
public interface ResourceRoleMapper extends AbBaseMapper<ResourceRole> {
|
||||
/**
|
||||
* 根据roleId获取资源关联信息
|
||||
* @param roleId
|
||||
* @return
|
||||
*/
|
||||
List<ResourceRole> getByRoleId(String roleId);
|
||||
|
||||
/**
|
||||
* 根据roleId和appId移除资源关联
|
||||
* @param roleId
|
||||
* @param appId
|
||||
*/
|
||||
void removeByRoleAndSystem(@Param("roleId")String roleId, @Param("appId")String appId);
|
||||
|
||||
/**
|
||||
* 获取资源和角色的映射关系
|
||||
* @return
|
||||
*/
|
||||
List<ResourceRole> getAllResRole();
|
||||
|
||||
/**
|
||||
* 根据资源URL获取角色ID
|
||||
*
|
||||
* @param url 资源URL
|
||||
* @return 角色ID集合
|
||||
*/
|
||||
Set<String> getRoleIdByResourceUrl(String url);
|
||||
|
||||
/**
|
||||
* 根据角色ID查询应用ID集合
|
||||
*
|
||||
* @param roleIds 角色ID
|
||||
* @return 应用ID集合
|
||||
*/
|
||||
Set<String> selectAppIdByRoleIds(@Param("roleIds") Iterable<String> roleIds);
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.dstz.auth.core.mapper;
|
||||
|
||||
import com.dstz.auth.core.entity.SysApplication;
|
||||
import com.dstz.base.mapper.AbBaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 应用 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author lightning
|
||||
* @since 2022-02-07
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysApplicationMapper extends AbBaseMapper<SysApplication> {
|
||||
|
||||
/**
|
||||
* 判断别名是否存在
|
||||
*
|
||||
* @param subsystem
|
||||
* @return
|
||||
*/
|
||||
Integer isExist(SysApplication subsystem);
|
||||
|
||||
/**
|
||||
* 更新为默认。
|
||||
*/
|
||||
void updNoDefault();
|
||||
|
||||
/**
|
||||
* 根据code获取系统
|
||||
* @return
|
||||
*/
|
||||
SysApplication getByAlias(String systemAlias);
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package com.dstz.auth.core.mapper;
|
||||
|
||||
import com.dstz.auth.core.entity.SysResource;
|
||||
import com.dstz.base.mapper.AbBaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 系统权限资源定义 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author lightning
|
||||
* @since 2022-02-07
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysResourceMapper extends AbBaseMapper<SysResource> {
|
||||
/**
|
||||
* 根据子系统ID取定义对象。
|
||||
*
|
||||
* @param appId
|
||||
* @return
|
||||
*/
|
||||
List<SysResource> getBySystemId(@Param("appId")String appId);
|
||||
|
||||
/**
|
||||
* 根据角色和系统id获取资源。
|
||||
*
|
||||
* @param appId
|
||||
* @param roleId
|
||||
* @return
|
||||
*/
|
||||
List<SysResource> getBySystemAndRole(@Param("appId") String appId, @Param("roleId") String roleId);
|
||||
|
||||
/**
|
||||
* 判断资源是否存在。
|
||||
*
|
||||
* @param resource
|
||||
* @return
|
||||
*/
|
||||
Integer isExist(SysResource resource);
|
||||
|
||||
/**
|
||||
* 根据父ID获取下级节点。
|
||||
*
|
||||
* @param parentId
|
||||
* @return
|
||||
*/
|
||||
List<SysResource> getByParentId(String parentId);
|
||||
|
||||
/**
|
||||
* 根据系统id和用户id获取资源列表。
|
||||
*
|
||||
* @param appId 系统id
|
||||
* @param roleIds 角色ID集合
|
||||
* @return 系统资源
|
||||
*/
|
||||
List<SysResource> getByAppIdAndRoleIds(@Param("appId") String appId, @Param("roleIds") Iterable<String> roleIds);
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package com.dstz.auth.rest.controller;
|
||||
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.dstz.auth.authentication.api.constant.AuthStatusCode;
|
||||
import com.dstz.auth.core.entity.ResourceRole;
|
||||
import com.dstz.auth.core.manager.ResourceRoleManager;
|
||||
import com.dstz.auth.core.manager.SysApplicationManager;
|
||||
import com.dstz.auth.core.manager.SysResourceManager;
|
||||
import com.dstz.auth.rest.model.dto.GrantRoleResourceDTO;
|
||||
import com.dstz.auth.rest.model.vo.SysResourceTreeVO;
|
||||
import com.dstz.base.api.vo.ApiResponse;
|
||||
import com.dstz.base.common.constats.AbAppRestConstant;
|
||||
import com.dstz.base.common.exceptions.BusinessMessage;
|
||||
import com.dstz.base.web.controller.AbCrudController;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 资源角色关联表 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author lightning
|
||||
* @since 2022-02-07
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping(AbAppRestConstant.SYS_SERVICE_PREFIX + "/resRole")
|
||||
public class ResourceRoleController extends AbCrudController<ResourceRole> {
|
||||
|
||||
@Autowired
|
||||
ResourceRoleManager resourceRoleManager;
|
||||
|
||||
@Autowired
|
||||
SysResourceManager sysResourceManager;
|
||||
|
||||
@Autowired
|
||||
SysApplicationManager sysApplicationManager;
|
||||
|
||||
@Override
|
||||
protected String getEntityDesc() {
|
||||
return "资源角色关联表";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 角色资源分配明细页面
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
* @throws Exception ModelAndView
|
||||
*/
|
||||
@RequestMapping(value = "getJson", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public ApiResponse<ResourceRole> getJson(@RequestParam("id") String id) throws Exception {
|
||||
if (StrUtil.isEmpty(id)) {
|
||||
throw new BusinessMessage(AuthStatusCode.PARAM_IS_NULL.formatDefaultMessage("id"));
|
||||
}
|
||||
return ApiResponse.success(resourceRoleManager.getById(id));
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping("getTreeData")
|
||||
public ApiResponse<List<SysResourceTreeVO>> getTreeData(@RequestParam("roleId") String roleId, @RequestParam("systemId") String systemId) throws Exception {
|
||||
return ApiResponse.success(resourceRoleManager.getRoleRes(systemId, roleId));
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping("getRoleResTreeData")
|
||||
public ApiResponse<List<SysResourceTreeVO>> getRoleResTreeData(@RequestParam("roleId") String roleId, @RequestParam("code") String code) throws Exception {
|
||||
return ApiResponse.success(resourceRoleManager.getRoleResTreeData(roleId, code));
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色资源分配
|
||||
*
|
||||
* @param dto 分配数据对象
|
||||
* @return 接口处理结果
|
||||
*/
|
||||
@RequestMapping(value = "grantRoleResource")
|
||||
public ApiResponse<Void> grantRoleResource(@Valid @RequestBody GrantRoleResourceDTO dto) {
|
||||
resourceRoleManager.grantRoleResource(dto);
|
||||
return ApiResponse.success();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
package com.dstz.auth.rest.controller;
|
||||
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.dstz.auth.authentication.api.constant.AuthCacheKeyConstant;
|
||||
import com.dstz.auth.authentication.api.constant.AuthStatusCode;
|
||||
import com.dstz.auth.core.entity.SysApplication;
|
||||
import com.dstz.auth.core.manager.SysApplicationManager;
|
||||
import com.dstz.auth.core.mapper.SysApplicationMapper;
|
||||
import com.dstz.base.api.dto.QueryParamDTO;
|
||||
import com.dstz.base.api.vo.ApiResponse;
|
||||
import com.dstz.base.common.cache.ICache;
|
||||
import com.dstz.base.common.constats.AbAppRestConstant;
|
||||
import com.dstz.base.common.exceptions.BusinessMessage;
|
||||
import com.dstz.base.web.controller.AbCrudController;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.util.List;
|
||||
|
||||
import static com.dstz.base.api.vo.ApiResponse.success;
|
||||
|
||||
/**
|
||||
* 系统应用 前端控制器
|
||||
*
|
||||
* @author lightning
|
||||
* @since 2022-02-07
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping(AbAppRestConstant.SYS_SERVICE_PREFIX + "/application")
|
||||
public class SysApplicationController extends AbCrudController<SysApplication> {
|
||||
|
||||
|
||||
@Autowired
|
||||
SysApplicationManager sysApplicationManager;
|
||||
|
||||
@Autowired
|
||||
SysApplicationMapper sysApplicationMapper;
|
||||
|
||||
@Autowired
|
||||
ICache iCache;
|
||||
|
||||
|
||||
@Override
|
||||
protected String getEntityDesc() {
|
||||
return "应用";
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询按时间排序
|
||||
*
|
||||
* @param queryParamDto 查询条件
|
||||
* @return 查询结果
|
||||
*/
|
||||
@Override
|
||||
@RequestMapping(value = "listJson")
|
||||
public ApiResponse<?> listJson(@Valid @RequestBody QueryParamDTO queryParamDto) {
|
||||
queryParamDto.setSortColumn("createTime");
|
||||
queryParamDto.setSortOrder("desc");
|
||||
return super.listJson(queryParamDto);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 移动端并且启用的应用列表
|
||||
*
|
||||
* @return 查询结果
|
||||
*/
|
||||
@GetMapping(value = "mobileApplication")
|
||||
public ApiResponse<List<SysApplication>> mobileApplication() {
|
||||
return success(sysApplicationManager.selectByWrapper(Wrappers.lambdaQuery(SysApplication.class)
|
||||
.eq(SysApplication::getEnabled, 1)
|
||||
.eq(SysApplication::getAppType, 1)));
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value = "getUserSystem", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public ApiResponse<List> getUserSystem() {
|
||||
return success(sysApplicationMapper.selectList(new QueryWrapper<>()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 子系统定义明细页面(查询指定ID)
|
||||
*
|
||||
* @param id
|
||||
* @return SysApplication
|
||||
* @throws Exception ModelAndView
|
||||
*/
|
||||
@RequestMapping("getJson")
|
||||
public ApiResponse<SysApplication> getJson(@NotBlank(message = "id不能为空") @RequestParam("id") String id) {
|
||||
SysApplication subsystem = sysApplicationMapper.selectById(id);
|
||||
return success(subsystem);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sysApplication
|
||||
* @return 保存子系统定义信息
|
||||
* @throws Exception void
|
||||
* @throws
|
||||
*/
|
||||
@RequestMapping("save")
|
||||
@Override
|
||||
public ApiResponse<String> save(@RequestBody SysApplication sysApplication) {
|
||||
String resultMsg = null;
|
||||
Assert.isFalse(sysApplicationManager.isExist(sysApplication), () -> new BusinessMessage(AuthStatusCode.RESOURCES_CODE_REPEAT.formatDefaultMessage(sysApplication.getCode())));
|
||||
|
||||
if (StrUtil.isEmpty(sysApplication.getId())) {
|
||||
sysApplicationMapper.insert(sysApplication);
|
||||
resultMsg = "添加子系统定义成功";
|
||||
} else {
|
||||
sysApplicationManager.updateById(sysApplication);
|
||||
resultMsg = "更新子系统定义成功";
|
||||
}
|
||||
iCache.invalidate(AuthCacheKeyConstant.CACHE_REGION_AUTH_CLIENT, AuthCacheKeyConstant.AUTH_APP_LIST_EL);
|
||||
return success(resultMsg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
package com.dstz.auth.rest.controller;
|
||||
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.dstz.auth.authentication.api.constant.AuthStatusCode;
|
||||
import com.dstz.auth.core.entity.SysApplication;
|
||||
import com.dstz.auth.core.entity.SysResource;
|
||||
import com.dstz.auth.core.manager.SysApplicationManager;
|
||||
import com.dstz.auth.core.manager.SysResourceManager;
|
||||
import com.dstz.auth.rest.model.dto.SysResourceDTO;
|
||||
import com.dstz.auth.rest.model.vo.SysResourceTreeVO;
|
||||
import com.dstz.auth.rest.model.vo.SysResourceVO;
|
||||
import com.dstz.base.api.vo.ApiResponse;
|
||||
import com.dstz.base.common.constats.AbAppRestConstant;
|
||||
import com.dstz.base.common.constats.NumberPool;
|
||||
import com.dstz.base.common.exceptions.BusinessMessage;
|
||||
import com.dstz.base.web.controller.AbCrudController;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.dstz.auth.authentication.api.constant.AuthStatusCode.PARAM_IS_NULL;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 系统权限资源定义 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author lightning
|
||||
* @since 2022-02-07
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping(AbAppRestConstant.SYS_SERVICE_PREFIX + "/resource")
|
||||
public class SysResourceController extends AbCrudController<SysResource> {
|
||||
|
||||
@Autowired
|
||||
SysResourceManager sysResourceManager;
|
||||
@Autowired
|
||||
SysApplicationManager sysApplicationManager;
|
||||
|
||||
|
||||
@Override
|
||||
protected String getEntityDesc() {
|
||||
return "系统权限资源定义";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 资源明细页面
|
||||
*
|
||||
* @param id
|
||||
* @param parentId
|
||||
* @param systemId
|
||||
* @return
|
||||
* @throws Exception ModelAndView
|
||||
*/
|
||||
@RequestMapping("getJson")
|
||||
public ApiResponse<SysResourceVO> getJson(@RequestParam(value = "id", required = false) String id,
|
||||
@RequestParam(value = "parentId", required = false) String parentId,
|
||||
@RequestParam(value = "systemId", required = false) String systemId) {
|
||||
return ApiResponse.success(sysResourceManager.getResourceDetailById(id, parentId, systemId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存子系统资源信息
|
||||
*
|
||||
* @param sysResource @throws Exception void @throws
|
||||
*/
|
||||
@Override
|
||||
@RequestMapping("save")
|
||||
public ApiResponse<String> save(@RequestBody SysResource sysResource) {
|
||||
return ApiResponse.success(sysResourceManager.saveSysResource(sysResource));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 批量删除子系统资源记录
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
@Override
|
||||
@RequestMapping("remove")
|
||||
public ApiResponse remove(@RequestParam("id") String id) {
|
||||
|
||||
try {
|
||||
sysResourceManager.removeByResId(id);
|
||||
return ApiResponse.success("删除子系统资源成功");
|
||||
} catch (Exception e) {
|
||||
throw new BusinessMessage(AuthStatusCode.DELETE_RESOURCES_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping("sysResourceGet")
|
||||
public ApiResponse<SysResource> sysResourceGet(@RequestParam("id") String id) {
|
||||
SysResource sysResource = sysResourceManager.getById(id);
|
||||
return ApiResponse.success(sysResource);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过应用id获取资源树
|
||||
*
|
||||
* @param systemId 应用ID
|
||||
* @return 资源树对象
|
||||
*/
|
||||
@RequestMapping("getTreeData")
|
||||
public ApiResponse<List<SysResourceTreeVO>> getTreeData(@RequestParam("systemId") String systemId) {
|
||||
Assert.notEmpty(systemId, () -> new BusinessMessage(PARAM_IS_NULL.formatDefaultMessage(" systemId ")));
|
||||
return ApiResponse.success(sysApplicationManager.getTreeDataByApplication(sysApplicationManager.getById(systemId)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过应用code获取资源树
|
||||
*
|
||||
* @param systemCode 应用编码
|
||||
* @return 资源树对象
|
||||
*/
|
||||
@RequestMapping("getTreeDataByCode")
|
||||
public ApiResponse<List<SysResourceTreeVO>> getTreeDataByCode(@RequestParam("systemCode") String systemCode) {
|
||||
Assert.notEmpty(systemCode, () -> new BusinessMessage(PARAM_IS_NULL.formatDefaultMessage(" systemCode ")));
|
||||
SysApplication sysApplication = sysApplicationManager.selectOne(Wrappers.lambdaQuery(SysApplication.class)
|
||||
.eq(SysApplication::getCode, systemCode));
|
||||
return ApiResponse.success(sysApplicationManager.getTreeDataByApplication(sysApplication));
|
||||
}
|
||||
|
||||
@RequestMapping("getUserResource")
|
||||
public ApiResponse getUserResource(@RequestParam("userId") String userId, @RequestParam("systemId") String appId) {
|
||||
|
||||
|
||||
Map<String, Object> mapParam = new HashMap<>(16);
|
||||
if (StrUtil.isEmpty(appId)) {
|
||||
List<SysApplication> subsystemList = sysApplicationManager.getSystemByUser(userId);
|
||||
Assert.notNull(subsystemList, () -> new BusinessMessage(AuthStatusCode.USER_HAS_NOT_ASSIGNED_ANY_RESOURCES));
|
||||
appId = subsystemList.get(0).getId();
|
||||
mapParam.put("subsystemList", subsystemList);
|
||||
}
|
||||
|
||||
List<SysResource> groupList = sysResourceManager.getByAppIdAndUserId(appId, userId);
|
||||
SysResource rootResource = new SysResource();
|
||||
rootResource.setName("菜单资源");
|
||||
rootResource.setId(NumberPool.INTEGER_ZERO.toString());
|
||||
rootResource.setAppId(appId); // 根节点
|
||||
groupList.add(rootResource);
|
||||
mapParam.put("groupList", groupList);
|
||||
return ApiResponse.success(mapParam);
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value = "saveTree", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public ApiResponse<String> saveTree(@RequestBody SysResourceDTO sysResource) {
|
||||
sysResourceManager.saveTree(sysResource);
|
||||
return ApiResponse.success("操作成功");
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
package com.dstz.auth.rest.controller;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.dstz.auth.authentication.api.constant.AuthStatusCode;
|
||||
import com.dstz.auth.authentication.api.constant.ResouceTypeConstant;
|
||||
import com.dstz.auth.authentication.api.model.ISysApplication;
|
||||
import com.dstz.auth.core.entity.SysApplication;
|
||||
import com.dstz.auth.core.entity.SysResource;
|
||||
import com.dstz.auth.core.manager.SysApplicationManager;
|
||||
import com.dstz.auth.core.manager.SysResourceManager;
|
||||
import com.dstz.auth.rest.model.vo.SysResourceTreeVO;
|
||||
import com.dstz.base.api.vo.ApiResponse;
|
||||
import com.dstz.base.common.constats.AbAppRestConstant;
|
||||
import com.dstz.base.common.constats.NumberPool;
|
||||
import com.dstz.base.common.constats.StrPool;
|
||||
import com.dstz.base.common.enums.GlobalApiCodes;
|
||||
import com.dstz.base.common.exceptions.BusinessException;
|
||||
import com.dstz.base.common.exceptions.BusinessMessage;
|
||||
import com.dstz.base.common.utils.BeanConversionUtils;
|
||||
import com.dstz.base.common.utils.BeanCopierUtils;
|
||||
import com.dstz.base.common.utils.UserContextUtils;
|
||||
import com.dstz.org.api.GroupApi;
|
||||
import com.dstz.org.api.enums.GroupType;
|
||||
import com.dstz.org.api.model.IGroup;
|
||||
import com.dstz.org.api.model.IUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 用户资源
|
||||
*
|
||||
* @author lightning
|
||||
* @since 2022-02-07
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping(AbAppRestConstant.SYS_SERVICE_PREFIX + "/userResource")
|
||||
public class UserResourceController {
|
||||
|
||||
@Autowired
|
||||
private SysResourceManager sysResourceManager;
|
||||
|
||||
@Autowired
|
||||
private GroupApi groupApi;
|
||||
|
||||
@Autowired
|
||||
private SysApplicationManager sysApplicationManager;
|
||||
|
||||
@RequestMapping(value = "/userMsg", method = {RequestMethod.POST, RequestMethod.GET})
|
||||
public ApiResponse<?> userMsg() {
|
||||
return userMsg(false);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/appUserMsg", method = {RequestMethod.POST, RequestMethod.GET})
|
||||
public ApiResponse<?> appUserMsg() {
|
||||
return userMsg(true);
|
||||
}
|
||||
|
||||
private ApiResponse<?> userMsg(boolean isMobile) {
|
||||
final IUser currentUser = UserContextUtils.getUser().orElseThrow(() -> new BusinessException(GlobalApiCodes.LOGIN_INVALID));
|
||||
|
||||
//获取当前用户可用的应用列表
|
||||
List<SysApplication> sysApplications;
|
||||
|
||||
// 筛选出不同端的应用列表
|
||||
if (isMobile) {
|
||||
sysApplications = CollUtil.filter(sysApplicationManager.getCurrentUserSystem(), item -> NumberPool.INTEGER_ONE.equals(item.getAppType()));
|
||||
} else {
|
||||
sysApplications = CollUtil.filter(sysApplicationManager.getCurrentUserSystem(), item -> !NumberPool.INTEGER_ONE.equals(item.getAppType()));
|
||||
}
|
||||
|
||||
if (CollectionUtil.isEmpty(sysApplications)) {
|
||||
throw new BusinessMessage(AuthStatusCode.USER_HAS_NOT_ASSIGNED_ANY_RESOURCES);
|
||||
}
|
||||
|
||||
ISysApplication currentApplication = getCurrentUserApp(isMobile, currentUser , sysApplications);
|
||||
|
||||
|
||||
Map<String, Object> map = MapUtil.newHashMap();
|
||||
map.put("currentEnviroment", SpringUtil.getActiveProfile());
|
||||
map.put("subsystemList", sysApplications);
|
||||
map.put("currentSystem", currentApplication.getCode());
|
||||
map.put("username", currentUser.getFullName());
|
||||
map.put("currentOrg", UserContextUtils.getGroup().orElse(null));
|
||||
map.put("orgList", groupApi.getByGroupTypeAndUserId(GroupType.ORG.getType(), currentUser.getUserId()));
|
||||
map.put("user", userModel(currentUser));
|
||||
map.put("pwdIsexpire", getUserPwdIsExpired());
|
||||
|
||||
getSysResource(map, currentApplication.getId(), currentUser.getUserId());
|
||||
|
||||
return ApiResponse.success(map);
|
||||
}
|
||||
|
||||
|
||||
private ISysApplication getCurrentUserApp(boolean isMobile, IUser currentUser, List<SysApplication> sysApplications) {
|
||||
// TODO 取切换后的应用名称
|
||||
return sysApplications.stream()
|
||||
.filter(sysApplication -> NumberPool.BOOLEAN_TRUE.equals(sysApplication.getIsDefault()))
|
||||
.findFirst()
|
||||
.orElseGet(() -> CollUtil.getFirst(sysApplications));
|
||||
}
|
||||
|
||||
private Map<String, Object> userModel(IUser user) {
|
||||
Map<String, Object> userModel = BeanCopierUtils.transformMap(user, IUser.class);
|
||||
// 签名
|
||||
userModel.put("signature", user.getAttrValue("signature", String.class));
|
||||
// 头像
|
||||
userModel.put("photo", user.getAttrValue("photo", String.class));
|
||||
return userModel;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <12 只是12毫秒 ,用户到期时间小于 当前时间 则视为需要重置密码
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
private Boolean getUserPwdIsExpired() {
|
||||
Optional<IUser> user = UserContextUtils.getUserContext().getUser();
|
||||
Date expireDate = user.map(o -> o.getAttrValue(IUser.ATTR_EXPIRE_DATE, Date.class)).orElse(null);
|
||||
return expireDate != null && expireDate.getTime() - System.currentTimeMillis() > 0;
|
||||
}
|
||||
|
||||
private void getSysResource(Map<String, Object> map, String appId, String userId) {
|
||||
List<SysResource> sysResourceList;
|
||||
if (UserContextUtils.isSuperAdmin()) {
|
||||
sysResourceList = sysResourceManager.getBySystemId(appId);
|
||||
} else {
|
||||
sysResourceList = sysResourceManager.getByAppIdAndUserId(appId, userId);
|
||||
}
|
||||
// 菜单和按钮分离
|
||||
List<SysResourceTreeVO> menuList = new ArrayList<>();
|
||||
Map<String, Boolean> buttonPermission = MapUtil.newHashMap();
|
||||
List<SysResourceTreeVO> sysResources = BeanCopierUtils.transformList(sysResourceList, SysResourceTreeVO.class);
|
||||
for (SysResourceTreeVO sysResource : sysResources) {
|
||||
if (ResouceTypeConstant.MENU.getKey().equals(sysResource.getType())) {
|
||||
menuList.add(sysResource);
|
||||
} else {
|
||||
buttonPermission.put(sysResource.getCode(), NumberPool.INTEGER_ONE.equals(sysResource.getEnable()));
|
||||
}
|
||||
}
|
||||
map.put("userMenuList", BeanConversionUtils.listToTree(menuList));
|
||||
map.put("buttonPermission", buttonPermission);
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换应用
|
||||
*
|
||||
* @param appCode 应用编码
|
||||
* @return 接口响应
|
||||
*/
|
||||
@RequestMapping(value = "/switchApp/{appCode}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public ApiResponse<?> switchApp(@PathVariable("appCode") String appCode, @RequestParam(value = "isMobile", defaultValue = "false", required = false) boolean isMobile) {
|
||||
SysApplication sysApplication = CollUtil.findOne(sysApplicationManager.getCurrentUserSystem(), item -> StrUtil.equalsIgnoreCase(appCode, item.getCode()));
|
||||
Assert.notNull(sysApplication, () -> new BusinessMessage(AuthStatusCode.APPLICATION_NO_PERMISSIONS.formatDefaultMessage(appCode)));
|
||||
List<SysResource> sysResourceList;
|
||||
if (UserContextUtils.isSuperAdmin()) {
|
||||
sysResourceList = sysResourceManager.getBySystemId(sysApplication.getId());
|
||||
} else {
|
||||
sysResourceList = sysResourceManager.getByAppIdAndUserId(sysApplication.getId(), UserContextUtils.getUserId());
|
||||
}
|
||||
List<SysResourceTreeVO> menuList = new ArrayList<>();
|
||||
List<SysResourceTreeVO> sysResources = BeanCopierUtils.transformList(sysResourceList, SysResourceTreeVO.class);
|
||||
for (SysResourceTreeVO sysResource : sysResources) {
|
||||
if (ResouceTypeConstant.MENU.getKey().equals(sysResource.getType()) && sysResource.getEnable().equals(NumberPool.INTEGER_ONE)) {
|
||||
menuList.add(sysResource);
|
||||
}
|
||||
}
|
||||
if (menuList.size() == NumberPool.INTEGER_ZERO) {
|
||||
return AuthStatusCode.APP_NO_RESOURCE.formatDefaultMessage(sysApplication.getName()).buildApiResponse();
|
||||
}
|
||||
// 打开方式为0(跳转),需检查是否有菜单资源
|
||||
if (StrPool.NUMBER_ZERO.equals(sysApplication.getOpenType())) {
|
||||
if (sysResourceManager.selectCount(Wrappers.lambdaQuery(SysResource.class).eq(SysResource::getAppId, sysApplication.getId())) <= NumberPool.INTEGER_ZERO) {
|
||||
return AuthStatusCode.APP_NO_RESOURCE.formatDefaultMessage(sysApplication.getName()).buildApiResponse();
|
||||
}
|
||||
}
|
||||
// TODO 切换应用实现
|
||||
return ApiResponse.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换组织
|
||||
*
|
||||
* @param orgCode 组织编码
|
||||
* @return 接口响应
|
||||
*/
|
||||
@RequestMapping(value = "/switchOrg/{orgCode}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public ApiResponse<Void> switchOrg(@PathVariable("orgCode") String orgCode) {
|
||||
final IUser currentUser = UserContextUtils.getValidUser();
|
||||
List<? extends IGroup> orgList = groupApi.getByGroupTypeAndUserId(GroupType.ORG.getType(), currentUser.getUserId());
|
||||
if (CollUtil.isEmpty(orgList)) {
|
||||
return AuthStatusCode.USER_UNABSORBED_ORG.buildApiResponse();
|
||||
}
|
||||
IGroup org = CollUtil.findOne(orgList, filterItem -> StrUtil.equals(filterItem.getGroupCode(), orgCode));
|
||||
if (org == null) {
|
||||
return AuthStatusCode.ILLEGAL_CURRENT_ORG.formatDefaultMessage(orgCode).buildApiResponse();
|
||||
}
|
||||
// TODO 切换组织实现
|
||||
return ApiResponse.success();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package com.dstz.auth.rest.model.dto;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 角色资源分配
|
||||
*
|
||||
* @author wacxhs
|
||||
*/
|
||||
public class GrantRoleResourceDTO {
|
||||
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
@NotEmpty(message = "角色ID不能为空")
|
||||
private String roleId;
|
||||
|
||||
/**
|
||||
* 应用ID
|
||||
*/
|
||||
@NotEmpty(message = "应用ID不能为空")
|
||||
private String appId;
|
||||
|
||||
/**
|
||||
* 资源ID
|
||||
*/
|
||||
private Set<String> resIds;
|
||||
|
||||
/**
|
||||
* 半选中资源
|
||||
*/
|
||||
private Set<String> halfResIds;
|
||||
|
||||
public String getRoleId() {
|
||||
return roleId;
|
||||
}
|
||||
|
||||
public void setRoleId(String roleId) {
|
||||
this.roleId = roleId;
|
||||
}
|
||||
|
||||
public String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
public Set<String> getResIds() {
|
||||
return resIds;
|
||||
}
|
||||
|
||||
public void setResIds(Set<String> resIds) {
|
||||
this.resIds = resIds;
|
||||
}
|
||||
|
||||
public Set<String> getHalfResIds() {
|
||||
return halfResIds;
|
||||
}
|
||||
|
||||
public void setHalfResIds(Set<String> halfResIds) {
|
||||
this.halfResIds = halfResIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GrantRoleResourceDTO{" +
|
||||
"roleId='" + roleId + '\'' +
|
||||
", appId='" + appId + '\'' +
|
||||
", resIds=" + resIds +
|
||||
", halfResIds=" + halfResIds +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.dstz.auth.rest.model.dto;
|
||||
|
||||
import com.dstz.auth.core.entity.SysResource;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SysResourceDTO extends SysResource {
|
||||
private List<SysResourceDTO> children ;
|
||||
|
||||
public List<SysResourceDTO> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<SysResourceDTO> children) {
|
||||
this.children = children;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
package com.dstz.auth.rest.model.vo;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.dstz.auth.authentication.api.model.ISysResource;
|
||||
import com.dstz.auth.core.entity.SysResource;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
public class SysResourceTreeVO extends SysResource implements ISysResource, Serializable {
|
||||
|
||||
|
||||
/**
|
||||
* 是否已分配给角色
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
protected boolean checked = false;
|
||||
|
||||
|
||||
private List<SysResource> children;
|
||||
|
||||
@Override
|
||||
public List<SysResource> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChildren(List children) {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
|
||||
public boolean isChecked() {
|
||||
return checked;
|
||||
}
|
||||
|
||||
public void setChecked(boolean checked) {
|
||||
this.checked = checked;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return super.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAppId() {
|
||||
return super.getAppId();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
return super.getCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return super.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return super.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl() {
|
||||
return super.getUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getEnable() {
|
||||
return super.getEnable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getOpened() {
|
||||
return super.getOpened();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIsApi() {
|
||||
return super.getIsApi();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIcon() {
|
||||
return super.getIcon();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return super.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getSn() {
|
||||
return super.getSn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParentId() {
|
||||
return super.getParentId();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Boolean getHidden() {
|
||||
if (this.getEnable() == null) return false;
|
||||
|
||||
return this.getEnable() == 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.dstz.auth.rest.model.vo;
|
||||
|
||||
import com.dstz.auth.authentication.api.model.ISysResource;
|
||||
import com.dstz.auth.core.entity.SysResource;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
public class SysResourceVO extends SysResource implements ISysResource, Serializable {
|
||||
private List<SysResource> children;
|
||||
|
||||
private String parentName;
|
||||
|
||||
protected boolean checked = false;
|
||||
|
||||
public boolean isChecked() {
|
||||
return checked;
|
||||
}
|
||||
|
||||
public void setChecked(boolean checked) {
|
||||
this.checked = checked;
|
||||
}
|
||||
|
||||
public String getParentName() {
|
||||
return parentName;
|
||||
}
|
||||
|
||||
public void setParentName(String parentName) {
|
||||
this.parentName = parentName;
|
||||
}
|
||||
|
||||
public List<SysResource> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChildren(List list) {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Boolean getHidden() {
|
||||
if (this.getEnable() == null) return false;
|
||||
|
||||
return this.getEnable() == 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.dstz.auth.core.mapper.ResourceRoleMapper">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="ResourceRole" type="com.dstz.auth.core.entity.ResourceRole">
|
||||
<id column="id_" property="id" />
|
||||
<result column="app_id_" property="appId" />
|
||||
<result column="resource_id_" property="resourceId" />
|
||||
<result column="role_id_" property="roleId" />
|
||||
<result column="create_time_" property="createTime" />
|
||||
<result column="create_by_" property="createBy" />
|
||||
</resultMap>
|
||||
|
||||
<select id="query" parameterType="java.util.Map" resultMap="ResourceRole">
|
||||
SELECT id_, app_id_, resource_id_, role_id_, create_time_, create_by_ FROM sys_resource_role
|
||||
<where>
|
||||
<if test="whereSql!=null">
|
||||
${whereSql}
|
||||
</if>
|
||||
</where>
|
||||
<if test="orderBySql!=null">
|
||||
ORDER BY ${orderBySql}
|
||||
</if>
|
||||
<if test="orderBySql==null">
|
||||
ORDER BY id_ DESC
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<delete id="removeByRoleAndSystem" parameterType="java.util.Map">
|
||||
DELETE FROM sys_resource_role
|
||||
WHERE
|
||||
role_id_=#{roleId}
|
||||
AND
|
||||
app_id_=#{appId}
|
||||
</delete>
|
||||
|
||||
<select id="getAllResRole" parameterType="java.lang.String" resultType="com.dstz.auth.core.entity.ResourceRole">
|
||||
select b.*, a.code_ resAlias,c.code_ roleAlias,a.url_ url
|
||||
from sys_resource a
|
||||
left join sys_resource_role b on a.id_= b.resource_id_
|
||||
left join org_role c on b.role_id_= c.id_
|
||||
where c.enabled_=1 and a.enable_=1
|
||||
|
||||
</select>
|
||||
|
||||
<select id="getRoleIdByResourceUrl" parameterType="string" resultType="string">
|
||||
SELECT DISTINCT b.role_id_
|
||||
FROM sys_resource a
|
||||
INNER JOIN sys_resource_role b ON b.resource_id_ = a.id_
|
||||
WHERE a.url_ = #{url,jdbcType=VARCHAR} AND a.enable_ = 1
|
||||
</select>
|
||||
|
||||
<select id="selectAppIdByRoleIds" resultType="string">
|
||||
SELECT
|
||||
DISTINCT a.app_id_
|
||||
FROM sys_resource a
|
||||
INNER JOIN sys_resource_role b ON b.resource_id_ = a.id_
|
||||
WHERE b.role_id_ IN <foreach collection="roleIds" open="(" item="roleId" close=")" separator=",">#{roleId,jdbcType=VARCHAR}</foreach>
|
||||
</select>
|
||||
</mapper>
|
|
@ -0,0 +1,69 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.dstz.auth.core.mapper.SysApplicationMapper">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="SysApplication" type="com.dstz.auth.core.entity.SysApplication">
|
||||
<id column="id_" property="id"/>
|
||||
<result column="name_" property="name"/>
|
||||
<result column="code_" property="code"/>
|
||||
<result column="secret_" property="secret"/>
|
||||
<result column="resource_ids_" property="resourceIds"/>
|
||||
<result column="scope_" property="scope"/>
|
||||
<result column="refresh_token_validity_" property="refreshTokenValidity"/>
|
||||
<result column="access_token_validity_" property="accessTokenValidity"/>
|
||||
<result column="grant_types_" property="grantTypes"/>
|
||||
<result column="autoapprove_" property="autoapprove"/>
|
||||
<result column="authorities_" property="authorities"/>
|
||||
<result column="url_" property="url"/>
|
||||
<result column="redirect_uri_" property="redirectUri"/>
|
||||
<result column="open_type_" property="openType"/>
|
||||
<result column="enabled_" property="enabled"/>
|
||||
<result column="is_default_" property="isDefault"/>
|
||||
<result column="desc_" property="desc"/>
|
||||
<result column="config_" property="config"/>
|
||||
<result column="create_time_" property="createTime"/>
|
||||
<result column="create_by_" property="createBy"/>
|
||||
<result column="create_org_id_" property="createOrgId"/>
|
||||
<result column="update_time_" property="updateTime"/>
|
||||
<result column="update_by_" property="updateBy"/>
|
||||
<result column="updater_" property="updater"/>
|
||||
<result column="app_type_" property="appType"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="query" parameterType="java.util.Map" resultMap="SysApplication">
|
||||
SELECT id_, name_, code_, secret_, refresh_token_validity_, access_token_validity_, url_, redirect_uri_,
|
||||
open_type_, enabled_, is_default_, desc_, config_, create_time_, create_by_, create_org_id_, update_time_,
|
||||
updater_, update_by_,resource_ids_ ,scope_,grant_types_,autoapprove_,authorities_ ,app_type_ FROM sys_application
|
||||
<where>
|
||||
<if test="whereSql!=null">
|
||||
${whereSql}
|
||||
</if>
|
||||
</where>
|
||||
<if test="orderBySql!=null">
|
||||
ORDER BY ${orderBySql}
|
||||
</if>
|
||||
<if test="orderBySql==null">
|
||||
ORDER BY id_ DESC
|
||||
</if>
|
||||
</select>
|
||||
|
||||
|
||||
<update id="updNoDefault" parameterType="com.dstz.auth.core.entity.SysApplication">
|
||||
UPDATE sys_application SET is_default_=0
|
||||
</update>
|
||||
|
||||
|
||||
<select id="isExist" resultType="java.lang.Integer" parameterType="com.dstz.auth.core.entity.SysApplication">
|
||||
SELECT count(1) FROM sys_application WHERE code_=#{code}
|
||||
<if test="id!=null">
|
||||
and ID_!=#{id}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getByAlias" parameterType="java.lang.String" resultMap="SysApplication">
|
||||
SELECT * FROM sys_application
|
||||
WHERE
|
||||
code_=#{code}
|
||||
</select>
|
||||
</mapper>
|
|
@ -0,0 +1,86 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.dstz.auth.core.mapper.SysResourceMapper">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="SysResource" type="com.dstz.auth.core.entity.SysResource">
|
||||
<id column="id_" property="id"/>
|
||||
<result column="app_id_" property="appId"/>
|
||||
<result column="code_" property="code"/>
|
||||
<result column="name_" property="name"/>
|
||||
<result column="url_" property="url"/>
|
||||
<result column="enable_" property="enable"/>
|
||||
<result column="opened_" property="opened"/>
|
||||
<result column="is_api_" property="isApi"/>
|
||||
<result column="icon_" property="icon"/>
|
||||
<result column="type_" property="type"/>
|
||||
<result column="sn_" property="sn"/>
|
||||
<result column="parent_id_" property="parentId"/>
|
||||
<result column="path_" property="path"/>
|
||||
<result column="create_time_" property="createTime"/>
|
||||
<result column="create_by_" property="createBy"/>
|
||||
<result column="create_org_id_" property="createOrgId"/>
|
||||
<result column="update_time_" property="updateTime"/>
|
||||
<result column="updater_" property="updater"/>
|
||||
<result column="update_by_" property="updateBy"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="query" parameterType="java.util.Map" resultMap="SysResource">
|
||||
SELECT id_, app_id_, code_, name_, url_, enable_, opened_, is_api_, icon_, type_, sn_, parent_id_, path_,
|
||||
create_time_, create_by_, create_org_id_, update_time_, updater_, update_by_ FROM sys_resource
|
||||
<where>
|
||||
<if test="whereSql!=null">
|
||||
${whereSql}
|
||||
</if>
|
||||
</where>
|
||||
<if test="orderBySql!=null">
|
||||
ORDER BY ${orderBySql}
|
||||
</if>
|
||||
<if test="orderBySql==null">
|
||||
ORDER BY id_ DESC
|
||||
</if>
|
||||
</select>
|
||||
|
||||
|
||||
<select id="getBySystemId" parameterType="java.lang.String" resultMap="SysResource">
|
||||
SELECT * FROM sys_resource WHERE app_id_=#{appId} order by sn_ asc, id_ asc
|
||||
</select>
|
||||
|
||||
<select id="getBySystemAndRole" parameterType="java.util.Map" resultMap="SysResource">
|
||||
SELECT a.* FROM sys_resource a, sys_resource_role b
|
||||
WHERE a.id_=b.resource_id_ AND b.ROLE_id_=#{roleId} AND b.app_id_=#{appId} AND b.half_checked_ = 0
|
||||
order by a.sn_ asc, a.id_ asc
|
||||
</select>
|
||||
|
||||
<select id="isExist" resultType="java.lang.Integer">
|
||||
SELECT count(1) FROM sys_resource where code_=#{code} and app_id_=#{appId}
|
||||
<if test="id!=null">
|
||||
and id_!=#{id}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getByParentId" parameterType="java.lang.String" resultMap="SysResource">
|
||||
SELECT * FROM sys_resource WHERE parent_id_=#{parentId}
|
||||
</select>
|
||||
|
||||
<select id="getByAppIdAndRoleIds" resultMap="SysResource">
|
||||
SELECT DISTINCT a.id_,
|
||||
a.app_id_,
|
||||
a.code_,
|
||||
a.name_,
|
||||
a.url_,
|
||||
a.enable_,
|
||||
a.opened_,
|
||||
a.is_api_,
|
||||
a.icon_,
|
||||
a.type_,
|
||||
a.sn_,
|
||||
a.parent_id_,
|
||||
a.path_
|
||||
FROM sys_resource a
|
||||
LEFT JOIN sys_resource_role b ON b.resource_id_ = a.id_
|
||||
WHERE a.app_id_ = #{appId,jdbcType=VARCHAR}
|
||||
AND b.role_id_ IN <foreach collection="roleIds" item="roleId" open="(" separator="," close=")">#{roleId,jdbcType=VARCHAR}</foreach>
|
||||
ORDER BY a.sn_, a.id_
|
||||
</select>
|
||||
</mapper>
|
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>ab-auth</artifactId>
|
||||
<groupId>com.dstz</groupId>
|
||||
<version>2.5.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>ab-auth-spring-security-oauth2</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.dstz</groupId>
|
||||
<artifactId>ab-auth-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.dstz</groupId>
|
||||
<artifactId>ab-sys-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.dstz</groupId>
|
||||
<artifactId>ab-base-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-captcha</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-http</artifactId>
|
||||
<version>${hutool.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.springboot.security</groupId>
|
||||
<artifactId>spring-security-oauth2-authorization-server</artifactId>
|
||||
<version>0.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security.oauth.boot</groupId>
|
||||
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
|
||||
<version>2.1.2.RELEASE</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>jaxb-impl</artifactId>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1,91 @@
|
|||
package com.dstz.auth.api;
|
||||
|
||||
import com.dstz.base.common.utils.CastUtils;
|
||||
import com.dstz.base.web.api.WebSessionAttributesApi;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
|
||||
import org.springframework.security.oauth2.provider.token.TokenStore;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* web 会话属性接口实现
|
||||
*
|
||||
* @author wacxhs
|
||||
*/
|
||||
@Component
|
||||
public class WebSessionAttributesApiImpl implements WebSessionAttributesApi {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(WebSessionAttributesApiImpl.class);
|
||||
|
||||
@Autowired
|
||||
private TokenStore tokenStore;
|
||||
|
||||
@Override
|
||||
public void setValue(String name, Serializable value) {
|
||||
Map<String, Serializable> values = ImmutableMap.of(name, value);
|
||||
setValues(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValues(Map<String, ? extends Serializable> values) {
|
||||
OAuth2Authentication oauth2Authentication = getOauth2Authentication();
|
||||
if (oauth2Authentication == null) {
|
||||
return;
|
||||
}
|
||||
AbstractAuthenticationToken authenticationToken = (AbstractAuthenticationToken) oauth2Authentication.getUserAuthentication();
|
||||
Map<String, Serializable> originDetails = CastUtils.cast(authenticationToken.getDetails());
|
||||
|
||||
Map<String, Serializable> newDetails = new LinkedHashMap<>();
|
||||
if (originDetails != null) {
|
||||
newDetails.putAll(originDetails);
|
||||
}
|
||||
|
||||
// 更新值
|
||||
for (Map.Entry<String, ? extends Serializable> entry : values.entrySet()) {
|
||||
if (entry.getValue() == null) {
|
||||
newDetails.remove(entry.getKey());
|
||||
} else {
|
||||
newDetails.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
authenticationToken.setDetails(newDetails);
|
||||
|
||||
// 存储
|
||||
OAuth2AccessToken accessToken = tokenStore.readAccessToken(((OAuth2AuthenticationDetails)oauth2Authentication.getDetails()).getTokenValue());
|
||||
tokenStore.storeAccessToken(accessToken, oauth2Authentication);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable getValue(String name) {
|
||||
OAuth2Authentication oauth2Authentication = getOauth2Authentication();
|
||||
if (oauth2Authentication == null) {
|
||||
return null;
|
||||
}
|
||||
Object details = oauth2Authentication.getUserAuthentication().getDetails();
|
||||
if (details == null) {
|
||||
return null;
|
||||
}
|
||||
return CastUtils.<Map<String, Serializable>>cast(details).get(name);
|
||||
}
|
||||
|
||||
private OAuth2Authentication getOauth2Authentication() {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
if (!(authentication instanceof OAuth2Authentication)) {
|
||||
logger.info("当前非OAuth2实现,无法切换租户");
|
||||
return null;
|
||||
}
|
||||
return (OAuth2Authentication) authentication;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.dstz.auth.authentication;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
import com.dstz.base.common.utils.AbRequestUtils;
|
||||
import org.springframework.security.oauth2.common.util.OAuth2Utils;
|
||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
import org.springframework.security.oauth2.provider.OAuth2Request;
|
||||
import org.springframework.security.oauth2.provider.token.DefaultAuthenticationKeyGenerator;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 重写token生成
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public class AbAuthenticationTokenGenerator extends DefaultAuthenticationKeyGenerator {
|
||||
|
||||
private static final String SCOPE = "scope";
|
||||
|
||||
private static final String USERNAME = "username";
|
||||
|
||||
private static final String UUID = "uuid";
|
||||
|
||||
@Override
|
||||
public String extractKey(OAuth2Authentication authentication) {
|
||||
Map<String, String> values = new LinkedHashMap<>();
|
||||
OAuth2Request authorizationRequest = authentication.getOAuth2Request();
|
||||
if (!authentication.isClientOnly()) {
|
||||
values.put(USERNAME, authentication.getName());
|
||||
}
|
||||
if (authorizationRequest.getScope() != null) {
|
||||
values.put(SCOPE, OAuth2Utils.formatParameterList(new TreeSet<>(authorizationRequest.getScope())));
|
||||
}
|
||||
// authorizationRequest.getRequestParameters().get("param");
|
||||
values.put(UUID, StrUtil.uuid());
|
||||
return generateKey(values);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package com.dstz.auth.authentication;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.dstz.auth.authentication.api.SysApplicationApi;
|
||||
import com.dstz.auth.authentication.api.constant.AuthStatusCode;
|
||||
import com.dstz.auth.authentication.vo.SysApplicationVO;
|
||||
import com.dstz.auth.exception.Auth2CustomizeExceptionTranslator;
|
||||
import com.dstz.base.common.constats.StrPool;
|
||||
import com.dstz.base.common.exceptions.BusinessException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
|
||||
import org.springframework.security.oauth2.provider.ClientDetails;
|
||||
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
|
||||
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* 客户端信息
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
@Component
|
||||
public class AbClientDetailsServiceImpl extends JdbcClientDetailsService {
|
||||
|
||||
@Autowired
|
||||
private SysApplicationApi sysApplicationApi;
|
||||
|
||||
public AbClientDetailsServiceImpl(DataSource dataSource) {
|
||||
super(dataSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientDetails loadClientByClientId(String clientId) throws InvalidClientException {
|
||||
try {
|
||||
SysApplicationVO sysApplication = sysApplicationApi.getByCode(clientId);
|
||||
Assert.notNull(sysApplication, () -> new BusinessException(AuthStatusCode.NO_FIND_APP.formatDefaultMessage(clientId)));
|
||||
|
||||
BaseClientDetails baseClientDetails = new BaseClientDetails();
|
||||
//客户端clientId
|
||||
baseClientDetails.setClientId(sysApplication.getCode());
|
||||
//客户端秘钥
|
||||
baseClientDetails.setClientSecret("{noop}" + sysApplication.getSecret());
|
||||
// 方法级权限控制 指定客户端申请的权限范围
|
||||
baseClientDetails.setScope(StrUtil.split(sysApplication.getScope(), StrPool.COMMA));
|
||||
//客户端所能访问的资源id集合,多个资源时用逗号(,)分隔 如果没设置,就是所有权限
|
||||
baseClientDetails.setResourceIds(StrUtil.isNotEmpty(sysApplication.getResourceIds()) ? StrUtil.split(sysApplication.getResourceIds(), StrPool.COMMA) : null);
|
||||
//支持的鉴权类型
|
||||
baseClientDetails.setAuthorizedGrantTypes(StrUtil.isNotEmpty(sysApplication.getGrantTypes()) ? StrUtil.split(sysApplication.getGrantTypes(), StrPool.COMMA) : CollUtil.newArrayList());
|
||||
|
||||
//回调地址
|
||||
baseClientDetails.setRegisteredRedirectUri(StrUtil.isNotEmpty(sysApplication.getRedirectUri()) ? CollUtil.newHashSet(StrUtil.split(sysApplication.getRedirectUri(), StrPool.COMMA)) : null);
|
||||
|
||||
//设置用户是否自动Approval操作, 默认值为 'false'该字段只适用于grant_type="authorization_code"的情况,当用户登录成功后,若该值为'true'或支持的scope值,则会跳过用户Approve的页面, 直接授权.
|
||||
baseClientDetails.setAutoApproveScopes(Collections.singletonList(sysApplication.getAutoapprove().toString()));
|
||||
|
||||
//token有效时间
|
||||
baseClientDetails.setAccessTokenValiditySeconds(sysApplication.getAccessTokenValidity());
|
||||
//刷新token有效时间
|
||||
baseClientDetails.setRefreshTokenValiditySeconds(sysApplication.getRefreshTokenValidity());
|
||||
return baseClientDetails;
|
||||
} catch (Exception e) {
|
||||
throw new Auth2CustomizeExceptionTranslator.CustomizeException(AuthStatusCode.LOAD_CLIENT_BY_CLIENTID_ERROR.formatDefaultMessage(e.getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package com.dstz.auth.authentication;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.dstz.auth.authentication.api.MultipleFromAuthentication;
|
||||
import com.dstz.auth.authentication.api.constant.AuthApiConstant;
|
||||
import com.dstz.auth.model.LoginUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 重写根据系统来源登录
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public class AbDaoAuthenticationProvider extends DaoAuthenticationProvider {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Autowired(required = false)
|
||||
private SessionAuthenticationStrategy sessionStrategy;
|
||||
|
||||
|
||||
|
||||
private Map<String, MultipleFromAuthentication> multipleFromAuthenticationBeanMap;
|
||||
|
||||
/**
|
||||
* 将来源转换为小写,在匹配时不区分大小写
|
||||
*
|
||||
* @param from 账户来源
|
||||
* @return 小写字符来源
|
||||
*/
|
||||
private String fromToLowerCase(String from) {
|
||||
return StrUtil.swapCase(from);
|
||||
}
|
||||
|
||||
private MultipleFromAuthentication getMultipleFromAuthenticationImplement(String from) {
|
||||
Map<String, MultipleFromAuthentication> localMap = multipleFromAuthenticationBeanMap;
|
||||
if (localMap == null) {
|
||||
synchronized (this) {
|
||||
localMap = multipleFromAuthenticationBeanMap;
|
||||
if (localMap == null) {
|
||||
Collection<MultipleFromAuthentication> multipleFromAuthenticationBeans = applicationContext.getBeansOfType(MultipleFromAuthentication.class).values();
|
||||
localMap = new HashMap<>(multipleFromAuthenticationBeans.size());
|
||||
for (MultipleFromAuthentication multipleFromAuthenticationBean : multipleFromAuthenticationBeans) {
|
||||
localMap.put(fromToLowerCase(multipleFromAuthenticationBean.getFrom()), multipleFromAuthenticationBean);
|
||||
}
|
||||
multipleFromAuthenticationBeanMap = localMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
return localMap.get(fromToLowerCase(from));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken
|
||||
authentication) {
|
||||
if (!(userDetails instanceof LoginUser)) {
|
||||
super.additionalAuthenticationChecks(userDetails, authentication);
|
||||
} else {
|
||||
LoginUser loginUser = (LoginUser) userDetails;
|
||||
if (StrUtil.isEmpty(loginUser.getFrom()) || AuthApiConstant.SYSTEM.equalsIgnoreCase(loginUser.getFrom())) {
|
||||
super.additionalAuthenticationChecks(userDetails, authentication);
|
||||
} else {
|
||||
multipleFromAuthentication(loginUser, authentication);
|
||||
}
|
||||
}
|
||||
//兼容其它版本未注入
|
||||
if (sessionStrategy != null) {
|
||||
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
sessionStrategy.onAuthentication(new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), null, userDetails.getAuthorities()), requestAttributes.getRequest(), requestAttributes.getResponse());
|
||||
}
|
||||
}
|
||||
|
||||
private void multipleFromAuthentication(LoginUser userDetails, UsernamePasswordAuthenticationToken
|
||||
authentication) {
|
||||
MultipleFromAuthentication multipleFromAuthentication = getMultipleFromAuthenticationImplement(userDetails.getFrom());
|
||||
if (multipleFromAuthentication == null) {
|
||||
super.additionalAuthenticationChecks(userDetails, authentication);
|
||||
} else {
|
||||
multipleFromAuthentication.authentication(userDetails, authentication);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package com.dstz.auth.authentication;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.dstz.auth.authentication.api.SysResourceApi;
|
||||
import com.dstz.auth.constant.PlatformConsts;
|
||||
import com.dstz.base.common.utils.UserContextUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.AccessDecisionManager;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.access.ConfigAttribute;
|
||||
import org.springframework.security.authentication.InsufficientAuthenticationException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.web.FilterInvocation;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 访问决策管理器。 通过当前资源需要角色,判断用户是否有这些角色,若有则通过
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public class AbResourceRoleAuthProvider implements AccessDecisionManager {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Autowired
|
||||
private SysResourceApi sysResourceApi;
|
||||
|
||||
/**
|
||||
* 判断 当前用户所拥有的角色 是否满足 当前资源所需的角色
|
||||
*/
|
||||
@Override
|
||||
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
|
||||
if (configAttributes.contains(PlatformConsts.ROLE_CONFIG_ANONYMOUS)) {
|
||||
return;
|
||||
}
|
||||
if (authentication.isAuthenticated()) {
|
||||
FilterInvocation filterInvocation = (FilterInvocation) object;
|
||||
final String servletPath = filterInvocation.getRequest().getServletPath();
|
||||
|
||||
if (UserContextUtils.isSuperAdmin()) {
|
||||
logger.trace("路径:{}, 当前访问用户为超级管理员, 跳过资源管控", servletPath);
|
||||
return;
|
||||
}
|
||||
|
||||
Set<String> accessRoleByUrl = sysResourceApi.getAccessRoleByUrl(servletPath);
|
||||
if (CollUtil.isEmpty(accessRoleByUrl)) {
|
||||
logger.trace("路径:{}, 未查询到授权角色,当前访问将不做权限校验", servletPath);
|
||||
return;
|
||||
}
|
||||
|
||||
// 遍历当前用户的角色,如果当前页面对应的角色包含当前用户的某个角色则有权限访问。
|
||||
for (GrantedAuthority grantedAuthority : ObjectUtil.<Collection<? extends GrantedAuthority>>defaultIfNull(authentication.getAuthorities(), Collections.emptyList())) {
|
||||
if (accessRoleByUrl.contains(grantedAuthority.getAuthority())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new AccessDeniedException("对不起,您没有该资源访问权限");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean supports(ConfigAttribute attribute) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<?> clazz) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.dstz.auth.authentication;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.dstz.auth.constant.PlatformConsts;
|
||||
import com.dstz.auth.utils.IngoreChecker;
|
||||
import org.springframework.security.access.ConfigAttribute;
|
||||
import org.springframework.security.web.FilterInvocation;
|
||||
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 根据当前的URL获取他上面分配的角色列表
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public class AbResourceRoleRelationProvider extends IngoreChecker implements FilterInvocationSecurityMetadataSource {
|
||||
|
||||
@Override
|
||||
public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
|
||||
FilterInvocation filterInvocation = ((FilterInvocation) object);
|
||||
HttpServletRequest request = filterInvocation.getRequest();
|
||||
// 是否匿名访问
|
||||
if (isIngores(request)) {
|
||||
return CollUtil.newHashSet(PlatformConsts.ROLE_CONFIG_ANONYMOUS);
|
||||
}
|
||||
return CollUtil.newHashSet(PlatformConsts.URL_AUTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ConfigAttribute> getAllConfigAttributes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<?> clazz) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package com.dstz.auth.constant;
|
||||
|
||||
/**
|
||||
* 授权校验常量
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public interface AuthConstant {
|
||||
|
||||
/**
|
||||
* 表字段
|
||||
*/
|
||||
String CLIENT_FIELDS = "client_id_, CONCAT('{noop}',client_secret_) as client_secret_, resource_ids_, scope_, grant_types_, " +
|
||||
"redirect_uri_, authorities_, access_token_validity_, " +
|
||||
"refresh_token_validity_, commentate_, autoapprove_, status_, is_deleted_, create_time_, create_by_, create_org_id_, update_time_,updater_,update_by_";
|
||||
|
||||
/**
|
||||
* 查询语句
|
||||
*/
|
||||
String BASE_STATEMENT = "select " + CLIENT_FIELDS + " from oauth_client";
|
||||
|
||||
/**
|
||||
* 查询排序
|
||||
*/
|
||||
String DEFAULT_FIND_STATEMENT = BASE_STATEMENT + " order by client_id_";
|
||||
|
||||
/**
|
||||
* 查询条件
|
||||
*/
|
||||
String DEFAULT_SELECT_STATEMENT = BASE_STATEMENT + " where client_id_ = ?";
|
||||
|
||||
/**
|
||||
* oauth内置接口集合
|
||||
*/
|
||||
String [] OAUTH_DEFAULT_URL = new String[]{"/oauth/token","/oauth/authorize"};
|
||||
|
||||
/**
|
||||
* oauth grant_type
|
||||
*/
|
||||
String GRANT_TYPE = "grant_type";
|
||||
|
||||
/**
|
||||
* grant_type authorization_code
|
||||
*/
|
||||
String AUTHORIZATION_CODE = "authorization_code";
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.dstz.auth.constant;
|
||||
|
||||
import org.springframework.security.access.ConfigAttribute;
|
||||
import org.springframework.security.access.SecurityConfig;
|
||||
|
||||
/**
|
||||
* 权限类型
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public class PlatformConsts {
|
||||
|
||||
/**
|
||||
* 匿名级
|
||||
*/
|
||||
private static final String ROLE_ANONYMOUS = "ROLE_ANONYMOUS";
|
||||
|
||||
/**
|
||||
* 验证权限
|
||||
*/
|
||||
private final static String ROLE_AUTH = "ROLE_AUTH";
|
||||
|
||||
public static final ConfigAttribute ROLE_CONFIG_ANONYMOUS = new SecurityConfig(ROLE_ANONYMOUS);
|
||||
|
||||
public static final ConfigAttribute URL_AUTH = new SecurityConfig(ROLE_AUTH);
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package com.dstz.auth.exception;
|
||||
|
||||
import com.dstz.auth.authentication.api.constant.AuthStatusCode;
|
||||
import com.dstz.base.api.vo.ApiResponse;
|
||||
import com.dstz.base.common.codes.IBaseCode;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.oauth2.common.DefaultThrowableAnalyzer;
|
||||
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
|
||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
|
||||
import org.springframework.security.web.util.ThrowableAnalyzer;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
/**
|
||||
* 自定义oauth异常
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public class Auth2CustomizeExceptionTranslator implements WebResponseExceptionTranslator {
|
||||
|
||||
private ThrowableAnalyzer throwableAnalyzer = new DefaultThrowableAnalyzer();
|
||||
|
||||
@Override
|
||||
public ResponseEntity translate(Exception e) throws Exception {
|
||||
|
||||
// Try to extract a SpringSecurityException from the stacktrace
|
||||
Throwable[] causeChain = throwableAnalyzer.determineCauseChain(e);
|
||||
Exception ase = (OAuth2Exception) throwableAnalyzer.getFirstThrowableOfType(OAuth2Exception.class, causeChain);
|
||||
//用户名或密码错误
|
||||
if (ase instanceof InvalidGrantException) {
|
||||
return dealResponseEntity(AuthStatusCode.LOGIN_ERROR);
|
||||
}
|
||||
|
||||
ase = (AuthenticationException) throwableAnalyzer.getFirstThrowableOfType(AuthenticationException.class,
|
||||
causeChain);
|
||||
//登录用户名未找到
|
||||
if (ase instanceof UsernameNotFoundException) {
|
||||
return dealResponseEntity(AuthStatusCode.ACCOUNT_NOT_FIND);
|
||||
}
|
||||
|
||||
ase = (AccessDeniedException) throwableAnalyzer
|
||||
.getFirstThrowableOfType(AccessDeniedException.class, causeChain);
|
||||
//无访问权限
|
||||
if (ase instanceof AccessDeniedException) {
|
||||
return dealResponseEntity(AuthStatusCode.APP_CONFIG_ERROR.getCode(), AuthStatusCode.APP_CONFIG_ERROR.getMessage() + e.getMessage());
|
||||
}
|
||||
|
||||
ase = (HttpRequestMethodNotSupportedException) throwableAnalyzer.getFirstThrowableOfType(
|
||||
HttpRequestMethodNotSupportedException.class, causeChain);
|
||||
//方法未被允许
|
||||
if (ase instanceof HttpRequestMethodNotSupportedException) {
|
||||
return dealResponseEntity(AuthStatusCode.METHOD_NOT_ALLOWED.getCode(), AuthStatusCode.METHOD_NOT_ALLOWED.getMessage() + e.getMessage());
|
||||
|
||||
}
|
||||
//其他异常
|
||||
return dealResponseEntity(AuthStatusCode.SERVICE_ERROR.getCode(), AuthStatusCode.SERVICE_ERROR.getMessage() + e.getMessage());
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static ResponseEntity dealResponseEntity(IBaseCode baseCode) {
|
||||
return dealResponseEntity(baseCode.getCode(), baseCode.getMessage());
|
||||
}
|
||||
|
||||
private static ResponseEntity dealResponseEntity(String code, String message) {
|
||||
return ResponseEntity
|
||||
.status(HttpStatus.OK)
|
||||
.body(ApiResponse.fail(code, message));
|
||||
}
|
||||
|
||||
public static class CustomizeException extends MyOAuth2Exception {
|
||||
String code = "";
|
||||
|
||||
public CustomizeException(IBaseCode baseCode) {
|
||||
super(baseCode.getMessage());
|
||||
this.code = baseCode.getCode();
|
||||
}
|
||||
|
||||
public CustomizeException(String code, String msg) {
|
||||
super(msg);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOAuth2ErrorCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.dstz.auth.exception;
|
||||
|
||||
import com.dstz.auth.authentication.api.constant.AuthStatusCode;
|
||||
import com.dstz.base.api.vo.ApiResponse;
|
||||
import com.dstz.base.common.utils.JsonUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* 鉴权失败返回信息
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public class AuthExceptionEntryPoint implements AuthenticationEntryPoint {
|
||||
@Override
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
|
||||
byte[] responseBytes = JsonUtils.toJSONBytes(ApiResponse.fail(AuthStatusCode.TOKEN_INVALID.getCode(), AuthStatusCode.TOKEN_INVALID.getMessage()));
|
||||
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||
response.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
|
||||
response.setContentLength(responseBytes.length);
|
||||
response.getOutputStream().write(responseBytes, 0, responseBytes.length);
|
||||
response.getOutputStream().flush();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.dstz.auth.exception;
|
||||
|
||||
import com.dstz.auth.authentication.api.constant.AuthStatusCode;
|
||||
import com.dstz.base.api.vo.ApiResponse;
|
||||
import com.dstz.base.common.utils.JsonUtils;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.web.access.AccessDeniedHandler;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
/**
|
||||
* 权限不足返回信息
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public class CustomizeAccessDeniedHandler implements AccessDeniedHandler {
|
||||
@Override
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
|
||||
response.setContentType("text/html;charset=UTF-8");
|
||||
response.getWriter().write(JsonUtils.toJSONString(ApiResponse.fail(AuthStatusCode.NOT_PERMISSION.getCode(), AuthStatusCode.NOT_PERMISSION.getMessage())));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
package com.dstz.auth.exception;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
||||
import org.springframework.security.oauth2.common.exceptions.*;
|
||||
import org.springframework.security.oauth2.common.util.OAuth2Utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 自定义反序列化
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public class CustomizeOAuthExceptionDeserializer extends StdDeserializer<OAuth2Exception> {
|
||||
public CustomizeOAuthExceptionDeserializer() {
|
||||
super(OAuth2Exception.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2Exception deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
|
||||
JsonProcessingException {
|
||||
|
||||
JsonToken t = jp.getCurrentToken();
|
||||
if (t == JsonToken.START_OBJECT) {
|
||||
t = jp.nextToken();
|
||||
}
|
||||
Map<String, Object> errorParams = new HashMap<String, Object>();
|
||||
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
|
||||
// Must point to field name
|
||||
String fieldName = jp.getCurrentName();
|
||||
// And then the value...
|
||||
t = jp.nextToken();
|
||||
// Note: must handle null explicitly here; value deserializers won't
|
||||
Object value;
|
||||
if (t == JsonToken.VALUE_NULL) {
|
||||
value = null;
|
||||
}
|
||||
else if (t == JsonToken.START_ARRAY) {
|
||||
value = jp.readValueAs(List.class);
|
||||
} else if (t == JsonToken.START_OBJECT) {
|
||||
value = jp.readValueAs(Map.class);
|
||||
} else {
|
||||
value = jp.getText();
|
||||
}
|
||||
errorParams.put(fieldName, value);
|
||||
}
|
||||
|
||||
Object errorCode = errorParams.get(OAuth2Exception.ERROR);
|
||||
String errorMessage = errorParams.get(OAuth2Exception.DESCRIPTION) != null ? errorParams.get(OAuth2Exception.DESCRIPTION).toString() : null;
|
||||
if (errorMessage == null) {
|
||||
errorMessage = errorCode == null ? "OAuth Error" : errorCode.toString();
|
||||
}
|
||||
|
||||
OAuth2Exception ex;
|
||||
if (OAuth2Exception.INVALID_CLIENT.equals(errorCode)) {
|
||||
ex = new InvalidClientException(errorMessage);
|
||||
} else if (OAuth2Exception.UNAUTHORIZED_CLIENT.equals(errorCode)) {
|
||||
ex = new UnauthorizedClientException(errorMessage);
|
||||
} else if (OAuth2Exception.INVALID_GRANT.equals(errorCode)) {
|
||||
if (errorMessage.toLowerCase().contains("redirect") && errorMessage.toLowerCase().contains("match")) {
|
||||
ex = new RedirectMismatchException(errorMessage);
|
||||
} else {
|
||||
ex = new InvalidGrantException(errorMessage);
|
||||
}
|
||||
} else if (OAuth2Exception.INVALID_SCOPE.equals(errorCode)) {
|
||||
ex = new InvalidScopeException(errorMessage);
|
||||
} else if (OAuth2Exception.INVALID_TOKEN.equals(errorCode)) {
|
||||
ex = new InvalidTokenException(errorMessage);
|
||||
} else if (OAuth2Exception.INVALID_REQUEST.equals(errorCode)) {
|
||||
ex = new InvalidRequestException(errorMessage);
|
||||
} else if (OAuth2Exception.REDIRECT_URI_MISMATCH.equals(errorCode)) {
|
||||
ex = new RedirectMismatchException(errorMessage);
|
||||
} else if (OAuth2Exception.UNSUPPORTED_GRANT_TYPE.equals(errorCode)) {
|
||||
ex = new UnsupportedGrantTypeException(errorMessage);
|
||||
} else if (OAuth2Exception.UNSUPPORTED_RESPONSE_TYPE.equals(errorCode)) {
|
||||
ex = new UnsupportedResponseTypeException(errorMessage);
|
||||
} else if (OAuth2Exception.INSUFFICIENT_SCOPE.equals(errorCode)) {
|
||||
ex = new InsufficientScopeException(errorMessage, OAuth2Utils.parseParameterList((String) errorParams
|
||||
.get("scope")));
|
||||
} else if (OAuth2Exception.ACCESS_DENIED.equals(errorCode)) {
|
||||
ex = new UserDeniedAuthorizationException(errorMessage);
|
||||
} else {
|
||||
ex = new OAuth2Exception(errorMessage);
|
||||
}
|
||||
|
||||
Set<Map.Entry<String, Object>> entries = errorParams.entrySet();
|
||||
for (Map.Entry<String, Object> entry : entries) {
|
||||
String key = entry.getKey();
|
||||
if (!"error".equals(key) && !"error_description".equals(key)) {
|
||||
Object value = entry.getValue();
|
||||
ex.addAdditionalInformation(key, value == null ? null : value.toString());
|
||||
}
|
||||
}
|
||||
return ex;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.dstz.auth.exception;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
/**
|
||||
* 自定义序列化
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public class CustomizeOauthExceptionSerializer extends StdSerializer<MyOAuth2Exception> {
|
||||
public CustomizeOauthExceptionSerializer() {
|
||||
super(MyOAuth2Exception.class);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void serialize(MyOAuth2Exception value, JsonGenerator jgen, SerializerProvider provider) throws IOException,
|
||||
JsonProcessingException {
|
||||
|
||||
jgen.writeStartObject();
|
||||
jgen.writeFieldName("isOk");
|
||||
jgen.writeBoolean(Boolean.FALSE);
|
||||
jgen.writeFieldName("code");
|
||||
jgen.writeString(value.getOAuth2ErrorCode());
|
||||
jgen.writeFieldName("message");
|
||||
jgen.writeString(value.getMessage());
|
||||
jgen.writeFieldName("msg");
|
||||
jgen.writeString(value.getMessage());
|
||||
jgen.writeEndObject();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.dstz.auth.exception;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||
|
||||
/**
|
||||
* 自定义异常类
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
@JsonSerialize(using = CustomizeOauthExceptionSerializer.class)
|
||||
@JsonDeserialize(using = CustomizeOAuthExceptionDeserializer.class)
|
||||
public class MyOAuth2Exception extends OAuth2Exception {
|
||||
public MyOAuth2Exception(String msg, Throwable t) {
|
||||
super(msg, t);
|
||||
}
|
||||
|
||||
public MyOAuth2Exception(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.dstz.auth.filter;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
import com.dstz.auth.utils.IngoreChecker;
|
||||
import com.dstz.base.api.vo.ApiResponse;
|
||||
import com.dstz.base.common.constats.StrPool;
|
||||
import com.dstz.base.common.utils.JsonUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static com.dstz.auth.authentication.api.constant.AuthApiConstant.AUTHORIZATION;
|
||||
import static com.dstz.auth.authentication.api.constant.AuthStatusCode.NO_AUTH_TOKEN;
|
||||
|
||||
/**
|
||||
* Authorization参数过滤
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public class AuthorizationTokenCheckFilter extends IngoreChecker implements Filter {
|
||||
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
HttpServletRequest req = (HttpServletRequest) request;
|
||||
//处理匿名接口
|
||||
if (this.isIngores(req)) {
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
String token = ServletUtil.getHeader(req, AUTHORIZATION, StrPool.EMPTY);
|
||||
if (StrUtil.isBlank(token) || !token.trim().startsWith(OAuth2AccessToken.BEARER_TYPE)) {
|
||||
response.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
|
||||
ServletUtil.write((HttpServletResponse) response, JsonUtils.toJSONString(ApiResponse.fail(NO_AUTH_TOKEN.getCode(), NO_AUTH_TOKEN.getMessage())), MediaType.APPLICATION_JSON_VALUE);
|
||||
} else {
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package com.dstz.auth.filter;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Cors过滤器
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public class CorsFilter extends OncePerRequestFilter implements Ordered {
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse resp, FilterChain filterChain) throws ServletException, IOException {
|
||||
//此处我们忽略跨域问题由 @RefererCsrfFilter.java 来处理
|
||||
//默认全部支持跨域
|
||||
setHeader(resp, HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "accept, origin, content-type, accessToken, token, Authorization, Cookie");
|
||||
setHeader(resp, HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "Ab-Product-Past");
|
||||
setHeader(resp, HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "POST,GET,PUT");
|
||||
setHeader(resp, HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, req.getHeader(HttpHeaders.ORIGIN));
|
||||
setHeader(resp, HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, Boolean.TRUE.toString());
|
||||
|
||||
if (req.getMethod().equals(HttpMethod.OPTIONS.name())) {
|
||||
resp.setStatus(HttpStatus.OK.value());
|
||||
setHeader(resp, HttpHeaders.ACCESS_CONTROL_MAX_AGE, "3600");
|
||||
} else {
|
||||
filterChain.doFilter(req, resp);
|
||||
}
|
||||
}
|
||||
|
||||
private void setHeader(HttpServletResponse resp, String name, String value) {
|
||||
if (resp.getHeader(name) == null) {
|
||||
resp.setHeader(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return -300;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package com.dstz.auth.filter;
|
||||
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
import com.dstz.auth.utils.IngoreChecker;
|
||||
import com.dstz.auth.utils.RefererCsrfChecker;
|
||||
import com.dstz.base.api.vo.ApiResponse;
|
||||
import com.dstz.base.common.enums.GlobalApiCodes;
|
||||
import com.dstz.base.common.utils.JsonUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* 防止CSRF跨站请求攻击。<br>
|
||||
* 这个主要是防止外链连入到本系统。
|
||||
*
|
||||
* @author lightning
|
||||
*/
|
||||
public class RefererCsrfFilter extends RefererCsrfChecker implements Filter {
|
||||
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
HttpServletRequest req = (HttpServletRequest) request;
|
||||
|
||||
//判断是否外链。
|
||||
String referer = req.getHeader("Referer");
|
||||
String serverName = request.getServerName();
|
||||
//请求不是来自本网站。
|
||||
if (null != referer && referer.indexOf(serverName) < 0) {
|
||||
//是否包含当前URL
|
||||
boolean isIngoreUrl = this.isIngores(referer);
|
||||
if (isIngoreUrl) {
|
||||
chain.doFilter(request, response);
|
||||
} else {
|
||||
String msg = String.format("系统不支持当前域名的访问,请联系管理员!<br> 服务器:%s,当前域名:%s", serverName, referer);
|
||||
response.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
|
||||
ServletUtil.write((HttpServletResponse) response, JsonUtils.toJSONString(ApiResponse.fail(GlobalApiCodes.INTERNAL_ERROR.getCode(), msg)), MediaType.APPLICATION_JSON_VALUE);
|
||||
}
|
||||
} else {
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig config) {
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue