vran
3 years ago
committed by
GitHub
22 changed files with 290 additions and 67 deletions
@ -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,10 +1,15 @@ |
|||
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 { |
|||
|
|||
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(); |
|||
} |
|||
} |
@ -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); |
|||
} |
|||
} |
|||
} |
@ -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