Merge pull request #22 from stianst/master

Changed SaaS to use login form from sdk-html
This commit is contained in:
stianst 2013-08-06 03:12:39 -07:00
commit 6b00a538f2
16 changed files with 956 additions and 501 deletions

View file

@ -20,7 +20,7 @@
<!-- <select class="nav pull-left" ng-options="r.name for r in current.realms"></select> --> <!-- <select class="nav pull-left" ng-options="r.name for r in current.realms"></select> -->
</div> </div>
<ul class="nav pull-right" data-ng-hide="auth.loggedIn"> <ul class="nav pull-right" data-ng-hide="auth.loggedIn">
<li><a href="/auth-server/saas/saas-login.jsp">Login</a></li> <li><a href="/auth-server/rest/saas/login">Login</a></li>
<li><a href="/auth-server/saas/saas-register.jsp">Register</a></li> <li><a href="/auth-server/saas/saas-register.jsp">Register</a></li>
</ul> </ul>
<ul class="nav pull-right" data-ng-show="auth.loggedIn"> <ul class="nav pull-right" data-ng-show="auth.loggedIn">

View file

@ -1,82 +0,0 @@
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%><!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Log in to Keycloak</title>
<link rel="stylesheet" href="<%=application.getContextPath()%>/saas/css/reset.css">
<link rel="stylesheet" type="text/css" href="<%=application.getContextPath()%>/saas/css/base.css">
<link rel="stylesheet" type="text/css" href="<%=application.getContextPath()%>/saas/css/forms.css">
<link rel="stylesheet" type="text/css" href="<%=application.getContextPath()%>/saas/css/zocial/zocial.css">
<link rel="stylesheet" type="text/css" href="<%=application.getContextPath()%>/saas/css/login-screen.css">
<link rel="stylesheet" type="text/css" href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic,800,800italic'>
</head>
<body class="rcue-login-register">
<h1><a href="#" title="Go to the home page"><img src="<%=application.getContextPath()%>/saas/img/red-hat-logo.png" alt="Red Hat logo"></a></h1>
<div class="content">
<h2>Log in to <strong>Keycloak</strong></h2>
<div class="background-area">
<div class="form-area social clearfix">
<section class="app-form">
<h3>Application login area</h3>
<form action="<%=application.getContextPath()%>/rest/saas/login" method="POST">
<%
String errorMessage = (String)request.getAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE");
if (errorMessage != null) { %>
<div class="feedback feedback-error">
<p><font color="red"><%=errorMessage%></font></p>
</div>
<% } %>
<div>
<label for="username">Username</label><input type="text" id="username" name="username" autofocus>
</div>
<div>
<label for="password">Password</label><input type="password" name="Password" id="password">
</div> <!--
<div>
<label for="one-time-pswd" class="two-lines">One-time-password</label><input type="password" id="one-time-pswd">
</div> -->
<div class="aside-btn">
<input type="checkbox" id="remember"><label for="remember">Remember Username</label>
<p>Forgot <a href="#">Username</a> or <a href="#">Password</a>?</p>
</div>
<input type="submit" value="Log In">
</form>
</section>
<section class="social-login">
<span>or</span>
<h3>Social login area</h3>
<p>Log In with</p>
<ul>
<li>
<a href="#" class="zocial facebook">
<span class="text">Facebook</span>
</a>
</li>
<li>
<a href="#" class="zocial googleplus">
<span class="text">Google</span>
</a>
</li>
<li>
<a href="#" class="zocial twitter">
<span class="text">Twitter</span>
</a>
</li>
</ul>
</section>
<section class="info-area">
<h3>Info area</h3>
<p>Does not have an account? <a href="<%=application.getContextPath()%>/saas/saas-register.jsp">Register</a>.</p>
<ul>
<li><strong>Domain:</strong> 10.0.0.1</li>
<li><strong>Zone:</strong> Live</li>
<li><strong>Appliance:</strong> Yep</li>
</ul>
</section>
</div>
</div>
</div>
</body>
</html>

View file

