Browse Source

Feature/oauth2 github (#27)

* feat: jooq generate

* feat: support github oauth

* feat: support oauth2 login

* feat: update content-type

* feat: add custom authentication exception

* feat: add oauth2 app api

* fix: checkstyle
master
vran 3 years ago
committed by GitHub
parent
commit
cd20dfd7cf
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      api/build.gradle
  2. 19
      api/src/main/java/com/databasir/api/LoginController.java
  3. 87
      api/src/main/java/com/databasir/api/OpenAuth2AppController.java
  4. 2
      api/src/main/java/com/databasir/api/OperationLogController.java
  5. 17
      api/src/main/java/com/databasir/api/Routes.java
  6. 2
      api/src/main/java/com/databasir/api/config/SecurityConfig.java
  7. 28
      api/src/main/java/com/databasir/api/config/oauth2/DatabasirOAuth2Authentication.java
  8. 62
      api/src/main/java/com/databasir/api/config/oauth2/DatabasirOauth2LoginFilter.java
  9. 42
      api/src/main/java/com/databasir/api/config/oauth2/OAuth2AuthenticationSuccessHandler.java
  10. 7
      api/src/main/java/com/databasir/api/config/security/DatabasirAuthenticationFailureHandler.java
  11. 28
      api/src/main/java/com/databasir/api/config/security/DatabasirAuthenticationSuccessHandler.java
  12. 3
      api/src/main/java/com/databasir/api/config/security/DatabasirUserDetailService.java
  13. 2
      api/src/main/resources/application-local.properties
  14. 10
      common/src/main/java/com/databasir/common/JsonData.java
  15. 3
      core/build.gradle
  16. 4
      core/src/main/java/com/databasir/core/domain/DomainErrors.java
  17. 111
      core/src/main/java/com/databasir/core/domain/app/OpenAuthAppService.java
  18. 26
      core/src/main/java/com/databasir/core/domain/app/converter/OAuthAppPojoConverter.java
  19. 11
      core/src/main/java/com/databasir/core/domain/app/converter/OAuthAppResponseConverter.java
  20. 35
      core/src/main/java/com/databasir/core/domain/app/data/OAuthAppCreateRequest.java
  21. 31
      core/src/main/java/com/databasir/core/domain/app/data/OAuthAppDetailResponse.java
  22. 30
      core/src/main/java/com/databasir/core/domain/app/data/OAuthAppPageCondition.java
  23. 30
      core/src/main/java/com/databasir/core/domain/app/data/OAuthAppPageResponse.java
  24. 28
      core/src/main/java/com/databasir/core/domain/app/data/OAuthAppResponse.java
  25. 39
      core/src/main/java/com/databasir/core/domain/app/data/OAuthAppUpdateRequest.java
  26. 19
      core/src/main/java/com/databasir/core/domain/app/exception/DatabasirAuthenticationException.java
  27. 83
      core/src/main/java/com/databasir/core/domain/app/handler/GithubOpenAuthHandler.java
  28. 22
      core/src/main/java/com/databasir/core/domain/app/handler/OAuthProcessContext.java
  29. 16
      core/src/main/java/com/databasir/core/domain/app/handler/OAuthProcessResult.java
  30. 10
      core/src/main/java/com/databasir/core/domain/app/handler/OpenAuthHandler.java
  31. 4
      core/src/main/java/com/databasir/core/domain/login/data/UserLoginResponse.java
  32. 40
      core/src/main/java/com/databasir/core/domain/login/service/LoginService.java
  33. 16
      core/src/main/java/com/databasir/core/domain/user/data/UserLoginRequest.java
  34. 19
      core/src/main/java/com/databasir/core/domain/user/service/UserService.java
  35. 34
      core/src/main/java/com/databasir/core/infrastructure/remote/ClientConfig.java
  36. 23
      core/src/main/java/com/databasir/core/infrastructure/remote/github/GithubApiClient.java
  37. 20
      core/src/main/java/com/databasir/core/infrastructure/remote/github/GithubOauthClient.java
  38. 74
      core/src/main/java/com/databasir/core/infrastructure/remote/github/GithubRemoteService.java
  39. 32
      core/src/main/java/com/databasir/core/infrastructure/remote/github/TokenRequest.java
  40. 7
      dao/generated-src/jooq/main/java/com/databasir/dao/Databasir.java
  41. 2
      dao/generated-src/jooq/main/java/com/databasir/dao/Indexes.java
  42. 5
      dao/generated-src/jooq/main/java/com/databasir/dao/Keys.java
  43. 6
      dao/generated-src/jooq/main/java/com/databasir/dao/Tables.java
  44. 199
      dao/generated-src/jooq/main/java/com/databasir/dao/tables/OauthApp.java
  45. 12
      dao/generated-src/jooq/main/java/com/databasir/dao/tables/UserFavoriteProject.java
  46. 265
      dao/generated-src/jooq/main/java/com/databasir/dao/tables/pojos/OauthAppPojo.java
  47. 539
      dao/generated-src/jooq/main/java/com/databasir/dao/tables/records/OauthAppRecord.java
  48. 10
      dao/src/main/java/com/databasir/dao/enums/OAuthAppType.java
  49. 6
      dao/src/main/java/com/databasir/dao/impl/BaseDao.java
  50. 7
      dao/src/main/java/com/databasir/dao/impl/LoginDao.java
  51. 37
      dao/src/main/java/com/databasir/dao/impl/OauthAppDao.java
  52. 18
      dao/src/main/resources/db/migration/V1.4__oauth.sql

1
api/build.gradle

@ -26,6 +26,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-quartz'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.flywaydb:flyway-core'

19
api/src/main/java/com/databasir/api/LoginController.java

@ -1,5 +1,6 @@
package com.databasir.api;
import com.databasir.api.config.security.DatabasirUserDetails;
import com.databasir.common.DatabasirException;
import com.databasir.common.JsonData;
import com.databasir.common.exception.InvalidTokenException;
@ -7,10 +8,10 @@ import com.databasir.core.domain.DomainErrors;
import com.databasir.core.domain.log.annotation.Operation;
import com.databasir.core.domain.login.data.AccessTokenRefreshRequest;
import com.databasir.core.domain.login.data.AccessTokenRefreshResponse;
import com.databasir.core.domain.login.data.UserLoginResponse;
import com.databasir.core.domain.login.service.LoginService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
@ -27,8 +28,6 @@ import java.util.Objects;
@Slf4j
public class LoginController {
private final AuthenticationManager authenticationManager;
private final LoginService loginService;
@GetMapping(Routes.Login.LOGOUT)
@ -39,8 +38,8 @@ public class LoginController {
}
@PostMapping(Routes.Login.REFRESH_ACCESS_TOKEN)
public JsonData<AccessTokenRefreshResponse> refreshAccessTokens(@RequestBody @Valid
AccessTokenRefreshRequest request) {
public JsonData<AccessTokenRefreshResponse> refreshAccessTokens(@RequestBody
@Valid AccessTokenRefreshRequest request) {
try {
return JsonData.ok(loginService.refreshAccessTokens(request));
} catch (DatabasirException e) {
@ -53,4 +52,14 @@ public class LoginController {
throw e;
}
}
@GetMapping(Routes.Login.LOGIN_INFO)
public JsonData<UserLoginResponse> getUserLoginData() {
DatabasirUserDetails user = (DatabasirUserDetails) SecurityContextHolder.getContext()
.getAuthentication()
.getPrincipal();
Integer userId = user.getUserPojo().getId();
return JsonData.ok(loginService.getUserLoginData(userId));
}
}

87
api/src/main/java/com/databasir/api/OpenAuth2AppController.java

@ -0,0 +1,87 @@
package com.databasir.api;
import com.databasir.common.JsonData;
import com.databasir.core.domain.app.OpenAuthAppService;
import com.databasir.core.domain.app.data.*;
import com.databasir.core.domain.app.handler.OpenAuthHandler;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
import static org.springframework.data.domain.Sort.Direction.DESC;
@Controller
@RequiredArgsConstructor
public class OpenAuth2AppController {
private final OpenAuthHandler openAuthHandler;
private final OpenAuthAppService openAuthAppService;
/**
* 无需授权
*/
@GetMapping("/oauth2/authorization/{registrationId}")
@ResponseBody
public JsonData<String> authorization(@PathVariable String registrationId) {
String authorization = openAuthHandler.authorization(registrationId);
return JsonData.ok(authorization);
}
/**
* 无需授权
*/
@GetMapping("/oauth2/apps")
@ResponseBody
public JsonData<List<OAuthAppResponse>> listApps() {
return JsonData.ok(openAuthAppService.listAll());
}
@GetMapping(Routes.OAuth2App.LIST_PAGE)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@ResponseBody
public JsonData<Page<OAuthAppPageResponse>> listPage(@PageableDefault(sort = "id", direction = DESC)
Pageable page,
OAuthAppPageCondition condition) {
return JsonData.ok(openAuthAppService.listPage(page, condition));
}
@GetMapping(Routes.OAuth2App.GET_ONE)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@ResponseBody
public JsonData<OAuthAppDetailResponse> getOne(@PathVariable Integer id) {
return JsonData.ok(openAuthAppService.getOne(id));
}
@PostMapping(Routes.OAuth2App.CREATE)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@ResponseBody
public JsonData<Integer> create(@RequestBody @Valid OAuthAppCreateRequest request) {
Integer id = openAuthAppService.create(request);
return JsonData.ok(id);
}
@PatchMapping(Routes.OAuth2App.UPDATE)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@ResponseBody
public JsonData<Void> updateById(@RequestBody @Valid OAuthAppUpdateRequest request) {
openAuthAppService.updateById(request);
return JsonData.ok();
}
@DeleteMapping(Routes.OAuth2App.DELETE)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@ResponseBody
public JsonData<Void> deleteById(@PathVariable Integer id) {
openAuthAppService.deleteById(id);
return JsonData.ok();
}
}

2
api/src/main/java/com/databasir/api/OperationLogController.java

@ -9,6 +9,7 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@ -21,6 +22,7 @@ public class OperationLogController {
private final OperationLogService operationLogService;
@GetMapping(Routes.OperationLog.LIST)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
public JsonData<Page<OperationLogPageResponse>> list(@PageableDefault(sort = "id", direction = Sort.Direction.DESC)
Pageable page,
OperationLogPageCondition condition) {

17
api/src/main/java/com/databasir/api/Routes.java

@ -102,9 +102,26 @@ public interface Routes {
String LOGOUT = "/logout";
String REFRESH_ACCESS_TOKEN = "/access_tokens";
String LOGIN_INFO = "/login_info";
}
interface OperationLog {
String LIST = BASE + "/operation_logs";
}
interface OAuth2App {
String LIST_PAGE = BASE + "/oauth2_apps";
String CREATE = BASE + "/oauth2_apps";
String UPDATE = BASE + "/oauth2_apps";
String DELETE = BASE + "/oauth2_apps/{id}";
String GET_ONE = BASE + "/oauth2_apps/{id}";
}
}

2
api/src/main/java/com/databasir/api/config/SecurityConfig.java

@ -45,6 +45,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
.and()
.authorizeRequests()
.antMatchers("/login", Routes.Login.REFRESH_ACCESS_TOKEN).permitAll()
.antMatchers("/oauth2/apps", "/oauth2/failure", "/oauth2/authorization/*", "/oauth2/login/*")
.permitAll()
.antMatchers("/", "/*.html", "/js/**", "/css/**", "/img/**", "/*.ico").permitAll()
.anyRequest().authenticated()
.and()

28
api/src/main/java/com/databasir/api/config/oauth2/DatabasirOAuth2Authentication.java

@ -0,0 +1,28 @@
package com.databasir.api.config.oauth2;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
public class DatabasirOAuth2Authentication extends AbstractAuthenticationToken {
private Object credentials;
private Object principal;
public DatabasirOAuth2Authentication(UserDetails principal) {
super(principal.getAuthorities());
this.credentials = null;
this.principal = principal;
setAuthenticated(false);
}
@Override
public Object getCredentials() {
return this.credentials;
}
@Override
public Object getPrincipal() {
return this.principal;
}
}

62
api/src/main/java/com/databasir/api/config/oauth2/DatabasirOauth2LoginFilter.java

@ -0,0 +1,62 @@
package com.databasir.api.config.oauth2;
import com.databasir.api.config.security.DatabasirUserDetailService;
import com.databasir.core.domain.user.data.UserDetailResponse;
import com.databasir.core.domain.app.OpenAuthAppService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
@Component
@Slf4j
public class DatabasirOauth2LoginFilter extends AbstractAuthenticationProcessingFilter {
public static final String OAUTH_LOGIN_URI = "/oauth2/login/*";
@Autowired
private OpenAuthAppService openAuthAppService;
@Autowired
private DatabasirUserDetailService databasirUserDetailService;
public DatabasirOauth2LoginFilter(AuthenticationManager authenticationManager,
OAuth2AuthenticationSuccessHandler auth2AuthenticationSuccessHandler,
AuthenticationFailureHandler authenticationFailureHandler) {
super(OAUTH_LOGIN_URI, authenticationManager);
this.setAuthenticationSuccessHandler(auth2AuthenticationSuccessHandler);
this.setAuthenticationFailureHandler(authenticationFailureHandler);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException {
Map<String, String[]> params = request.getParameterMap();
String registrationId = new AntPathMatcher().extractPathWithinPattern(OAUTH_LOGIN_URI, request.getRequestURI());
UserDetailResponse userDetailResponse = openAuthAppService.oauthCallback(registrationId, params);
UserDetails details = databasirUserDetailService.loadUserByUsername(userDetailResponse.getUsername());
DatabasirOAuth2Authentication authentication = new DatabasirOAuth2Authentication(details);
if (!userDetailResponse.getEnabled()) {
throw new DisabledException("账号已禁用");
}
authentication.setAuthenticated(true);
if (log.isDebugEnabled()) {
log.debug("login {} success", registrationId);
}
return authentication;
}
}

42
api/src/main/java/com/databasir/api/config/oauth2/OAuth2AuthenticationSuccessHandler.java

@ -0,0 +1,42 @@
package com.databasir.api.config.oauth2;
import com.databasir.api.config.security.DatabasirUserDetails;
import com.databasir.common.JsonData;
import com.databasir.core.domain.login.data.LoginKeyResponse;
import com.databasir.core.domain.login.data.UserLoginResponse;
import com.databasir.core.domain.login.service.LoginService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@Component
@RequiredArgsConstructor
public class OAuth2AuthenticationSuccessHandler implements AuthenticationSuccessHandler {
private final LoginService loginService;
private final ObjectMapper objectMapper;
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
DatabasirUserDetails details = (DatabasirUserDetails) authentication.getPrincipal();
LoginKeyResponse loginKey = loginService.generate(details.getUserPojo().getId());
UserLoginResponse data = loginService.getUserLoginData(details.getUserPojo().getId())
.orElseThrow(() -> new CredentialsExpiredException("请重新登陆"));
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
objectMapper.writeValue(response.getWriter(), JsonData.ok(data));
}
}

7
api/src/main/java/com/databasir/api/config/security/DatabasirAuthenticationFailureHandler.java

@ -1,5 +1,6 @@
package com.databasir.api.config.security;
import com.databasir.core.domain.app.exception.DatabasirAuthenticationException;
import com.databasir.common.JsonData;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
@ -39,6 +40,12 @@ public class DatabasirAuthenticationFailureHandler implements AuthenticationFail
String jsonString = objectMapper.writeValueAsString(data);
response.setStatus(HttpStatus.OK.value());
response.getOutputStream().write(jsonString.getBytes(StandardCharsets.UTF_8));
} else if (exception instanceof DatabasirAuthenticationException) {
DatabasirAuthenticationException bizException = (DatabasirAuthenticationException) exception;
JsonData<Void> data = JsonData.error("-1", bizException.getMessage());
String jsonString = objectMapper.writeValueAsString(data);
response.setStatus(HttpStatus.OK.value());
response.getOutputStream().write(jsonString.getBytes(StandardCharsets.UTF_8));
} else {
JsonData<Void> data = JsonData.error("-1", "未登录或未授权用户");
String jsonString = objectMapper.writeValueAsString(data);

28
api/src/main/java/com/databasir/api/config/security/DatabasirAuthenticationSuccessHandler.java

@ -2,11 +2,12 @@ package com.databasir.api.config.security;
import com.databasir.common.JsonData;
import com.databasir.core.domain.login.data.LoginKeyResponse;
import com.databasir.core.domain.login.data.UserLoginResponse;
import com.databasir.core.domain.login.service.LoginService;
import com.databasir.core.domain.user.data.UserLoginResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
@ -16,9 +17,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.ZoneId;
import java.util.List;
import java.util.stream.Collectors;
@Component
@RequiredArgsConstructor
@ -35,28 +33,10 @@ public class DatabasirAuthenticationSuccessHandler implements AuthenticationSucc
DatabasirUserDetails user = (DatabasirUserDetails) authentication.getPrincipal();
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
UserLoginResponse data = new UserLoginResponse();
data.setId(user.getUserPojo().getId());
data.setNickname(user.getUserPojo().getNickname());
data.setEmail(user.getUserPojo().getEmail());
data.setUsername(user.getUserPojo().getUsername());
LoginKeyResponse loginKey = loginService.generate(user.getUserPojo().getId());
data.setAccessToken(loginKey.getAccessToken());
long expireAt = loginKey.getAccessTokenExpireAt().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
data.setAccessTokenExpireAt(expireAt);
data.setRefreshToken(loginKey.getRefreshToken());
List<UserLoginResponse.RoleResponse> roles = user.getRoles()
.stream()
.map(ur -> {
UserLoginResponse.RoleResponse roleResponse = new UserLoginResponse.RoleResponse();
roleResponse.setRole(ur.getRole());
roleResponse.setGroupId(ur.getGroupId());
return roleResponse;
})
.collect(Collectors.toList());
data.setRoles(roles);
UserLoginResponse data = loginService.getUserLoginData(user.getUserPojo().getId())
.orElseThrow(() -> new CredentialsExpiredException("请重新登陆"));
objectMapper.writeValue(response.getWriter(), JsonData.ok(data));
}
}

3
api/src/main/java/com/databasir/api/config/security/DatabasirUserDetailService.java

@ -1,6 +1,5 @@
package com.databasir.api.config.security;
import com.databasir.dao.impl.LoginDao;
import com.databasir.dao.impl.UserDao;
import com.databasir.dao.impl.UserRoleDao;
import com.databasir.dao.tables.pojos.UserPojo;
@ -22,8 +21,6 @@ public class DatabasirUserDetailService implements UserDetailsService {
private final UserRoleDao userRoleDao;
private final LoginDao loginDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserPojo user = userDao.selectByEmailOrUsername(username)

2
api/src/main/resources/application-local.properties

@ -8,4 +8,4 @@ spring.jooq.sql-dialect=mysql
spring.flyway.enabled=true
spring.flyway.baseline-on-migrate=true
spring.flyway.locations=classpath:db/migration
spring.flyway.locations=classpath:db/migration

10
common/src/main/java/com/databasir/common/JsonData.java

@ -2,6 +2,8 @@ package com.databasir.common;
import lombok.Data;
import java.util.Optional;
@Data
public class JsonData<T> {
@ -21,7 +23,7 @@ public class JsonData<T> {
private String errMessage;
public static <T> JsonData<T> ok() {
return ok(null);
return ok(Optional.empty());
}
public static <T> JsonData<T> ok(T data) {
@ -30,6 +32,12 @@ public class JsonData<T> {
return jsonData;
}
public static <T> JsonData<T> ok(Optional<T> data) {
JsonData<T> jsonData = new JsonData<>();
jsonData.setData(data.orElse(null));
return jsonData;
}
public static <T> JsonData<T> error(String errorCode, String errMessage) {
JsonData<T> jsonData = new JsonData<>();
jsonData.setErrCode(errorCode);

3
core/build.gradle

@ -31,6 +31,9 @@ dependencies {
implementation 'org.commonmark:commonmark:0.18.1'
implementation 'org.freemarker:freemarker:2.3.31'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-jackson:2.9.0'
// test
testImplementation "mysql:mysql-connector-java:${mysqlConnectorVersion}"
}

4
core/src/main/java/com/databasir/core/domain/DomainErrors.java

@ -10,6 +10,7 @@ import lombok.RequiredArgsConstructor;
public enum DomainErrors implements DatabasirErrors {
REFRESH_TOKEN_EXPIRED("X_0001", "refresh token expired"),
INVALID_REFRESH_TOKEN_OPERATION("X_0002", "invalid refresh token operation"),
NETWORK_ERROR("X_0003", "网络似乎不稳定,请稍后再试"),
NOT_SUPPORT_DATABASE_TYPE("A_10000", "不支持的数据库类型, 请检查项目配置"),
PROJECT_NOT_FOUND("A_10001", "项目不存在"),
@ -23,7 +24,8 @@ public enum DomainErrors implements DatabasirErrors {
CANNOT_UPDATE_SELF_ROLE("A_10009", "无法对自己执行角色变更的操作"),
UPDATE_PASSWORD_CONFIRM_FAILED("A_10010", "两次密码输入不一致"),
ORIGIN_PASSWORD_NOT_CORRECT("A_10011", "原密码不正确"),
INVALID_CRON_EXPRESSION("A_10012", "不合法的 cron 表达式");
INVALID_CRON_EXPRESSION("A_10012", "不合法的 cron 表达式"),
REGISTRATION_ID_DUPLICATE("A_10013", "应用注册 ID 不能重复");
private final String errCode;

111
core/src/main/java/com/databasir/core/domain/app/OpenAuthAppService.java

@ -0,0 +1,111 @@
package com.databasir.core.domain.app;
import com.databasir.core.domain.DomainErrors;
import com.databasir.core.domain.app.converter.OAuthAppPojoConverter;
import com.databasir.core.domain.app.converter.OAuthAppResponseConverter;
import com.databasir.core.domain.app.data.*;
import com.databasir.core.domain.app.handler.OpenAuthHandler;
import com.databasir.core.domain.app.handler.OAuthProcessContext;
import com.databasir.core.domain.app.handler.OAuthProcessResult;
import com.databasir.core.domain.user.data.UserCreateRequest;
import com.databasir.core.domain.user.data.UserDetailResponse;
import com.databasir.core.domain.user.service.UserService;
import com.databasir.dao.impl.OauthAppDao;
import com.databasir.dao.tables.pojos.OauthAppPojo;
import lombok.RequiredArgsConstructor;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class OpenAuthAppService {
private final List<OpenAuthHandler> openAuthHandlers;
private final OauthAppDao oauthAppDao;
private final UserService userService;
private final OAuthAppResponseConverter oauthAppResponseConverter;
private final OAuthAppPojoConverter oauthAppPojoConverter;
public UserDetailResponse oauthCallback(String registrationId, Map<String, String[]> params) {
// match handler
OauthAppPojo app = oauthAppDao.selectByRegistrationId(registrationId);
OpenAuthHandler openAuthHandler = openAuthHandlers.stream()
.filter(handler -> handler.support(app.getAppType()))
.findFirst()
.orElseThrow(() -> new UsernameNotFoundException("暂不支持该类型登陆"));
// process by handler
OAuthProcessContext context = OAuthProcessContext.builder()
.callbackParameters(params)
.registrationId(registrationId)
.build();
OAuthProcessResult result = openAuthHandler.process(context);
// get or create new user
return userService.get(result.getEmail())
.orElseGet(() -> {
UserCreateRequest user = new UserCreateRequest();
user.setUsername(result.getUsername());
user.setNickname(result.getNickname());
user.setEmail(result.getEmail());
user.setAvatar(result.getAvatar());
user.setEnabled(true);
user.setPassword(UUID.randomUUID().toString().substring(0, 6));
Integer id = userService.create(user);
return userService.get(id);
});
}
public List<OAuthAppResponse> listAll() {
List<OauthAppPojo> apps = oauthAppDao.selectAll();
return apps.stream()
.map(oauthAppResponseConverter::to)
.collect(Collectors.toList());
}
public void deleteById(Integer id) {
if (oauthAppDao.existsById(id)) {
oauthAppDao.deleteById(id);
}
}
public void updateById(OAuthAppUpdateRequest request) {
OauthAppPojo pojo = oauthAppPojoConverter.of(request);
try {
oauthAppDao.updateById(pojo);
} catch (DuplicateKeyException e) {
throw DomainErrors.REGISTRATION_ID_DUPLICATE.exception();
}
}
public Integer create(OAuthAppCreateRequest request) {
OauthAppPojo pojo = oauthAppPojoConverter.of(request);
try {
return oauthAppDao.insertAndReturnId(pojo);
} catch (DuplicateKeyException e) {
throw DomainErrors.REGISTRATION_ID_DUPLICATE.exception();
}
}
public Page<OAuthAppPageResponse> listPage(Pageable page, OAuthAppPageCondition condition) {
return oauthAppDao.selectByPage(page, condition.toCondition()).map(oauthAppPojoConverter::toPageResponse);
}
public Optional<OAuthAppDetailResponse> getOne(Integer id) {
return oauthAppDao.selectOptionalById(id).map(oauthAppPojoConverter::toDetailResponse);
}
}

26
core/src/main/java/com/databasir/core/domain/app/converter/OAuthAppPojoConverter.java

@ -0,0 +1,26 @@
package com.databasir.core.domain.app.converter;
import com.databasir.core.domain.app.data.OAuthAppCreateRequest;
import com.databasir.core.domain.app.data.OAuthAppDetailResponse;
import com.databasir.core.domain.app.data.OAuthAppPageResponse;
import com.databasir.core.domain.app.data.OAuthAppUpdateRequest;
import com.databasir.dao.tables.pojos.OauthAppPojo;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
@Mapper(componentModel = "spring")
public interface OAuthAppPojoConverter {
@Mapping(target = "id", ignore = true)
@Mapping(target = "createAt", ignore = true)
@Mapping(target = "updateAt", ignore = true)
OauthAppPojo of(OAuthAppCreateRequest request);
@Mapping(target = "createAt", ignore = true)
@Mapping(target = "updateAt", ignore = true)
OauthAppPojo of(OAuthAppUpdateRequest request);
OAuthAppPageResponse toPageResponse(OauthAppPojo pojo);
OAuthAppDetailResponse toDetailResponse(OauthAppPojo pojo);
}

11
core/src/main/java/com/databasir/core/domain/app/converter/OAuthAppResponseConverter.java

@ -0,0 +1,11 @@
package com.databasir.core.domain.app.converter;
import com.databasir.core.domain.app.data.OAuthAppResponse;
import com.databasir.dao.tables.pojos.OauthAppPojo;
import org.mapstruct.Mapper;
@Mapper(componentModel = "spring")
public interface OAuthAppResponseConverter {
OAuthAppResponse to(OauthAppPojo pojo);
}

35
core/src/main/java/com/databasir/core/domain/app/data/OAuthAppCreateRequest.java

@ -0,0 +1,35 @@
package com.databasir.core.domain.app.data;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class OAuthAppCreateRequest {
@NotNull
private String registrationId;
@NotBlank
private String appName;
@NotBlank
private String appType;
private String appIcon;
@NotBlank
private String authUrl;
@NotBlank
private String resourceUrl;
@NotBlank
private String clientId;
@NotBlank
private String clientSecret;
private String scope;
}

31
core/src/main/java/com/databasir/core/domain/app/data/OAuthAppDetailResponse.java

@ -0,0 +1,31 @@
package com.databasir.core.domain.app.data;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class OAuthAppDetailResponse {
private Integer id;
private String appName;
private String appIcon;
private String appType;
private String registrationId;
private String clientId;
private String clientSecret;
private String authUrl;
private String resourceUrl;
private LocalDateTime updateAt;
private LocalDateTime createAt;
}

30
core/src/main/java/com/databasir/core/domain/app/data/OAuthAppPageCondition.java

@ -0,0 +1,30 @@
package com.databasir.core.domain.app.data;
import com.databasir.dao.Tables;
import lombok.Data;
import org.jooq.Condition;
import org.jooq.impl.DSL;
import java.util.ArrayList;
import java.util.List;
@Data
public class OAuthAppPageCondition {
private String appNameContains;
private String appType;
public Condition toCondition() {
List<Condition> conditions = new ArrayList<>();
if (appNameContains != null && !appNameContains.trim().equals("")) {
conditions.add(Tables.OAUTH_APP.APP_NAME.contains(appNameContains));
}
if (appType != null) {
conditions.add(Tables.OAUTH_APP.APP_TYPE.eq(appType));
}
return conditions.stream()
.reduce(Condition::and)
.orElse(DSL.trueCondition());
}
}

30
core/src/main/java/com/databasir/core/domain/app/data/OAuthAppPageResponse.java

@ -0,0 +1,30 @@
package com.databasir.core.domain.app.data;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class OAuthAppPageResponse {
private Integer id;
private String appName;
private String appIcon;
private String appType;
private String registrationId;
private String clientId;
private String authUrl;
private String resourceUrl;
private LocalDateTime updateAt;
private LocalDateTime createAt;
}

28
core/src/main/java/com/databasir/core/domain/app/data/OAuthAppResponse.java

@ -0,0 +1,28 @@
package com.databasir.core.domain.app.data;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OAuthAppResponse {
private Integer id;
private String appName;
private String appIcon;
private String appType;
private String registrationId;
private LocalDateTime createAt;
}

39
core/src/main/java/com/databasir/core/domain/app/data/OAuthAppUpdateRequest.java

@ -0,0 +1,39 @@
package com.databasir.core.domain.app.data;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class OAuthAppUpdateRequest {
@NotNull
private Integer id;
@NotBlank
private String registrationId;
@NotBlank
private String appName;
@NotBlank
private String appType;
private String appIcon;
@NotBlank
private String authUrl;
@NotBlank
private String resourceUrl;
@NotBlank
private String clientId;
@NotBlank
private String clientSecret;
private String scope;
}

19
core/src/main/java/com/databasir/core/domain/app/exception/DatabasirAuthenticationException.java

@ -0,0 +1,19 @@
package com.databasir.core.domain.app.exception;
import com.databasir.common.DatabasirException;
import org.springframework.security.core.AuthenticationException;
public class DatabasirAuthenticationException extends AuthenticationException {
public DatabasirAuthenticationException(DatabasirException databasirException) {
super(databasirException.getErrMessage(), databasirException);
}
public DatabasirAuthenticationException(String msg) {
super(msg);
}
public DatabasirAuthenticationException(String msg, Throwable cause) {
super(msg, cause);
}
}

83
core/src/main/java/com/databasir/core/domain/app/handler/GithubOpenAuthHandler.java

@ -0,0 +1,83 @@
package com.databasir.core.domain.app.handler;
import com.databasir.core.domain.DomainErrors;
import com.databasir.core.domain.app.exception.DatabasirAuthenticationException;
import com.databasir.core.infrastructure.remote.github.GithubRemoteService;
import com.databasir.dao.enums.OAuthAppType;
import com.databasir.dao.impl.OauthAppDao;
import com.databasir.dao.tables.pojos.OauthAppPojo;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.RequiredArgsConstructor;
import org.jooq.tools.StringUtils;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;
import java.util.Map;
@Component
@RequiredArgsConstructor
public class GithubOpenAuthHandler implements OpenAuthHandler {
private final GithubRemoteService githubRemoteService;
private final OauthAppDao oauthAppDao;
@Override
public boolean support(String oauthAppType) {
return OAuthAppType.GITHUB.isSame(oauthAppType);
}
@Override
public String authorization(String registrationId) {
OauthAppPojo app = oauthAppDao.selectByRegistrationId(registrationId);
String authUrl = app.getAuthUrl();
String clientId = app.getClientId();
String authorizeUrl = authUrl + "/login/oauth/authorize";
String url = UriComponentsBuilder.fromUriString(authorizeUrl)
.queryParam("client_id", clientId)
.queryParam("scope", "read:user user:email")
.encode()
.build()
.toUriString();
return url;
}
@Override
public OAuthProcessResult process(OAuthProcessContext context) {
OauthAppPojo authApp = oauthAppDao.selectByRegistrationId(context.getRegistrationId());
String clientId = authApp.getClientId();
String clientSecret = authApp.getClientSecret();
String baseUrl = authApp.getResourceUrl();
Map<String, String[]> params = context.getCallbackParameters();
String code = params.get("code")[0];
JsonNode tokenNode = githubRemoteService.getToken(baseUrl, clientId, clientSecret, code)
.get("access_token");
if (tokenNode == null) {
throw new DatabasirAuthenticationException(DomainErrors.NETWORK_ERROR.exception());
}
String accessToken = tokenNode.asText();
if (StringUtils.isBlank(accessToken)) {
throw new CredentialsExpiredException("授权失效,请重新登陆");
}
String email = null;
for (JsonNode node : githubRemoteService.getEmail(baseUrl, accessToken)) {
if (node.get("primary").asBoolean()) {
email = node.get("email").asText();
}
}
if (StringUtils.isBlank(email)) {
throw new CredentialsExpiredException("授权失效,请重新登陆");
}
JsonNode profile = githubRemoteService.getProfile(baseUrl, accessToken);
String nickname = profile.get("name").asText();
String avatar = profile.get("avatar_url").asText();
OAuthProcessResult result = new OAuthProcessResult();
result.setEmail(email);
result.setNickname(nickname);
result.setUsername(email);
result.setAvatar(avatar);
return result;
}
}

22
core/src/main/java/com/databasir/core/domain/app/handler/OAuthProcessContext.java

@ -0,0 +1,22 @@
package com.databasir.core.domain.app.handler;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.HashMap;
import java.util.Map;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class OAuthProcessContext {
private String registrationId;
@Builder.Default
private Map<String, String[]> callbackParameters = new HashMap<>();
}

16
core/src/main/java/com/databasir/core/domain/app/handler/OAuthProcessResult.java

@ -0,0 +1,16 @@
package com.databasir.core.domain.app.handler;
import lombok.Data;
@Data
public class OAuthProcessResult {
private String email;
private String username;
private String nickname;
private String avatar;
}

10
core/src/main/java/com/databasir/core/domain/app/handler/OpenAuthHandler.java

@ -0,0 +1,10 @@
package com.databasir.core.domain.app.handler;
public interface OpenAuthHandler {
boolean support(String oauthAppType);
String authorization(String registrationId);
OAuthProcessResult process(OAuthProcessContext context);
}

4
core/src/main/java/com/databasir/core/domain/user/data/UserLoginResponse.java → core/src/main/java/com/databasir/core/domain/login/data/UserLoginResponse.java

@ -1,4 +1,4 @@
package com.databasir.core.domain.user.data;
package com.databasir.core.domain.login.data;
import lombok.Data;
@ -15,6 +15,8 @@ public class UserLoginResponse {
private String username;
private String avatar;
private String accessToken;
private long accessTokenExpireAt;

40
core/src/main/java/com/databasir/core/domain/login/service/LoginService.java

@ -4,11 +4,14 @@ import com.databasir.core.domain.DomainErrors;
import com.databasir.core.domain.login.data.AccessTokenRefreshRequest;
import com.databasir.core.domain.login.data.AccessTokenRefreshResponse;
import com.databasir.core.domain.login.data.LoginKeyResponse;
import com.databasir.core.domain.login.data.UserLoginResponse;
import com.databasir.core.infrastructure.jwt.JwtTokens;
import com.databasir.dao.impl.LoginDao;
import com.databasir.dao.impl.UserDao;
import com.databasir.dao.impl.UserRoleDao;
import com.databasir.dao.tables.pojos.LoginPojo;
import com.databasir.dao.tables.pojos.UserPojo;
import com.databasir.dao.tables.pojos.UserRolePojo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@ -16,8 +19,11 @@ import org.springframework.stereotype.Service;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
@ -28,6 +34,8 @@ public class LoginService {
private final UserDao userDao;
private final UserRoleDao userRoleDao;
private final JwtTokens jwtTokens;
public AccessTokenRefreshResponse refreshAccessTokens(AccessTokenRefreshRequest request) {
@ -91,4 +99,36 @@ public class LoginService {
.refreshTokenExpireAt(refreshTokenExpireAt)
.build();
}
public Optional<UserLoginResponse> getUserLoginData(Integer userId) {
return loginDao.selectByUserId(userId)
.map(login -> {
UserPojo user = userDao.selectById(login.getUserId());
UserLoginResponse data = new UserLoginResponse();
data.setId(user.getId());
data.setNickname(user.getNickname());
data.setEmail(user.getEmail());
data.setUsername(user.getUsername());
data.setAccessToken(login.getAccessToken());
data.setAvatar(user.getAvatar());
long expireAt = login.getAccessTokenExpireAt()
.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
data.setAccessTokenExpireAt(expireAt);
data.setRefreshToken(login.getRefreshToken());
List<UserRolePojo> rolePojoList =
userRoleDao.selectByUserIds(Collections.singletonList(user.getId()));
List<UserLoginResponse.RoleResponse> roles = rolePojoList
.stream()
.map(ur -> {
UserLoginResponse.RoleResponse roleResponse = new UserLoginResponse.RoleResponse();
roleResponse.setRole(ur.getRole());
roleResponse.setGroupId(ur.getGroupId());
return roleResponse;
})
.collect(Collectors.toList());
data.setRoles(roles);
return data;
});
}
}

16
core/src/main/java/com/databasir/core/domain/user/data/UserLoginRequest.java

@ -1,16 +0,0 @@
package com.databasir.core.domain.user.data;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class UserLoginRequest {
@NotBlank
private String username;
@NotBlank
private String password;
}

19
core/src/main/java/com/databasir/core/domain/user/service/UserService.java

@ -65,14 +65,14 @@ public class UserService {
}
@Transactional
public void create(UserCreateRequest userCreateRequest) {
public Integer create(UserCreateRequest userCreateRequest) {
userDao.selectByEmailOrUsername(userCreateRequest.getUsername()).ifPresent(data -> {
throw DomainErrors.USERNAME_OR_EMAIL_DUPLICATE.exception();
});
String hashedPassword = bCryptPasswordEncoder.encode(userCreateRequest.getPassword());
UserPojo pojo = userPojoConverter.of(userCreateRequest, hashedPassword);
try {
userDao.insertAndReturnId(pojo);
return userDao.insertAndReturnId(pojo);
} catch (DuplicateKeyException e) {
throw DomainErrors.USERNAME_OR_EMAIL_DUPLICATE.exception();
}
@ -91,6 +91,21 @@ public class UserService {
return userResponseConverter.detailResponse(pojo, roles, groupNameMapById);
}
public Optional<UserDetailResponse> get(String email) {
return userDao.selectByEmail(email)
.map(user -> {
List<UserRolePojo> roles = userRoleDao.selectByUserIds(Collections.singletonList(user.getId()));
List<Integer> groupIds = roles.stream()
.map(UserRolePojo::getGroupId)
.filter(Objects::nonNull)
.collect(toList());
Map<Integer, String> groupNameMapById = groupDao.selectInIds(groupIds)
.stream()
.collect(toMap(GroupPojo::getId, GroupPojo::getName));
return userResponseConverter.detailResponse(user, roles, groupNameMapById);
});
}
@Transactional
public String renewPassword(Integer userId) {
UserPojo userPojo = userDao.selectById(userId);

34
core/src/main/java/com/databasir/core/infrastructure/remote/ClientConfig.java

@ -0,0 +1,34 @@
package com.databasir.core.infrastructure.remote;
import com.databasir.core.infrastructure.remote.github.GithubApiClient;
import com.databasir.core.infrastructure.remote.github.GithubOauthClient;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import retrofit2.Retrofit;
import retrofit2.converter.jackson.JacksonConverterFactory;
@Configuration
@RequiredArgsConstructor
@Slf4j
public class ClientConfig {
@Bean
public GithubApiClient githubApiClient() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(JacksonConverterFactory.create())
.build();
return retrofit.create(GithubApiClient.class);
}
@Bean
public GithubOauthClient githubOauthClient() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://github.com")
.addConverterFactory(JacksonConverterFactory.create())
.build();
return retrofit.create(GithubOauthClient.class);
}
}

23
core/src/main/java/com/databasir/core/infrastructure/remote/github/GithubApiClient.java

@ -0,0 +1,23 @@
package com.databasir.core.infrastructure.remote.github;
import com.fasterxml.jackson.databind.JsonNode;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.Url;
public interface GithubApiClient {
@GET
@Headers(value = {
"Accept: application/json"
})
Call<JsonNode> getEmail(@Url String url, @Header("Authorization") String token);
@GET
@Headers(value = {
"Accept: application/json"
})
Call<JsonNode> getProfile(@Url String url, @Header("Authorization") String token);
}

20
core/src/main/java/com/databasir/core/infrastructure/remote/github/GithubOauthClient.java

@ -0,0 +1,20 @@
package com.databasir.core.infrastructure.remote.github;
import com.fasterxml.jackson.databind.JsonNode;
import retrofit2.Call;
import retrofit2.http.Headers;
import retrofit2.http.POST;
import retrofit2.http.QueryMap;
import retrofit2.http.Url;
import java.util.Map;
public interface GithubOauthClient {
@Headers(value = {
"Accept: application/json"
})
@POST
Call<JsonNode> getAccessToken(@Url String url, @QueryMap Map<String, String> request);
}

74
core/src/main/java/com/databasir/core/infrastructure/remote/github/GithubRemoteService.java

@ -0,0 +1,74 @@
package com.databasir.core.infrastructure.remote.github;
import com.databasir.common.SystemException;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import retrofit2.Call;
import retrofit2.Response;
import java.io.IOException;
@Service
@RequiredArgsConstructor
@Slf4j
public class GithubRemoteService {
private static final String TOKEN_PREFIX = "token ";
private final GithubApiClient githubApiClient;
private final GithubOauthClient githubOauthClient;
public JsonNode getToken(String baseUrl,
String clientId,
String clientSecret,
String code) {
TokenRequest request = TokenRequest.builder()
.client_id(clientId)
.client_secret(clientSecret)
.code(code)
.build();
String path = "/login/oauth/access_token";
String url = baseUrl + path;
return execute(githubOauthClient.getAccessToken(url, request.toMap()));
}
public JsonNode getEmail(String baseUrl, String token) {
String path;
if (baseUrl.contains("api.github.com")) {
path = "/user/emails";
} else {
path = "/api/v3/user/emails";
}
String url = baseUrl + path;
return execute(githubApiClient.getEmail(url, TOKEN_PREFIX + token));
}
public JsonNode getProfile(String baseUrl, String token) {
String path;
if (baseUrl.contains("api.github.com")) {
path = "/user";
} else {
path = "/api/v3/user";
}
String url = baseUrl + path;
return execute(githubApiClient.getProfile(url, TOKEN_PREFIX + token));
}
private <T> T execute(Call<T> call) {
try {
Response<T> response = call.execute();
if (!response.isSuccessful()) {
log.error("request error: " + call.request() + ", response = " + response);
throw new SystemException("Call Remote Error");
} else {
T body = response.body();
return body;
}
} catch (IOException e) {
throw new SystemException("System Error", e);
}
}
}

32
core/src/main/java/com/databasir/core/infrastructure/remote/github/TokenRequest.java

@ -0,0 +1,32 @@
package com.databasir.core.infrastructure.remote.github;
import lombok.Builder;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
@Data
@SuppressWarnings("checkstyle:all")
@Builder
public class TokenRequest {
private String client_id;
private String client_secret;
private String code;
private String redirect_uri;
public Map<String, String> toMap() {
HashMap<String, String> map = new HashMap<>();
map.put("client_id", client_id);
map.put("client_secret", client_secret);
map.put("code", code);
if (redirect_uri != null) {
map.put("redirect_uri", redirect_uri);
}
return map;
}
}

7
dao/generated-src/jooq/main/java/com/databasir/dao/Databasir.java

@ -11,6 +11,7 @@ import com.databasir.dao.tables.DatabaseDocumentHistory;
import com.databasir.dao.tables.DocumentRemark;
import com.databasir.dao.tables.Group;
import com.databasir.dao.tables.Login;
import com.databasir.dao.tables.OauthApp;
import com.databasir.dao.tables.OperationLog;
import com.databasir.dao.tables.Project;
import com.databasir.dao.tables.ProjectSyncRule;
@ -80,6 +81,11 @@ public class Databasir extends SchemaImpl {
*/
public final Login LOGIN = Login.LOGIN;
/**
* oauth app info
*/
public final OauthApp OAUTH_APP = OauthApp.OAUTH_APP;
/**
* The table <code>databasir.operation_log</code>.
*/
@ -163,6 +169,7 @@ public class Databasir extends SchemaImpl {
DocumentRemark.DOCUMENT_REMARK,
Group.GROUP,
Login.LOGIN,
OauthApp.OAUTH_APP,
OperationLog.OPERATION_LOG,
Project.PROJECT,
ProjectSyncRule.PROJECT_SYNC_RULE,

2
dao/generated-src/jooq/main/java/com/databasir/dao/Indexes.java

@ -11,7 +11,6 @@ import com.databasir.dao.tables.TableColumnDocument;
import com.databasir.dao.tables.TableDocument;
import com.databasir.dao.tables.TableIndexDocument;
import com.databasir.dao.tables.TableTriggerDocument;
import com.databasir.dao.tables.UserFavoriteProject;
import org.jooq.Index;
import org.jooq.OrderField;
@ -39,5 +38,4 @@ public class Indexes {
public static final Index TABLE_COLUMN_DOCUMENT_IDX_TABLE_DOCUMENT_ID = Internal.createIndex(DSL.name("idx_table_document_id"), TableColumnDocument.TABLE_COLUMN_DOCUMENT, new OrderField[] { TableColumnDocument.TABLE_COLUMN_DOCUMENT.TABLE_DOCUMENT_ID }, false);
public static final Index TABLE_INDEX_DOCUMENT_IDX_TABLE_DOCUMENT_ID = Internal.createIndex(DSL.name("idx_table_document_id"), TableIndexDocument.TABLE_INDEX_DOCUMENT, new OrderField[] { TableIndexDocument.TABLE_INDEX_DOCUMENT.TABLE_DOCUMENT_ID }, false);
public static final Index TABLE_TRIGGER_DOCUMENT_IDX_TABLE_DOCUMENT_ID = Internal.createIndex(DSL.name("idx_table_document_id"), TableTriggerDocument.TABLE_TRIGGER_DOCUMENT, new OrderField[] { TableTriggerDocument.TABLE_TRIGGER_DOCUMENT.TABLE_DOCUMENT_ID }, false);
public static final Index USER_FAVORITE_PROJECT_IDX_USER_ID = Internal.createIndex(DSL.name("idx_user_id"), UserFavoriteProject.USER_FAVORITE_PROJECT, new OrderField[] { UserFavoriteProject.USER_FAVORITE_PROJECT.USER_ID }, false);
}

5
dao/generated-src/jooq/main/java/com/databasir/dao/Keys.java

@ -11,6 +11,7 @@ import com.databasir.dao.tables.DatabaseDocumentHistory;
import com.databasir.dao.tables.DocumentRemark;
import com.databasir.dao.tables.Group;
import com.databasir.dao.tables.Login;
import com.databasir.dao.tables.OauthApp;
import com.databasir.dao.tables.OperationLog;
import com.databasir.dao.tables.Project;
import com.databasir.dao.tables.ProjectSyncRule;
@ -30,6 +31,7 @@ import com.databasir.dao.tables.records.DatabaseDocumentRecord;
import com.databasir.dao.tables.records.DocumentRemarkRecord;
import com.databasir.dao.tables.records.GroupRecord;
import com.databasir.dao.tables.records.LoginRecord;
import com.databasir.dao.tables.records.OauthAppRecord;
import com.databasir.dao.tables.records.OperationLogRecord;
import com.databasir.dao.tables.records.ProjectRecord;
import com.databasir.dao.tables.records.ProjectSyncRuleRecord;
@ -71,6 +73,8 @@ public class Keys {
public static final UniqueKey<GroupRecord> KEY_GROUP_PRIMARY = Internal.createUniqueKey(Group.GROUP, DSL.name("KEY_group_PRIMARY"), new TableField[] { Group.GROUP.ID }, true);
public static final UniqueKey<LoginRecord> KEY_LOGIN_PRIMARY = Internal.createUniqueKey(Login.LOGIN, DSL.name("KEY_login_PRIMARY"), new TableField[] { Login.LOGIN.ID }, true);
public static final UniqueKey<LoginRecord> KEY_LOGIN_UK_USER_ID = Internal.createUniqueKey(Login.LOGIN, DSL.name("KEY_login_uk_user_id"), new TableField[] { Login.LOGIN.USER_ID }, true);
public static final UniqueKey<OauthAppRecord> KEY_OAUTH_APP_PRIMARY = Internal.createUniqueKey(OauthApp.OAUTH_APP, DSL.name("KEY_oauth_app_PRIMARY"), new TableField[] { OauthApp.OAUTH_APP.ID }, true);
public static final UniqueKey<OauthAppRecord> KEY_OAUTH_APP_UK_REGISTRATION_ID = Internal.createUniqueKey(OauthApp.OAUTH_APP, DSL.name("KEY_oauth_app_uk_registration_id"), new TableField[] { OauthApp.OAUTH_APP.REGISTRATION_ID }, true);
public static final UniqueKey<OperationLogRecord> KEY_OPERATION_LOG_PRIMARY = Internal.createUniqueKey(OperationLog.OPERATION_LOG, DSL.name("KEY_operation_log_PRIMARY"), new TableField[] { OperationLog.OPERATION_LOG.ID }, true);
public static final UniqueKey<ProjectRecord> KEY_PROJECT_PRIMARY = Internal.createUniqueKey(Project.PROJECT, DSL.name("KEY_project_PRIMARY"), new TableField[] { Project.PROJECT.ID }, true);
public static final UniqueKey<ProjectRecord> KEY_PROJECT_UK_GROUP_ID_NAME = Internal.createUniqueKey(Project.PROJECT, DSL.name("KEY_project_uk_group_id_name"), new TableField[] { Project.PROJECT.GROUP_ID, Project.PROJECT.NAME }, true);
@ -86,6 +90,7 @@ public class Keys {
public static final UniqueKey<UserRecord> KEY_USER_UK_EMAIL = Internal.createUniqueKey(User.USER, DSL.name("KEY_user_uk_email"), new TableField[] { User.USER.EMAIL }, true);
public static final UniqueKey<UserRecord> KEY_USER_UK_USERNAME = Internal.createUniqueKey(User.USER, DSL.name("KEY_user_uk_username"), new TableField[] { User.USER.USERNAME }, true);
public static final UniqueKey<UserFavoriteProjectRecord> KEY_USER_FAVORITE_PROJECT_PRIMARY = Internal.createUniqueKey(UserFavoriteProject.USER_FAVORITE_PROJECT, DSL.name("KEY_user_favorite_project_PRIMARY"), new TableField[] { UserFavoriteProject.USER_FAVORITE_PROJECT.ID }, true);
public static final UniqueKey<UserFavoriteProjectRecord> KEY_USER_FAVORITE_PROJECT_UK_USER_ID_PROJECT_ID = Internal.createUniqueKey(UserFavoriteProject.USER_FAVORITE_PROJECT, DSL.name("KEY_user_favorite_project_uk_user_id_project_id"), new TableField[] { UserFavoriteProject.USER_FAVORITE_PROJECT.USER_ID, UserFavoriteProject.USER_FAVORITE_PROJECT.PROJECT_ID }, true);
public static final UniqueKey<UserRoleRecord> KEY_USER_ROLE_PRIMARY = Internal.createUniqueKey(UserRole.USER_ROLE, DSL.name("KEY_user_role_PRIMARY"), new TableField[] { UserRole.USER_ROLE.ID }, true);
public static final UniqueKey<UserRoleRecord> KEY_USER_ROLE_UK_USER_ID_GROUP_ID_ROLE = Internal.createUniqueKey(UserRole.USER_ROLE, DSL.name("KEY_user_role_uk_user_id_group_id_role"), new TableField[] { UserRole.USER_ROLE.USER_ID, UserRole.USER_ROLE.GROUP_ID, UserRole.USER_ROLE.ROLE }, true);
}

6
dao/generated-src/jooq/main/java/com/databasir/dao/Tables.java

@ -11,6 +11,7 @@ import com.databasir.dao.tables.DatabaseDocumentHistory;
import com.databasir.dao.tables.DocumentRemark;
import com.databasir.dao.tables.Group;
import com.databasir.dao.tables.Login;
import com.databasir.dao.tables.OauthApp;
import com.databasir.dao.tables.OperationLog;
import com.databasir.dao.tables.Project;
import com.databasir.dao.tables.ProjectSyncRule;
@ -66,6 +67,11 @@ public class Tables {
*/
public static final Login LOGIN = Login.LOGIN;
/**
* oauth app info
*/
public static final OauthApp OAUTH_APP = OauthApp.OAUTH_APP;
/**
* The table <code>databasir.operation_log</code>.
*/

199
dao/generated-src/jooq/main/java/com/databasir/dao/tables/OauthApp.java

@ -0,0 +1,199 @@
/*
* This file is generated by jOOQ.
*/
package com.databasir.dao.tables;
import com.databasir.dao.Databasir;
import com.databasir.dao.Keys;
import com.databasir.dao.tables.records.OauthAppRecord;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import org.jooq.Field;
import org.jooq.ForeignKey;
import org.jooq.Identity;
import org.jooq.Name;
import org.jooq.Record;
import org.jooq.Row12;
import org.jooq.Schema;
import org.jooq.Table;
import org.jooq.TableField;
import org.jooq.TableOptions;
import org.jooq.UniqueKey;
import org.jooq.impl.DSL;
import org.jooq.impl.SQLDataType;
import org.jooq.impl.TableImpl;
/**
* oauth app info
*/
@SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class OauthApp extends TableImpl<OauthAppRecord> {
private static final long serialVersionUID = 1L;
/**
* The reference instance of <code>databasir.oauth_app</code>
*/
public static final OauthApp OAUTH_APP = new OauthApp();
/**
* The class holding records for this type
*/
@Override
public Class<OauthAppRecord> getRecordType() {
return OauthAppRecord.class;
}
/**
* The column <code>databasir.oauth_app.id</code>.
*/
public final TableField<OauthAppRecord, Integer> ID = createField(DSL.name("id"), SQLDataType.INTEGER.nullable(false).identity(true), this, "");
/**
* The column <code>databasir.oauth_app.registration_id</code>.
*/
public final TableField<OauthAppRecord, String> REGISTRATION_ID = createField(DSL.name("registration_id"), SQLDataType.VARCHAR(100).nullable(false), this, "");
/**
* The column <code>databasir.oauth_app.app_name</code>.
*/
public final TableField<OauthAppRecord, String> APP_NAME = createField(DSL.name("app_name"), SQLDataType.VARCHAR(128).nullable(false), this, "");
/**
* The column <code>databasir.oauth_app.app_icon</code>.
*/
public final TableField<OauthAppRecord, String> APP_ICON = createField(DSL.name("app_icon"), SQLDataType.VARCHAR(256).nullable(false).defaultValue(DSL.inline("", SQLDataType.VARCHAR)), this, "");
/**
* The column <code>databasir.oauth_app.app_type</code>. github, gitlab
*/
public final TableField<OauthAppRecord, String> APP_TYPE = createField(DSL.name("app_type"), SQLDataType.VARCHAR(64).nullable(false), this, "github, gitlab");
/**
* The column <code>databasir.oauth_app.client_id</code>.
*/
public final TableField<OauthAppRecord, String> CLIENT_ID = createField(DSL.name("client_id"), SQLDataType.VARCHAR(256), this, "");
/**
* The column <code>databasir.oauth_app.client_secret</code>.
*/
public final TableField<OauthAppRecord, String> CLIENT_SECRET = createField(DSL.name("client_secret"), SQLDataType.VARCHAR(256), this, "");
/**
* The column <code>databasir.oauth_app.auth_url</code>.
*/
public final TableField<OauthAppRecord, String> AUTH_URL = createField(DSL.name("auth_url"), SQLDataType.VARCHAR(256), this, "");
/**
* The column <code>databasir.oauth_app.resource_url</code>.
*/
public final TableField<OauthAppRecord, String> RESOURCE_URL = createField(DSL.name("resource_url"), SQLDataType.VARCHAR(256), this, "");
/**
* The column <code>databasir.oauth_app.scope</code>.
*/
public final TableField<OauthAppRecord, String> SCOPE = createField(DSL.name("scope"), SQLDataType.VARCHAR(256), this, "");
/**
* The column <code>databasir.oauth_app.update_at</code>.
*/
public final TableField<OauthAppRecord, LocalDateTime> UPDATE_AT = createField(DSL.name("update_at"), SQLDataType.LOCALDATETIME(0).nullable(false).defaultValue(DSL.field("CURRENT_TIMESTAMP", SQLDataType.LOCALDATETIME)), this, "");
/**
* The column <code>databasir.oauth_app.create_at</code>.
*/
public final TableField<OauthAppRecord, LocalDateTime> CREATE_AT = createField(DSL.name("create_at"), SQLDataType.LOCALDATETIME(0).nullable(false).defaultValue(DSL.field("CURRENT_TIMESTAMP", SQLDataType.LOCALDATETIME)), this, "");
private OauthApp(Name alias, Table<OauthAppRecord> aliased) {
this(alias, aliased, null);
}
private OauthApp(Name alias, Table<OauthAppRecord> aliased, Field<?>[] parameters) {
super(alias, null, aliased, parameters, DSL.comment("oauth app info"), TableOptions.table());
}
/**
* Create an aliased <code>databasir.oauth_app</code> table reference
*/
public OauthApp(String alias) {
this(DSL.name(alias), OAUTH_APP);
}
/**
* Create an aliased <code>databasir.oauth_app</code> table reference
*/
public OauthApp(Name alias) {
this(alias, OAUTH_APP);
}
/**
* Create a <code>databasir.oauth_app</code> table reference
*/
public OauthApp() {
this(DSL.name("oauth_app"), null);
}
public <O extends Record> OauthApp(Table<O> child, ForeignKey<O, OauthAppRecord> key) {
super(child, key, OAUTH_APP);
}
@Override
public Schema getSchema() {
return aliased() ? null : Databasir.DATABASIR;
}
@Override
public Identity<OauthAppRecord, Integer> getIdentity() {
return (Identity<OauthAppRecord, Integer>) super.getIdentity();
}
@Override
public UniqueKey<OauthAppRecord> getPrimaryKey() {
return Keys.KEY_OAUTH_APP_PRIMARY;
}
@Override
public List<UniqueKey<OauthAppRecord>> getUniqueKeys() {
return Arrays.asList(Keys.KEY_OAUTH_APP_UK_REGISTRATION_ID);
}
@Override
public OauthApp as(String alias) {
return new OauthApp(DSL.name(alias), this);
}
@Override
public OauthApp as(Name alias) {
return new OauthApp(alias, this);
}
/**
* Rename this table
*/
@Override
public OauthApp rename(String name) {
return new OauthApp(DSL.name(name), null);
}
/**
* Rename this table
*/
@Override
public OauthApp rename(Name name) {
return new OauthApp(name, null);
}
// -------------------------------------------------------------------------
// Row12 type methods
// -------------------------------------------------------------------------
@Override
public Row12<Integer, String, String, String, String, String, String, String, String, String, LocalDateTime, LocalDateTime> fieldsRow() {
return (Row12) super.fieldsRow();
}
}

12
dao/generated-src/jooq/main/java/com/databasir/dao/tables/UserFavoriteProject.java

@ -5,7 +5,6 @@ package com.databasir.dao.tables;
import com.databasir.dao.Databasir;
import com.databasir.dao.Indexes;
import com.databasir.dao.Keys;
import com.databasir.dao.tables.records.UserFavoriteProjectRecord;
@ -16,7 +15,6 @@ import java.util.List;
import org.jooq.Field;
import org.jooq.ForeignKey;
import org.jooq.Identity;
import org.jooq.Index;
import org.jooq.Name;
import org.jooq.Record;
import org.jooq.Row4;
@ -111,11 +109,6 @@ public class UserFavoriteProject extends TableImpl<UserFavoriteProjectRecord> {
return aliased() ? null : Databasir.DATABASIR;
}
@Override
public List<Index> getIndexes() {
return Arrays.asList(Indexes.USER_FAVORITE_PROJECT_IDX_USER_ID);
}
@Override
public Identity<UserFavoriteProjectRecord, Integer> getIdentity() {
return (Identity<UserFavoriteProjectRecord, Integer>) super.getIdentity();
@ -126,6 +119,11 @@ public class UserFavoriteProject extends TableImpl<UserFavoriteProjectRecord> {
return Keys.KEY_USER_FAVORITE_PROJECT_PRIMARY;
}
@Override
public List<UniqueKey<UserFavoriteProjectRecord>> getUniqueKeys() {
return Arrays.asList(Keys.KEY_USER_FAVORITE_PROJECT_UK_USER_ID_PROJECT_ID);
}
@Override
public UserFavoriteProject as(String alias) {
return new UserFavoriteProject(DSL.name(alias), this);

265
dao/generated-src/jooq/main/java/com/databasir/dao/tables/pojos/OauthAppPojo.java

@ -0,0 +1,265 @@
/*
* This file is generated by jOOQ.
*/
package com.databasir.dao.tables.pojos;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* oauth app info
*/
@SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class OauthAppPojo implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String registrationId;
private String appName;
private String appIcon;
private String appType;
private String clientId;
private String clientSecret;
private String authUrl;
private String resourceUrl;
private String scope;
private LocalDateTime updateAt;
private LocalDateTime createAt;
public OauthAppPojo() {}
public OauthAppPojo(OauthAppPojo value) {
this.id = value.id;
this.registrationId = value.registrationId;
this.appName = value.appName;
this.appIcon = value.appIcon;
this.appType = value.appType;
this.clientId = value.clientId;
this.clientSecret = value.clientSecret;
this.authUrl = value.authUrl;
this.resourceUrl = value.resourceUrl;
this.scope = value.scope;
this.updateAt = value.updateAt;
this.createAt = value.createAt;
}
public OauthAppPojo(
Integer id,
String registrationId,
String appName,
String appIcon,
String appType,
String clientId,
String clientSecret,
String authUrl,
String resourceUrl,
String scope,
LocalDateTime updateAt,
LocalDateTime createAt
) {
this.id = id;
this.registrationId = registrationId;
this.appName = appName;
this.appIcon = appIcon;
this.appType = appType;
this.clientId = clientId;
this.clientSecret = clientSecret;
this.authUrl = authUrl;
this.resourceUrl = resourceUrl;
this.scope = scope;
this.updateAt = updateAt;
this.createAt = createAt;
}
/**
* Getter for <code>databasir.oauth_app.id</code>.
*/
public Integer getId() {
return this.id;
}
/**
* Setter for <code>databasir.oauth_app.id</code>.
*/
public void setId(Integer id) {
this.id = id;
}
/**
* Getter for <code>databasir.oauth_app.registration_id</code>.
*/
public String getRegistrationId() {
return this.registrationId;
}
/**
* Setter for <code>databasir.oauth_app.registration_id</code>.
*/
public void setRegistrationId(String registrationId) {
this.registrationId = registrationId;
}
/**
* Getter for <code>databasir.oauth_app.app_name</code>.
*/
public String getAppName() {
return this.appName;
}
/**
* Setter for <code>databasir.oauth_app.app_name</code>.
*/
public void setAppName(String appName) {
this.appName = appName;
}
/**
* Getter for <code>databasir.oauth_app.app_icon</code>.
*/
public String getAppIcon() {
return this.appIcon;
}
/**
* Setter for <code>databasir.oauth_app.app_icon</code>.
*/
public void setAppIcon(String appIcon) {
this.appIcon = appIcon;
}
/**
* Getter for <code>databasir.oauth_app.app_type</code>. github, gitlab
*/
public String getAppType() {
return this.appType;
}
/**
* Setter for <code>databasir.oauth_app.app_type</code>. github, gitlab
*/
public void setAppType(String appType) {
this.appType = appType;
}
/**
* Getter for <code>databasir.oauth_app.client_id</code>.
*/
public String getClientId() {
return this.clientId;
}
/**
* Setter for <code>databasir.oauth_app.client_id</code>.
*/
public void setClientId(String clientId) {
this.clientId = clientId;
}
/**
* Getter for <code>databasir.oauth_app.client_secret</code>.
*/
public String getClientSecret() {
return this.clientSecret;
}
/**
* Setter for <code>databasir.oauth_app.client_secret</code>.
*/
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
/**
* Getter for <code>databasir.oauth_app.auth_url</code>.
*/
public String getAuthUrl() {
return this.authUrl;
}
/**
* Setter for <code>databasir.oauth_app.auth_url</code>.
*/
public void setAuthUrl(String authUrl) {
this.authUrl = authUrl;
}
/**
* Getter for <code>databasir.oauth_app.resource_url</code>.
*/
public String getResourceUrl() {
return this.resourceUrl;
}
/**
* Setter for <code>databasir.oauth_app.resource_url</code>.
*/
public void setResourceUrl(String resourceUrl) {
this.resourceUrl = resourceUrl;
}
/**
* Getter for <code>databasir.oauth_app.scope</code>.
*/
public String getScope() {
return this.scope;
}
/**
* Setter for <code>databasir.oauth_app.scope</code>.
*/
public void setScope(String scope) {
this.scope = scope;
}
/**
* Getter for <code>databasir.oauth_app.update_at</code>.
*/
public LocalDateTime getUpdateAt() {
return this.updateAt;
}
/**
* Setter for <code>databasir.oauth_app.update_at</code>.
*/
public void setUpdateAt(LocalDateTime updateAt) {
this.updateAt = updateAt;
}
/**
* Getter for <code>databasir.oauth_app.create_at</code>.
*/
public LocalDateTime getCreateAt() {
return this.createAt;
}
/**
* Setter for <code>databasir.oauth_app.create_at</code>.
*/
public void setCreateAt(LocalDateTime createAt) {
this.createAt = createAt;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("OauthAppPojo (");
sb.append(id);
sb.append(", ").append(registrationId);
sb.append(", ").append(appName);
sb.append(", ").append(appIcon);
sb.append(", ").append(appType);
sb.append(", ").append(clientId);
sb.append(", ").append(clientSecret);
sb.append(", ").append(authUrl);
sb.append(", ").append(resourceUrl);
sb.append(", ").append(scope);
sb.append(", ").append(updateAt);
sb.append(", ").append(createAt);
sb.append(")");
return sb.toString();
}
}

539
dao/generated-src/jooq/main/java/com/databasir/dao/tables/records/OauthAppRecord.java

@ -0,0 +1,539 @@
/*
* This file is generated by jOOQ.
*/
package com.databasir.dao.tables.records;
import com.databasir.dao.tables.OauthApp;
import com.databasir.dao.tables.pojos.OauthAppPojo;
import java.time.LocalDateTime;
import org.jooq.Field;
import org.jooq.Record1;
import org.jooq.Record12;
import org.jooq.Row12;
import org.jooq.impl.UpdatableRecordImpl;
/**
* oauth app info
*/
@SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class OauthAppRecord extends UpdatableRecordImpl<OauthAppRecord> implements Record12<Integer, String, String, String, String, String, String, String, String, String, LocalDateTime, LocalDateTime> {
private static final long serialVersionUID = 1L;
/**
* Setter for <code>databasir.oauth_app.id</code>.
*/
public void setId(Integer value) {
set(0, value);
}
/**
* Getter for <code>databasir.oauth_app.id</code>.
*/
public Integer getId() {
return (Integer) get(0);
}
/**
* Setter for <code>databasir.oauth_app.registration_id</code>.
*/
public void setRegistrationId(String value) {
set(1, value);
}
/**
* Getter for <code>databasir.oauth_app.registration_id</code>.
*/
public String getRegistrationId() {
return (String) get(1);
}
/**
* Setter for <code>databasir.oauth_app.app_name</code>.
*/
public void setAppName(String value) {
set(2, value);
}
/**
* Getter for <code>databasir.oauth_app.app_name</code>.
*/
public String getAppName() {
return (String) get(2);
}
/**
* Setter for <code>databasir.oauth_app.app_icon</code>.
*/
public void setAppIcon(String value) {
set(3, value);
}
/**
* Getter for <code>databasir.oauth_app.app_icon</code>.
*/
public String getAppIcon() {
return (String) get(3);
}
/**
* Setter for <code>databasir.oauth_app.app_type</code>. github, gitlab
*/
public void setAppType(String value) {
set(4, value);
}
/**
* Getter for <code>databasir.oauth_app.app_type</code>. github, gitlab
*/
public String getAppType() {
return (String) get(4);
}
/**
* Setter for <code>databasir.oauth_app.client_id</code>.
*/
public void setClientId(String value) {
set(5, value);
}
/**
* Getter for <code>databasir.oauth_app.client_id</code>.
*/
public String getClientId() {
return (String) get(5);
}
/**
* Setter for <code>databasir.oauth_app.client_secret</code>.
*/
public void setClientSecret(String value) {
set(6, value);
}
/**
* Getter for <code>databasir.oauth_app.client_secret</code>.
*/
public String getClientSecret() {
return (String) get(6);
}
/**
* Setter for <code>databasir.oauth_app.auth_url</code>.
*/
public void setAuthUrl(String value) {
set(7, value);
}
/**
* Getter for <code>databasir.oauth_app.auth_url</code>.
*/
public String getAuthUrl() {
return (String) get(7);
}
/**
* Setter for <code>databasir.oauth_app.resource_url</code>.
*/
public void setResourceUrl(String value) {
set(8, value);
}
/**
* Getter for <code>databasir.oauth_app.resource_url</code>.
*/
public String getResourceUrl() {
return (String) get(8);
}
/**
* Setter for <code>databasir.oauth_app.scope</code>.
*/
public void setScope(String value) {
set(9, value);
}
/**
* Getter for <code>databasir.oauth_app.scope</code>.
*/
public String getScope() {
return (String) get(9);
}
/**
* Setter for <code>databasir.oauth_app.update_at</code>.
*/
public void setUpdateAt(LocalDateTime value) {
set(10, value);
}
/**
* Getter for <code>databasir.oauth_app.update_at</code>.
*/
public LocalDateTime getUpdateAt() {
return (LocalDateTime) get(10);
}
/**
* Setter for <code>databasir.oauth_app.create_at</code>.
*/
public void setCreateAt(LocalDateTime value) {
set(11, value);
}
/**
* Getter for <code>databasir.oauth_app.create_at</code>.
*/
public LocalDateTime getCreateAt() {
return (LocalDateTime) get(11);
}
// -------------------------------------------------------------------------
// Primary key information
// -------------------------------------------------------------------------
@Override
public Record1<Integer> key() {
return (Record1) super.key();
}
// -------------------------------------------------------------------------
// Record12 type implementation
// -------------------------------------------------------------------------
@Override
public Row12<Integer, String, String, String, String, String, String, String, String, String, LocalDateTime, LocalDateTime> fieldsRow() {
return (Row12) super.fieldsRow();
}
@Override
public Row12<Integer, String, String, String, String, String, String, String, String, String, LocalDateTime, LocalDateTime> valuesRow() {
return (Row12) super.valuesRow();
}
@Override
public Field<Integer> field1() {
return OauthApp.OAUTH_APP.ID;
}
@Override
public Field<String> field2() {
return OauthApp.OAUTH_APP.REGISTRATION_ID;
}
@Override
public Field<String> field3() {
return OauthApp.OAUTH_APP.APP_NAME;
}
@Override
public Field<String> field4() {
return OauthApp.OAUTH_APP.APP_ICON;
}
@Override
public Field<String> field5() {
return OauthApp.OAUTH_APP.APP_TYPE;
}
@Override
public Field<String> field6() {
return OauthApp.OAUTH_APP.CLIENT_ID;
}
@Override
public Field<String> field7() {
return OauthApp.OAUTH_APP.CLIENT_SECRET;
}
@Override
public Field<String> field8() {
return OauthApp.OAUTH_APP.AUTH_URL;
}
@Override
public Field<String> field9() {
return OauthApp.OAUTH_APP.RESOURCE_URL;
}
@Override
public Field<String> field10() {
return OauthApp.OAUTH_APP.SCOPE;
}
@Override
public Field<LocalDateTime> field11() {
return OauthApp.OAUTH_APP.UPDATE_AT;
}
@Override
public Field<LocalDateTime> field12() {
return OauthApp.OAUTH_APP.CREATE_AT;
}
@Override
public Integer component1() {
return getId();
}
@Override
public String component2() {
return getRegistrationId();
}
@Override
public String component3() {
return getAppName();
}
@Override
public String component4() {
return getAppIcon();
}
@Override
public String component5() {
return getAppType();
}
@Override
public String component6() {
return getClientId();
}
@Override
public String component7() {
return getClientSecret();
}
@Override
public String component8() {
return getAuthUrl();
}
@Override
public String component9() {
return getResourceUrl();
}
@Override
public String component10() {
return getScope();
}
@Override
public LocalDateTime component11() {
return getUpdateAt();
}
@Override
public LocalDateTime component12() {
return getCreateAt();
}
@Override
public Integer value1() {
return getId();
}
@Override
public String value2() {
return getRegistrationId();
}
@Override
public String value3() {
return getAppName();
}
@Override
public String value4() {
return getAppIcon();
}
@Override
public String value5() {
return getAppType();
}
@Override
public String value6() {
return getClientId();
}
@Override
public String value7() {
return getClientSecret();
}
@Override
public String value8() {
return getAuthUrl();
}
@Override
public String value9() {
return getResourceUrl();
}
@Override
public String value10() {
return getScope();
}
@Override
public LocalDateTime value11() {
return getUpdateAt();
}
@Override
public LocalDateTime value12() {
return getCreateAt();
}
@Override
public OauthAppRecord value1(Integer value) {
setId(value);
return this;
}
@Override
public OauthAppRecord value2(String value) {
setRegistrationId(value);
return this;
}
@Override
public OauthAppRecord value3(String value) {
setAppName(value);
return this;
}
@Override
public OauthAppRecord value4(String value) {
setAppIcon(value);
return this;
}
@Override
public OauthAppRecord value5(String value) {
setAppType(value);
return this;
}
@Override
public OauthAppRecord value6(String value) {
setClientId(value);
return this;
}
@Override
public OauthAppRecord value7(String value) {
setClientSecret(value);
return this;
}
@Override
public OauthAppRecord value8(String value) {
setAuthUrl(value);
return this;
}
@Override
public OauthAppRecord value9(String value) {
setResourceUrl(value);
return this;
}
@Override
public OauthAppRecord value10(String value) {
setScope(value);
return this;
}
@Override
public OauthAppRecord value11(LocalDateTime value) {
setUpdateAt(value);
return this;
}
@Override
public OauthAppRecord value12(LocalDateTime value) {
setCreateAt(value);
return this;
}
@Override
public OauthAppRecord values(Integer value1, String value2, String value3, String value4, String value5, String value6, String value7, String value8, String value9, String value10, LocalDateTime value11, LocalDateTime value12) {
value1(value1);
value2(value2);
value3(value3);
value4(value4);
value5(value5);
value6(value6);
value7(value7);
value8(value8);
value9(value9);
value10(value10);
value11(value11);
value12(value12);
return this;
}
// -------------------------------------------------------------------------
// Constructors
// -------------------------------------------------------------------------
/**
* Create a detached OauthAppRecord
*/
public OauthAppRecord() {
super(OauthApp.OAUTH_APP);
}
/**
* Create a detached, initialised OauthAppRecord
*/
public OauthAppRecord(Integer id, String registrationId, String appName, String appIcon, String appType, String clientId, String clientSecret, String authUrl, String resourceUrl, String scope, LocalDateTime updateAt, LocalDateTime createAt) {
super(OauthApp.OAUTH_APP);
setId(id);
setRegistrationId(registrationId);
setAppName(appName);
setAppIcon(appIcon);
setAppType(appType);
setClientId(clientId);
setClientSecret(clientSecret);
setAuthUrl(authUrl);
setResourceUrl(resourceUrl);
setScope(scope);
setUpdateAt(updateAt);
setCreateAt(createAt);
}
/**
* Create a detached, initialised OauthAppRecord
*/
public OauthAppRecord(OauthAppPojo value) {
super(OauthApp.OAUTH_APP);
if (value != null) {
setId(value.getId());
setRegistrationId(value.getRegistrationId());
setAppName(value.getAppName());
setAppIcon(value.getAppIcon());
setAppType(value.getAppType());
setClientId(value.getClientId());
setClientSecret(value.getClientSecret());
setAuthUrl(value.getAuthUrl());
setResourceUrl(value.getResourceUrl());
setScope(value.getScope());
setUpdateAt(value.getUpdateAt());
setCreateAt(value.getCreateAt());
}
}
}

10
dao/src/main/java/com/databasir/dao/enums/OAuthAppType.java

@ -0,0 +1,10 @@
package com.databasir.dao.enums;
public enum OAuthAppType {
GITHUB, GITLAB;
public boolean isSame(String type) {
return this.name().equalsIgnoreCase(type);
}
}

6
dao/src/main/java/com/databasir/dao/impl/BaseDao.java

@ -90,6 +90,12 @@ public abstract class BaseDao<R> {
.fetchInto(pojoType);
}
public List<R> selectAll() {
return this.getDslContext()
.selectFrom(table())
.fetchInto(pojoType);
}
public Page<R> selectByPage(Pageable request, Condition condition) {
Integer count = getDslContext()
.selectCount().from(table).where(condition)

7
dao/src/main/java/com/databasir/dao/impl/LoginDao.java

@ -40,6 +40,13 @@ public class LoginDao extends BaseDao<LoginPojo> {
.fetchOptionalInto(LoginPojo.class);
}
public Optional<LoginPojo> selectByAccessToken(String accessToken) {
return getDslContext()
.selectFrom(LOGIN).where(LOGIN.ACCESS_TOKEN.eq(accessToken)
.and(LOGIN.ACCESS_TOKEN_EXPIRE_AT.ge(LocalDateTime.now())))
.fetchOptionalInto(LoginPojo.class);
}
public void updateAccessToken(String accessToken, LocalDateTime accessTokenExpireAt, Integer userId) {
getDslContext()
.update(LOGIN)

37
dao/src/main/java/com/databasir/dao/impl/OauthAppDao.java

@ -0,0 +1,37 @@
package com.databasir.dao.impl;
import com.databasir.dao.exception.DataNotExistsException;
import com.databasir.dao.tables.pojos.OauthAppPojo;
import lombok.Getter;
import org.jooq.DSLContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.Optional;
import static com.databasir.dao.Tables.OAUTH_APP;
@Repository
public class OauthAppDao extends BaseDao<OauthAppPojo> {
@Autowired
@Getter
private DSLContext dslContext;
public OauthAppDao() {
super(OAUTH_APP, OauthAppPojo.class);
}
public Optional<OauthAppPojo> selectOptionByRegistrationId(String registrationId) {
return this.getDslContext()
.select(OAUTH_APP.fields()).from(OAUTH_APP).where(OAUTH_APP.REGISTRATION_ID.eq(registrationId))
.fetchOptionalInto(OauthAppPojo.class);
}
public OauthAppPojo selectByRegistrationId(String registrationId) {
return this.getDslContext()
.select(OAUTH_APP.fields()).from(OAUTH_APP).where(OAUTH_APP.REGISTRATION_ID.eq(registrationId))
.fetchOptionalInto(OauthAppPojo.class)
.orElseThrow(() -> new DataNotExistsException("can not found oauth app by " + registrationId));
}
}

18
dao/src/main/resources/db/migration/V1.4__oauth.sql

@ -0,0 +1,18 @@
CREATE TABLE IF NOT EXISTS oauth_app
(
id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
registration_id VARCHAR(100) NOT NULL,
app_name VARCHAR(128) NOT NULL,
app_icon VARCHAR(256) NOT NULL DEFAULT '',
app_type VARCHAR(64) NOT NULL COMMENT 'github, gitlab',
client_id VARCHAR(256),
client_secret VARCHAR(256),
auth_url VARCHAR(256),
resource_url VARCHAR(256),
scope VARCHAR(256),
update_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
create_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE uk_registration_id (registration_id)
) CHARSET utf8mb4
COLLATE utf8mb4_unicode_ci COMMENT 'oauth app info';
Loading…
Cancel
Save