committed by
							
								 GitHub
								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