first commit

This commit is contained in:
jerryjzhang
2023-06-12 18:44:01 +08:00
commit dc4fc69b57
879 changed files with 573090 additions and 0 deletions

41
auth/api/pom.xml Normal file
View File

@@ -0,0 +1,41 @@
<?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>
<groupId>com.tencent.supersonic</groupId>
<artifactId>auth</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>auth-api</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.supersonic</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>

View File

@@ -0,0 +1,26 @@
package com.tencent.supersonic.auth.api.authentication.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
public class AuthenticationConfig {
@Value("${authentication.exclude.path:XXX}")
private String excludePath;
@Value("${authentication.enable:false}")
private boolean enabled;
@Value("${authentication.token.secret:secret}")
private String tokenSecret;
@Value("${authentication.token.http.header.key:Auth}")
private String tokenHttpHeaderKey;
}

View File

@@ -0,0 +1,26 @@
package com.tencent.supersonic.auth.api.authentication.constant;
public class UserConstants {
public static final String TOKEN_USER_ID = "token_user_id";
public static final String TOKEN_USER_NAME = "token_user_name";
public static final String TOKEN_USER_PASSWORD = "token_user_password";
public static final String TOKEN_USER_DISPLAY_NAME = "token_user_display_name";
public static final String TOKEN_USER_EMAIL = "token_user_email";
public static final String TOKEN_ALGORITHM = "HS512";
public static final String TOKEN_CREATE_TIME = "token_create_time";
public static final String TOKEN_PREFIX = "Bearer";
public static final Long TOKEN_TIME_OUT = 25920000000L;
public static final String INTERNAL = "internal";
}

View File

@@ -0,0 +1,34 @@
package com.tencent.supersonic.auth.api.authentication.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Long id;
private String name;
private String displayName;
private String email;
public static User get(Long id, String name, String displayName, String email) {
return new User(id, name, displayName, email);
}
public static User getFakeUser() {
return new User(1L, "admin", "admin", "admin@email");
}
public String getDisplayName() {
return StringUtils.isBlank(displayName) ? name : displayName;
}
}

View File

@@ -0,0 +1,21 @@
package com.tencent.supersonic.auth.api.authentication.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class UserWithPassword extends User {
private String password;
public UserWithPassword(Long id, String name, String displayName, String email, String password) {
super(id, name, displayName, email);
this.password = password;
}
public static UserWithPassword get(Long id, String name, String displayName, String email, String password) {
return new UserWithPassword(id, name, displayName, email, password);
}
}

View File

@@ -0,0 +1,17 @@
package com.tencent.supersonic.auth.api.authentication.request;
import javax.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class UserReq {
@NotBlank(message = "name can not be null")
private String name;
@NotBlank(message = "password can not be null")
private String password;
}

View File

@@ -0,0 +1,17 @@
package com.tencent.supersonic.auth.api.authentication.service;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.request.UserReq;
import java.util.List;
public interface UserService {
List<String> getUserNames();
List<User> getUserList();
void register(UserReq userCmd);
String login(UserReq userCmd);
}

View File

@@ -0,0 +1,14 @@
package com.tencent.supersonic.auth.api.authentication.service;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface UserStrategy {
boolean accept(boolean isEnableAuthentication);
User findUser(HttpServletRequest request, HttpServletResponse response);
}

View File

@@ -0,0 +1,20 @@
package com.tencent.supersonic.auth.api.authentication.utils;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.service.UserStrategy;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public final class UserHolder {
private static UserStrategy REPO;
public static synchronized void setStrategy(UserStrategy strategy) {
REPO = strategy;
}
public static User findUser(HttpServletRequest request, HttpServletResponse response) {
return REPO.findUser(request, response);
}
}

View File

@@ -0,0 +1,20 @@
package com.tencent.supersonic.auth.api.authorization.pojo;
import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class AuthRes {
private String domainId;
private String name;
public AuthRes() {
}
public AuthRes(String domainId, String name) {
this.domainId = domainId;
this.name = name;
}
}

View File

@@ -0,0 +1,11 @@
package com.tencent.supersonic.auth.api.authorization.pojo;
import java.util.ArrayList;
import java.util.List;
import lombok.Data;
@Data
public class AuthResGrp {
private List<AuthRes> group = new ArrayList<>();
}

View File

@@ -0,0 +1,12 @@
package com.tencent.supersonic.auth.api.authorization.pojo;
import java.util.ArrayList;
import java.util.List;
import lombok.Data;
@Data
public class DimensionFilter {
private List<String> expressions = new ArrayList<>();
private String description;
}

View File

@@ -0,0 +1,11 @@
package com.tencent.supersonic.auth.api.authorization.request;
import java.util.List;
import lombok.Data;
@Data
public class AddUsersToGroupReq {
private Integer groupId;
private List<String> users;
}

View File

@@ -0,0 +1,16 @@
package com.tencent.supersonic.auth.api.authorization.request;
import com.tencent.supersonic.auth.api.authorization.pojo.AuthRes;
import java.util.List;
import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class QueryAuthResReq {
private String user;
private List<AuthRes> resources;
private String domainId;
}

View File

@@ -0,0 +1,13 @@
package com.tencent.supersonic.auth.api.authorization.request;
import com.tencent.supersonic.common.request.PageBaseReq;
import java.util.List;
import lombok.Data;
@Data
public class QueryGroupReq extends PageBaseReq {
private List<Integer> groupIds;
private List<String> users;
}

View File

@@ -0,0 +1,10 @@
package com.tencent.supersonic.auth.api.authorization.request;
import java.util.List;
import lombok.Data;
@Data
public class RemoveGroupReq {
private List<Integer> groupIds;
}

View File

@@ -0,0 +1,11 @@
package com.tencent.supersonic.auth.api.authorization.request;
import java.util.List;
import lombok.Data;
@Data
public class RemoveUsersFromGroupReq {
private Integer groupId;
private List<String> users;
}

View File

@@ -0,0 +1,16 @@
package com.tencent.supersonic.auth.api.authorization.response;
import com.tencent.supersonic.auth.api.authorization.pojo.AuthResGrp;
import com.tencent.supersonic.auth.api.authorization.pojo.DimensionFilter;
import java.util.ArrayList;
import java.util.List;
import lombok.Data;
@Data
public class AuthorizedResourceResp {
private List<AuthResGrp> resources = new ArrayList<>();
private List<DimensionFilter> filters = new ArrayList<>();
}

