Skip to content

Commit

Permalink
Merge pull request #23 from KTB16Team/feature/19-auth
Browse files Browse the repository at this point in the history
Feature/19 auth
  • Loading branch information
mng990 authored Oct 22, 2024
2 parents 20ff15a + 3eaf92e commit 5514e22
Show file tree
Hide file tree
Showing 44 changed files with 400 additions and 101 deletions.
3 changes: 3 additions & 0 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ dependencies {
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'

//DB
runtimeOnly 'com.h2database:h2'
}

tasks.named('test') {
Expand Down
Empty file modified backend/gradlew
100644 → 100755
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.springframework.security.config.annotation.web.configurers.LogoutConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.logout.LogoutFilter;
Expand All @@ -39,6 +40,7 @@ public class SecurityConfig {
private final PasswordEncoder passwordEncoder;
private final AntPathMatcher pathMatcher = new AntPathMatcher();


@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// 비활성확 목록
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package aiin.backend.auth.security.exceptionHandlingFilter;

import aiin.backend.util.dto.ErrorResponse;
import aiin.backend.auth.exception.ApiException;
import aiin.backend.auth.exception.ErrorCode;
import aiin.backend.common.dto.ErrorResponse;
import aiin.backend.common.exception.ApiException;
import aiin.backend.common.exception.ErrorCode;
import aiin.backend.util.responseWriter.ResponseWriter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package aiin.backend.auth.security.jwtFilter;

import static aiin.backend.auth.exception.ErrorCode.*;
import static aiin.backend.common.exception.ErrorCode.*;

import aiin.backend.auth.exception.ApiException;
import aiin.backend.auth.exception.ErrorCode;
import aiin.backend.common.exception.ApiException;
import aiin.backend.common.exception.ErrorCode;
import aiin.backend.auth.properties.SecurityProperties;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
Expand Down Expand Up @@ -54,15 +54,18 @@ protected void doFilterInternal(
//3. access토큰이 존재하며, accessToken이 유효하면 인증
//4. access토큰이 존재하며, accesToken이 유효하지 않으면 에러 리턴
//5. 그 외 모든 경우는 에러 리턴
if (refreshToken != null && jwtTokenProvider.isTokenValid(refreshToken)) {

if (refreshToken != null && jwtTokenProvider.isTokenValid(refreshToken) && request.getRequestURI().matches("^\\/reissue$")) {
log.info("refresh토큰 인증 성공");
jwtTokenProvider.checkRefreshTokenAndReIssueAccessAndRefreshToken(response, accessToken, refreshToken);
} else if (refreshToken != null && !jwtTokenProvider.isTokenValid(refreshToken)) {
log.info("refresh토큰 인증 실패");
throw ApiException.from(INVALID_REFRESH_TOKEN);
} else if (accessToken != null && !jwtTokenProvider.isRefreshTokenValid(accessToken)) {
log.info("access토큰 만료(BlackList)");
throw ApiException.from(INVALID_REFRESH_TOKEN);
} else if (accessToken != null && jwtTokenProvider.isTokenValid(accessToken)) {
checkLogoutToken(accessToken);

log.info("access토큰 인증 성공");
Authentication authentication = jwtTokenProvider.getAuthentication(accessToken);
saveAuthentication(authentication);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,7 @@ public interface JwtTokenProvider {

void checkRefreshTokenAndReIssueAccessAndRefreshToken(HttpServletResponse response, String accessToken, String refreshToken);

boolean isRefreshTokenValid(String refreshToken);

boolean isLogout(String accessToken);
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package aiin.backend.auth.security.jwtFilter;

import static aiin.backend.auth.exception.ErrorCode.*;
import static aiin.backend.common.exception.ErrorCode.*;

import aiin.backend.util.dto.DataResponse;
import aiin.backend.auth.exception.ApiException;
import aiin.backend.common.dto.DataResponse;
import aiin.backend.common.exception.ApiException;
import aiin.backend.auth.properties.JwtProperties;
import aiin.backend.util.responseWriter.ResponseWriter;
import aiin.backend.member.entity.Member;
import aiin.backend.member.entity.RefreshToken;
import aiin.backend.member.repository.MemberRepository;
import aiin.backend.member.service.LogoutService;
import aiin.backend.member.service.RefreshTokenService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
Expand Down Expand Up @@ -43,19 +42,16 @@ public class JwtTokenProviderImpl implements JwtTokenProvider {
private final JwtProperties jwtProperties;
private final MemberRepository memberRepository;
private final Key key;
private final LogoutService logoutService;
private final RefreshTokenService refreshTokenService;

public JwtTokenProviderImpl(
JwtProperties jwtProperties,
MemberRepository memberRepository,
LogoutService logoutService,
RefreshTokenService refreshTokenService
) {
this.jwtProperties = jwtProperties;
this.memberRepository = memberRepository;
this.key = Keys.hmacShaKeyFor(jwtProperties.getSecret().getBytes());
this.logoutService = logoutService;
this.refreshTokenService = refreshTokenService;
}

Expand Down Expand Up @@ -197,7 +193,7 @@ public void checkRefreshTokenAndReIssueAccessAndRefreshToken(HttpServletResponse
Long memberId = extractMemberId(refreshToken)
.orElseThrow(() -> ApiException.from(INVALID_REFRESH_TOKEN));

if(refreshTokenService.existsByAccessToken(accessToken)){
if(!isRefreshTokenValid(accessToken)){
throw ApiException.from(INVALID_REFRESH_TOKEN);
}

Expand All @@ -209,8 +205,15 @@ public void checkRefreshTokenAndReIssueAccessAndRefreshToken(HttpServletResponse
sendAccessAndRefreshToken(response, newAccessToken, newRefreshToken);
}

@Override
public boolean isRefreshTokenValid(String accessToken){

return !refreshTokenService.existsByAccessToken(accessToken);
}

@Override
public boolean isLogout(String accessToken) {
return !logoutService.existsByAccessToken(accessToken);

return refreshTokenService.existsByAccessToken(accessToken);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package aiin.backend.auth.security.loginFilter;

import static aiin.backend.auth.exception.ErrorCode.*;
import static aiin.backend.common.exception.ErrorCode.*;

import org.springframework.http.HttpStatus;
import org.springframework.lang.Nullable;
Expand All @@ -11,8 +11,8 @@
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import aiin.backend.auth.security.jwtFilter.JwtTokenProvider;
import aiin.backend.util.dto.DataResponse;
import aiin.backend.auth.exception.ApiException;
import aiin.backend.common.dto.DataResponse;
import aiin.backend.common.exception.ApiException;
import aiin.backend.util.responseWriter.ResponseWriter;
import aiin.backend.member.entity.Member;
import aiin.backend.member.service.MemberService;
Expand All @@ -25,7 +25,7 @@
public class LoginFilter extends UsernamePasswordAuthenticationFilter {

private final static String EMAIL_PARAMETER = "email";
private final static String PW_PARAMETER = "pw";
private final static String PW_PARAMETER = "password";

private final JwtTokenProvider jwtTokenProvider;
private final MemberService memberService;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package aiin.backend.auth.config;
package aiin.backend.common.config;

import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package aiin.backend.util.dto;
package aiin.backend.common.dto;

import com.fasterxml.jackson.annotation.JsonFormat;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package aiin.backend.util.dto;
package aiin.backend.common.dto;

import org.springframework.http.HttpStatus;

Expand All @@ -25,5 +25,5 @@ public static <T> DataResponse<Void> ok() {
return new DataResponse<>(HttpStatus.OK, null);
}
public static <T> DataResponse<Void> created() { return new DataResponse<>(HttpStatus.CREATED, null); }
public static <T> DataResponse<Void> delete() { return new DataResponse<>(HttpStatus.NO_CONTENT, null); }
public static <T> DataResponse<Void> noContent() { return new DataResponse<>(HttpStatus.NO_CONTENT, null); }
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package aiin.backend.util.dto;
package aiin.backend.common.dto;

import java.util.List;

import org.springframework.http.HttpStatus;

import com.fasterxml.jackson.annotation.JsonInclude;

import aiin.backend.auth.exception.ErrorCode;
import aiin.backend.common.exception.ErrorCode;
import lombok.Getter;

@Getter
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package aiin.backend.util.entity;
package aiin.backend.common.entity;

import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package aiin.backend.auth.exception;
package aiin.backend.common.exception;

import lombok.Getter;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package aiin.backend.auth.exception;
package aiin.backend.common.exception;

import org.springframework.http.HttpStatus;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package aiin.backend.dispute.controller;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import aiin.backend.common.dto.DataResponse;
import aiin.backend.dispute.service.AudioService;
import aiin.backend.dispute.service.DialogueService;
import aiin.backend.dispute.service.DisputeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
@RequestMapping("/api/dispute")
@RequiredArgsConstructor
public class DisputeController {

private final AudioService audioService;
private final DisputeService disputeService;
private final DialogueService dialogueService;

@PostMapping("/audio")
public ResponseEntity<DataResponse<Void>> uploadAudio(@RequestParam("file") MultipartFile file) {


return ResponseEntity
.status(HttpStatus.CREATED)
.body(DataResponse.created());
}

}
35 changes: 35 additions & 0 deletions backend/src/main/java/aiin/backend/dispute/entity/AudioRecord.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package aiin.backend.dispute.entity;

import static lombok.AccessLevel.*;

import aiin.backend.common.entity.BaseEntity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "audio_records")
@Getter
@NoArgsConstructor(access = PROTECTED)
public class AudioRecord extends BaseEntity {
@Id @GeneratedValue
@Column(name = "audio_id")
private Long id;

@Column(nullable = false, name = "audio_file_url")
private String url;

@Column(nullable = false, name = "audio_file_size")
private String size;

@Column(nullable = false, name = "audio_file_extension")
private String extension;

@OneToOne(mappedBy = "audioRecord")
private Dispute dispute;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package aiin.backend.dispute.entity;

import aiin.backend.common.entity.BaseEntity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.Getter;

@Entity
@Getter
@Table(name = "dialogue_records")
public class DialogueRecord extends BaseEntity {
@Id @GeneratedValue
@Column(name = "dialogue_id")
private Long id;

@Column(nullable = false)
private String dialogue;

@OneToOne(mappedBy = "dialogueRecord")
private Dispute dispute;
}
58 changes: 58 additions & 0 deletions backend/src/main/java/aiin/backend/dispute/entity/Dispute.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package aiin.backend.dispute.entity;

import static lombok.AccessLevel.*;

import aiin.backend.dispute.model.OriginType;
import aiin.backend.member.entity.Member;
import aiin.backend.member.model.Provider;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@Table(name = "disputes")
@NoArgsConstructor(access = PROTECTED)
public class Dispute {
@Id @GeneratedValue
@Column(name = "dispute_id")
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", nullable = true)
private Member member;

@Column(name = "stance_plaintiff")
private String stanceA;

@Column(name = "stance_defendant")
private String stanceB;

@Column(name = "summary_ai")
private String summaryAi;

@Column(name = "summary_masking")
private String summaryMasking;

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "origin_audio_id", referencedColumnName = "audio_id")
private AudioRecord audioRecord;

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "orgin_dialogue_id", referencedColumnName = "dialogue_id")
private DialogueRecord dialogueRecord;

@Enumerated(EnumType.STRING)
@Column(nullable = false)
private OriginType originType;
}
Loading

0 comments on commit 5514e22

Please sign in to comment.