Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
50 changes: 50 additions & 0 deletions .github/workflows/build-all.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Create and publish a Docker image for Each branches

on:
push:
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build:
environment:
name: deploy
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: "Checkout repository"
uses: actions/checkout@v4

- name: 'Set up Docker Buildx'
uses: docker/setup-buildx-action@v3

- name: 'Run gradlew build'
run: ./gradlew build

- name: "Log in to the Container registry"
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: "Extract metadata (tags, labels) for Docker"
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

- name: "Build and push Docker image"
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
file: Dockerfile
5 changes: 5 additions & 0 deletions .github/workflows/build-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ jobs:
- name: 'Set up Docker Buildx'
uses: docker/setup-buildx-action@v3

- name: 'Replace application.yml for docker deployment'
run: |
rm ./src/main/resources/application.yml
mv ./src/main/resources/application.docker.yml ./src/main/resources/application.yml

- name: 'Run gradlew build'
run: ./gradlew build

Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ jobs:
- name: 'Set up Docker Buildx'
uses: docker/setup-buildx-action@v3

- name: 'Replace application.yml for docker deployment'
run: |
rm ./src/main/resources/application.yml
mv ./src/main/resources/application.docker.yml ./src/main/resources/application.yml

- name: 'Run gradlew build'
run: ./gradlew build

Expand Down
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-mail'
implementation 'org.springframework.security:spring-security-core'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
runtimeOnly 'com.h2database:h2'
Expand Down
4 changes: 2 additions & 2 deletions docker-compose.monolithic.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
services:
db:
image: mariadb:latest
image: mysql:latest
container_name: 'unideal-db'
environment:
# MYSQL_ROOT_PASSWORD: changeme
MYSQL_DATABASE: unideal
MYSQL_USER: unideal
MYSQL_PASSWORD: changeme
MARIADB_RANDOM_ROOT_PASSWORD: 1
MYSQL_RANDOM_ROOT_PASSWORD: 1
volumes:
- unideal-db_data:/var/lib/mysql
app:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package kr.unideal.server.backend.controller;

import kr.unideal.server.backend.dto.*;
import kr.unideal.server.backend.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
public class AuthController {

private final UserService userService;

@PostMapping("/auth/signup")
public ResponseEntity<SignUpResponseDTO> signup(
@RequestBody SignUpRequestDTO signUpRequestDTO,
BindingResult bindingResult
) {

if (bindingResult.hasErrors()) {
throw new IllegalArgumentException("입력값 규격이 올바르지 않습니다.");
}

try {
userService.register(signUpRequestDTO);
} catch (IllegalArgumentException e) {
throw e;
}

return ResponseEntity.ok(
new SignUpResponseDTO()
);
}

// 인증번호 기반 코드 인증 시도
@PostMapping("/auth/validate")
public ResponseEntity<VerifyResponseDTO> validate(@RequestBody VerifyRequestDTO verifyRequestDTO, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
throw new IllegalArgumentException("입력값 규격이 올바르지 않습니다.");
}

try {
userService.verifyUser(verifyRequestDTO);
} catch (IllegalArgumentException e) {
throw e;
}

return ResponseEntity.ok(
new VerifyResponseDTO()
);
}

@PostMapping("/auth/login")
public ResponseEntity<LogInResponseDTO> login(
@RequestBody LogInRequestDTO logInRequestDTO,
BindingResult bindingResult
) {
if (bindingResult.hasErrors()) {
throw new IllegalArgumentException("입력값 규격이 올바르지 않습니다.");
}

try {
userService.login(logInRequestDTO);
} catch (IllegalArgumentException e) {
throw e;
}

return ResponseEntity.ok(
new LogInResponseDTO()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package kr.unideal.server.backend.controller;

import kr.unideal.server.backend.dto.LogInRequestDTO;
import kr.unideal.server.backend.dto.SignUpRequestDTO;
import kr.unideal.server.backend.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

// 대체 왜 여기에 SSR 을????
// 일단 API는 RestController 사용하는 것이 편하므로 분리
//
// 아니 근데 FE React 로 만들기로 한거 아녔나.... Thymeleaf 로 왜...?
@Controller
@RequiredArgsConstructor
public class AuthPageController {

//signup 페이지 GET
@GetMapping("/signup")
public String signupPage(Model model) {
model.addAttribute("signUpRequestDTO", new SignUpRequestDTO());
return "signup";
}

//login 페이지 Get
@GetMapping("/login")
public String loginPage(Model model) {
model.addAttribute("logInRequestDTO", new LogInRequestDTO());
return "login";
}

}
17 changes: 17 additions & 0 deletions src/main/java/kr/unideal/server/backend/dto/LogInRequestDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package kr.unideal.server.backend.dto;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class LogInRequestDTO {
@NotBlank
@Email
private String email;

@NotBlank
private String password;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package kr.unideal.server.backend.dto;

public class LogInResponseDTO {
}
23 changes: 23 additions & 0 deletions src/main/java/kr/unideal/server/backend/dto/SignUpRequestDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package kr.unideal.server.backend.dto;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
public class SignUpRequestDTO {
@Getter
@Setter

@NotBlank
@Email
private String email;

@NotBlank
private String password;

@NotBlank
private String name;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package kr.unideal.server.backend.dto;

public class SignUpResponseDTO {

}
20 changes: 20 additions & 0 deletions src/main/java/kr/unideal/server/backend/dto/VerifyRequestDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package kr.unideal.server.backend.dto;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.Setter;

public class VerifyRequestDTO {
@Getter
@Setter

@NotBlank
@Email
String email;

@Getter
@Setter
@NotBlank
String code;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package kr.unideal.server.backend.dto;

public class VerifyResponseDTO {
}
35 changes: 35 additions & 0 deletions src/main/java/kr/unideal/server/backend/entity/User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package kr.unideal.server.backend.entity;

import jakarta.persistence.*;
import kr.unideal.server.backend.utils.VerificationCodeUtils;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.Instant;

@Entity
@Table(name = "`user`") // user는 예약어이므로 백틱 사용
@Getter
@Setter
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

@Column(nullable = false, unique = true, length = 100)
private String email;

@Column(nullable = false, length = 255)
private String password;

@Column(nullable = false, length = 100)
private String name;

@Column(nullable = false)
private boolean isVerified = false;

@Column
private String verificationToken;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package kr.unideal.server.backend.repository;

import kr.unideal.server.backend.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface UserRepository extends JpaRepository<User, Integer> {
//존재하는 이메일인지 확인
boolean existsByEmail(String email);

//user의 데이터를 email로 찾음
Optional<User> findByEmail(String email);
}
35 changes: 35 additions & 0 deletions src/main/java/kr/unideal/server/backend/service/MailService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package kr.unideal.server.backend.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

@Service
public class MailService {

@Value("${unideal.mailer.from}")
private String from;

@Autowired
private JavaMailSender mailSender;

public void sendSimpleMail(String to, String subject, String text) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to);
message.setSubject(subject);
message.setText(text);

mailSender.send(message);
}

public void sendVerificationCode(String to, String code) {
this.sendSimpleMail(
to,
"Unideal 가입 인증코드",
"Unideal에 가입해 주셔서 감사합니다. 회원가입을 위한 인증코드는 "+code+" 입니다."
);
}
}
Loading