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