refactor: 初始化v2
This commit is contained in:
parent
e6402ff9b9
commit
910d5b26ab
13
.github/workflows/auto-pr.yml
vendored
13
.github/workflows/auto-pr.yml
vendored
@ -1,13 +0,0 @@
|
|||||||
on: [push, pull_request, release]
|
|
||||||
|
|
||||||
name: DataEase pull request handler
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
generic_handler:
|
|
||||||
name: Generic handler for DataEase Repos
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Add labels
|
|
||||||
uses: jumpserver/action-generic-handler@master
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUBTOKEN }}
|
|
||||||
16
.github/workflows/issue-open.yml
vendored
16
.github/workflows/issue-open.yml
vendored
@ -1,16 +0,0 @@
|
|||||||
name: Issue Open Check
|
|
||||||
|
|
||||||
on:
|
|
||||||
issues:
|
|
||||||
types: [opened]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
issue-open-add-labels:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Add labels
|
|
||||||
uses: actions-cool/issues-helper@v2
|
|
||||||
if: ${{ !github.event.comment.pull_request.pull_request }}
|
|
||||||
with:
|
|
||||||
actions: 'add-labels'
|
|
||||||
labels: '状态:待处理'
|
|
||||||
17
.github/workflows/issue-recent-alert.yml
vendored
17
.github/workflows/issue-recent-alert.yml
vendored
@ -1,17 +0,0 @@
|
|||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 1 * * *"
|
|
||||||
|
|
||||||
name: Check recent handle issues
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check-recent-issues-not-handle:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Check recent issues and send msg
|
|
||||||
uses: jumpserver/action-issues-alert@master
|
|
||||||
with:
|
|
||||||
hook: ${{ secrets.WECHAT_GROUP_WEB_HOOK }}
|
|
||||||
type: recent
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUBTOKEN }}
|
|
||||||
16
.github/workflows/sync2gitee.yml
vendored
16
.github/workflows/sync2gitee.yml
vendored
@ -1,16 +0,0 @@
|
|||||||
name: sync2gitee
|
|
||||||
on: [push]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
repo-sync:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Mirror the Github organization repos to Gitee.
|
|
||||||
uses: Yikun/hub-mirror-action@master
|
|
||||||
with:
|
|
||||||
src: 'github/dataease'
|
|
||||||
dst: 'gitee/fit2cloud-feizhiyun'
|
|
||||||
dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
|
|
||||||
dst_token: ${{ secrets.GITEE_TOKEN }}
|
|
||||||
static_list: "DataEase"
|
|
||||||
force_update: true
|
|
||||||
57
.gitignore
vendored
57
.gitignore
vendored
@ -18,44 +18,25 @@
|
|||||||
*.zip
|
*.zip
|
||||||
*.tar.gz
|
*.tar.gz
|
||||||
*.rar
|
*.rar
|
||||||
|
.idea/
|
||||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
|
||||||
hs_err_pid*
|
|
||||||
/.idea/
|
|
||||||
target/
|
target/
|
||||||
|
.vscode/
|
||||||
|
.lh/
|
||||||
*.iml
|
*.iml
|
||||||
.DS_Store
|
hs_err_pid*
|
||||||
node_modules
|
node_modules/
|
||||||
/dist
|
dist/
|
||||||
node/
|
|
||||||
|
|
||||||
# local env files
|
|
||||||
.env.demo
|
|
||||||
.env.*.local
|
|
||||||
|
|
||||||
# Log files
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
pnpm-debug.log*
|
|
||||||
|
|
||||||
# Editor directories and files
|
|
||||||
.lh
|
|
||||||
.idea
|
|
||||||
.vscode
|
|
||||||
*.suo
|
|
||||||
*.ntvs*
|
|
||||||
*.njsproj
|
|
||||||
*.sln
|
|
||||||
*.sw?
|
|
||||||
*.lock
|
|
||||||
*.classpath
|
|
||||||
*.project
|
|
||||||
.settings/
|
|
||||||
.lh
|
|
||||||
|
|
||||||
|
|
||||||
### Spring flatten ###
|
|
||||||
.flattened-pom.xml
|
|
||||||
|
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
.DS_Store
|
||||||
|
.stylelintcache
|
||||||
|
core/core-frontend/release/
|
||||||
|
plugins/vite-test
|
||||||
|
core/core-frontend/.stylelintcache
|
||||||
|
/core/core-backend/src/main/resources/static/
|
||||||
|
/core/core-backend/src/test
|
||||||
|
/core/core-frontend/node/
|
||||||
|
/core/core-frontend/lib/
|
||||||
|
/core/core-frontend/components.d.ts
|
||||||
|
core/core-frontend/src/assets/fsSvg.js
|
||||||
|
core/core-frontend/src/assets/fsSvg.html
|
||||||
|
/de-xpack/
|
||||||
|
|||||||
31
.typos.toml
31
.typos.toml
@ -1,29 +1,6 @@
|
|||||||
[default.extend-words]
|
[default.extend-words]
|
||||||
Rela = "Rela"
|
ser = "ser"
|
||||||
eles = "eles"
|
Referer = "Referer"
|
||||||
delink = "delink"
|
Encryp = "Encryp"
|
||||||
testng = "testng"
|
|
||||||
ba = "ba"
|
|
||||||
referer = "referer"
|
|
||||||
keynode = "keynode"
|
|
||||||
SCHEM = "SCHEM"
|
|
||||||
|
|
||||||
[files]
|
[files]
|
||||||
extend-exclude = [
|
extend-exclude = ["mapFiles/**"]
|
||||||
"public/",
|
|
||||||
"amap-wx/",
|
|
||||||
"m-icon/",
|
|
||||||
"uni-card/",
|
|
||||||
"uni-col/",
|
|
||||||
"uni-link/",
|
|
||||||
"uni-list/",
|
|
||||||
"uni-list-item/",
|
|
||||||
"uni-row/",
|
|
||||||
"migration/",
|
|
||||||
"mapFiles/",
|
|
||||||
"core/frontend/src/views/chart/components/table/TableNormal.vue",
|
|
||||||
"core/backend/src/main/java/io/dataease/ext/ExtSysUserMapper.xml",
|
|
||||||
"core/backend/src/main/java/io/dataease/ext/AuthMapper.xml",
|
|
||||||
"installer/dataease/templates/be.conf"
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|||||||
25
Dockerfile
25
Dockerfile
@ -1,23 +1,22 @@
|
|||||||
FROM registry.cn-qingdao.aliyuncs.com/dataease/fabric8-java-alpine-openjdk8-jre:edge-chromium-11
|
FROM registry.cn-qingdao.aliyuncs.com/dataease/alpine-openjdk17-jre
|
||||||
|
|
||||||
ARG IMAGE_TAG
|
ARG IMAGE_TAG
|
||||||
|
|
||||||
RUN mkdir -p /opt/apps /opt/dataease/data/feature/full /opt/dataease/drivers /opt/dataease/plugins/default
|
RUN mkdir -p /opt/apps/config /opt/dataease/drivers/ /opt/dataease2.0/cache/ /opt/dataease2.0/data/map /opt/dataease2.0/data/static-resource/
|
||||||
|
|
||||||
ADD core/mapFiles/full/ /opt/dataease/data/feature/full/
|
ADD drivers/* /opt/dataease/drivers/
|
||||||
|
ADD mapFiles/ /opt/dataease2.0/data/map/
|
||||||
|
ADD staticResource/ /opt/dataease2.0/data/static-resource/
|
||||||
|
|
||||||
ADD core/drivers/* /opt/dataease/drivers/
|
WORKDIR /opt/apps
|
||||||
|
|
||||||
ADD plugins/default/ /opt/dataease/plugins/default/
|
ADD core/core-backend/target/CoreApplication.jar /opt/apps/app.jar
|
||||||
|
ADD de-xpack/xpack-permissions/target/xpack-permissions-$IMAGE_TAG.jar /opt/apps/xpack-permission.jar
|
||||||
|
ADD de-xpack/xpack-base/target/xpack-base-$IMAGE_TAG.jar /opt/apps/xpack-base.jar
|
||||||
|
|
||||||
ADD core/backend/target/backend-$IMAGE_TAG.jar /opt/apps
|
ENV JAVA_APP_JAR=/opt/apps/app.jar
|
||||||
|
|
||||||
ENV JAVA_APP_JAR=/opt/apps/backend-$IMAGE_TAG.jar
|
HEALTHCHECK --interval=15s --timeout=5s --retries=20 --start-period=30s CMD curl -f 127.0.0.1:8100
|
||||||
|
|
||||||
ENV AB_OFF=true
|
|
||||||
|
|
||||||
ENV JAVA_OPTIONS=-Dfile.encoding=utf-8
|
CMD java -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/dataease2.0/logs/dump.hprof -Dloader.path=/opt/apps/xpack-permission.jar,/opt/apps/xpack-base.jar -jar /opt/apps/app.jar
|
||||||
|
|
||||||
HEALTHCHECK --interval=15s --timeout=5s --retries=20 --start-period=30s CMD curl -f 127.0.0.1:8081
|
|
||||||
|
|
||||||
CMD ["/deployments/run-java.sh"]
|
|
||||||
|
|||||||
61
core/.gitignore
vendored
61
core/.gitignore
vendored
@ -1,61 +0,0 @@
|
|||||||
# 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*
|
|
||||||
/.idea/
|
|
||||||
target/
|
|
||||||
*.iml
|
|
||||||
.DS_Store
|
|
||||||
node_modules
|
|
||||||
/dist
|
|
||||||
node/
|
|
||||||
|
|
||||||
# local env files
|
|
||||||
.env.demo
|
|
||||||
.env.*.local
|
|
||||||
|
|
||||||
# Log files
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
pnpm-debug.log*
|
|
||||||
|
|
||||||
# Editor directories and files
|
|
||||||
.lh
|
|
||||||
.idea
|
|
||||||
.vscode
|
|
||||||
*.suo
|
|
||||||
*.ntvs*
|
|
||||||
*.njsproj
|
|
||||||
*.sln
|
|
||||||
*.sw?
|
|
||||||
*.lock
|
|
||||||
*.classpath
|
|
||||||
*.project
|
|
||||||
.settings/
|
|
||||||
.lh
|
|
||||||
|
|
||||||
|
|
||||||
### Spring flatten ###
|
|
||||||
.flattened-pom.xml
|
|
||||||
|
|
||||||
package-lock.json
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
. "$(dirname -- "$0")/_/husky.sh"
|
|
||||||
|
|
||||||
cd ./frontend
|
|
||||||
npm run lint-staged
|
|
||||||
35
core/backend/.gitignore
vendored
35
core/backend/.gitignore
vendored
@ -1,35 +0,0 @@
|
|||||||
# Created by .ignore support plugin (hsz.mobi)
|
|
||||||
.DS_Store
|
|
||||||
node_modules
|
|
||||||
node/
|
|
||||||
/dist
|
|
||||||
|
|
||||||
# local env files
|
|
||||||
.env.local
|
|
||||||
.env.*.local
|
|
||||||
|
|
||||||
# Log files
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
|
|
||||||
# Editor directories and files
|
|
||||||
.idea
|
|
||||||
*.iml
|
|
||||||
.vscode
|
|
||||||
*.suo
|
|
||||||
*.ntvs*
|
|
||||||
*.njsproj
|
|
||||||
*.sln
|
|
||||||
*.sw?
|
|
||||||
|
|
||||||
|
|
||||||
src/main/resources/static
|
|
||||||
src/main/resources/templates
|
|
||||||
src/test/
|
|
||||||
target
|
|
||||||
.settings
|
|
||||||
.project
|
|
||||||
.classpath
|
|
||||||
.factorypath
|
|
||||||
src/main/resources/jmeter/lib/
|
|
||||||
@ -1,544 +0,0 @@
|
|||||||
<?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>dataease-server</artifactId>
|
|
||||||
<groupId>io.dataease</groupId>
|
|
||||||
<version>${dataease.version}</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<artifactId>backend</artifactId>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
<shiro.version>1.9.1</shiro.version>
|
|
||||||
<java.version>11</java.version>
|
|
||||||
<graalvm.version>20.1.0</graalvm.version>
|
|
||||||
<jwt.version>3.12.1</jwt.version>
|
|
||||||
<buji.version>4.0.0</buji.version>
|
|
||||||
<pac4j.version>3.3.0</pac4j.version>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
<version>32.0.0-jre</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter</artifactId>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-api</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-aop</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.servlet</groupId>
|
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
|
||||||
<version>4.0.1</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-mail</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.code.gson</groupId>
|
|
||||||
<artifactId>gson</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<!-- flyway -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.flywaydb</groupId>
|
|
||||||
<artifactId>flyway-core</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>mysql</groupId>
|
|
||||||
<artifactId>mysql-connector-java</artifactId>
|
|
||||||
<version>8.0.28</version>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.pagehelper</groupId>
|
|
||||||
<artifactId>pagehelper</artifactId>
|
|
||||||
<version>5.3.1</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.shiro</groupId>
|
|
||||||
<artifactId>shiro-spring</artifactId>
|
|
||||||
<version>${shiro.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-lang3</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-collections4</artifactId>
|
|
||||||
<version>4.4</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-text</artifactId>
|
|
||||||
<version>1.10.0</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>commons-codec</groupId>
|
|
||||||
<artifactId>commons-codec</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.alibaba</groupId>
|
|
||||||
<artifactId>fastjson</artifactId>
|
|
||||||
<version>1.2.83</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.auth0</groupId>
|
|
||||||
<artifactId>java-jwt</artifactId>
|
|
||||||
<version>${jwt.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.curator</groupId>
|
|
||||||
<artifactId>curator-framework</artifactId>
|
|
||||||
<version>4.0.1</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-api</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.curator</groupId>
|
|
||||||
<artifactId>curator-recipes</artifactId>
|
|
||||||
<version>4.0.1</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.fit2cloud</groupId>
|
|
||||||
<artifactId>quartz-spring-boot-starter</artifactId>
|
|
||||||
<version>0.0.7</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-api</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-compress</artifactId>
|
|
||||||
<version>1.21</version>
|
|
||||||
</dependency>
|
|
||||||
<!--xpath不加这个依赖会报错-->
|
|
||||||
<dependency>
|
|
||||||
<groupId>jaxen</groupId>
|
|
||||||
<artifactId>jaxen</artifactId>
|
|
||||||
<version>1.2.0</version>
|
|
||||||
</dependency>
|
|
||||||
<!--开启 cache 缓存 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-cache</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.testng</groupId>
|
|
||||||
<artifactId>testng</artifactId>
|
|
||||||
<version>7.7.0</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<!-- ehcache 缓存 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.sf.ehcache</groupId>
|
|
||||||
<artifactId>ehcache</artifactId>
|
|
||||||
<version>2.9.1</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-api</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.dataease</groupId>
|
|
||||||
<artifactId>dataease-plugin-interface</artifactId>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.dataease</groupId>
|
|
||||||
<artifactId>dataease-plugin-view</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.dataease</groupId>
|
|
||||||
<artifactId>dataease-plugin-datasource</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<!-- kettle及数据源依赖 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>pentaho-kettle</groupId>
|
|
||||||
<artifactId>kettle-core</artifactId>
|
|
||||||
<version>8.3.0.18-1112</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-api</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>commons-io</artifactId>
|
|
||||||
<groupId>commons-io</groupId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>pentaho-kettle</groupId>
|
|
||||||
<artifactId>kettle-engine</artifactId>
|
|
||||||
<version>8.3.0.18-1112</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-api</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.springframework.security</groupId>
|
|
||||||
<artifactId>spring-security-core</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>commons-io</artifactId>
|
|
||||||
<groupId>commons-io</groupId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>pentaho</groupId>
|
|
||||||
<artifactId>metastore</artifactId>
|
|
||||||
<version>8.3.0.18-1112</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>commons-io</artifactId>
|
|
||||||
<groupId>commons-io</groupId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.pentaho.di.plugins</groupId>
|
|
||||||
<artifactId>pdi-engine-configuration-impl</artifactId>
|
|
||||||
<version>8.3.0.7-683</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.alibaba</groupId>
|
|
||||||
<artifactId>druid</artifactId>
|
|
||||||
<version>1.2.8</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.alibaba</groupId>
|
|
||||||
<artifactId>jconsole</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.alibaba</groupId>
|
|
||||||
<artifactId>tools</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.seleniumhq.selenium</groupId>
|
|
||||||
<artifactId>selenium-java</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jsoup</groupId>
|
|
||||||
<artifactId>jsoup</artifactId>
|
|
||||||
<version>1.15.3</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.jayway.jsonpath</groupId>
|
|
||||||
<artifactId>json-path</artifactId>
|
|
||||||
<version>2.4.0</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-api</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-pool2</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>ru.yandex.qatools.ashot</groupId>
|
|
||||||
<artifactId>ashot</artifactId>
|
|
||||||
<version>1.5.4</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<resources>
|
|
||||||
<resource>
|
|
||||||
<directory>src/main/java</directory>
|
|
||||||
<includes>
|
|
||||||
<include>**/*.properties</include>
|
|
||||||
<include>**/*.xml</include>
|
|
||||||
</includes>
|
|
||||||
<filtering>false</filtering>
|
|
||||||
</resource>
|
|
||||||
<resource>
|
|
||||||
<directory>src/main/resources</directory>
|
|
||||||
<filtering>true</filtering>
|
|
||||||
<excludes>
|
|
||||||
<exclude>static/**/*.woff</exclude>
|
|
||||||
<exclude>static/**/*.woff2</exclude>
|
|
||||||
<exclude>static/**/*.ttf</exclude>
|
|
||||||
<exclude>static/**/*.ico</exclude>
|
|
||||||
</excludes>
|
|
||||||
</resource>
|
|
||||||
<resource>
|
|
||||||
<directory>src/main/resources</directory>
|
|
||||||
<filtering>false</filtering>
|
|
||||||
<includes>
|
|
||||||
<include>static/**/*.woff</include>
|
|
||||||
<include>static/**/*.woff2</include>
|
|
||||||
<include>static/**/*.ttf</include>
|
|
||||||
<include>static/**/*.ico</include>
|
|
||||||
</includes>
|
|
||||||
</resource>
|
|
||||||
</resources>
|
|
||||||
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-resources-plugin</artifactId>
|
|
||||||
<version>3.1.0</version>
|
|
||||||
<configuration>
|
|
||||||
<encoding>UTF-8</encoding>
|
|
||||||
<nonFilteredFileExtensions>
|
|
||||||
<nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
|
|
||||||
</nonFilteredFileExtensions>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<addResources>true</addResources>
|
|
||||||
<excludes>
|
|
||||||
<exclude>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
</exclude>
|
|
||||||
<exclude>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
|
||||||
</exclude>
|
|
||||||
</excludes>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
|
||||||
<version>2.12.4</version>
|
|
||||||
<configuration>
|
|
||||||
<skipTests>true</skipTests>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-clean-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<filesets>
|
|
||||||
<fileset>
|
|
||||||
<directory>src/main/resources/static</directory>
|
|
||||||
<includes>
|
|
||||||
<include>**</include>
|
|
||||||
</includes>
|
|
||||||
<followSymlinks>false</followSymlinks>
|
|
||||||
</fileset>
|
|
||||||
<fileset>
|
|
||||||
<directory>src/main/resources/templates</directory>
|
|
||||||
<includes>
|
|
||||||
<include>**</include>
|
|
||||||
</includes>
|
|
||||||
<followSymlinks>false</followSymlinks>
|
|
||||||
</fileset>
|
|
||||||
</filesets>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<source>11</source>
|
|
||||||
<target>11</target>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<!-- Overlay guacamole-common-js (zip) -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
|
||||||
<version>2.6</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.mybatis.generator</groupId>
|
|
||||||
<artifactId>mybatis-generator-maven-plugin</artifactId>
|
|
||||||
<version>1.3.7</version>
|
|
||||||
<configuration>
|
|
||||||
<verbose>true</verbose>
|
|
||||||
<overwrite>true</overwrite>
|
|
||||||
</configuration>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>mysql</groupId>
|
|
||||||
<artifactId>mysql-connector-java</artifactId>
|
|
||||||
<version>8.0.28</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.itfsw</groupId>
|
|
||||||
<artifactId>mybatis-generator-plugin</artifactId>
|
|
||||||
<version>1.3.8</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<profiles>
|
|
||||||
<profile>
|
|
||||||
<id>whole</id>
|
|
||||||
<properties>
|
|
||||||
<profiles.active>whole</profiles.active>
|
|
||||||
</properties>
|
|
||||||
<activation>
|
|
||||||
<activeByDefault>true</activeByDefault>
|
|
||||||
</activation>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-antrun-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<?m2e execute onConfiguration?>
|
|
||||||
<id>main-class-placement</id>
|
|
||||||
<phase>generate-resources</phase>
|
|
||||||
<configuration>
|
|
||||||
<target>
|
|
||||||
<move todir="src/main/resources/static">
|
|
||||||
<fileset dir="../frontend/dist">
|
|
||||||
<exclude name="*.html"/>
|
|
||||||
</fileset>
|
|
||||||
</move>
|
|
||||||
<move todir="src/main/resources/templates">
|
|
||||||
<fileset dir="../frontend/dist">
|
|
||||||
<include name="*.html"/>
|
|
||||||
</fileset>
|
|
||||||
</move>
|
|
||||||
<copy todir="src/main/resources/static/de-app">
|
|
||||||
<fileset dir="../mobile/dist">
|
|
||||||
<exclude name="*.html"/>
|
|
||||||
</fileset>
|
|
||||||
</copy>
|
|
||||||
<copy file="../mobile/dist/index.html"
|
|
||||||
tofile="src/main/resources/templates/app.html"/>
|
|
||||||
</target>
|
|
||||||
</configuration>
|
|
||||||
<goals>
|
|
||||||
<goal>run</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</profile>
|
|
||||||
<profile>
|
|
||||||
<id>stage</id>
|
|
||||||
<properties>
|
|
||||||
<profiles.active>stage</profiles.active>
|
|
||||||
</properties>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
|
|
||||||
<repositories>
|
|
||||||
<repository>
|
|
||||||
<id>pentaho-public</id>
|
|
||||||
<name>Pentaho Public</name>
|
|
||||||
<url>https://repo.orl.eng.hitachivantara.com/artifactory/pnt-mvn/</url>
|
|
||||||
<releases>
|
|
||||||
<enabled>true</enabled>
|
|
||||||
<updatePolicy>daily</updatePolicy>
|
|
||||||
</releases>
|
|
||||||
<snapshots>
|
|
||||||
<enabled>true</enabled>
|
|
||||||
<updatePolicy>interval:15</updatePolicy>
|
|
||||||
</snapshots>
|
|
||||||
</repository>
|
|
||||||
|
|
||||||
<repository>
|
|
||||||
<id>clojars</id>
|
|
||||||
<url>https://repo.clojars.org/</url>
|
|
||||||
</repository>
|
|
||||||
</repositories>
|
|
||||||
|
|
||||||
</project>
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
package io.dataease;
|
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
|
|
||||||
import org.springframework.boot.web.servlet.ServletComponentScan;
|
|
||||||
import org.springframework.cache.annotation.EnableCaching;
|
|
||||||
import org.springframework.context.annotation.PropertySource;
|
|
||||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
|
||||||
|
|
||||||
@EnableCaching
|
|
||||||
@SpringBootApplication(exclude = {
|
|
||||||
QuartzAutoConfiguration.class,
|
|
||||||
LdapAutoConfiguration.class
|
|
||||||
})
|
|
||||||
@ServletComponentScan
|
|
||||||
@EnableScheduling
|
|
||||||
@PropertySource(value = {"file:/opt/dataease/conf/dataease.properties"}, encoding = "UTF-8", ignoreResourceNotFound = true)
|
|
||||||
public class Application {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
SpringApplication.run(Application.class, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
package io.dataease.auth.annotation;
|
|
||||||
|
|
||||||
import io.dataease.commons.constants.DePermissionType;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
public @interface DeCleaner {
|
|
||||||
|
|
||||||
DePermissionType value();
|
|
||||||
|
|
||||||
int paramIndex() default 0;
|
|
||||||
|
|
||||||
String key() default "";
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
package io.dataease.auth.annotation;
|
|
||||||
|
|
||||||
import io.dataease.commons.constants.SysLogConstants.OPERATE_TYPE;
|
|
||||||
import io.dataease.commons.constants.SysLogConstants.SOURCE_TYPE;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
public @interface DeLog {
|
|
||||||
|
|
||||||
OPERATE_TYPE operatetype();
|
|
||||||
|
|
||||||
|
|
||||||
SOURCE_TYPE sourcetype();
|
|
||||||
|
|
||||||
|
|
||||||
int positionIndex() default -1;
|
|
||||||
String positionKey() default "";
|
|
||||||
|
|
||||||
|
|
||||||
int sourceIndex() default 0;
|
|
||||||
String sourceKey() default "";
|
|
||||||
|
|
||||||
int targetIndex() default -1;
|
|
||||||
String targetKey() default "";
|
|
||||||
SOURCE_TYPE targetType() default SOURCE_TYPE.USER;
|
|
||||||
|
|
||||||
String value() default "";
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
package io.dataease.auth.annotation;
|
|
||||||
|
|
||||||
import io.dataease.commons.constants.DePermissionType;
|
|
||||||
import io.dataease.commons.constants.ResourceAuthLevel;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
public @interface DePermission {
|
|
||||||
|
|
||||||
DePermissionType type();
|
|
||||||
|
|
||||||
ResourceAuthLevel level() default ResourceAuthLevel.COMMON_LEVEL_USE;
|
|
||||||
|
|
||||||
String value() default "";
|
|
||||||
|
|
||||||
int paramIndex() default 0;
|
|
||||||
}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
package io.dataease.auth.annotation;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
public @interface DePermissionProxy {
|
|
||||||
|
|
||||||
String value() default "";
|
|
||||||
|
|
||||||
int paramIndex() default 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
package io.dataease.auth.annotation;
|
|
||||||
|
|
||||||
|
|
||||||
import org.apache.shiro.authz.annotation.Logical;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE, ElementType.TYPE})
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
public @interface DePermissions {
|
|
||||||
|
|
||||||
DePermission[] value();
|
|
||||||
|
|
||||||
Logical logical() default Logical.AND;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
package io.dataease.auth.annotation;
|
|
||||||
|
|
||||||
import org.springframework.core.annotation.AliasFor;
|
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Documented
|
|
||||||
public @interface DeRateLimiter {
|
|
||||||
|
|
||||||
long DEFAULT_REQUEST = 2;
|
|
||||||
|
|
||||||
@AliasFor("max") long value() default DEFAULT_REQUEST;
|
|
||||||
|
|
||||||
@AliasFor("value") long max() default DEFAULT_REQUEST;
|
|
||||||
|
|
||||||
String key() default "";
|
|
||||||
|
|
||||||
long timeout() default 500;
|
|
||||||
|
|
||||||
TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
package io.dataease.auth.annotation;
|
|
||||||
|
|
||||||
|
|
||||||
import java.lang.annotation.Documented;
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|
||||||
|
|
||||||
@Documented
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
@Retention(RUNTIME)
|
|
||||||
public @interface SqlInjectValidator {
|
|
||||||
|
|
||||||
String[] value() default {};
|
|
||||||
}
|
|
||||||
@ -1,62 +0,0 @@
|
|||||||
package io.dataease.auth.aop;
|
|
||||||
|
|
||||||
import io.dataease.auth.annotation.DeCleaner;
|
|
||||||
import io.dataease.commons.constants.DePermissionType;
|
|
||||||
import io.dataease.commons.utils.AopUtils;
|
|
||||||
import io.dataease.commons.utils.CommonBeanFactory;
|
|
||||||
import io.dataease.commons.utils.LogUtil;
|
|
||||||
import io.dataease.service.decatch.DeCatchProcess;
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
|
||||||
import org.aspectj.lang.JoinPoint;
|
|
||||||
import org.aspectj.lang.annotation.AfterReturning;
|
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
|
||||||
import org.aspectj.lang.reflect.MethodSignature;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
@Aspect
|
|
||||||
@Component
|
|
||||||
public class DeCleanerAnnotationHandler {
|
|
||||||
|
|
||||||
@AfterReturning(value = "@annotation(io.dataease.auth.annotation.DeCleaner)")
|
|
||||||
public void CleanerAround(JoinPoint point) {
|
|
||||||
try {
|
|
||||||
MethodSignature ms = (MethodSignature) point.getSignature();
|
|
||||||
Method method = ms.getMethod();
|
|
||||||
DeCleaner deCleaner = method.getAnnotation(DeCleaner.class);
|
|
||||||
DePermissionType type = deCleaner.value();
|
|
||||||
String key = deCleaner.key();
|
|
||||||
Object[] args = point.getArgs();
|
|
||||||
Object paramValue = null;
|
|
||||||
if (ObjectUtils.isNotEmpty(key) && ArrayUtils.isNotEmpty(args)) {
|
|
||||||
int pi = deCleaner.paramIndex();
|
|
||||||
Object arg = point.getArgs()[pi];
|
|
||||||
paramValue = AopUtils.getParamValue(arg, key, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
switch (type.name()) {
|
|
||||||
case "DATASOURCE":
|
|
||||||
catchProcess().cleanDataSource(paramValue);
|
|
||||||
break;
|
|
||||||
case "DATASET":
|
|
||||||
catchProcess().cleanDataSet(paramValue);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
catchProcess().cleanPanel(paramValue);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
LogUtil.error(e.getMessage(), e);
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public DeCatchProcess catchProcess() {
|
|
||||||
return CommonBeanFactory.getBean(DeCatchProcess.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,135 +0,0 @@
|
|||||||
package io.dataease.auth.aop;
|
|
||||||
|
|
||||||
|
|
||||||
import io.dataease.auth.annotation.DeLog;
|
|
||||||
import io.dataease.commons.constants.SysLogConstants;
|
|
||||||
import io.dataease.commons.utils.AopUtils;
|
|
||||||
import io.dataease.controller.ResultHolder;
|
|
||||||
import io.dataease.dto.SysLogDTO;
|
|
||||||
import io.dataease.dto.log.FolderItem;
|
|
||||||
import io.dataease.service.sys.log.LogManager;
|
|
||||||
import io.dataease.service.sys.log.LogService;
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.aspectj.lang.JoinPoint;
|
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
|
||||||
import org.aspectj.lang.annotation.Around;
|
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
|
||||||
import org.aspectj.lang.reflect.MethodSignature;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Aspect
|
|
||||||
@Component
|
|
||||||
public class DeLogAnnotationHandler {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private LogManager logManager;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private LogService logService;
|
|
||||||
|
|
||||||
private static final List<Integer> before = new ArrayList<>();
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void init() {
|
|
||||||
before.add(SysLogConstants.OPERATE_TYPE.DELETE.getValue());
|
|
||||||
before.add(SysLogConstants.OPERATE_TYPE.UNSHARE.getValue());
|
|
||||||
before.add(SysLogConstants.OPERATE_TYPE.UNAUTHORIZE.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
private SysLogDTO exec(JoinPoint point, DeLog deLog) throws Exception {
|
|
||||||
|
|
||||||
Object[] args = point.getArgs();
|
|
||||||
if (ArrayUtils.isEmpty(args)) return null;
|
|
||||||
|
|
||||||
SysLogConstants.OPERATE_TYPE operatetype = deLog.operatetype();
|
|
||||||
SysLogConstants.SOURCE_TYPE sourcetype = deLog.sourcetype();
|
|
||||||
|
|
||||||
String sourceKey = StringUtils.isNotBlank(deLog.sourceKey()) ? deLog.sourceKey() : deLog.value();
|
|
||||||
int sourceIndex = deLog.sourceIndex();
|
|
||||||
if (args.length <= sourceIndex) return null;
|
|
||||||
Object arg = args[sourceIndex];
|
|
||||||
Object sourceIdValue = AopUtils.getParamValue(arg, sourceKey, 0);
|
|
||||||
if (ObjectUtils.isEmpty(sourceIdValue)) return null;
|
|
||||||
|
|
||||||
SysLogDTO sysLogDTO = new SysLogDTO();
|
|
||||||
sysLogDTO.setOperateType(operatetype.getValue());
|
|
||||||
sysLogDTO.setSourceType(sourcetype.getValue());
|
|
||||||
sysLogDTO.setSourceId(sourceIdValue.toString());
|
|
||||||
FolderItem sourceInfo = logManager.nameWithId(sourceIdValue.toString(), sourcetype.getValue());
|
|
||||||
if (ObjectUtils.isEmpty(sourceInfo)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
sysLogDTO.setSourceName(sourceInfo.getName());
|
|
||||||
|
|
||||||
// 填充资源位置信息
|
|
||||||
int positionIndex = deLog.positionIndex();
|
|
||||||
if (positionIndex > -1 && args.length > positionIndex) {
|
|
||||||
String positionKey = deLog.positionKey();
|
|
||||||
Object positionArg = args[positionIndex];
|
|
||||||
Object bottomPositionValue = AopUtils.getParamValue(positionArg, positionKey, 0);
|
|
||||||
if (ObjectUtils.isNotEmpty(bottomPositionValue)) {
|
|
||||||
if (sourcetype == SysLogConstants.SOURCE_TYPE.DATASOURCE) {
|
|
||||||
FolderItem folderItem = logManager.dsTypeInfo(bottomPositionValue.toString());
|
|
||||||
List<FolderItem> items = new ArrayList<>();
|
|
||||||
items.add(folderItem);
|
|
||||||
sysLogDTO.setPositions(items);
|
|
||||||
} else {
|
|
||||||
List<FolderItem> parentsAndSelf = logManager.parentsAndSelf(bottomPositionValue.toString(), sourcetype);
|
|
||||||
sysLogDTO.setPositions(parentsAndSelf);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 填充资源目标位置信息
|
|
||||||
int targetIndex = deLog.targetIndex();
|
|
||||||
if (targetIndex > -1 && args.length > targetIndex) {
|
|
||||||
String targetKey = deLog.targetKey();
|
|
||||||
Object targetArg = args[targetIndex];
|
|
||||||
SysLogConstants.SOURCE_TYPE targetType = deLog.targetType();
|
|
||||||
Object bottomTargetValue = AopUtils.getParamValue(targetArg, targetKey, 0);
|
|
||||||
if (ObjectUtils.isNotEmpty(bottomTargetValue)) {
|
|
||||||
List<FolderItem> parentsAndSelf = logManager.parentsAndSelf(bottomTargetValue.toString(), targetType);
|
|
||||||
sysLogDTO.setRemarks(parentsAndSelf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sysLogDTO;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Around(value = "@annotation(io.dataease.auth.annotation.DeLog)")
|
|
||||||
public Object logAround(ProceedingJoinPoint point) throws Throwable {
|
|
||||||
SysLogDTO logDTO = null;
|
|
||||||
Object result = null;
|
|
||||||
DeLog log = getLog(point);
|
|
||||||
if (before.contains(log.operatetype().getValue())) {
|
|
||||||
// 前置处理 比如删除操作 需要在数据删除之前查询
|
|
||||||
logDTO = exec(point, log);
|
|
||||||
result = point.proceed(point.getArgs());
|
|
||||||
} else {
|
|
||||||
// 后置处理 比如保存操作 需要在保存之后才有主键
|
|
||||||
result = point.proceed(point.getArgs());
|
|
||||||
logDTO = exec(point, log);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ObjectUtils.isNotEmpty(result) && result instanceof ResultHolder && !((ResultHolder) result).isSuccess()) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
Optional.ofNullable(logDTO).ifPresent(logService::saveLog);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private DeLog getLog(JoinPoint point) {
|
|
||||||
MethodSignature ms = (MethodSignature) point.getSignature();
|
|
||||||
Method method = ms.getMethod();
|
|
||||||
return method.getAnnotation(DeLog.class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,164 +0,0 @@
|
|||||||
package io.dataease.auth.aop;
|
|
||||||
|
|
||||||
import io.dataease.auth.annotation.DePermission;
|
|
||||||
import io.dataease.auth.annotation.DePermissions;
|
|
||||||
import io.dataease.auth.entity.AuthItem;
|
|
||||||
import io.dataease.auth.util.ReflectUtil;
|
|
||||||
import io.dataease.commons.constants.DePermissionType;
|
|
||||||
import io.dataease.commons.utils.AuthUtils;
|
|
||||||
import io.dataease.dto.log.FolderItem;
|
|
||||||
import io.dataease.i18n.Translator;
|
|
||||||
import io.dataease.service.sys.log.LogManager;
|
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.shiro.authz.UnauthorizedException;
|
|
||||||
import org.apache.shiro.authz.annotation.Logical;
|
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
|
||||||
import org.aspectj.lang.annotation.Around;
|
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
|
||||||
import org.aspectj.lang.reflect.MethodSignature;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.lang.reflect.Array;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Aspect
|
|
||||||
@Component
|
|
||||||
public class DePermissionAnnotationHandler {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private LogManager logManager;
|
|
||||||
|
|
||||||
@Around(value = "@annotation(io.dataease.auth.annotation.DePermissions)")
|
|
||||||
public Object PermissionsAround(ProceedingJoinPoint point) throws Throwable {
|
|
||||||
|
|
||||||
if (AuthUtils.getUser().getIsAdmin()) {
|
|
||||||
return point.proceed(point.getArgs());
|
|
||||||
}
|
|
||||||
Boolean access = false;
|
|
||||||
MethodSignature ms = (MethodSignature) point.getSignature();
|
|
||||||
Method method = ms.getMethod();
|
|
||||||
DePermissions annotation = method.getAnnotation(DePermissions.class);
|
|
||||||
Logical logical = annotation.logical();
|
|
||||||
DePermission[] dePermissions = annotation.value();
|
|
||||||
Object[] args = point.getArgs();
|
|
||||||
if (logical == Logical.AND) {
|
|
||||||
access = true;
|
|
||||||
for (int i = 0; i < dePermissions.length; i++) {
|
|
||||||
DePermission permission = dePermissions[i];
|
|
||||||
boolean currentAccess = access(args[permission.paramIndex()], permission, 0);
|
|
||||||
if (!currentAccess) {
|
|
||||||
access = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
List<Exception> exceptions = new ArrayList<>();
|
|
||||||
for (int i = 0; i < dePermissions.length; i++) {
|
|
||||||
DePermission permission = dePermissions[i];
|
|
||||||
try {
|
|
||||||
boolean currentAccess = access(args[permission.paramIndex()], permission, 0);
|
|
||||||
if (currentAccess) {
|
|
||||||
access = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
exceptions.add(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!access && exceptions.size() > 0) {
|
|
||||||
throw exceptions.get(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return access ? point.proceed(point.getArgs()) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Around(value = "@annotation(io.dataease.auth.annotation.DePermission)")
|
|
||||||
public Object PermissionAround(ProceedingJoinPoint point) throws Throwable {
|
|
||||||
Boolean access = false;
|
|
||||||
|
|
||||||
if (AuthUtils.getUser().getIsAdmin()) {
|
|
||||||
return point.proceed(point.getArgs());
|
|
||||||
}
|
|
||||||
MethodSignature ms = (MethodSignature) point.getSignature();
|
|
||||||
Method method = ms.getMethod();
|
|
||||||
DePermission annotation = method.getAnnotation(DePermission.class);
|
|
||||||
Object arg = point.getArgs()[annotation.paramIndex()];
|
|
||||||
if (access(arg, annotation, 0)) {
|
|
||||||
access = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return access ? point.proceed(point.getArgs()) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Boolean access(Object arg, DePermission annotation, int layer) throws Exception {
|
|
||||||
if (ObjectUtils.isEmpty(arg))
|
|
||||||
return true;
|
|
||||||
String type = annotation.type().name().toLowerCase();
|
|
||||||
String value = annotation.value();
|
|
||||||
Integer requireLevel = annotation.level().getLevel();
|
|
||||||
Set<String> resourceIds = AuthUtils.permissionByType(type).stream().filter(
|
|
||||||
item -> item.getLevel() >= requireLevel).map(AuthItem::getAuthSource).collect(Collectors.toSet());
|
|
||||||
Class<?> parameterType = arg.getClass();
|
|
||||||
if (parameterType.isPrimitive() || ReflectUtil.isWrapClass(parameterType) || ReflectUtil.isString(parameterType)) {
|
|
||||||
boolean permissionValid = resourceIds.contains(arg);
|
|
||||||
if (permissionValid)
|
|
||||||
return true;
|
|
||||||
throw new UnauthorizedException(msgI18n(arg, annotation));
|
|
||||||
} else if (ReflectUtil.isArray(parameterType)) {
|
|
||||||
for (int i = 0; i < Array.getLength(arg); i++) {
|
|
||||||
Object o = Array.get(arg, i);
|
|
||||||
if (!access(o, annotation, layer)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (ReflectUtil.isCollection(parameterType)) {
|
|
||||||
Object[] array = ((Collection) arg).toArray();
|
|
||||||
for (int i = 0; i < array.length; i++) {
|
|
||||||
Object o = array[i];
|
|
||||||
if (!access(o, annotation, layer)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (ReflectUtil.isMap(parameterType)) {
|
|
||||||
Map<String, Object> argMap = (Map) arg;
|
|
||||||
String[] values = value.split(".");
|
|
||||||
Object o = argMap.get(values[layer]);
|
|
||||||
return access(o, annotation, ++layer);
|
|
||||||
} else {
|
|
||||||
// 当作自定义类处理
|
|
||||||
String[] values = value.split("\\.");
|
|
||||||
String fieldName = values[layer];
|
|
||||||
Object fieldValue = ReflectUtil.getFieldValue(arg, fieldName);
|
|
||||||
return access(fieldValue, annotation, ++layer);
|
|
||||||
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String msgI18n(Object arg, DePermission annotation) {
|
|
||||||
int sourceTypeValue = 0;
|
|
||||||
DePermissionType type = annotation.type();
|
|
||||||
if (type == DePermissionType.DATASOURCE) {
|
|
||||||
sourceTypeValue = 1;
|
|
||||||
}
|
|
||||||
if (type == DePermissionType.DATASET) {
|
|
||||||
sourceTypeValue = 2;
|
|
||||||
}
|
|
||||||
if (type == DePermissionType.PANEL) {
|
|
||||||
sourceTypeValue = 3;
|
|
||||||
}
|
|
||||||
String name = arg.toString();
|
|
||||||
if (sourceTypeValue > 0) {
|
|
||||||
FolderItem sourceInfo = logManager.nameWithId(arg.toString(), sourceTypeValue);
|
|
||||||
if (ObjectUtils.isNotEmpty(sourceInfo))
|
|
||||||
name = StringUtils.isNotBlank(sourceInfo.getName()) ? sourceInfo.getName() : arg.toString();
|
|
||||||
}
|
|
||||||
String msg = Translator.get("I18N_NO_PERMISSION") + "[" + Translator.get("I18N_" + annotation.level().name()) + ": " + Translator.get("SOURCE_TYPE_" + annotation.type().name()) + ": " + name + "]," + Translator.get("I18N_PLEASE_CONCAT_ADMIN");
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,129 +0,0 @@
|
|||||||
package io.dataease.auth.aop;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
|
||||||
import org.aspectj.lang.annotation.Around;
|
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
|
||||||
import org.aspectj.lang.reflect.MethodSignature;
|
|
||||||
import org.springframework.core.annotation.Order;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import io.dataease.auth.annotation.DePermissionProxy;
|
|
||||||
import io.dataease.commons.utils.AuthUtils;
|
|
||||||
import io.dataease.commons.utils.LogUtil;
|
|
||||||
import io.dataease.dto.PermissionProxy;
|
|
||||||
import io.dataease.exception.DataEaseException;
|
|
||||||
|
|
||||||
@Aspect
|
|
||||||
@Component
|
|
||||||
@Order(0)
|
|
||||||
public class DePermissionProxyHandler {
|
|
||||||
|
|
||||||
@Around(value = "@annotation(io.dataease.auth.annotation.DePermissionProxy)")
|
|
||||||
public Object proxyAround(ProceedingJoinPoint point) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
MethodSignature ms = (MethodSignature) point.getSignature();
|
|
||||||
Method method = ms.getMethod();
|
|
||||||
DePermissionProxy annotation = method.getAnnotation(DePermissionProxy.class);
|
|
||||||
Object[] args = point.getArgs();
|
|
||||||
if (null == args || args.length == 0) {
|
|
||||||
return point.proceed(args);
|
|
||||||
}
|
|
||||||
Object arg = point.getArgs()[annotation.paramIndex()];
|
|
||||||
PermissionProxy proxy = getProxy(arg, annotation, 0);
|
|
||||||
if (null != proxy && null != proxy.getUserId()) {
|
|
||||||
AuthUtils.setProxyUser(proxy.getUserId());
|
|
||||||
}
|
|
||||||
return point.proceed(args);
|
|
||||||
} catch (Throwable throwable) {
|
|
||||||
LogUtil.error(throwable.getMessage(), throwable);
|
|
||||||
DataEaseException.throwException(throwable);
|
|
||||||
} finally {
|
|
||||||
AuthUtils.cleanProxyUser();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private PermissionProxy getProxy(Object arg, DePermissionProxy annotation, int layer) throws Exception {
|
|
||||||
if (null == arg)
|
|
||||||
return null;
|
|
||||||
String value = annotation.value();
|
|
||||||
Class<?> parameterType = arg.getClass();
|
|
||||||
if (arg instanceof PermissionProxy) {
|
|
||||||
return (PermissionProxy) arg;
|
|
||||||
} else if (isArray(parameterType)) {
|
|
||||||
return null;
|
|
||||||
} else if (isCollection(parameterType)) {
|
|
||||||
return null;
|
|
||||||
} else if (isMap(parameterType)) {
|
|
||||||
Map<String, Object> argMap = (Map) arg;
|
|
||||||
String[] values = value.split(".");
|
|
||||||
Object o = argMap.get(values[layer]);
|
|
||||||
return getProxy(o, annotation, ++layer);
|
|
||||||
} else {
|
|
||||||
// 当作自定义类处理
|
|
||||||
String[] values = value.split("\\.");
|
|
||||||
String fieldName = values[layer];
|
|
||||||
Object fieldValue = getFieldValue(arg, fieldName);
|
|
||||||
return getProxy(fieldValue, annotation, ++layer);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object getFieldValue(Object o, String fieldName) throws Exception {
|
|
||||||
Class<?> aClass = o.getClass();
|
|
||||||
while (null != aClass.getSuperclass()) {
|
|
||||||
Field[] declaredFields = aClass.getDeclaredFields();
|
|
||||||
for (int i = 0; i < declaredFields.length; i++) {
|
|
||||||
Field field = declaredFields[i];
|
|
||||||
String name = field.getName();
|
|
||||||
if (StringUtils.equals(name, fieldName)) {
|
|
||||||
field.setAccessible(true);
|
|
||||||
return field.get(o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
aClass = aClass.getSuperclass();
|
|
||||||
}
|
|
||||||
throw new NoSuchFieldException(fieldName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final static String[] wrapClasies = {
|
|
||||||
"java.lang.Boolean",
|
|
||||||
"java.lang.Character",
|
|
||||||
"java.lang.Integer",
|
|
||||||
"java.lang.Byte",
|
|
||||||
"java.lang.Short",
|
|
||||||
"java.lang.Long",
|
|
||||||
"java.lang.Float",
|
|
||||||
"java.lang.Double",
|
|
||||||
};
|
|
||||||
|
|
||||||
private Boolean isString(Class clz) {
|
|
||||||
return StringUtils.equals("java.lang.String", clz.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Boolean isArray(Class clz) {
|
|
||||||
return clz.isArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Boolean isCollection(Class clz) {
|
|
||||||
return Collection.class.isAssignableFrom(clz);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Boolean isMap(Class clz) {
|
|
||||||
return Map.class.isAssignableFrom(clz);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Boolean isWrapClass(Class clz) {
|
|
||||||
return Arrays.stream(wrapClasies).anyMatch(item -> StringUtils.equals(item, clz.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
package io.dataease.auth.aop;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import io.dataease.auth.annotation.DeRateLimiter;
|
|
||||||
import io.dataease.auth.service.DeLimitService;
|
|
||||||
import io.dataease.commons.utils.IPUtils;
|
|
||||||
import io.dataease.commons.utils.ServletUtils;
|
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
|
||||||
import org.aspectj.lang.annotation.Around;
|
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
|
||||||
import org.aspectj.lang.reflect.MethodSignature;
|
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
@Aspect
|
|
||||||
@Component
|
|
||||||
public class DeRateLimiterHandler {
|
|
||||||
|
|
||||||
private final static String SEPARATOR = ":";
|
|
||||||
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private DeLimitService deLimitService;
|
|
||||||
|
|
||||||
|
|
||||||
@Around(value = "@annotation(io.dataease.auth.annotation.DeRateLimiter)")
|
|
||||||
public Object around(ProceedingJoinPoint point) throws Throwable {
|
|
||||||
MethodSignature signature = (MethodSignature) point.getSignature();
|
|
||||||
Method method = signature.getMethod();
|
|
||||||
DeRateLimiter rateLimiter = AnnotationUtils.findAnnotation(method, DeRateLimiter.class);
|
|
||||||
if (rateLimiter != null) {
|
|
||||||
String key = rateLimiter.key();
|
|
||||||
if (StrUtil.isBlank(key)) {
|
|
||||||
key = method.getDeclaringClass().getName() + StrUtil.DOT + method.getName();
|
|
||||||
}
|
|
||||||
key = key + SEPARATOR + IPUtils.get();
|
|
||||||
|
|
||||||
long max = rateLimiter.max();
|
|
||||||
long timeout = rateLimiter.timeout();
|
|
||||||
TimeUnit timeUnit = rateLimiter.timeUnit();
|
|
||||||
Boolean limited = deLimitService.checkRestricted(key, max, timeout, timeUnit);
|
|
||||||
if (limited) {
|
|
||||||
String msg = "The current API [%s] is limited, please try again later!";
|
|
||||||
String requestURI = ServletUtils.request().getRequestURI();
|
|
||||||
throw new RuntimeException(String.format(msg, requestURI));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return point.proceed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
package io.dataease.auth.aop;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
|
||||||
import io.dataease.auth.annotation.SqlInjectValidator;
|
|
||||||
import io.dataease.commons.exception.DEException;
|
|
||||||
import io.dataease.plugins.common.request.KeywordRequest;
|
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
|
||||||
import org.aspectj.lang.Signature;
|
|
||||||
import org.aspectj.lang.annotation.Around;
|
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
|
||||||
import org.aspectj.lang.reflect.MethodSignature;
|
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
@Aspect
|
|
||||||
public class SqlInjectAop {
|
|
||||||
|
|
||||||
@Around(value = "@annotation(io.dataease.auth.annotation.SqlInjectValidator)")
|
|
||||||
public Object around(ProceedingJoinPoint point) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
Signature signature = point.getSignature();
|
|
||||||
MethodSignature methodSignature = (MethodSignature) signature;
|
|
||||||
Method method = methodSignature.getMethod();
|
|
||||||
Object[] args = point.getArgs();
|
|
||||||
if (args == null || args.length == 0) {
|
|
||||||
return point.proceed();
|
|
||||||
}
|
|
||||||
KeywordRequest request = null;
|
|
||||||
for (int i = 0; i < args.length; i++) {
|
|
||||||
if (args[i] instanceof KeywordRequest) {
|
|
||||||
request = (KeywordRequest) args[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (request == null) return point.proceed(args);
|
|
||||||
SqlInjectValidator annotation = AnnotationUtils.findAnnotation(method, SqlInjectValidator.class);
|
|
||||||
String[] value = annotation.value();
|
|
||||||
boolean illegal = isIllegal(value, request.getOrders());
|
|
||||||
if (illegal) {
|
|
||||||
DEException.throwException("Illegal sort exp");
|
|
||||||
}
|
|
||||||
return point.proceed(args);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isIllegal(String[] value, List<String> orderList) {
|
|
||||||
if (CollectionUtils.isEmpty(orderList) || ArrayUtil.isEmpty(value)) return false;
|
|
||||||
Set<String> wordList = Arrays.stream(value).collect(Collectors.toSet());
|
|
||||||
wordList.add("asc");
|
|
||||||
wordList.add("desc");
|
|
||||||
|
|
||||||
return orderList.stream().anyMatch(exp ->
|
|
||||||
Arrays.stream(exp.toLowerCase().split(",")).anyMatch(word ->
|
|
||||||
Arrays.stream(word.split(" ")).anyMatch(item ->
|
|
||||||
StringUtils.isNotBlank(item.trim()) && !wordList.contains(item.trim()))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,97 +0,0 @@
|
|||||||
package io.dataease.auth.api;
|
|
||||||
|
|
||||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
|
||||||
import io.dataease.auth.api.dto.CurrentUserDto;
|
|
||||||
import io.dataease.auth.api.dto.LoginDto;
|
|
||||||
import io.dataease.auth.api.dto.SeizeLoginDto;
|
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import springfox.documentation.annotations.ApiIgnore;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Api(tags = "登录:登录管理")
|
|
||||||
@ApiSupport(order = 10)
|
|
||||||
@RequestMapping("/api/auth")
|
|
||||||
public interface AuthApi {
|
|
||||||
|
|
||||||
@ApiOperation("登录")
|
|
||||||
@PostMapping("/login")
|
|
||||||
Object login(LoginDto loginDto) throws Exception;
|
|
||||||
|
|
||||||
@ApiOperation("移动端登录")
|
|
||||||
@PostMapping("/mobileLogin")
|
|
||||||
Object mobileLogin(LoginDto loginDto) throws Exception;
|
|
||||||
|
|
||||||
@PostMapping("/seizeLogin")
|
|
||||||
Object seizeLogin(SeizeLoginDto loginDto) throws Exception;
|
|
||||||
|
|
||||||
@ApiOperation("获取用户信息")
|
|
||||||
@PostMapping("/userInfo")
|
|
||||||
CurrentUserDto userInfo();
|
|
||||||
|
|
||||||
@ApiOperation("是否使用初始密码")
|
|
||||||
@PostMapping("/useInitPwd")
|
|
||||||
Boolean useInitPwd();
|
|
||||||
|
|
||||||
@ApiOperation("不再提示修改密码")
|
|
||||||
@PostMapping("/removeNoti")
|
|
||||||
void removeNoti();
|
|
||||||
|
|
||||||
@ApiOperation("用户初始密码")
|
|
||||||
@PostMapping("/defaultPwd")
|
|
||||||
String defaultPwd();
|
|
||||||
|
|
||||||
@ApiOperation("登出")
|
|
||||||
@PostMapping("/logout")
|
|
||||||
String logout();
|
|
||||||
|
|
||||||
@ApiIgnore
|
|
||||||
@PostMapping("/deLogout")
|
|
||||||
String deLogout();
|
|
||||||
|
|
||||||
@ApiOperation("验证账号")
|
|
||||||
@PostMapping("/validateName")
|
|
||||||
Boolean validateName(Map<String, String> nameDto);
|
|
||||||
|
|
||||||
@ApiOperation("是否开启ldap")
|
|
||||||
@PostMapping("/isOpenLdap")
|
|
||||||
boolean isOpenLdap();
|
|
||||||
|
|
||||||
@ApiOperation("是否开启oidc")
|
|
||||||
@PostMapping("/isOpenOidc")
|
|
||||||
boolean isOpenOidc();
|
|
||||||
|
|
||||||
@ApiOperation("是否开启cas")
|
|
||||||
@PostMapping("/isOpenCas")
|
|
||||||
boolean isOpenCas();
|
|
||||||
|
|
||||||
|
|
||||||
@ApiOperation("是否开启企业微信")
|
|
||||||
@PostMapping("/isOpenWecom")
|
|
||||||
boolean isOpenWecom();
|
|
||||||
|
|
||||||
@ApiOperation("是否开启钉钉")
|
|
||||||
@PostMapping("/isOpenDingtalk")
|
|
||||||
boolean isOpenDingtalk();
|
|
||||||
|
|
||||||
@ApiOperation("是否开启飞书")
|
|
||||||
@PostMapping("/isOpenLark")
|
|
||||||
boolean isOpenLark();
|
|
||||||
|
|
||||||
@ApiOperation("是否开启国际飞书")
|
|
||||||
@PostMapping("/isOpenLarksuite")
|
|
||||||
boolean isOpenLarksuite();
|
|
||||||
|
|
||||||
@ApiIgnore
|
|
||||||
@PostMapping("/isPluginLoaded")
|
|
||||||
boolean isPluginLoaded();
|
|
||||||
|
|
||||||
@ApiIgnore
|
|
||||||
@GetMapping("/getPublicKey")
|
|
||||||
String getPublicKey();
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
package io.dataease.auth.api;
|
|
||||||
|
|
||||||
|
|
||||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
|
||||||
import io.dataease.auth.api.dto.DynamicMenuDto;
|
|
||||||
import io.dataease.controller.handler.annotation.I18n;
|
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Api(tags = "登录:动态菜单")
|
|
||||||
@ApiSupport(order = 20)
|
|
||||||
@RequestMapping("/api/dynamicMenu")
|
|
||||||
public interface DynamicMenuApi {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据heads中获取的token 获取username 获取对应权限的菜单
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@ApiOperation("查询")
|
|
||||||
@PostMapping("/menus")
|
|
||||||
@I18n
|
|
||||||
List<DynamicMenuDto> menus();
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
package io.dataease.auth.api.dto;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class CurrentRoleDto implements Serializable {
|
|
||||||
|
|
||||||
@ApiModelProperty("ID")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@ApiModelProperty("名称")
|
|
||||||
private String name;
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
package io.dataease.auth.api.dto;
|
|
||||||
|
|
||||||
import io.dataease.auth.entity.SysUserEntity;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@NoArgsConstructor
|
|
||||||
public class CurrentUserDto extends SysUserEntity implements Serializable {
|
|
||||||
|
|
||||||
@ApiModelProperty("角色集合")
|
|
||||||
private List<CurrentRoleDto> roles;
|
|
||||||
|
|
||||||
@ApiModelProperty("权限集合")
|
|
||||||
private List<String> permissions;
|
|
||||||
|
|
||||||
public CurrentUserDto(String username, String nickName) {
|
|
||||||
super.setUsername(username);
|
|
||||||
super.setNickName(nickName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
package io.dataease.auth.api.dto;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class DynamicMenuDto implements Serializable {
|
|
||||||
|
|
||||||
@ApiModelProperty("路径")
|
|
||||||
private String path;
|
|
||||||
@ApiModelProperty("组件")
|
|
||||||
private String component;
|
|
||||||
@ApiModelProperty("重定向")
|
|
||||||
private String redirect;
|
|
||||||
@ApiModelProperty("名称")
|
|
||||||
private String name;
|
|
||||||
@ApiModelProperty("元数据")
|
|
||||||
private MenuMeta meta;
|
|
||||||
@ApiModelProperty("父ID")
|
|
||||||
private Long pid;
|
|
||||||
@ApiModelProperty("ID")
|
|
||||||
private Long id;
|
|
||||||
@ApiModelProperty("权限")
|
|
||||||
private String permission;
|
|
||||||
@ApiModelProperty("是否隐藏")
|
|
||||||
private Boolean hidden;
|
|
||||||
@ApiModelProperty("类型")
|
|
||||||
private Integer type;
|
|
||||||
@ApiModelProperty("菜单序号")
|
|
||||||
private Integer menuSort;
|
|
||||||
@ApiModelProperty("是否插件")
|
|
||||||
private Boolean isPlugin;
|
|
||||||
@ApiModelProperty(hidden = true)
|
|
||||||
private Boolean noLayout;
|
|
||||||
@ApiModelProperty("子节点")
|
|
||||||
private List<DynamicMenuDto> children;
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
package io.dataease.auth.api.dto;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class LoginDto implements Serializable {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "账号", required = true)
|
|
||||||
private String username;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "密码", required = true)
|
|
||||||
private String password;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 0: 默认登录
|
|
||||||
* 1:ldap登录
|
|
||||||
* 2:单点登录
|
|
||||||
*/
|
|
||||||
@ApiModelProperty(value = "登录方式{0:普通登录, 1:ldap登录}", required = true, allowableValues = "0, 1")
|
|
||||||
private int loginType;
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
package io.dataease.auth.api.dto;
|
|
||||||
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class MenuMeta implements Serializable {
|
|
||||||
@ApiModelProperty("标题")
|
|
||||||
private String title;
|
|
||||||
@ApiModelProperty("图标")
|
|
||||||
private String icon;
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
package io.dataease.auth.api.dto;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class SeizeLoginDto implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = -3318473577764636483L;
|
|
||||||
|
|
||||||
private String token;
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package io.dataease.auth.config;
|
|
||||||
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.web.cors.CorsConfiguration;
|
|
||||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
|
||||||
import org.springframework.web.filter.CorsFilter;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class CorsConfig {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public CorsFilter corsFilter() {
|
|
||||||
CorsConfiguration corsConfiguration = new CorsConfiguration();
|
|
||||||
//1,允许任何来源
|
|
||||||
corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*"));
|
|
||||||
//2,允许任何请求头
|
|
||||||
corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
|
|
||||||
//3,允许任何方法
|
|
||||||
corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
|
|
||||||
//4,允许凭证
|
|
||||||
corsConfiguration.setAllowCredentials(true);
|
|
||||||
|
|
||||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
|
||||||
source.registerCorsConfiguration("/**", corsConfiguration);
|
|
||||||
return new CorsFilter(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,136 +0,0 @@
|
|||||||
package io.dataease.auth.config;
|
|
||||||
|
|
||||||
import io.dataease.auth.api.dto.CurrentRoleDto;
|
|
||||||
import io.dataease.auth.api.dto.CurrentUserDto;
|
|
||||||
import io.dataease.auth.entity.ASKToken;
|
|
||||||
import io.dataease.auth.entity.JWTToken;
|
|
||||||
import io.dataease.auth.entity.SysUserEntity;
|
|
||||||
import io.dataease.auth.entity.TokenInfo;
|
|
||||||
import io.dataease.auth.handler.ApiKeyHandler;
|
|
||||||
import io.dataease.auth.service.AuthUserService;
|
|
||||||
import io.dataease.auth.util.JWTUtils;
|
|
||||||
import io.dataease.commons.utils.BeanUtils;
|
|
||||||
import io.dataease.commons.utils.LogUtil;
|
|
||||||
import io.dataease.commons.utils.TokenCacheUtils;
|
|
||||||
import io.dataease.listener.util.CacheUtils;
|
|
||||||
import org.apache.shiro.authc.*;
|
|
||||||
import org.apache.shiro.authz.AuthorizationInfo;
|
|
||||||
import org.apache.shiro.authz.SimpleAuthorizationInfo;
|
|
||||||
import org.apache.shiro.realm.AuthorizingRealm;
|
|
||||||
import org.apache.shiro.subject.PrincipalCollection;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.Lazy;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class F2CRealm extends AuthorizingRealm {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
@Lazy // shiro组件加载过早 让authUserService等一等再注入 否则 注入的可能不是代理对象
|
|
||||||
private AuthUserService authUserService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supports(AuthenticationToken token) {
|
|
||||||
return token instanceof JWTToken || token instanceof ASKToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证资源权限
|
|
||||||
@Override
|
|
||||||
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
|
|
||||||
CurrentUserDto userDto = (CurrentUserDto) principals.getPrimaryPrincipal();
|
|
||||||
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
|
|
||||||
Set<String> role = new HashSet<>(
|
|
||||||
userDto.getRoles().stream().map(item -> (item.getId() + "")).collect(Collectors.toSet()));
|
|
||||||
simpleAuthorizationInfo.addRoles(role);
|
|
||||||
Set<String> permission = new HashSet<>(userDto.getPermissions());
|
|
||||||
simpleAuthorizationInfo.addStringPermissions(permission);
|
|
||||||
return simpleAuthorizationInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证登录权限
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
|
|
||||||
|
|
||||||
if (auth instanceof ASKToken) {
|
|
||||||
if (!authUserService.pluginLoaded()) {
|
|
||||||
throw new AuthenticationException("license error");
|
|
||||||
}
|
|
||||||
|
|
||||||
Object accessKey = auth.getPrincipal();
|
|
||||||
Object signature = auth.getCredentials();
|
|
||||||
Long userId = ApiKeyHandler.getUser(accessKey.toString(), signature.toString());
|
|
||||||
|
|
||||||
SysUserEntity userEntity = userWithId(userId);
|
|
||||||
CurrentUserDto currentUserDto = queryCacheUserDto(userEntity);
|
|
||||||
return new SimpleAuthenticationInfo(currentUserDto, signature, "f2cReam");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
CacheUtils.get("lic_info", "lic");
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogUtil.error(e);
|
|
||||||
throw new AuthenticationException("license error");
|
|
||||||
}
|
|
||||||
|
|
||||||
TokenInfo tokenInfo;
|
|
||||||
String token;
|
|
||||||
try {
|
|
||||||
token = (String) auth.getCredentials();
|
|
||||||
// 解密获得username,用于和数据库进行对比
|
|
||||||
tokenInfo = JWTUtils.tokenInfoByToken(token);
|
|
||||||
if (TokenCacheUtils.invalid(token)) {
|
|
||||||
throw new AuthenticationException("token invalid");
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new AuthenticationException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
Long userId = tokenInfo.getUserId();
|
|
||||||
String username = tokenInfo.getUsername();
|
|
||||||
if (username == null) {
|
|
||||||
throw new AuthenticationException("token invalid");
|
|
||||||
}
|
|
||||||
|
|
||||||
SysUserEntity user = userWithId(userId);
|
|
||||||
String pass = null;
|
|
||||||
try {
|
|
||||||
pass = user.getPassword();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
if (!JWTUtils.verify(token, tokenInfo, pass)) {
|
|
||||||
throw new AuthenticationException("Username or password error");
|
|
||||||
}
|
|
||||||
|
|
||||||
CurrentUserDto currentUserDto = queryCacheUserDto(user);
|
|
||||||
return new SimpleAuthenticationInfo(currentUserDto, token, "f2cReam");
|
|
||||||
}
|
|
||||||
|
|
||||||
public SysUserEntity userWithId(Long userId) {
|
|
||||||
SysUserEntity user = authUserService.getUserById(userId);
|
|
||||||
if (user == null) {
|
|
||||||
throw new AuthenticationException("User didn't existed!");
|
|
||||||
}
|
|
||||||
if (user.getEnabled() == 0) {
|
|
||||||
throw new AuthenticationException("User is valid!");
|
|
||||||
}
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CurrentUserDto queryCacheUserDto(SysUserEntity user) {
|
|
||||||
// 使用缓存
|
|
||||||
List<CurrentRoleDto> currentRoleDtos = authUserService.roleInfos(user.getUserId());
|
|
||||||
// 使用缓存
|
|
||||||
List<String> permissions = authUserService.permissions(user.getUserId());
|
|
||||||
CurrentUserDto currentUserDto = BeanUtils.copyBean(new CurrentUserDto(), user);
|
|
||||||
currentUserDto.setRoles(currentRoleDtos);
|
|
||||||
currentUserDto.setPermissions(permissions);
|
|
||||||
return currentUserDto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
package io.dataease.auth.config;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@Component
|
|
||||||
public class RsaProperties {
|
|
||||||
|
|
||||||
public static String privateKey;
|
|
||||||
|
|
||||||
public static String publicKey;
|
|
||||||
|
|
||||||
@Value("${rsa.private_key}")
|
|
||||||
public void setPrivateKey(String privateKey) {
|
|
||||||
RsaProperties.privateKey = privateKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Value("${rsa.public_key}")
|
|
||||||
public void setPublicKey(String publicKey) {
|
|
||||||
RsaProperties.publicKey = publicKey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
package io.dataease.auth.config;
|
|
||||||
|
|
||||||
|
|
||||||
import io.dataease.auth.service.ShiroService;
|
|
||||||
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
|
|
||||||
import org.apache.shiro.mgt.DefaultSubjectDAO;
|
|
||||||
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
|
|
||||||
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
|
|
||||||
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
|
||||||
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
|
|
||||||
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import javax.servlet.Filter;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import io.dataease.auth.filter.*;
|
|
||||||
import org.springframework.context.annotation.DependsOn;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class ShiroConfig {
|
|
||||||
|
|
||||||
@Bean("securityManager")
|
|
||||||
public DefaultWebSecurityManager getManager(F2CRealm f2cRealm) {
|
|
||||||
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
|
|
||||||
// 使用自己的realm
|
|
||||||
manager.setRealm(f2cRealm);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 关闭shiro自带的session,详情见文档
|
|
||||||
* http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29
|
|
||||||
*/
|
|
||||||
DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
|
|
||||||
DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
|
|
||||||
defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
|
|
||||||
subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
|
|
||||||
manager.setSubjectDAO(subjectDAO);
|
|
||||||
|
|
||||||
return manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean("shiroFilter")
|
|
||||||
public ShiroFilterFactoryBean factory(DefaultWebSecurityManager securityManager, ShiroService shiroService) {
|
|
||||||
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
|
|
||||||
// 添加自己的过滤器并且取名为jwt
|
|
||||||
Map<String, Filter> filterMap = new LinkedHashMap<>();
|
|
||||||
filterMap.put("f2cPerms", new F2CPermissionsFilter());
|
|
||||||
filterMap.put("jwt", new JWTFilter());
|
|
||||||
filterMap.put("logout", new F2CLogoutFilter());
|
|
||||||
filterMap.put("link", new F2CLinkFilter());
|
|
||||||
filterMap.put("doc", new F2CDocFilter());
|
|
||||||
factoryBean.setSecurityManager(securityManager);
|
|
||||||
factoryBean.setLoginUrl("/login");
|
|
||||||
factoryBean.setUnauthorizedUrl("/login");
|
|
||||||
factoryBean.setFilterChainDefinitionMap(shiroService.loadFilterChainDefinitionMap());
|
|
||||||
factoryBean.setFilters(filterMap);
|
|
||||||
return factoryBean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下面的代码是添加注解支持
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
@DependsOn("lifecycleBeanPostProcessor")
|
|
||||||
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
|
|
||||||
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
|
|
||||||
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
|
|
||||||
return defaultAdvisorAutoProxyCreator;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
|
|
||||||
return new LifecycleBeanPostProcessor();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
|
|
||||||
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
|
|
||||||
advisor.setSecurityManager(securityManager);
|
|
||||||
return advisor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,77 +0,0 @@
|
|||||||
package io.dataease.auth.config.cas;
|
|
||||||
|
|
||||||
import io.dataease.auth.service.impl.ShiroServiceImpl;
|
|
||||||
import io.dataease.commons.utils.CommonBeanFactory;
|
|
||||||
import io.dataease.commons.utils.ServletUtils;
|
|
||||||
import io.dataease.service.system.SystemParameterService;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.shiro.util.AntPathMatcher;
|
|
||||||
import org.jasig.cas.client.authentication.UrlPatternMatcherStrategy;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class CasStrategy implements UrlPatternMatcherStrategy {
|
|
||||||
|
|
||||||
|
|
||||||
private static Set<String> releaseTypes = new HashSet<>();
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void init() {
|
|
||||||
releaseTypes.add("anon");
|
|
||||||
releaseTypes.add("link");
|
|
||||||
releaseTypes.add("doc");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(String s) {
|
|
||||||
SystemParameterService service = CommonBeanFactory.getBean(SystemParameterService.class);
|
|
||||||
String serviceValue = service.getValue("cas.callBack");
|
|
||||||
if (StringUtils.isBlank(serviceValue)) return false;
|
|
||||||
String serverName = serviceValue.substring(0, serviceValue.indexOf("/cas/callBack"));
|
|
||||||
int beginIndex = -1;
|
|
||||||
if ((beginIndex = s.indexOf(serverName)) != -1) {
|
|
||||||
s = s.substring(beginIndex + serverName.length());
|
|
||||||
}
|
|
||||||
if (StringUtils.equals("/", s)) {
|
|
||||||
if (fromLink(serverName)) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (StringUtils.equals("/login", s)) return false;
|
|
||||||
if (StringUtils.startsWith(s, "/cas/callBack")) return false;
|
|
||||||
if (StringUtils.equals("/api/auth/deLogout", s)) return true;
|
|
||||||
if (s.startsWith("/link.html")) return true;
|
|
||||||
AntPathMatcher antPathMatcher = new AntPathMatcher();
|
|
||||||
ShiroServiceImpl shiroService = CommonBeanFactory.getBean(ShiroServiceImpl.class);
|
|
||||||
Map<String, String> stringStringMap = shiroService.loadFilterChainDefinitionMap();
|
|
||||||
for (Map.Entry<String, String> entry : stringStringMap.entrySet()) {
|
|
||||||
if (releaseTypes.contains(entry.getValue())) {
|
|
||||||
boolean matches = antPathMatcher.matches(entry.getKey(), s);
|
|
||||||
if (matches) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPattern(String s) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Boolean fromLink(String serverName) {
|
|
||||||
String referrer = ServletUtils.request().getHeader("referer");
|
|
||||||
if (StringUtils.isBlank(referrer)) return false;
|
|
||||||
int beginIndex = -1;
|
|
||||||
if ((beginIndex = referrer.indexOf(serverName)) != -1) {
|
|
||||||
referrer = referrer.substring(beginIndex + serverName.length());
|
|
||||||
return referrer.startsWith("/link.html");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
package io.dataease.auth.entity;
|
|
||||||
|
|
||||||
import org.apache.shiro.authc.AuthenticationToken;
|
|
||||||
|
|
||||||
public class ASKToken implements AuthenticationToken {
|
|
||||||
|
|
||||||
private String accessKey;
|
|
||||||
|
|
||||||
private String signature;
|
|
||||||
|
|
||||||
public ASKToken(String accessKey, String signature) {
|
|
||||||
this.accessKey = accessKey;
|
|
||||||
this.signature = signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getPrincipal() {
|
|
||||||
return accessKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getCredentials() {
|
|
||||||
return signature;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
package io.dataease.auth.entity;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class AccountLockStatus {
|
|
||||||
|
|
||||||
private Boolean locked = false;
|
|
||||||
|
|
||||||
private String username;
|
|
||||||
|
|
||||||
private Long unlockTime;
|
|
||||||
|
|
||||||
private Integer relieveTimes;
|
|
||||||
|
|
||||||
private Integer remainderTimes;
|
|
||||||
}
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
package io.dataease.auth.entity;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
@Data
|
|
||||||
public class AuthItem implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 7909546616315767531L;
|
|
||||||
|
|
||||||
private String authSource;
|
|
||||||
|
|
||||||
private Integer level;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
AuthItem authItem = (AuthItem) o;
|
|
||||||
return Objects.equals(authSource, authItem.authSource) &&
|
|
||||||
Objects.equals(level, authItem.level);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(authSource, level);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
package io.dataease.auth.entity;
|
|
||||||
|
|
||||||
import org.apache.shiro.authc.AuthenticationToken;
|
|
||||||
|
|
||||||
public class JWTToken implements AuthenticationToken {
|
|
||||||
|
|
||||||
private String token;
|
|
||||||
|
|
||||||
public JWTToken(String token) {
|
|
||||||
this.token = token;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getPrincipal() {
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getCredentials() {
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
package io.dataease.auth.entity;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
|
|
||||||
public class SysUserEntity implements Serializable {
|
|
||||||
|
|
||||||
@ApiModelProperty(hidden = true)
|
|
||||||
private Long userId;
|
|
||||||
|
|
||||||
@ApiModelProperty("账号")
|
|
||||||
private String username;
|
|
||||||
|
|
||||||
@ApiModelProperty("姓名")
|
|
||||||
private String nickName;
|
|
||||||
|
|
||||||
@ApiModelProperty("组织ID")
|
|
||||||
private Long deptId;
|
|
||||||
|
|
||||||
@ApiModelProperty("组织名称")
|
|
||||||
private String deptName;
|
|
||||||
|
|
||||||
@ApiModelProperty(hidden = true)
|
|
||||||
private String password;
|
|
||||||
|
|
||||||
@ApiModelProperty("状态")
|
|
||||||
private Integer enabled;
|
|
||||||
|
|
||||||
@ApiModelProperty("邮箱")
|
|
||||||
private String email;
|
|
||||||
|
|
||||||
@ApiModelProperty("电话")
|
|
||||||
private String phone;
|
|
||||||
|
|
||||||
@ApiModelProperty(hidden = true)
|
|
||||||
private String language;
|
|
||||||
|
|
||||||
@ApiModelProperty(hidden = true)
|
|
||||||
private Boolean isAdmin;
|
|
||||||
|
|
||||||
@ApiModelProperty(hidden = true)
|
|
||||||
private Integer from;
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
package io.dataease.auth.entity;
|
|
||||||
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@Builder
|
|
||||||
public class TokenInfo implements Serializable {
|
|
||||||
|
|
||||||
private String username;
|
|
||||||
|
|
||||||
private Long userId;
|
|
||||||
|
|
||||||
public String format() {
|
|
||||||
return username + "," + userId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,106 +0,0 @@
|
|||||||
package io.dataease.auth.filter;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
|
||||||
import com.auth0.jwt.algorithms.Algorithm;
|
|
||||||
import io.dataease.auth.entity.SysUserEntity;
|
|
||||||
import io.dataease.auth.entity.TokenInfo;
|
|
||||||
import io.dataease.auth.service.AuthUserService;
|
|
||||||
import io.dataease.auth.util.JWTUtils;
|
|
||||||
import io.dataease.commons.license.DefaultLicenseService;
|
|
||||||
import io.dataease.commons.license.F2CLicenseResponse;
|
|
||||||
import io.dataease.commons.utils.CommonBeanFactory;
|
|
||||||
import io.dataease.commons.utils.LogUtil;
|
|
||||||
import io.dataease.exception.DataEaseException;
|
|
||||||
import io.dataease.i18n.Translator;
|
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.shiro.web.filter.AccessControlFilter;
|
|
||||||
|
|
||||||
import javax.servlet.ServletRequest;
|
|
||||||
import javax.servlet.ServletResponse;
|
|
||||||
import javax.servlet.http.Cookie;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import static io.dataease.commons.license.F2CLicenseResponse.Status;
|
|
||||||
|
|
||||||
public class F2CDocFilter extends AccessControlFilter {
|
|
||||||
|
|
||||||
private static final String RESULT_URI_KEY = "result_uri_key";
|
|
||||||
private static final String NOLIC_PAGE = "nolic.html";
|
|
||||||
private static final String NO_LOGIN_PAGE = "/nologin.html";
|
|
||||||
private static final String DEFAULT_FAILED_PAGE = "/";
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
|
|
||||||
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
|
||||||
try {
|
|
||||||
DefaultLicenseService defaultLicenseService = CommonBeanFactory.getBean(DefaultLicenseService.class);
|
|
||||||
F2CLicenseResponse f2CLicenseResponse = defaultLicenseService.validateLicense();
|
|
||||||
Status status = f2CLicenseResponse.getStatus();
|
|
||||||
if (status != Status.valid) {
|
|
||||||
request.setAttribute(RESULT_URI_KEY, NOLIC_PAGE);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
request.setAttribute(RESULT_URI_KEY, NOLIC_PAGE);
|
|
||||||
LogUtil.error(e.getMessage(), e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Boolean isLogin = validateLogin(request);
|
|
||||||
if (!isLogin) {
|
|
||||||
request.setAttribute(RESULT_URI_KEY, NO_LOGIN_PAGE);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
request.setAttribute(RESULT_URI_KEY, NO_LOGIN_PAGE);
|
|
||||||
LogUtil.error(e.getMessage(), e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Boolean validateLogin(HttpServletRequest request) throws Exception {
|
|
||||||
String authorization = request.getHeader("Authorization");
|
|
||||||
if (StringUtils.isBlank(authorization)) {
|
|
||||||
Cookie[] cookies = request.getCookies();
|
|
||||||
if (ArrayUtil.isNotEmpty(cookies)) {
|
|
||||||
Cookie cookie = Arrays.stream(cookies).filter(item -> StringUtils.equals(item.getName(), "Authorization")).findFirst().orElse(null);
|
|
||||||
if (ObjectUtils.isNotEmpty(cookie) && StringUtils.isNotBlank(cookie.getValue())) {
|
|
||||||
authorization = cookie.getValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (StringUtils.isBlank(authorization)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
TokenInfo tokenInfo = JWTUtils.tokenInfoByToken(authorization);
|
|
||||||
AuthUserService authUserService = CommonBeanFactory.getBean(AuthUserService.class);
|
|
||||||
SysUserEntity user = authUserService.getUserById(tokenInfo.getUserId());
|
|
||||||
if (user == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
String password = user.getPassword();
|
|
||||||
boolean verify = JWTUtils.verify(authorization, tokenInfo, password);
|
|
||||||
return verify;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean onAccessDenied(ServletRequest req, ServletResponse res) throws Exception {
|
|
||||||
HttpServletResponse response = (HttpServletResponse) res;
|
|
||||||
HttpServletRequest request = (HttpServletRequest) req;
|
|
||||||
Object attribute = request.getAttribute(RESULT_URI_KEY);
|
|
||||||
String path = ObjectUtils.isNotEmpty(attribute) ? attribute.toString() : DEFAULT_FAILED_PAGE;
|
|
||||||
path += ("?_t" + System.currentTimeMillis());
|
|
||||||
response.setHeader("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate");
|
|
||||||
response.setHeader("Expires", "0");
|
|
||||||
request.getRequestDispatcher(path).forward(request, response);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
package io.dataease.auth.filter;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
|
||||||
import com.auth0.jwt.JWT;
|
|
||||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
|
||||||
import io.dataease.auth.util.JWTUtils;
|
|
||||||
import io.dataease.auth.util.LinkUtil;
|
|
||||||
import io.dataease.commons.utils.LogUtil;
|
|
||||||
import io.dataease.plugins.common.base.domain.PanelLink;
|
|
||||||
import org.apache.shiro.web.filter.authc.AnonymousFilter;
|
|
||||||
|
|
||||||
import javax.servlet.ServletRequest;
|
|
||||||
import javax.servlet.ServletResponse;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
public class F2CLinkFilter extends AnonymousFilter {
|
|
||||||
|
|
||||||
public static final String LINK_TOKEN_KEY = "LINK-PWD-TOKEN";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) {
|
|
||||||
try {
|
|
||||||
HttpServletRequest req = (HttpServletRequest) request;
|
|
||||||
String linkToken = req.getHeader(LINK_TOKEN_KEY);
|
|
||||||
DecodedJWT jwt = JWT.decode(linkToken);
|
|
||||||
String resourceId = jwt.getClaim("resourceId").asString();
|
|
||||||
Long userId = jwt.getClaim("userId").asLong();
|
|
||||||
PanelLink panelLink = LinkUtil.queryLink(resourceId, userId);
|
|
||||||
if (ObjectUtil.isEmpty(panelLink)) return false;
|
|
||||||
String pwd;
|
|
||||||
if (!panelLink.getEnablePwd()) {
|
|
||||||
panelLink.setPwd("dataease");
|
|
||||||
pwd = panelLink.getPwd();
|
|
||||||
} else {
|
|
||||||
pwd = panelLink.getPwd();
|
|
||||||
}
|
|
||||||
return JWTUtils.verifyLink(linkToken, resourceId, userId, pwd);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogUtil.error(e);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package io.dataease.auth.filter;
|
|
||||||
|
|
||||||
import org.apache.shiro.subject.Subject;
|
|
||||||
import org.apache.shiro.web.filter.authc.LogoutFilter;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.servlet.ServletRequest;
|
|
||||||
import javax.servlet.ServletResponse;
|
|
||||||
|
|
||||||
public class F2CLogoutFilter extends LogoutFilter {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(F2CLogoutFilter.class);
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
|
|
||||||
Subject subject = getSubject(request, response);
|
|
||||||
try {
|
|
||||||
subject.logout();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
logger.error("退出登录错误", ex);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
package io.dataease.auth.filter;
|
|
||||||
|
|
||||||
import org.apache.shiro.subject.Subject;
|
|
||||||
import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;
|
|
||||||
|
|
||||||
import javax.servlet.ServletRequest;
|
|
||||||
import javax.servlet.ServletResponse;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class F2CPermissionsFilter extends PermissionsAuthorizationFilter {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
|
|
||||||
Subject subject = getSubject(request, response);
|
|
||||||
String[] perms = (String[]) mappedValue;
|
|
||||||
if (perms != null && perms.length > 0) {
|
|
||||||
for (String str : perms) {
|
|
||||||
// 判断访问的用户是否拥有mappedValue权限
|
|
||||||
if (subject.isPermitted(str)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,149 +0,0 @@
|
|||||||
package io.dataease.auth.filter;
|
|
||||||
|
|
||||||
import io.dataease.auth.entity.ASKToken;
|
|
||||||
import io.dataease.auth.entity.JWTToken;
|
|
||||||
import io.dataease.auth.handler.ApiKeyHandler;
|
|
||||||
import io.dataease.commons.license.DefaultLicenseService;
|
|
||||||
import io.dataease.commons.license.F2CLicenseResponse;
|
|
||||||
import io.dataease.commons.utils.CommonBeanFactory;
|
|
||||||
import io.dataease.commons.utils.LogUtil;
|
|
||||||
import io.dataease.commons.utils.TokenCacheUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.shiro.authc.AuthenticationException;
|
|
||||||
import org.apache.shiro.subject.Subject;
|
|
||||||
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
|
|
||||||
import javax.servlet.ServletRequest;
|
|
||||||
import javax.servlet.ServletResponse;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
|
|
||||||
public class JWTFilter extends BasicHttpAuthenticationFilter {
|
|
||||||
|
|
||||||
|
|
||||||
public final static String expireMessage = "Login token is expire.";
|
|
||||||
public final static String licMessage = "license invalid";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断用户是否想要登入。
|
|
||||||
* 检测header里面是否包含Authorization字段即可
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) {
|
|
||||||
HttpServletRequest req = (HttpServletRequest) request;
|
|
||||||
String authorization = req.getHeader("Authorization");
|
|
||||||
return authorization != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
|
|
||||||
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
|
||||||
|
|
||||||
|
|
||||||
if (ApiKeyHandler.isApiKeyCall(httpServletRequest)) {
|
|
||||||
|
|
||||||
DefaultLicenseService licenseService = CommonBeanFactory.getBean(DefaultLicenseService.class);
|
|
||||||
F2CLicenseResponse licenseResponse = null;
|
|
||||||
try {
|
|
||||||
licenseResponse = licenseService.validateLicense();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new AuthenticationException(licMessage);
|
|
||||||
}
|
|
||||||
if (licenseResponse.getStatus() != F2CLicenseResponse.Status.valid) {
|
|
||||||
throw new AuthenticationException(licMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASKToken askToken = ApiKeyHandler.buildToken(httpServletRequest);
|
|
||||||
|
|
||||||
getSubject(request, response).login(askToken);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
String authorization = httpServletRequest.getHeader("Authorization");
|
|
||||||
if (StringUtils.startsWith(authorization, "Basic")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (TokenCacheUtils.invalid(authorization)) {
|
|
||||||
throw new AuthenticationException(expireMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
JWTToken token = new JWTToken(authorization);
|
|
||||||
Subject subject = getSubject(request, response);
|
|
||||||
// 提交给realm进行登入,如果错误他会抛出异常并被捕获
|
|
||||||
subject.login(token);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
|
|
||||||
// 先判断是不是api调用
|
|
||||||
HttpServletRequest hRequest = (HttpServletRequest) request;
|
|
||||||
|
|
||||||
if (isLoginAttempt(request, response) || ApiKeyHandler.isApiKeyCall(hRequest)) {
|
|
||||||
try {
|
|
||||||
boolean loginSuccess = executeLogin(request, response);
|
|
||||||
return loginSuccess;
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogUtil.error(e);
|
|
||||||
if (e instanceof AuthenticationException && StringUtils.equals(e.getMessage(), expireMessage)) {
|
|
||||||
responseExpire(request, response, e);
|
|
||||||
} else if (StringUtils.equals(licMessage, e.getMessage())) {
|
|
||||||
responseLicError(request, response, e);
|
|
||||||
} else {
|
|
||||||
tokenError(request, response, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 对跨域提供支持
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
|
|
||||||
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
|
||||||
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
|
|
||||||
httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
|
|
||||||
httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
|
|
||||||
httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
|
|
||||||
// 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态
|
|
||||||
if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
|
|
||||||
httpServletResponse.setStatus(HttpStatus.OK.value());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return super.preHandle(request, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void tokenError(ServletRequest req, ServletResponse resp, Exception e1) {
|
|
||||||
HttpServletResponse httpServletResponse = (HttpServletResponse) resp;
|
|
||||||
httpServletResponse.addHeader("Access-Control-Expose-Headers", "authentication-status");
|
|
||||||
httpServletResponse.setHeader("authentication-status", "invalid");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void responseExpire(ServletRequest req, ServletResponse resp, Exception e1) {
|
|
||||||
HttpServletResponse httpServletResponse = (HttpServletResponse) resp;
|
|
||||||
httpServletResponse.addHeader("Access-Control-Expose-Headers", "authentication-status");
|
|
||||||
httpServletResponse.setHeader("authentication-status", "login_expire");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void responseLicError(ServletRequest req, ServletResponse resp, Exception e1) {
|
|
||||||
HttpServletResponse httpServletResponse = (HttpServletResponse) resp;
|
|
||||||
httpServletResponse.addHeader("Access-Control-Expose-Headers", "authentication-status");
|
|
||||||
httpServletResponse.setHeader("authentication-status", licMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,87 +0,0 @@
|
|||||||
package io.dataease.auth.handler;
|
|
||||||
|
|
||||||
import io.dataease.auth.entity.ASKToken;
|
|
||||||
import io.dataease.commons.utils.CodingUtil;
|
|
||||||
import io.dataease.plugins.config.SpringContextUtil;
|
|
||||||
import io.dataease.plugins.xpack.ukey.dto.request.XpackUkeyDto;
|
|
||||||
import io.dataease.plugins.xpack.ukey.service.UkeyXpackService;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class ApiKeyHandler {
|
|
||||||
|
|
||||||
public static final String API_ACCESS_KEY = "accessKey";
|
|
||||||
|
|
||||||
public static final String API_SIGNATURE = "signature";
|
|
||||||
|
|
||||||
public static String random = UUID.randomUUID().toString() + UUID.randomUUID().toString();
|
|
||||||
|
|
||||||
public static Long getUser(HttpServletRequest request) {
|
|
||||||
if (request == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return getUser(request.getHeader(API_ACCESS_KEY), request.getHeader(API_SIGNATURE));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ASKToken buildToken(HttpServletRequest request) {
|
|
||||||
if (request == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String accessKey = request.getHeader(API_ACCESS_KEY);
|
|
||||||
String signature = request.getHeader(API_SIGNATURE);
|
|
||||||
ASKToken askToken = new ASKToken(accessKey, signature);
|
|
||||||
return askToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean isApiKeyCall(HttpServletRequest request) {
|
|
||||||
if (request == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (StringUtils.isBlank(request.getHeader(API_ACCESS_KEY)) || StringUtils.isBlank(request.getHeader(API_SIGNATURE))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static XpackUkeyDto ukey(String accessKey) {
|
|
||||||
UkeyXpackService ukeyXpackService = SpringContextUtil.getBean(UkeyXpackService.class);
|
|
||||||
XpackUkeyDto userKey = ukeyXpackService.getUserKey(accessKey);
|
|
||||||
return userKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Long getUser(String accessKey, String signature) {
|
|
||||||
if (StringUtils.isBlank(accessKey) || StringUtils.isBlank(signature)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
XpackUkeyDto userKey = ukey(accessKey);
|
|
||||||
if (userKey == null) {
|
|
||||||
throw new RuntimeException("invalid accessKey");
|
|
||||||
}
|
|
||||||
String signatureDecrypt;
|
|
||||||
try {
|
|
||||||
signatureDecrypt = CodingUtil.aesDecrypt(signature, userKey.getSecretKey(), accessKey);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
throw new RuntimeException("invalid signature");
|
|
||||||
}
|
|
||||||
String[] signatureArray = StringUtils.split(StringUtils.trimToNull(signatureDecrypt), "|");
|
|
||||||
if (signatureArray.length < 2) {
|
|
||||||
throw new RuntimeException("invalid signature");
|
|
||||||
}
|
|
||||||
if (!StringUtils.equals(accessKey, signatureArray[0])) {
|
|
||||||
throw new RuntimeException("invalid signature");
|
|
||||||
}
|
|
||||||
long signatureTime = 0l;
|
|
||||||
try {
|
|
||||||
signatureTime = Long.valueOf(signatureArray[signatureArray.length - 1]).longValue();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
if (Math.abs(System.currentTimeMillis() - signatureTime) > 1800000) {
|
|
||||||
//签名30分钟超时
|
|
||||||
throw new RuntimeException("expired signature");
|
|
||||||
}
|
|
||||||
return userKey.getUserId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,450 +0,0 @@
|
|||||||
package io.dataease.auth.server;
|
|
||||||
|
|
||||||
import io.dataease.auth.api.AuthApi;
|
|
||||||
import io.dataease.auth.api.dto.CurrentRoleDto;
|
|
||||||
import io.dataease.auth.api.dto.CurrentUserDto;
|
|
||||||
import io.dataease.auth.api.dto.LoginDto;
|
|
||||||
import io.dataease.auth.api.dto.SeizeLoginDto;
|
|
||||||
import io.dataease.auth.config.RsaProperties;
|
|
||||||
import io.dataease.auth.entity.AccountLockStatus;
|
|
||||||
import io.dataease.auth.entity.SysUserEntity;
|
|
||||||
import io.dataease.auth.entity.TokenInfo;
|
|
||||||
import io.dataease.auth.service.AuthUserService;
|
|
||||||
import io.dataease.auth.util.JWTUtils;
|
|
||||||
import io.dataease.auth.util.RsaUtil;
|
|
||||||
import io.dataease.commons.constants.SysLogConstants;
|
|
||||||
import io.dataease.commons.exception.DEException;
|
|
||||||
import io.dataease.commons.utils.*;
|
|
||||||
import io.dataease.controller.sys.request.LdapAddRequest;
|
|
||||||
import io.dataease.exception.DataEaseException;
|
|
||||||
import io.dataease.i18n.Translator;
|
|
||||||
import io.dataease.plugins.common.entity.XpackLdapUserEntity;
|
|
||||||
import io.dataease.plugins.config.SpringContextUtil;
|
|
||||||
import io.dataease.plugins.util.PluginUtils;
|
|
||||||
import io.dataease.plugins.xpack.cas.service.CasXpackService;
|
|
||||||
import io.dataease.plugins.xpack.ldap.dto.request.LdapValidateRequest;
|
|
||||||
import io.dataease.plugins.xpack.ldap.dto.response.ValidateResult;
|
|
||||||
import io.dataease.plugins.xpack.ldap.service.LdapXpackService;
|
|
||||||
import io.dataease.plugins.xpack.oidc.service.OidcXpackService;
|
|
||||||
import io.dataease.service.sys.SysUserService;
|
|
||||||
|
|
||||||
import io.dataease.service.system.SystemParameterService;
|
|
||||||
import io.dataease.websocket.entity.WsMessage;
|
|
||||||
import io.dataease.websocket.service.WsService;
|
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.shiro.SecurityUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpSession;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
public class AuthServer implements AuthApi {
|
|
||||||
|
|
||||||
private static final String LDAP_EMAIL_SUFFIX = "@ldap.com";
|
|
||||||
@Value("${dataease.init_password:DataEase123..}")
|
|
||||||
private String DEFAULT_PWD;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private AuthUserService authUserService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SysUserService sysUserService;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private SystemParameterService systemParameterService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private WsService wsService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object mobileLogin(@RequestBody LoginDto loginDto) throws Exception {
|
|
||||||
String username = RsaUtil.decryptByPrivateKey(RsaProperties.privateKey, loginDto.getUsername());
|
|
||||||
String pwd = RsaUtil.decryptByPrivateKey(RsaProperties.privateKey, loginDto.getPassword());
|
|
||||||
AccountLockStatus accountLockStatus = authUserService.lockStatus(username, 0);
|
|
||||||
if (accountLockStatus.getLocked()) {
|
|
||||||
String msg = Translator.get("I18N_ACCOUNT_LOCKED");
|
|
||||||
msg = String.format(msg, username, accountLockStatus.getRelieveTimes().toString());
|
|
||||||
DataEaseException.throwException(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
SysUserEntity user = authUserService.getUserByName(username);
|
|
||||||
|
|
||||||
if (ObjectUtils.isEmpty(user)) {
|
|
||||||
AccountLockStatus lockStatus = authUserService.recordLoginFail(username, 0);
|
|
||||||
DataEaseException.throwException(appendLoginErrorMsg(Translator.get("i18n_id_or_pwd_error"), lockStatus));
|
|
||||||
}
|
|
||||||
if (user.getEnabled() == 0) {
|
|
||||||
AccountLockStatus lockStatus = authUserService.recordLoginFail(username, 0);
|
|
||||||
DataEaseException.throwException(appendLoginErrorMsg(Translator.get("i18n_user_is_disable"), lockStatus));
|
|
||||||
}
|
|
||||||
String realPwd = user.getPassword();
|
|
||||||
pwd = CodingUtil.md5(pwd);
|
|
||||||
|
|
||||||
if (!StringUtils.equals(pwd, realPwd)) {
|
|
||||||
AccountLockStatus lockStatus = authUserService.recordLoginFail(username, 0);
|
|
||||||
DataEaseException.throwException(appendLoginErrorMsg(Translator.get("i18n_id_or_pwd_error"), lockStatus));
|
|
||||||
}
|
|
||||||
TokenInfo tokenInfo = TokenInfo.builder().userId(user.getUserId()).username(username).build();
|
|
||||||
String token = JWTUtils.sign(tokenInfo, realPwd, false);
|
|
||||||
// 记录token操作时间
|
|
||||||
Map<String, Object> result = new HashMap<>();
|
|
||||||
result.put("token", token);
|
|
||||||
ServletUtils.setToken(token);
|
|
||||||
DeLogUtils.save(SysLogConstants.OPERATE_TYPE.LOGIN, SysLogConstants.SOURCE_TYPE.USER, user.getUserId(), null, null, null);
|
|
||||||
authUserService.unlockAccount(username, 0);
|
|
||||||
authUserService.clearCache(user.getUserId());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object login(@RequestBody LoginDto loginDto) throws Exception {
|
|
||||||
Map<String, Object> result = new HashMap<>();
|
|
||||||
String username = RsaUtil.decryptByPrivateKey(RsaProperties.privateKey, loginDto.getUsername());
|
|
||||||
String pwd = RsaUtil.decryptByPrivateKey(RsaProperties.privateKey, loginDto.getPassword());
|
|
||||||
|
|
||||||
// 增加ldap登录方式
|
|
||||||
Integer loginType = loginDto.getLoginType();
|
|
||||||
boolean isSupportLdap = authUserService.supportLdap();
|
|
||||||
if (loginType == 1 && isSupportLdap) {
|
|
||||||
AccountLockStatus accountLockStatus = authUserService.lockStatus(username, 1);
|
|
||||||
if (accountLockStatus.getLocked()) {
|
|
||||||
String msg = Translator.get("I18N_ACCOUNT_LOCKED");
|
|
||||||
msg = String.format(msg, username, accountLockStatus.getRelieveTimes().toString());
|
|
||||||
DataEaseException.throwException(msg);
|
|
||||||
}
|
|
||||||
LdapXpackService ldapXpackService = SpringContextUtil.getBean(LdapXpackService.class);
|
|
||||||
LdapValidateRequest request = LdapValidateRequest.builder().userName(username).password(pwd).build();
|
|
||||||
ValidateResult<XpackLdapUserEntity> validateResult = ldapXpackService.login(request);
|
|
||||||
|
|
||||||
if (!validateResult.isSuccess()) {
|
|
||||||
AccountLockStatus lockStatus = authUserService.recordLoginFail(username, 1);
|
|
||||||
DataEaseException.throwException(appendLoginErrorMsg(validateResult.getMsg(), lockStatus));
|
|
||||||
}
|
|
||||||
XpackLdapUserEntity ldapUserEntity = validateResult.getData();
|
|
||||||
if (StringUtils.isBlank(ldapUserEntity.getEmail())) {
|
|
||||||
ldapUserEntity.setEmail(username + LDAP_EMAIL_SUFFIX);
|
|
||||||
}
|
|
||||||
SysUserEntity user = authUserService.getLdapUserByName(username);
|
|
||||||
if (ObjectUtils.isEmpty(user) || ObjectUtils.isEmpty(user.getUserId())) {
|
|
||||||
LdapAddRequest ldapAddRequest = new LdapAddRequest();
|
|
||||||
ldapAddRequest.setUsers(new ArrayList<XpackLdapUserEntity>() {
|
|
||||||
{
|
|
||||||
add(ldapUserEntity);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
ldapAddRequest.setEnabled(1L);
|
|
||||||
ldapAddRequest.setRoleIds(new ArrayList<Long>() {
|
|
||||||
{
|
|
||||||
add(2L);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
sysUserService.validateExistUser(ldapUserEntity.getUsername(), ldapUserEntity.getNickname(),
|
|
||||||
ldapUserEntity.getEmail());
|
|
||||||
sysUserService.saveLdapUsers(ldapAddRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
username = validateResult.getData().getUsername();
|
|
||||||
}
|
|
||||||
// 增加ldap登录方式
|
|
||||||
AccountLockStatus accountLockStatus = authUserService.lockStatus(username, 0);
|
|
||||||
if (accountLockStatus.getLocked()) {
|
|
||||||
String msg = Translator.get("I18N_ACCOUNT_LOCKED");
|
|
||||||
msg = String.format(msg, username, accountLockStatus.getRelieveTimes().toString());
|
|
||||||
DataEaseException.throwException(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
SysUserEntity user = authUserService.getUserByName(username);
|
|
||||||
|
|
||||||
if (ObjectUtils.isEmpty(user)) {
|
|
||||||
AccountLockStatus lockStatus = authUserService.recordLoginFail(username, 0);
|
|
||||||
DataEaseException.throwException(appendLoginErrorMsg(Translator.get("i18n_id_or_pwd_error"), lockStatus));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证登录类型是否与用户类型相同
|
|
||||||
if (!sysUserService.validateLoginType(user.getFrom(), loginType)) {
|
|
||||||
AccountLockStatus lockStatus = authUserService.recordLoginFail(username, 0);
|
|
||||||
DataEaseException.throwException(appendLoginErrorMsg(Translator.get("i18n_login_type_error"), lockStatus));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user.getEnabled() == 0) {
|
|
||||||
AccountLockStatus lockStatus = authUserService.recordLoginFail(username, 0);
|
|
||||||
DataEaseException.throwException(appendLoginErrorMsg(Translator.get("i18n_user_is_disable"), lockStatus));
|
|
||||||
}
|
|
||||||
String realPwd = user.getPassword();
|
|
||||||
|
|
||||||
// 普通登录需要验证密码
|
|
||||||
if (loginType == 0 || !isSupportLdap) {
|
|
||||||
// 私钥解密
|
|
||||||
|
|
||||||
// md5加密
|
|
||||||
pwd = CodingUtil.md5(pwd);
|
|
||||||
|
|
||||||
if (!StringUtils.equals(pwd, realPwd)) {
|
|
||||||
AccountLockStatus lockStatus = authUserService.recordLoginFail(username, 0);
|
|
||||||
DataEaseException.throwException(appendLoginErrorMsg(Translator.get("i18n_id_or_pwd_error"), lockStatus));
|
|
||||||
}
|
|
||||||
if (user.getIsAdmin() && user.getPassword().equals("40b8893ea9ebc2d631c4bb42bb1e8996")) {
|
|
||||||
result.put("passwordModified", false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TokenInfo tokenInfo = TokenInfo.builder().userId(user.getUserId()).username(username).build();
|
|
||||||
String token = JWTUtils.sign(tokenInfo, realPwd);
|
|
||||||
// 记录token操作时间
|
|
||||||
result.put("token", token);
|
|
||||||
ServletUtils.setToken(token);
|
|
||||||
DeLogUtils.save(SysLogConstants.OPERATE_TYPE.LOGIN, SysLogConstants.SOURCE_TYPE.USER, user.getUserId(), null, null, null);
|
|
||||||
authUserService.unlockAccount(username, ObjectUtils.isEmpty(loginType) ? 0 : loginType);
|
|
||||||
authUserService.clearCache(user.getUserId());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object seizeLogin(@RequestBody SeizeLoginDto loginDto) throws Exception {
|
|
||||||
String token = loginDto.getToken();
|
|
||||||
Map<String, Object> result = new HashMap<>();
|
|
||||||
result.put("token", token);
|
|
||||||
ServletUtils.setToken(token);
|
|
||||||
TokenInfo tokenInfo = JWTUtils.tokenInfoByToken(token);
|
|
||||||
Long userId = tokenInfo.getUserId();
|
|
||||||
JWTUtils.seizeSign(userId, token);
|
|
||||||
DeLogUtils.save(SysLogConstants.OPERATE_TYPE.LOGIN, SysLogConstants.SOURCE_TYPE.USER, userId, null, null, null);
|
|
||||||
WsMessage message = new WsMessage(userId, "/web-seize-topic", IPUtils.get());
|
|
||||||
wsService.releaseMessage(message);
|
|
||||||
authUserService.clearCache(userId);
|
|
||||||
Thread.sleep(3000L);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String appendLoginErrorMsg(String msg, AccountLockStatus lockStatus) {
|
|
||||||
if (ObjectUtils.isEmpty(lockStatus)) return msg;
|
|
||||||
if (ObjectUtils.isNotEmpty(lockStatus.getRemainderTimes())) {
|
|
||||||
String i18n = Translator.get("i18n_login_remainder_times");
|
|
||||||
msg += String.format(i18n, lockStatus.getRemainderTimes());
|
|
||||||
}
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CurrentUserDto userInfo() {
|
|
||||||
CurrentUserDto userDto = (CurrentUserDto) SecurityUtils.getSubject().getPrincipal();
|
|
||||||
if (ObjectUtils.isEmpty(userDto)) {
|
|
||||||
String token = ServletUtils.getToken();
|
|
||||||
Long userId = JWTUtils.tokenInfoByToken(token).getUserId();
|
|
||||||
SysUserEntity user = authUserService.getUserById(userId);
|
|
||||||
CurrentUserDto currentUserDto = BeanUtils.copyBean(new CurrentUserDto(), user, "password");
|
|
||||||
List<CurrentRoleDto> currentRoleDtos = authUserService.roleInfos(user.getUserId());
|
|
||||||
List<String> permissions = authUserService.permissions(user.getUserId());
|
|
||||||
currentUserDto.setRoles(currentRoleDtos);
|
|
||||||
currentUserDto.setPermissions(permissions);
|
|
||||||
return currentUserDto;
|
|
||||||
}
|
|
||||||
userDto.setPassword(null);
|
|
||||||
return userDto;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean useInitPwd() {
|
|
||||||
CurrentUserDto user = AuthUtils.getUser();
|
|
||||||
if (null == user || 0 != user.getFrom()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
String md5 = CodingUtil.md5(DEFAULT_PWD);
|
|
||||||
boolean isInitPwd = StringUtils.equals(AuthUtils.getUser().getPassword(), md5);
|
|
||||||
if (isInitPwd) {
|
|
||||||
return sysUserService.needPwdNoti(user.getUserId());
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeNoti() {
|
|
||||||
sysUserService.saveUserAssist(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String defaultPwd() {
|
|
||||||
return DEFAULT_PWD;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String deLogout() {
|
|
||||||
String token = ServletUtils.getToken();
|
|
||||||
if (StringUtils.isEmpty(token) || StringUtils.equals("null", token) || StringUtils.equals("undefined", token)) {
|
|
||||||
return "success";
|
|
||||||
}
|
|
||||||
SecurityUtils.getSubject().logout();
|
|
||||||
String result = null;
|
|
||||||
Integer defaultLoginType = systemParameterService.defaultLoginType();
|
|
||||||
if (defaultLoginType == 3 && isOpenCas()) {
|
|
||||||
HttpServletRequest request = ServletUtils.request();
|
|
||||||
HttpSession session = request.getSession();
|
|
||||||
session.invalidate();
|
|
||||||
CasXpackService casXpackService = SpringContextUtil.getBean(CasXpackService.class);
|
|
||||||
result = casXpackService.logout();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Long userId = JWTUtils.tokenInfoByToken(token).getUserId();
|
|
||||||
authUserService.clearCache(userId);
|
|
||||||
if (StringUtils.isBlank(result)) {
|
|
||||||
result = "success";
|
|
||||||
}
|
|
||||||
TokenCacheUtils.add(token, userId);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogUtil.error(e);
|
|
||||||
if (StringUtils.isBlank(result)) {
|
|
||||||
result = "fail";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String logout() {
|
|
||||||
String token = ServletUtils.getToken();
|
|
||||||
|
|
||||||
if (isOpenOidc()) {
|
|
||||||
HttpServletRequest request = ServletUtils.request();
|
|
||||||
String idToken = request.getHeader("IdToken");
|
|
||||||
if (StringUtils.isNotBlank(idToken)) {
|
|
||||||
try {
|
|
||||||
OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class);
|
|
||||||
oidcXpackService.logout(idToken);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogUtil.error(e.getMessage(), e);
|
|
||||||
DEException.throwException("oidc_logout_error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StringUtils.isEmpty(token) || StringUtils.equals("null", token) || StringUtils.equals("undefined", token)) {
|
|
||||||
return "success";
|
|
||||||
}
|
|
||||||
|
|
||||||
SecurityUtils.getSubject().logout();
|
|
||||||
String result = null;
|
|
||||||
Integer defaultLoginType = systemParameterService.defaultLoginType();
|
|
||||||
if (defaultLoginType == 3 && isOpenCas()) {
|
|
||||||
try {
|
|
||||||
HttpServletRequest request = ServletUtils.request();
|
|
||||||
HttpSession session = request.getSession();
|
|
||||||
session.invalidate();
|
|
||||||
CasXpackService casXpackService = SpringContextUtil.getBean(CasXpackService.class);
|
|
||||||
result = casXpackService.logout();
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogUtil.error(e.getMessage(), e);
|
|
||||||
DEException.throwException("cas_logout_error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Long userId = JWTUtils.tokenInfoByToken(token).getUserId();
|
|
||||||
|
|
||||||
authUserService.clearCache(userId);
|
|
||||||
if (StringUtils.isBlank(result)) {
|
|
||||||
result = "success";
|
|
||||||
}
|
|
||||||
TokenCacheUtils.add(token, userId);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogUtil.error(e);
|
|
||||||
if (StringUtils.isBlank(result)) {
|
|
||||||
result = "fail";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean validateName(@RequestBody Map<String, String> nameDto) {
|
|
||||||
String userName = nameDto.get("userName");
|
|
||||||
if (StringUtils.isEmpty(userName))
|
|
||||||
return false;
|
|
||||||
SysUserEntity userEntity = authUserService.getUserByName(userName);
|
|
||||||
return !ObjectUtils.isEmpty(userEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isOpenLdap() {
|
|
||||||
Boolean licValid = PluginUtils.licValid();
|
|
||||||
if (!licValid)
|
|
||||||
return false;
|
|
||||||
return authUserService.supportLdap();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isOpenOidc() {
|
|
||||||
Boolean licValid = PluginUtils.licValid();
|
|
||||||
if (!licValid)
|
|
||||||
return false;
|
|
||||||
return authUserService.supportOidc();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isOpenCas() {
|
|
||||||
Boolean licValid = PluginUtils.licValid();
|
|
||||||
if (!licValid)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return authUserService.supportCas();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isOpenWecom() {
|
|
||||||
Boolean licValid = PluginUtils.licValid();
|
|
||||||
if (!licValid)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return authUserService.supportWecom();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isOpenDingtalk() {
|
|
||||||
Boolean licValid = PluginUtils.licValid();
|
|
||||||
if (!licValid)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return authUserService.supportDingtalk();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isOpenLark() {
|
|
||||||
Boolean licValid = PluginUtils.licValid();
|
|
||||||
if (!licValid)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return authUserService.supportLark();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isOpenLarksuite() {
|
|
||||||
Boolean licValid = PluginUtils.licValid();
|
|
||||||
if (!licValid)
|
|
||||||
return false;
|
|
||||||
return authUserService.supportLarksuite();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isPluginLoaded() {
|
|
||||||
Boolean licValid = PluginUtils.licValid();
|
|
||||||
if (!licValid)
|
|
||||||
return false;
|
|
||||||
return authUserService.pluginLoaded();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getPublicKey() {
|
|
||||||
return RsaProperties.publicKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
package io.dataease.auth.server;
|
|
||||||
|
|
||||||
import io.dataease.auth.api.DynamicMenuApi;
|
|
||||||
import io.dataease.auth.api.dto.DynamicMenuDto;
|
|
||||||
import io.dataease.auth.service.DynamicMenuService;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
public class DynamicMenuServer implements DynamicMenuApi {
|
|
||||||
@Autowired
|
|
||||||
private DynamicMenuService dynamicMenuService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<DynamicMenuDto> menus() {
|
|
||||||
return dynamicMenuService.load(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
package io.dataease.auth.service;
|
|
||||||
|
|
||||||
import io.dataease.auth.api.dto.CurrentRoleDto;
|
|
||||||
import io.dataease.auth.entity.AccountLockStatus;
|
|
||||||
import io.dataease.auth.entity.SysUserEntity;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface AuthUserService {
|
|
||||||
|
|
||||||
|
|
||||||
SysUserEntity getUserById(Long userId);
|
|
||||||
|
|
||||||
SysUserEntity getUserByName(String username);
|
|
||||||
|
|
||||||
SysUserEntity getLdapUserByName(String username);
|
|
||||||
|
|
||||||
SysUserEntity getCasUserByName(String username);
|
|
||||||
|
|
||||||
SysUserEntity getUserBySub(String sub, Integer from);
|
|
||||||
|
|
||||||
SysUserEntity getUserByWecomId(String weComId);
|
|
||||||
|
|
||||||
SysUserEntity getUserByDingtalkId(String dingtalkId);
|
|
||||||
|
|
||||||
SysUserEntity getUserByLarkId(String larkId);
|
|
||||||
|
|
||||||
SysUserEntity getUserByLarksuiteId(String larksuiteId);
|
|
||||||
|
|
||||||
List<String> roles(Long userId);
|
|
||||||
|
|
||||||
List<String> permissions(Long userId);
|
|
||||||
|
|
||||||
List<CurrentRoleDto> roleInfos(Long userId);
|
|
||||||
|
|
||||||
void clearCache(Long userId);
|
|
||||||
|
|
||||||
boolean supportLdap();
|
|
||||||
|
|
||||||
Boolean supportOidc();
|
|
||||||
|
|
||||||
Boolean supportCas();
|
|
||||||
|
|
||||||
Boolean supportWecom();
|
|
||||||
|
|
||||||
Boolean supportDingtalk();
|
|
||||||
|
|
||||||
Boolean supportLark();
|
|
||||||
|
|
||||||
Boolean supportLarksuite();
|
|
||||||
|
|
||||||
Boolean supportLoginLimit();
|
|
||||||
|
|
||||||
Boolean pluginLoaded();
|
|
||||||
|
|
||||||
void checkAdmin(String uname, String pwd);
|
|
||||||
|
|
||||||
AccountLockStatus recordLoginFail(String username, Integer logintype);
|
|
||||||
|
|
||||||
void unlockAccount(String username, Integer logintype);
|
|
||||||
|
|
||||||
AccountLockStatus lockStatus(String username, Integer logintype);
|
|
||||||
|
|
||||||
void clearAllLock();
|
|
||||||
|
|
||||||
Boolean checkScanCreateLimit();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
package io.dataease.auth.service;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public interface DeLimitService {
|
|
||||||
|
|
||||||
Boolean checkRestricted(String key, long max, long timeout, TimeUnit timeUnit);
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
package io.dataease.auth.service;
|
|
||||||
|
|
||||||
import io.dataease.auth.api.dto.DynamicMenuDto;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface DynamicMenuService {
|
|
||||||
|
|
||||||
List<DynamicMenuDto> load(String userId);
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
package io.dataease.auth.service;
|
|
||||||
|
|
||||||
import io.dataease.auth.entity.AuthItem;
|
|
||||||
import io.dataease.commons.model.AuthURD;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public interface ExtAuthService {
|
|
||||||
|
|
||||||
Set<Long> userIdsByRD(AuthURD request);
|
|
||||||
|
|
||||||
AuthURD resourceTarget(String resourceId);
|
|
||||||
|
|
||||||
List<AuthItem> dataSourceIdByUser(Long userId);
|
|
||||||
List<AuthItem> dataSetIdByUser(Long userId);
|
|
||||||
List<AuthItem> panelIdByUser(Long userId);
|
|
||||||
|
|
||||||
List<AuthItem> dataSourceIdByRole(Long roleId);
|
|
||||||
List<AuthItem> dataSetIdByRole(Long roleId);
|
|
||||||
List<AuthItem> panelIdByRole(Long roleId);
|
|
||||||
|
|
||||||
List<AuthItem> dataSourceIdByDept(Long deptId);
|
|
||||||
List<AuthItem> dataSetIdByDept(Long deptId);
|
|
||||||
List<AuthItem> panelIdByDept(Long deptId);
|
|
||||||
|
|
||||||
void clearUserResource(Long userId);
|
|
||||||
void clearDeptResource(Long deptId);
|
|
||||||
void clearRoleResource(Long roleId);
|
|
||||||
|
|
||||||
List<String> parentResource(String resourceId, String type);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
package io.dataease.auth.service;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.shiro.authc.AuthenticationException;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.Lazy;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import io.dataease.auth.api.dto.CurrentRoleDto;
|
|
||||||
import io.dataease.auth.api.dto.CurrentUserDto;
|
|
||||||
import io.dataease.auth.entity.SysUserEntity;
|
|
||||||
import io.dataease.commons.utils.BeanUtils;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class ProxyAuthService {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
@Lazy
|
|
||||||
private AuthUserService authUserService;
|
|
||||||
|
|
||||||
public CurrentUserDto queryCacheUserDto(Long userId) {
|
|
||||||
|
|
||||||
SysUserEntity user = authUserService.getUserById(userId);
|
|
||||||
if (user == null) {
|
|
||||||
throw new AuthenticationException("User didn't existed!");
|
|
||||||
}
|
|
||||||
if (user.getEnabled() == 0) {
|
|
||||||
throw new AuthenticationException("User is valid!");
|
|
||||||
}
|
|
||||||
// 使用缓存
|
|
||||||
List<CurrentRoleDto> currentRoleDtos = authUserService.roleInfos(user.getUserId());
|
|
||||||
// 使用缓存
|
|
||||||
List<String> permissions = authUserService.permissions(user.getUserId());
|
|
||||||
CurrentUserDto currentUserDto = BeanUtils.copyBean(new CurrentUserDto(), user);
|
|
||||||
currentUserDto.setRoles(currentRoleDtos);
|
|
||||||
currentUserDto.setPermissions(permissions);
|
|
||||||
return currentUserDto;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
package io.dataease.auth.service;
|
|
||||||
|
|
||||||
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public interface ShiroService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化权限 -> 拿全部权限
|
|
||||||
*
|
|
||||||
* @param :
|
|
||||||
* @return: java.util.Map<java.lang.String, java.lang.String>
|
|
||||||
*/
|
|
||||||
Map<String, String> loadFilterChainDefinitionMap();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 在对uri权限进行增删改操作时,需要调用此方法进行动态刷新加载数据库中的uri权限
|
|
||||||
*
|
|
||||||
* @param shiroFilterFactoryBean
|
|
||||||
* @param roleId
|
|
||||||
* @param isRemoveSession:
|
|
||||||
* @return: void
|
|
||||||
*/
|
|
||||||
void updatePermission(ShiroFilterFactoryBean shiroFilterFactoryBean, Integer roleId, Boolean isRemoveSession);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* shiro动态权限加载 -> 原理:删除shiro缓存,重新执行doGetAuthorizationInfo方法授权角色和权限
|
|
||||||
*
|
|
||||||
* @param roleId
|
|
||||||
* @param isRemoveSession:
|
|
||||||
* @return: void
|
|
||||||
*/
|
|
||||||
void updatePermissionByRoleId(Integer roleId, Boolean isRemoveSession);
|
|
||||||
}
|
|
||||||
@ -1,379 +0,0 @@
|
|||||||
package io.dataease.auth.service.impl;
|
|
||||||
|
|
||||||
import io.dataease.auth.api.dto.CurrentRoleDto;
|
|
||||||
import io.dataease.auth.entity.AccountLockStatus;
|
|
||||||
import io.dataease.auth.entity.SysUserEntity;
|
|
||||||
import io.dataease.auth.service.AuthUserService;
|
|
||||||
import io.dataease.commons.constants.AuthConstants;
|
|
||||||
import io.dataease.commons.constants.ParamConstants;
|
|
||||||
import io.dataease.commons.utils.CodingUtil;
|
|
||||||
import io.dataease.commons.utils.LogUtil;
|
|
||||||
import io.dataease.exception.DataEaseException;
|
|
||||||
import io.dataease.ext.AuthMapper;
|
|
||||||
import io.dataease.i18n.Translator;
|
|
||||||
import io.dataease.plugins.common.base.domain.SysLoginLimit;
|
|
||||||
import io.dataease.plugins.common.base.domain.SysLoginLimitExample;
|
|
||||||
import io.dataease.plugins.common.base.domain.SysUser;
|
|
||||||
import io.dataease.plugins.common.base.mapper.SysLoginLimitMapper;
|
|
||||||
import io.dataease.plugins.common.base.mapper.SysUserMapper;
|
|
||||||
import io.dataease.plugins.common.service.PluginCommonService;
|
|
||||||
import io.dataease.plugins.config.SpringContextUtil;
|
|
||||||
import io.dataease.plugins.util.PluginUtils;
|
|
||||||
import io.dataease.plugins.xpack.cas.service.CasXpackService;
|
|
||||||
import io.dataease.plugins.xpack.dingtalk.service.DingtalkXpackService;
|
|
||||||
import io.dataease.plugins.xpack.lark.service.LarkXpackService;
|
|
||||||
import io.dataease.plugins.xpack.larksuite.service.LarksuiteXpackService;
|
|
||||||
import io.dataease.plugins.xpack.ldap.service.LdapXpackService;
|
|
||||||
import io.dataease.plugins.xpack.loginlimit.dto.response.LoginLimitInfo;
|
|
||||||
import io.dataease.plugins.xpack.loginlimit.service.LoginLimitXpackService;
|
|
||||||
import io.dataease.plugins.xpack.oidc.service.OidcXpackService;
|
|
||||||
import io.dataease.plugins.xpack.wecom.service.WecomXpackService;
|
|
||||||
import io.dataease.service.sys.SysUserService;
|
|
||||||
import io.dataease.service.system.EmailService;
|
|
||||||
import io.dataease.service.system.SystemParameterService;
|
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
|
||||||
import org.springframework.cache.annotation.Caching;
|
|
||||||
import org.springframework.context.annotation.Lazy;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static io.dataease.commons.constants.ParamConstants.BASIC.LOCKED_EMAIL;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class AuthUserServiceImpl implements AuthUserService {
|
|
||||||
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private AuthMapper authMapper;
|
|
||||||
@Resource
|
|
||||||
private SysUserMapper sysUserMapper;
|
|
||||||
@Resource
|
|
||||||
private DynamicMenuServiceImpl dynamicMenuService;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private SysLoginLimitMapper sysLoginLimitMapper;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private SystemParameterService systemParameterService;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private EmailService emailService;
|
|
||||||
|
|
||||||
@Lazy
|
|
||||||
@Resource
|
|
||||||
private SysUserService sysUserService;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 此处需被F2CRealm登录认证调用 也就是说每次请求都会被调用 所以最好加上缓存
|
|
||||||
*
|
|
||||||
* @param userId
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Cacheable(value = AuthConstants.USER_CACHE_NAME, key = "'user' + #userId")
|
|
||||||
@Override
|
|
||||||
public SysUserEntity getUserById(Long userId) {
|
|
||||||
return authMapper.findUser(userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SysUserEntity getUserByIdNoCache(Long userId) {
|
|
||||||
return authMapper.findUser(userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SysUserEntity getUserByName(String username) {
|
|
||||||
return authMapper.findUserByName(username);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SysUserEntity getLdapUserByName(String username) {
|
|
||||||
return authMapper.findLdapUserByName(username);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SysUserEntity getCasUserByName(String username) {
|
|
||||||
return authMapper.findCasUserByName(username);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SysUserEntity getUserBySub(String sub, Integer from) {
|
|
||||||
return authMapper.findUserBySub(sub, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SysUserEntity getUserByWecomId(String weComId) {
|
|
||||||
return authMapper.findWecomUser(weComId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SysUserEntity getUserByDingtalkId(String dingtalkId) {
|
|
||||||
return authMapper.findDingtalkUser(dingtalkId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SysUserEntity getUserByLarkId(String larkId) {
|
|
||||||
return authMapper.findLarkUser(larkId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SysUserEntity getUserByLarksuiteId(String larksuiteId) {
|
|
||||||
return authMapper.findLarksuiteUser(larksuiteId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> roles(Long userId) {
|
|
||||||
return authMapper.roleCodes(userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 此处需被F2CRealm登录认证调用 也就是说每次请求都会被调用 所以最好加上缓存
|
|
||||||
*
|
|
||||||
* @param userId
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Cacheable(value = AuthConstants.USER_PERMISSION_CACHE_NAME, key = "'user' + #userId")
|
|
||||||
@Override
|
|
||||||
public List<String> permissions(Long userId) {
|
|
||||||
try {
|
|
||||||
// 用户登录获取菜单权限时同时更新插件菜单表
|
|
||||||
dynamicMenuService.syncPluginMenu(PluginUtils.pluginMenus());
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogUtil.error(e);
|
|
||||||
//ignore
|
|
||||||
}
|
|
||||||
List<String> permissions;
|
|
||||||
SysUser sysUser = sysUserMapper.selectByPrimaryKey(userId);
|
|
||||||
if (sysUser.getIsAdmin() != null && sysUser.getIsAdmin()) {
|
|
||||||
permissions = authMapper.permissionsAll();
|
|
||||||
} else {
|
|
||||||
permissions = authMapper.permissions(userId);
|
|
||||||
}
|
|
||||||
return Optional.ofNullable(permissions).orElse(new ArrayList<>()).stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 此处需被F2CRealm登录认证调用 也就是说每次请求都会被调用 所以最好加上缓存
|
|
||||||
*
|
|
||||||
* @param userId
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Cacheable(value = AuthConstants.USER_ROLE_CACHE_NAME, key = "'user' + #userId")
|
|
||||||
@Override
|
|
||||||
public List<CurrentRoleDto> roleInfos(Long userId) {
|
|
||||||
return authMapper.roles(userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 一波清除3个缓存
|
|
||||||
*
|
|
||||||
* @param userId
|
|
||||||
*/
|
|
||||||
@Caching(evict = {
|
|
||||||
@CacheEvict(value = AuthConstants.USER_CACHE_NAME, key = "'user' + #userId"),
|
|
||||||
@CacheEvict(value = AuthConstants.USER_ROLE_CACHE_NAME, key = "'user' + #userId"),
|
|
||||||
@CacheEvict(value = AuthConstants.USER_PERMISSION_CACHE_NAME, key = "'user' + #userId")
|
|
||||||
})
|
|
||||||
@Override
|
|
||||||
public void clearCache(Long userId) {
|
|
||||||
LogUtil.info("正在清除用户缓存【{}】", userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportLdap() {
|
|
||||||
Map<String, LdapXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((LdapXpackService.class));
|
|
||||||
if (beansOfType.keySet().size() == 0) return false;
|
|
||||||
LdapXpackService ldapXpackService = SpringContextUtil.getBean(LdapXpackService.class);
|
|
||||||
if (ObjectUtils.isEmpty(ldapXpackService)) return false;
|
|
||||||
return ldapXpackService.isOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean supportOidc() {
|
|
||||||
Map<String, OidcXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((OidcXpackService.class));
|
|
||||||
if (beansOfType.keySet().size() == 0) return false;
|
|
||||||
OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class);
|
|
||||||
if (ObjectUtils.isEmpty(oidcXpackService)) return false;
|
|
||||||
return oidcXpackService.isSupportOIDC();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean supportCas() {
|
|
||||||
Map<String, CasXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((CasXpackService.class));
|
|
||||||
if (beansOfType.keySet().size() == 0) return false;
|
|
||||||
CasXpackService casXpackService = SpringContextUtil.getBean(CasXpackService.class);
|
|
||||||
if (ObjectUtils.isEmpty(casXpackService)) return false;
|
|
||||||
return casXpackService.supportCas();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean supportWecom() {
|
|
||||||
Map<String, WecomXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((WecomXpackService.class));
|
|
||||||
if (beansOfType.keySet().size() == 0) return false;
|
|
||||||
WecomXpackService wecomXpackService = SpringContextUtil.getBean(WecomXpackService.class);
|
|
||||||
if (ObjectUtils.isEmpty(wecomXpackService)) return false;
|
|
||||||
return wecomXpackService.isOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean supportDingtalk() {
|
|
||||||
Map<String, DingtalkXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((DingtalkXpackService.class));
|
|
||||||
if (beansOfType.keySet().size() == 0) return false;
|
|
||||||
DingtalkXpackService dingtalkXpackService = SpringContextUtil.getBean(DingtalkXpackService.class);
|
|
||||||
if (ObjectUtils.isEmpty(dingtalkXpackService)) return false;
|
|
||||||
return dingtalkXpackService.isOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean supportLark() {
|
|
||||||
Map<String, LarkXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((LarkXpackService.class));
|
|
||||||
if (beansOfType.keySet().size() == 0) return false;
|
|
||||||
LarkXpackService larkXpackService = SpringContextUtil.getBean(LarkXpackService.class);
|
|
||||||
if (ObjectUtils.isEmpty(larkXpackService)) return false;
|
|
||||||
return larkXpackService.isOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean supportLarksuite() {
|
|
||||||
Map<String, LarksuiteXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((LarksuiteXpackService.class));
|
|
||||||
if (beansOfType.keySet().size() == 0) return false;
|
|
||||||
LarksuiteXpackService larkXpackService = SpringContextUtil.getBean(LarksuiteXpackService.class);
|
|
||||||
if (ObjectUtils.isEmpty(larkXpackService)) return false;
|
|
||||||
return larkXpackService.isOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean supportLoginLimit() {
|
|
||||||
Map<String, LoginLimitXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((LoginLimitXpackService.class));
|
|
||||||
if (beansOfType.keySet().size() == 0) return false;
|
|
||||||
LoginLimitXpackService loginLimitXpackService = SpringContextUtil.getBean(LoginLimitXpackService.class);
|
|
||||||
if (ObjectUtils.isEmpty(loginLimitXpackService)) return false;
|
|
||||||
return loginLimitXpackService.isOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean pluginLoaded() {
|
|
||||||
Map<String, PluginCommonService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((PluginCommonService.class));
|
|
||||||
if (beansOfType.keySet().size() == 0) return false;
|
|
||||||
PluginCommonService pluginCommonService = SpringContextUtil.getBean(PluginCommonService.class);
|
|
||||||
if (ObjectUtils.isEmpty(pluginCommonService)) return false;
|
|
||||||
return pluginCommonService.isPluginLoaded();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void checkAdmin(String uname, String pwd) {
|
|
||||||
|
|
||||||
SysUserEntity user = getUserByName(uname);
|
|
||||||
if (ObjectUtils.isEmpty(user)) {
|
|
||||||
DataEaseException.throwException(Translator.get("i18n_user_not_exist"));
|
|
||||||
}
|
|
||||||
if (!user.getIsAdmin()) {
|
|
||||||
DataEaseException.throwException(Translator.get("i18n_not_admin_error"));
|
|
||||||
}
|
|
||||||
String realPwd = user.getPassword();
|
|
||||||
pwd = CodingUtil.md5(pwd);
|
|
||||||
if (!StringUtils.equals(pwd, realPwd)) {
|
|
||||||
DataEaseException.throwException(Translator.get("i18n_id_or_pwd_error"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AccountLockStatus recordLoginFail(String username, Integer logintype) {
|
|
||||||
if (!supportLoginLimit()) return null;
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
SysLoginLimit sysLoginLimit = new SysLoginLimit();
|
|
||||||
sysLoginLimit.setUsername(username);
|
|
||||||
sysLoginLimit.setLoginType(logintype);
|
|
||||||
sysLoginLimit.setRecordTime(now);
|
|
||||||
sysLoginLimitMapper.insert(sysLoginLimit);
|
|
||||||
AccountLockStatus accountLockStatus = lockStatus(username, logintype);
|
|
||||||
if (ObjectUtils.isNotEmpty(accountLockStatus) && accountLockStatus.getLocked()) {
|
|
||||||
sendLockedEmail(username);
|
|
||||||
}
|
|
||||||
return accountLockStatus;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendLockedEmail(String username) {
|
|
||||||
String value = systemParameterService.getValue(LOCKED_EMAIL.getValue());
|
|
||||||
if (StringUtils.isNotBlank(value) && StringUtils.equals("true", value)) {
|
|
||||||
String email = sysUserService.adminEmail();
|
|
||||||
if (StringUtils.isBlank(email)) return;
|
|
||||||
String format = "账号【%s】登录失败次数过多,已被锁定!";
|
|
||||||
String content = String.format(format, username);
|
|
||||||
try {
|
|
||||||
emailService.send(email, "账号锁定通知", content);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogUtil.error(e.getMessage(), e);
|
|
||||||
systemParameterService.disabledLockedEmail();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unlockAccount(String username, Integer logintype) {
|
|
||||||
SysLoginLimitExample example = new SysLoginLimitExample();
|
|
||||||
example.createCriteria().andUsernameEqualTo(username).andLoginTypeEqualTo(logintype);
|
|
||||||
sysLoginLimitMapper.deleteByExample(example);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AccountLockStatus lockStatus(String username, Integer logintype) {
|
|
||||||
AccountLockStatus accountLockStatus = new AccountLockStatus();
|
|
||||||
accountLockStatus.setUsername(username);
|
|
||||||
if (!supportLoginLimit()) return accountLockStatus;
|
|
||||||
|
|
||||||
LoginLimitXpackService loginLimitXpackService = SpringContextUtil.getBean(LoginLimitXpackService.class);
|
|
||||||
LoginLimitInfo info = loginLimitXpackService.info();
|
|
||||||
Integer limitTimes = info.getLimitTimes();
|
|
||||||
Integer relieveTimes = info.getRelieveTimes();
|
|
||||||
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
|
|
||||||
long longRelieveTimes = Long.parseLong(relieveTimes.toString());
|
|
||||||
long dividingPointTime = now - (longRelieveTimes * 60L * 1000L);
|
|
||||||
SysLoginLimitExample example = new SysLoginLimitExample();
|
|
||||||
example.createCriteria().andUsernameEqualTo(username).andLoginTypeEqualTo(logintype).andRecordTimeGreaterThan(dividingPointTime);
|
|
||||||
List<SysLoginLimit> sysLoginLimits = sysLoginLimitMapper.selectByExample(example);
|
|
||||||
accountLockStatus.setRemainderTimes(limitTimes);
|
|
||||||
if (CollectionUtils.isNotEmpty(sysLoginLimits)) {
|
|
||||||
boolean needLock = sysLoginLimits.size() >= limitTimes;
|
|
||||||
accountLockStatus.setRemainderTimes(limitTimes - sysLoginLimits.size());
|
|
||||||
accountLockStatus.setLocked(needLock);
|
|
||||||
if (needLock) {
|
|
||||||
long unlockTime = now + (longRelieveTimes * 60L * 1000L);
|
|
||||||
accountLockStatus.setUnlockTime(unlockTime);
|
|
||||||
accountLockStatus.setRelieveTimes(relieveTimes);
|
|
||||||
accountLockStatus.setRemainderTimes(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
example.clear();
|
|
||||||
example.createCriteria().andUsernameEqualTo(username).andLoginTypeEqualTo(logintype).andRecordTimeLessThanOrEqualTo(dividingPointTime);
|
|
||||||
sysLoginLimitMapper.deleteByExample(example);
|
|
||||||
return accountLockStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clearAllLock() {
|
|
||||||
SysLoginLimitExample example = new SysLoginLimitExample();
|
|
||||||
sysLoginLimitMapper.deleteByExample(example);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean checkScanCreateLimit() {
|
|
||||||
String value = systemParameterService.getValue(ParamConstants.BASIC.SCAN_CREATE_USER.getValue());
|
|
||||||
return StringUtils.isNotBlank(value) && StringUtils.equals("true", value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,129 +0,0 @@
|
|||||||
package io.dataease.auth.service.impl;
|
|
||||||
|
|
||||||
import io.dataease.auth.api.dto.DynamicMenuDto;
|
|
||||||
import io.dataease.auth.api.dto.MenuMeta;
|
|
||||||
import io.dataease.auth.service.DynamicMenuService;
|
|
||||||
import io.dataease.plugins.common.base.domain.SysMenu;
|
|
||||||
import io.dataease.plugins.common.base.mapper.SysMenuMapper;
|
|
||||||
import io.dataease.ext.ExtPluginSysMenuMapper;
|
|
||||||
import io.dataease.ext.ExtSysMenuMapper;
|
|
||||||
import io.dataease.plugins.common.dto.PluginSysMenu;
|
|
||||||
import io.dataease.plugins.util.PluginUtils;
|
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class DynamicMenuServiceImpl implements DynamicMenuService {
|
|
||||||
|
|
||||||
@Autowired(required = false)
|
|
||||||
private SysMenuMapper sysMenuMapper;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private ExtPluginSysMenuMapper extPluginSysMenuMapper;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private ExtSysMenuMapper extSysMenuMapper;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<DynamicMenuDto> load(String userId) {
|
|
||||||
List<SysMenu> sysMenus = extSysMenuMapper.querySysMenu();
|
|
||||||
List<DynamicMenuDto> dynamicMenuDtos = sysMenus.stream().map(this::convert).collect(Collectors.toList());
|
|
||||||
//增加插件中的菜单
|
|
||||||
List<PluginSysMenu> pluginSysMenus = PluginUtils.pluginMenus();
|
|
||||||
if (CollectionUtils.isNotEmpty(pluginSysMenus)) {
|
|
||||||
pluginSysMenus = pluginSysMenus.stream().filter(menu -> menu.getType() <= 1).collect(Collectors.toList());
|
|
||||||
List<DynamicMenuDto> pluginDtos = pluginSysMenus.stream().map(this::convert).collect(Collectors.toList());
|
|
||||||
dynamicMenuDtos.addAll(pluginDtos);
|
|
||||||
}
|
|
||||||
dynamicMenuDtos = dynamicMenuDtos.stream().sorted((s1, s2) -> {
|
|
||||||
int sortIndex1 = null == s1.getMenuSort() ? 999 : s1.getMenuSort();
|
|
||||||
int sortIndex2 = null == s2.getMenuSort() ? 999 : s2.getMenuSort();
|
|
||||||
return sortIndex1 - sortIndex2;
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
dynamicMenuDtos.sort((s1, s2) -> s1.getHidden().compareTo(s2.getHidden()));
|
|
||||||
return buildTree(dynamicMenuDtos);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DynamicMenuDto convert(SysMenu sysMenu) {
|
|
||||||
DynamicMenuDto dynamicMenuDto = new DynamicMenuDto();
|
|
||||||
dynamicMenuDto.setId(sysMenu.getMenuId());
|
|
||||||
dynamicMenuDto.setPid(sysMenu.getPid());
|
|
||||||
dynamicMenuDto.setName(sysMenu.getName());
|
|
||||||
dynamicMenuDto.setPath(sysMenu.getPath());
|
|
||||||
dynamicMenuDto.setRedirect(null);
|
|
||||||
dynamicMenuDto.setType(sysMenu.getType());
|
|
||||||
dynamicMenuDto.setComponent(sysMenu.getComponent());
|
|
||||||
MenuMeta menuMeta = new MenuMeta();
|
|
||||||
menuMeta.setTitle(sysMenu.getTitle());
|
|
||||||
menuMeta.setIcon(sysMenu.getIcon());
|
|
||||||
dynamicMenuDto.setMeta(menuMeta);
|
|
||||||
dynamicMenuDto.setPermission(sysMenu.getPermission());
|
|
||||||
dynamicMenuDto.setMenuSort(sysMenu.getMenuSort());
|
|
||||||
dynamicMenuDto.setHidden(sysMenu.getHidden());
|
|
||||||
dynamicMenuDto.setIsPlugin(false);
|
|
||||||
return dynamicMenuDto;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DynamicMenuDto convert(PluginSysMenu sysMenu) {
|
|
||||||
DynamicMenuDto dynamicMenuDto = new DynamicMenuDto();
|
|
||||||
dynamicMenuDto.setId(sysMenu.getMenuId());
|
|
||||||
dynamicMenuDto.setPid(sysMenu.getPid());
|
|
||||||
dynamicMenuDto.setName(sysMenu.getName());
|
|
||||||
dynamicMenuDto.setPath(sysMenu.getPath());
|
|
||||||
dynamicMenuDto.setRedirect(null);
|
|
||||||
dynamicMenuDto.setType(sysMenu.getType());
|
|
||||||
dynamicMenuDto.setComponent(sysMenu.getComponent());
|
|
||||||
MenuMeta menuMeta = new MenuMeta();
|
|
||||||
menuMeta.setTitle(sysMenu.getTitle());
|
|
||||||
menuMeta.setIcon(sysMenu.getIcon());
|
|
||||||
dynamicMenuDto.setMeta(menuMeta);
|
|
||||||
dynamicMenuDto.setPermission(sysMenu.getPermission());
|
|
||||||
dynamicMenuDto.setMenuSort(sysMenu.getMenuSort());
|
|
||||||
dynamicMenuDto.setHidden(sysMenu.getHidden());
|
|
||||||
dynamicMenuDto.setIsPlugin(true);
|
|
||||||
dynamicMenuDto.setNoLayout(!!sysMenu.isNoLayout());
|
|
||||||
return dynamicMenuDto;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<DynamicMenuDto> buildTree(List<DynamicMenuDto> lists) {
|
|
||||||
List<DynamicMenuDto> rootNodes = new ArrayList<>();
|
|
||||||
lists.forEach(node -> {
|
|
||||||
if (isParent(node.getPid())) {
|
|
||||||
rootNodes.add(node);
|
|
||||||
}
|
|
||||||
lists.forEach(tNode -> {
|
|
||||||
if (tNode.getPid().equals(node.getId())) {
|
|
||||||
if (node.getChildren() == null) {
|
|
||||||
node.setChildren(new ArrayList<DynamicMenuDto>());
|
|
||||||
node.setRedirect(node.getPath() + "/" + tNode.getPath());//第一个子节点的path
|
|
||||||
}
|
|
||||||
node.getChildren().add(tNode);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return rootNodes;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Boolean isParent(Long pid) {
|
|
||||||
return null == pid || pid == 0L;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
|
||||||
public void syncPluginMenu(List<PluginSysMenu> pluginSysMenuList) {
|
|
||||||
extPluginSysMenuMapper.deletePluginMenu();
|
|
||||||
if (CollectionUtils.isNotEmpty(pluginSysMenuList)) {
|
|
||||||
extPluginSysMenuMapper.savePluginMenu(pluginSysMenuList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,204 +0,0 @@
|
|||||||
package io.dataease.auth.service.impl;
|
|
||||||
|
|
||||||
import io.dataease.auth.entity.AuthItem;
|
|
||||||
import io.dataease.auth.service.ExtAuthService;
|
|
||||||
import io.dataease.commons.constants.SysAuthConstants;
|
|
||||||
import io.dataease.plugins.common.base.domain.SysAuth;
|
|
||||||
import io.dataease.ext.ExtAuthMapper;
|
|
||||||
import io.dataease.commons.constants.AuthConstants;
|
|
||||||
import io.dataease.commons.model.AuthURD;
|
|
||||||
import io.dataease.commons.utils.LogUtil;
|
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
|
||||||
import org.springframework.cache.annotation.Caching;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class ExtAuthServiceImpl implements ExtAuthService {
|
|
||||||
|
|
||||||
private static final List<AuthItem> emptyResult = new ArrayList();
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private ExtAuthMapper extAuthMapper;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Long> userIdsByRD(AuthURD request) {
|
|
||||||
Set<Long> result = new HashSet<>();
|
|
||||||
List<Long> roleIds = request.getRoleIds();
|
|
||||||
List<Long> deptIds = request.getDeptIds();
|
|
||||||
if (!CollectionUtils.isEmpty(roleIds)) {
|
|
||||||
result.addAll(extAuthMapper.queryUserIdWithRoleIds(roleIds));
|
|
||||||
}
|
|
||||||
if (!CollectionUtils.isEmpty(deptIds)) {
|
|
||||||
result.addAll(extAuthMapper.queryUserIdWithDeptIds(deptIds));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AuthURD resourceTarget(String resourceId) {
|
|
||||||
AuthURD authURD = new AuthURD();
|
|
||||||
|
|
||||||
List<SysAuth> sysAuths = extAuthMapper.queryByResource(resourceId);
|
|
||||||
|
|
||||||
Map<String, List<SysAuth>> authMap = sysAuths.stream().collect(Collectors.groupingBy(SysAuth::getAuthTargetType));
|
|
||||||
if (!CollectionUtils.isEmpty(authMap.get("user"))) {
|
|
||||||
authURD.setUserIds(authMap.get("user").stream().map(item -> Long.parseLong(item.getAuthTarget())).collect(Collectors.toList()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!CollectionUtils.isEmpty(authMap.get("role"))) {
|
|
||||||
authURD.setRoleIds(authMap.get("role").stream().map(item -> Long.parseLong(item.getAuthTarget())).collect(Collectors.toList()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!CollectionUtils.isEmpty(authMap.get("dept"))) {
|
|
||||||
authURD.setDeptIds(authMap.get("dept").stream().map(item -> Long.parseLong(item.getAuthTarget())).collect(Collectors.toList()));
|
|
||||||
}
|
|
||||||
return authURD;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Cacheable(value = AuthConstants.USER_LINK_NAME, key = "'user' + #userId")
|
|
||||||
@Override
|
|
||||||
public List<AuthItem> dataSourceIdByUser(Long userId) {
|
|
||||||
return extAuthMapper.queryAuthItems(
|
|
||||||
SysAuthConstants.AUTH_TARGET_TYPE_USER,
|
|
||||||
userId.toString(),
|
|
||||||
SysAuthConstants.AUTH_SOURCE_TYPE_DATASOURCE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Cacheable(value = AuthConstants.USER_DATASET_NAME, key = "'user' + #userId")
|
|
||||||
@Override
|
|
||||||
public List<AuthItem> dataSetIdByUser(Long userId) {
|
|
||||||
return extAuthMapper.queryAuthItems(
|
|
||||||
SysAuthConstants.AUTH_TARGET_TYPE_USER,
|
|
||||||
userId.toString(),
|
|
||||||
SysAuthConstants.AUTH_SOURCE_TYPE_DATASET
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Cacheable(value = AuthConstants.USER_PANEL_NAME, key = "'user' + #userId")
|
|
||||||
@Override
|
|
||||||
public List<AuthItem> panelIdByUser(Long userId) {
|
|
||||||
return extAuthMapper.queryAuthItems(
|
|
||||||
SysAuthConstants.AUTH_TARGET_TYPE_USER,
|
|
||||||
userId.toString(),
|
|
||||||
SysAuthConstants.AUTH_SOURCE_TYPE_PANEL
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Cacheable(value = AuthConstants.ROLE_LINK_NAME, key = "'role' + #roleId")
|
|
||||||
@Override
|
|
||||||
public List<AuthItem> dataSourceIdByRole(Long roleId) {
|
|
||||||
return extAuthMapper.queryAuthItems(
|
|
||||||
SysAuthConstants.AUTH_TARGET_TYPE_ROLE,
|
|
||||||
roleId.toString(),
|
|
||||||
SysAuthConstants.AUTH_SOURCE_TYPE_DATASOURCE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Cacheable(value = AuthConstants.ROLE_DATASET_NAME, key = "'role' + #roleId")
|
|
||||||
@Override
|
|
||||||
public List<AuthItem> dataSetIdByRole(Long roleId) {
|
|
||||||
return extAuthMapper.queryAuthItems(
|
|
||||||
SysAuthConstants.AUTH_TARGET_TYPE_ROLE,
|
|
||||||
roleId.toString(),
|
|
||||||
SysAuthConstants.AUTH_SOURCE_TYPE_DATASET
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Cacheable(value = AuthConstants.ROLE_PANEL_NAME, key = "'role' + #roleId")
|
|
||||||
@Override
|
|
||||||
public List<AuthItem> panelIdByRole(Long roleId) {
|
|
||||||
return extAuthMapper.queryAuthItems(
|
|
||||||
SysAuthConstants.AUTH_TARGET_TYPE_ROLE,
|
|
||||||
roleId.toString(),
|
|
||||||
SysAuthConstants.AUTH_SOURCE_TYPE_PANEL
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Cacheable(value = AuthConstants.DEPT_LINK_NAME, key = "'dept' + #deptId")
|
|
||||||
@Override
|
|
||||||
public List<AuthItem> dataSourceIdByDept(Long deptId) {
|
|
||||||
if (ObjectUtils.isEmpty(deptId)) return emptyResult;
|
|
||||||
return extAuthMapper.queryAuthItems(
|
|
||||||
SysAuthConstants.AUTH_TARGET_TYPE_DEPT,
|
|
||||||
deptId.toString(),
|
|
||||||
SysAuthConstants.AUTH_SOURCE_TYPE_DATASOURCE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Cacheable(value = AuthConstants.DEPT_DATASET_NAME, key = "'dept' + #deptId")
|
|
||||||
@Override
|
|
||||||
public List<AuthItem> dataSetIdByDept(Long deptId) {
|
|
||||||
if (ObjectUtils.isEmpty(deptId)) return emptyResult;
|
|
||||||
return extAuthMapper.queryAuthItems(
|
|
||||||
SysAuthConstants.AUTH_TARGET_TYPE_DEPT,
|
|
||||||
deptId.toString(),
|
|
||||||
SysAuthConstants.AUTH_SOURCE_TYPE_DATASET
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Cacheable(value = AuthConstants.DEPT_PANEL_NAME, key = "'dept' + #deptId")
|
|
||||||
@Override
|
|
||||||
public List<AuthItem> panelIdByDept(Long deptId) {
|
|
||||||
if (ObjectUtils.isEmpty(deptId)) return emptyResult;
|
|
||||||
return extAuthMapper.queryAuthItems(
|
|
||||||
SysAuthConstants.AUTH_TARGET_TYPE_DEPT,
|
|
||||||
deptId.toString(),
|
|
||||||
SysAuthConstants.AUTH_SOURCE_TYPE_PANEL
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Caching(evict = {
|
|
||||||
@CacheEvict(value = AuthConstants.USER_LINK_NAME, key = "'user' + #userId"),
|
|
||||||
@CacheEvict(value = AuthConstants.USER_DATASET_NAME, key = "'user' + #userId"),
|
|
||||||
@CacheEvict(value = AuthConstants.USER_PANEL_NAME, key = "'user' + #userId")
|
|
||||||
})
|
|
||||||
public void clearUserResource(Long userId) {
|
|
||||||
LogUtil.info("all permission resource of user {} is cleaning...", userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Caching(evict = {
|
|
||||||
@CacheEvict(value = AuthConstants.DEPT_LINK_NAME, key = "'dept' + #deptId"),
|
|
||||||
@CacheEvict(value = AuthConstants.DEPT_DATASET_NAME, key = "'dept' + #deptId"),
|
|
||||||
@CacheEvict(value = AuthConstants.DEPT_PANEL_NAME, key = "'dept' + #deptId")
|
|
||||||
})
|
|
||||||
public void clearDeptResource(Long deptId) {
|
|
||||||
LogUtil.info("all permission resource of dept {} is cleaning...", deptId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Caching(evict = {
|
|
||||||
@CacheEvict(value = AuthConstants.ROLE_LINK_NAME, key = "'role' + #roleId"),
|
|
||||||
@CacheEvict(value = AuthConstants.ROLE_DATASET_NAME, key = "'role' + #roleId"),
|
|
||||||
@CacheEvict(value = AuthConstants.ROLE_PANEL_NAME, key = "'role' + #roleId")
|
|
||||||
})
|
|
||||||
public void clearRoleResource(Long roleId) {
|
|
||||||
LogUtil.info("all permission resource of role {} is cleaning...", roleId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> parentResource(String resourceId, String type) {
|
|
||||||
String s = extAuthMapper.parentResource(resourceId, type);
|
|
||||||
if (StringUtils.isNotBlank(s)) {
|
|
||||||
String[] split = s.split(",");
|
|
||||||
List<String> results = new ArrayList<>();
|
|
||||||
for (int i = 0; i < split.length; i++) {
|
|
||||||
String s1 = split[i];
|
|
||||||
if (StringUtils.isNotBlank(s1)) {
|
|
||||||
results.add(s1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return CollectionUtils.isEmpty(results) ? null : results;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
package io.dataease.auth.service.impl;
|
|
||||||
|
|
||||||
import io.dataease.auth.service.DeLimitService;
|
|
||||||
import io.dataease.commons.condition.RedisStatusCondition;
|
|
||||||
import io.dataease.commons.utils.LogUtil;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.springframework.context.annotation.Conditional;
|
|
||||||
import org.springframework.context.annotation.Primary;
|
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
|
||||||
import org.springframework.data.redis.core.script.RedisScript;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
@Conditional({RedisStatusCondition.class})
|
|
||||||
@Component
|
|
||||||
@Primary
|
|
||||||
public class RedisLimitServiceImpl implements DeLimitService {
|
|
||||||
|
|
||||||
Logger log = LogUtil.getLogger();
|
|
||||||
private final static String REDIS_LIMIT_KEY_PREFIX = "limit:";
|
|
||||||
@Resource
|
|
||||||
private RedisScript<Long> limitRedisScript;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private StringRedisTemplate stringRedisTemplate;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean checkRestricted(String key, long max, long timeout, TimeUnit timeUnit) {
|
|
||||||
key = REDIS_LIMIT_KEY_PREFIX + key;
|
|
||||||
long ttl = timeUnit.toMillis(timeout);
|
|
||||||
long now = Instant.now().toEpochMilli();
|
|
||||||
long expired = now - ttl;
|
|
||||||
|
|
||||||
Long executeTimes = stringRedisTemplate.execute(limitRedisScript, Collections.singletonList(key), now + "", ttl + "", expired + "", max + "");
|
|
||||||
if (executeTimes != null) {
|
|
||||||
if (executeTimes == 0) {
|
|
||||||
|
|
||||||
log.error("【{}】在单位时间 {} 毫秒内已达到访问上限,当前接口上限 {}", key, ttl, max);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
log.info("【{}】在单位时间 {} 毫秒内访问 {} 次", key, ttl, executeTimes);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,154 +0,0 @@
|
|||||||
package io.dataease.auth.service.impl;
|
|
||||||
|
|
||||||
import io.dataease.auth.service.ShiroService;
|
|
||||||
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class ShiroServiceImpl implements ShiroService {
|
|
||||||
|
|
||||||
private final static String ANON = "anon";
|
|
||||||
private final static String DOC = "doc";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> loadFilterChainDefinitionMap() {
|
|
||||||
// 权限控制map
|
|
||||||
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
|
|
||||||
// 配置过滤:不会被拦截的链接 -> 放行 start
|
|
||||||
// ----------------------------------------------------------
|
|
||||||
// 放行Swagger2页面,需要放行这些
|
|
||||||
|
|
||||||
filterChainDefinitionMap.put("/doc.html**", DOC);
|
|
||||||
filterChainDefinitionMap.put("/deApi**", DOC);
|
|
||||||
filterChainDefinitionMap.put("/swagger-ui.html", ANON);
|
|
||||||
filterChainDefinitionMap.put("/swagger-ui/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/swagger/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/webjars/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/swagger-resources/**", DOC);
|
|
||||||
filterChainDefinitionMap.put("/v2/**", DOC);
|
|
||||||
filterChainDefinitionMap.put("/v3/**", DOC);
|
|
||||||
|
|
||||||
filterChainDefinitionMap.put("/**.gif", ANON);
|
|
||||||
filterChainDefinitionMap.put("/**.png", ANON);
|
|
||||||
|
|
||||||
filterChainDefinitionMap.put("/static/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/css/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/js/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/img/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/fonts/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/favicon.ico", ANON);
|
|
||||||
filterChainDefinitionMap.put("/", ANON);
|
|
||||||
filterChainDefinitionMap.put("/login", ANON);
|
|
||||||
filterChainDefinitionMap.put("/link/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/index.html", ANON);
|
|
||||||
filterChainDefinitionMap.put("/link.html", ANON);
|
|
||||||
filterChainDefinitionMap.put("/board/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/websocket/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/system/defaultLoginType", ANON);
|
|
||||||
|
|
||||||
// 获取主题信息
|
|
||||||
filterChainDefinitionMap.put("/plugin/theme/themes", ANON);
|
|
||||||
filterChainDefinitionMap.put("/plugin/theme/items/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/plugin/view/types", ANON);
|
|
||||||
filterChainDefinitionMap.put("/static-resource/**", ANON);
|
|
||||||
|
|
||||||
// 验证链接
|
|
||||||
filterChainDefinitionMap.put("/api/link/validate**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/api/map/areaEntitys/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/api/map/globalEntitys/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/linkJump/queryPanelJumpInfo/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/linkJump/queryTargetPanelJumpInfo", ANON);
|
|
||||||
|
|
||||||
//外部跳转参数
|
|
||||||
filterChainDefinitionMap.put("/outerParams/**", ANON);
|
|
||||||
|
|
||||||
|
|
||||||
filterChainDefinitionMap.put("/tempMobileLink/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/de-app/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/app.html", ANON);
|
|
||||||
|
|
||||||
filterChainDefinitionMap.put("/**/*.json", ANON);
|
|
||||||
filterChainDefinitionMap.put("/system/ui/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/system/filedown/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/system/showpicture/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/**/*.js", ANON);
|
|
||||||
filterChainDefinitionMap.put("/**/*.css", ANON);
|
|
||||||
filterChainDefinitionMap.put("/**/*.map", ANON);
|
|
||||||
filterChainDefinitionMap.put("/**/*.svg", ANON);
|
|
||||||
|
|
||||||
|
|
||||||
filterChainDefinitionMap.put("/api/auth/login", ANON);
|
|
||||||
filterChainDefinitionMap.put("/api/auth/seizeLogin", ANON);
|
|
||||||
filterChainDefinitionMap.put("/api/auth/logout", ANON);
|
|
||||||
filterChainDefinitionMap.put("/api/auth/mobileLogin", ANON);
|
|
||||||
filterChainDefinitionMap.put("/api/auth/isPluginLoaded", ANON);
|
|
||||||
filterChainDefinitionMap.put("/system/requestTimeOut", ANON);
|
|
||||||
filterChainDefinitionMap.put("/api/auth/validateName", ANON);
|
|
||||||
filterChainDefinitionMap.put("/api/auth/isOpenLdap", ANON);
|
|
||||||
filterChainDefinitionMap.put("/api/auth/isOpenOidc", ANON);
|
|
||||||
filterChainDefinitionMap.put("/api/auth/isOpenWecom", ANON);
|
|
||||||
filterChainDefinitionMap.put("/api/auth/isOpenDingtalk", ANON);
|
|
||||||
filterChainDefinitionMap.put("/api/auth/isOpenLark", ANON);
|
|
||||||
filterChainDefinitionMap.put("/api/auth/isOpenCas", ANON);
|
|
||||||
filterChainDefinitionMap.put("/api/auth/isOpenLarksuite", ANON);
|
|
||||||
filterChainDefinitionMap.put("/api/auth/getPublicKey", ANON);
|
|
||||||
filterChainDefinitionMap.put("/api/pluginCommon/component/*", ANON);
|
|
||||||
filterChainDefinitionMap.put("/api/pluginCommon/staticInfo/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/plugin/oidc/authInfo", ANON);
|
|
||||||
filterChainDefinitionMap.put("/sso/callBack*", ANON);
|
|
||||||
filterChainDefinitionMap.put("/cas/callBack*", ANON);
|
|
||||||
filterChainDefinitionMap.put("/plugin/wecom/callBack*", ANON);
|
|
||||||
filterChainDefinitionMap.put("/plugin/wecom/bind*", ANON);
|
|
||||||
filterChainDefinitionMap.put("/plugin/wecom/getQrParam", ANON);
|
|
||||||
filterChainDefinitionMap.put("/plugin/dingtalk/callBack*", ANON);
|
|
||||||
filterChainDefinitionMap.put("/plugin/dingtalk/bind*", ANON);
|
|
||||||
filterChainDefinitionMap.put("/plugin/dingtalk/getQrParam", ANON);
|
|
||||||
filterChainDefinitionMap.put("/plugin/lark/callBack*", ANON);
|
|
||||||
filterChainDefinitionMap.put("/plugin/lark/bind*", ANON);
|
|
||||||
filterChainDefinitionMap.put("/plugin/lark/getQrParam", ANON);
|
|
||||||
filterChainDefinitionMap.put("/plugin/lark/appId", ANON);
|
|
||||||
filterChainDefinitionMap.put("/plugin/larksuite/callBack*", ANON);
|
|
||||||
filterChainDefinitionMap.put("/plugin/larksuite/bind*", ANON);
|
|
||||||
filterChainDefinitionMap.put("/plugin/larksuite/getQrParam", ANON);
|
|
||||||
filterChainDefinitionMap.put("/cas/reset/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/cas/loginPage", ANON);
|
|
||||||
filterChainDefinitionMap.put("/pdf-template/queryAll", ANON);
|
|
||||||
|
|
||||||
|
|
||||||
filterChainDefinitionMap.put("/unauth", ANON);
|
|
||||||
filterChainDefinitionMap.put("/display/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/tokenExpired", ANON);
|
|
||||||
filterChainDefinitionMap.put("/downline", ANON);
|
|
||||||
filterChainDefinitionMap.put("/common-files/**", ANON);
|
|
||||||
filterChainDefinitionMap.put("/linkage/getPanelAllLinkageInfo/**", ANON);
|
|
||||||
|
|
||||||
filterChainDefinitionMap.put("/api/link/resourceDetail/**", "link");
|
|
||||||
filterChainDefinitionMap.put("/api/link/viewDetail/**", "link");
|
|
||||||
filterChainDefinitionMap.put("/api/link/viewLog", "link");
|
|
||||||
filterChainDefinitionMap.put("/panel/group/exportDetails", ANON);
|
|
||||||
filterChainDefinitionMap.put("/dataset/field/linkMultFieldValues", "link");
|
|
||||||
filterChainDefinitionMap.put("/dataset/field/linkMappingFieldValues", "link");
|
|
||||||
filterChainDefinitionMap.put("/systemInfo/proxyUserLoginInfo", ANON);
|
|
||||||
filterChainDefinitionMap.put("/system/onlineMapKey", ANON);
|
|
||||||
|
|
||||||
filterChainDefinitionMap.put("/**", "authc");
|
|
||||||
|
|
||||||
filterChainDefinitionMap.put("/**", "jwt");
|
|
||||||
|
|
||||||
return filterChainDefinitionMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updatePermission(ShiroFilterFactoryBean shiroFilterFactoryBean, Integer roleId,
|
|
||||||
Boolean isRemoveSession) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updatePermissionByRoleId(Integer roleId, Boolean isRemoveSession) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package io.dataease.auth.service.impl;
|
|
||||||
|
|
||||||
|
|
||||||
import com.google.common.util.concurrent.RateLimiter;
|
|
||||||
import io.dataease.auth.service.DeLimitService;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class StandaloneLimitServiceImpl implements DeLimitService {
|
|
||||||
|
|
||||||
private static ConcurrentHashMap<String, RateLimiter> RATE_LIMITER = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean checkRestricted(String key, long max, long timeout, TimeUnit timeUnit) {
|
|
||||||
RateLimiter rateLimiter = null;
|
|
||||||
if (!RATE_LIMITER.containsKey(key)) {
|
|
||||||
RATE_LIMITER.put(key, RateLimiter.create(max));
|
|
||||||
}
|
|
||||||
rateLimiter = RATE_LIMITER.get(key);
|
|
||||||
return !rateLimiter.tryAcquire(timeout, timeUnit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,190 +0,0 @@
|
|||||||
package io.dataease.auth.util;
|
|
||||||
|
|
||||||
import com.auth0.jwt.JWT;
|
|
||||||
import com.auth0.jwt.JWTVerifier;
|
|
||||||
import com.auth0.jwt.JWTCreator.Builder;
|
|
||||||
import com.auth0.jwt.algorithms.Algorithm;
|
|
||||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
|
||||||
import com.auth0.jwt.interfaces.Verification;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import io.dataease.auth.entity.TokenInfo;
|
|
||||||
import io.dataease.auth.entity.TokenInfo.TokenInfoBuilder;
|
|
||||||
import io.dataease.commons.model.OnlineUserModel;
|
|
||||||
import io.dataease.commons.utils.*;
|
|
||||||
import io.dataease.exception.DataEaseException;
|
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
|
|
||||||
import javax.servlet.http.Cookie;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class JWTUtils {
|
|
||||||
|
|
||||||
|
|
||||||
private static Long expireTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 校验token是否正确
|
|
||||||
*
|
|
||||||
* @param token 密钥
|
|
||||||
* @param secret 用户的密码
|
|
||||||
* @return 是否正确
|
|
||||||
*/
|
|
||||||
public static boolean verify(String token, TokenInfo tokenInfo, String secret) {
|
|
||||||
|
|
||||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
|
||||||
Verification verification = JWT.require(algorithm)
|
|
||||||
.withClaim("username", tokenInfo.getUsername())
|
|
||||||
.withClaim("userId", tokenInfo.getUserId());
|
|
||||||
JWTVerifier verifier = verification.build();
|
|
||||||
|
|
||||||
verifySign(algorithm, token);
|
|
||||||
verifier.verify(token);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void verifySign(Algorithm algorithm, String token) {
|
|
||||||
DecodedJWT decode = JWT.decode(token);
|
|
||||||
algorithm.verify(decode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得token中的信息无需secret解密也能获得
|
|
||||||
*
|
|
||||||
* @return token中包含的用户名
|
|
||||||
*/
|
|
||||||
public static TokenInfo tokenInfoByToken(String token) {
|
|
||||||
DecodedJWT jwt = JWT.decode(token);
|
|
||||||
String username = jwt.getClaim("username").asString();
|
|
||||||
Long userId = jwt.getClaim("userId").asLong();
|
|
||||||
if (StringUtils.isEmpty(username) || ObjectUtils.isEmpty(userId)) {
|
|
||||||
DataEaseException.throwException("token格式错误!");
|
|
||||||
}
|
|
||||||
TokenInfoBuilder tokenInfoBuilder = TokenInfo.builder().username(username).userId(userId);
|
|
||||||
return tokenInfoBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param tokenInfo 用户信息
|
|
||||||
* @param secret 用户的密码
|
|
||||||
* @return 加密的token
|
|
||||||
*/
|
|
||||||
public static String sign(TokenInfo tokenInfo, String secret) {
|
|
||||||
return sign(tokenInfo, secret, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean tokenValid(OnlineUserModel model) {
|
|
||||||
String token = model.getToken();
|
|
||||||
// 如果已经加入黑名单 则直接返回无效
|
|
||||||
boolean invalid = TokenCacheUtils.invalid(token);
|
|
||||||
if (invalid) return false;
|
|
||||||
|
|
||||||
Long loginTime = model.getLoginTime();
|
|
||||||
if (ObjectUtils.isEmpty(expireTime)) {
|
|
||||||
expireTime = CommonBeanFactory.getBean(Environment.class).getProperty("dataease.login_timeout", Long.class, 480L);
|
|
||||||
}
|
|
||||||
long expireTimeMillis = expireTime * 60000L;
|
|
||||||
// 如果当前时间减去登录时间小于超时时间则说明token未过期 返回有效状态
|
|
||||||
return System.currentTimeMillis() - loginTime < expireTimeMillis;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String models2Json(OnlineUserModel model, boolean withCurToken, String token) {
|
|
||||||
Set<OnlineUserModel> models = new LinkedHashSet<>();
|
|
||||||
models.add(model);
|
|
||||||
Gson gson = new Gson();
|
|
||||||
List<OnlineUserModel> userModels = models.stream().map(item -> {
|
|
||||||
item.setToken(null);
|
|
||||||
return item;
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
if (withCurToken) {
|
|
||||||
userModels.get(0).setToken(token);
|
|
||||||
}
|
|
||||||
String json = gson.toJson(userModels);
|
|
||||||
try {
|
|
||||||
return URLEncoder.encode(json, "utf-8");
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String seizeSign(Long userId, String token) {
|
|
||||||
Optional.ofNullable(TokenCacheUtils.onlineUserToken(userId)).ifPresent(model -> TokenCacheUtils.add(model.getToken(), userId));
|
|
||||||
TokenCacheUtils.add2OnlinePools(token, userId);
|
|
||||||
return IPUtils.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String sign(TokenInfo tokenInfo, String secret, boolean writeOnline) {
|
|
||||||
|
|
||||||
Long userId = tokenInfo.getUserId();
|
|
||||||
String multiLoginType = null;
|
|
||||||
if (writeOnline && StringUtils.equals("1", (multiLoginType = TokenCacheUtils.multiLoginType()))) {
|
|
||||||
OnlineUserModel userModel = TokenCacheUtils.onlineUserToken(userId);
|
|
||||||
if (ObjectUtils.isNotEmpty(userModel) && tokenValid(userModel)) {
|
|
||||||
HttpServletResponse response = ServletUtils.response();
|
|
||||||
Cookie cookie_token = new Cookie("MultiLoginError1", models2Json(userModel, false, null));
|
|
||||||
cookie_token.setPath("/");
|
|
||||||
cookie_token.setPath("/");
|
|
||||||
response.addCookie(cookie_token);
|
|
||||||
DataEaseException.throwException("MultiLoginError1");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ObjectUtils.isEmpty(expireTime)) {
|
|
||||||
expireTime = CommonBeanFactory.getBean(Environment.class).getProperty("dataease.login_timeout", Long.class, 480L);
|
|
||||||
}
|
|
||||||
long expireTimeMillis = expireTime * 60000L;
|
|
||||||
Date date = new Date(System.currentTimeMillis() + expireTimeMillis);
|
|
||||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
|
||||||
Builder builder = JWT.create()
|
|
||||||
.withClaim("username", tokenInfo.getUsername())
|
|
||||||
.withClaim("userId", userId);
|
|
||||||
String sign = builder.withExpiresAt(date).sign(algorithm);
|
|
||||||
|
|
||||||
if (StringUtils.equals("2", multiLoginType)) {
|
|
||||||
OnlineUserModel userModel = TokenCacheUtils.onlineUserToken(userId);
|
|
||||||
if (ObjectUtils.isNotEmpty(userModel) && tokenValid(userModel)) {
|
|
||||||
HttpServletResponse response = ServletUtils.response();
|
|
||||||
Cookie cookie_token = new Cookie("MultiLoginError2", models2Json(userModel, true, sign));
|
|
||||||
cookie_token.setPath("/");
|
|
||||||
response.addCookie(cookie_token);
|
|
||||||
DataEaseException.throwException("MultiLoginError");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (writeOnline && !StringUtils.equals("0", multiLoginType)) {
|
|
||||||
TokenCacheUtils.add2OnlinePools(sign, userId);
|
|
||||||
}
|
|
||||||
return sign;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static String signLink(String resourceId, Long userId, String secret) {
|
|
||||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
|
||||||
if (userId == null) {
|
|
||||||
return JWT.create().withClaim("resourceId", resourceId).sign(algorithm);
|
|
||||||
} else {
|
|
||||||
return JWT.create().withClaim("resourceId", resourceId).withClaim("userId", userId).sign(algorithm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean verifyLink(String token, String resourceId, Long userId, String secret) {
|
|
||||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
|
||||||
JWTVerifier verifier;
|
|
||||||
if (userId == null) {
|
|
||||||
verifier = JWT.require(algorithm).withClaim("resourceId", resourceId).build();
|
|
||||||
} else {
|
|
||||||
verifier = JWT.require(algorithm).withClaim("resourceId", resourceId).withClaim("userId", userId).build();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
verifier.verify(token);
|
|
||||||
return true;
|
|
||||||
} catch (Exception e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
package io.dataease.auth.util;
|
|
||||||
|
|
||||||
import io.dataease.plugins.common.base.domain.PanelLink;
|
|
||||||
import io.dataease.service.panel.PanelLinkService;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class LinkUtil {
|
|
||||||
|
|
||||||
|
|
||||||
private static PanelLinkService panelLinkService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public void setPanelLinkService(PanelLinkService panelLinkService) {
|
|
||||||
LinkUtil.panelLinkService = panelLinkService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PanelLink queryLink(String resourceId, Long user) {
|
|
||||||
return panelLinkService.findOne(resourceId, user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,59 +0,0 @@
|
|||||||
package io.dataease.auth.util;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class ReflectUtil {
|
|
||||||
|
|
||||||
public static Object getFieldValue(Object o, String fieldName) throws Exception {
|
|
||||||
Class<?> aClass = o.getClass();
|
|
||||||
while (null != aClass.getSuperclass()) {
|
|
||||||
Field[] declaredFields = aClass.getDeclaredFields();
|
|
||||||
for (int i = 0; i < declaredFields.length; i++) {
|
|
||||||
Field field = declaredFields[i];
|
|
||||||
String name = field.getName();
|
|
||||||
if (StringUtils.equals(name, fieldName)) {
|
|
||||||
field.setAccessible(true);
|
|
||||||
return field.get(o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
aClass = aClass.getSuperclass();
|
|
||||||
}
|
|
||||||
throw new NoSuchFieldException(fieldName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final static String[] wrapClasies = {
|
|
||||||
"java.lang.Boolean",
|
|
||||||
"java.lang.Character",
|
|
||||||
"java.lang.Integer",
|
|
||||||
"java.lang.Byte",
|
|
||||||
"java.lang.Short",
|
|
||||||
"java.lang.Long",
|
|
||||||
"java.lang.Float",
|
|
||||||
"java.lang.Double",
|
|
||||||
};
|
|
||||||
|
|
||||||
public static Boolean isString(Class clz) {
|
|
||||||
return StringUtils.equals("java.lang.String", clz.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean isArray(Class clz) {
|
|
||||||
return clz.isArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean isCollection(Class clz) {
|
|
||||||
return Collection.class.isAssignableFrom(clz);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean isMap(Class clz) {
|
|
||||||
return Map.class.isAssignableFrom(clz);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean isWrapClass(Class clz) {
|
|
||||||
return Arrays.stream(wrapClasies).anyMatch(item -> StringUtils.equals(item, clz.getName()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,62 +0,0 @@
|
|||||||
package io.dataease.auth.util;
|
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
|
||||||
import org.apache.commons.lang.ArrayUtils;
|
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import java.security.KeyFactory;
|
|
||||||
import java.security.PrivateKey;
|
|
||||||
import java.security.PublicKey;
|
|
||||||
import java.security.spec.PKCS8EncodedKeySpec;
|
|
||||||
import java.security.spec.X509EncodedKeySpec;
|
|
||||||
|
|
||||||
public class RsaUtil {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 私钥解密
|
|
||||||
*
|
|
||||||
* @param privateKeyText 私钥
|
|
||||||
* @param text 待解密的文本
|
|
||||||
* @return /
|
|
||||||
* @throws Exception /
|
|
||||||
*/
|
|
||||||
public static String decryptByPrivateKey(String privateKeyText, String text) throws Exception {
|
|
||||||
PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText));
|
|
||||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
|
||||||
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
|
|
||||||
Cipher cipher = Cipher.getInstance("RSA");
|
|
||||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
|
||||||
// 下面该用分段加密
|
|
||||||
byte[] result = null;
|
|
||||||
byte[] b = Base64.decodeBase64(text);
|
|
||||||
for (int i = 0; i < b.length; i += 64) {
|
|
||||||
byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(b, i, i + 64));
|
|
||||||
result = ArrayUtils.addAll(result, doFinal);
|
|
||||||
}
|
|
||||||
return new String(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 公钥加密
|
|
||||||
*
|
|
||||||
* @param publicKeyText 公钥
|
|
||||||
* @param text 待加密的文本
|
|
||||||
* @return /
|
|
||||||
*/
|
|
||||||
public static String encryptByPublicKey(String publicKeyText, String text) throws Exception {
|
|
||||||
X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText));
|
|
||||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
|
||||||
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
|
|
||||||
Cipher cipher = Cipher.getInstance("RSA");
|
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
|
||||||
// 下面该用分段加密
|
|
||||||
byte[] result = null;
|
|
||||||
byte[] b = text.getBytes("utf-8");
|
|
||||||
for (int i = 0; i < b.length; i += 50) {
|
|
||||||
byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(b, i, i + 50));
|
|
||||||
result = ArrayUtils.addAll(result, doFinal);
|
|
||||||
}
|
|
||||||
return Base64.encodeBase64String(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package io.dataease.commons.condition;
|
|
||||||
|
|
||||||
import io.dataease.commons.license.DefaultLicenseService;
|
|
||||||
import io.dataease.commons.license.F2CLicenseResponse;
|
|
||||||
import io.dataease.commons.utils.CommonBeanFactory;
|
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
|
||||||
import org.springframework.context.annotation.Condition;
|
|
||||||
import org.springframework.context.annotation.ConditionContext;
|
|
||||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
|
||||||
|
|
||||||
|
|
||||||
public class LicStatusCondition implements Condition {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
|
|
||||||
|
|
||||||
DefaultLicenseService defaultLicenseService = CommonBeanFactory.getBean(DefaultLicenseService.class);
|
|
||||||
|
|
||||||
|
|
||||||
if (ObjectUtils.isNotEmpty(defaultLicenseService)) {
|
|
||||||
F2CLicenseResponse f2CLicenseResponse = defaultLicenseService.validateLicense();
|
|
||||||
return F2CLicenseResponse.Status.valid == f2CLicenseResponse.getStatus();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
package io.dataease.commons.condition;
|
|
||||||
|
|
||||||
import io.dataease.commons.utils.CommonBeanFactory;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.context.annotation.Condition;
|
|
||||||
import org.springframework.context.annotation.ConditionContext;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
|
||||||
|
|
||||||
public class RedisStatusCondition implements Condition {
|
|
||||||
|
|
||||||
private static final String DEFAULT_TYPE = "ehcache";
|
|
||||||
private static final String TARGET_TYPE = "redis";
|
|
||||||
private static final String TYPE_KEY = "spring.cache.type";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
|
||||||
Environment environment = context.getEnvironment();
|
|
||||||
String ehcacheType = environment.getProperty(TYPE_KEY, String.class, DEFAULT_TYPE);
|
|
||||||
|
|
||||||
return StringUtils.equals(TARGET_TYPE, ehcacheType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public class AuthConstants {
|
|
||||||
|
|
||||||
public final static String TOKEN_KEY = "Authorization";
|
|
||||||
public final static String USER_CACHE_NAME = "users_info";
|
|
||||||
public final static String USER_ROLE_CACHE_NAME = "users_roles_info";
|
|
||||||
public final static String USER_PERMISSION_CACHE_NAME = "users_permissions_info";
|
|
||||||
public final static String ID_TOKEN_KEY = "IdToken";
|
|
||||||
|
|
||||||
|
|
||||||
public final static String USER_LINK_NAME = "user_link";
|
|
||||||
public final static String USER_DATASET_NAME = "user_dataset";
|
|
||||||
public final static String USER_PANEL_NAME = "user_panel";
|
|
||||||
|
|
||||||
public final static String ROLE_LINK_NAME = "role_link";
|
|
||||||
public final static String ROLE_DATASET_NAME = "role_dataset";
|
|
||||||
public final static String ROLE_PANEL_NAME = "role_panel";
|
|
||||||
|
|
||||||
public final static String DEPT_LINK_NAME = "dept_link";
|
|
||||||
public final static String DEPT_DATASET_NAME = "dept_dataset";
|
|
||||||
public final static String DEPT_PANEL_NAME = "dept_panel";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static final String DE_DOWN_ERROR_KEY = "de-down-error-msg";
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public class ColumnPermissionConstants {
|
|
||||||
|
|
||||||
public final static String Prohibit = "Prohibit";
|
|
||||||
public final static String Desensitization = "Desensitization";
|
|
||||||
}
|
|
||||||
@ -1,83 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Author: wangjiahao
|
|
||||||
* Date: 2021-05-25
|
|
||||||
* Description:
|
|
||||||
*/
|
|
||||||
public class CommonConstants {
|
|
||||||
|
|
||||||
|
|
||||||
//操作类型
|
|
||||||
public static final class OPT_TYPE {
|
|
||||||
|
|
||||||
public static final String INSERT = "insert";
|
|
||||||
|
|
||||||
public static final String UPDATE = "update";
|
|
||||||
|
|
||||||
public static final String DELETE = "delete";
|
|
||||||
|
|
||||||
public static final String SELECT = "select";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//操作类型
|
|
||||||
public static final class CHECK_RESULT {
|
|
||||||
|
|
||||||
// 不存在
|
|
||||||
public static final String NONE = "none";
|
|
||||||
|
|
||||||
// 全局存在
|
|
||||||
public static final String EXIST_ALL = "exist_all";
|
|
||||||
|
|
||||||
// 当前用户存在
|
|
||||||
public static final String EXIST_USER = "exist_user";
|
|
||||||
|
|
||||||
// 其他用户存在
|
|
||||||
public static final String EXIST_OTHER = "exist_other";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//视图数据查询来源
|
|
||||||
public static final class VIEW_QUERY_FROM {
|
|
||||||
|
|
||||||
// 仪表板
|
|
||||||
public static final String PANEL = "panel";
|
|
||||||
|
|
||||||
// 仪表板编辑
|
|
||||||
public static final String PANEL_EDIT = "panel_edit";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//视图数据查询模式
|
|
||||||
public static final class VIEW_RESULT_MODE {
|
|
||||||
|
|
||||||
// 所有
|
|
||||||
public static final String ALL = "all";
|
|
||||||
|
|
||||||
// 自定义
|
|
||||||
public static final String CUSTOM = "custom";
|
|
||||||
}
|
|
||||||
|
|
||||||
//视图数据查询来源
|
|
||||||
public static final class VIEW_EDIT_FROM {
|
|
||||||
|
|
||||||
// 仪表板
|
|
||||||
public static final String PANEL = "panel";
|
|
||||||
|
|
||||||
// 仪表板编辑
|
|
||||||
public static final String CACHE = "cache";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//视图数据读取来源
|
|
||||||
public static final class VIEW_DATA_FROM {
|
|
||||||
|
|
||||||
// 模板数据
|
|
||||||
public static final String TEMPLATE = "template";
|
|
||||||
|
|
||||||
//数据集数据
|
|
||||||
public static final String CHART = "dataset";
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public class DatasetMode {
|
|
||||||
public static final String EXTRACT = "1";
|
|
||||||
public static final String DIRECT = "0";
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public enum DePermissionType {
|
|
||||||
DATASOURCE, DATASET, PANEL
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public enum FileType {
|
|
||||||
JMX(".jmx"), CSV(".csv"), JSON(".json"), PDF(".pdf"),
|
|
||||||
JPG(".jpg"), PNG(".png"), JPEG(".jpeg"), DOC(".doc"),
|
|
||||||
XLSX(".xlsx"), DOCX(".docx"), JAR(".jar");
|
|
||||||
|
|
||||||
// 保存后缀
|
|
||||||
private String suffix;
|
|
||||||
|
|
||||||
FileType(String suffix) {
|
|
||||||
this.suffix = suffix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String suffix() {
|
|
||||||
return this.suffix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public class I18nConstants {
|
|
||||||
|
|
||||||
public static final String LANG_COOKIE_NAME = "DE_USER_LANG";
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public enum IssuesManagePlatform {
|
|
||||||
Tapd, Jira, Local, Zentao
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public class JdbcConstants {
|
|
||||||
|
|
||||||
public final static String VIEW_CACHE_KEY = "view_cache";
|
|
||||||
|
|
||||||
public final static String PANEL_CACHE_KEY="panel_cache-";
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public enum JobStatus {
|
|
||||||
Prepare, Underway, Completed, Error
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public interface NoticeConstants {
|
|
||||||
|
|
||||||
interface TaskType {
|
|
||||||
String JENKINS_TASK = "JENKINS_TASK";
|
|
||||||
String TEST_PLAN_TASK = "TEST_PLAN_TASK";
|
|
||||||
String REVIEW_TASK = "REVIEW_TASK";
|
|
||||||
String DEFECT_TASK = "DEFECT_TASK";
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Mode {
|
|
||||||
String API = "API";
|
|
||||||
String SCHEDULE = "SCHEDULE";
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Type {
|
|
||||||
String EMAIL = "EMAIL";
|
|
||||||
String NAIL_ROBOT = "NAIL_ROBOT";
|
|
||||||
String WECHAT_ROBOT = "WECHAT_ROBOT";
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Event {
|
|
||||||
String EXECUTE_SUCCESSFUL = "EXECUTE_SUCCESSFUL";
|
|
||||||
String EXECUTE_FAILED = "EXECUTE_FAILED";
|
|
||||||
String CREATE = "CREATE";
|
|
||||||
String UPDATE = "UPDATE";
|
|
||||||
String DELETE = "DELETE";
|
|
||||||
String COMMENT = "COMMENT";
|
|
||||||
}
|
|
||||||
|
|
||||||
interface RelatedUser {
|
|
||||||
String FOUNDER = "FOUNDER";//创建人
|
|
||||||
String EXECUTOR = "EXECUTOR";//负责人(评审人)
|
|
||||||
String MAINTAINER = "MAINTAINER";//维护人
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,83 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Author: wangjiahao
|
|
||||||
* Date: 2021-03-22
|
|
||||||
* Description:
|
|
||||||
*/
|
|
||||||
public class PanelConstants {
|
|
||||||
|
|
||||||
public final static String COMPONENT_TYPE_VIEW = "view";
|
|
||||||
|
|
||||||
public final static String COMPONENT_TYPE_PUBLIC = "public";
|
|
||||||
|
|
||||||
public final static String TEMPLATE_TYPE_SYSTEM = "system";
|
|
||||||
|
|
||||||
public final static String TEMPLATE_TYPE_SELF = "self";
|
|
||||||
|
|
||||||
|
|
||||||
public final static String PANEL_NODE_TYPE_FOlDER = "folder";
|
|
||||||
|
|
||||||
public final static String PANEL_NODE_TYPE_PANEL = "panel";
|
|
||||||
|
|
||||||
public final static String OPT_TYPE_INSERT = "insert";
|
|
||||||
|
|
||||||
public final static String OPT_TYPE_UPDATE = "update";
|
|
||||||
|
|
||||||
public final static String PANEL_GATHER_DEFAULT_PANEL = "default_panel";
|
|
||||||
|
|
||||||
public final static String PANEL_GATHER_PANEL_LIST = "panel_list";
|
|
||||||
|
|
||||||
|
|
||||||
//新建仪表板来源
|
|
||||||
public static final class NEW_PANEL_FROM {
|
|
||||||
|
|
||||||
// 直接新建
|
|
||||||
public static final String NEW = "new";
|
|
||||||
|
|
||||||
// 内部模板新建
|
|
||||||
public static final String NEW_INNER_TEMPLATE = "new_inner_template";
|
|
||||||
|
|
||||||
// 外部模板新建
|
|
||||||
public static final String NEW_OUTER_TEMPLATE = "new_outer_template";
|
|
||||||
|
|
||||||
// 模板市场新建
|
|
||||||
public static final String NEW_MARKET_TEMPLATE = "new_market_template";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//仪表板类型
|
|
||||||
public static final class PANEL_TYPE {
|
|
||||||
|
|
||||||
// 普通仪表板
|
|
||||||
public static final String SELF = "self";
|
|
||||||
|
|
||||||
// 默认仪表板
|
|
||||||
public static final String SYSTEM = "system";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//仪表板查询来源
|
|
||||||
public static final class QUERY_FROM {
|
|
||||||
|
|
||||||
// 普通查询
|
|
||||||
public static final String NORMAL = "normal";
|
|
||||||
|
|
||||||
// 编辑查询
|
|
||||||
public static final String EDIT = "edit";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//应用数据源来源
|
|
||||||
public static final class APP_DATASOURCE_FROM {
|
|
||||||
|
|
||||||
// 新建
|
|
||||||
public static final String NEW = "new";
|
|
||||||
|
|
||||||
// 复用
|
|
||||||
public static final String HISTORY = "history";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,181 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public interface ParamConstants {
|
|
||||||
|
|
||||||
String getValue();
|
|
||||||
|
|
||||||
enum Type implements ParamConstants {
|
|
||||||
|
|
||||||
PASSWORD("password"),
|
|
||||||
TEXT("text"),
|
|
||||||
JSON("json");
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
Type(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Classify implements ParamConstants {
|
|
||||||
MAIL("smtp"),
|
|
||||||
BASE("base"),
|
|
||||||
LDAP("ldap"),
|
|
||||||
UI("ui"),
|
|
||||||
REGISTRY("registry");
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
Classify(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Registry implements ParamConstants {
|
|
||||||
URL("registry.url"),
|
|
||||||
REPO("registry.repo"),
|
|
||||||
USERNAME("registry.username"),
|
|
||||||
PASSWORD("registry.password");
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
Registry(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum I18n implements ParamConstants {
|
|
||||||
|
|
||||||
LANGUAGE("i18n.language");
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
I18n(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum MAIL implements ParamConstants {
|
|
||||||
SERVER("smtp.host"),
|
|
||||||
PORT("smtp.port"),
|
|
||||||
ACCOUNT("smtp.account"),
|
|
||||||
PASSWORD("smtp.password"),
|
|
||||||
SSL("smtp.ssl"),
|
|
||||||
TLS("smtp.tls"),
|
|
||||||
RECIPIENTS("smtp.recipient");
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
private MAIL(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum BASIC implements ParamConstants {
|
|
||||||
FRONT_TIME_OUT("basic.frontTimeOut"),
|
|
||||||
MSG_TIME_OUT("basic.msgTimeOut"),
|
|
||||||
|
|
||||||
LOG_TIME_OUT("basic.logTimeOut"),
|
|
||||||
DS_CHECK_INTERVAL("basic.dsCheckInterval"),
|
|
||||||
DS_CHECK_INTERVAL_TYPE("basic.dsCheckIntervalType"),
|
|
||||||
DEFAULT_LOGIN_TYPE("basic.loginType"),
|
|
||||||
OPEN_HOME_PAGE("ui.openHomePage"),
|
|
||||||
AUTO_MOBILE("ui.autoMobile"),
|
|
||||||
OPEN_MARKET_PAGE("ui.openMarketPage"),
|
|
||||||
TEMPLATE_MARKET_ULR("basic.templateMarketUlr"),
|
|
||||||
|
|
||||||
LOGIN_LIMIT_LIMITTIMES("loginlimit.limitTimes"),
|
|
||||||
|
|
||||||
LOGIN_LIMIT_RELIEVETIMES("loginlimit.relieveTimes"),
|
|
||||||
|
|
||||||
LOGIN_LIMIT_OPEN("loginlimit.open"),
|
|
||||||
LOCKED_EMAIL("loginlimit.lockedEmail"),
|
|
||||||
|
|
||||||
SCAN_CREATE_USER("loginlimit.scanCreateUser"),
|
|
||||||
|
|
||||||
MULTI_LOGIN("loginlimit.multiLogin"),
|
|
||||||
TEMPLATE_ACCESS_KEY("basic.templateAccessKey");
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private BASIC(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum BASE implements ParamConstants {
|
|
||||||
URL("base.url");
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
private BASE(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum LDAP implements ParamConstants {
|
|
||||||
URL("ldap.url"),
|
|
||||||
DN("ldap.dn"),
|
|
||||||
PASSWORD("ldap.password"),
|
|
||||||
OU("ldap.ou"),
|
|
||||||
FILTER("ldap.filter"),
|
|
||||||
MAPPING("ldap.mapping"),
|
|
||||||
OPEN("ldap.open");
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
LDAP(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public class RedisConstants {
|
|
||||||
|
|
||||||
public static final String GLOBAL_REDIS_TOPIC = "global_redis_topic";
|
|
||||||
|
|
||||||
public static final String PLUGIN_INSTALL_MSG = "pluginMsgService";
|
|
||||||
|
|
||||||
public static final String WEBSOCKET_MSG = "wsMsgService";
|
|
||||||
|
|
||||||
public static final String DS_REDIS_TOPIC = "ds_redis_topic";
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public enum ResourceAuthLevel {
|
|
||||||
|
|
||||||
COMMON_LEVEL_USE(1),
|
|
||||||
|
|
||||||
PANEL_LEVEL_VIEW(1),
|
|
||||||
PANEL_LEVEL_EXPORT(3),
|
|
||||||
PANEL_LEVEL_MANAGE(5),
|
|
||||||
PANEL_LEVEL_GRANT(15),
|
|
||||||
|
|
||||||
DATASET_LEVEL_USE(1),
|
|
||||||
DATASET_LEVEL_MANAGE(3),
|
|
||||||
DATASET_LEVEL_GRANT(15),
|
|
||||||
|
|
||||||
LINK_LEVEL_USE(1),
|
|
||||||
LINK_LEVEL_MANAGE(3),
|
|
||||||
LINK_LEVEL_GRANT(15),
|
|
||||||
|
|
||||||
DATASOURCE_LEVEL_USE(1),
|
|
||||||
DATASOURCE_LEVEL_MANAGE(3),
|
|
||||||
DATASOURCE_LEVEL_GRANT(15);
|
|
||||||
|
|
||||||
private Integer level;
|
|
||||||
|
|
||||||
public Integer getLevel() {
|
|
||||||
return level;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLevel(Integer level) {
|
|
||||||
this.level = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResourceAuthLevel(Integer level) {
|
|
||||||
this.level = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public enum ScheduleGroup {
|
|
||||||
API_TEST, PERFORMANCE_TEST, API_SCENARIO_TEST, TEST_PLAN_TEST, SWAGGER_IMPORT
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public enum ScheduleType {
|
|
||||||
CRON, SIMPLE, SIMPLE_CRON
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public class SessionConstants {
|
|
||||||
public static final String ATTR_USER = "user";
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
import static io.dataease.commons.utils.StaticResourceUtils.ensureSuffix;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Author: wangjiahao
|
|
||||||
* Date: 2022/4/28
|
|
||||||
* Description:
|
|
||||||
*/
|
|
||||||
public class StaticResourceConstants {
|
|
||||||
|
|
||||||
public static final String FILE_PROTOCOL = "file://";
|
|
||||||
|
|
||||||
public static final String FILE_SEPARATOR = File.separator;
|
|
||||||
|
|
||||||
public static final String USER_HOME = "/opt/dataease/data";
|
|
||||||
|
|
||||||
public static String WORK_DIR = ensureSuffix(USER_HOME, FILE_SEPARATOR) + "static-resource" + FILE_SEPARATOR;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Upload prefix.
|
|
||||||
*/
|
|
||||||
public final static String UPLOAD_URL_PREFIX = "static-resource";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* url separator.
|
|
||||||
*/
|
|
||||||
public static final String URL_SEPARATOR = "/";
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Author: wangjiahao
|
|
||||||
* Date: 2022/4/2
|
|
||||||
* Description:
|
|
||||||
*/
|
|
||||||
public class SysAuthConstants {
|
|
||||||
|
|
||||||
public final static String AUTH_TARGET_TYPE_USER = "user";
|
|
||||||
|
|
||||||
public final static String AUTH_TARGET_TYPE_ROLE = "role";
|
|
||||||
|
|
||||||
public final static String AUTH_TARGET_TYPE_DEPT = "dept";
|
|
||||||
|
|
||||||
public final static String AUTH_SOURCE_TYPE_PANEL = "panel";
|
|
||||||
|
|
||||||
public final static String AUTH_SOURCE_TYPE_DATASET = "dataset";
|
|
||||||
|
|
||||||
public final static String AUTH_SOURCE_TYPE_DATASOURCE = "link";
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class SysLogConstants {
|
|
||||||
|
|
||||||
public static String operateTypeName(Integer value) {
|
|
||||||
Optional<OPERATE_TYPE> any = Arrays.stream(OPERATE_TYPE.class.getEnumConstants()).filter(e -> e.value == value).findAny();
|
|
||||||
if (any.isPresent()) return any.get().name;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum OPERATE_TYPE {
|
|
||||||
CREATE(1, "OPERATE_TYPE_CREATE"),
|
|
||||||
MODIFY(2, "OPERATE_TYPE_MODIFY"),
|
|
||||||
DELETE(3, "OPERATE_TYPE_DELETE"),
|
|
||||||
SHARE(4, "OPERATE_TYPE_SHARE"),
|
|
||||||
UNSHARE(5, "OPERATE_TYPE_UNSHARE"),
|
|
||||||
AUTHORIZE(6, "OPERATE_TYPE_AUTHORIZE"),
|
|
||||||
UNAUTHORIZE(7, "OPERATE_TYPE_UNAUTHORIZE"),
|
|
||||||
CREATELINK(8, "OPERATE_TYPE_CREATELINK"),
|
|
||||||
DELETELINK(9, "OPERATE_TYPE_DELETELINK"),
|
|
||||||
MODIFYLINK(10, "OPERATE_TYPE_MODIFYLINK"),
|
|
||||||
UPLOADFILE(11, "OPERATE_TYPE_UPLOADFILE"),
|
|
||||||
|
|
||||||
LOGIN(12, "OPERATE_TYPE_LOGIN"),
|
|
||||||
|
|
||||||
PC_VIEW(13, "OPERATE_TYPE_PC_VIEW"),
|
|
||||||
|
|
||||||
MB_VIEW(14, "OPERATE_TYPE_MB_VIEW"),
|
|
||||||
|
|
||||||
EXPORT(15, "OPERATE_TYPE_EXPORT"),
|
|
||||||
|
|
||||||
BIND(16, "OPERATE_TYPE_BIND"),
|
|
||||||
|
|
||||||
UNBIND(17, "OPERATE_TYPE_UNBIND");
|
|
||||||
private Integer value;
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
OPERATE_TYPE(Integer value, String name) {
|
|
||||||
this.value = value;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String sourceTypeName(Integer value) {
|
|
||||||
Optional<SOURCE_TYPE> any = Arrays.stream(SOURCE_TYPE.class.getEnumConstants()).filter(e -> e.value == value).findAny();
|
|
||||||
if (any.isPresent()) return any.get().name;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum SOURCE_TYPE {
|
|
||||||
DATASOURCE(1, "SOURCE_TYPE_DATASOURCE"),
|
|
||||||
DATASET(2, "SOURCE_TYPE_DATASET"),
|
|
||||||
PANEL(3, "SOURCE_TYPE_PANEL"),
|
|
||||||
VIEW(4, "SOURCE_TYPE_VIEW"),
|
|
||||||
LINK(5, "SOURCE_TYPE_LINK"),
|
|
||||||
USER(6, "SOURCE_TYPE_USER"),
|
|
||||||
DEPT(7, "SOURCE_TYPE_DEPT"),
|
|
||||||
ROLE(8, "SOURCE_TYPE_ROLE"),
|
|
||||||
DRIVER(9, "SOURCE_TYPE_DRIVER"),
|
|
||||||
DRIVER_FILE(10, "SOURCE_TYPE_DRIVER_FILE"),
|
|
||||||
MENU(11, "SOURCE_TYPE_MENU"),
|
|
||||||
APIKEY(12, "SOURCE_TYPE_APIKEY");
|
|
||||||
private Integer value;
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
SOURCE_TYPE(Integer value, String name) {
|
|
||||||
this.value = value;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public class SysMsgConstants {
|
|
||||||
|
|
||||||
public final static String SYS_MSG_CHANNEL = "sys_msg_channel";
|
|
||||||
public final static String SYS_MSG_TYPE = "sys_msg_type";
|
|
||||||
public final static String SYS_MSG_USER_SUBSCRIBE = "sys_msg_user_subscribe";
|
|
||||||
}
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Author: wangjiahao
|
|
||||||
* Date: 2021-03-22
|
|
||||||
* Description:
|
|
||||||
*/
|
|
||||||
public class SystemConstants {
|
|
||||||
|
|
||||||
public static final class WITH_EXTEND {
|
|
||||||
public final static String NOW = "now";
|
|
||||||
public final static String PARENT = "parent";
|
|
||||||
public final static String CHILDREN = "children";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static final class PRIVILEGE_VALUE {
|
|
||||||
public final static Integer ON = 1;
|
|
||||||
public final static Integer OFF = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class AUTH_SOURCE {
|
|
||||||
public final static String MENU = "menu";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public enum TaskStatus {
|
|
||||||
Underway, Stopped, Pending, Exec
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public enum TriggerType {
|
|
||||||
Cron, Custom
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package io.dataease.commons.constants;
|
|
||||||
|
|
||||||
public enum UpdateType {
|
|
||||||
all_scope, add_scope
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
package io.dataease.commons.exception;
|
|
||||||
|
|
||||||
public class DEException extends RuntimeException {
|
|
||||||
|
|
||||||
private DEException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DEException(Throwable t) {
|
|
||||||
super(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void throwException(String message) {
|
|
||||||
throw new DEException(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DEException getException(String message) {
|
|
||||||
throw new DEException(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void throwException(Throwable t) {
|
|
||||||
throw new DEException(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,95 +0,0 @@
|
|||||||
package io.dataease.commons.filter;
|
|
||||||
|
|
||||||
import io.dataease.commons.exception.DEException;
|
|
||||||
import io.dataease.commons.holder.ThreadLocalContextHolder;
|
|
||||||
import io.dataease.commons.wrapper.XssAndSqlHttpServletRequestWrapper;
|
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.web.context.request.RequestContextHolder;
|
|
||||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
|
||||||
|
|
||||||
import javax.servlet.*;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
|
||||||
public class SqlFilter implements Filter {
|
|
||||||
|
|
||||||
private List<String> excludedUris = new ArrayList<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void destroy() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
|
||||||
if (ObjectUtils.isEmpty(RequestContextHolder.getRequestAttributes())) {
|
|
||||||
ServletRequestAttributes attributes = new ServletRequestAttributes((HttpServletRequest) request);
|
|
||||||
RequestContextHolder.setRequestAttributes(attributes);
|
|
||||||
}
|
|
||||||
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
|
||||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
|
||||||
if ("TRACE".equalsIgnoreCase(httpRequest.getMethod()) || "TRACK".equalsIgnoreCase(httpRequest.getMethod())) {
|
|
||||||
httpResponse.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(excludedUris.contains(((HttpServletRequest) request).getRequestURI())){
|
|
||||||
chain.doFilter(request, response);
|
|
||||||
}else {
|
|
||||||
String method = "GET";
|
|
||||||
String param;
|
|
||||||
XssAndSqlHttpServletRequestWrapper xssRequest = null;
|
|
||||||
if (request instanceof HttpServletRequest) {
|
|
||||||
method = ((HttpServletRequest) request).getMethod();
|
|
||||||
xssRequest = new XssAndSqlHttpServletRequestWrapper((HttpServletRequest) request);
|
|
||||||
}
|
|
||||||
if ("POST".equalsIgnoreCase(method)) {
|
|
||||||
param = this.getBodyString(xssRequest.getReader());
|
|
||||||
if (StringUtils.isNotBlank(param)) {
|
|
||||||
if (xssRequest.checkXSSAndSql(param)) {
|
|
||||||
response.setCharacterEncoding("UTF-8");
|
|
||||||
response.setContentType("application/json;charset=UTF-8");
|
|
||||||
String msg = ThreadLocalContextHolder.getData().toString();
|
|
||||||
DEException.throwException(msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (xssRequest.checkParameter()) {
|
|
||||||
response.setCharacterEncoding("UTF-8");
|
|
||||||
response.setContentType("application/json;charset=UTF-8");
|
|
||||||
String msg = ThreadLocalContextHolder.getData().toString();
|
|
||||||
DEException.throwException(msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
chain.doFilter(xssRequest, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(FilterConfig filterConfig) throws ServletException {
|
|
||||||
excludedUris.add("/dataset/table/excel/upload");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取request请求body中参数
|
|
||||||
public static String getBodyString(BufferedReader br) {
|
|
||||||
String inputLine;
|
|
||||||
String str = "";
|
|
||||||
try {
|
|
||||||
while ((inputLine = br.readLine()) != null) {
|
|
||||||
str += inputLine;
|
|
||||||
}
|
|
||||||
br.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
package io.dataease.commons.holder;
|
|
||||||
|
|
||||||
public class ThreadLocalContextHolder {
|
|
||||||
|
|
||||||
|
|
||||||
private static ThreadLocal<Object> sceneThreadLocal = new ThreadLocal<>();
|
|
||||||
|
|
||||||
|
|
||||||
public static Object getData() {
|
|
||||||
return sceneThreadLocal.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setData(Object data) {
|
|
||||||
if (ThreadLocalContextHolder.sceneThreadLocal == null) {
|
|
||||||
ThreadLocalContextHolder.sceneThreadLocal = new ThreadLocal<>();
|
|
||||||
}
|
|
||||||
ThreadLocalContextHolder.sceneThreadLocal.set(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void clearScene() {
|
|
||||||
setData(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,125 +0,0 @@
|
|||||||
package io.dataease.commons.license;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import io.dataease.commons.exception.DEException;
|
|
||||||
import io.dataease.commons.utils.LogUtil;
|
|
||||||
import io.dataease.plugins.common.base.domain.License;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class DefaultLicenseService {
|
|
||||||
@Resource
|
|
||||||
private InnerLicenseService innerLicenseService;
|
|
||||||
|
|
||||||
private static final String LICENSE_ID = "fit2cloud_license";
|
|
||||||
private static final String validatorUtil = "/usr/bin/validator";
|
|
||||||
private static final String product = "DataEase";
|
|
||||||
|
|
||||||
@Value("${dataease.use_process_lic:false}")
|
|
||||||
private boolean useProcessLic;
|
|
||||||
|
|
||||||
public F2CLicenseResponse validateLicense(String product, String licenseKey) {
|
|
||||||
List<String> command = new ArrayList<String>();
|
|
||||||
StringBuilder result = new StringBuilder();
|
|
||||||
command.add(validatorUtil);
|
|
||||||
command.add(licenseKey);
|
|
||||||
try {
|
|
||||||
if (useProcessLic) {
|
|
||||||
execCommand(result, command);
|
|
||||||
} else {
|
|
||||||
runtimeExecCommand(result, command);
|
|
||||||
}
|
|
||||||
|
|
||||||
LogUtil.info("read lic content is : " + result.toString());
|
|
||||||
F2CLicenseResponse f2CLicenseResponse = new Gson().fromJson(result.toString(), F2CLicenseResponse.class);
|
|
||||||
if (f2CLicenseResponse.getStatus() != F2CLicenseResponse.Status.valid) {
|
|
||||||
return f2CLicenseResponse;
|
|
||||||
}
|
|
||||||
if (!StringUtils.equals(f2CLicenseResponse.getLicense().getProduct(), product)) {
|
|
||||||
f2CLicenseResponse.setStatus(F2CLicenseResponse.Status.invalid);
|
|
||||||
f2CLicenseResponse.setLicense(null);
|
|
||||||
f2CLicenseResponse.setMessage("The license is unavailable for this product.");
|
|
||||||
return f2CLicenseResponse;
|
|
||||||
}
|
|
||||||
return f2CLicenseResponse;
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogUtil.error(e.getMessage());
|
|
||||||
return F2CLicenseResponse.noRecord();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void runtimeExecCommand(StringBuilder result, List<String> command) throws Exception {
|
|
||||||
Process proc = Runtime.getRuntime().exec(command.stream().collect(Collectors.joining(" ")));
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream(), "utf-8"));
|
|
||||||
String line = null;
|
|
||||||
while ((line = reader.readLine()) != null) {
|
|
||||||
result.append(line).append("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static void execCommand(StringBuilder result, List<String> command) throws Exception {
|
|
||||||
ProcessBuilder builder = new ProcessBuilder();
|
|
||||||
builder.command(command);
|
|
||||||
Process process = builder.start();
|
|
||||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
|
||||||
String line = null;
|
|
||||||
while ((line = bufferedReader.readLine()) != null) {
|
|
||||||
result.append(line).append("\n");
|
|
||||||
}
|
|
||||||
command.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public F2CLicenseResponse validateLicense() {
|
|
||||||
try {
|
|
||||||
License license = readLicense();
|
|
||||||
return validateLicense(product, license.getLicense());
|
|
||||||
} catch (Exception e) {
|
|
||||||
return F2CLicenseResponse.noRecord();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public F2CLicenseResponse updateLicense(String product, String licenseKey) {
|
|
||||||
// 验证license
|
|
||||||
F2CLicenseResponse response = validateLicense(product, licenseKey);
|
|
||||||
if (response.getStatus() != F2CLicenseResponse.Status.valid) {
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
// 覆盖原license
|
|
||||||
writeLicense(licenseKey, response);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 从数据库读取License
|
|
||||||
public License readLicense() {
|
|
||||||
License license = innerLicenseService.getLicense(LICENSE_ID);
|
|
||||||
if (license == null) {
|
|
||||||
DEException.throwException("i18n_no_license_record");
|
|
||||||
}
|
|
||||||
if (StringUtils.isBlank(license.getLicense())) {
|
|
||||||
DEException.throwException("i18n_license_is_empty");
|
|
||||||
}
|
|
||||||
return license;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建或更新License
|
|
||||||
private void writeLicense(String licenseKey, F2CLicenseResponse response) {
|
|
||||||
if (StringUtils.isBlank(licenseKey)) {
|
|
||||||
DEException.throwException("i18n_license_is_empty");
|
|
||||||
}
|
|
||||||
License license = new License();
|
|
||||||
license.setId(LICENSE_ID);
|
|
||||||
license.setLicense(licenseKey);
|
|
||||||
license.setF2cLicense(new Gson().toJson(response));
|
|
||||||
innerLicenseService.saveLicense(license);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user