Skip to content

Commit 839b331

Browse files
committed
Add page for 403 error.
Fix GH #87
1 parent b58dc38 commit 839b331

File tree

12 files changed

+343
-1
lines changed

12 files changed

+343
-1
lines changed

src/main/config/checkstyle-suppressions.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<suppress checks="LineLength" files="AbstractPage.java" lines="44,45" />
99
<suppress checks="LineLength" files="AbstractPageWithForm.java" lines="27,28,33" />
1010
<suppress checks="LineLength" files="Form.java" lines="31,32,37" />
11-
<suppress checks="LineLength" files="Url.java" lines="73" />
11+
<suppress checks="LineLength" files="Url.java" lines="74" />
1212
<suppress checks="LineLength" files="ErrorController.java" lines="73" />
1313
<suppress checks="LineLength" files="SecurityConfig.java" lines="36,37,40,41" />
1414
<suppress checks="LineLength" files="JdbcSeriesDaoImpl.java" lines="125" />

src/main/java/ru/mystamps/web/Url.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public final class Url {
6363

6464
// see also error-page definitions at src/main/webapp/WEB-INF/web.xml
6565
public static final String UNAUTHORIZED_PAGE = "/error/401";
66+
public static final String FORBIDDEN_PAGE = "/error/403";
6667
public static final String NOT_FOUND_PAGE = "/error/404";
6768
public static final String INTERNAL_ERROR_PAGE = "/error/500";
6869

src/main/java/ru/mystamps/web/config/MvcConfig.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public void configureDefaultServletHandling(DefaultServletHandlerConfigurer conf
7272
public void addViewControllers(ViewControllerRegistry registry) {
7373
registry.addViewController(Url.AUTHENTICATION_PAGE);
7474
registry.addViewController(Url.UNAUTHORIZED_PAGE);
75+
registry.addViewController(Url.FORBIDDEN_PAGE);
7576
}
7677

7778
@Override

src/main/resources/ru/mystamps/i18n/Messages.properties

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ t_register = Register
5858
t_401_title = 401: unauthorized
5959
t_401_description = Authorization required{0}to access page
6060

61+
# error/403.html
62+
t_403_title = 403: forbidden
63+
t_403_description = Forbidden
64+
6165
# error/404.html
6266
t_404_title = 404: page not found
6367
t_404_description = Requested page{0}not found

src/main/resources/ru/mystamps/i18n/Messages_ru.properties

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ t_register = Зарегистрироваться
5858
t_401_title = 401: не авторизован
5959
t_401_description = Необходима авторизация{0}для доступа к странице
6060

61+
# error/403.html
62+
t_403_title = 403: доступ запрещён
63+
t_403_description = Доступ запрещён
64+
6165
# error/404.html
6266
t_404_title = 404: страница не найдена
6367
t_404_description = Запрашиваемая страница{0}не найдена
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<!DOCTYPE html>
2+
<html xmlns="http://www.w3.org/1999/xhtml"
3+
xmlns:th="http://www.thymeleaf.org"
4+
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
5+
<head>
6+
<meta charset="utf-8" />
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
8+
<meta name="robots" content="noindex" />
9+
<title th:text="#{t_403_title}">403: forbidden</title>
10+
<link rel="shortcut icon" type="image/x-icon" href="../../../favicon.ico" th:href="${FAVICON_ICO}" />
11+
<link rel="stylesheet" href="http://yandex.st/bootstrap/2.3.1/css/bootstrap.min.css" th:href="${BOOTSTRAP_CSS}" />
12+
<link rel="stylesheet" href="http://yandex.st/bootstrap/2.3.1/css/bootstrap-responsive.min.css" th:href="${BOOTSTRAP_RESPONSIVE_CSS}" />
13+
<link rel="stylesheet" href="../../static/styles/main.css" th:href="${MAIN_CSS}" />
14+
</head>
15+
<body lang="en" th:lang="${#locale.language == 'ru' ? 'ru' : 'en'}">
16+
<div class="row-fluid" id="header">
17+
<div id="logo" class="span10">
18+
<a href="../site/index.html" th:href="'/'" th:text="#{t_my_stamps}">My stamps</a>
19+
</div>
20+
21+
<div id="user_bar" class="span2">
22+
<ul class="unstyled">
23+
<!--/*/
24+
<li sec:authorize="isAuthenticated()">
25+
<i class="icon-user"></i>
26+
<a sec:authentication="principal.user.name"
27+
href="../collection/info.html"
28+
title="Open my collection"
29+
th:title="#{t_open_my_collection}"
30+
th:href="@{${INFO_COLLECTION_PAGE}(id=${#authentication.principal.user.collection.id},slug=${#authentication.principal.user.collection.slug})}">
31+
John Doe
32+
</a>
33+
</li>
34+
/*/-->
35+
<li sec:authorize="isAnonymous()">
36+
<a href="../account/auth.html" th:href="@{${AUTHENTICATION_PAGE}}" th:text="#{t_enter}">Sign in</a>
37+
</li>
38+
<!--/*/
39+
<li sec:authorize="isAuthenticated()">
40+
<form id="LogoutForm" method="get" action="../site/index.html" class="no-margin" th:method="post" th:action="@{${LOGOUT_PAGE}}">
41+
<i class="icon-share"></i>&nbsp;<input type="submit" value="Sign out" class="btn btn-link no-padding" th:value="#{t_logout}" />
42+
</form>
43+
</li>
44+
/*/-->
45+
<li sec:authorize="isAnonymous()">
46+
<a href="../account/register.html" th:href="@{${REGISTRATION_PAGE}}" th:text="#{t_register}">Register</a>
47+
</li>
48+
</ul>
49+
</div>
50+
</div>
51+
52+
<div class="row-fluid text-center">
53+
<div id="content" class="span12">
54+
<h1 id="error-code">
55+
403
56+
</h1>
57+
<h4 id="error-msg" th:text="#{t_403_description}">
58+
Forbidden
59+
</h4>
60+
</div>
61+
</div>
62+
63+
<div class="row-fluid">
64+
<footer class="text-right">
65+
<i class="icon-envelope"></i>
66+
<a href="mailto:[email protected]" title="Write e-mail" th:href="|mailto:#{t_site_author_email}|" th:title="#{t_write_email}" th:text="#{t_site_author_name}">Slava Semushin</a>, 2009-2015
67+
</footer>
68+
</div>
69+
70+
<!-- Placed at the end of the document so the pages load faster -->
71+
<script src="http://yandex.st/bootstrap/2.3.1/js/bootstrap.min.js" th:src="${BOOTSTRAP_JS}"></script>
72+
</body>
73+
</html>

src/main/webapp/WEB-INF/web.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@
7474
<location>/error/401</location>
7575
</error-page>
7676

77+
<error-page>
78+
<error-code>403</error-code>
79+
<location>/error/403</location>
80+
</error-page>
81+
7782
<error-page>
7883
<error-code>404</error-code>
7984
<location>/error/404</location>

src/test/config/testng.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,24 @@
139139
</classes>
140140
</test>
141141

142+
<test name="When anonymous user at forbidden page">
143+
<classes>
144+
<class name="ru.mystamps.web.tests.cases.WhenAnonymousUserAtForbiddenPage" />
145+
</classes>
146+
</test>
147+
148+
<test name="When anonymous user open Togglz console">
149+
<classes>
150+
<class name="ru.mystamps.web.tests.cases.WhenAnonymousUserOpenTogglzConsole" />
151+
</classes>
152+
</test>
153+
154+
<test name="When user open Togglz console">
155+
<classes>
156+
<class name="ru.mystamps.web.tests.cases.WhenUserOpenTogglzConsole" />
157+
</classes>
158+
</test>
159+
142160
<test name="When anonymous user register account">
143161
<classes>
144162
<class name="ru.mystamps.web.tests.cases.WhenAnonymousUserRegisterAccount" />
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright (C) 2009-2015 Slava Semushin <[email protected]>
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17+
*/
18+
package ru.mystamps.web.tests.cases;
19+
20+
import java.net.HttpURLConnection;
21+
22+
import org.testng.annotations.BeforeClass;
23+
import org.testng.annotations.Test;
24+
25+
import static org.fest.assertions.api.Assertions.assertThat;
26+
27+
import ru.mystamps.web.tests.page.ForbiddenErrorPage;
28+
29+
import ru.mystamps.web.Url;
30+
31+
import static ru.mystamps.web.tests.TranslationUtils.tr;
32+
33+
public class WhenAnonymousUserAtForbiddenPage
34+
extends WhenAnyUserAtAnyPage<ForbiddenErrorPage> {
35+
36+
public WhenAnonymousUserAtForbiddenPage() {
37+
super(ForbiddenErrorPage.class);
38+
hasTitleWithoutStandardPrefix(tr("t_403_title"));
39+
hasResponseServerCode(HttpURLConnection.HTTP_FORBIDDEN);
40+
}
41+
42+
@BeforeClass
43+
public void setUp() {
44+
page.open(Url.FORBIDDEN_PAGE);
45+
}
46+
47+
@Test(groups = "std")
48+
public void shouldHaveStandardStructure() {
49+
checkStandardStructure();
50+
}
51+
52+
@Test(groups = "misc", dependsOnGroups = "std")
53+
public void shouldExistsErrorMessage() {
54+
assertThat(page.getErrorMessage()).isEqualTo(tr("t_403_description"));
55+
}
56+
57+
@Test(groups = "misc", dependsOnGroups = "std")
58+
public void shouldExistsErrorCode() {
59+
assertThat(page.getErrorCode()).isEqualTo("403");
60+
}
61+
62+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (C) 2009-2015 Slava Semushin <[email protected]>
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17+
*/
18+
package ru.mystamps.web.tests.cases;
19+
20+
import java.net.HttpURLConnection;
21+
22+
import org.testng.annotations.BeforeClass;
23+
import org.testng.annotations.Test;
24+
25+
import ru.mystamps.web.tests.page.ForbiddenErrorPage;
26+
27+
import static ru.mystamps.web.tests.TranslationUtils.tr;
28+
29+
import static org.fest.assertions.api.Assertions.assertThat;
30+
31+
public class WhenAnonymousUserOpenTogglzConsole extends WhenAnyUserAtAnyPage<ForbiddenErrorPage> {
32+
33+
public WhenAnonymousUserOpenTogglzConsole() {
34+
super(ForbiddenErrorPage.class);
35+
hasTitleWithoutStandardPrefix(tr("t_403_title"));
36+
hasResponseServerCode(HttpURLConnection.HTTP_FORBIDDEN);
37+
}
38+
39+
@BeforeClass
40+
public void setUp() {
41+
page.open("/togglz");
42+
}
43+
44+
@Test(groups = "std")
45+
public void shouldHaveStandardStructure() {
46+
checkStandardStructure();
47+
}
48+
49+
@Test(groups = "misc", dependsOnGroups = "std")
50+
public void shouldExistsErrorMessage() {
51+
assertThat(page.getErrorMessage()).isEqualTo(tr("t_403_description"));
52+
}
53+
54+
@Test(groups = "misc", dependsOnGroups = "std")
55+
public void shouldExistsErrorCode() {
56+
assertThat(page.getErrorCode()).isEqualTo("403");
57+
}
58+
59+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright (C) 2009-2015 Slava Semushin <[email protected]>
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17+
*/
18+
package ru.mystamps.web.tests.cases;
19+
20+
import java.net.HttpURLConnection;
21+
22+
import org.testng.annotations.AfterClass;
23+
import org.testng.annotations.BeforeClass;
24+
import org.testng.annotations.Test;
25+
26+
import org.springframework.beans.factory.annotation.Value;
27+
28+
import ru.mystamps.web.tests.page.ForbiddenErrorPage;
29+
30+
import static ru.mystamps.web.tests.TranslationUtils.tr;
31+
32+
import static org.fest.assertions.api.Assertions.assertThat;
33+
34+
public class WhenUserOpenTogglzConsole extends WhenAnyUserAtAnyPage<ForbiddenErrorPage> {
35+
36+
@Value("${valid_user_login}")
37+
private String validUserLogin;
38+
39+
@Value("${valid_user_password}")
40+
private String validUserPassword;
41+
42+
public WhenUserOpenTogglzConsole() {
43+
super(ForbiddenErrorPage.class);
44+
hasTitleWithoutStandardPrefix(tr("t_403_title"));
45+
hasResponseServerCode(HttpURLConnection.HTTP_FORBIDDEN);
46+
}
47+
48+
@BeforeClass
49+
public void setUp() {
50+
page.login(validUserLogin, validUserPassword);
51+
page.open("/togglz");
52+
}
53+
54+
@AfterClass(alwaysRun = true)
55+
public void tearDown() {
56+
page.logout();
57+
}
58+
59+
@Test(groups = "std")
60+
public void shouldHaveStandardStructure() {
61+
checkStandardStructure();
62+
}
63+
64+
@Test(groups = "misc", dependsOnGroups = "std")
65+
public void shouldExistsErrorMessage() {
66+
assertThat(page.getErrorMessage()).isEqualTo(tr("t_403_description"));
67+
}
68+
69+
@Test(groups = "misc", dependsOnGroups = "std")
70+
public void shouldExistsErrorCode() {
71+
assertThat(page.getErrorCode()).isEqualTo("403");
72+
}
73+
74+
@Override
75+
protected void shouldHaveUserBar() {
76+
// Ignore this check because when user authenticated there is no links for login/register.
77+
}
78+
79+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (C) 2009-2015 Slava Semushin <[email protected]>
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17+
*/
18+
package ru.mystamps.web.tests.page;
19+
20+
import org.openqa.selenium.WebDriver;
21+
22+
public class ForbiddenErrorPage extends AbstractPage {
23+
24+
public ForbiddenErrorPage(WebDriver driver) {
25+
super(driver, "/togglz");
26+
}
27+
28+
public String getErrorMessage() {
29+
return getTextOfElementById("error-msg");
30+
}
31+
32+
public String getErrorCode() {
33+
return getTextOfElementById("error-code");
34+
}
35+
36+
}

0 commit comments

Comments
 (0)