refactor: 初始化v2

This commit is contained in:
fit2cloud-chenyw 2023-10-23 21:58:50 +08:00
parent e6402ff9b9
commit 910d5b26ab
10068 changed files with 174 additions and 548930 deletions

View File

@ -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 }}

View File

@ -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: '状态:待处理'

View File

@ -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 }}

View File

@ -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
View File

@ -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/

View File

@ -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/**"]

View File

@ -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
View File

@ -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

View File

@ -1,5 +0,0 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
cd ./frontend
npm run lint-staged

View File

@ -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/

View File

@ -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>

View File

@ -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);
}
}

View File

@ -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 "";
}

View File

@ -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 "";
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 {};
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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()));
}
}

View File

@ -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();
}
}

View File

@ -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()))));
}
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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: 默认登录
* 1ldap登录
* 2单点登录
*/
@ApiModelProperty(value = "登录方式{0:普通登录, 1:ldap登录}", required = true, allowableValues = "0, 1")
private int loginType;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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) {
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -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()));
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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";
}

View File

@ -1,7 +0,0 @@
package io.dataease.commons.constants;
public class ColumnPermissionConstants {
public final static String Prohibit = "Prohibit";
public final static String Desensitization = "Desensitization";
}

View File

@ -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";
}
}

View File

@ -1,6 +0,0 @@
package io.dataease.commons.constants;
public class DatasetMode {
public static final String EXTRACT = "1";
public static final String DIRECT = "0";
}

View File

@ -1,5 +0,0 @@
package io.dataease.commons.constants;
public enum DePermissionType {
DATASOURCE, DATASET, PANEL
}

View File

@ -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;
}
}

View File

@ -1,6 +0,0 @@
package io.dataease.commons.constants;
public class I18nConstants {
public static final String LANG_COOKIE_NAME = "DE_USER_LANG";
}

View File

@ -1,5 +0,0 @@
package io.dataease.commons.constants;
public enum IssuesManagePlatform {
Tapd, Jira, Local, Zentao
}

View File

@ -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-";
}

View File

@ -1,5 +0,0 @@
package io.dataease.commons.constants;
public enum JobStatus {
Prepare, Underway, Completed, Error
}

View File

@ -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";//维护人
}
}

View File

@ -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";
}
}

View File

@ -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;
}
}
}

View File

@ -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";
}

View File

@ -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;
}
}

View File

@ -1,5 +0,0 @@
package io.dataease.commons.constants;
public enum ScheduleGroup {
API_TEST, PERFORMANCE_TEST, API_SCENARIO_TEST, TEST_PLAN_TEST, SWAGGER_IMPORT
}

View File

@ -1,5 +0,0 @@
package io.dataease.commons.constants;
public enum ScheduleType {
CRON, SIMPLE, SIMPLE_CRON
}

View File

@ -1,5 +0,0 @@
package io.dataease.commons.constants;
public class SessionConstants {
public static final String ATTR_USER = "user";
}

View File

@ -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 = "/";
}

View File

@ -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";
}

View File

@ -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;
}
}
}

View File

@ -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";
}

View File

@ -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";
}
}

View File

@ -1,5 +0,0 @@
package io.dataease.commons.constants;
public enum TaskStatus {
Underway, Stopped, Pending, Exec
}

View File

@ -1,5 +0,0 @@
package io.dataease.commons.constants;
public enum TriggerType {
Cron, Custom
}

View File

@ -1,5 +0,0 @@
package io.dataease.commons.constants;
public enum UpdateType {
all_scope, add_scope
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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