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

Feat/spring rest docs hellomatia #13

Merged
merged 11 commits into from
May 21, 2024
39 changes: 38 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
plugins {
id 'java'
id "org.asciidoctor.jvm.convert" version "3.3.2"
id 'org.springframework.boot' version '3.2.5'
id 'io.spring.dependency-management' version '1.1.4'
}
Expand All @@ -12,6 +13,7 @@ java {
}

configurations {
asciidoctorExt
compileOnly {
extendsFrom annotationProcessor
}
Expand Down Expand Up @@ -49,6 +51,9 @@ dependencies {

implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
implementation group: 'org.javassist', name: 'javassist', version: '3.15.0-GA'

asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor'
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
}

tasks.named('test') {
Expand Down Expand Up @@ -76,4 +81,36 @@ bootRun {
String activeProfile = System.properties['spring.profiles.active']
println "zone: $activeProfile"
systemProperty "spring.profiles.active", activeProfile
}
}

ext {
snippetsDir = file('build/generated-snippets')
}

test {
outputs.dir snippetsDir
}

asciidoctor {
inputs.dir snippetsDir
configurations 'asciidoctorExt'
dependsOn test
}

bootJar {
dependsOn asciidoctor
from ("${asciidoctor.outputDir}/html5") {
into 'static/docs'
}
}

tasks.register('copyDocument', Copy) {
dependsOn asciidoctor

from file("build/docs/asciidoc/")
into file("src/main/resources/static/")
}

build {
dependsOn copyDocument
}
91 changes: 91 additions & 0 deletions src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
= M-LOG API 문서
:doctype: book
:icons: font
:source-highlighter: highlightjs
:toc: left
:toclevels: 3

== 회원

=== 로그인
**Request**
include::{snippets}/user/login/http-request.adoc[]

**Response**
include::{snippets}/user/login/http-response.adoc[]

=== 회원 가입

**Request**
include::{snippets}/user/join/http-request.adoc[]

**Response**
include::{snippets}/user/join/http-response.adoc[]

=== 회원 수정

**Request**
include::{snippets}/user/modify/http-request.adoc[]

**Response**
include::{snippets}/user/modify/http-response.adoc[]

=== 회원 삭제

**Request**
include::{snippets}/user/delete/http-request.adoc[]

**Response**
include::{snippets}/user/delete/http-response.adoc[]

=== 회원 정보 조회

==== 1. JWT 토큰 기반
**Request**
include::{snippets}/user/me/http-request.adoc[]

**Response**
include::{snippets}/user/me/http-response.adoc[]

---

==== 2. ID 기반
**Request**
include::{snippets}/user/find/http-request.adoc[]

**Response**
include::{snippets}/user/find/http-response.adoc[]

== 여행

=== 여행 정보 저장 (JWT 기반)

**Request**
include::{snippets}/travel/save/http-request.adoc[]

**Response**
include::{snippets}/travel/save/http-response.adoc[]

=== 여행 정보 리스트 조회 (JWT 기반)

**Request**
include::{snippets}/travel/list/http-request.adoc[]

**Response**
include::{snippets}/travel/list/http-response.adoc[]

=== 여행 상세 정보 조회

**Request**
include::{snippets}/travel/detail/http-request.adoc[]

**Response**
include::{snippets}/travel/detail/http-response.adoc[]

=== 여행 상세 사진 조회

**Request**
include::{snippets}/travel/photos/http-request.adoc[]

**Response**
include::{snippets}/travel/photos/http-response.adoc[]
4 changes: 2 additions & 2 deletions src/main/java/com/mlog/config/WebSecurityConfigure.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
.sessionCreationPolicy(SessionCreationPolicy.STATELESS))

.authorizeHttpRequests(auth -> auth
.requestMatchers("/user/login").permitAll()
.anyRequest().permitAll())
.requestMatchers("/user/login", "/", "/index.html").permitAll()
.anyRequest().authenticated())

.formLogin(AbstractHttpConfigurer::disable);

Expand Down
3 changes: 1 addition & 2 deletions src/main/java/com/mlog/error/GeneralExceptionHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,4 @@ public ResponseEntity<?> handleException(Exception e) {
public ResponseEntity<?> handleUnauthorizedException(Exception e) {
return newResponse(e, HttpStatus.UNAUTHORIZED);
}

}
}
5 changes: 0 additions & 5 deletions src/main/java/com/mlog/user/controller/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,6 @@ public class UserController {
private final AuthenticationManager authenticationManager;
private final UserService userService;

@GetMapping
public ApiResult<String> hello() {
return success("hello user");
}

@PostMapping("/login")
public ApiResult<LoginResult> login(@Valid @RequestBody LoginRequest request)
throws UnauthorizedException {
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/com/mlog/user/service/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ public boolean update(UserDTO userDTO, Long id) {
User data = userMapper.findById(id).orElseThrow(() -> new UnauthorizedException("Invalid id"));
userMapper.update(User.builder()
.id(id)
.name(userDTO.getName() != null ? userDTO.getName() : null)
.email(userDTO.getEmail())
.password(passwordEncoder.encode(userDTO.getPassword()))
.name(userDTO.getName() != null ? userDTO.getName() : data.getName())
.email(userDTO.getEmail() != null ? userDTO.getEmail() : data.getEmail())
.password(userDTO.getPassword() != null ? passwordEncoder.encode(userDTO.getPassword()) : data.getPassword())
.role("ROLE_USER")
.build());

Expand Down
17 changes: 17 additions & 0 deletions src/test/java/com/mlog/security/WithMockJwtAuthentication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.mlog.security;

import org.springframework.security.test.context.support.WithSecurityContext;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@WithSecurityContext(factory = WithMockJwtAuthenticationSecurityContextFactory.class)
public @interface WithMockJwtAuthentication {

long id() default 1L;

String name() default "tester";

String role() default "ROLE_USER";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.mlog.security;

import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.test.context.support.WithSecurityContextFactory;

import static org.springframework.security.core.authority.AuthorityUtils.createAuthorityList;

public class WithMockJwtAuthenticationSecurityContextFactory implements WithSecurityContextFactory<WithMockJwtAuthentication> {

@Override
public SecurityContext createSecurityContext(WithMockJwtAuthentication annotation) {
SecurityContext context = SecurityContextHolder.createEmptyContext();
JwtAuthenticationToken authentication =
new JwtAuthenticationToken(
new JwtAuthentication(annotation.id(), annotation.name()),
null,
createAuthorityList(annotation.role())
);
context.setAuthentication(authentication);
return context;
}
}
Loading
Loading