forked from github/dataease
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
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
/.idea/
|
||||
.idea/
|
||||
target/
|
||||
.vscode/
|
||||
.lh/
|
||||
*.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
|
||||
|
||||
hs_err_pid*
|
||||
node_modules/
|
||||
dist/
|
||||
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]
|
||||
Rela = "Rela"
|
||||
eles = "eles"
|
||||
delink = "delink"
|
||||
testng = "testng"
|
||||
ba = "ba"
|
||||
referer = "referer"
|
||||
keynode = "keynode"
|
||||
SCHEM = "SCHEM"
|
||||
|
||||
ser = "ser"
|
||||
Referer = "Referer"
|
||||
Encryp = "Encryp"
|
||||
[files]
|
||||
extend-exclude = [
|
||||
"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"
|
||||
]
|
||||
|
||||
extend-exclude = ["mapFiles/**"]
|
||||
|
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
|
||||
|
||||
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
|
||||
|
||||
HEALTHCHECK --interval=15s --timeout=5s --retries=20 --start-period=30s CMD curl -f 127.0.0.1:8081
|
||||
|
||||
CMD ["/deployments/run-java.sh"]
|
||||
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
|
||||
|
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