@ -0,0 +1,41 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2002-2013 the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.security.samples.mvc.config; |
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.core.Ordered; |
||||||
|
import org.thymeleaf.spring3.SpringTemplateEngine; |
||||||
|
import org.thymeleaf.spring3.view.ThymeleafViewResolver; |
||||||
|
|
||||||
|
/** |
||||||
|
* Disable tiles so that we can provide our custom view without being decorated. |
||||||
|
* |
||||||
|
* @author Rob Winch |
||||||
|
* |
||||||
|
*/ |
||||||
|
@Configuration |
||||||
|
public class CustomMvcConfig { |
||||||
|
|
||||||
|
@Bean |
||||||
|
public ThymeleafViewResolver thymeleafViewResolver(SpringTemplateEngine templateEngine) { |
||||||
|
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver(); |
||||||
|
viewResolver.setOrder(Ordered.HIGHEST_PRECEDENCE - 10); |
||||||
|
viewResolver.setTemplateEngine(templateEngine); |
||||||
|
return viewResolver; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,158 @@ |
|||||||
|
<html xmlns:th="http://www.thymeleaf.org"> |
||||||
|
<head> |
||||||
|
<title>SecureMail</title> |
||||||
|
<link rel="icon" type="image/x-icon" th:href="@{/resources/img/favicon.ico}"/> |
||||||
|
<link th:href="@{/resources/css/bootstrap.css}" rel="stylesheet"></link> |
||||||
|
<style type="text/css"> |
||||||
|
/* Sticky footer styles |
||||||
|
-------------------------------------------------- */ |
||||||
|
|
||||||
|
html, |
||||||
|
body { |
||||||
|
height: 100%; |
||||||
|
/* The html and body elements cannot have any padding or margin. */ |
||||||
|
} |
||||||
|
|
||||||
|
/* Wrapper for page content to push down footer */ |
||||||
|
#wrap { |
||||||
|
min-height: 100%; |
||||||
|
height: auto !important; |
||||||
|
height: 100%; |
||||||
|
/* Negative indent footer by it's height */ |
||||||
|
margin: 0 auto -60px; |
||||||
|
} |
||||||
|
|
||||||
|
/* Set the fixed height of the footer here */ |
||||||
|
#push, |
||||||
|
#footer { |
||||||
|
height: 60px; |
||||||
|
} |
||||||
|
#footer { |
||||||
|
background-color: #f5f5f5; |
||||||
|
} |
||||||
|
|
||||||
|
/* Lastly, apply responsive CSS fixes as necessary */ |
||||||
|
@media (max-width: 767px) { |
||||||
|
#footer { |
||||||
|
margin-left: -20px; |
||||||
|
margin-right: -20px; |
||||||
|
padding-left: 20px; |
||||||
|
padding-right: 20px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Custom page CSS |
||||||
|
-------------------------------------------------- */ |
||||||
|
/* Not required for template or sticky footer method. */ |
||||||
|
|
||||||
|
.container { |
||||||
|
width: auto; |
||||||
|
max-width: 680px; |
||||||
|
} |
||||||
|
.container .credit { |
||||||
|
margin: 20px 0; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
a { |
||||||
|
color: green; |
||||||
|
} |
||||||
|
.navbar-form { |
||||||
|
margin-left: 1em; |
||||||
|
} |
||||||
|
</style> |
||||||
|
<link th:href="@{/resources/css/bootstrap-responsive.css}" rel="stylesheet"></link> |
||||||
|
|
||||||
|
<!-- HTML5 shim, for IE6-8 support of HTML5 elements --> |
||||||
|
<!--[if lt IE 9]> |
||||||
|
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> |
||||||
|
<![endif]--> |
||||||
|
<meta name="_csrf" th:content="${_csrf.token}"/> |
||||||
|
<meta name="_csrf_header" th:content="${_csrf.headerName}"/> |
||||||
|
</head> |
||||||
|
|
||||||
|
|
||||||
|
<body> |
||||||
|
<div id="wrap"> |
||||||
|
<div class="navbar navbar-inverse navbar-static-top"> |
||||||
|
<div class="navbar-inner"> |
||||||
|
<div class="container"> |
||||||
|
<a class="brand" th:href="@{/}"><img th:src="@{/resources/img/logo.png}" alt="Spring Security Sample"/></a> |
||||||
|
<div class="nav-collapse collapse"> |
||||||
|
<div th:if="${#httpServletRequest.remoteUser != null}"> |
||||||
|
<form class="navbar-form pull-right" th:action="@{/logout}" method="post"> |
||||||
|
<input type="submit" value="Log out" /> |
||||||
|
</form> |
||||||
|
<p class="navbar-text pull-right" th:text="${#httpServletRequest.remoteUser}"> |
||||||
|
sample_user |
||||||
|
</p> |
||||||
|
</div> |
||||||
|
<ul class="nav"> |
||||||
|
<li><a data-bind="click: $root.goToInbox" th:href="@{/}">Inbox</a></li> |
||||||
|
<li><a data-bind="click: $root.goToCompose" th:href="@{/(form)}">Compose</a></li> |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<!-- Begin page content --> |
||||||
|
<div class="container"> |
||||||
|
<div data-bind="with: inbox"> |
||||||
|
<h1>Inbox</h1> |
||||||
|
<table class="table"> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th>Created</th> |
||||||
|
<th>Summary</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody data-bind="foreach: $root.messages"> |
||||||
|
<tr data-bind="click: $root.goToMessage"> |
||||||
|
<td data-bind="text: created"></td> |
||||||
|
<td><a data-bind="text: summary, attr: { href: id}"></a></td> |
||||||
|
</tr> |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="container" data-bind="with: chosenMessageData"> |
||||||
|
<h1>Message : <span data-bind="text: summary"></span></h1> |
||||||
|
<dl> |
||||||
|
<dt>Created</dt> |
||||||
|
<dd data-bind="text: created"></dd> |
||||||
|
<dt>Message</dt> |
||||||
|
<dd data-bind="html: text"></dd> |
||||||
|
</dl> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="container" data-bind="with: compose"> |
||||||
|
<h1>Messages : Create</h1> |
||||||
|
<div class="alert alert-error" data-bind="foreach: $root.errors, visible: $root.errors().length"> |
||||||
|
<p data-bind="text: $data"></p> |
||||||
|
</div> |
||||||
|
<form action="./" method="post"> |
||||||
|
<label for="summary">Summary</label> |
||||||
|
<input type="text" id="summary" data-bind="value: summary" name="summary" class="input-xxlarge" /> |
||||||
|
<label for="text">Message</label> |
||||||
|
<textarea name="text" id="text" data-bind="value: text" class="input-xxlarge"><!-- --></textarea> |
||||||
|
<div class="form-actions"> |
||||||
|
<input type="button" data-bind="click: $root.save" value="Create" /> |
||||||
|
</div> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div id="push"><!-- --></div> |
||||||
|
</div> |
||||||
|
<div id="footer"> |
||||||
|
<div class="container"> |
||||||
|
<p class="muted credit">Visit the <a href="#">Spring Security</a> site for more <a href="#">samples</a>.</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<script type="text/javascript" th:src="@{/resources/js/jquery-1.8.3.js}"><!-- --></script> |
||||||
|
<script type="text/javascript" th:src="@{/resources/js/knockout-2.3.0.js}"><!-- --></script> |
||||||
|
<script type="text/javascript" th:src="@{/resources/js/message.js}"><!-- --></script> |
||||||
|
</body> |
||||||
|
</html> |
||||||
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 237 B |
|
After Width: | Height: | Size: 740 B |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
@ -0,0 +1,46 @@ |
|||||||
|
<html xmlns:th="http://www.thymeleaf.org" xmlns:tiles="http://www.thymeleaf.org"> |
||||||
|
<head> |
||||||
|
<title tiles:fragment="title">Messages : Login</title> |
||||||
|
<!-- /Simple OpenID Selector --> |
||||||
|
<link rel="stylesheet" th:href="@{/resources/css/openid.css}" /> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<div tiles:fragment="content"> |
||||||
|
<form name="f" th:action="@{/login/openid}" method="post" id="openid_form"> |
||||||
|
<input type="hidden" name="action" value="verify" /> |
||||||
|
<fieldset> |
||||||
|
<legend>Sign-in or Create New Account</legend> |
||||||
|
<div th:if="${param.error}" class="alert alert-error"> |
||||||
|
Invalid username and password. |
||||||
|
</div> |
||||||
|
<div th:if="${param.logout}" class="alert alert-success"> |
||||||
|
You have been logged out. |
||||||
|
</div> |
||||||
|
<div id="openid_choice"> |
||||||
|
<p>Please click your account provider:</p> |
||||||
|
<div id="openid_btns"></div> |
||||||
|
|
||||||
|
</div> |
||||||
|
|
||||||
|
<div id="openid_input_area"> |
||||||
|
<input id="openid_identifier" name="openid_identifier" type="text" value="http://" /> |
||||||
|
<input id="openid_submit" type="submit" value="Sign-In"/> |
||||||
|
</div> |
||||||
|
<noscript> |
||||||
|
<p>OpenID is a service that allows you to log-on to many different websites using a single identity. |
||||||
|
Find out <a href="http://openid.net/what/">more about OpenID</a> and <a href="http://openid.net/get/">how to get an OpenID enabled account</a>.</p> |
||||||
|
</noscript> |
||||||
|
</fieldset> |
||||||
|
</form> |
||||||
|
|
||||||
|
<script type="text/javascript" th:src="@{/resources/js/jquery-1.2.6.min.js}"><!-- --></script> |
||||||
|
<script type="text/javascript" th:src="@{/resources/js/openid-jquery.js}"><!-- --></script> |
||||||
|
<script type="text/javascript"> |
||||||
|
$(document).ready(function() { |
||||||
|
openid.init('openid_identifier'); |
||||||
|
// openid.setDemoMode(true); Stops form submission for client javascript-only test purposes |
||||||
|
}); |
||||||
|
</script> |
||||||
|
</div> |
||||||
|
</body> |
||||||
|
</html> |
||||||
@ -0,0 +1,34 @@ |
|||||||
|
<html xmlns:th="http://www.thymeleaf.org" xmlns:tiles="http://www.thymeleaf.org"> |
||||||
|
<head> |
||||||
|
<title tiles:fragment="title">Messages : Login</title> |
||||||
|
<!-- /Simple OpenID Selector --> |
||||||
|
<link rel="stylesheet" th:href="@{/resources/css/openid.css}" /> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<div tiles:fragment="content"> |
||||||
|
<h1>User Attributes</h1> |
||||||
|
<table class="table table-border"> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th>Attribute Name</th> |
||||||
|
<th>Attribute Value</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
<tr> |
||||||
|
<td>ID</td> |
||||||
|
<td th:text="${authentication.identityUrl}">https://example.com/user/id</td> |
||||||
|
</tr> |
||||||
|
<tr th:each="attribute : ${authentication.attributes}"> |
||||||
|
<td th:text="${attribute.name}">Attribute Name</td> |
||||||
|
<td> |
||||||
|
<dl th:each="value : ${attribute.values}"> |
||||||
|
<dd th:text="${value}">Attribute Value</dd> |
||||||
|
</dl> |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
</div> |
||||||
|
</body> |
||||||
|
</html> |
||||||
@ -0,0 +1,27 @@ |
|||||||
|
<html xmlns:th="http://www.thymeleaf.org" xmlns:tiles="http://www.thymeleaf.org"> |
||||||
|
<head> |
||||||
|
<title tiles:fragment="title">Messages : Create</title> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<div tiles:fragment="content"> |
||||||
|
<form name="f" th:action="@{/j_security_check}" method="post"> |
||||||
|
<fieldset> |
||||||
|
<legend>Please Login</legend> |
||||||
|
<div th:if="${param.error}" class="alert alert-error"> |
||||||
|
Invalid username and password. |
||||||
|
</div> |
||||||
|
<div th:if="${param.logout}" class="alert alert-success"> |
||||||
|
You have been logged out. |
||||||
|
</div> |
||||||
|
<label for="j_username">Username</label> |
||||||
|
<input type="text" id="j_username" name="j_username"/> |
||||||
|
<label for="j_password">Password</label> |
||||||
|
<input type="password" id="j_password" name="j_password"/> |
||||||
|
<div class="form-actions"> |
||||||
|
<button type="submit" class="btn">Log in</button> |
||||||
|
</div> |
||||||
|
</fieldset> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
</body> |
||||||
|
</html> |
||||||
@ -0,0 +1,29 @@ |
|||||||
|
<html xmlns:th="http://www.thymeleaf.org" xmlns:tiles="http://www.thymeleaf.org"> |
||||||
|
<head> |
||||||
|
<title tiles:fragment="title">Messages : Create</title> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<div tiles:fragment="content"> |
||||||
|
<form name="f" th:action="@{/login}" method="post"> |
||||||
|
<fieldset> |
||||||
|
<legend>Please Login</legend> |
||||||
|
<div th:if="${param.error}" class="alert alert-error"> |
||||||
|
Invalid username and password. |
||||||
|
</div> |
||||||
|
<div th:if="${param.logout}" class="alert alert-success"> |
||||||
|
You have been logged out. |
||||||
|
</div> |
||||||
|
<label for="username">Username</label> |
||||||
|
<input type="text" id="username" name="username"/> |
||||||
|
<label for="password">Password</label> |
||||||
|
<input type="password" id="password" name="password"/> |
||||||
|
<label for="remember-me">Remember Me?</label> |
||||||
|
<input type="checkbox" id="remember-me" name="remember-me"/> |
||||||
|
<div class="form-actions"> |
||||||
|
<button type="submit" class="btn">Log in</button> |
||||||
|
</div> |
||||||
|
</fieldset> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
</body> |
||||||
|
</html> |
||||||