Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release/0.6.0 #69

Merged
merged 22 commits into from
Aug 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
abe2fd9
feat: develop ν™˜κ²½ https 적용
SHEOMM Apr 3, 2024
f1620e5
Feat/Attendee μ°Έκ°€μž λ³€κ²½μ—μ„œ 이름 변경도 κ°€λŠ₯ν•˜λ„λ‘ μˆ˜μ • (#39)
SHEOMM Apr 3, 2024
53fbdeb
Feat/Session μ„Έμ…˜ 일괄 μˆ˜μ • κ΅¬ν˜„ (#41)
SHEOMM Apr 3, 2024
c0e2cd1
Feat/Session 각 상세 νŽ˜μ΄μ§€μ—μ„œ ν•­λͺ© id λ°˜ν™˜ (#42)
SHEOMM Apr 5, 2024
6d45a68
Feat/OSIV: Open Session In View μ„€μ • 끄기. (#44)
SHEOMM Apr 5, 2024
ab764fb
Feat/attendance μΆœμ„ 검증과 μΆœμ„ μ‚½μž… μ‹œμ  뢄리 (#45)
SHEOMM Apr 8, 2024
bbc0a4b
Fix/redis: μ“°κΈ° μš”μ²­μ΄ Redis에 동기화 (#46)
SHEOMM Apr 9, 2024
798c809
Fix/Timezone: change default timezone to Asia/Seoul (#47)
SHEOMM Apr 13, 2024
18abf31
Refactor/attend: μΆœμ„ 일괄 Batch 처리 및 ActiveSession νŒ¨ν‚€μ§€ λ¦¬νŒ©ν† λ§ (#49)
SHEOMM Apr 16, 2024
ff330f9
refactor: λ©”μ†Œλ“œλͺ… 일관성 있게 λ³€κ²½ (#50)
SHEOMM Apr 18, 2024
2b3b73a
Feat/Manager Manager μ‚­μ œ (#51)
SHEOMM Apr 19, 2024
3a4c3b5
Feat/Session: ν™œμ„±ν™”λ˜μ§€ μ•Šμ€ μ„Έμ…˜ μ‚­μ œ API (#53)
SHEOMM Apr 19, 2024
ae8c876
Feat/email 이메일 인증 μ„œλΉ„μŠ€ (#54)
SHEOMM Apr 27, 2024
14187c5
Feat/Log-Error μŠ¬λž™μ— μ—λŸ¬λ©”μ‹œμ§€ 연동 (#56)
SHEOMM Jun 28, 2024
38c78aa
Fix/Error-Log μ„œλ²„ 였λ₯˜λ§Œ 전솑 (#59)
SHEOMM Jun 28, 2024
575c9c4
Merge branch 'main' into develop
SHEOMM Jun 29, 2024
d01c79e
Hotfix/signup: 이메일 인증 λΉ„ν™œμ„±ν™” (#61)
SHEOMM Jul 8, 2024
2bc061a
Merge branch 'main' into develop
SHEOMM Jul 8, 2024
26fc26a
fix: 이메일 κΈ°λŠ₯ 원볡 (#63)
SHEOMM Aug 7, 2024
974e364
Feat/email: 이메일 인증 μ„œλΉ„μŠ€ OCI 방식 μˆ˜μ • (#67)
SHEOMM Aug 8, 2024
62e2f51
Fix/Api-Error: Session Date μˆ˜μ •, 404 였λ₯˜ Global Handling, API 경둜 μˆ˜μ • (#68)
SHEOMM Aug 11, 2024
7a45a3b
Merge branch 'main' into develop
SHEOMM Aug 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public String activate(Long sessionId, Long courseId) {
Course course = courseService.get(courseId);
Session session = sessionQueryService.get(sessionId);
LocalDateTime currentTime = LocalDateTime.now(ZoneId.of("Asia/Seoul"));
sessionCommandService.setAuthCodeDate(session, currentTime);
return activeAttendanceService.activate(course, session, currentTime);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons
// TODO: 인증과 μΈκ°€λŠ” λ³„κ°œμ΄λ‹€. 인가 μ€‘μ—μ„œλ„ 각 userκ°€ μ–΄λ”” record에 μ ‘κ·ΌκΆŒν•œμ„ κ°€μ§ˆ 지 μ œμ–΄ν•˜λŠ” κ³΅ν†΅λœ λ‘œμ§μ„ κ³ λ―Όν•΄ 봐야 ν•œλ‹€.
// TODO
} catch (UnAuthenticatedException e) {
request.getRequestDispatcher("/api/manager/unauthorized").forward(request, response);
request.getRequestDispatcher("/api/auth/unauthorized").forward(request, response);
return false;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,10 @@
public class SessionManager {

private final HttpSession httpSession;
private final CourseRepository courseRepository;

private static final String LOG_ID = "logId";

public void createSession(Long managerId){
List<Course> courses = courseRepository.findAllByManagerId(managerId);

List<Long> courseIds = courses == null || courses.isEmpty() ?
Collections.emptyList()
: courses.stream().map(course -> course.getManager().getId()).toList();

LoginUser loginUser = new LoginUser(managerId);
httpSession.setAttribute(LOG_ID, loginUser);
}
Expand Down
44 changes: 0 additions & 44 deletions src/main/java/com/waruru/areyouhere/common/config/EmailConfig.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
package com.waruru.areyouhere.common.error;

import static com.waruru.areyouhere.common.utils.HttpStatusResponseEntity.RESPONSE_NOT_FOUND;

import com.waruru.areyouhere.common.annotation.SlackNotification;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import net.gpedro.integrations.slack.SlackApi;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.resource.NoResourceFoundException;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {


@ExceptionHandler(NoResourceFoundException.class)
public ResponseEntity<HttpStatus> handle404Exception(HttpServletRequest request, Exception e){
return RESPONSE_NOT_FOUND;
}

@SlackNotification
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(Exception.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ public class HttpStatusResponseEntity {
public static final ResponseEntity<HttpStatus> RESPONSE_UNAUTHORIZED = ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();

public static final ResponseEntity<HttpStatus> RESPONSE_FORBIDDEN = ResponseEntity.status(HttpStatus.FORBIDDEN).build();
public static final ResponseEntity<HttpStatus> RESPONSE_INTERNAL_ERROR = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface CourseRepository extends JpaRepository<Course, Long> {
List<Course> findAllByManagerId(Long managerId);

@Query("SELECT c FROM course c WHERE c.manager.id = :managerId")
List<Course> findAllByManagerId(@Param("managerId")Long managerId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import com.waruru.areyouhere.course.domain.repository.CourseRepository;
import com.waruru.areyouhere.attendee.exception.AttendeesNotUniqueException;
import com.waruru.areyouhere.course.dto.CourseData;
import com.waruru.areyouhere.course.exception.CourseNotFoundException;
import com.waruru.areyouhere.course.exception.UnauthorizedManagerException;
import com.waruru.areyouhere.manager.domain.entity.Manager;
import com.waruru.areyouhere.manager.domain.repository.ManagerRepository;
import com.waruru.areyouhere.session.domain.entity.Session;
Expand Down Expand Up @@ -45,7 +47,7 @@ public class CourseServiceImpl implements CourseService {
public void create(Long managerId, String name, String description, List<AttendeeData> attendees,
boolean onlyListNameAllowed) {
Manager manager = managerRepository.findManagerById(managerId)
.orElseThrow(() -> new IllegalArgumentException("Manager not found"));
.orElseThrow(() -> new UnauthorizedManagerException("Manager not found"));

Course course = Course.builder()
.manager(manager)
Expand Down Expand Up @@ -97,10 +99,10 @@ public List<CourseData> getAll(Long managerId) {
@Override
public void update(Long managerId, Long courseId, String name, String description, boolean onlyListNameAllowed) {
Course course = courseRepository.findById(courseId).
orElseThrow(() -> new IllegalArgumentException("Course not found"));
orElseThrow(() -> new CourseNotFoundException("Course not found"));

if (!course.getManager().getId().equals(managerId)) {
throw new IllegalArgumentException("Manager not authorized");
throw new UnauthorizedManagerException("Manager not authorized");
}

course.update(name, description, onlyListNameAllowed);
Expand All @@ -115,10 +117,10 @@ public void delete(Long managerId, Long courseId) {
}

Course course = courseRepository.findById(courseId).
orElseThrow(() -> new IllegalArgumentException("Course not found"));
orElseThrow(() -> new CourseNotFoundException("Course not found"));

if (!course.getManager().getId().equals(managerId)) {
throw new IllegalArgumentException("Manager not authorized");
throw new UnauthorizedManagerException("Manager not authorized");
}
List<Session> sessions = sessionRepository.findAllByCourseId(courseId);
attendanceRepository.deleteAllBySessionIds(sessions.stream().map(Session::getId).toList());
Expand All @@ -127,11 +129,13 @@ public void delete(Long managerId, Long courseId) {
courseRepository.delete(course);
}



@Override
@Transactional(readOnly = true)
public Course get(Long courseId) {
return courseRepository.findById(courseId).
orElseThrow(() -> new IllegalArgumentException("Course not found"));
orElseThrow(() -> new CourseNotFoundException("Course not found"));
}

private boolean isAttendeesUnique(List<String> attendees) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.waruru.areyouhere.email.advice;


import com.waruru.areyouhere.common.annotation.SlackNotification;
import com.waruru.areyouhere.common.error.ErrorResponse;
import com.waruru.areyouhere.email.exception.EmailSendException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

// 이메일 전솑이 μ•ˆλ˜λŠ” 것은 이메일 μ„œλ²„μ— 이상이 μžˆμœΌλ―€λ‘œ slackμ—μ„œ 처리될 수 μžˆλ„λ‘ ν•œλ‹€.
@RestControllerAdvice("com.waruru.areyouhere.email")
@Slf4j
public class EmailExceptionAdvice {

@ExceptionHandler(EmailSendException.class)
@SlackNotification
public ErrorResponse emailSendException(HttpServletRequest request, Exception e){
log.error("Internal Server Error", e);
StringBuilder sb = new StringBuilder();
sb.append(request.getMethod());
sb.append(request.getRemoteAddr());
sb.append(request.getRequestURL());
sb.append(e.getMessage());

return ErrorResponse.of("INTERNAL SERVER ERROR", sb.toString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ public class MessageHolder {

public MessageHolder(String title, MessageTemplate messageTemplate, Object... values){
this.title = title;
this.contents = String.format(messageTemplate.getTemplate(), (Object) values);
this.contents = String.format(messageTemplate.getTemplate(), values);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.waruru.areyouhere.email.domain;

public enum MessageTemplate {
PASSWORD_RESET("You can reset password by this link: %s"),
SIGN_UP("You can verify your email by this link: %s");
PASSWORD_RESET("You can reset password by this code: %s"),
SIGN_UP("You can verify your email by this code: %s");

private final String template;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.waruru.areyouhere.email.exception;

public class EmailSendException extends RuntimeException{

public EmailSendException() {
}

public EmailSendException(String message) {
super(message);
}

public EmailSendException(String message, Throwable cause) {
super(message, cause);
}

public EmailSendException(Throwable cause) {
super(cause);
}

public EmailSendException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,92 @@

import com.waruru.areyouhere.email.domain.MessageHolder;
import com.waruru.areyouhere.email.domain.MessageTemplate;
import com.waruru.areyouhere.email.exception.EmailSendException;
import jakarta.mail.Message.RecipientType;
import jakarta.mail.MessagingException;
import jakarta.mail.Session;
import jakarta.mail.Transport;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;
import java.io.UnsupportedEncodingException;
import java.util.Properties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

@RequiredArgsConstructor
@Service
@Slf4j
public class JavaEmailServiceImpl implements EmailService {
private final JavaMailSender emailSender;

@Value("${spring.mail.from}")
private String from;
@Value("${spring.mail.username}")
private String username;
@Value("${spring.mail.password}")
private String password;
@Value("${spring.mail.host}")
private String host;
@Value("${spring.mail.port}")
private int port;



public void sendVerifyEmail(String to, String title, String verificationLink, MessageTemplate messageTemplate) {
MessageHolder messageHolder = new MessageHolder(title, messageTemplate, verificationLink);
sendSimpleMessage(to, messageHolder.getTitle(), messageHolder.getContents());
}

private void sendSimpleMessage(String to, String title, String content) {
private void sendSimpleMessage(String to, String title, String content) {
if (from == null || from.isEmpty()) {
log.info("Email text Test: " + content);
return;
}
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to);
message.setSubject(title);
message.setText(content);
emailSender.send(message);

Session session = getSession();
try {
MimeMessage msg = setMessage(to, from, content, session);
doSend(session, msg);

} catch (MessagingException | UnsupportedEncodingException e) {
throw new EmailSendException();
}


}

private void doSend(Session session, MimeMessage msg) throws MessagingException {
Transport transport = session.getTransport();
transport.connect(host, username, password);
transport.sendMessage(msg, msg.getAllRecipients());
transport.close();
}

private MimeMessage setMessage(String to, String title, String content, Session session)
throws MessagingException, UnsupportedEncodingException {
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(from, from));
InternetAddress internetAddress = new InternetAddress(to);
internetAddress.validate();
msg.setRecipient(RecipientType.TO, internetAddress);
msg.setSubject(title);
msg.setContent(content, "text/html");
msg.setHeader("X-SES-CONFIGURATION-SET", "ConfigSet");
return msg;
}

private Session getSession(){
Properties emailProps = System.getProperties();
emailProps.put("mail.transport.protocol", "smtp");
emailProps.put("mail.smtp.port", port);
emailProps.put("mail.smtp.starttls.required", "true");
emailProps.put("mail.smtp.auth.login.disable", "true");
emailProps.put("mail.smtp.starttls.enable", "true");
emailProps.put("mail.smtp.auth", "true");

return Session.getDefaultInstance(emailProps);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,13 @@ public ResponseEntity<HttpStatus> delete(@Login Manager manager) {
@GetMapping("/email")
public ResponseEntity<HttpStatus> sendSignUpEmail(@RequestParam String email) {
managerService.sendEmailForSignUp(email);
return RESPONSE_BAD_REQUEST;
return RESPONSE_OK;
}

@GetMapping("/password")
public ResponseEntity<HttpStatus> sendPasswordEmail(@RequestParam String email) {
managerService.sendEmailForPasswordReset(email);
return RESPONSE_BAD_REQUEST;
return RESPONSE_OK;
}

@PostMapping("/verification")
Expand Down
Loading
Loading