Made forms use resource bundle for messages
This commit is contained in:
parent
92235e3b07
commit
5c4afc7163
6 changed files with 68 additions and 58 deletions
|
@ -1,4 +1,4 @@
|
||||||
package org.keycloak.sdk;
|
package org.keycloak.forms;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -14,9 +14,12 @@ import javax.faces.context.FacesContext;
|
||||||
import javax.imageio.spi.ServiceRegistry;
|
import javax.imageio.spi.ServiceRegistry;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.ws.rs.core.MultivaluedMap;
|
import javax.ws.rs.core.MultivaluedMap;
|
||||||
|
import javax.ws.rs.core.UriBuilder;
|
||||||
|
|
||||||
import org.keycloak.services.models.RealmModel;
|
import org.keycloak.services.models.RealmModel;
|
||||||
import org.keycloak.services.models.RequiredCredentialModel;
|
import org.keycloak.services.models.RequiredCredentialModel;
|
||||||
|
import org.keycloak.services.resources.flows.FormFlows;
|
||||||
|
import org.keycloak.services.resources.flows.Urls;
|
||||||
|
|
||||||
@ManagedBean(name = "forms")
|
@ManagedBean(name = "forms")
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
|
@ -30,7 +33,7 @@ public class FormsBean {
|
||||||
|
|
||||||
private String loginAction;
|
private String loginAction;
|
||||||
|
|
||||||
private String socialLoginUrl;
|
private UriBuilder socialLoginUrlBuilder;
|
||||||
|
|
||||||
private String registrationUrl;
|
private String registrationUrl;
|
||||||
|
|
||||||
|
@ -38,8 +41,6 @@ public class FormsBean {
|
||||||
|
|
||||||
private List<RequiredCredential> requiredCredentials;
|
private List<RequiredCredential> requiredCredentials;
|
||||||
|
|
||||||
private List<Property> hiddenProperties;
|
|
||||||
|
|
||||||
private List<SocialProvider> providers;
|
private List<SocialProvider> providers;
|
||||||
|
|
||||||
private String theme;
|
private String theme;
|
||||||
|
@ -62,9 +63,11 @@ public class FormsBean {
|
||||||
|
|
||||||
HttpServletRequest request = (HttpServletRequest) ctx.getExternalContext().getRequest();
|
HttpServletRequest request = (HttpServletRequest) ctx.getExternalContext().getRequest();
|
||||||
|
|
||||||
realm = (RealmModel) request.getAttribute(RealmModel.class.getName());
|
realm = (RealmModel) request.getAttribute(FormFlows.REALM);
|
||||||
|
|
||||||
if (RealmModel.DEFAULT_REALM.equals(realm.getName())) {
|
boolean saas = RealmModel.DEFAULT_REALM.equals(realm.getName());
|
||||||
|
|
||||||
|
if (saas) {
|
||||||
name = "Keycloak";
|
name = "Keycloak";
|
||||||
} else {
|
} else {
|
||||||
name = realm.getName();
|
name = realm.getName();
|
||||||
|
@ -73,17 +76,28 @@ public class FormsBean {
|
||||||
view = ctx.getViewRoot().getViewId();
|
view = ctx.getViewRoot().getViewId();
|
||||||
view = view.substring(view.lastIndexOf('/') + 1, view.lastIndexOf('.'));
|
view = view.substring(view.lastIndexOf('/') + 1, view.lastIndexOf('.'));
|
||||||
|
|
||||||
loginUrl = ((URI) request.getAttribute("KEYCLOAK_LOGIN_PAGE")).toString();
|
UriBuilder b = UriBuilder.fromUri(request.getRequestURI()).replaceQuery(request.getQueryString())
|
||||||
loginAction = ((URI) request.getAttribute("KEYCLOAK_LOGIN_ACTION")).toString();
|
.replacePath(request.getContextPath()).path("rest");
|
||||||
|
URI baseURI = b.build();
|
||||||
|
|
||||||
registrationUrl = ((URI) request.getAttribute("KEYCLOAK_REGISTRATION_PAGE")).toString();
|
if (saas) {
|
||||||
registrationAction = ((URI) request.getAttribute("KEYCLOAK_REGISTRATION_ACTION")).toString();
|
loginUrl = Urls.saasLoginPage(baseURI).toString();
|
||||||
|
loginAction = Urls.saasLoginAction(baseURI).toString();
|
||||||
|
|
||||||
socialLoginUrl = ((URI) request.getAttribute("KEYCLOAK_SOCIAL_LOGIN")).toString();
|
registrationUrl = Urls.saasRegisterPage(baseURI).toString();
|
||||||
|
registrationAction = Urls.saasRegisterAction(baseURI).toString();
|
||||||
|
} else {
|
||||||
|
loginUrl = Urls.realmLoginPage(baseURI, realm.getId()).toString();
|
||||||
|
loginAction = Urls.realmLoginAction(baseURI, realm.getId()).toString();
|
||||||
|
|
||||||
|
registrationUrl = Urls.realmRegisterPage(baseURI, realm.getId()).toString();
|
||||||
|
registrationAction = Urls.realmRegisterAction(baseURI, realm.getId()).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
socialLoginUrlBuilder = UriBuilder.fromUri(Urls.socialRedirectToProviderAuth(baseURI, realm.getId()));
|
||||||
|
|
||||||
addRequiredCredentials();
|
addRequiredCredentials();
|
||||||
addFormData(request);
|
addFormData(request);
|
||||||
addHiddenProperties(request, "client_id", "scope", "state", "redirect_uri");
|
|
||||||
addSocialProviders();
|
addSocialProviders();
|
||||||
addErrors(request);
|
addErrors(request);
|
||||||
|
|
||||||
|
@ -132,10 +146,6 @@ public class FormsBean {
|
||||||
return formData;
|
return formData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Property> getHiddenProperties() {
|
|
||||||
return hiddenProperties;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<RequiredCredential> getRequiredCredentials() {
|
public List<RequiredCredential> getRequiredCredentials() {
|
||||||
return requiredCredentials;
|
return requiredCredentials;
|
||||||
}
|
}
|
||||||
|
@ -173,7 +183,7 @@ public class FormsBean {
|
||||||
formData = new HashMap<String, String>();
|
formData = new HashMap<String, String>();
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
MultivaluedMap<String, String> t = (MultivaluedMap<String, String>) request.getAttribute("KEYCLOAK_FORM_DATA");
|
MultivaluedMap<String, String> t = (MultivaluedMap<String, String>) request.getAttribute(FormFlows.DATA);
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
for (String k : t.keySet()) {
|
for (String k : t.keySet()) {
|
||||||
formData.put(k, t.getFirst(k));
|
formData.put(k, t.getFirst(k));
|
||||||
|
@ -181,16 +191,6 @@ public class FormsBean {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addHiddenProperties(HttpServletRequest request, String... names) {
|
|
||||||
hiddenProperties = new LinkedList<Property>();
|
|
||||||
for (String name : names) {
|
|
||||||
Object v = request.getAttribute(name);
|
|
||||||
if (v != null) {
|
|
||||||
hiddenProperties.add(new Property(name, (String) v));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addRequiredCredentials() {
|
private void addRequiredCredentials() {
|
||||||
requiredCredentials = new LinkedList<RequiredCredential>();
|
requiredCredentials = new LinkedList<RequiredCredential>();
|
||||||
for (RequiredCredentialModel m : realm.getRequiredCredentials()) {
|
for (RequiredCredentialModel m : realm.getRequiredCredentials()) {
|
||||||
|
@ -211,7 +211,7 @@ public class FormsBean {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addErrors(HttpServletRequest request) {
|
private void addErrors(HttpServletRequest request) {
|
||||||
error = (String) request.getAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE");
|
error = (String) request.getAttribute(FormFlows.ERROR_MESSAGE);
|
||||||
|
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
if (view.equals("login")) {
|
if (view.equals("login")) {
|
||||||
|
@ -288,13 +288,7 @@ public class FormsBean {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLoginUrl() {
|
public String getLoginUrl() {
|
||||||
StringBuilder sb = new StringBuilder();
|
return socialLoginUrlBuilder.replaceQueryParam("provider_id", id).build().toString();
|
||||||
sb.append(socialLoginUrl);
|
|
||||||
sb.append("?provider_id=" + id);
|
|
||||||
for (Property p : hiddenProperties) {
|
|
||||||
sb.append("&" + p.getName() + "=" + p.getValue());
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd ">
|
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd ">
|
||||||
|
|
||||||
|
<application>
|
||||||
|
<resource-bundle>
|
||||||
|
<base-name>org.keycloak.forms.messages</base-name>
|
||||||
|
<var>messages</var>
|
||||||
|
</resource-bundle>
|
||||||
|
</application>
|
||||||
|
|
||||||
</faces-config>
|
</faces-config>
|
||||||
|
|
|
@ -7,20 +7,16 @@
|
||||||
<ui:define name="form">
|
<ui:define name="form">
|
||||||
<form action="#{forms.loginAction}" method="post">
|
<form action="#{forms.loginAction}" method="post">
|
||||||
<div>
|
<div>
|
||||||
<label for="username">Username</label>
|
<label for="username">#{messages.username}</label>
|
||||||
<input id="username" name="username" value="#{forms.formData['username']}" type="text" />
|
<input id="username" name="username" value="#{forms.formData['username']}" type="text" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ui:repeat var="c" value="#{forms.requiredCredentials}">
|
<ui:repeat var="c" value="#{forms.requiredCredentials}">
|
||||||
<div>
|
<div>
|
||||||
<label for="#{c.name}">#{c.label}</label> <input id="#{c.name}" name="#{c.name}" type="#{c.inputType}" />
|
<label for="#{c.name}">#{messages[c.label]}</label> <input id="#{c.name}" name="#{c.name}" type="#{c.inputType}" />
|
||||||
</div>
|
</div>
|
||||||
</ui:repeat>
|
</ui:repeat>
|
||||||
|
|
||||||
<ui:repeat var="p" value="#{forms.hiddenProperties}">
|
|
||||||
<input name="#{p.name}" value="#{p.value}" type="hidden" />
|
|
||||||
</ui:repeat>
|
|
||||||
|
|
||||||
<div class="aside-btn">
|
<div class="aside-btn">
|
||||||
<!-- <input type="checkbox" id="remember" /><label for="remember">Remember Username</label> -->
|
<!-- <input type="checkbox" id="remember" /><label for="remember">Remember Username</label> -->
|
||||||
<!-- <p>Forgot <a href="#">Username</a> or <a href="#">Password</a>?</p> -->
|
<!-- <p>Forgot <a href="#">Username</a> or <a href="#">Password</a>?</p> -->
|
||||||
|
@ -32,7 +28,7 @@
|
||||||
|
|
||||||
<ui:define name="info">
|
<ui:define name="info">
|
||||||
<h:panelGroup rendered="#{forms.registrationAllowed}">
|
<h:panelGroup rendered="#{forms.registrationAllowed}">
|
||||||
<p>No account? <a href="#{forms.registrationUrl}">Register</a>.</p>
|
<p>#{messages.noAccount} <a href="#{forms.registrationUrl}">#{messages.register}</a>.</p>
|
||||||
</h:panelGroup>
|
</h:panelGroup>
|
||||||
</ui:define>
|
</ui:define>
|
||||||
</ui:composition>
|
</ui:composition>
|
|
@ -4,36 +4,32 @@
|
||||||
|
|
||||||
<ui:param name="bodyClass" value="register" />
|
<ui:param name="bodyClass" value="register" />
|
||||||
|
|
||||||
<ui:define name="header">Register with <strong>#{forms.name}</strong></ui:define>
|
<ui:define name="header">#{messages.registerWith} <strong>#{forms.name}</strong></ui:define>
|
||||||
|
|
||||||
<ui:define name="form">
|
<ui:define name="form">
|
||||||
<form action="#{forms.registrationAction}" method="post">
|
<form action="#{forms.registrationAction}" method="post">
|
||||||
<p class="subtitle">All fields are required</p>
|
<p class="subtitle">#{messages.allRequired}</p>
|
||||||
<div>
|
<div>
|
||||||
<label for="name">Full name</label>
|
<label for="name">#{messages.fullName}</label>
|
||||||
<input type="text" id="name" name="name" value="#{forms.formData['name']}" />
|
<input type="text" id="name" name="name" value="#{forms.formData['name']}" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="email">Email</label>
|
<label for="email">#{messages.email}</label>
|
||||||
<input type="text" id="email" name="email" value="#{forms.formData['email']}" />
|
<input type="text" id="email" name="email" value="#{forms.formData['email']}" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="username">Username</label>
|
<label for="username">#{messages.username}</label>
|
||||||
<input type="text" id="username" name="username" value="#{forms.formData['username']}" />
|
<input type="text" id="username" name="username" value="#{forms.formData['username']}" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="password">Password</label>
|
<label for="password">#{messages.password}</label>
|
||||||
<input type="password" id="password" name="password" />
|
<input type="password" id="password" name="password" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="password-confirm">Password confirmation</label>
|
<label for="password-confirm">#{messages.passwordConfirm}</label>
|
||||||
<input type="password" id="password-confirm" name="password-confirm" />
|
<input type="password" id="password-confirm" name="password-confirm" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ui:repeat var="p" value="#{forms.hiddenProperties}">
|
|
||||||
<input name="#{p.name}" value="#{p.value}" type="hidden" />
|
|
||||||
</ui:repeat>
|
|
||||||
|
|
||||||
<div class="aside-btn">
|
<div class="aside-btn">
|
||||||
<p>By registering you agree to the <a href="#">Terms of Service</a> and the <a href="#">Privacy Policy</a>.</p>
|
<p>By registering you agree to the <a href="#">Terms of Service</a> and the <a href="#">Privacy Policy</a>.</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -43,6 +39,6 @@
|
||||||
</ui:define>
|
</ui:define>
|
||||||
|
|
||||||
<ui:define name="info">
|
<ui:define name="info">
|
||||||
<p>Already have an account? <a href="#{forms.loginUrl}">Log in</a>.</p>
|
<p>#{messages.alreadyHaveAccount} <a href="#{forms.loginUrl}">#{messages.logIn}</a>.</p>
|
||||||
</ui:define>
|
</ui:define>
|
||||||
</ui:composition>
|
</ui:composition>
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
<h:head>
|
<h:head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
<title>Log in to #{forms.name}</title>
|
<title>#{messages.logInTo} #{forms.name}</title>
|
||||||
<link href="#{forms.themeConfig['styles']}" rel="stylesheet" />
|
<link href="#{forms.themeConfig['styles']}" rel="stylesheet" />
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
<section class="social-login">
|
<section class="social-login">
|
||||||
<span>or</span>
|
<span>or</span>
|
||||||
<h3>Social login area</h3>
|
<h3>Social login area</h3>
|
||||||
<p>Log In with</p>
|
<p>#{messages.logInWith}</p>
|
||||||
<ul>
|
<ul>
|
||||||
<ui:repeat var="p" value="#{forms.providers}">
|
<ui:repeat var="p" value="#{forms.providers}">
|
||||||
<li><a href="#{p.loginUrl}" class="zocial #{p.id}"> <span class="text">#{p.name}</span></a></li>
|
<li><a href="#{p.loginUrl}" class="zocial #{p.id}"> <span class="text">#{p.name}</span></a></li>
|
||||||
|
@ -63,7 +63,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h:panelGroup rendered="#{forms.themeConfig['displayPoweredBy']}">
|
<h:panelGroup rendered="#{forms.themeConfig['displayPoweredBy']}">
|
||||||
<p class="powered"><a href="#">Powered by Keycloak</a></p>
|
<p class="powered"><a href="#">#{messages.poweredByKeycloak}</a></p>
|
||||||
</h:panelGroup>
|
</h:panelGroup>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
logIn=Log in
|
||||||
|
logInTo=Log in to
|
||||||
|
logInWith=Log in with
|
||||||
|
noAccount=No account?
|
||||||
|
register=Register
|
||||||
|
registerWith=Register with
|
||||||
|
allRequired=All fields are required
|
||||||
|
alreadyHaveAccount=Already have an account?
|
||||||
|
|
||||||
|
poweredByKeycloak=Powered by Keycloak
|
||||||
|
|
||||||
|
username=Username
|
||||||
|
fullName=Full name
|
||||||
|
email=Email
|
||||||
|
password=Password
|
||||||
|
passwordConfirm=Password confirmation
|
||||||
|
|
||||||
|
authenticatorCode=Authenticator Code
|
||||||
|
clientCertificate=Client Certificate
|
Loading…
Reference in a new issue