View File

@@ -0,0 +1,10 @@
package com.tencent.supersonic.auth.api.authorization.service;
import com.tencent.supersonic.auth.api.authorization.request.QueryAuthResReq;
import com.tencent.supersonic.auth.api.authorization.response.AuthorizedResourceResp;
import javax.servlet.http.HttpServletRequest;
public interface AuthService {
AuthorizedResourceResp queryAuthorizedResources(HttpServletRequest request, QueryAuthResReq req);
}

View File

@@ -0,0 +1,82 @@
<?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>auth</artifactId>
<groupId>com.tencent.supersonic</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>auth-authentication</artifactId>
<dependencies>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jjwt.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${alibaba.druid.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>${pagehelper.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.tencent.supersonic</groupId>
<artifactId>auth-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.tencent.supersonic</groupId>
<artifactId>common</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,89 @@
package com.tencent.supersonic.auth.authentication.application;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.pojo.UserWithPassword;
import com.tencent.supersonic.auth.api.authentication.request.UserReq;
import com.tencent.supersonic.auth.api.authentication.service.UserService;
import com.tencent.supersonic.auth.authentication.domain.dataobject.UserDO;
import com.tencent.supersonic.auth.authentication.domain.repository.UserRepository;
import com.tencent.supersonic.auth.authentication.domain.utils.UserTokenUtils;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
private UserRepository userRepository;
private UserTokenUtils userTokenUtils;
public UserServiceImpl(UserRepository userRepository, UserTokenUtils userTokenUtils) {
this.userRepository = userRepository;
this.userTokenUtils = userTokenUtils;
}
private List<UserDO> getUserDOList() {
return userRepository.getUserList();
}
private UserDO getUser(String name) {
return userRepository.getUser(name);
}
public boolean checkExist(UserWithPassword user) {
UserDO userDO = getUser(user.getName());
if (userDO == null) {
return false;
}
return userDO.getPassword().equals(user.getPassword());
}
@Override
public List<String> getUserNames() {
return getUserDOList().stream().map(UserDO::getName).collect(Collectors.toList());
}
@Override
public List<User> getUserList() {
List<UserDO> userDOS = getUserDOList();
return userDOS.stream().map(this::convert).collect(Collectors.toList());
}
private User convert(UserDO userDO) {
User user = new User();
BeanUtils.copyProperties(userDO, user);
return user;
}
@Override
public void register(UserReq userReq) {
List<String> userDOS = getUserNames();
if (userDOS.contains(userReq.getName())) {
throw new RuntimeException(String.format("user %s exist", userReq.getName()));
}
UserDO userDO = new UserDO();
BeanUtils.copyProperties(userReq, userDO);
userRepository.addUser(userDO);
}
@Override
public String login(UserReq userReq) {
UserDO userDO = getUser(userReq.getName());
if (userDO == null) {
throw new RuntimeException("user not exist,please register");
}
if (userDO.getPassword().equals(userReq.getPassword())) {
UserWithPassword user = UserWithPassword.get(userDO.getId(), userDO.getName(), userDO.getDisplayName(),
userDO.getEmail(), userDO.getPassword());
return userTokenUtils.generateToken(user);
}
throw new RuntimeException("password not correct, please try again");
}
}

View File

@@ -0,0 +1,99 @@
package com.tencent.supersonic.auth.authentication.domain.dataobject;
public class UserDO {
/**
*
*/
private Long id;
/**
*
*/
private String name;
/**
*
*/
private String password;
/**
*
*/
private String displayName;
/**
*
*/
private String email;
/**
* @return id
*/
public Long getId() {
return id;
}
/**
* @param id
*/
public void setId(Long id) {
this.id = id;
}
/**
* @return name
*/
public String getName() {
return name;
}
/**
* @param name
*/
public void setName(String name) {
this.name = name == null ? null : name.trim();
}
/**
* @return password
*/
public String getPassword() {
return password;
}
/**
* @param password
*/
public void setPassword(String password) {
this.password = password == null ? null : password.trim();
}
/**
* @return display_name
*/
public String getDisplayName() {
return displayName;
}
/**
* @param displayName
*/
public void setDisplayName(String displayName) {
this.displayName = displayName == null ? null : displayName.trim();
}
/**
* @return email
*/
public String getEmail() {
return email;
}
/**
* @param email
*/
public void setEmail(String email) {
this.email = email == null ? null : email.trim();
}
}

View File

@@ -0,0 +1,632 @@
package com.tencent.supersonic.auth.authentication.domain.dataobject;
import java.util.ArrayList;
import java.util.List;
public class UserDOExample {
/**
* s2_user
*/
protected String orderByClause;
/**
* s2_user
*/
protected boolean distinct;
/**
* s2_user
*/
protected List<Criteria> oredCriteria;
/**
* s2_user
*/
protected Integer limitStart;
/**
* s2_user
*/
protected Integer limitEnd;
/**
* @mbg.generated
*/
public UserDOExample() {
oredCriteria = new ArrayList<Criteria>();
}
/**
* @mbg.generated
*/
public void setOrderByClause(String orderByClause) {
this.orderByClause = orderByClause;
}
/**
* @mbg.generated
*/
public String getOrderByClause() {
return orderByClause;
}
/**
* @mbg.generated
*/
public void setDistinct(boolean distinct) {
this.distinct = distinct;
}
/**
* @mbg.generated
*/
public boolean isDistinct() {
return distinct;
}
/**
* @mbg.generated
*/
public List<Criteria> getOredCriteria() {
return oredCriteria;
}
/**
* @mbg.generated
*/
public void or(Criteria criteria) {
oredCriteria.add(criteria);
}
/**
* @mbg.generated
*/
public Criteria or() {
Criteria criteria = createCriteriaInternal();
oredCriteria.add(criteria);
return criteria;
}
/**
* @mbg.generated
*/
public Criteria createCriteria() {
Criteria criteria = createCriteriaInternal();
if (oredCriteria.size() == 0) {
oredCriteria.add(criteria);
}
return criteria;
}
/**
* @mbg.generated
*/
protected Criteria createCriteriaInternal() {
Criteria criteria = new Criteria();
return criteria;
}
/**
* @mbg.generated
*/
public void clear() {
oredCriteria.clear();
orderByClause = null;
distinct = false;
}
/**
* @mbg.generated
*/
public void setLimitStart(Integer limitStart) {
this.limitStart = limitStart;
}
/**
* @mbg.generated
*/
public Integer getLimitStart() {
return limitStart;
}
/**
* @mbg.generated
*/
public void setLimitEnd(Integer limitEnd) {
this.limitEnd = limitEnd;
}
/**
* @mbg.generated
*/
public Integer getLimitEnd() {
return limitEnd;
}
/**
* s2_user null
*/
protected abstract static class GeneratedCriteria {
protected List<Criterion> criteria;
protected GeneratedCriteria() {
super();
criteria = new ArrayList<Criterion>();
}
public boolean isValid() {
return criteria.size() > 0;
}
public List<Criterion> getAllCriteria() {
return criteria;
}
public List<Criterion> getCriteria() {
return criteria;
}
protected void addCriterion(String condition) {
if (condition == null) {
throw new RuntimeException("Value for condition cannot be null");
}
criteria.add(new Criterion(condition));
}
protected void addCriterion(String condition, Object value, String property) {
if (value == null) {
throw new RuntimeException("Value for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value));
}
protected void addCriterion(String condition, Object value1, Object value2, String property) {
if (value1 == null || value2 == null) {
throw new RuntimeException("Between values for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value1, value2));
}
public Criteria andIdIsNull() {
addCriterion("id is null");
return (Criteria) this;
}
public Criteria andIdIsNotNull() {
addCriterion("id is not null");
return (Criteria) this;
}
public Criteria andIdEqualTo(Long value) {
addCriterion("id =", value, "id");
return (Criteria) this;
}
public Criteria andIdNotEqualTo(Long value) {
addCriterion("id <>", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThan(Long value) {
addCriterion("id >", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThanOrEqualTo(Long value) {
addCriterion("id >=", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThan(Long value) {
addCriterion("id <", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThanOrEqualTo(Long value) {
addCriterion("id <=", value, "id");
return (Criteria) this;
}
public Criteria andIdIn(List<Long> values) {
addCriterion("id in", values, "id");
return (Criteria) this;
}
public Criteria andIdNotIn(List<Long> values) {
addCriterion("id not in", values, "id");
return (Criteria) this;
}
public Criteria andIdBetween(Long value1, Long value2) {
addCriterion("id between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andIdNotBetween(Long value1, Long value2) {
addCriterion("id not between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andNameIsNull() {
addCriterion("name is null");
return (Criteria) this;
}
public Criteria andNameIsNotNull() {
addCriterion("name is not null");
return (Criteria) this;
}
public Criteria andNameEqualTo(String value) {
addCriterion("name =", value, "name");
return (Criteria) this;
}
public Criteria andNameNotEqualTo(String value) {
addCriterion("name <>", value, "name");
return (Criteria) this;
}
public Criteria andNameGreaterThan(String value) {
addCriterion("name >", value, "name");
return (Criteria) this;
}
public Criteria andNameGreaterThanOrEqualTo(String value) {
addCriterion("name >=", value, "name");
return (Criteria) this;
}
public Criteria andNameLessThan(String value) {
addCriterion("name <", value, "name");
return (Criteria) this;
}
public Criteria andNameLessThanOrEqualTo(String value) {
addCriterion("name <=", value, "name");
return (Criteria) this;
}
public Criteria andNameLike(String value) {
addCriterion("name like", value, "name");
return (Criteria) this;
}
public Criteria andNameNotLike(String value) {
addCriterion("name not like", value, "name");
return (Criteria) this;
}
public Criteria andNameIn(List<String> values) {
addCriterion("name in", values, "name");
return (Criteria) this;
}
public Criteria andNameNotIn(List<String> values) {
addCriterion("name not in", values, "name");
return (Criteria) this;
}
public Criteria andNameBetween(String value1, String value2) {
addCriterion("name between", value1, value2, "name");
return (Criteria) this;
}
public Criteria andNameNotBetween(String value1, String value2) {
addCriterion("name not between", value1, value2, "name");
return (Criteria) this;
}
public Criteria andPasswordIsNull() {
addCriterion("password is null");
return (Criteria) this;
}
public Criteria andPasswordIsNotNull() {
addCriterion("password is not null");
return (Criteria) this;
}
public Criteria andPasswordEqualTo(String value) {
addCriterion("password =", value, "password");
return (Criteria) this;
}
public Criteria andPasswordNotEqualTo(String value) {
addCriterion("password <>", value, "password");
return (Criteria) this;
}
public Criteria andPasswordGreaterThan(String value) {
addCriterion("password >", value, "password");
return (Criteria) this;
}
public Criteria andPasswordGreaterThanOrEqualTo(String value) {
addCriterion("password >=", value, "password");
return (Criteria) this;
}
public Criteria andPasswordLessThan(String value) {
addCriterion("password <", value, "password");
return (Criteria) this;
}
public Criteria andPasswordLessThanOrEqualTo(String value) {
addCriterion("password <=", value, "password");
return (Criteria) this;
}
public Criteria andPasswordLike(String value) {
addCriterion("password like", value, "password");
return (Criteria) this;
}
public Criteria andPasswordNotLike(String value) {
addCriterion("password not like", value, "password");
return (Criteria) this;
}
public Criteria andPasswordIn(List<String> values) {
addCriterion("password in", values, "password");
return (Criteria) this;
}
public Criteria andPasswordNotIn(List<String> values) {
addCriterion("password not in", values, "password");
return (Criteria) this;
}
public Criteria andPasswordBetween(String value1, String value2) {
addCriterion("password between", value1, value2, "password");
return (Criteria) this;
}
public Criteria andPasswordNotBetween(String value1, String value2) {
addCriterion("password not between", value1, value2, "password");
return (Criteria) this;
}
public Criteria andDisplayNameIsNull() {
addCriterion("display_name is null");
return (Criteria) this;
}
public Criteria andDisplayNameIsNotNull() {
addCriterion("display_name is not null");
return (Criteria) this;
}
public Criteria andDisplayNameEqualTo(String value) {
addCriterion("display_name =", value, "displayName");
return (Criteria) this;
}
public Criteria andDisplayNameNotEqualTo(String value) {
addCriterion("display_name <>", value, "displayName");
return (Criteria) this;
}
public Criteria andDisplayNameGreaterThan(String value) {
addCriterion("display_name >", value, "displayName");
return (Criteria) this;
}
public Criteria andDisplayNameGreaterThanOrEqualTo(String value) {
addCriterion("display_name >=", value, "displayName");
return (Criteria) this;
}
public Criteria andDisplayNameLessThan(String value) {
addCriterion("display_name <", value, "displayName");
return (Criteria) this;
}
public Criteria andDisplayNameLessThanOrEqualTo(String value) {
addCriterion("display_name <=", value, "displayName");
return (Criteria) this;
}
public Criteria andDisplayNameLike(String value) {
addCriterion("display_name like", value, "displayName");
return (Criteria) this;
}
public Criteria andDisplayNameNotLike(String value) {
addCriterion("display_name not like", value, "displayName");
return (Criteria) this;
}
public Criteria andDisplayNameIn(List<String> values) {
addCriterion("display_name in", values, "displayName");
return (Criteria) this;
}
public Criteria andDisplayNameNotIn(List<String> values) {
addCriterion("display_name not in", values, "displayName");
return (Criteria) this;
}
public Criteria andDisplayNameBetween(String value1, String value2) {
addCriterion("display_name between", value1, value2, "displayName");
return (Criteria) this;
}
public Criteria andDisplayNameNotBetween(String value1, String value2) {
addCriterion("display_name not between", value1, value2, "displayName");
return (Criteria) this;
}
public Criteria andEmailIsNull() {
addCriterion("email is null");
return (Criteria) this;
}
public Criteria andEmailIsNotNull() {
addCriterion("email is not null");
return (Criteria) this;
}
public Criteria andEmailEqualTo(String value) {
addCriterion("email =", value, "email");
return (Criteria) this;
}
public Criteria andEmailNotEqualTo(String value) {
addCriterion("email <>", value, "email");
return (Criteria) this;
}
public Criteria andEmailGreaterThan(String value) {
addCriterion("email >", value, "email");
return (Criteria) this;
}
public Criteria andEmailGreaterThanOrEqualTo(String value) {
addCriterion("email >=", value, "email");
return (Criteria) this;
}
public Criteria andEmailLessThan(String value) {
addCriterion("email <", value, "email");
return (Criteria) this;
}
public Criteria andEmailLessThanOrEqualTo(String value) {
addCriterion("email <=", value, "email");
return (Criteria) this;
}
public Criteria andEmailLike(String value) {
addCriterion("email like", value, "email");
return (Criteria) this;
}
public Criteria andEmailNotLike(String value) {
addCriterion("email not like", value, "email");
return (Criteria) this;
}
public Criteria andEmailIn(List<String> values) {
addCriterion("email in", values, "email");
return (Criteria) this;
}
public Criteria andEmailNotIn(List<String> values) {
addCriterion("email not in", values, "email");
return (Criteria) this;
}
public Criteria andEmailBetween(String value1, String value2) {
addCriterion("email between", value1, value2, "email");
return (Criteria) this;
}
public Criteria andEmailNotBetween(String value1, String value2) {
addCriterion("email not between", value1, value2, "email");
return (Criteria) this;
}
}
/**
* s2_user
*/
public static class Criteria extends GeneratedCriteria {
protected Criteria() {
super();
}
}
/**
* s2_user null
*/
public static class Criterion {
private String condition;
private Object value;
private Object secondValue;
private boolean noValue;
private boolean singleValue;
private boolean betweenValue;
private boolean listValue;
private String typeHandler;
public String getCondition() {
return condition;
}
public Object getValue() {
return value;
}
public Object getSecondValue() {
return secondValue;
}
public boolean isNoValue() {
return noValue;
}
public boolean isSingleValue() {
return singleValue;
}
public boolean isBetweenValue() {
return betweenValue;
}
public boolean isListValue() {
return listValue;
}
public String getTypeHandler() {
return typeHandler;
}
protected Criterion(String condition) {
super();
this.condition = condition;
this.typeHandler = null;
this.noValue = true;
}
protected Criterion(String condition, Object value, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.typeHandler = typeHandler;
if (value instanceof List<?>) {
this.listValue = true;
} else {
this.singleValue = true;
}
}
protected Criterion(String condition, Object value) {
this(condition, value, null);
}
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.secondValue = secondValue;
this.typeHandler = typeHandler;
this.betweenValue = true;
}
protected Criterion(String condition, Object value, Object secondValue) {
this(condition, value, secondValue, null);
}
}
}

View File

@@ -0,0 +1,13 @@
package com.tencent.supersonic.auth.authentication.domain.interceptor;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthenticationIgnore {
}

View File

@@ -0,0 +1,89 @@
package com.tencent.supersonic.auth.authentication.domain.interceptor;
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
import com.tencent.supersonic.auth.api.authentication.constant.UserConstants;
import com.tencent.supersonic.auth.authentication.application.UserServiceImpl;
import com.tencent.supersonic.auth.authentication.domain.utils.UserTokenUtils;
import com.tencent.supersonic.common.util.context.S2ThreadContext;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.catalina.connector.RequestFacade;
import org.apache.logging.log4j.util.Strings;
import org.apache.tomcat.util.http.MimeHeaders;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
import org.springframework.web.servlet.HandlerInterceptor;
public abstract class AuthenticationInterceptor implements HandlerInterceptor {
protected AuthenticationConfig authenticationConfig;
protected UserServiceImpl userServiceImpl;
protected UserTokenUtils userTokenUtils;
protected S2ThreadContext s2ThreadContext;
protected boolean isExcludedUri(String uri) {
String excludePathStr = authenticationConfig.getExcludePath();
if (Strings.isEmpty(excludePathStr)) {
return false;
}
List<String> excludePaths = Arrays.asList(excludePathStr.split(","));
if (CollectionUtils.isEmpty(excludePaths)) {
return false;
}
return excludePaths.stream().anyMatch(uri::startsWith);
}
protected boolean isInternalRequest(HttpServletRequest request) {
String internal = request.getHeader(UserConstants.INTERNAL);
return "true".equalsIgnoreCase(internal);
}
protected void reflectSetparam(HttpServletRequest request, String key, String value) {
try {
if (request instanceof StandardMultipartHttpServletRequest) {
RequestFacade servletRequest =
(RequestFacade) ((StandardMultipartHttpServletRequest) request).getRequest();
Class<? extends HttpServletRequest> servletRequestClazz = servletRequest.getClass();
Field request1 = servletRequestClazz.getDeclaredField("request");
request1.setAccessible(true);
Object o = request1.get(servletRequest);
Field coyoteRequest = o.getClass().getDeclaredField("coyoteRequest");
coyoteRequest.setAccessible(true);
Object o1 = coyoteRequest.get(o);
Field headers = o1.getClass().getDeclaredField("headers");
headers.setAccessible(true);
MimeHeaders o2 = (MimeHeaders) headers.get(o1);
if (o2.getValue(key) != null) {
o2.setValue(key).setString(value);
} else {
o2.addValue(key).setString(value);
}
} else {
Class<? extends HttpServletRequest> requestClass = request.getClass();
Field request1 = requestClass.getDeclaredField("request");
request1.setAccessible(true);
Object o = request1.get(request);
Field coyoteRequest = o.getClass().getDeclaredField("coyoteRequest");
coyoteRequest.setAccessible(true);
Object o1 = coyoteRequest.get(o);
Field headers = o1.getClass().getDeclaredField("headers");
headers.setAccessible(true);
MimeHeaders o2 = (MimeHeaders) headers.get(o1);
o2.addValue(key).setString(value);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,64 @@
package com.tencent.supersonic.auth.authentication.domain.interceptor;
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
import com.tencent.supersonic.auth.api.authentication.pojo.UserWithPassword;
import com.tencent.supersonic.auth.authentication.application.UserServiceImpl;
import com.tencent.supersonic.auth.authentication.domain.utils.UserTokenUtils;
import com.tencent.supersonic.common.exception.AccessException;
import com.tencent.supersonic.common.util.context.ContextUtils;
import com.tencent.supersonic.common.util.context.S2ThreadContext;
import com.tencent.supersonic.common.util.context.ThreadContext;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
@Component
@Slf4j
public class DefaultAuthenticationInterceptor extends AuthenticationInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws AccessException {
authenticationConfig = ContextUtils.getBean(AuthenticationConfig.class);
userServiceImpl = ContextUtils.getBean(UserServiceImpl.class);
userTokenUtils = ContextUtils.getBean(UserTokenUtils.class);
s2ThreadContext = ContextUtils.getBean(S2ThreadContext.class);
if (!authenticationConfig.isEnabled()) {
return true;
}
if (isInternalRequest(request)) {
String token = userTokenUtils.generateAdminToken();
reflectSetparam(request, authenticationConfig.getTokenHttpHeaderKey(), token);
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
AuthenticationIgnore ignore = method.getAnnotation(AuthenticationIgnore.class);
if (ignore != null) {
return true;
}
String uri = request.getServletPath();
if (isExcludedUri(uri)) {
return true;
}
UserWithPassword user = userTokenUtils.getUserWithPassword(request);
if (StringUtils.isNotBlank(user.getName())) {
ThreadContext threadContext = ThreadContext.builder()
.token(request.getHeader(authenticationConfig.getTokenHttpHeaderKey()))
.userName(user.getName())
.build();
s2ThreadContext.set(threadContext);
return true;
}
throw new AccessException("authentication failed, please login");
}
}

View File

@@ -0,0 +1,29 @@
package com.tencent.supersonic.auth.authentication.domain.interceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
@Configuration
public class InterceptorFactory implements WebMvcConfigurer {
private List<AuthenticationInterceptor> authenticationInterceptors;
public InterceptorFactory() {
authenticationInterceptors = SpringFactoriesLoader.loadFactories(AuthenticationInterceptor.class,
Thread.currentThread().getContextClassLoader());
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
for (AuthenticationInterceptor authenticationInterceptor : authenticationInterceptors) {
registry.addInterceptor(authenticationInterceptor).addPathPatterns("/**")
.excludePathPatterns("/", "/webapp/**","/error");
}
}
}

View File

@@ -0,0 +1,13 @@
package com.tencent.supersonic.auth.authentication.domain.repository;
import com.tencent.supersonic.auth.authentication.domain.dataobject.UserDO;
import java.util.List;
public interface UserRepository {
List<UserDO> getUserList();
void addUser(UserDO userDO);
UserDO getUser(String name);
}

View File

@@ -0,0 +1,24 @@
package com.tencent.supersonic.auth.authentication.domain.strategy;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.service.UserStrategy;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;
@Service
public class FakeUserStrategy implements UserStrategy {
@Override
public boolean accept(boolean isEnableAuthentication) {
return !isEnableAuthentication;
}
@Override
public User findUser(HttpServletRequest request, HttpServletResponse response) {
return User.getFakeUser();
}
}

View File

@@ -0,0 +1,31 @@
package com.tencent.supersonic.auth.authentication.domain.strategy;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.service.UserStrategy;
import com.tencent.supersonic.auth.authentication.domain.utils.UserTokenUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;
@Service
public class HttpHeaderUserStrategy implements UserStrategy {
private final UserTokenUtils userTokenUtils;
public HttpHeaderUserStrategy(UserTokenUtils userTokenUtils) {
this.userTokenUtils = userTokenUtils;
}
@Override
public boolean accept(boolean isEnableAuthentication) {
return isEnableAuthentication;
}
@Override
public User findUser(HttpServletRequest request, HttpServletResponse response) {
return userTokenUtils.getUser(request);
}
}

View File

@@ -0,0 +1,36 @@
package com.tencent.supersonic.auth.authentication.domain.strategy;
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
import com.tencent.supersonic.auth.api.authentication.service.UserStrategy;
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
import java.util.List;
import javax.annotation.PostConstruct;
import lombok.Data;
import org.springframework.context.annotation.Configuration;
@Configuration
@Data
public class UserStrategyFactory {
private List<UserStrategy> userStrategyList;
private AuthenticationConfig authenticationConfig;
public UserStrategyFactory(AuthenticationConfig authenticationConfig, List<UserStrategy> userStrategyList) {
this.authenticationConfig = authenticationConfig;
this.userStrategyList = userStrategyList;
}
@PostConstruct
public void setUserStrategy() {
for (UserStrategy userStrategy : userStrategyList) {
if (userStrategy.accept(authenticationConfig.isEnabled())) {
UserHolder.setStrategy(userStrategy);
}
}
}
}

View File

@@ -0,0 +1,114 @@
package com.tencent.supersonic.auth.authentication.domain.utils;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_ALGORITHM;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_CREATE_TIME;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_PREFIX;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_TIME_OUT;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_DISPLAY_NAME;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_EMAIL;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_ID;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_NAME;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_PASSWORD;
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.pojo.UserWithPassword;
import com.tencent.supersonic.common.exception.AccessException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
@Component
public class UserTokenUtils {
private AuthenticationConfig authenticationConfig;
public UserTokenUtils(AuthenticationConfig authenticationConfig) {
this.authenticationConfig = authenticationConfig;
}
public String generateToken(UserWithPassword user) {
Map<String, Object> claims = new HashMap<>(5);
claims.put(TOKEN_USER_ID, user.getId());
claims.put(TOKEN_USER_NAME, StringUtils.isEmpty(user.getName()) ? "" : user.getName());
claims.put(TOKEN_USER_PASSWORD, StringUtils.isEmpty(user.getPassword()) ? "" : user.getPassword());
claims.put(TOKEN_USER_DISPLAY_NAME, user.getDisplayName());
claims.put(TOKEN_CREATE_TIME, System.currentTimeMillis());
return generate(claims);
}
public String generateAdminToken() {
Map<String, Object> claims = new HashMap<>(5);
claims.put(TOKEN_USER_ID, "1");
claims.put(TOKEN_USER_NAME, "admin");
claims.put(TOKEN_USER_PASSWORD, "admin");
claims.put(TOKEN_USER_DISPLAY_NAME, "admin");
claims.put(TOKEN_CREATE_TIME, System.currentTimeMillis());
return generate(claims);
}
public User getUser(HttpServletRequest request) {
String token = request.getHeader(authenticationConfig.getTokenHttpHeaderKey());
final Claims claims = getClaims(token);
Long userId = Long.parseLong(claims.getOrDefault(TOKEN_USER_ID, 0).toString());
String userName = String.valueOf(claims.get(TOKEN_USER_NAME));
String email = String.valueOf(claims.get(TOKEN_USER_EMAIL));
String displayName = String.valueOf(claims.get(TOKEN_USER_DISPLAY_NAME));
return User.get(userId, userName, displayName, email);
}
public UserWithPassword getUserWithPassword(HttpServletRequest request) {
String token = request.getHeader(authenticationConfig.getTokenHttpHeaderKey());
if (StringUtils.isBlank(token)) {
throw new AccessException("token is blank, get user failed");
}
final Claims claims = getClaims(token);
Long userId = Long.parseLong(claims.getOrDefault(TOKEN_USER_ID, 0).toString());
String userName = String.valueOf(claims.get(TOKEN_USER_NAME));
String email = String.valueOf(claims.get(TOKEN_USER_EMAIL));
String displayName = String.valueOf(claims.get(TOKEN_USER_DISPLAY_NAME));
String password = String.valueOf(claims.get(TOKEN_USER_PASSWORD));
return UserWithPassword.get(userId, userName, displayName, email, password);
}
private Claims getClaims(String token) {
Claims claims;
try {
claims = Jwts.parser()
.setSigningKey(authenticationConfig.getTokenSecret().getBytes(StandardCharsets.UTF_8))
.parseClaimsJws(token.startsWith(TOKEN_PREFIX)
? token.substring(token.indexOf(TOKEN_PREFIX) + TOKEN_PREFIX.length()).trim() :
token.trim()).getBody();
} catch (Exception e) {
throw new AccessException("parse user info from token failed :" + token);
}
return claims;
}
private String generate(Map<String, Object> claims) {
return toTokenString(claims);
}
private String toTokenString(Map<String, Object> claims) {
long expiration = Long.parseLong(claims.get(TOKEN_CREATE_TIME) + "") + TOKEN_TIME_OUT;
SignatureAlgorithm.valueOf(TOKEN_ALGORITHM);
return Jwts.builder()
.setClaims(claims)
.setSubject(claims.get(TOKEN_USER_NAME).toString())
.setExpiration(new Date(expiration))
.signWith(SignatureAlgorithm.valueOf(TOKEN_ALGORITHM),
authenticationConfig.getTokenSecret().getBytes(StandardCharsets.UTF_8))
.compact();
}
}

View File

@@ -0,0 +1,51 @@
package com.tencent.supersonic.auth.authentication.infrastructure.mapper;
import com.tencent.supersonic.auth.authentication.domain.dataobject.UserDO;
import com.tencent.supersonic.auth.authentication.domain.dataobject.UserDOExample;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserDOMapper {
/**
* @mbg.generated
*/
long countByExample(UserDOExample example);
/**
* @mbg.generated
*/
int deleteByPrimaryKey(Long id);
/**
* @mbg.generated
*/
int insert(UserDO record);
/**
* @mbg.generated
*/
int insertSelective(UserDO record);
/**
* @mbg.generated
*/
List<UserDO> selectByExample(UserDOExample example);
/**
* @mbg.generated
*/
UserDO selectByPrimaryKey(Long id);
/**
* @mbg.generated
*/
int updateByPrimaryKeySelective(UserDO record);
/**
* @mbg.generated
*/
int updateByPrimaryKey(UserDO record);
}

View File

@@ -0,0 +1,44 @@
package com.tencent.supersonic.auth.authentication.infrastructure.repository;
import com.tencent.supersonic.auth.authentication.domain.dataobject.UserDO;
import com.tencent.supersonic.auth.authentication.domain.dataobject.UserDOExample;
import com.tencent.supersonic.auth.authentication.domain.repository.UserRepository;
import com.tencent.supersonic.auth.authentication.infrastructure.mapper.UserDOMapper;
import java.util.List;
import java.util.Optional;
import org.springframework.stereotype.Component;
@Component
public class UserRepositoryImpl implements UserRepository {
private UserDOMapper userDOMapper;
public UserRepositoryImpl(UserDOMapper userDOMapper) {
this.userDOMapper = userDOMapper;
}
@Override
public List<UserDO> getUserList() {
return userDOMapper.selectByExample(new UserDOExample());
}
@Override
public void addUser(UserDO userDO) {
userDOMapper.insert(userDO);
}
@Override
public UserDO getUser(String name) {
UserDOExample userDOExample = new UserDOExample();
userDOExample.createCriteria().andNameEqualTo(name);
List<UserDO> userDOS = userDOMapper.selectByExample(userDOExample);
Optional<UserDO> userDOOptional = userDOS.stream().findFirst();
return userDOOptional.orElse(null);
}
}

View File

@@ -0,0 +1,57 @@
package com.tencent.supersonic.auth.authentication.rest;
import com.tencent.supersonic.auth.api.authentication.pojo.User;
import com.tencent.supersonic.auth.api.authentication.request.UserReq;
import com.tencent.supersonic.auth.api.authentication.service.UserService;
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/auth/user")
@Slf4j
public class UserController {
private UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/getCurrentUser")
public User getCurrentUser(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
return UserHolder.findUser(httpServletRequest, httpServletResponse);
}
@GetMapping("/getUserNames")
public List<String> getUserNames() {
return userService.getUserNames();
}
@GetMapping("/getUserList")
public List<User> getUserList() {
return userService.getUserList();
}
@PostMapping("/register")
public void register(@RequestBody UserReq userCmd) {
userService.register(userCmd);
}
@PostMapping("/login")
public String login(@RequestBody UserReq userCmd) {
return userService.login(userCmd);
}
}

View File

@@ -0,0 +1,145 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tencent.supersonic.auth.authentication.infrastructure.mapper.UserDOMapper">
<resultMap id="BaseResultMap" type="com.tencent.supersonic.auth.authentication.domain.dataobject.UserDO">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="password" jdbcType="VARCHAR" property="password" />
<result column="display_name" jdbcType="VARCHAR" property="displayName" />
<result column="email" jdbcType="VARCHAR" property="email" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List">
id, name, password, display_name, email
</sql>
<select id="selectByExample" parameterType="com.tencent.supersonic.auth.authentication.domain.dataobject.UserDOExample" resultMap="BaseResultMap">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
from s2_user
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
<if test="limitStart != null and limitStart>=0">
limit #{limitStart} , #{limitEnd}
</if>
</select>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from s2_user
where id = #{id,jdbcType=BIGINT}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
delete from s2_user
where id = #{id,jdbcType=BIGINT}
</delete>
<insert id="insert" parameterType="com.tencent.supersonic.auth.authentication.domain.dataobject.UserDO">
insert into s2_user (id, name, password,
display_name, email)
values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR},
#{displayName,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="com.tencent.supersonic.auth.authentication.domain.dataobject.UserDO">
insert into s2_user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="name != null">
name,
</if>
<if test="password != null">
password,
</if>
<if test="displayName != null">
display_name,
</if>
<if test="email != null">
email,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=BIGINT},
</if>
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
<if test="password != null">
#{password,jdbcType=VARCHAR},
</if>
<if test="displayName != null">
#{displayName,jdbcType=VARCHAR},
</if>
<if test="email != null">
#{email,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="com.tencent.supersonic.auth.authentication.domain.dataobject.UserDOExample" resultType="java.lang.Long">
select count(*) from s2_user
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</select>
<update id="updateByPrimaryKeySelective" parameterType="com.tencent.supersonic.auth.authentication.domain.dataobject.UserDO">
update s2_user
<set>
<if test="name != null">
name = #{name,jdbcType=VARCHAR},
</if>
<if test="password != null">
password = #{password,jdbcType=VARCHAR},
</if>
<if test="displayName != null">
display_name = #{displayName,jdbcType=VARCHAR},
</if>
<if test="email != null">
email = #{email,jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
<update id="updateByPrimaryKey" parameterType="com.tencent.supersonic.auth.authentication.domain.dataobject.UserDO">
update s2_user
set name = #{name,jdbcType=VARCHAR},
password = #{password,jdbcType=VARCHAR},
display_name = #{displayName,jdbcType=VARCHAR},
email = #{email,jdbcType=VARCHAR}
where id = #{id,jdbcType=BIGINT}
</update>
</mapper>

View File

@@ -0,0 +1,51 @@
<?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>auth</artifactId>
<groupId>com.tencent.supersonic</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>auth-authorization</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.tencent.supersonic</groupId>
<artifactId>auth-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.supersonic</groupId>
<artifactId>auth-authentication</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,118 @@
package com.tencent.supersonic.auth.authorization.application;
import com.google.common.base.Strings;
import com.google.gson.Gson;
import com.tencent.supersonic.auth.api.authorization.pojo.AuthRes;
import com.tencent.supersonic.auth.api.authorization.pojo.AuthResGrp;
import com.tencent.supersonic.auth.api.authorization.pojo.DimensionFilter;
import com.tencent.supersonic.auth.api.authorization.request.QueryAuthResReq;
import com.tencent.supersonic.auth.api.authorization.response.AuthorizedResourceResp;
import com.tencent.supersonic.auth.authorization.domain.pojo.AuthGroup;
import com.tencent.supersonic.auth.authorization.domain.pojo.AuthRule;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
@Component
@Slf4j
public class AuthApplicationService {
@Autowired
private JdbcTemplate jdbcTemplate;
private List<AuthGroup> load() {
List<String> rows = jdbcTemplate.queryForList("select config from s2_auth_groups", String.class);
Gson g = new Gson();
return rows.stream().map(row -> g.fromJson(row, AuthGroup.class)).collect(Collectors.toList());
}
public List<AuthGroup> queryAuthGroups(String domainId, Integer groupId) {
return load().stream()
.filter(group -> (Objects.isNull(groupId) || groupId.equals(group.getGroupId()))
&& domainId.equals(group.getDomainId()))
.collect(Collectors.toList());
}
public void updateAuthGroup(AuthGroup group) {
Gson g = new Gson();
if (group.getGroupId() == null) {
int nextGroupId = 1;
String sql = "select max(group_id) as group_id from s2_auth_groups";
Integer obj = jdbcTemplate.queryForObject(sql, Integer.class);
if (obj != null) {
nextGroupId = obj + 1;
}
group.setGroupId(nextGroupId);
jdbcTemplate.update("insert into s2_auth_groups (group_id, config) values (?, ?);", nextGroupId,
g.toJson(group));
} else {
jdbcTemplate.update("update s2_auth_groups set config = ? where group_id = ?;", g.toJson(group),
group.getGroupId());
}
}
public AuthorizedResourceResp queryAuthorizedResources(QueryAuthResReq req, HttpServletRequest request) {
List<AuthGroup> groups = load().stream().
filter(group -> group.getAuthorizedUsers().contains(req.getUser()) && req.getDomainId()
.equals(group.getDomainId())).
collect(Collectors.toList());
AuthorizedResourceResp resource = new AuthorizedResourceResp();
Map<String, List<AuthGroup>> authGroupsByDomainId = groups.stream()
.collect(Collectors.groupingBy(AuthGroup::getDomainId));
Map<String, List<AuthRes>> reqAuthRes = req.getResources().stream()
.collect(Collectors.groupingBy(AuthRes::getDomainId));
for (String domainId : reqAuthRes.keySet()) {
List<AuthRes> reqResourcesList = reqAuthRes.get(domainId);
AuthResGrp rg = new AuthResGrp();
if (authGroupsByDomainId.containsKey(domainId)) {
List<AuthGroup> authGroups = authGroupsByDomainId.get(domainId);
for (AuthRes reqRes : reqResourcesList) {
for (AuthGroup authRuleGroup : authGroups) {
List<AuthRule> authRules = authRuleGroup.getAuthRules();
List<String> allAuthItems = new ArrayList<>();
authRules.stream().forEach(authRule -> allAuthItems.addAll(authRule.resourceNames()));
if (allAuthItems.contains(reqRes.getName())) {
rg.getGroup().add(reqRes);
}
}
}
}
if (Objects.nonNull(rg) && !CollectionUtils.isEmpty(rg.getGroup())) {
resource.getResources().add(rg);
}
}
if (StringUtils.isNotEmpty(req.getDomainId())) {
List<AuthGroup> authGroups = authGroupsByDomainId.get(req.getDomainId());
if (!CollectionUtils.isEmpty(authGroups)) {
for (AuthGroup group : authGroups) {
if (group.getDimensionFilters() != null
&& group.getDimensionFilters().stream().anyMatch(expr -> !Strings.isNullOrEmpty(expr))) {
DimensionFilter df = new DimensionFilter();
df.setDescription(group.getDimensionFilterDescription());
df.setExpressions(group.getDimensionFilters());
resource.getFilters().add(df);
}
}
}
}
return resource;
}
public void removeAuthGroup(AuthGroup group) {
jdbcTemplate.update("delete from s2_auth_groups where group_id = ?", group.getGroupId());
}
}

View File

@@ -0,0 +1,24 @@
package com.tencent.supersonic.auth.authorization.application;
import com.tencent.supersonic.auth.api.authorization.request.QueryAuthResReq;
import com.tencent.supersonic.auth.api.authorization.response.AuthorizedResourceResp;
import com.tencent.supersonic.auth.api.authorization.service.AuthService;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class AuthServiceImpl implements AuthService {
private final AuthApplicationService authApplicationService;
public AuthServiceImpl(AuthApplicationService authApplicationService) {
this.authApplicationService = authApplicationService;
}
@Override
public AuthorizedResourceResp queryAuthorizedResources(HttpServletRequest request, QueryAuthResReq req) {
return authApplicationService.queryAuthorizedResources(req, request);
}
}

View File

@@ -0,0 +1,27 @@
package com.tencent.supersonic.auth.authorization.domain.pojo;
import java.util.List;
import lombok.Data;
@Data
public class AuthGroup {
private String domainId;
private String name;
private Integer groupId;
private List<AuthRule> authRules;
/**
* row permission expression
*/
private List<String> dimensionFilters;
/**
* row permission expression description information
*/
private String dimensionFilterDescription;
private List<String> authorizedUsers;
/**
* authorization Department Id
*/
private List<String> authorizedDepartmentIds;
}

View File

@@ -0,0 +1,28 @@
package com.tencent.supersonic.auth.authorization.domain.pojo;
import java.beans.Transient;
import java.util.ArrayList;
import java.util.List;
import lombok.Data;
@Data
public class AuthRule {
private String name;
private String description;
private List<String> metrics;
private List<String> dimensions;
@Transient
public List<String> resourceNames() {
ArrayList<String> res = new ArrayList<>();
if (metrics != null) {
res.addAll(metrics);
}
if (dimensions != null) {
res.addAll(dimensions);
}
return res;
}
}

View File

@@ -0,0 +1,73 @@
package com.tencent.supersonic.auth.authorization.rest;
import com.tencent.supersonic.auth.api.authorization.request.QueryAuthResReq;
import com.tencent.supersonic.auth.api.authorization.response.AuthorizedResourceResp;
import com.tencent.supersonic.auth.authorization.application.AuthApplicationService;
import com.tencent.supersonic.auth.authorization.domain.pojo.AuthGroup;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/auth")
@Slf4j
public class AuthController {
private final AuthApplicationService service;
public AuthController(AuthApplicationService service) {
this.service = service;
}
@GetMapping("/queryGroup")
public List<AuthGroup> queryAuthGroup(@RequestParam("domainId") String domainId,
@RequestParam(value = "groupId", required = false) Integer groupId) {
return service.queryAuthGroups(domainId, groupId);
}
/**
* 新建权限组
*/
@PostMapping("/createGroup")
public void newAuthGroup(@RequestBody AuthGroup group) {
group.setGroupId(null);
service.updateAuthGroup(group);
}
@PostMapping("/removeGroup")
public void removeAuthGroup(@RequestBody AuthGroup group) {
service.removeAuthGroup(group);
}
/**
* 更新权限组
*
* @param group
*/
@PostMapping("/updateGroup")
public void updateAuthGroup(@RequestBody AuthGroup group) {
if (group.getGroupId() == null || group.getGroupId() == 0) {
throw new RuntimeException("groupId is empty");
}
service.updateAuthGroup(group);
}
/**
* 查询有权限访问的受限资源id
*
* @param req
* @param request
* @return
*/
@PostMapping("/queryAuthorizedRes")
public AuthorizedResourceResp queryAuthorizedResources(@RequestBody QueryAuthResReq req,
HttpServletRequest request) {
return service.queryAuthorizedResources(req, request);
}
}

21
auth/pom.xml Normal file
View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>supersonic</artifactId>
<groupId>com.tencent.supersonic</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>auth</artifactId>
<packaging>pom</packaging>
<modules>
<module>api</module>
<module>authentication</module>
<module>authorization</module>
</modules>
</project>