Skip to content

Commit

Permalink
feat : uid 방식 -> 로그인 방식
Browse files Browse the repository at this point in the history
  • Loading branch information
DevJunsik committed Aug 2, 2024
1 parent edb63a8 commit b2c6407
Show file tree
Hide file tree
Showing 36 changed files with 533 additions and 201 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ dependencies {
implementation 'com.google.firebase:firebase-admin:9.2.0'
implementation 'com.fasterxml.jackson.core:jackson-core:2.16.1' // Jackson Data Bind
implementation group: 'com.squareup.okhttp3', name: 'okhttp', version: '4.2.2'

implementation 'org.springframework.boot:spring-boot-starter-mail'

}

Expand Down
14 changes: 6 additions & 8 deletions src/main/java/site/balpyo/ai/controller/AIUserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import site.balpyo.ai.dto.AIGenerateRequest;
import site.balpyo.ai.service.AIGenerateService;
Expand All @@ -27,19 +30,14 @@ public class AIUserController {
public String BALPYO_API_KEY;

@PostMapping("/script")
public ResponseEntity<CommonResponse> generateScript(@Valid @RequestBody AIGenerateRequest aiGenerateRequest,
@RequestHeader(value = "UID", required = false) String uid){

if(!BALPYO_API_KEY.equals(aiGenerateRequest.getBalpyoAPIKey()))return CommonResponse.error(ErrorEnum.BALPYO_API_KEY_ERROR);
//TODO :: 임시 api 시크릿 키 구현 (차후 로그인 연동시 삭제예정)
System.out.println(uid);
if(CommonUtils.isAnyParameterNullOrBlank(uid))return CommonResponse.error(ErrorEnum.BALPYO_UID_KEY_MISSING);
@PreAuthorize("hasRole('USER') or hasRole('MODERATOR') or hasRole('ADMIN')")
public ResponseEntity<CommonResponse> generateScript(@Valid @RequestBody AIGenerateRequest aiGenerateRequest){

log.info("-------------------- 스크립트 생성 요청");
log.info("-------------------- 요청 내용 ");
log.info("--------------------" + aiGenerateRequest);

return aiGenerateService.generateScript(aiGenerateRequest,uid);
return aiGenerateService.generateScript(aiGenerateRequest);
}

}
2 changes: 2 additions & 0 deletions src/main/java/site/balpyo/ai/controller/PollyController.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
Expand Down Expand Up @@ -47,6 +48,7 @@ public class PollyController {
* @return 호출 시, 요청정보에 따른 mp3 음성파일을 반환(audioBytes)한다.
*/
@PostMapping("/generateAudio")
@PreAuthorize("hasRole('USER') or hasRole('MODERATOR') or hasRole('ADMIN')")
public ResponseEntity<?> synthesizeText(@RequestBody PollyDTO pollyDTO) {

log.info("--------------------controller로 텍스트 음성 변환 요청");
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/site/balpyo/ai/controller/UploadController.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
Expand All @@ -31,6 +32,7 @@ public class UploadController {

//post 방식으로 파일 등록
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@PreAuthorize("hasRole('USER') or hasRole('MODERATOR') or hasRole('ADMIN')")
public UploadResultDTO upload(UploadFileDTO uploadFileDTO) throws IOException {

AmazonS3 s3 = s3Client.getAmazonS3();
Expand Down
25 changes: 11 additions & 14 deletions src/main/java/site/balpyo/ai/entity/AIGenerateLogEntity.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package site.balpyo.ai.entity;


import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.CreationTimestamp;
import site.balpyo.ai.dto.AIGenerateRequest;
import site.balpyo.auth.entity.User;
import site.balpyo.guest.entity.GuestEntity;
import site.balpyo.script.entity.ScriptEntity;

Expand All @@ -20,7 +20,7 @@
public class AIGenerateLogEntity {

@Id
@GeneratedValue
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long aiLogId;

private Integer secTime;
Expand All @@ -31,29 +31,26 @@ public class AIGenerateLogEntity {

private double secPerLetter;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "uid")
private GuestEntity guestEntity;
@CreationTimestamp
private LocalDateTime createdAt;

@OneToOne(fetch = FetchType.LAZY,cascade = CascadeType.ALL)
@JoinColumn(name = "gpt_info_id", referencedColumnName = "gptInfoId")
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@JoinColumn(name = "gpt_info_id")
private GPTInfoEntity gptInfoEntity;

@OneToOne(fetch = FetchType.LAZY, mappedBy = "aiGenerateLogEntity", cascade = CascadeType.ALL)
private ScriptEntity scriptEntity;

@CreationTimestamp
private LocalDateTime createdAt;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@JoinColumn(name = "script_id")
private ScriptEntity scriptEntity;

public AIGenerateLogEntity convertToEntity(AIGenerateRequest aiGenerateRequest, GPTInfoEntity gptInfoEntity, GuestEntity guestEntity){
public AIGenerateLogEntity convertToEntity(AIGenerateRequest aiGenerateRequest, GPTInfoEntity gptInfoEntity,ScriptEntity scriptEntity){
return AIGenerateLogEntity.builder()
.scriptEntity(scriptEntity)
.secTime(aiGenerateRequest.getSecTime())
.topic(aiGenerateRequest.getTopic())
.keywords(aiGenerateRequest.getKeywords())
.secPerLetter(0) // TODO :: 차후 0 값 변경
.gptInfoEntity(gptInfoEntity)
.guestEntity(guestEntity)
.build();
}

}
12 changes: 5 additions & 7 deletions src/main/java/site/balpyo/ai/entity/GPTInfoEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.CreationTimestamp;
import org.springframework.stereotype.Service;
import site.balpyo.ai.dto.GPTResponse;

import javax.annotation.processing.Completion;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Getter
@Setter
Expand Down Expand Up @@ -40,18 +39,17 @@ public class GPTInfoEntity {

private Integer totalToken;

@OneToOne(mappedBy = "gptInfoEntity")
private AIGenerateLogEntity aiGenerateLogEntity;

@CreationTimestamp
private LocalDateTime createdAt;

@OneToMany(mappedBy = "gptInfoEntity", cascade = CascadeType.ALL, orphanRemoval = true)
private List<AIGenerateLogEntity> aiGenerateLogs = new ArrayList<>();

public GPTInfoEntity ResponseBodyToGPTInfoEntity(Object resultBody){

ObjectMapper mapper = new ObjectMapper();
GPTResponse response = mapper.convertValue(resultBody, GPTResponse.class);


return GPTInfoEntity.builder()
.gptInfoId(response.getGptInfoId())
.gptObject(response.getGptObject())
Expand Down
37 changes: 19 additions & 18 deletions src/main/java/site/balpyo/ai/service/AIGenerateService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import site.balpyo.ai.dto.AIGenerateRequest;
import site.balpyo.ai.dto.AIGenerateResponse;
import site.balpyo.ai.entity.AIGenerateLogEntity;
import site.balpyo.ai.entity.GPTInfoEntity;
import site.balpyo.ai.repository.AIGenerateLogRepository;
import site.balpyo.auth.entity.User;
import site.balpyo.auth.repository.UserRepository;
import site.balpyo.auth.service.AuthenticationService;
import site.balpyo.auth.service.UserDetailsImpl;
import site.balpyo.common.dto.CommonResponse;
import site.balpyo.common.dto.ErrorEnum;
import site.balpyo.common.util.CommonUtils;
Expand Down Expand Up @@ -39,10 +46,16 @@ public class AIGenerateService {

private final ScriptRepository scriptRepository;

private final UserRepository userRepository;

private final AuthenticationService authenticationService;

@Value("${secrets.GPT_API_KEY}")
public String GPT_API_KEY;
@Transactional
public ResponseEntity<CommonResponse> generateScript(AIGenerateRequest request,String uid){
public ResponseEntity<CommonResponse> generateScript(AIGenerateRequest request){

User user = authenticationService.authenticationToUser();

// TODO :: TEST인 경우 TEST값 반환 <- 개발 완료 후 삭제 예정
if(request.isTest()) return CommonResponse.success(new GPTTestObject().getGPTTestObject());
Expand All @@ -61,35 +74,23 @@ public ResponseEntity<CommonResponse> generateScript(AIGenerateRequest request,S
//5. GPT 응답에서 GPTInfoEntity 추출 및 jpa로 저장할 수 있도록 GPTInfoEntity로변환
GPTInfoEntity gptInfoData = new GPTInfoEntity().ResponseBodyToGPTInfoEntity(resultBody);

//6. AI 사용기록에 gpt정보와 요청값들을 AIGenerateLogEntity형태로 변환

GuestEntity guestEntity = null;
Optional<GuestEntity> optionalGuestEntity= guestRepository.findById(uid);
if(optionalGuestEntity.isPresent()){guestEntity = optionalGuestEntity.get();}


//6. AI 사용기록에 gpt정보와 요청값들을 AIGenerateLogEntity형태로 변환
AIGenerateLogEntity aiGenerateLog = new AIGenerateLogEntity().convertToEntity(request , gptInfoData,guestEntity);
Optional<ScriptEntity> optionalScriptEntity = scriptRepository.findByUserAndScriptId(user, request.getScriptId());
if(optionalScriptEntity.isEmpty()) return CommonResponse.error(ErrorEnum.SCRIPT_DETAIL_NOT_FOUND);

AIGenerateLogEntity aiGenerateLog = new AIGenerateLogEntity().convertToEntity(request, gptInfoData,optionalScriptEntity.get());

aiGenerateLogRepository.save(aiGenerateLog); //저장
String GPTId = aiGenerateLog.getGptInfoEntity().getGptInfoId();

Optional<ScriptEntity> optionalScriptEntity = scriptRepository.findById(request.getScriptId());
if(optionalScriptEntity.isEmpty()){return CommonResponse.error(ErrorEnum.GPT_GENERATION_ERROR);}

ScriptEntity selectedScriptEntity = optionalScriptEntity.get();
selectedScriptEntity.setIsGenerating(false);
selectedScriptEntity.setAiGenerateLogEntity(aiGenerateLog);
scriptRepository.save(selectedScriptEntity);

log.info("-------------------- 저장된 사용 기록 : " + aiGenerateLog);

return CommonResponse.success(new AIGenerateResponse(resultScript,GPTId));
return CommonResponse.success(new AIGenerateResponse(resultScript, gptInfoData.getGptInfoId()));
}






}
33 changes: 33 additions & 0 deletions src/main/java/site/balpyo/auth/EmailConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package site.balpyo.auth;

import org.springframework.stereotype.Component;


@Component
public class EmailConfig {

private static final String BALPYO_TITLE = "[발표몇분] 회원가입 인증코드";

private static final String SUPPORT_EMAIL = "[email protected]";

public String getBalpyoTitle() {
return BALPYO_TITLE;
}

public String getBalpyoBody(String link) {
return new StringBuilder()
.append("안녕하세요,\n")
.append("발표몇분입니다.\n")
.append("\n")
.append("아래 버튼으로 이메일 인증을 해주세요.\n")
.append(link).append("\n")
.append("\n")
.append("감사합니다,\n")
.append("발표몇분 드림\n")
.append("\n")
.append("클릭으로 인증이 되지 않는다면,\n")
.append("위의 긴 주소를 인터넷 브라우저 주소 창에 붙여 넣어 보세요!\n")
.append("계속 인증에 실패한다면 ").append(SUPPORT_EMAIL).append("을 통해 저희에게 연락 부탁 드립니다!")
.toString();
}
}
7 changes: 6 additions & 1 deletion src/main/java/site/balpyo/auth/WebSecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
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;
Expand Down Expand Up @@ -71,13 +72,15 @@ public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}



// @Override
// protected void configure(HttpSecurity http) throws Exception {
// http.cors().and().csrf().disable()
// .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
// .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
// .authorizeRequests().antMatchers("/api/auth/**").permitAll()
// .antMatchers("/api/test/**").permitAll()
// .antMatchers("*").permitAll()
// .anyRequest().authenticated();
//
// http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
Expand All @@ -98,6 +101,8 @@ public CorsConfigurationSource corsConfigurationSource() {
return source;
}



@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf(csrf -> csrf.disable())
Expand Down
Loading

0 comments on commit b2c6407

Please sign in to comment.