Skip to content
Open
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
18 changes: 18 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

plugins {
id 'org.springframework.boot' version '2.4.2'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
Expand All @@ -14,7 +15,24 @@ repositories {

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.mariadb.jdbc:mariadb-java-client'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

//db - mysql
runtimeOnly 'mysql:mysql-connector-java'

//security
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'io.jsonwebtoken:jjwt:0.9.1'

compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'

testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
}

test {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.backdev.happy.wblserver.bakery.controller;

import com.backdev.happy.wblserver.bakery.domain.Bakery;
import com.backdev.happy.wblserver.bakery.dto.BakeryDto;
import com.backdev.happy.wblserver.bakery.repository.BakeryRepository;
import com.backdev.happy.wblserver.bakery.service.BakeryManageService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/bakeries")
@RequiredArgsConstructor
public class BakeryController {

private final BakeryManageService bakeryManageService;

@PostMapping
public ResponseEntity<String> createBakery(@RequestBody BakeryDto.CreateRequest request) {
final Bakery bakery = bakeryManageService.createBakery(request);
return new ResponseEntity<>("success to create bakery: "+bakery.toString(), HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.backdev.happy.wblserver.bakery.domain;

import com.backdev.happy.wblserver.global.config.security.UserRole;
import com.backdev.happy.wblserver.member.domain.Member;
import lombok.*;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import javax.persistence.*;
import java.util.Date;

@Getter
@ToString(of = {"member", "name"})
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "bakeries")
@Entity
public class Bakery {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@OneToOne //(cascade={CascadeType.ALL})
@JoinColumn(name = "member_id", referencedColumnName = "id")
private Member member; // 외래키가 있는 곳이 연관관계 주인 -> 하나의 member는 여러 개의 bakery를 가질 수 있으므로(one to many 관계) 주인을 seller로 설정

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

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

@Column(nullable = false, length = 45)
private String address;

@Column(columnDefinition = "TEXT")
private String introduction;

@CreationTimestamp
@Column(name = "create_time")
private Date createTime;

@UpdateTimestamp
@Column(name = "update_time")
private Date updateTime;

@Builder
public Bakery(final Long memberId, final String name, final String img, final String address, final String introduction){
this.member = new Member(memberId);
this.name = name;
this.img = img;
this.address = address;
this.introduction = introduction;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.backdev.happy.wblserver.bakery.dto;

import com.backdev.happy.wblserver.bakery.domain.Bakery;
import com.backdev.happy.wblserver.global.config.security.UserRole;
import com.backdev.happy.wblserver.member.domain.Member;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;

public class BakeryDto {

@Getter
@NoArgsConstructor
public static class CreateRequest {
private Long memberId;
private String name;
private String img;
private String address;
private String introduction;

@Builder
public CreateRequest(Long memberId, String name, String img, String address, String introduction){
this.memberId = memberId;
this.name = name;
this.img = img;
this.address = address;
this.introduction = introduction;
}

public Bakery toEntity(){
return Bakery.builder()
.memberId(memberId)
.name(name)
.img(img)
.address(address)
.introduction(introduction)
.build();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.backdev.happy.wblserver.bakery.repository;

import com.backdev.happy.wblserver.bakery.domain.Bakery;
import org.springframework.data.jpa.repository.JpaRepository;

public interface BakeryRepository extends JpaRepository<Bakery,Long> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.backdev.happy.wblserver.bakery.service;

import com.backdev.happy.wblserver.bakery.domain.Bakery;
import com.backdev.happy.wblserver.bakery.dto.BakeryDto;
import com.backdev.happy.wblserver.bakery.repository.BakeryRepository;

public interface BakeryManageService {
Bakery createBakery(final BakeryDto.CreateRequest dto);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.backdev.happy.wblserver.bakery.service.impl;

import com.backdev.happy.wblserver.bakery.domain.Bakery;
import com.backdev.happy.wblserver.bakery.dto.BakeryDto;
import com.backdev.happy.wblserver.bakery.repository.BakeryRepository;
import com.backdev.happy.wblserver.bakery.service.BakeryManageService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class BakeryManageServiceImpl implements BakeryManageService {

private final BakeryRepository bakeryRepository;

@Override
public Bakery createBakery(BakeryDto.CreateRequest dto) {
return bakeryRepository.save(dto.toEntity());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.backdev.happy.wblserver.global.config.security;


import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@RequiredArgsConstructor
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

private final JwtTokenProvider jwtTokenProvider;

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable() // rest api 이므로 기본설정 사용안함. 기본설정은 비인증시 로그인폼 화면으로 리다이렉트 된다.
.csrf().disable() // rest api이므로 csrf 보안이 필요없으므로 disable처리.
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // jwt token으로 인증하므로 세션은 필요없으므로 생성안함.
.and()
.authorizeRequests() // 다음 리퀘스트에 대한 사용권한 체크
.antMatchers("/members/signin", "members/signup").permitAll() // 가입 및 인증 주소는 누구나 접근가능
.antMatchers("/bakeries/**","/members/*/hello").hasRole("SELLER")
//.anyRequest().hasRole("CUSTOMER") // 그외 나머지 요청은 모두 인증된 회원만 접근 가능
.and()
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class); // jwt token 필터를 id/password 인증 필터 전에 넣는다

}

@Override // ignore check swagger resource
public void configure(WebSecurity web) {
// web.ignoring().antMatchers("/v2/api-docs", "/swagger-resources/**",
// "/swagger-ui.html", "/webjars/**", "/swagger/**");

}

@Bean
public PasswordEncoder passwordEncoder(){
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.backdev.happy.wblserver.global.config.security;

import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.Arrays;

@AllArgsConstructor
@Getter
public enum UserRole {
USER("ROLE_USER"),
ADMIN("ROLE_ADMIN"),
CUSTOMER("ROLE_CUSTOMER"),
SELLER("ROLE_SELLER");

private String value;

public static UserRole findByString(String val) {
return Arrays.stream(values())
.filter(v -> val.equals(v.value))
.findFirst()
.orElseThrow(() -> new RuntimeException(val + " is not supported"));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.backdev.happy.wblserver.member.controller;

import com.backdev.happy.wblserver.global.config.security.JwtTokenProvider;
import com.backdev.happy.wblserver.member.domain.Member;
import com.backdev.happy.wblserver.member.dto.MemberDto;
import com.backdev.happy.wblserver.member.service.MemberManageService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/members")
@RequiredArgsConstructor
public class MemberController {

private final MemberManageService memberManageService;
private final JwtTokenProvider jwtTokenProvider; // jwt 쓴다면 이용할 예정

@GetMapping(value = "/a/hello")
public String hello(){
return "hello world";
}

@PostMapping(value = "/signin")
public ResponseEntity<String> signIn(@RequestBody MemberDto.SignInRequest request) {
Member member = memberManageService.signInMember(request);
// return responseService.getSingleResult(jwtTokenProvider.createToken(String.valueOf(customer.getMsrl()), customer.getRoles()));
return new ResponseEntity<>("success to sign in: "+member.toString(), HttpStatus.OK);
}

@PostMapping(value = "/signup")
public ResponseEntity<String> signUp(@RequestBody MemberDto.SignUpRequest request) {
Member member = memberManageService.signUpMember(request);
return new ResponseEntity<>("success to sign up: "+member.toString(), HttpStatus.OK);
}

}
Loading