support gitlab oauth2 login (#28)
* feat: support gitlab oauth login * feat: change appType to enum
This commit is contained in:
parent
cd20dfd7cf
commit
905d7d5543
|
@ -3,7 +3,7 @@ package com.databasir.api;
|
||||||
import com.databasir.common.JsonData;
|
import com.databasir.common.JsonData;
|
||||||
import com.databasir.core.domain.app.OpenAuthAppService;
|
import com.databasir.core.domain.app.OpenAuthAppService;
|
||||||
import com.databasir.core.domain.app.data.*;
|
import com.databasir.core.domain.app.data.*;
|
||||||
import com.databasir.core.domain.app.handler.OpenAuthHandler;
|
import com.databasir.core.domain.app.handler.OpenAuthHandlers;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
@ -12,8 +12,10 @@ import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.springframework.data.domain.Sort.Direction.DESC;
|
import static org.springframework.data.domain.Sort.Direction.DESC;
|
||||||
|
|
||||||
|
@ -21,17 +23,19 @@ import static org.springframework.data.domain.Sort.Direction.DESC;
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class OpenAuth2AppController {
|
public class OpenAuth2AppController {
|
||||||
|
|
||||||
private final OpenAuthHandler openAuthHandler;
|
|
||||||
|
|
||||||
private final OpenAuthAppService openAuthAppService;
|
private final OpenAuthAppService openAuthAppService;
|
||||||
|
|
||||||
|
private final OpenAuthHandlers openAuthHandlers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 无需授权
|
* 无需授权
|
||||||
*/
|
*/
|
||||||
@GetMapping("/oauth2/authorization/{registrationId}")
|
@GetMapping("/oauth2/authorization/{registrationId}")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public JsonData<String> authorization(@PathVariable String registrationId) {
|
public JsonData<String> authorization(@PathVariable String registrationId,
|
||||||
String authorization = openAuthHandler.authorization(registrationId);
|
HttpServletRequest request) {
|
||||||
|
Map<String, String[]> parameters = request.getParameterMap();
|
||||||
|
String authorization = openAuthHandlers.authorizeUrl(registrationId, parameters);
|
||||||
return JsonData.ok(authorization);
|
return JsonData.ok(authorization);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,8 @@ public enum DomainErrors implements DatabasirErrors {
|
||||||
UPDATE_PASSWORD_CONFIRM_FAILED("A_10010", "两次密码输入不一致"),
|
UPDATE_PASSWORD_CONFIRM_FAILED("A_10010", "两次密码输入不一致"),
|
||||||
ORIGIN_PASSWORD_NOT_CORRECT("A_10011", "原密码不正确"),
|
ORIGIN_PASSWORD_NOT_CORRECT("A_10011", "原密码不正确"),
|
||||||
INVALID_CRON_EXPRESSION("A_10012", "不合法的 cron 表达式"),
|
INVALID_CRON_EXPRESSION("A_10012", "不合法的 cron 表达式"),
|
||||||
REGISTRATION_ID_DUPLICATE("A_10013", "应用注册 ID 不能重复");
|
REGISTRATION_ID_DUPLICATE("A_10013", "应用注册 ID 不能重复"),
|
||||||
|
MISS_REQUIRED_PARAMETERS("A_10014", "缺少必填参数");
|
||||||
|
|
||||||
private final String errCode;
|
private final String errCode;
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,8 @@ import com.databasir.core.domain.DomainErrors;
|
||||||
import com.databasir.core.domain.app.converter.OAuthAppPojoConverter;
|
import com.databasir.core.domain.app.converter.OAuthAppPojoConverter;
|
||||||
import com.databasir.core.domain.app.converter.OAuthAppResponseConverter;
|
import com.databasir.core.domain.app.converter.OAuthAppResponseConverter;
|
||||||
import com.databasir.core.domain.app.data.*;
|
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.app.handler.OAuthProcessResult;
|
||||||
|
import com.databasir.core.domain.app.handler.OpenAuthHandlers;
|
||||||
import com.databasir.core.domain.user.data.UserCreateRequest;
|
import com.databasir.core.domain.user.data.UserCreateRequest;
|
||||||
import com.databasir.core.domain.user.data.UserDetailResponse;
|
import com.databasir.core.domain.user.data.UserDetailResponse;
|
||||||
import com.databasir.core.domain.user.service.UserService;
|
import com.databasir.core.domain.user.service.UserService;
|
||||||
|
@ -16,7 +15,6 @@ import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.dao.DuplicateKeyException;
|
import org.springframework.dao.DuplicateKeyException;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -29,7 +27,7 @@ import java.util.stream.Collectors;
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class OpenAuthAppService {
|
public class OpenAuthAppService {
|
||||||
|
|
||||||
private final List<OpenAuthHandler> openAuthHandlers;
|
private final OpenAuthHandlers openAuthHandlers;
|
||||||
|
|
||||||
private final OauthAppDao oauthAppDao;
|
private final OauthAppDao oauthAppDao;
|
||||||
|
|
||||||
|
@ -40,20 +38,8 @@ public class OpenAuthAppService {
|
||||||
private final OAuthAppPojoConverter oauthAppPojoConverter;
|
private final OAuthAppPojoConverter oauthAppPojoConverter;
|
||||||
|
|
||||||
public UserDetailResponse oauthCallback(String registrationId, Map<String, String[]> params) {
|
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
|
// process by handler
|
||||||
OAuthProcessContext context = OAuthProcessContext.builder()
|
OAuthProcessResult result = openAuthHandlers.process(registrationId, params);
|
||||||
.callbackParameters(params)
|
|
||||||
.registrationId(registrationId)
|
|
||||||
.build();
|
|
||||||
OAuthProcessResult result = openAuthHandler.process(context);
|
|
||||||
|
|
||||||
// get or create new user
|
// get or create new user
|
||||||
return userService.get(result.getEmail())
|
return userService.get(result.getEmail())
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.databasir.core.domain.app.data;
|
package com.databasir.core.domain.app.data;
|
||||||
|
|
||||||
|
import com.databasir.dao.enums.OAuthAppType;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
|
@ -14,8 +15,8 @@ public class OAuthAppCreateRequest {
|
||||||
@NotBlank
|
@NotBlank
|
||||||
private String appName;
|
private String appName;
|
||||||
|
|
||||||
@NotBlank
|
@NotNull
|
||||||
private String appType;
|
private OAuthAppType appType;
|
||||||
|
|
||||||
private String appIcon;
|
private String appIcon;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.databasir.core.domain.app.data;
|
package com.databasir.core.domain.app.data;
|
||||||
|
|
||||||
|
import com.databasir.dao.enums.OAuthAppType;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
@ -13,7 +14,7 @@ public class OAuthAppDetailResponse {
|
||||||
|
|
||||||
private String appIcon;
|
private String appIcon;
|
||||||
|
|
||||||
private String appType;
|
private OAuthAppType appType;
|
||||||
|
|
||||||
private String registrationId;
|
private String registrationId;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.databasir.core.domain.app.data;
|
package com.databasir.core.domain.app.data;
|
||||||
|
|
||||||
import com.databasir.dao.Tables;
|
import com.databasir.dao.Tables;
|
||||||
|
import com.databasir.dao.enums.OAuthAppType;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.jooq.Condition;
|
import org.jooq.Condition;
|
||||||
import org.jooq.impl.DSL;
|
import org.jooq.impl.DSL;
|
||||||
|
@ -13,7 +14,7 @@ public class OAuthAppPageCondition {
|
||||||
|
|
||||||
private String appNameContains;
|
private String appNameContains;
|
||||||
|
|
||||||
private String appType;
|
private OAuthAppType appType;
|
||||||
|
|
||||||
public Condition toCondition() {
|
public Condition toCondition() {
|
||||||
List<Condition> conditions = new ArrayList<>();
|
List<Condition> conditions = new ArrayList<>();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.databasir.core.domain.app.data;
|
package com.databasir.core.domain.app.data;
|
||||||
|
|
||||||
|
import com.databasir.dao.enums.OAuthAppType;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
@ -13,7 +14,7 @@ public class OAuthAppPageResponse {
|
||||||
|
|
||||||
private String appIcon;
|
private String appIcon;
|
||||||
|
|
||||||
private String appType;
|
private OAuthAppType appType;
|
||||||
|
|
||||||
private String registrationId;
|
private String registrationId;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.databasir.core.domain.app.data;
|
package com.databasir.core.domain.app.data;
|
||||||
|
|
||||||
|
import com.databasir.dao.enums.OAuthAppType;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
@ -19,7 +20,7 @@ public class OAuthAppResponse {
|
||||||
|
|
||||||
private String appIcon;
|
private String appIcon;
|
||||||
|
|
||||||
private String appType;
|
private OAuthAppType appType;
|
||||||
|
|
||||||
private String registrationId;
|
private String registrationId;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.databasir.core.domain.app.data;
|
package com.databasir.core.domain.app.data;
|
||||||
|
|
||||||
|
import com.databasir.dao.enums.OAuthAppType;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
|
@ -17,8 +18,8 @@ public class OAuthAppUpdateRequest {
|
||||||
@NotBlank
|
@NotBlank
|
||||||
private String appName;
|
private String appName;
|
||||||
|
|
||||||
@NotBlank
|
@NotNull
|
||||||
private String appType;
|
private OAuthAppType appType;
|
||||||
|
|
||||||
private String appIcon;
|
private String appIcon;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import com.databasir.core.domain.DomainErrors;
|
||||||
import com.databasir.core.domain.app.exception.DatabasirAuthenticationException;
|
import com.databasir.core.domain.app.exception.DatabasirAuthenticationException;
|
||||||
import com.databasir.core.infrastructure.remote.github.GithubRemoteService;
|
import com.databasir.core.infrastructure.remote.github.GithubRemoteService;
|
||||||
import com.databasir.dao.enums.OAuthAppType;
|
import com.databasir.dao.enums.OAuthAppType;
|
||||||
import com.databasir.dao.impl.OauthAppDao;
|
|
||||||
import com.databasir.dao.tables.pojos.OauthAppPojo;
|
import com.databasir.dao.tables.pojos.OauthAppPojo;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
@ -21,16 +20,13 @@ public class GithubOpenAuthHandler implements OpenAuthHandler {
|
||||||
|
|
||||||
private final GithubRemoteService githubRemoteService;
|
private final GithubRemoteService githubRemoteService;
|
||||||
|
|
||||||
private final OauthAppDao oauthAppDao;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean support(String oauthAppType) {
|
public boolean support(OAuthAppType oauthAppType) {
|
||||||
return OAuthAppType.GITHUB.isSame(oauthAppType);
|
return OAuthAppType.GITHUB == oauthAppType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String authorization(String registrationId) {
|
public String authorizationUrl(OauthAppPojo app, Map<String, String[]> requestParams) {
|
||||||
OauthAppPojo app = oauthAppDao.selectByRegistrationId(registrationId);
|
|
||||||
String authUrl = app.getAuthUrl();
|
String authUrl = app.getAuthUrl();
|
||||||
String clientId = app.getClientId();
|
String clientId = app.getClientId();
|
||||||
String authorizeUrl = authUrl + "/login/oauth/authorize";
|
String authorizeUrl = authUrl + "/login/oauth/authorize";
|
||||||
|
@ -44,14 +40,12 @@ public class GithubOpenAuthHandler implements OpenAuthHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OAuthProcessResult process(OAuthProcessContext context) {
|
public OAuthProcessResult process(OauthAppPojo app, Map<String, String[]> requestParams) {
|
||||||
OauthAppPojo authApp = oauthAppDao.selectByRegistrationId(context.getRegistrationId());
|
String clientId = app.getClientId();
|
||||||
String clientId = authApp.getClientId();
|
String clientSecret = app.getClientSecret();
|
||||||
String clientSecret = authApp.getClientSecret();
|
String baseUrl = app.getResourceUrl();
|
||||||
String baseUrl = authApp.getResourceUrl();
|
|
||||||
|
|
||||||
Map<String, String[]> params = context.getCallbackParameters();
|
String code = requestParams.get("code")[0];
|
||||||
String code = params.get("code")[0];
|
|
||||||
JsonNode tokenNode = githubRemoteService.getToken(baseUrl, clientId, clientSecret, code)
|
JsonNode tokenNode = githubRemoteService.getToken(baseUrl, clientId, clientSecret, code)
|
||||||
.get("access_token");
|
.get("access_token");
|
||||||
if (tokenNode == null) {
|
if (tokenNode == null) {
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
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.gitlab.GitlabRemoteService;
|
||||||
|
import com.databasir.dao.enums.OAuthAppType;
|
||||||
|
import com.databasir.dao.tables.pojos.OauthAppPojo;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class GitlabOpenAuthHandler implements OpenAuthHandler {
|
||||||
|
|
||||||
|
private final GitlabRemoteService gitlabRemoteService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean support(OAuthAppType oauthAppType) {
|
||||||
|
return OAuthAppType.GITLAB == oauthAppType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String authorizationUrl(OauthAppPojo app, Map<String, String[]> params) {
|
||||||
|
if (!params.containsKey("redirect_uri")) {
|
||||||
|
throw DomainErrors.MISS_REQUIRED_PARAMETERS.exception("缺少参数 redirect_uri", null);
|
||||||
|
}
|
||||||
|
String authUrl = app.getAuthUrl();
|
||||||
|
String clientId = app.getClientId();
|
||||||
|
String authorizeUrl = authUrl + "/oauth/authorize";
|
||||||
|
String redirectUri = params.get("redirect_uri")[0];
|
||||||
|
String url = UriComponentsBuilder.fromUriString(authorizeUrl)
|
||||||
|
.queryParam("client_id", clientId)
|
||||||
|
.queryParam("redirect_uri", redirectUri)
|
||||||
|
.queryParam("response_type", "code")
|
||||||
|
.queryParam("state", redirectUri)
|
||||||
|
.encode()
|
||||||
|
.build()
|
||||||
|
.toUriString();
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OAuthProcessResult process(OauthAppPojo app, Map<String, String[]> requestParams) {
|
||||||
|
if (!requestParams.containsKey("redirect_uri")) {
|
||||||
|
throw DomainErrors.MISS_REQUIRED_PARAMETERS.exception("缺少参数 redirect_uri", null);
|
||||||
|
}
|
||||||
|
String url = app.getAuthUrl();
|
||||||
|
String code = requestParams.get("code")[0];
|
||||||
|
String state = requestParams.get("state")[0];
|
||||||
|
String redirectUri = requestParams.get("redirect_uri")[0];
|
||||||
|
JsonNode accessTokenData =
|
||||||
|
gitlabRemoteService.getAccessToken(url, code, app.getClientId(), app.getClientSecret(), redirectUri);
|
||||||
|
if (accessTokenData == null) {
|
||||||
|
throw new DatabasirAuthenticationException(DomainErrors.NETWORK_ERROR.exception());
|
||||||
|
}
|
||||||
|
String accessToken = accessTokenData.get("access_token").asText();
|
||||||
|
JsonNode userData = gitlabRemoteService.getUser(app.getResourceUrl(), accessToken);
|
||||||
|
if (userData == null) {
|
||||||
|
throw new DatabasirAuthenticationException(DomainErrors.NETWORK_ERROR.exception());
|
||||||
|
}
|
||||||
|
String email = userData.get("email").asText();
|
||||||
|
String avatar = userData.get("avatar_url").asText();
|
||||||
|
String name = userData.get("name").asText();
|
||||||
|
OAuthProcessResult result = new OAuthProcessResult();
|
||||||
|
result.setAvatar(avatar);
|
||||||
|
result.setEmail(email);
|
||||||
|
result.setNickname(name);
|
||||||
|
result.setUsername(email);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package com.databasir.core.domain.app.handler;
|
package com.databasir.core.domain.app.handler;
|
||||||
|
|
||||||
|
import com.databasir.dao.tables.pojos.OauthAppPojo;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
@ -16,7 +17,9 @@ public class OAuthProcessContext {
|
||||||
|
|
||||||
private String registrationId;
|
private String registrationId;
|
||||||
|
|
||||||
|
private OauthAppPojo app;
|
||||||
|
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
private Map<String, String[]> callbackParameters = new HashMap<>();
|
private Map<String, String[]> parameters = new HashMap<>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
package com.databasir.core.domain.app.handler;
|
package com.databasir.core.domain.app.handler;
|
||||||
|
|
||||||
|
import com.databasir.dao.enums.OAuthAppType;
|
||||||
|
import com.databasir.dao.tables.pojos.OauthAppPojo;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public interface OpenAuthHandler {
|
public interface OpenAuthHandler {
|
||||||
|
|
||||||
boolean support(String oauthAppType);
|
boolean support(OAuthAppType oauthAppType);
|
||||||
|
|
||||||
String authorization(String registrationId);
|
String authorizationUrl(OauthAppPojo app, Map<String, String[]> requestParams);
|
||||||
|
|
||||||
OAuthProcessResult process(OAuthProcessContext context);
|
OAuthProcessResult process(OauthAppPojo app, Map<String, String[]> requestParams);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.databasir.core.domain.app.handler;
|
||||||
|
|
||||||
|
import com.databasir.dao.impl.OauthAppDao;
|
||||||
|
import com.databasir.dao.tables.pojos.OauthAppPojo;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class OpenAuthHandlers {
|
||||||
|
|
||||||
|
private final List<OpenAuthHandler> handlers;
|
||||||
|
|
||||||
|
private final OauthAppDao oauthAppDao;
|
||||||
|
|
||||||
|
public String authorizeUrl(String registrationId, Map<String, String[]> parameters) {
|
||||||
|
OauthAppPojo app = oauthAppDao.selectByRegistrationId(registrationId);
|
||||||
|
return handlers.stream()
|
||||||
|
.filter(handler -> handler.support(app.getAppType()))
|
||||||
|
.findFirst()
|
||||||
|
.map(handler -> handler.authorizationUrl(app, parameters))
|
||||||
|
.orElseThrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
public OAuthProcessResult process(String registrationId, Map<String, String[]> parameters) {
|
||||||
|
OauthAppPojo app = oauthAppDao.selectByRegistrationId(registrationId);
|
||||||
|
return handlers.stream()
|
||||||
|
.filter(handler -> handler.support(app.getAppType()))
|
||||||
|
.findFirst()
|
||||||
|
.map(handler -> handler.process(app, parameters))
|
||||||
|
.orElseThrow();
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ package com.databasir.core.infrastructure.remote;
|
||||||
|
|
||||||
import com.databasir.core.infrastructure.remote.github.GithubApiClient;
|
import com.databasir.core.infrastructure.remote.github.GithubApiClient;
|
||||||
import com.databasir.core.infrastructure.remote.github.GithubOauthClient;
|
import com.databasir.core.infrastructure.remote.github.GithubOauthClient;
|
||||||
|
import com.databasir.core.infrastructure.remote.gitlab.GitlabApiClient;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
@ -31,4 +32,13 @@ public class ClientConfig {
|
||||||
.build();
|
.build();
|
||||||
return retrofit.create(GithubOauthClient.class);
|
return retrofit.create(GithubOauthClient.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public GitlabApiClient gitlabApiClient() {
|
||||||
|
Retrofit retrofit = new Retrofit.Builder()
|
||||||
|
.baseUrl("https://gitlab.com")
|
||||||
|
.addConverterFactory(JacksonConverterFactory.create())
|
||||||
|
.build();
|
||||||
|
return retrofit.create(GitlabApiClient.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.databasir.core.infrastructure.remote.gitlab;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.http.*;
|
||||||
|
|
||||||
|
public interface GitlabApiClient {
|
||||||
|
@GET
|
||||||
|
@Headers(value = {
|
||||||
|
"Accept: application/json"
|
||||||
|
})
|
||||||
|
Call<JsonNode> getUser(@Url String url, @Header("Authorization") String token);
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Headers(value = {
|
||||||
|
"Accept: application/json"
|
||||||
|
})
|
||||||
|
Call<JsonNode> getAccessToken(@Url String url);
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package com.databasir.core.infrastructure.remote.gitlab;
|
||||||
|
|
||||||
|
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 org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Response;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class GitlabRemoteService {
|
||||||
|
|
||||||
|
private final GitlabApiClient gitlabApiClient;
|
||||||
|
|
||||||
|
public JsonNode getAccessToken(String baseUrl,
|
||||||
|
String code,
|
||||||
|
String clientId,
|
||||||
|
String clientSecret,
|
||||||
|
String redirectUri) {
|
||||||
|
String path = "/oauth/token";
|
||||||
|
String uri = baseUrl + path;
|
||||||
|
String uriStr = UriComponentsBuilder.fromUriString(uri)
|
||||||
|
.queryParam("client_id", clientId)
|
||||||
|
.queryParam("client_secret", clientSecret)
|
||||||
|
.queryParam("code", code)
|
||||||
|
.queryParam("grant_type", "authorization_code")
|
||||||
|
.queryParam("redirect_uri", redirectUri)
|
||||||
|
.encode()
|
||||||
|
.toUriString();
|
||||||
|
return execute(gitlabApiClient.getAccessToken(uriStr));
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonNode getUser(String baseUrl, String accessToken) {
|
||||||
|
String tokenHeaderValue = "Bearer " + accessToken;
|
||||||
|
String uri = baseUrl + "/api/v4/user";
|
||||||
|
return execute(gitlabApiClient.getUser(uri, tokenHeaderValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
log.info("response " + response);
|
||||||
|
T body = response.body();
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new SystemException("System Error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -60,6 +60,12 @@ jooq {
|
||||||
includeExpression = '.*'
|
includeExpression = '.*'
|
||||||
includeTypes = 'INET'
|
includeTypes = 'INET'
|
||||||
}
|
}
|
||||||
|
forcedType {
|
||||||
|
userType = 'com.databasir.dao.enums.OAuthAppType'
|
||||||
|
converter = 'com.databasir.dao.converter.OAuthAppTypeConverter'
|
||||||
|
includeExpression = 'app_type'
|
||||||
|
includeTypes = '.*'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
generate {
|
generate {
|
||||||
|
|
|
@ -6,6 +6,8 @@ package com.databasir.dao.tables;
|
||||||
|
|
||||||
import com.databasir.dao.Databasir;
|
import com.databasir.dao.Databasir;
|
||||||
import com.databasir.dao.Keys;
|
import com.databasir.dao.Keys;
|
||||||
|
import com.databasir.dao.converter.OAuthAppTypeConverter;
|
||||||
|
import com.databasir.dao.enums.OAuthAppType;
|
||||||
import com.databasir.dao.tables.records.OauthAppRecord;
|
import com.databasir.dao.tables.records.OauthAppRecord;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
@ -72,7 +74,7 @@ public class OauthApp extends TableImpl<OauthAppRecord> {
|
||||||
/**
|
/**
|
||||||
* The column <code>databasir.oauth_app.app_type</code>. github, gitlab
|
* 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");
|
public final TableField<OauthAppRecord, OAuthAppType> APP_TYPE = createField(DSL.name("app_type"), SQLDataType.VARCHAR(64).nullable(false), this, "github, gitlab", new OAuthAppTypeConverter());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The column <code>databasir.oauth_app.client_id</code>.
|
* The column <code>databasir.oauth_app.client_id</code>.
|
||||||
|
@ -193,7 +195,7 @@ public class OauthApp extends TableImpl<OauthAppRecord> {
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Row12<Integer, String, String, String, String, String, String, String, String, String, LocalDateTime, LocalDateTime> fieldsRow() {
|
public Row12<Integer, String, String, String, OAuthAppType, String, String, String, String, String, LocalDateTime, LocalDateTime> fieldsRow() {
|
||||||
return (Row12) super.fieldsRow();
|
return (Row12) super.fieldsRow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
package com.databasir.dao.tables.pojos;
|
package com.databasir.dao.tables.pojos;
|
||||||
|
|
||||||
|
|
||||||
|
import com.databasir.dao.enums.OAuthAppType;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@ -20,7 +22,7 @@ public class OauthAppPojo implements Serializable {
|
||||||
private String registrationId;
|
private String registrationId;
|
||||||
private String appName;
|
private String appName;
|
||||||
private String appIcon;
|
private String appIcon;
|
||||||
private String appType;
|
private OAuthAppType appType;
|
||||||
private String clientId;
|
private String clientId;
|
||||||
private String clientSecret;
|
private String clientSecret;
|
||||||
private String authUrl;
|
private String authUrl;
|
||||||
|
@ -51,7 +53,7 @@ public class OauthAppPojo implements Serializable {
|
||||||
String registrationId,
|
String registrationId,
|
||||||
String appName,
|
String appName,
|
||||||
String appIcon,
|
String appIcon,
|
||||||
String appType,
|
OAuthAppType appType,
|
||||||
String clientId,
|
String clientId,
|
||||||
String clientSecret,
|
String clientSecret,
|
||||||
String authUrl,
|
String authUrl,
|
||||||
|
@ -133,14 +135,14 @@ public class OauthAppPojo implements Serializable {
|
||||||
/**
|
/**
|
||||||
* Getter for <code>databasir.oauth_app.app_type</code>. github, gitlab
|
* Getter for <code>databasir.oauth_app.app_type</code>. github, gitlab
|
||||||
*/
|
*/
|
||||||
public String getAppType() {
|
public OAuthAppType getAppType() {
|
||||||
return this.appType;
|
return this.appType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setter for <code>databasir.oauth_app.app_type</code>. github, gitlab
|
* Setter for <code>databasir.oauth_app.app_type</code>. github, gitlab
|
||||||
*/
|
*/
|
||||||
public void setAppType(String appType) {
|
public void setAppType(OAuthAppType appType) {
|
||||||
this.appType = appType;
|
this.appType = appType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
package com.databasir.dao.tables.records;
|
package com.databasir.dao.tables.records;
|
||||||
|
|
||||||
|
|
||||||
|
import com.databasir.dao.enums.OAuthAppType;
|
||||||
import com.databasir.dao.tables.OauthApp;
|
import com.databasir.dao.tables.OauthApp;
|
||||||
import com.databasir.dao.tables.pojos.OauthAppPojo;
|
import com.databasir.dao.tables.pojos.OauthAppPojo;
|
||||||
|
|
||||||
|
@ -20,7 +21,7 @@ import org.jooq.impl.UpdatableRecordImpl;
|
||||||
* oauth app info
|
* oauth app info
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "all", "unchecked", "rawtypes" })
|
@SuppressWarnings({ "all", "unchecked", "rawtypes" })
|
||||||
public class OauthAppRecord extends UpdatableRecordImpl<OauthAppRecord> implements Record12<Integer, String, String, String, String, String, String, String, String, String, LocalDateTime, LocalDateTime> {
|
public class OauthAppRecord extends UpdatableRecordImpl<OauthAppRecord> implements Record12<Integer, String, String, String, OAuthAppType, String, String, String, String, String, LocalDateTime, LocalDateTime> {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@ -83,15 +84,15 @@ public class OauthAppRecord extends UpdatableRecordImpl<OauthAppRecord> implemen
|
||||||
/**
|
/**
|
||||||
* Setter for <code>databasir.oauth_app.app_type</code>. github, gitlab
|
* Setter for <code>databasir.oauth_app.app_type</code>. github, gitlab
|
||||||
*/
|
*/
|
||||||
public void setAppType(String value) {
|
public void setAppType(OAuthAppType value) {
|
||||||
set(4, value);
|
set(4, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Getter for <code>databasir.oauth_app.app_type</code>. github, gitlab
|
* Getter for <code>databasir.oauth_app.app_type</code>. github, gitlab
|
||||||
*/
|
*/
|
||||||
public String getAppType() {
|
public OAuthAppType getAppType() {
|
||||||
return (String) get(4);
|
return (OAuthAppType) get(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -206,12 +207,12 @@ public class OauthAppRecord extends UpdatableRecordImpl<OauthAppRecord> implemen
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Row12<Integer, String, String, String, String, String, String, String, String, String, LocalDateTime, LocalDateTime> fieldsRow() {
|
public Row12<Integer, String, String, String, OAuthAppType, String, String, String, String, String, LocalDateTime, LocalDateTime> fieldsRow() {
|
||||||
return (Row12) super.fieldsRow();
|
return (Row12) super.fieldsRow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Row12<Integer, String, String, String, String, String, String, String, String, String, LocalDateTime, LocalDateTime> valuesRow() {
|
public Row12<Integer, String, String, String, OAuthAppType, String, String, String, String, String, LocalDateTime, LocalDateTime> valuesRow() {
|
||||||
return (Row12) super.valuesRow();
|
return (Row12) super.valuesRow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +237,7 @@ public class OauthAppRecord extends UpdatableRecordImpl<OauthAppRecord> implemen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Field<String> field5() {
|
public Field<OAuthAppType> field5() {
|
||||||
return OauthApp.OAUTH_APP.APP_TYPE;
|
return OauthApp.OAUTH_APP.APP_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +297,7 @@ public class OauthAppRecord extends UpdatableRecordImpl<OauthAppRecord> implemen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String component5() {
|
public OAuthAppType component5() {
|
||||||
return getAppType();
|
return getAppType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,7 +357,7 @@ public class OauthAppRecord extends UpdatableRecordImpl<OauthAppRecord> implemen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String value5() {
|
public OAuthAppType value5() {
|
||||||
return getAppType();
|
return getAppType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,7 +421,7 @@ public class OauthAppRecord extends UpdatableRecordImpl<OauthAppRecord> implemen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OauthAppRecord value5(String value) {
|
public OauthAppRecord value5(OAuthAppType value) {
|
||||||
setAppType(value);
|
setAppType(value);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -468,7 +469,7 @@ public class OauthAppRecord extends UpdatableRecordImpl<OauthAppRecord> implemen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) {
|
public OauthAppRecord values(Integer value1, String value2, String value3, String value4, OAuthAppType value5, String value6, String value7, String value8, String value9, String value10, LocalDateTime value11, LocalDateTime value12) {
|
||||||
value1(value1);
|
value1(value1);
|
||||||
value2(value2);
|
value2(value2);
|
||||||
value3(value3);
|
value3(value3);
|
||||||
|
@ -498,7 +499,7 @@ public class OauthAppRecord extends UpdatableRecordImpl<OauthAppRecord> implemen
|
||||||
/**
|
/**
|
||||||
* Create a detached, initialised OauthAppRecord
|
* 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) {
|
public OauthAppRecord(Integer id, String registrationId, String appName, String appIcon, OAuthAppType appType, String clientId, String clientSecret, String authUrl, String resourceUrl, String scope, LocalDateTime updateAt, LocalDateTime createAt) {
|
||||||
super(OauthApp.OAUTH_APP);
|
super(OauthApp.OAUTH_APP);
|
||||||
|
|
||||||
setId(id);
|
setId(id);
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.databasir.dao.converter;
|
||||||
|
|
||||||
|
import com.databasir.dao.enums.OAuthAppType;
|
||||||
|
import org.jooq.impl.EnumConverter;
|
||||||
|
|
||||||
|
public class OAuthAppTypeConverter extends EnumConverter<String, OAuthAppType> {
|
||||||
|
|
||||||
|
public OAuthAppTypeConverter() {
|
||||||
|
super(String.class, OAuthAppType.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue