Skip to content

Commit 7d83e93

Browse files
committed
Render default UIs using lightweight templates
1 parent 9f24fad commit 7d83e93

File tree

9 files changed

+1089
-402
lines changed

9 files changed

+1089
-402
lines changed

config/src/test/java/org/springframework/security/config/annotation/web/configurers/DefaultLoginPageConfigurerTests.java

Lines changed: 167 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -67,140 +67,140 @@
6767
@ExtendWith(SpringTestContextExtension.class)
6868
public class DefaultLoginPageConfigurerTests {
6969

70-
//@formatter:off
71-
public static final String EXPECTED_HTML_HEAD = " <head>\n"
72-
+ " <meta charset=\"utf-8\">\n"
73-
+ " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n"
74-
+ " <meta name=\"description\" content=\"\">\n"
75-
+ " <meta name=\"author\" content=\"\">\n"
76-
+ " <title>Please sign in</title>\n"
77-
+ " <style>\n"
78-
+ " /* General layout */\n"
79-
+ " body {\n"
80-
+ " font-family: system-ui, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n"
81-
+ " background-color: #eee;\n"
82-
+ " padding: 40px 0;\n"
83-
+ " margin: 0;\n"
84-
+ " line-height: 1.5;\n"
85-
+ " }\n"
86-
+ " \n"
87-
+ " h2 {\n"
88-
+ " margin-top: 0;\n"
89-
+ " margin-bottom: 0.5rem;\n"
90-
+ " font-size: 2rem;\n"
91-
+ " font-weight: 500;\n"
92-
+ " line-height: 2rem;\n"
93-
+ " }\n"
94-
+ " \n"
95-
+ " .content {\n"
96-
+ " margin-right: auto;\n"
97-
+ " margin-left: auto;\n"
98-
+ " padding-right: 15px;\n"
99-
+ " padding-left: 15px;\n"
100-
+ " width: 100%;\n"
101-
+ " box-sizing: border-box;\n"
102-
+ " }\n"
103-
+ " \n"
104-
+ " @media (min-width: 800px) {\n"
105-
+ " .content {\n"
106-
+ " max-width: 760px;\n"
107-
+ " }\n"
108-
+ " }\n"
109-
+ " \n"
110-
+ " /* Components */\n"
111-
+ " a,\n"
112-
+ " a:visited {\n"
113-
+ " text-decoration: none;\n"
114-
+ " color: #06f;\n"
115-
+ " }\n"
116-
+ " \n"
117-
+ " a:hover {\n"
118-
+ " text-decoration: underline;\n"
119-
+ " color: #003c97;\n"
120-
+ " }\n"
121-
+ " \n"
122-
+ " input[type=\"text\"],\n"
123-
+ " input[type=\"password\"] {\n"
124-
+ " height: auto;\n"
125-
+ " width: 100%;\n"
126-
+ " font-size: 1rem;\n"
127-
+ " padding: 0.5rem;\n"
128-
+ " box-sizing: border-box;\n"
129-
+ " }\n"
130-
+ " \n"
131-
+ " button {\n"
132-
+ " padding: 0.5rem 1rem;\n"
133-
+ " font-size: 1.25rem;\n"
134-
+ " line-height: 1.5;\n"
135-
+ " border: none;\n"
136-
+ " border-radius: 0.1rem;\n"
137-
+ " width: 100%;\n"
138-
+ " }\n"
139-
+ " \n"
140-
+ " button.primary {\n"
141-
+ " color: #fff;\n"
142-
+ " background-color: #06f;\n"
143-
+ " }\n"
144-
+ " \n"
145-
+ " .alert {\n"
146-
+ " padding: 0.75rem 1rem;\n"
147-
+ " margin-bottom: 1rem;\n"
148-
+ " line-height: 1.5;\n"
149-
+ " border-radius: 0.1rem;\n"
150-
+ " width: 100%;\n"
151-
+ " box-sizing: border-box;\n"
152-
+ " border-width: 1px;\n"
153-
+ " border-style: solid;\n"
154-
+ " }\n"
155-
+ " \n"
156-
+ " .alert.alert-danger {\n"
157-
+ " color: #6b1922;\n"
158-
+ " background-color: #f7d5d7;\n"
159-
+ " border-color: #eab6bb;\n"
160-
+ " }\n"
161-
+ " \n"
162-
+ " .alert.alert-success {\n"
163-
+ " color: #145222;\n"
164-
+ " background-color: #d1f0d9;\n"
165-
+ " border-color: #c2ebcb;\n"
166-
+ " }\n"
167-
+ " \n"
168-
+ " .screenreader {\n"
169-
+ " position: absolute;\n"
170-
+ " clip: rect(0 0 0 0);\n"
171-
+ " height: 1px;\n"
172-
+ " width: 1px;\n"
173-
+ " padding: 0;\n"
174-
+ " border: 0;\n"
175-
+ " overflow: hidden;\n"
176-
+ " }\n"
177-
+ " \n"
178-
+ " table {\n"
179-
+ " width: 100%;\n"
180-
+ " max-width: 100%;\n"
181-
+ " margin-bottom: 2rem;\n"
182-
+ " }\n"
183-
+ " \n"
184-
+ " .table-striped tr:nth-of-type(2n + 1) {\n"
185-
+ " background-color: #e1e1e1;\n"
186-
+ " }\n"
187-
+ " \n"
188-
+ " td {\n"
189-
+ " padding: 0.75rem;\n"
190-
+ " vertical-align: top;\n"
191-
+ " }\n"
192-
+ " \n"
193-
+ " /* Login / logout layouts */\n"
194-
+ " .login-form,\n"
195-
+ " .logout-form {\n"
196-
+ " max-width: 340px;\n"
197-
+ " padding: 0 15px 15px 15px;\n"
198-
+ " margin: 0 auto 2rem auto;\n"
199-
+ " box-sizing: border-box;\n"
200-
+ " }\n"
201-
+ " </style>\n"
202-
+ " </head>\n";
203-
//@formatter:on
70+
public static final String EXPECTED_HTML_HEAD = """
71+
<head>
72+
<meta charset="utf-8">
73+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
74+
<meta name="description" content="">
75+
<meta name="author" content="">
76+
<title>Please sign in</title>
77+
<style>
78+
/* General layout */
79+
body {
80+
font-family: system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
81+
background-color: #eee;
82+
padding: 40px 0;
83+
margin: 0;
84+
line-height: 1.5;
85+
}
86+
\s
87+
h2 {
88+
margin-top: 0;
89+
margin-bottom: 0.5rem;
90+
font-size: 2rem;
91+
font-weight: 500;
92+
line-height: 2rem;
93+
}
94+
\s
95+
.content {
96+
margin-right: auto;
97+
margin-left: auto;
98+
padding-right: 15px;
99+
padding-left: 15px;
100+
width: 100%;
101+
box-sizing: border-box;
102+
}
103+
\s
104+
@media (min-width: 800px) {
105+
.content {
106+
max-width: 760px;
107+
}
108+
}
109+
\s
110+
/* Components */
111+
a,
112+
a:visited {
113+
text-decoration: none;
114+
color: #06f;
115+
}
116+
\s
117+
a:hover {
118+
text-decoration: underline;
119+
color: #003c97;
120+
}
121+
\s
122+
input[type="text"],
123+
input[type="password"] {
124+
height: auto;
125+
width: 100%;
126+
font-size: 1rem;
127+
padding: 0.5rem;
128+
box-sizing: border-box;
129+
}
130+
\s
131+
button {
132+
padding: 0.5rem 1rem;
133+
font-size: 1.25rem;
134+
line-height: 1.5;
135+
border: none;
136+
border-radius: 0.1rem;
137+
width: 100%;
138+
}
139+
\s
140+
button.primary {
141+
color: #fff;
142+
background-color: #06f;
143+
}
144+
\s
145+
.alert {
146+
padding: 0.75rem 1rem;
147+
margin-bottom: 1rem;
148+
line-height: 1.5;
149+
border-radius: 0.1rem;
150+
width: 100%;
151+
box-sizing: border-box;
152+
border-width: 1px;
153+
border-style: solid;
154+
}
155+
\s
156+
.alert.alert-danger {
157+
color: #6b1922;
158+
background-color: #f7d5d7;
159+
border-color: #eab6bb;
160+
}
161+
\s
162+
.alert.alert-success {
163+
color: #145222;
164+
background-color: #d1f0d9;
165+
border-color: #c2ebcb;
166+
}
167+
\s
168+
.screenreader {
169+
position: absolute;
170+
clip: rect(0 0 0 0);
171+
height: 1px;
172+
width: 1px;
173+
padding: 0;
174+
border: 0;
175+
overflow: hidden;
176+
}
177+
\s
178+
table {
179+
width: 100%;
180+
max-width: 100%;
181+
margin-bottom: 2rem;
182+
}
183+
\s
184+
.table-striped tr:nth-of-type(2n + 1) {
185+
background-color: #e1e1e1;
186+
}
187+
\s
188+
td {
189+
padding: 0.75rem;
190+
vertical-align: top;
191+
}
192+
\s
193+
/* Login / logout layouts */
194+
.login-form,
195+
.logout-form {
196+
max-width: 340px;
197+
padding: 0 15px 15px 15px;
198+
margin: 0 auto 2rem auto;
199+
box-sizing: border-box;
200+
}
201+
</style>
202+
</head>
203+
""";
204204

205205
public final SpringTestContext spring = new SpringTestContext(this);
206206

@@ -226,9 +226,10 @@ public void loginPageThenDefaultLoginPageIsRendered() throws Exception {
226226
+ "<html lang=\"en\">\n"
227227
+ EXPECTED_HTML_HEAD
228228
+ " <body>\n"
229-
+ " <div class=\"content\">\n"
229+
+ " <div class=\"content\">\n"
230230
+ " <form class=\"login-form\" method=\"post\" action=\"/login\">\n"
231231
+ " <h2>Please sign in</h2>\n"
232+
+ " \n"
232233
+ " <p>\n"
233234
+ " <label for=\"username\" class=\"screenreader\">Username</label>\n"
234235
+ " <input type=\"text\" id=\"username\" name=\"username\" placeholder=\"Username\" required autofocus>\n"
@@ -237,11 +238,15 @@ public void loginPageThenDefaultLoginPageIsRendered() throws Exception {
237238
+ " <label for=\"password\" class=\"screenreader\">Password</label>\n"
238239
+ " <input type=\"password\" id=\"password\" name=\"password\" placeholder=\"Password\" required>\n"
239240
+ " </p>\n"
241+
+ "\n"
240242
+ "<input name=\"" + token.getParameterName() + "\" type=\"hidden\" value=\"" + token.getToken() + "\" />\n"
241243
+ " <button type=\"submit\" class=\"primary\">Sign in</button>\n"
242244
+ " </form>\n"
243-
+ "</div>\n"
244-
+ "</body></html>");
245+
+ "\n"
246+
+ "\n"
247+
+ " </div>\n"
248+
+ " </body>\n"
249+
+ "</html>");
245250
});
246251
// @formatter:on
247252
}
@@ -267,21 +272,26 @@ public void loginPageWhenErrorThenDefaultLoginPageWithError() throws Exception {
267272
+ "<html lang=\"en\">\n"
268273
+ EXPECTED_HTML_HEAD
269274
+ " <body>\n"
270-
+ " <div class=\"content\">\n"
275+
+ " <div class=\"content\">\n"
271276
+ " <form class=\"login-form\" method=\"post\" action=\"/login\">\n"
272277
+ " <h2>Please sign in</h2>\n"
273-
+ "<div class=\"alert alert-danger\" role=\"alert\">Bad credentials</div> <p>\n"
278+
+ " <div class=\"alert alert-danger\" role=\"alert\">Bad credentials</div>\n"
279+
+ " <p>\n"
274280
+ " <label for=\"username\" class=\"screenreader\">Username</label>\n"
275281
+ " <input type=\"text\" id=\"username\" name=\"username\" placeholder=\"Username\" required autofocus>\n"
276282
+ " </p>\n" + " <p>\n"
277283
+ " <label for=\"password\" class=\"screenreader\">Password</label>\n"
278284
+ " <input type=\"password\" id=\"password\" name=\"password\" placeholder=\"Password\" required>\n"
279285
+ " </p>\n"
286+
+ "\n"
280287
+ "<input name=\"" + token.getParameterName() + "\" type=\"hidden\" value=\"" + token.getToken() + "\" />\n"
281288
+ " <button type=\"submit\" class=\"primary\">Sign in</button>\n"
282289
+ " </form>\n"
283-
+ "</div>\n"
284-
+ "</body></html>");
290+
+ "\n"
291+
+ "\n"
292+
+ " </div>\n"
293+
+ " </body>\n"
294+
+ "</html>");
285295
});
286296
// @formatter:on
287297
}
@@ -311,22 +321,27 @@ public void loginPageWhenLoggedOutThenDefaultLoginPageWithLogoutMessage() throws
311321
+ "<html lang=\"en\">\n"
312322
+ EXPECTED_HTML_HEAD
313323
+ " <body>\n"
314-
+ " <div class=\"content\">\n"
324+
+ " <div class=\"content\">\n"
315325
+ " <form class=\"login-form\" method=\"post\" action=\"/login\">\n"
316326
+ " <h2>Please sign in</h2>\n"
317-
+ "<div class=\"alert alert-success\" role=\"alert\">You have been signed out</div> <p>\n"
327+
+ " <div class=\"alert alert-success\" role=\"alert\">You have been signed out</div>\n"
328+
+ " <p>\n"
318329
+ " <label for=\"username\" class=\"screenreader\">Username</label>\n"
319330
+ " <input type=\"text\" id=\"username\" name=\"username\" placeholder=\"Username\" required autofocus>\n"
320331
+ " </p>\n"
321332
+ " <p>\n"
322333
+ " <label for=\"password\" class=\"screenreader\">Password</label>\n"
323334
+ " <input type=\"password\" id=\"password\" name=\"password\" placeholder=\"Password\" required>\n"
324335
+ " </p>\n"
336+
+ "\n"
325337
+ "<input name=\"" + token.getParameterName() + "\" type=\"hidden\" value=\"" + token.getToken() + "\" />\n"
326338
+ " <button type=\"submit\" class=\"primary\">Sign in</button>\n"
327339
+ " </form>\n"
328-
+ "</div>\n"
329-
+ "</body></html>");
340+
+ "\n"
341+
+ "\n"
342+
+ " </div>\n"
343+
+ " </body>\n"
344+
+ "</html>");
330345
});
331346
// @formatter:on
332347
}
@@ -356,9 +371,10 @@ public void loginPageWhenRememberConfigureThenDefaultLoginPageWithRememberMeChec
356371
+ "<html lang=\"en\">\n"
357372
+ EXPECTED_HTML_HEAD
358373
+ " <body>\n"
359-
+ " <div class=\"content\">\n"
374+
+ " <div class=\"content\">\n"
360375
+ " <form class=\"login-form\" method=\"post\" action=\"/login\">\n"
361376
+ " <h2>Please sign in</h2>\n"
377+
+ " \n"
362378
+ " <p>\n"
363379
+ " <label for=\"username\" class=\"screenreader\">Username</label>\n"
364380
+ " <input type=\"text\" id=\"username\" name=\"username\" placeholder=\"Username\" required autofocus>\n"
@@ -371,8 +387,11 @@ public void loginPageWhenRememberConfigureThenDefaultLoginPageWithRememberMeChec
371387
+ "<input name=\"" + token.getParameterName() + "\" type=\"hidden\" value=\"" + token.getToken() + "\" />\n"
372388
+ " <button type=\"submit\" class=\"primary\">Sign in</button>\n"
373389
+ " </form>\n"
374-
+ "</div>\n"
375-
+ "</body></html>");
390+
+ "\n"
391+
+ "\n"
392+
+ " </div>\n"
393+
+ " </body>\n"
394+
+ "</html>");
376395
});
377396
// @formatter:on
378397
}

0 commit comments

Comments
 (0)