Skip to content

Commit

Permalink
Merge pull request EveryUniv#117 from EveryUniv/dev
Browse files Browse the repository at this point in the history
Release dev_deploy
  • Loading branch information
gutanbug authored Feb 23, 2024
2 parents 103c4ad + b910f27 commit fb580f0
Show file tree
Hide file tree
Showing 27 changed files with 803 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
HELP.md
.gradle
.gradle/
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.dku.council.domain.oauth.controller;

import com.dku.council.domain.oauth.model.dto.request.OauthLoginRequest;
import com.dku.council.domain.oauth.model.dto.request.OauthRequest;
import com.dku.council.domain.oauth.model.dto.request.TokenExchangeRequest;
import com.dku.council.domain.oauth.model.dto.response.OauthLoginResponse;
import com.dku.council.domain.oauth.model.dto.response.TokenExchangeResponse;
import com.dku.council.domain.oauth.service.OauthService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@RestController
@RequestMapping("/oauth")
@RequiredArgsConstructor
public class OauthController {
private final OauthService oauthService;

@GetMapping("/authorize")
public void authorize(@RequestParam String codeChallenge,
@RequestParam(required = false) String codeChallengeMethod,
@RequestParam String clientId,
@RequestParam String redirectUri,
@RequestParam String responseType,
@RequestParam String scope,
HttpServletResponse response) throws IOException {
OauthRequest request = OauthRequest.of(codeChallenge, codeChallengeMethod, clientId,
redirectUri, responseType, scope);
String uri = oauthService.authorize(request);
response.sendRedirect(uri);
}

@PostMapping("/login")
public ResponseEntity<OauthLoginResponse> login(@RequestBody OauthLoginRequest request) throws IOException {
OauthLoginResponse response = oauthService.login(request.toLoginInfo(), request.toOauthInfo());
return ResponseEntity.ok(response);
}


@PostMapping("/token")
public ResponseEntity<TokenExchangeResponse> exchangeToken(@RequestParam String grantType,
@RequestParam String clientId,
@RequestParam String redirectUri,
@RequestParam String clientSecret,
@RequestParam String code,
@RequestParam String codeVerifier) {
TokenExchangeRequest request = TokenExchangeRequest.of(grantType, clientId, redirectUri,
clientSecret, code, codeVerifier);
TokenExchangeResponse response = oauthService.exchangeToken(request.toClientInfo(), request.toAuthTarget());
return ResponseEntity.ok(response);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.dku.council.domain.oauth.exception;

import com.dku.council.global.error.exception.LocalizedMessageException;
import org.springframework.http.HttpStatus;

public class InvalidCodeChallengeException extends LocalizedMessageException {
public InvalidCodeChallengeException(String code) {
super(HttpStatus.BAD_REQUEST, "invalid.code-challenge: " + code);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.dku.council.domain.oauth.exception;

import com.dku.council.global.error.exception.LocalizedMessageException;
import org.springframework.http.HttpStatus;

public class InvalidGrantTypeException extends LocalizedMessageException {
public InvalidGrantTypeException(String grantType) {
super(HttpStatus.BAD_REQUEST, "invalid.oauth-grant-type: " + grantType);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.dku.council.domain.oauth.exception;


import com.dku.council.global.error.exception.LocalizedMessageException;
import org.springframework.http.HttpStatus;

public class InvalidOauthClientIdException extends LocalizedMessageException {
public InvalidOauthClientIdException(String clientId) {
super(HttpStatus.BAD_REQUEST, "invalid.oauth-client-id: " + clientId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.dku.council.domain.oauth.exception;

import com.dku.council.global.error.exception.LocalizedMessageException;
import org.springframework.http.HttpStatus;

public class InvalidOauthRedirectUriException extends LocalizedMessageException {
public InvalidOauthRedirectUriException(String redirectUri) {
super(HttpStatus.BAD_REQUEST, "invalid.oauth-redirect-uri", redirectUri);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.dku.council.domain.oauth.exception;

import com.dku.council.global.error.exception.LocalizedMessageException;
import org.springframework.http.HttpStatus;

public class InvalidOauthResponseTypeException extends LocalizedMessageException {
public InvalidOauthResponseTypeException(String responseType) {
super(HttpStatus.BAD_REQUEST, "invalid.oauth-response-type", responseType);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.dku.council.domain.oauth.exception;

import com.dku.council.global.error.exception.LocalizedMessageException;
import org.springframework.http.HttpStatus;

public class OauthClientNotFoundException extends LocalizedMessageException {
public OauthClientNotFoundException() {
super(HttpStatus.NOT_FOUND, "notfound.oauth-client");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.dku.council.domain.oauth.model.dto.request;

import lombok.Getter;

@Getter
public class ClientInfo {
private final String clientId;
private final String clientSecret;
private final String redirectUri;

private ClientInfo(String clientId, String clientSecret, String redirectUri) {
this.clientId = clientId;
this.clientSecret = clientSecret;
this.redirectUri = redirectUri;
}

public static ClientInfo of(String clientId, String clientSecret, String redirectUri) {
return new ClientInfo(clientId, clientSecret, redirectUri);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.dku.council.domain.oauth.model.dto.request;

import lombok.Getter;

@Getter
public class OAuthTarget {
private final String grantType;
private final String code;
private final String codeVerifier;

private OAuthTarget(String grantType, String code, String codeVerifier) {
this.grantType = grantType;
this.code = code;
this.codeVerifier = codeVerifier;
}

public static OAuthTarget of(String grantType, String code, String codeVerifier) {
return new OAuthTarget(grantType, code, codeVerifier);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.dku.council.domain.oauth.model.dto.request;

import com.dku.council.domain.oauth.exception.InvalidCodeChallengeException;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class OauthCachePayload {
Long userId;
String codeChallenge;
String codeChallengeMethod;
String scope;

public static OauthCachePayload of(Long userId, String codeChallenge, String codeChallengeMethod, String scope) {
return new OauthCachePayload(userId, codeChallenge, codeChallengeMethod, scope);
}

public void checkCodeChallenge(String codeChallenge) {
if (!this.codeChallenge.equals(codeChallenge)) {
throw new InvalidCodeChallengeException(codeChallenge);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.dku.council.domain.oauth.model.dto.request;

import lombok.Getter;

@Getter
public class OauthInfo {
private final String clientId;
private final String redirectUri;
private final String codeChallenge;
private final String codeChallengeMethod;
private final String scope;
private final String responseType;

private OauthInfo(String clientId, String redirectUri, String codeChallenge, String codeChallengeMethod, String scope, String responseType) {
this.clientId = clientId;
this.redirectUri = redirectUri;
this.codeChallenge = codeChallenge;
this.codeChallengeMethod = codeChallengeMethod;
this.scope = scope;
this.responseType = responseType;
}

public static OauthInfo of(String clientId, String redirectUri, String codeChallenge, String codeChallengeMethod, String scope, String responseType) {
return new OauthInfo(clientId, redirectUri, codeChallenge, codeChallengeMethod, scope, responseType);
}

public OauthCachePayload toCachePayload(Long userId) {
return OauthCachePayload.of(userId, codeChallenge, codeChallengeMethod, scope);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.dku.council.domain.oauth.model.dto.request;

import com.dku.council.domain.user.model.dto.request.RequestLoginDto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;

import javax.validation.constraints.NotBlank;

@Getter
@AllArgsConstructor
public class OauthLoginRequest {
@NotBlank
@Schema(description = "아이디(학번)", example = "12345678")
private final String studentId;

@NotBlank
@Schema(description = "비밀번호", example = "121212")
private final String password;

private final String clientId;

private final String redirectUri;

private final String codeChallenge;

private final String codeChallengeMethod;

private final String scope;

private final String responseType;

public RequestLoginDto toLoginInfo() {
return new RequestLoginDto(studentId, password);
}

public OauthInfo toOauthInfo() {
return OauthInfo.of(clientId, redirectUri, codeChallenge, codeChallengeMethod, scope, responseType);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.dku.council.domain.oauth.model.dto.request;

import lombok.Getter;

@Getter
public class OauthRequest {
private final String codeChallenge;
private String codeChallengeMethod = "S256";
private final String clientId;
private final String redirectUri;
private final String responseType;
private final String scope;

private OauthRequest(String codeChallenge, String codeChallengeMethod, String clientId,
String redirectUri, String responseType, String scope) {
this.codeChallenge = codeChallenge;
this.codeChallengeMethod = codeChallengeMethod;
this.clientId = clientId;
this.redirectUri = redirectUri;
this.responseType = responseType;
this.scope = scope;
}

private OauthRequest(String codeChallenge, String clientId, String redirectUri, String responseType, String scope) {
this.codeChallenge = codeChallenge;
this.clientId = clientId;
this.redirectUri = redirectUri;
this.responseType = responseType;
this.scope = scope;
}

public static OauthRequest of(String codeChallenge, String codeChallengeMethod, String clientId,
String redirectUri, String responseType, String scope) {
if (codeChallengeMethod == null) {
return OauthRequest.of(codeChallenge, clientId, redirectUri, responseType, scope);
}
return new OauthRequest(codeChallenge, codeChallengeMethod, clientId, redirectUri, responseType, scope);
}

public static OauthRequest of(String codeChallenge, String clientId,
String redirectUri, String responseType, String scope) {
return new OauthRequest(codeChallenge, clientId, redirectUri, responseType, scope);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.dku.council.domain.oauth.model.dto.request;

import lombok.Getter;

@Getter
public class TokenExchangeRequest {
String grantType;
String clientId;
String redirectUri;
String clientSecret;
String code;
String codeVerifier;

private TokenExchangeRequest(String grantType, String clientId, String redirectUri,
String clientSecret, String code, String codeVerifier) {
this.grantType = grantType;
this.clientId = clientId;
this.redirectUri = redirectUri;
this.clientSecret = clientSecret;
this.code = code;
this.codeVerifier = codeVerifier;
}

public static TokenExchangeRequest of(String grantType, String clientId, String redirectUri,
String clientSecret, String code, String codeVerifier) {
return new TokenExchangeRequest(grantType, clientId, redirectUri, clientSecret, code, codeVerifier);
}

public ClientInfo toClientInfo() {
return ClientInfo.of(clientId, clientSecret, redirectUri);
}

public OAuthTarget toAuthTarget() {
return OAuthTarget.of(grantType, code, codeVerifier);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.dku.council.domain.oauth.model.dto.response;

import lombok.Getter;

@Getter
public class OauthLoginResponse {
private final String authCode;

private OauthLoginResponse(String authCode) {
this.authCode = authCode;
}
public static OauthLoginResponse from(String authCode) {
return new OauthLoginResponse(authCode);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.dku.council.domain.oauth.model.dto.response;

import lombok.Getter;

@Getter
public class TokenExchangeResponse {
private String accessToken;
private String refreshToken;
private final String tokenType = "Bearer";
private String scope;

private TokenExchangeResponse(String accessToken, String refreshToken, String scope) {
this.accessToken = accessToken;
this.refreshToken = refreshToken;
this.scope = scope;
}

public static TokenExchangeResponse of(String accessToken, String refreshToken, String scope) {
return new TokenExchangeResponse(accessToken, refreshToken, scope);
}
}
Loading

0 comments on commit fb580f0

Please sign in to comment.