@ -24,6 +24,8 @@ public class LoginBean {
private RealmModel realm; private RealmModel realm;
private String name;
private String loginAction; private String loginAction;
private String socialLoginUrl; private String socialLoginUrl;
@ -42,6 +44,8 @@ public class LoginBean {
private Map<String, Object> themeConfig; private Map<String, Object> themeConfig;
private String error;
@PostConstruct @PostConstruct
public void init() { public void init() {
FacesContext ctx = FacesContext.getCurrentInstance(); FacesContext ctx = FacesContext.getCurrentInstance();
@ -50,20 +54,21 @@ public class LoginBean {
realm = (RealmModel) request.getAttribute(RealmModel.class.getName()); realm = (RealmModel) request.getAttribute(RealmModel.class.getName());
if (RealmModel.DEFAULT_REALM.equals(realm.getName())) {
name = "Keycloak";
} else {
name = realm.getName();
}
loginAction = ((URI) request.getAttribute("KEYCLOAK_LOGIN_ACTION")).toString(); loginAction = ((URI) request.getAttribute("KEYCLOAK_LOGIN_ACTION")).toString();
socialLoginUrl = ((URI) request.getAttribute("KEYCLOAK_SOCIAL_LOGIN")).toString(); socialLoginUrl = ((URI) request.getAttribute("KEYCLOAK_SOCIAL_LOGIN")).toString();
username = (String) request.getAttribute("username"); username = (String) request.getAttribute("username");
if (request.getAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE") != null) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR,
(String) request.getAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE"), null);
ctx.addMessage(null, message);
}
addRequiredCredentials(); addRequiredCredentials();
addHiddenProperties(request, "client_id", "scope", "state", "redirect_uri"); addHiddenProperties(request, "client_id", "scope", "state", "redirect_uri");
addSocialProviders(); addSocialProviders();
addErrors(request);
// TODO Get theme name from realm // TODO Get theme name from realm
theme = "default"; theme = "default";
@ -87,13 +92,17 @@ public class LoginBean {
} }
public String getName() { public String getName() {
return realm.getName(); return name;
} }
public String getLoginAction() { public String getLoginAction() {
return loginAction; return loginAction;
} }
public String getError() {
return error;
}
public List<Property> getHiddenProperties() { public List<Property> getHiddenProperties() {
return hiddenProperties; return hiddenProperties;
} }
@ -152,6 +161,10 @@ public class LoginBean {
} }
} }
private void addErrors(HttpServletRequest request) {
error = (String) request.getAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE");
}
public class Property { public class Property {
private String name; private String name;
private String value; private String value;

View file

@ -7,29 +7,35 @@
padding: 0; padding: 0;
font-family: "Open Sans", sans-serif; font-family: "Open Sans", sans-serif;
} }
body { body {
min-width: 120em; min-width: 120em;
height: 100%; height: 100%;
width: 100%; width: 100%;
font-family: "Open Sans", sans-serif; font-family: "Open Sans", sans-serif;
} }
body { body {
font-size: 62.5%; font-size: 62.5%;
} }
h1,
h1, h2, h3, h4, h5, h6 { h2,
h3,
h4,
h5,
h6 {
letter-spacing: -0.1em; letter-spacing: -0.1em;
font-weight: normal; font-weight: normal;
font-family: "Overpass", sans-serif; font-family: "Overpass", sans-serif;
} }
a { a {
color: #0099d3; color: #0099d3;
text-decoration: none; text-decoration: none;
} }
a:hover { a:hover {
text-decoration: underline; text-decoration: underline;
} }
strong {
font-weight: bold;
}
.hidden {
display: none;
}

View file

@ -24,29 +24,56 @@ input[type="email"]:focus {
border-color: #62afdb; border-color: #62afdb;
box-shadow: #62afdb 0 0 5px; box-shadow: #62afdb 0 0 5px;
} }
input[type="text"].error,
input[type="password"].error,
input[type="email"].error {
border-color: #ba1212;
background-color: #f8e7e7;
transition: all 0.33s ease-in-out;
-moz-transition: all 0.33s ease-in-out;
-webkit-transition: all 0.33s ease-in-out;
}
input[type="text"].error:focus,
input[type="password"].error:focus,
input[type="email"].error:focus {
box-shadow: 0 0 5px #ba1212;
}
input[type="button"],
input[type="submit"] { input[type="submit"] {
font-size: 1.3em; font-size: 1.3em;
padding: 0.30769230769231em 1.07692307692308em; padding: 0.30769230769231em 1.07692307692308em;
border: 1px #21799e solid; border-width: 1px;
border-radius: 2px; border-radius: 2px;
color: #fff;
font-weight: bold;
letter-spacing: 0.04em;
}
input[type="submit"] {
background-image: linear-gradient(top, #00a9ec 0%, #009bd3 100%); background-image: linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -o-linear-gradient(top, #00a9ec 0%, #009bd3 100%); background-image: -o-linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -moz-linear-gradient(top, #00a9ec 0%, #009bd3 100%); background-image: -moz-linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -webkit-linear-gradient(top, #00a9ec 0%, #009bd3 100%); background-image: -webkit-linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -ms-linear-gradient(top, #00a9ec 0%, #009bd3 100%); background-image: -ms-linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #00a9ec), color-stop(1, 0, #009bd3)); background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #00a9ec), color-stop(1, 0, #009bd3));
color: #fff; border-color: #21799e;
font-weight: bold; border-style: solid;
letter-spacing: 0.04em;
} }
input[type="submit"]:hover, input[type="submit"]:hover,
input[type="submit"]:focus { input[type="submit"]:focus {
background-color: #009BD3; background-color: #009BD3;
background-image: none;
cursor: pointer;
} }
input[type="submit"]:active { input[type="submit"]:active {
background-color: #0099d4; background-color: #0099d4;
}
input[type="button"]:hover,
input[type="button"]:focus,
input[type="submit"]:hover,
input[type="submit"]:focus {
background-image: none;
cursor: pointer;
}
input[type="button"]:active,
input[type="submit"]:active {
background-image: none; background-image: none;
cursor: pointer; cursor: pointer;
box-shadow: inset 0 0 5px 3px #0074ae; box-shadow: inset 0 0 5px 3px #0074ae;
@ -54,3 +81,35 @@ input[type="submit"]:active {
input[type="checkbox"] { input[type="checkbox"] {
margin-right: 0.5em; margin-right: 0.5em;
} }
.feedback {
position: absolute;
opacity: 0;
transition: opacity 0.33s ease-in-out;
-moz-transition: opacity 0.33s ease-in-out;
-webkit-transition: opacity 0.33s ease-in-out;
}
.feedback.show {
opacity: 1;
}
.feedback.error {
background-image: url(img/feedback-error-arrow-down.svg);
background-position: left bottom;
background-repeat: no-repeat;
padding-bottom: 1em;
}
.feedback.error p {
border-color: #b91415;
background-image: url(img/feedback-error-sign.svg);
background-color: #f8e7e7;
color: #4d5258;
}
.feedback p {
padding: 1em 3.63636363636364em;
border-style: solid;
border-width: 1px 1px 0px 1px;
background-repeat: no-repeat;
background-position: 1.27272727272727em 1.63636363636364em;
font-size: 1.1em;
line-height: 1.27272727272727em;
border-radius: 2px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 B

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="1000px" height="11px" viewBox="0 0 1000 11" enable-background="new 0 0 1000 11" xml:space="preserve">
<g>
<path fill="#F7E6E6" d="M1000,0c0,1.104-0.896,2-2,2H38l-8,9l-8-9H2C0.896,2,0,1.104,0,0"/>
<path fill="#B82025" d="M999,0c0,0.551-0.448,1-1,1H38h-0.449l-0.298,0.335L30,9.495l-7.253-8.159L22.449,1H22H2
C1.449,1,1,0.551,1,0 M0,0c0,1.104,0.896,2,2,2h20l8,9l8-9h960c1.104,0,2-0.896,2-2"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 793 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" id="svg7384" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="17px" height="17px" viewBox="0 0 17 17" enable-background="new 0 0 17 17" xml:space="preserve">
<g>
<path fill="#CC0000" d="M8.196,3.822C8.74,3.806,9.244,4.31,9.228,4.854v3.938c0.007,0.528-0.473,1.014-1,1.014
c-0.528,0-1.008-0.486-1-1.014V4.854c-0.008-0.467,0.354-0.913,0.812-1C8.091,3.839,8.144,3.83,8.196,3.822L8.196,3.822z"/>
<rect x="7.228" y="10.792" fill="#CC0000" width="2" height="2"/>
</g>
<g>
<g>
<path fill="#CC0000" d="M11.432,16.5H5.126L0,11.373V5.097L5.127,0h6.247l5.125,5.157V11.4L11.432,16.5z M5.747,15h5.06
l4.192-4.218V5.775L10.75,1.5H5.746L1.5,5.721v5.031L5.747,15z"/>
<path fill="#CC0000" d="M5.229,16.25h6.098l4.922-4.953V5.26L11.27,0.25H5.23L0.25,5.201v6.069L5.229,16.25z M10.91,15.25H5.644
L1.25,10.855V5.617L5.643,1.25h5.212l4.395,4.422v5.212L10.91,15.25z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -68,6 +68,7 @@ body {
} }
.rcue-login-register section.app-form { .rcue-login-register section.app-form {
padding-left: 0; padding-left: 0;
position: relative;
} }
.rcue-login-register form > div { .rcue-login-register form > div {
margin-bottom: 1em; margin-bottom: 1em;
@ -116,6 +117,7 @@ body {
/* 6px */ /* 6px */
} }
.rcue-login-register form > input[type="button"],
.rcue-login-register form > input[type="submit"] { .rcue-login-register form > input[type="submit"] {
float: right; float: right;
margin-top: 0.76923076923077em; margin-top: 0.76923076923077em;
@ -129,6 +131,11 @@ body {
right: 4.09090909090909em; right: 4.09090909090909em;
top: -0.636363636363636em; top: -0.636363636363636em;
} }
.rcue-login-register .feedback {
left: 32.7em;
top: -9.2em;
min-width: 35em;
}
.rcue-login-register section.social-login > span { .rcue-login-register section.social-login > span {
display: none; display: none;
} }
@ -251,8 +258,6 @@ a.zocial:before {
.rcue-login-register.register form > div.aside-btn p { .rcue-login-register.register form > div.aside-btn p {
line-height: 1.3em; line-height: 1.3em;
} }
/* Customer login */
.rcue-login-register p.powered { .rcue-login-register p.powered {
font-size: 1.1em; font-size: 1.1em;
margin-top: 1.27272727272727em; margin-top: 1.27272727272727em;

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,8 @@
<ui:composition xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" <ui:composition xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jstl/core" template="template.xhtml"> xmlns:c="http://java.sun.com/jstl/core" template="template.xhtml">
<ui:param name="bodyClass" value="register" />
<ui:define name="header">Register with <strong>#{login.name}</strong></ui:define> <ui:define name="header">Register with <strong>#{login.name}</strong></ui:define>
<ui:define name="form"> <ui:define name="form">

View file

@ -2,5 +2,5 @@
@IMPORT url("css/base.css"); @IMPORT url("css/base.css");
@IMPORT url("css/forms.css"); @IMPORT url("css/forms.css");
@IMPORT url("css/zocial/zocial.css"); @IMPORT url("css/zocial/zocial.css");
@IMPORT url("css/login-screen.css"); @IMPORT url("css/login-register.css");
@IMPORT url("http://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic,800,800italic"); @IMPORT url("http://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic,800,800italic");

View file

@ -13,7 +13,7 @@
</style> </style>
</h:head> </h:head>
<h:body class="rcue-login-register"> <h:body class="rcue-login-register #{bodyClass}">
<h:panelGroup rendered="#{not empty login.themeConfig['logo']}"> <h:panelGroup rendered="#{not empty login.themeConfig['logo']}">
<h1><a href="#" title="Go to the home page"><img src="#{login.themeConfig['logo']}" alt="Logo" /></a></h1> <h1><a href="#" title="Go to the home page"><img src="#{login.themeConfig['logo']}" alt="Logo" /></a></h1>
</h:panelGroup> </h:panelGroup>
@ -25,7 +25,11 @@
<div class="form-area #{login.social ? 'social' : ''} clearfix"> <div class="form-area #{login.social ? 'social' : ''} clearfix">
<section class="app-form"> <section class="app-form">
<h3>Application login area</h3> <h3>Application login area</h3>
<h:messages />
<h:panelGroup rendered="#{not empty login.error}">
<div class="feedback error bottom-left show"><p><strong>#{login.error}</strong></p></div>
</h:panelGroup>
<ui:insert name="form" /> <ui:insert name="form" />
</section> </section>

View file

@ -29,9 +29,9 @@ public abstract class AbstractLoginService {
@Context @Context
HttpResponse response; HttpResponse response;
protected String securityFailurePath = "/saas/securityFailure.jsp"; public final static String securityFailurePath = "/saas/securityFailure.jsp";
protected String loginFormPath = "/sdk/login.xhtml"; public final static String loginFormPath = "/sdk/login.xhtml";
protected String oauthFormPath = "/saas/oauthGrantForm.jsp"; public final static String oauthFormPath = "/saas/oauthGrantForm.jsp";
protected RealmModel realm; protected RealmModel realm;
protected TokenManager tokenManager; protected TokenManager tokenManager;