Skip to content

Commit

Permalink
feat: api 별 접근 권한 처리
Browse files Browse the repository at this point in the history
- swagger 에 접근 가능한 권한 명시함
- 접근 권한은 추후 쉽게 변경가능
  • Loading branch information
versatile0010 committed Aug 5, 2023
1 parent 2b6eb36 commit 2e57e93
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 42 deletions.
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
package com.example.couphoneserver.controller;

import com.example.couphoneserver.common.annotation.NoAuth;
import com.example.couphoneserver.common.exception.BadRequestException;
import com.example.couphoneserver.common.response.BaseResponse;
import com.example.couphoneserver.dto.brand.GetBrandDetailResponse;
import com.example.couphoneserver.dto.brand.GetBrandResponse;
import com.example.couphoneserver.dto.brand.PostBrandRequest;
import com.example.couphoneserver.dto.brand.PostBrandResponse;
import com.example.couphoneserver.service.BrandService;
import com.example.couphoneserver.service.MemberService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
Expand All @@ -28,24 +27,29 @@
@RequestMapping("/brands")
public class BrandController {
private final BrandService brandService;
private final MemberService memberService;

@PreAuthorize("hasRole('ADMIN')")
@PostMapping("")
@NoAuth
@Operation(summary = "브랜드 등록",
description = "Request Body에 브랜드 이름, 보상 설명, 이미지 url, 카테고리 id 담아서 보내주세요!")
public BaseResponse<PostBrandResponse> postBrand(@RequestBody PostBrandRequest request){
description = """
Request Body에 브랜드 이름, 보상 설명, 이미지 url, 카테고리 id 담아서 보내주세요!
- [ROLE_ADMIN ONLY]
""",
security = @SecurityRequirement(name = "bearerAuth"))
public BaseResponse<PostBrandResponse> postBrand(@RequestBody PostBrandRequest request) {
return new BaseResponse<>(brandService.saveBrand(request));
}

@PreAuthorize("hasRole('MEMBER') or hasRole('ADMIN')")
@GetMapping("")
@Operation(summary = "브랜드 조회",
description =
"""
브랜드를 검색어 또는 카테고리별로 조회합니다. Header에 Access Token 담아주세요!
Query String으로 카테고리 ID를 담아서 보내주시면 카테고리별로 브랜드를 조회하고,
검색어 담아서 보내주시면 검색한 이름에 따라 브랜드를 조회합니다.
""",
브랜드를 검색어 또는 카테고리별로 조회합니다.
- [ROLE_MEMBER OR ROLE_ADMIN]
- Header에 Access Token 담아주세요!
- Query String으로 카테고리 ID를 담아서 보내주시면 카테고리별로 브랜드를 조회하고, 검색어 담아서 보내주시면 검색한 이름에 따라 브랜드를 조회합니다.
""",
security = @SecurityRequirement(name = "bearerAuth"))
public BaseResponse<List<GetBrandResponse>> getBrand(@RequestParam(required = false, value = "category-id") Long categoryId,
@RequestParam(required = false, value = "name") String name,
Expand All @@ -62,9 +66,14 @@ public BaseResponse<List<GetBrandResponse>> getBrand(@RequestParam(required = fa
throw new BadRequestException(BAD_REQUEST);
}

@PreAuthorize("hasRole('MEMBER') or hasRole('ADMIN')")
@GetMapping("/{brand-id}")
@Operation(summary = "브랜드 상세 조회",
description = "브랜드를 상세 조회합니다. Path Vriable로 브랜드 ID, Header에 Access Token 담아서 보내주세요!",
description = """
브랜드를 상세 조회합니다.
- [ROLE_MEMBER OR ROLE_ADMIN]
- Path Vriable로 브랜드 ID, Header에 Access Token 담아서 보내주세요!
""",
security = @SecurityRequirement(name = "bearerAuth"))
public BaseResponse<GetBrandDetailResponse> getBrandDetail(@PathVariable(value = "brand-id") Long brandId,
Principal principal) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
Expand All @@ -29,14 +31,19 @@ public class CategoryController {

private final CategoryService categoryService;

@PreAuthorize("hasRole('MEMBER') or hasRole('ADMIN')")
@GetMapping("")
@Operation(summary = "카테고리 정보 제공", description = "카테고리 정보를 제공합니다.", responses = {
@Operation(summary = "카테고리 정보 제공", description = """
카테고리 정보를 제공합니다.
- [ROLE_MEMBER OR ROLE_ADMIN]
""", responses = {
@ApiResponse(responseCode = "200", description = "쿼리가 null인 경우, 모든 카테고리 조회 성공", content = @Content(schema = @Schema(implementation = GetCategoryResponse.class))),
@ApiResponse(responseCode = "200", description = "쿼리에 이름을 넣은 경우, 카테고리 조회 성공", content = @Content(schema = @Schema(implementation = GetCategoryResponse.class))),
@ApiResponse(responseCode = "400", description = "존재하지 않은 리소스 접근", content = @Content(schema = @Schema(implementation = BaseErrorResponse.class)))
})
}, security = @SecurityRequirement(name = "bearerAuth"))

public BaseResponse<List<GetCategoryResponse>> getCategory(@Parameter(name = "query", description = "카테고리의 이름(선택)", in = ParameterIn.QUERY)
@RequestParam(required = false) String query){
@RequestParam(required = false) String query) {
return new BaseResponse<>(categoryService.findCategory(query));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import com.example.couphoneserver.dto.coupon.*;
import com.example.couphoneserver.service.CouponService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

@Tag(name = "coupons", description = "쿠폰 관련 API")
Expand All @@ -14,21 +16,35 @@
@RequestMapping("/coupons")
public class CouponController {
private final CouponService couponService;

@PreAuthorize("hasRole('ADMIN')")
@PostMapping("")
@Operation(summary = "쿠폰 등록", description = "Request Body에 브랜드 ID, 멤버 ID 넣어주세요!")
@Operation(summary = "쿠폰 등록", description = """
Request Body에 브랜드 ID, 멤버 ID 넣어주세요!
- [ROLE_ADMIN ONLY]
""",
security = @SecurityRequirement(name = "bearerAuth"))
public BaseResponse<PostCouponResponse> postCouponItem(@RequestBody PostCouponRequest request){
return new BaseResponse<>(couponService.saveCoupon(request));
}

@PreAuthorize("hasRole('ADMIN')")
@PatchMapping("/stamp/{coupon-id}")
@Operation(summary = "쿠폰 스탬프 적립", description = "Path Variable로 쿠폰 ID 넣어주세요!")
@Operation(summary = "쿠폰 스탬프 적립", description = """
Path Variable로 쿠폰 ID 넣어주세요!
- [ROLE_ADMIN ONLY]
""",
security = @SecurityRequirement(name = "bearerAuth"))
public BaseResponse<PatchCouponCountResponse> patchCouponItemCount(@PathVariable("coupon-id") Long couponId) {
return new BaseResponse<>(couponService.collectStamp(couponId));
}

@PreAuthorize("hasRole('MEMBER') or hasRole('ADMIN')")
@PatchMapping("/status/{coupon-id}")
@Operation(summary = "쿠폰 사용하기", description = "Path Variable로 쿠폰 ID 넣어주세요!")
@Operation(summary = "쿠폰 사용하기", description = """
Path Variable로 쿠폰 ID 넣어주세요!
- [ROLE_MEMBER OR ROLE_ADMIN]
""",
security = @SecurityRequirement(name = "bearerAuth"))
public BaseResponse<PatchCouponStatusResponse> patchCouponItemStatus(@PathVariable("coupon-id") Long couponId) {
return new BaseResponse<>(couponService.useCoupon(couponId));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,60 @@
import com.example.couphoneserver.dto.member.response.PatchMemberResponse;
import com.example.couphoneserver.service.MemberService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

@Tag(name = "회원 컨트롤러", description = "회원 관련 API 입니다.")

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/users")
public class MemberController {
private final MemberService memberService;

@PreAuthorize("hasRole('MEMBER') or hasRole('ADMIN')")
@PatchMapping("/{member-id}")
@Operation(summary = "회원 탈퇴", description =
"회원의 상태를 TERMINATED 으로 변경합니다. path variable 로 멤버 id 담아서 보내주세요!")
"""
회원의 상태를 TERMINATED 으로 변경합니다.
- [ROLE_MEMBER OR ROLE_ADMIN]
- path variable 로 멤버 id 담아서 보내주세요!
""",
security = @SecurityRequirement(name = "bearerAuth"))
public BaseResponse<PatchMemberResponse> delete(@PathVariable("member-id") Long memberId) {
Member member = memberService.findOneById(memberId);
return new BaseResponse<>(memberService.delete(member));
}

@PreAuthorize("hasRole('MEMBER') or hasRole('ADMIN')")
@GetMapping("/{member-id}")
@Operation(summary = "회원 정보 조회", description =
"회원 정보를 조회합니다. path variable 로 멤버 id 담아서 보내주세요!")
"""
회원 정보를 조회합니다.
- [ROLE_MEMBER OR ROLE_ADMIN]
- path variable 로 멤버 id 담아서 보내주세요!
""",
security = @SecurityRequirement(name = "bearerAuth"))
public BaseResponse<GetMemberResponse> show(@PathVariable("member-id") Long memberId) {
Member member = memberService.findOneById(memberId);
return new BaseResponse<>(memberService.getMemberInfo(member));
}

@PreAuthorize("hasRole('MEMBER') or hasRole('ADMIN')")
@GetMapping("/{member-id}/brands")
@Operation(summary = "정렬 조건에 따른 브랜드 조회", description =
"""
path variable 으로 member-id 를 보내면 해당 회원이 가지고 있는 쿠폰 브랜드 리스트를 반환합니다.
정렬 조건은 query string 으로 sort 값을 보내주세요. {1, 2, 3} 에 따라 달라집니다.
- [ROLE_MEMBER OR ROLE_ADMIN]
- 1(default)번 옵션은 쿠폰 많은 순, 생성 시간이 이른 순
- 2번 옵션은 생성 시간이 이른 순, 쿠폰 많은 순
- 3번 옵션은 브랜드 이름 순으로 정렬하여 데이터를 반환합니다.
""")
""",
security = @SecurityRequirement(name = "bearerAuth"))
public BaseResponse<GetMemberCouponBrandsResponse> getBrands(
@PathVariable("member-id") Long memberId,
@RequestParam(required = false, defaultValue = "1", value = "sort") String sort) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
package com.example.couphoneserver.controller;

import com.example.couphoneserver.common.annotation.NoAuth;
import com.example.couphoneserver.common.datatype.Coordinate;
import com.example.couphoneserver.common.exception.StoreException;
import com.example.couphoneserver.common.response.BaseResponse;
import com.example.couphoneserver.dto.store.*;
import com.example.couphoneserver.repository.mappingInterface.StoreInfoMapping;
import com.example.couphoneserver.service.StoreService;
import com.example.couphoneserver.utils.CoordinateConverter;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
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;

import java.security.Principal;
import java.util.List;
Expand All @@ -31,37 +34,50 @@ public class StoreController {
private final StoreService storeService;
private final CoordinateConverter coordinateConverter;

@NoAuth
@PreAuthorize("hasRole('ADMIN')")
@PostMapping("")
@Operation(summary = "가게 등록", description = "Request Body에 브랜드 아이디, 매장명, 위도, 경도, 주소를 담아서 보내주세요!")
@Operation(summary = "가게 등록", description = """
Request Body에 브랜드 아이디, 매장명, 위도, 경도, 주소를 담아서 보내주세요!
- [ROLE_ADMIN ONLY]
""",
security = @SecurityRequirement(name = "bearerAuth"))
public BaseResponse<PostStoreResponse> postBrand(@Validated @RequestBody PostStoreRequest request,
BindingResult bindingResult){
if (bindingResult.hasErrors()){
throw new StoreException(INVALID_STORE_VALUE,getErrorMessages(bindingResult));
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
throw new StoreException(INVALID_STORE_VALUE, getErrorMessages(bindingResult));
}
return new BaseResponse<>(storeService.save(request));
}

@NoAuth
@PreAuthorize("hasRole('ADMIN')")
@PostMapping("/coordinate")
@Operation(summary = "좌표 변환", description = "Request Body에 주소를 담아 보내면 좌표를 반환합니다.")
@Operation(summary = "좌표 변환", description = """
Request Body에 주소를 담아 보내면 좌표를 반환합니다.
- [ROLE_ADMIN ONLY]
""",
security = @SecurityRequirement(name = "bearerAuth"))
public BaseResponse<Coordinate> translateCoordinate(@Validated @RequestBody PostCoordinateRequest request,
BindingResult bindingResult){
if (bindingResult.hasErrors()){
throw new StoreException(INVALID_STORE_VALUE,getErrorMessages(bindingResult));
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
throw new StoreException(INVALID_STORE_VALUE, getErrorMessages(bindingResult));
}
return new BaseResponse<>(coordinateConverter.getCoordinate(request.getAddress()));
}

@PreAuthorize("hasRole('MEMBER') or hasRole('ADMIN')")
@PostMapping("/nearby")
@Operation(summary = "좌표 중심 가게 반환", description = "Request Body에 좌표를 담아 보내면 주변 가게 리스트를 반환합니다.")
@Operation(summary = "좌표 중심 가게 반환", description = """
Request Body에 좌표를 담아 보내면 주변 가게 리스트를 반환합니다.
- [ROLE_MEMBER OR ROLE_ADMIN]
""",
security = @SecurityRequirement(name = "bearerAuth"))
public BaseResponse<List<PostNearbyStoreResponse>> translateCoordinate(@Validated @RequestBody PostNearbyStoreRequest request,
Principal principal,
BindingResult bindingResult){
if (bindingResult.hasErrors()){
throw new StoreException(INVALID_STORE_VALUE,getErrorMessages(bindingResult));
Principal principal,
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
throw new StoreException(INVALID_STORE_VALUE, getErrorMessages(bindingResult));
}
return new BaseResponse<>(storeService.findNearbyStores(principal,request));
return new BaseResponse<>(storeService.findNearbyStores(principal, request));
}

}

0 comments on commit 2e57e93

Please sign in to comment.