
Merge branch 'refectoring/actions' of whiteship/yobi
from pull request 727
@0978c4354a4d389aa9186c5be6ffc8b5f53906b1
--- app/actions/AbstractProjectCheckAction.java
+++ app/actions/AbstractProjectCheckAction.java
... | ... | @@ -37,10 +37,9 @@ |
37 | 37 |
|
38 | 38 |
/** |
39 | 39 |
* /{user.loginId}/{project.name}/** 패턴의 요청에 해당하는 프로젝트가 존재하는지 확인하는 액션. |
40 |
- * - URL에 해당하는 프로젝트가 없을 때 404 Not Found 로 응답한다. |
|
41 |
- * - 현재 사용자가 URL에 해당하는 프로젝트에 읽기 권한이 없을 경우 404 Not Found 로 응답한다. |
|
40 |
+ * - URL에 해당하는 프로젝트가 없거나 현재 사용자가 읽기 권한이 없을 때 403 Forbidden으로 응답한다. |
|
42 | 41 |
* - URL에 해당하는 프로젝트가 있을 때 {@link AbstractProjectCheckAction#call(Project, Context)} 을 |
43 |
- * 호출하여 이후 검증 과정을 수행한다. |
|
42 |
+ * 호출하여 이후에 추가 검증 과정을 수행한다. |
|
44 | 43 |
* |
45 | 44 |
* @author Keesun Baik, kjkmadness |
46 | 45 |
*/ |
--- app/actions/AnonymousCheckAction.java
+++ app/actions/AnonymousCheckAction.java
... | ... | @@ -30,6 +30,7 @@ |
30 | 30 |
import utils.Constants; |
31 | 31 |
|
32 | 32 |
/** |
33 |
+ * {@link actions.AbstractProjectCheckAction}의 추가작업으로, |
|
33 | 34 |
* 현재 사용자가 anonymouse이면 로그인 페이지로 리다이렉트 한다. |
34 | 35 |
* |
35 | 36 |
* @author Wansoon Park, Keesun Beak |
+++ app/actions/DefaultProjectCheckAction.java
... | ... | @@ -0,0 +1,39 @@ |
1 | +/** | |
2 | + * Yobi, Project Hosting SW | |
3 | + * | |
4 | + * Copyright 2013 NAVER Corp. | |
5 | + * http://yobi.io | |
6 | + * | |
7 | + * @Author Keesun Baik | |
8 | + * | |
9 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
10 | + * you may not use this file except in compliance with the License. | |
11 | + * You may obtain a copy of the License at | |
12 | + * | |
13 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
14 | + * | |
15 | + * Unless required by applicable law or agreed to in writing, software | |
16 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
17 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
18 | + * See the License for the specific language governing permissions and | |
19 | + * limitations under the License. | |
20 | + */ | |
21 | +package actions; | |
22 | + | |
23 | +import actions.support.PathParser; | |
24 | +import models.Project; | |
25 | +import play.mvc.Http.Context; | |
26 | +import play.mvc.Result; | |
27 | + | |
28 | +/** | |
29 | + * {@link AbstractProjectCheckAction}에서 제공하는 기능만을 실행하는 액션. | |
30 | + * | |
31 | + * @see {@link AbstractProjectCheckAction} | |
32 | + * @author Keesun Baik | |
33 | + */ | |
34 | +public class DefaultProjectCheckAction extends AbstractProjectCheckAction<Void> { | |
35 | + @Override | |
36 | + protected Result call(Project project, Context context, PathParser parser) throws Throwable { | |
37 | + return this.delegate.call(context); | |
38 | + } | |
39 | +} |
--- app/actions/IsAllowedAction.java
+++ app/actions/IsAllowedAction.java
... | ... | @@ -35,6 +35,7 @@ |
35 | 35 |
import utils.ErrorViews; |
36 | 36 |
|
37 | 37 |
/** |
38 |
+ * {@link actions.AbstractProjectCheckAction}의 추가작업으로, |
|
38 | 39 |
* 1. 특정 타입의 리소스가 존재하는지 확인한다. |
39 | 40 |
* 2. 특정 타입의 리소스에 권한이 있는지 확인한다. |
40 | 41 |
* |
--- app/actions/IsCreatableAction.java
+++ app/actions/IsCreatableAction.java
... | ... | @@ -32,6 +32,7 @@ |
32 | 32 |
import controllers.annotation.IsCreatable; |
33 | 33 |
|
34 | 34 |
/** |
35 |
+ * {@link actions.AbstractProjectCheckAction}의 추가작업으로, |
|
35 | 36 |
* 프로젝트에 특정 타입의 리소스를 생성할 수 있는지 확인한다. |
36 | 37 |
* |
37 | 38 |
* @author Wansoon Park, Keesun Baik |
--- app/actions/IsOnlyGitAvailableAction.java
+++ app/actions/IsOnlyGitAvailableAction.java
... | ... | @@ -29,6 +29,7 @@ |
29 | 29 |
import utils.ErrorViews; |
30 | 30 |
|
31 | 31 |
/** |
32 |
+ * {@link actions.AbstractProjectCheckAction}의 추가작업으로, |
|
32 | 33 |
* 프로젝트가 Git 프로젝트인지 확인한다. |
33 | 34 |
* |
34 | 35 |
* @see {@link AbstractProjectCheckAction} |
--- app/actions/NullProjectCheckAction.java
+++ app/actions/NullProjectCheckAction.java
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 |
* Copyright 2013 NAVER Corp. |
5 | 5 |
* http://yobi.io |
6 | 6 |
* |
7 |
- * @Author Keesun Baik |
|
7 |
+ * @Author Wansoon Park, Keesun Baek |
|
8 | 8 |
* |
9 | 9 |
* Licensed under the Apache License, Version 2.0 (the "License"); |
10 | 10 |
* you may not use this file except in compliance with the License. |
... | ... | @@ -21,21 +21,44 @@ |
21 | 21 |
package actions; |
22 | 22 |
|
23 | 23 |
import actions.support.PathParser; |
24 |
+import controllers.UserApp; |
|
24 | 25 |
import models.Project; |
25 |
-import play.mvc.Http.Context; |
|
26 |
+import models.User; |
|
27 |
+import play.i18n.Messages; |
|
28 |
+import play.mvc.Action; |
|
29 |
+import play.mvc.Http; |
|
26 | 30 |
import play.mvc.Result; |
31 |
+import utils.AccessLogger; |
|
32 |
+import utils.ErrorViews; |
|
33 |
+ |
|
34 |
+import static play.mvc.Controller.flash; |
|
27 | 35 |
|
28 | 36 |
/** |
29 | 37 |
* /{user.loginId}/{project.name}/** 패턴의 요청에 해당하는 프로젝트가 존재하는지 확인하는 액션. |
30 |
- * - URL에 해당하는 프로젝트가 없을 때 404 Not Found로 응답한다. |
|
31 |
- * - URL에 해당하는 프로젝트가 있을 때 요청 처리한다. |
|
38 |
+ * - URL에 해당하는 프로젝트가 없을 때 403 Forbidden으로 응답한다. |
|
32 | 39 |
* |
33 |
- * @see {@link AbstractProjectCheckAction} |
|
34 |
- * @author Keesun Baik |
|
40 |
+ * @author Keeun Baik |
|
35 | 41 |
*/ |
36 |
-public class NullProjectCheckAction extends AbstractProjectCheckAction<Void> { |
|
42 |
+public class NullProjectCheckAction extends Action<Void> { |
|
43 |
+ |
|
37 | 44 |
@Override |
38 |
- protected Result call(Project project, Context context, PathParser parser) throws Throwable { |
|
45 |
+ public Result call(Http.Context context) throws Throwable { |
|
46 |
+ PathParser parser = new PathParser(context); |
|
47 |
+ String ownerLoginId = parser.getOwnerLoginId(); |
|
48 |
+ String projectName = parser.getProjectName(); |
|
49 |
+ |
|
50 |
+ Project project = Project.findByOwnerAndProjectName(ownerLoginId, projectName); |
|
51 |
+ |
|
52 |
+ if (project == null) { |
|
53 |
+ if (UserApp.currentUser() == User.anonymous){ |
|
54 |
+ flash("failed", Messages.get("error.auth.unauthorized.waringMessage")); |
|
55 |
+ return AccessLogger.log(context.request(), |
|
56 |
+ forbidden(ErrorViews.Forbidden.render("error.forbidden.or.notfound", context.request().path())), null); |
|
57 |
+ } |
|
58 |
+ return AccessLogger.log(context.request(), |
|
59 |
+ forbidden(ErrorViews.NotFound.render("error.forbidden.or.notfound")), null); |
|
60 |
+ } |
|
61 |
+ |
|
39 | 62 |
return this.delegate.call(context); |
40 | 63 |
} |
41 | 64 |
} |
--- app/controllers/BoardApp.java
+++ app/controllers/BoardApp.java
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 |
package controllers; |
3 | 3 |
|
4 | 4 |
import actions.AnonymousCheckAction; |
5 |
-import actions.NullProjectCheckAction; |
|
5 |
+import actions.DefaultProjectCheckAction; |
|
6 | 6 |
|
7 | 7 |
import com.avaje.ebean.ExpressionList; |
8 | 8 |
import com.avaje.ebean.Page; |
... | ... | @@ -220,7 +220,7 @@ |
220 | 220 |
* @see AbstractPostingApp#editPosting(models.AbstractPosting, models.AbstractPosting, play.data.Form |
221 | 221 |
*/ |
222 | 222 |
@Transactional |
223 |
- @With(NullProjectCheckAction.class) |
|
223 |
+ @With(DefaultProjectCheckAction.class) |
|
224 | 224 |
public static Result editPost(String userName, String projectName, Long number) { |
225 | 225 |
Form<Posting> postForm = new Form<>(Posting.class).bindFromRequest(); |
226 | 226 |
Project project = ProjectApp.getProject(userName, projectName); |
... | ... | @@ -321,7 +321,7 @@ |
321 | 321 |
* @see controllers.AbstractPostingApp#delete(play.db.ebean.Model, models.resource.Resource, play.mvc.Call) |
322 | 322 |
*/ |
323 | 323 |
@Transactional |
324 |
- @With(NullProjectCheckAction.class) |
|
324 |
+ @With(DefaultProjectCheckAction.class) |
|
325 | 325 |
public static Result deleteComment(String userName, String projectName, Long number, Long commentId) { |
326 | 326 |
Comment comment = PostingComment.find.byId(commentId); |
327 | 327 |
Project project = comment.asResource().getProject(); |
--- app/controllers/CodeApp.java
+++ app/controllers/CodeApp.java
... | ... | @@ -1,6 +1,6 @@ |
1 | 1 |
package controllers; |
2 | 2 |
|
3 |
-import actions.NullProjectCheckAction; |
|
3 |
+import actions.DefaultProjectCheckAction; |
|
4 | 4 |
import controllers.annotation.IsAllowed; |
5 | 5 |
import models.Project; |
6 | 6 |
import models.enumeration.Operation; |
... | ... | @@ -21,7 +21,6 @@ |
21 | 21 |
|
22 | 22 |
import javax.servlet.ServletException; |
23 | 23 |
import java.io.IOException; |
24 |
-import java.io.InputStream; |
|
25 | 24 |
import java.net.URLEncoder; |
26 | 25 |
import java.util.ArrayList; |
27 | 26 |
import java.util.Arrays; |
... | ... | @@ -75,7 +74,7 @@ |
75 | 74 |
* @param branch 브랜치 이름 |
76 | 75 |
* @param path 파일 경로 |
77 | 76 |
*/ |
78 |
- @With(NullProjectCheckAction.class) |
|
77 |
+ @With(DefaultProjectCheckAction.class) |
|
79 | 78 |
public static Result codeBrowserWithBranch(String userName, String projectName, String branch, String path) |
80 | 79 |
throws UnsupportedOperationException, IOException, SVNException, GitAPIException, ServletException { |
81 | 80 |
Project project = ProjectApp.getProject(userName, projectName); |
... | ... | @@ -110,7 +109,7 @@ |
110 | 109 |
* @param projectName 프로젝트 이름 |
111 | 110 |
* @param path 파일 또는 폴더의 경로 |
112 | 111 |
*/ |
113 |
- @With(NullProjectCheckAction.class) |
|
112 |
+ @With(DefaultProjectCheckAction.class) |
|
114 | 113 |
public static Result ajaxRequest(String userName, String projectName, String path) throws Exception{ |
115 | 114 |
PlayRepository repository = RepositoryService.getRepository(userName, projectName); |
116 | 115 |
ObjectNode fileInfo = repository.getMetaDataFromPath(path); |
... | ... | @@ -130,7 +129,7 @@ |
130 | 129 |
* @param branch 브랜치 이름 |
131 | 130 |
* @param path 파일 또는 폴더의 경로 |
132 | 131 |
*/ |
133 |
- @With(NullProjectCheckAction.class) |
|
132 |
+ @With(DefaultProjectCheckAction.class) |
|
134 | 133 |
public static Result ajaxRequestWithBranch(String userName, String projectName, String branch, String path) |
135 | 134 |
throws UnsupportedOperationException, IOException, SVNException, GitAPIException, ServletException{ |
136 | 135 |
CodeApp.hostName = request().host(); |
... | ... | @@ -152,7 +151,7 @@ |
152 | 151 |
* @param revision |
153 | 152 |
* @param path |
154 | 153 |
*/ |
155 |
- @With(NullProjectCheckAction.class) |
|
154 |
+ @With(DefaultProjectCheckAction.class) |
|
156 | 155 |
public static Result showRawFile(String userName, String projectName, String revision, String path) throws Exception{ |
157 | 156 |
byte[] fileAsRaw = RepositoryService.getFileAsRaw(userName, projectName, revision, path); |
158 | 157 |
if(fileAsRaw == null){ |
... | ... | @@ -168,7 +167,7 @@ |
168 | 167 |
* @param projectName |
169 | 168 |
* @param path |
170 | 169 |
*/ |
171 |
- @With(NullProjectCheckAction.class) |
|
170 |
+ @With(DefaultProjectCheckAction.class) |
|
172 | 171 |
public static Result showImageFile(String userName, String projectName, String revision, String path) throws Exception{ |
173 | 172 |
final byte[] fileAsRaw = RepositoryService.getFileAsRaw(userName, projectName, revision, path); |
174 | 173 |
String mimeType = tika.detect(fileAsRaw); |
--- app/controllers/CodeHistoryApp.java
+++ app/controllers/CodeHistoryApp.java
... | ... | @@ -1,6 +1,6 @@ |
1 | 1 |
package controllers; |
2 | 2 |
|
3 |
-import actions.NullProjectCheckAction; |
|
3 |
+import actions.DefaultProjectCheckAction; |
|
4 | 4 |
import controllers.annotation.IsAllowed; |
5 | 5 |
import controllers.annotation.IsCreatable; |
6 | 6 |
import models.Attachment; |
... | ... | @@ -59,7 +59,7 @@ |
59 | 59 |
* @throws GitAPIException |
60 | 60 |
* @throws SVNException |
61 | 61 |
*/ |
62 |
- @With(NullProjectCheckAction.class) |
|
62 |
+ @With(DefaultProjectCheckAction.class) |
|
63 | 63 |
public static Result historyUntilHead(String ownerName, String projectName) throws IOException, |
64 | 64 |
UnsupportedOperationException, ServletException, GitAPIException, |
65 | 65 |
SVNException { |
... | ... | @@ -218,7 +218,7 @@ |
218 | 218 |
return toView; |
219 | 219 |
} |
220 | 220 |
|
221 |
- @With(NullProjectCheckAction.class) |
|
221 |
+ @With(DefaultProjectCheckAction.class) |
|
222 | 222 |
@IsAllowed(value = Operation.DELETE, resourceType = ResourceType.COMMIT_COMMENT) |
223 | 223 |
public static Result deleteComment(String ownerName, String projectName, String commitId, |
224 | 224 |
Long id) { |
--- app/controllers/EnrollProjectApp.java
+++ app/controllers/EnrollProjectApp.java
... | ... | @@ -1,7 +1,7 @@ |
1 | 1 |
package controllers; |
2 | 2 |
|
3 | 3 |
import actions.AnonymousCheckAction; |
4 |
-import actions.NullProjectCheckAction; |
|
4 |
+import actions.DefaultProjectCheckAction; |
|
5 | 5 |
import models.NotificationEvent; |
6 | 6 |
import models.Project; |
7 | 7 |
import models.ProjectUser; |
... | ... | @@ -27,7 +27,7 @@ |
27 | 27 |
* @return |
28 | 28 |
*/ |
29 | 29 |
@Transactional |
30 |
- @With(NullProjectCheckAction.class) |
|
30 |
+ @With(DefaultProjectCheckAction.class) |
|
31 | 31 |
public static Result enroll(String loginId, String projectName) { |
32 | 32 |
Project project = Project.findByOwnerAndProjectName(loginId, projectName); |
33 | 33 |
|
... | ... | @@ -53,7 +53,7 @@ |
53 | 53 |
* @return |
54 | 54 |
*/ |
55 | 55 |
@Transactional |
56 |
- @With(NullProjectCheckAction.class) |
|
56 |
+ @With(DefaultProjectCheckAction.class) |
|
57 | 57 |
public static Result cancelEnroll(String loginId, String proejctName) { |
58 | 58 |
Project project = Project.findByOwnerAndProjectName(loginId, proejctName); |
59 | 59 |
|
--- app/controllers/IssueApp.java
+++ app/controllers/IssueApp.java
... | ... | @@ -1,6 +1,6 @@ |
1 | 1 |
package controllers; |
2 | 2 |
|
3 |
-import actions.NullProjectCheckAction; |
|
3 |
+import actions.DefaultProjectCheckAction; |
|
4 | 4 |
import actions.AnonymousCheckAction; |
5 | 5 |
import com.avaje.ebean.ExpressionList; |
6 | 6 |
import com.avaje.ebean.Page; |
... | ... | @@ -278,7 +278,7 @@ |
278 | 278 |
* @param number 이슈 번호 |
279 | 279 |
* @return |
280 | 280 |
*/ |
281 |
- @With(NullProjectCheckAction.class) |
|
281 |
+ @With(DefaultProjectCheckAction.class) |
|
282 | 282 |
public static Result issue(String ownerName, String projectName, Long number) { |
283 | 283 |
Project project = ProjectApp.getProject(ownerName, projectName); |
284 | 284 |
|
... | ... | @@ -380,7 +380,7 @@ |
380 | 380 |
* @throws IOException |
381 | 381 |
*/ |
382 | 382 |
@Transactional |
383 |
- @With(NullProjectCheckAction.class) |
|
383 |
+ @With(DefaultProjectCheckAction.class) |
|
384 | 384 |
public static Result massUpdate(String ownerName, String projectName) { |
385 | 385 |
Form<IssueMassUpdate> issueMassUpdateForm |
386 | 386 |
= new Form<>(IssueMassUpdate.class).bindFromRequest(); |
... | ... | @@ -642,7 +642,7 @@ |
642 | 642 |
* @throws IOException |
643 | 643 |
* @see {@link AbstractPostingApp#editPosting} |
644 | 644 |
*/ |
645 |
- @With(NullProjectCheckAction.class) |
|
645 |
+ @With(DefaultProjectCheckAction.class) |
|
646 | 646 |
public static Result editIssue(String ownerName, String projectName, Long number) { |
647 | 647 |
Form<Issue> issueForm = new Form<>(Issue.class).bindFromRequest(); |
648 | 648 |
|
... | ... | @@ -842,7 +842,7 @@ |
842 | 842 |
* @see {@link AbstractPostingApp#delete(play.db.ebean.Model, models.resource.Resource, Call)} |
843 | 843 |
*/ |
844 | 844 |
@Transactional |
845 |
- @With(NullProjectCheckAction.class) |
|
845 |
+ @With(DefaultProjectCheckAction.class) |
|
846 | 846 |
public static Result deleteComment(String ownerName, String projectName, Long issueNumber, |
847 | 847 |
Long commentId) { |
848 | 848 |
Comment comment = IssueComment.find.byId(commentId); |
--- app/controllers/ProjectApp.java
+++ app/controllers/ProjectApp.java
... | ... | @@ -1,7 +1,7 @@ |
1 | 1 |
package controllers; |
2 | 2 |
|
3 | 3 |
import actions.AnonymousCheckAction; |
4 |
-import actions.NullProjectCheckAction; |
|
4 |
+import actions.DefaultProjectCheckAction; |
|
5 | 5 |
|
6 | 6 |
import com.avaje.ebean.ExpressionList; |
7 | 7 |
import com.avaje.ebean.Junction; |
... | ... | @@ -655,7 +655,7 @@ |
655 | 655 |
* @return 프로젝트, 멤버목록, Role 목록 |
656 | 656 |
*/ |
657 | 657 |
@Transactional |
658 |
- @With(NullProjectCheckAction.class) |
|
658 |
+ @With(DefaultProjectCheckAction.class) |
|
659 | 659 |
public static Result newMember(String loginId, String projectName) { |
660 | 660 |
// TODO change into view validation |
661 | 661 |
Form<User> addMemberForm = form(User.class).bindFromRequest(); |
... | ... | @@ -712,7 +712,7 @@ |
712 | 712 |
* @return the result |
713 | 713 |
*/ |
714 | 714 |
@Transactional |
715 |
- @With(NullProjectCheckAction.class) |
|
715 |
+ @With(DefaultProjectCheckAction.class) |
|
716 | 716 |
public static Result deleteMember(String loginId, String projectName, Long userId) { |
717 | 717 |
Project project = Project.findByOwnerAndProjectName(loginId, projectName); |
718 | 718 |
|
... | ... | @@ -925,7 +925,7 @@ |
925 | 925 |
* @return the result |
926 | 926 |
*/ |
927 | 927 |
@Transactional |
928 |
- @With(NullProjectCheckAction.class) |
|
928 |
+ @With(DefaultProjectCheckAction.class) |
|
929 | 929 |
public static Result attachLabel(String ownerName, String projectName) { |
930 | 930 |
Project project = Project.findByOwnerAndProjectName(ownerName, projectName); |
931 | 931 |
|
... | ... | @@ -996,7 +996,7 @@ |
996 | 996 |
* @return the result |
997 | 997 |
*/ |
998 | 998 |
@Transactional |
999 |
- @With(NullProjectCheckAction.class) |
|
999 |
+ @With(DefaultProjectCheckAction.class) |
|
1000 | 1000 |
public static Result detachLabel(String ownerName, String projectName, Long id) { |
1001 | 1001 |
Project project = Project.findByOwnerAndProjectName(ownerName, projectName); |
1002 | 1002 |
|
--- app/controllers/StatisticsApp.java
+++ app/controllers/StatisticsApp.java
... | ... | @@ -1,6 +1,6 @@ |
1 | 1 |
package controllers; |
2 | 2 |
|
3 |
-import actions.NullProjectCheckAction; |
|
3 |
+import actions.DefaultProjectCheckAction; |
|
4 | 4 |
import models.Project; |
5 | 5 |
import play.mvc.Controller; |
6 | 6 |
import play.mvc.Result; |
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 |
|
10 | 10 |
public class StatisticsApp extends Controller { |
11 | 11 |
|
12 |
- @With(NullProjectCheckAction.class) |
|
12 |
+ @With(DefaultProjectCheckAction.class) |
|
13 | 13 |
public static Result statistics(String userName, String projectName) { |
14 | 14 |
Project project = Project.findByOwnerAndProjectName(userName, projectName); |
15 | 15 |
return ok(statistics.render("statistics", project)); |
--- docs/technical/validation-with-annotation.md
+++ docs/technical/validation-with-annotation.md
... | ... | @@ -11,6 +11,7 @@ |
11 | 11 |
* `@IsAllowed` |
12 | 12 |
* `@With(AnonymousCheckAction.class)` |
13 | 13 |
* `@With(NullProjectCheckAction.class)` |
14 |
+* `@With(DefaultProjectCheckAction.class)` |
|
14 | 15 |
|
15 | 16 |
Yobi에서 사용하는 인증 및 권한 검사 애노테이션은 다음과 같은 URL 패턴에만 적용할 수 있다. |
16 | 17 |
|
... | ... | @@ -18,12 +19,29 @@ |
18 | 19 |
|
19 | 20 |
`conf/application.conf`에 설정한 application.context가 있을 경우 해당 컨텍스트 패스를 제거한 URL 패턴에 적용된다. |
20 | 21 |
|
22 |
+## @With(DefaultProjectCheckAction.class) |
|
23 |
+ |
|
24 |
+이 애노테이션은 URL 패턴에 해당하는 프로젝트가 있는지 그리고 해당 프로젝트를 볼 수 있는 권한이 있는지 확인한다. |
|
25 |
+ |
|
26 |
+URL에 해당하는 프로젝트가 없거나 현재 사용자가 읽기 권한이 없을 때 403 Forbidden으로 응답한다. |
|
27 |
+ |
|
28 |
+### 사용예 |
|
29 |
+ |
|
30 |
+다음 코드는 URL 패턴에 해당하는 프로젝트가 있는지 확인한다. |
|
31 |
+ |
|
32 |
+``` |
|
33 |
+@With(DefaultProjectCheckAction.class) |
|
34 |
+public static Result editIssue(String ownerName, String projectName, Long number) { |
|
35 |
+ // 코드 생략 |
|
36 |
+} |
|
37 |
+``` |
|
38 |
+ |
|
21 | 39 |
## @IsOnlyGitAvailable |
22 | 40 |
|
23 |
-GIT 저장소를 사용하는 프로젝트인지 확인한다. |
|
41 |
+`@With(DefaultProjectCheckAction.class)`가 확인하는 작업에 추가로 GIT 저장소를 사용하는 프로젝트인지 확인한다. |
|
24 | 42 |
|
25 |
-URL 패턴에 해당하는 프로젝트가 없는 경우 응답으로 404 Not Found를 반환한다. |
|
26 |
-요청 핸들러에 이 애노테이션을 사용하면 GIT 저장소를 사용하지 않는 프로젝트는 응답으로 400 Bad Request를 반환한다. |
|
43 |
+URL에 해당하는 프로젝트가 없거나 현재 사용자가 읽기 권한이 없을 때 403 Forbidden으로 응답한다. |
|
44 |
+URL에 해당하는 프로젝트가 GIT 저장소를 사용하지 않는 프로젝트일 경우에는 응답으로 400 Bad Request를 반환한다. |
|
27 | 45 |
|
28 | 46 |
컨트롤러 클래스에 이 애노테이션을 사용하면 해당 컨트롤러의 모든 메서드에 적용된다. |
29 | 47 |
|
... | ... | @@ -40,10 +58,12 @@ |
40 | 58 |
|
41 | 59 |
## @IsCreatable |
42 | 60 |
|
43 |
-프로젝트에 특정 리소스 타입을 생성할 수 있는지 확인한다. |
|
61 |
+`@With(DefaultProjectCheckAction.class)`가 확인하는 작업에 추가로 현재 사용자가 프로젝트에 특정 리소스 타입을 생성할 수 있는지 확인한다. |
|
44 | 62 |
|
45 |
-URL 패턴에 해당하는 프로젝트가 없는 경우 응답으로 404 Not Found를 반환한다. |
|
46 |
-프로젝트에 해당 리소스를 생성할 권한이 없다면 응답으로 403 Forbidden을 반환한다. |
|
63 |
+다음의 경우 403 Forbidden으로 응답한다. |
|
64 |
+* URL에 해당하는 프로젝트가 없다. |
|
65 |
+* URL에 해당하는 프로젝트에 현재 사용자가 읽기 권한이 없다. |
|
66 |
+* URL에 해당하는 프로젝트에 해당 리소스를 생성할 권한이 없다. |
|
47 | 67 |
|
48 | 68 |
### 파라미터 |
49 | 69 |
|
... | ... | @@ -62,10 +82,12 @@ |
62 | 82 |
|
63 | 83 |
## @IsAllowed |
64 | 84 |
|
65 |
-특정 리소스에 특정 권한이 가능한지 확인한다. |
|
85 |
+`@With(DefaultProjectCheckAction.class)`가 확인하는 작업에 추가로 현재 사용자가 특정 리소스에 특정 권한이 가능한지 확인한다. |
|
66 | 86 |
|
67 |
-URL 패턴에 해당하는 프로젝트나 리소스가 없는 경우 응답으로 404 Not Found를 반환한다. |
|
68 |
-특정 리소스(`ResourceType`)에 특정 동작(`Operation`)이 가능하지 않을 경우 응답으로 403 Forbidden을 반환한다. |
|
87 |
+다음의 경우 403 Forbidden으로 응답한다. |
|
88 |
+* URL에 해당하는 프로젝트가 없다. |
|
89 |
+* URL에 해당하는 프로젝트에 현재 사용자가 읽기 권한이 없다. |
|
90 |
+* 현재 사용자에게 특정 리소스(`ResourceType`)에 특정 동작(`Operation`)을 허용하지 않는다. |
|
69 | 91 |
|
70 | 92 |
### 파라미터 |
71 | 93 |
|
... | ... | @@ -89,7 +111,6 @@ |
89 | 111 |
이밖에 필요한 리소스 타입이 있다면 `Resource.getResourceObject` 메서드에 코드를 추가해야 한다. |
90 | 112 |
|
91 | 113 |
### 사용예 |
92 |
- |
|
93 | 114 |
|
94 | 115 |
다음 코드는 resourceType을 명시하지 않았기 때문에 기본값인 PROJECT가 적용되어 현재 사용자가 PROJECT 리소스 타입에 READ 권한이 있는지 확인한다. |
95 | 116 |
|
... | ... | @@ -130,7 +151,7 @@ |
130 | 151 |
|
131 | 152 |
이 애노테이션은 URL 패턴에 해당하는 프로젝트가 있는지 확인한다. |
132 | 153 |
|
133 |
-URL 패턴에 해당하는 프로젝트가 없는 경우 응답으로 404 Not Found를 반환한다. |
|
154 |
+URL에 해당하는 프로젝트가 없을 때 403 Forbidden으로 응답한다. |
|
134 | 155 |
|
135 | 156 |
### 사용예 |
136 | 157 |
|
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?