Skip to content

Commit e83f410

Browse files
authored
Merge pull request #7 from BCSDLab/release/1.0.0
Release/1.0.0
2 parents 528a18d + c640bef commit e83f410

47 files changed

Lines changed: 2043 additions & 161 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/main/java/koreatech/in/annotation/Auth.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
import java.lang.annotation.RetentionPolicy;
66
import java.lang.annotation.Target;
77

8-
@Target(ElementType.TYPE)
8+
@Target({ElementType.TYPE, ElementType.METHOD})
99
@Retention(RetentionPolicy.RUNTIME)
1010
public @interface Auth {
11-
public enum Role { ADMIN, USER, NONE }
12-
public enum Authority { USER, CALLVAN, LAND, COMMUNITY, SHOP, VERSION, MARKET, CIRCLE, LOST, SURVEY, BCSDLAB, NONE }
11+
public enum Role { ADMIN, USER, OWNER, NONE }
12+
public enum Authority { USER, CALLVAN, LAND, COMMUNITY, SHOP, VERSION, MARKET, CIRCLE, LOST, SURVEY, BCSDLAB, EVENT, NONE }
1313

1414
public Role role() default Role.NONE;
1515
public Authority authority() default Authority.NONE;

src/main/java/koreatech/in/aop/SlackCrash.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,44 @@
99
import org.springframework.beans.factory.annotation.Autowired;
1010
import org.springframework.stereotype.Component;
1111

12+
import java.util.Arrays;
13+
1214
@Component
1315
@Aspect
1416
public class SlackCrash {
1517
@Autowired
1618
SlackNotiSender sender;
1719

18-
@AfterThrowing(pointcut = "execution(* koreatech.in.service.*ServiceImpl.*(..))", throwing = "exception")
20+
@AfterThrowing(pointcut = "execution(* koreatech.in.controller.admin.*Controller.*(..))", throwing = "exception")
21+
public void sendSlackHookingOnCrashForAdmin(JoinPoint joinPoint, Throwable exception) {
22+
if (exception instanceof ParentException)
23+
return; // Custom Exception들은 ParentException을 상속받고 있으므로 해당 Exception들만 걸러낼 수 있다.
24+
25+
String errorMessage = exception.getMessage(); // PreconditionFailedException{errorMessage={error={code=0, message=Date form is invalid}}}
26+
String errorService = joinPoint.getTarget().getClass().getName(); // koreatech.in.service.DiningServiceImpl
27+
String errorMethod = joinPoint.getSignature().getName(); // getDinings
28+
String errorArgs = Arrays.toString(joinPoint.getArgs()); // [123]
29+
String errorFile = exception.getStackTrace()[0].getFileName(); // DiningServiceImpl.java
30+
int errorLine = exception.getStackTrace()[0].getLineNumber(); // 39
31+
String errorName = exception.getClass().getSimpleName(); // PreconditionFailedException
32+
33+
String message = String.format("%s %s Line %d\n```%s\n\n===== [Arguments] =====\n%s```", errorName, errorFile, errorLine, errorMessage, errorArgs);
34+
35+
36+
NotiSlack slack_message = new NotiSlack();
37+
slack_message.setColor("danger");
38+
slack_message.setTitle(String.format("%s.%s", errorService, errorMethod));
39+
slack_message.setText(message);
40+
sender.noticeError(slack_message);
41+
}
42+
@AfterThrowing(pointcut = "execution(* koreatech.in.controller.*Controller.*(..))", throwing = "exception")
1943
public void sendSlackHookingOnCrash(JoinPoint joinPoint, Throwable exception) {
2044
if (exception instanceof ParentException)
2145
return; // Custom Exception들은 ParentException을 상속받고 있으므로 해당 Exception들만 걸러낼 수 있다.
2246

2347
String errorMessage = exception.getMessage(); // PreconditionFailedException{errorMessage={error={code=0, message=Date form is invalid}}}
2448
String errorService = joinPoint.getTarget().getClass().getName(); // koreatech.in.service.DiningServiceImpl
2549
String errorMethod = joinPoint.getSignature().getName(); // getDinings
26-
// String errorArgs = Arrays.toString(joinPoint.getArgs()); // [123]
2750
String errorFile = exception.getStackTrace()[0].getFileName(); // DiningServiceImpl.java
2851
int errorLine = exception.getStackTrace()[0].getLineNumber(); // 39
2952
String errorName = exception.getClass().getSimpleName(); // PreconditionFailedException

src/main/java/koreatech/in/controller/CommunityController.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import koreatech.in.domain.Community.Comment;
1313
import koreatech.in.domain.Criteria.Criteria;
1414
import koreatech.in.domain.Criteria.SearchCriteria;
15+
import koreatech.in.domain.ErrorMessage;
16+
import koreatech.in.exception.PreconditionFailedException;
1517
import koreatech.in.service.CommunityService;
1618
import koreatech.in.util.StringXssChecker;
1719
import org.springframework.http.HttpStatus;
@@ -146,6 +148,8 @@ ResponseEntity deleteComment(@ApiParam(required = true) @PathVariable int articl
146148
@RequestMapping(value = "/articles/grant/check", method = RequestMethod.POST)
147149
public @ResponseBody
148150
ResponseEntity checkGrantEditArticle(@ApiParam(value = "(required: article_id)", required = true) @RequestBody Map<String, Integer> article_id) throws Exception {
151+
if (article_id == null || !article_id.containsKey("article_id"))
152+
throw new PreconditionFailedException(new ErrorMessage("올바르지 않은 데이터입니다.", 0));
149153

150154
return new ResponseEntity<Map<String, Boolean>>(communityService.checkGrantEditArticle(article_id.get("article_id")), HttpStatus.OK);
151155
}

src/main/java/koreatech/in/controller/DiningController.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,10 @@
2020
public class DiningController {
2121
@Inject
2222
private DiningService diningService;
23-
24-
// TODO: menu 부분 TEXT 타입에서 배열로 파싱 필요
23+
2524
@RequestMapping(value = "/dinings", method = RequestMethod.GET)
2625
public ResponseEntity getDinings(@ApiParam(required = false) @RequestParam(value = "date", required = false) String date) throws Exception {
27-
if(date == null) {
28-
date = new SimpleDateFormat("yy-MM-dd").format(new Date());
29-
}
30-
return new ResponseEntity<List<Map<String, Object>>>(diningService.getDinings(date), HttpStatus.OK);
26+
27+
return new ResponseEntity<>(diningService.getDinings(date), HttpStatus.OK);
3128
}
3229
}
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
package koreatech.in.controller;
2+
3+
import io.swagger.annotations.*;
4+
import koreatech.in.annotation.Auth;
5+
import koreatech.in.annotation.AuthExcept;
6+
import koreatech.in.annotation.ParamValid;
7+
import koreatech.in.annotation.ValidationGroups;
8+
import koreatech.in.domain.Criteria.Criteria;
9+
import koreatech.in.domain.ErrorMessage;
10+
import koreatech.in.domain.Event.EventArticle;
11+
import koreatech.in.domain.Event.EventComment;
12+
import koreatech.in.exception.PreconditionFailedException;
13+
import koreatech.in.service.EventService;
14+
import koreatech.in.util.StringXssChecker;
15+
import org.springframework.http.HttpStatus;
16+
import org.springframework.http.ResponseEntity;
17+
import org.springframework.stereotype.Controller;
18+
import org.springframework.validation.BindingResult;
19+
import org.springframework.validation.annotation.Validated;
20+
import org.springframework.web.bind.annotation.*;
21+
import org.springframework.web.multipart.MultipartFile;
22+
import org.springframework.web.multipart.MultipartHttpServletRequest;
23+
24+
import javax.inject.Inject;
25+
import java.util.List;
26+
import java.util.Map;
27+
28+
@Auth(role = Auth.Role.OWNER)
29+
@Controller
30+
public class EventController {
31+
@Inject
32+
private EventService eventService;
33+
34+
@AuthExcept
35+
@ApiOperation(value = "전체 홍보글 조회")
36+
@RequestMapping(value = "/events", method = RequestMethod.GET)
37+
public @ResponseBody
38+
ResponseEntity<Map<String, Object>> getEventArticles(@ModelAttribute("criteria") Criteria criteria) throws Exception {
39+
40+
return new ResponseEntity<>(eventService.getEventArticles(criteria), HttpStatus.OK);
41+
}
42+
43+
@ParamValid
44+
@ApiOperation(value = "홍보글 작성", authorizations = {@Authorization(value = "Authorization")})
45+
@RequestMapping(value = "/events", method = RequestMethod.POST)
46+
public @ResponseBody
47+
ResponseEntity<EventArticle> createEventArticle(@ApiParam(value = "(required: title, event_title, content, shop_id, start_date, end_date), (optional: thumbnail)", required = true) @RequestBody @Validated(ValidationGroups.Create.class) EventArticle eventArticle, BindingResult result) throws Exception {
48+
EventArticle clear = new EventArticle();
49+
50+
return new ResponseEntity<>(eventService.createEventArticle((EventArticle) StringXssChecker.xssCheck(eventArticle, clear)), HttpStatus.CREATED);
51+
}
52+
53+
@AuthExcept
54+
@ApiOperation(value = "특정 홍보글 조회")
55+
@RequestMapping(value = "/events/{id}", method = RequestMethod.GET)
56+
public @ResponseBody
57+
ResponseEntity<Map<String, Object>> getEventArticle(@ApiParam(required = true) @PathVariable int id) throws Exception {
58+
59+
return new ResponseEntity<>(eventService.getEventArticle(id), HttpStatus.OK);
60+
}
61+
62+
@ParamValid
63+
@ApiOperation(value = "홍보글 수정", authorizations = {@Authorization(value = "Authorization")})
64+
@RequestMapping(value = "/events/{id}", method = RequestMethod.PUT)
65+
public @ResponseBody
66+
ResponseEntity<EventArticle> updateEventArticle(@ApiParam(value = "(optional: title, event_title, content, start_date, end_date)", required = false) @RequestBody @Validated(ValidationGroups.Update.class) EventArticle eventArticle, BindingResult bindingResult, @ApiParam(required = true) @PathVariable int id) throws Exception {
67+
EventArticle clear = new EventArticle();
68+
return new ResponseEntity<>(eventService.updateEventArticle((EventArticle) StringXssChecker.xssCheck(eventArticle, clear), id), HttpStatus.CREATED);
69+
}
70+
71+
@ApiOperation(value = "홍보글 삭제", authorizations = {@Authorization(value = "Authorization")})
72+
@RequestMapping(value = "/events/{id}", method = RequestMethod.DELETE)
73+
public @ResponseBody
74+
ResponseEntity<Map<String, Object>> deleteEventArticle(@ApiParam(required = true) @PathVariable int id) throws Exception {
75+
76+
return new ResponseEntity<>(eventService.deleteEventArticle(id), HttpStatus.OK);
77+
}
78+
79+
@Auth(role = Auth.Role.USER)
80+
@ParamValid
81+
@ApiOperation(value = "홍보글 댓글 작성", authorizations = {@Authorization(value = "Authorization")})
82+
@RequestMapping(value = "/events/{articleId}/comments", method = RequestMethod.POST)
83+
public @ResponseBody
84+
ResponseEntity<EventComment> createEventComment(@ApiParam(value = "(required: content)", required = true) @RequestBody @Validated(ValidationGroups.Create.class) EventComment comment, BindingResult bindingResult, @ApiParam(required = true) @PathVariable(value = "articleId") int articleId) throws Exception {
85+
EventComment clear = new EventComment();
86+
return new ResponseEntity<>(eventService.createEventComment((EventComment) StringXssChecker.xssCheck(comment, clear), articleId), HttpStatus.CREATED);
87+
}
88+
89+
// @AuthExcept
90+
// @ApiOperation(value = "특정 홍보글 댓글 조회", authorizations = {@Authorization(value = "Authorization")})
91+
// @RequestMapping(value = "/events/{articleId}/comments/{commentId}", method = RequestMethod.GET)
92+
// public @ResponseBody
93+
// ResponseEntity<EventComment> getEventComment(@ApiParam(required = true) @PathVariable int articleId, @ApiParam(required = true) @PathVariable int commentId) throws Exception {
94+
//
95+
// return new ResponseEntity<>(eventService.getEventComment(articleId, commentId), HttpStatus.OK);
96+
// }
97+
98+
@Auth(role = Auth.Role.USER)
99+
@ParamValid
100+
@ApiOperation(value = "홍보글 댓글 수정", authorizations = {@Authorization(value = "Authorization")})
101+
@RequestMapping(value = "/events/{articleId}/comments/{commentId}", method = RequestMethod.PUT)
102+
public @ResponseBody
103+
ResponseEntity<EventComment> updateEventComment(@ApiParam(value = "(optional: content)", required = false) @RequestBody @Validated(ValidationGroups.Update.class) EventComment comment, BindingResult bindingResult, @ApiParam(required = true) @PathVariable int articleId, @ApiParam(required = true) @PathVariable int commentId) throws Exception {
104+
EventComment clear = new EventComment();
105+
return new ResponseEntity<>(eventService.updateEventComment((EventComment) StringXssChecker.xssCheck(comment, clear), articleId, commentId), HttpStatus.CREATED);
106+
}
107+
108+
@Auth(role = Auth.Role.USER)
109+
@ApiOperation(value = "홍보글 댓글 삭제", authorizations = {@Authorization(value = "Authorization")})
110+
@RequestMapping(value = "/events/{articleId}/comments/{commentId}", method = RequestMethod.DELETE)
111+
public @ResponseBody
112+
ResponseEntity<Map<String, Object>> deleteEventComment(@ApiParam(required = true) @PathVariable int articleId, @ApiParam(required = true) @PathVariable int commentId) throws Exception {
113+
114+
return new ResponseEntity<>(eventService.deleteEventComment(articleId, commentId), HttpStatus.OK);
115+
}
116+
117+
@ApiOperation(value = "점주의 가게 조회", authorizations = {@Authorization(value = "Authorization")})
118+
@RequestMapping(value = "/events/my/shops", method = RequestMethod.GET)
119+
public @ResponseBody
120+
ResponseEntity<Map<String, Object>> getMyShops() {
121+
122+
return new ResponseEntity<>(eventService.getMyShops(), HttpStatus.OK);
123+
}
124+
125+
@ApiOperation(value = "점주의 진행 중인 홍보 조회", authorizations = {@Authorization(value = "Authorization")})
126+
@RequestMapping(value = "/events/pending/my", method = RequestMethod.GET)
127+
public @ResponseBody
128+
ResponseEntity<Map<String, Object>> getMyPendingEvent(@ModelAttribute("criteria") Criteria criteria) throws Exception {
129+
130+
return new ResponseEntity<>(eventService.getMyPendingEvent(criteria), HttpStatus.OK);
131+
}
132+
133+
@AuthExcept
134+
@ApiOperation(value = "진행 중인 전체 홍보글 조회")
135+
@RequestMapping(value = "/events/pending", method = RequestMethod.GET)
136+
public @ResponseBody
137+
ResponseEntity<Map<String, Object>> getPendingEvents(@ModelAttribute("criteria") Criteria criteria) throws Exception {
138+
139+
return new ResponseEntity<>(eventService.getPendingEvents(criteria), HttpStatus.OK);
140+
}
141+
142+
@AuthExcept
143+
@ApiOperation(value = "마감된 전체 홍보글 조회")
144+
@RequestMapping(value = "/events/closed", method = RequestMethod.GET)
145+
public @ResponseBody
146+
ResponseEntity<Map<String, Object>> getClosedEvents(@ModelAttribute("criteria") Criteria criteria) throws Exception {
147+
148+
return new ResponseEntity<>(eventService.getClosedEvents(criteria), HttpStatus.OK);
149+
}
150+
151+
@ApiOperation(value = "특정 홍보글 수정 권한 확인", authorizations = {@Authorization(value = "Authorization")})
152+
@RequestMapping(value = "/events/grant/check", method = RequestMethod.POST)
153+
public @ResponseBody
154+
ResponseEntity<Map<String, Boolean>> checkGrantEditEvent(@ApiParam(required = true) @RequestBody Map<String, Integer> article_id) throws Exception {
155+
if (article_id == null || !article_id.containsKey("article_id"))
156+
throw new PreconditionFailedException(new ErrorMessage("올바르지 않은 데이터입니다.", 0));
157+
158+
return new ResponseEntity<>(eventService.checkGrantEditEvent(article_id.get("article_id")), HttpStatus.OK);
159+
}
160+
161+
@AuthExcept
162+
@ApiOperation(value = "진행 중인 이벤트 랜덤 조회")
163+
@RequestMapping(value = "/events/pending/random", method = RequestMethod.GET)
164+
public @ResponseBody
165+
ResponseEntity<EventArticle> getRandomPendingEvent() {
166+
167+
return new ResponseEntity<>(eventService.getRandomPendingEvent(), HttpStatus.OK);
168+
}
169+
}

src/main/java/koreatech/in/controller/LostAndFoundController.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
import koreatech.in.annotation.ParamValid;
77
import koreatech.in.annotation.ValidationGroups;
88
import koreatech.in.domain.Criteria.Criteria;
9+
import koreatech.in.domain.ErrorMessage;
910
import koreatech.in.domain.LostAndFound.LostItem;
1011
import koreatech.in.domain.LostAndFound.LostItemComment;
12+
import koreatech.in.exception.PreconditionFailedException;
1113
import koreatech.in.repository.UserMapper;
1214
import koreatech.in.service.LostAndFoundService;
1315
import koreatech.in.util.StringXssChecker;
@@ -131,6 +133,8 @@ ResponseEntity deleteLostItemComment(@ApiParam(required = true) @PathVariable(va
131133
@RequestMapping(value = "/lost/lostItems/grant/check", method = RequestMethod.POST)
132134
public @ResponseBody
133135
ResponseEntity checkGrantEditItem(@ApiParam(required = true) @RequestBody Map<String, Integer> lostItem_id) throws Exception {
136+
if (lostItem_id == null || !lostItem_id.containsKey("article_id"))
137+
throw new PreconditionFailedException(new ErrorMessage("올바르지 않은 데이터입니다.", 0));
134138

135139
return new ResponseEntity<Map<String, Boolean>>(lostAndFoundService.checkGrantEditLostItem(lostItem_id.get("lostItem_id")), HttpStatus.OK);
136140
}

src/main/java/koreatech/in/controller/MarketPlaceController.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
import koreatech.in.annotation.ParamValid;
77
import koreatech.in.annotation.ValidationGroups;
88
import koreatech.in.domain.Criteria.Criteria;
9+
import koreatech.in.domain.ErrorMessage;
910
import koreatech.in.domain.MarketPlace.Item;
1011
import koreatech.in.domain.MarketPlace.ItemComment;
12+
import koreatech.in.exception.PreconditionFailedException;
1113
import koreatech.in.service.MarketPlaceService;
1214
import koreatech.in.util.StringXssChecker;
1315
import org.springframework.http.HttpStatus;
@@ -128,6 +130,8 @@ ResponseEntity deleteItemComment(@ApiParam(required = true) @PathVariable(value
128130
@RequestMapping(value = "/market/items/grant/check", method = RequestMethod.POST)
129131
public @ResponseBody
130132
ResponseEntity checkGrantEditItem(@ApiParam(required = true) @RequestBody Map<String, Integer> item_id) throws Exception {
133+
if (item_id == null || !item_id.containsKey("article_id"))
134+
throw new PreconditionFailedException(new ErrorMessage("올바르지 않은 데이터입니다.", 0));
131135

132136
return new ResponseEntity<Map<String, Boolean>>(marketPlaceService.checkGrantEditItem(item_id.get("item_id")), HttpStatus.OK);
133137
}

src/main/java/koreatech/in/controller/TemporaryCommunityController.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
import koreatech.in.annotation.ParamValid;
77
import koreatech.in.annotation.ValidationGroups;
88
import koreatech.in.domain.Criteria.Criteria;
9+
import koreatech.in.domain.ErrorMessage;
910
import koreatech.in.domain.TemporaryCommunity.TempArticle;
1011
import koreatech.in.domain.TemporaryCommunity.TempComment;
12+
import koreatech.in.exception.PreconditionFailedException;
1113
import koreatech.in.service.TemporaryCommunityService;
1214
import koreatech.in.util.StringXssChecker;
1315
import org.springframework.http.HttpStatus;
@@ -105,6 +107,9 @@ ResponseEntity deleteComment(@ApiParam(required = true) @PathVariable int articl
105107
@RequestMapping(value = "/temp/articles/grant/check", method = RequestMethod.POST)
106108
public @ResponseBody
107109
ResponseEntity checkGrantEditArticle(@ApiParam(value = "(required: article_id, password)", required = true) @RequestBody Map<String, Object> param) throws Exception {
110+
if (param == null || !param.containsKey("article_id") || !param.containsKey("password"))
111+
throw new PreconditionFailedException(new ErrorMessage("올바르지 않은 데이터입니다.", 0));
112+
108113
Integer article_id = Integer.parseInt(param.get("article_id").toString());
109114
String password = param.get("password").toString();
110115

@@ -114,6 +119,9 @@ ResponseEntity checkGrantEditArticle(@ApiParam(value = "(required: article_id, p
114119
@RequestMapping(value = "/temp/comments/grant/check", method = RequestMethod.POST)
115120
public @ResponseBody
116121
ResponseEntity checkGrantEditComment(@ApiParam(value = "(required: comment_id, password)", required = true) @RequestBody Map<String, Object> param) throws Exception {
122+
if (param == null || !param.containsKey("comment_id") || !param.containsKey("password"))
123+
throw new PreconditionFailedException(new ErrorMessage("올바르지 않은 데이터입니다.", 0));
124+
117125
Integer comment_id = Integer.parseInt(param.get("comment_id").toString());
118126
String password = param.get("password").toString();
119127

0 commit comments

Comments
 (0)