Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
d9cb1fc4a9
46 changed files with 666 additions and 300 deletions
|
@ -289,10 +289,9 @@ public class OIDCIdentityProvider extends AbstractOAuth2IdentityProvider<OIDCIde
|
||||||
}
|
}
|
||||||
JsonWebToken token = jws.readJsonContent(JsonWebToken.class);
|
JsonWebToken token = jws.readJsonContent(JsonWebToken.class);
|
||||||
|
|
||||||
String aud = token.getAudience();
|
|
||||||
String iss = token.getIssuer();
|
String iss = token.getIssuer();
|
||||||
|
|
||||||
if (aud != null && !aud.equals(getConfig().getClientId())) {
|
if (!token.hasAudience(getConfig().getClientId())) {
|
||||||
throw new IdentityBrokerException("Wrong audience from token.");
|
throw new IdentityBrokerException("Wrong audience from token.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package org.keycloak.json;
|
||||||
|
|
||||||
|
import org.codehaus.jackson.JsonNode;
|
||||||
|
import org.codehaus.jackson.JsonParser;
|
||||||
|
import org.codehaus.jackson.JsonProcessingException;
|
||||||
|
import org.codehaus.jackson.map.DeserializationContext;
|
||||||
|
import org.codehaus.jackson.map.JsonDeserializer;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
public class StringOrArrayDeserializer extends JsonDeserializer<Object> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
|
||||||
|
JsonNode jsonNode = jsonParser.readValueAsTree();
|
||||||
|
if (jsonNode.isArray()) {
|
||||||
|
ArrayList<String> a = new ArrayList<>(1);
|
||||||
|
Iterator<JsonNode> itr = jsonNode.iterator();
|
||||||
|
while (itr.hasNext()) {
|
||||||
|
a.add(itr.next().getTextValue());
|
||||||
|
}
|
||||||
|
return a.toArray(new String[a.size()]);
|
||||||
|
} else {
|
||||||
|
return new String[] { jsonNode.getTextValue() };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package org.keycloak.json;
|
||||||
|
|
||||||
|
import org.codehaus.jackson.JsonGenerator;
|
||||||
|
import org.codehaus.jackson.map.JsonSerializer;
|
||||||
|
import org.codehaus.jackson.map.SerializerProvider;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class StringOrArraySerializer extends JsonSerializer<Object> {
|
||||||
|
@Override
|
||||||
|
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
|
||||||
|
String[] array = (String[]) o;
|
||||||
|
if (array == null) {
|
||||||
|
jsonGenerator.writeNull();
|
||||||
|
} else if (array.length == 1) {
|
||||||
|
jsonGenerator.writeString(array[0]);
|
||||||
|
} else {
|
||||||
|
jsonGenerator.writeStartArray();
|
||||||
|
for (String s : array) {
|
||||||
|
jsonGenerator.writeString(s);
|
||||||
|
}
|
||||||
|
jsonGenerator.writeEndArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -163,11 +163,6 @@ public class AccessToken extends IDToken {
|
||||||
return (AccessToken) super.issuer(issuer);
|
return (AccessToken) super.issuer(issuer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public AccessToken audience(String audience) {
|
|
||||||
return (AccessToken) super.audience(audience);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AccessToken subject(String subject) {
|
public AccessToken subject(String subject) {
|
||||||
return (AccessToken) super.subject(subject);
|
return (AccessToken) super.subject(subject);
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
package org.keycloak.representations;
|
package org.keycloak.representations;
|
||||||
|
|
||||||
import org.codehaus.jackson.annotate.JsonAnyGetter;
|
|
||||||
import org.codehaus.jackson.annotate.JsonAnySetter;
|
|
||||||
import org.codehaus.jackson.annotate.JsonProperty;
|
import org.codehaus.jackson.annotate.JsonProperty;
|
||||||
import org.codehaus.jackson.annotate.JsonUnwrapped;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
|
|
@ -4,6 +4,10 @@ import org.codehaus.jackson.annotate.JsonAnyGetter;
|
||||||
import org.codehaus.jackson.annotate.JsonAnySetter;
|
import org.codehaus.jackson.annotate.JsonAnySetter;
|
||||||
import org.codehaus.jackson.annotate.JsonIgnore;
|
import org.codehaus.jackson.annotate.JsonIgnore;
|
||||||
import org.codehaus.jackson.annotate.JsonProperty;
|
import org.codehaus.jackson.annotate.JsonProperty;
|
||||||
|
import org.codehaus.jackson.map.annotate.JsonDeserialize;
|
||||||
|
import org.codehaus.jackson.map.annotate.JsonSerialize;
|
||||||
|
import org.keycloak.json.StringOrArrayDeserializer;
|
||||||
|
import org.keycloak.json.StringOrArraySerializer;
|
||||||
import org.keycloak.util.Time;
|
import org.keycloak.util.Time;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
@ -26,14 +30,16 @@ public class JsonWebToken implements Serializable {
|
||||||
@JsonProperty("iss")
|
@JsonProperty("iss")
|
||||||
protected String issuer;
|
protected String issuer;
|
||||||
@JsonProperty("aud")
|
@JsonProperty("aud")
|
||||||
protected String audience;
|
@JsonSerialize(using = StringOrArraySerializer.class)
|
||||||
|
@JsonDeserialize(using = StringOrArrayDeserializer.class)
|
||||||
|
protected String[] audience;
|
||||||
@JsonProperty("sub")
|
@JsonProperty("sub")
|
||||||
protected String subject;
|
protected String subject;
|
||||||
@JsonProperty("typ")
|
@JsonProperty("typ")
|
||||||
protected String type;
|
protected String type;
|
||||||
@JsonProperty("azp")
|
@JsonProperty("azp")
|
||||||
public String issuedFor;
|
public String issuedFor;
|
||||||
protected Map<String, Object> otherClaims = new HashMap<String, Object>();
|
protected Map<String, Object> otherClaims = new HashMap<>();
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return id;
|
return id;
|
||||||
|
@ -72,7 +78,6 @@ public class JsonWebToken implements Serializable {
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public boolean isNotBefore() {
|
public boolean isNotBefore() {
|
||||||
return Time.currentTime() >= notBefore;
|
return Time.currentTime() >= notBefore;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -113,12 +118,21 @@ public class JsonWebToken implements Serializable {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
public String getAudience() {
|
public String[] getAudience() {
|
||||||
return audience;
|
return audience;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonWebToken audience(String audience) {
|
public boolean hasAudience(String audience) {
|
||||||
|
for (String a : this.audience) {
|
||||||
|
if (a.equals(audience)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonWebToken audience(String... audience) {
|
||||||
this.audience = audience;
|
this.audience = audience;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package org.keycloak.util;
|
||||||
import org.codehaus.jackson.map.ObjectMapper;
|
import org.codehaus.jackson.map.ObjectMapper;
|
||||||
import org.codehaus.jackson.map.SerializationConfig;
|
import org.codehaus.jackson.map.SerializationConfig;
|
||||||
import org.codehaus.jackson.map.annotate.JsonSerialize;
|
import org.codehaus.jackson.map.annotate.JsonSerialize;
|
||||||
import org.codehaus.jackson.type.TypeReference;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
44
core/src/test/java/org/keycloak/jose/JsonWebTokenTest.java
Normal file
44
core/src/test/java/org/keycloak/jose/JsonWebTokenTest.java
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
package org.keycloak.jose;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.representations.JsonWebToken;
|
||||||
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by st on 20.08.15.
|
||||||
|
*/
|
||||||
|
public class JsonWebTokenTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAudSingle() throws IOException {
|
||||||
|
String single = "{ \"aud\": \"test\" }";
|
||||||
|
JsonWebToken s = JsonSerialization.readValue(single, JsonWebToken.class);
|
||||||
|
assertArrayEquals(new String[] { "test" }, s.getAudience());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAudArray() throws IOException {
|
||||||
|
String single = "{ \"aud\": [\"test\"] }";
|
||||||
|
JsonWebToken s = JsonSerialization.readValue(single, JsonWebToken.class);
|
||||||
|
assertArrayEquals(new String[]{"test"}, s.getAudience());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() throws IOException {
|
||||||
|
JsonWebToken jsonWebToken = new JsonWebToken();
|
||||||
|
jsonWebToken.audience("test");
|
||||||
|
assertTrue(JsonSerialization.writeValueAsPrettyString(jsonWebToken).contains("\"aud\" : \"test\""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testArray() throws IOException {
|
||||||
|
JsonWebToken jsonWebToken = new JsonWebToken();
|
||||||
|
jsonWebToken.audience("test", "test2");
|
||||||
|
assertTrue(JsonSerialization.writeValueAsPrettyString(jsonWebToken).contains("\"aud\" : [ \"test\", \"test2\" ]"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -104,6 +104,14 @@
|
||||||
impacts on performance.
|
impacts on performance.
|
||||||
</para>
|
</para>
|
||||||
</simplesect>
|
</simplesect>
|
||||||
|
<simplesect>
|
||||||
|
<title>Contact details removed from registration and account management</title>
|
||||||
|
<para>
|
||||||
|
In the default theme we have now removed the contact details from the registration page and account management. The admin console now lists
|
||||||
|
all the users attributes, not just contact specific attributes. The admin console also has the ability to add/remove attributes to a user.
|
||||||
|
If you want to add contact details, please refer to the address theme included in the examples.
|
||||||
|
</para>
|
||||||
|
</simplesect>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<title>Migrating to 1.3.0.Final</title>
|
<title>Migrating to 1.3.0.Final</title>
|
||||||
|
|
|
@ -177,6 +177,7 @@ new Keycloak({ url: 'http://localhost/auth', realm: 'myrealm', clientId: 'myApp'
|
||||||
<listitem>resourceAccess - the resource roles assocaited with the token</listitem>
|
<listitem>resourceAccess - the resource roles assocaited with the token</listitem>
|
||||||
<listitem>refreshToken - the base64 encoded token that can be used to retrieve a new token</listitem>
|
<listitem>refreshToken - the base64 encoded token that can be used to retrieve a new token</listitem>
|
||||||
<listitem>refreshTokenParsed - the parsed refresh token</listitem>
|
<listitem>refreshTokenParsed - the parsed refresh token</listitem>
|
||||||
|
<listitem>timeSkew - estimated skew between local time and Keycloak server in seconds</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
|
@ -167,6 +167,9 @@ public class CustomerService {
|
||||||
<auth-constraint>
|
<auth-constraint>
|
||||||
<role-name>admin</role-name>
|
<role-name>admin</role-name>
|
||||||
</auth-constraint>
|
</auth-constraint>
|
||||||
|
<user-data-constraint>
|
||||||
|
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
||||||
|
</user-data-constraint>
|
||||||
</security-constraint>
|
</security-constraint>
|
||||||
<security-constraint>
|
<security-constraint>
|
||||||
<web-resource-collection>
|
<web-resource-collection>
|
||||||
|
@ -176,12 +179,6 @@ public class CustomerService {
|
||||||
<auth-constraint>
|
<auth-constraint>
|
||||||
<role-name>user</role-name>
|
<role-name>user</role-name>
|
||||||
</auth-constraint>
|
</auth-constraint>
|
||||||
</security-constraint>
|
|
||||||
|
|
||||||
<security-constraint>
|
|
||||||
<web-resource-collection>
|
|
||||||
<url-pattern>/*</url-pattern>
|
|
||||||
</web-resource-collection>
|
|
||||||
<user-data-constraint>
|
<user-data-constraint>
|
||||||
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
||||||
</user-data-constraint>
|
</user-data-constraint>
|
||||||
|
@ -235,7 +232,7 @@ public class CustomerService {
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
The <literal>security-deployment</literal> <literal>name</literal> attribute identifies the WAR you want
|
The <literal>secure-deployment</literal> <literal>name</literal> attribute identifies the WAR you want
|
||||||
to secure. Its value is the <literal>module-name</literal> defined in <literal>web.xml</literal> with
|
to secure. Its value is the <literal>module-name</literal> defined in <literal>web.xml</literal> with
|
||||||
<literal>.war</literal> appended. The rest of the configuration corresponds pretty much one to one
|
<literal>.war</literal> appended. The rest of the configuration corresponds pretty much one to one
|
||||||
with the <literal>keycloak.json</literal> configuration options defined in <link linkend='adapter-config'>general adapter configuration</link>.
|
with the <literal>keycloak.json</literal> configuration options defined in <link linkend='adapter-config'>general adapter configuration</link>.
|
||||||
|
|
|
@ -132,12 +132,6 @@ $ java -jar $JETTY_HOME/start.jar --add-to-startd=keycloak
|
||||||
<auth-constraint>
|
<auth-constraint>
|
||||||
<role-name>user</role-name>
|
<role-name>user</role-name>
|
||||||
</auth-constraint>
|
</auth-constraint>
|
||||||
</security-constraint>
|
|
||||||
|
|
||||||
<security-constraint>
|
|
||||||
<web-resource-collection>
|
|
||||||
<url-pattern>/*</url-pattern>
|
|
||||||
</web-resource-collection>
|
|
||||||
<user-data-constraint>
|
<user-data-constraint>
|
||||||
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
||||||
</user-data-constraint>
|
</user-data-constraint>
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
if (refreshed) {
|
if (refreshed) {
|
||||||
output(keycloak.tokenParsed);
|
output(keycloak.tokenParsed);
|
||||||
} else {
|
} else {
|
||||||
output('Token not refreshed, valid for ' + Math.round(keycloak.tokenParsed.exp - new Date().getTime() / 1000) + ' seconds');
|
output('Token not refreshed, valid for ' + Math.round(keycloak.tokenParsed.exp + keycloak.timeSkew - new Date().getTime() / 1000) + ' seconds');
|
||||||
}
|
}
|
||||||
}).error(function() {
|
}).error(function() {
|
||||||
output('Failed to refresh token');
|
output('Failed to refresh token');
|
||||||
|
@ -62,11 +62,11 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var o = 'Token Expires:\t\t' + new Date(keycloak.tokenParsed.exp * 1000).toLocaleString() + '\n';
|
var o = 'Token Expires:\t\t' + new Date((keycloak.tokenParsed.exp + keycloak.timeSkew) * 1000).toLocaleString() + '\n';
|
||||||
o += 'Token Expires in:\t' + Math.round(keycloak.tokenParsed.exp - new Date().getTime() / 1000) + ' seconds\n';
|
o += 'Token Expires in:\t' + Math.round(keycloak.tokenParsed.exp + keycloak.timeSkew - new Date().getTime() / 1000) + ' seconds\n';
|
||||||
|
|
||||||
o += 'Refresh Token Expires:\t' + new Date(keycloak.refreshTokenParsed.exp * 1000).toLocaleString() + '\n';
|
o += 'Refresh Token Expires:\t' + new Date((keycloak.refreshTokenParsed.exp + keycloak.timeSkew) * 1000).toLocaleString() + '\n';
|
||||||
o += 'Refresh Expires in:\t' + Math.round(keycloak.refreshTokenParsed.exp - new Date().getTime() / 1000) + ' seconds';
|
o += 'Refresh Expires in:\t' + Math.round(keycloak.refreshTokenParsed.exp + keycloak.timeSkew - new Date().getTime() / 1000) + ' seconds';
|
||||||
output(o);
|
output(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,14 @@ Then open $KEYCLOAK_HOME/standalone/configuration/keycloak-server.json and regis
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Address Theme
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Example theme that adds address fields to registration page, account management and admin console. To enable the theme open the admin console, select your realm, click on `Theme`. In the dropdown for `Login Theme` and `Account Theme` select `address`. Click `Save` and login to the realm to see the new theme in action.
|
||||||
|
|
||||||
|
One thing to note is that to change the admin console for the master admin console (`/auth/admin`) you need to change the theme for the master realm. Changing the admin console theme for any other realms will only change the admin console for that specific realm (for example `/auth/admin/myrealm/console`).
|
||||||
|
|
||||||
|
|
||||||
Sunrise Login Theme
|
Sunrise Login Theme
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
{
|
{
|
||||||
"themes": [{
|
"themes": [{
|
||||||
|
"name" : "address",
|
||||||
|
"types": [ "admin", "account", "login" ]
|
||||||
|
}, {
|
||||||
"name" : "logo-example",
|
"name" : "logo-example",
|
||||||
"types": [ "admin", "account", "login", "welcome" ]
|
"types": [ "admin", "account", "login", "welcome" ]
|
||||||
}, {
|
}, {
|
||||||
|
|
114
examples/themes/src/main/resources/theme/address/account/account.ftl
Executable file
114
examples/themes/src/main/resources/theme/address/account/account.ftl
Executable file
|
@ -0,0 +1,114 @@
|
||||||
|
<#import "template.ftl" as layout>
|
||||||
|
<@layout.mainLayout active='account' bodyClass='user'; section>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h2>${msg("editAccountHtmlTtile")}</h2>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 subtitle">
|
||||||
|
<span class="subtitle"><span class="required">*</span> ${msg("requiredFields")}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form action="${url.accountUrl}" class="form-horizontal" method="post">
|
||||||
|
|
||||||
|
<input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker}">
|
||||||
|
|
||||||
|
<div class="form-group ${messagesPerField.printIfExists('username','has-error')}">
|
||||||
|
<div class="col-sm-2 col-md-2">
|
||||||
|
<label for="username" class="control-label">${msg("username")}</label> <#if realm.editUsernameAllowed><span class="required">*</span></#if>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-10 col-md-10">
|
||||||
|
<input type="text" class="form-control" id="username" name="username" <#if !realm.editUsernameAllowed>disabled="disabled"</#if> value="${(account.username!'')?html}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group ${messagesPerField.printIfExists('email','has-error')}">
|
||||||
|
<div class="col-sm-2 col-md-2">
|
||||||
|
<label for="email" class="control-label">${msg("email")}</label> <span class="required">*</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-10 col-md-10">
|
||||||
|
<input type="text" class="form-control" id="email" name="email" autofocus value="${(account.email!'')?html}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group ${messagesPerField.printIfExists('firstName','has-error')}">
|
||||||
|
<div class="col-sm-2 col-md-2">
|
||||||
|
<label for="firstName" class="control-label">${msg("firstName")}</label> <span class="required">*</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-10 col-md-10">
|
||||||
|
<input type="text" class="form-control" id="firstName" name="firstName" value="${(account.firstName!'')?html}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group ${messagesPerField.printIfExists('lastName','has-error')}">
|
||||||
|
<div class="col-sm-2 col-md-2">
|
||||||
|
<label for="lastName" class="control-label">${msg("lastName")}</label> <span class="required">*</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-10 col-md-10">
|
||||||
|
<input type="text" class="form-control" id="lastName" name="lastName" value="${(account.lastName!'')?html}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-2 col-md-2">
|
||||||
|
<label for="user.attributes.street" class="control-label">${msg("street")}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-10 col-md-10">
|
||||||
|
<input type="text" class="form-control" id="user.attributes.street" name="user.attributes.street" value="${(account.attributes.street!'')?html}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-2 col-md-2">
|
||||||
|
<label for="user.attributes.locality" class="control-label">${msg("locality")}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-10 col-md-10">
|
||||||
|
<input type="text" class="form-control" id="user.attributes.locality" name="user.attributes.locality" value="${(account.attributes.locality!'')?html}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-2 col-md-2">
|
||||||
|
<label for="user.attributes.region" class="control-label">${msg("region")}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-10 col-md-10">
|
||||||
|
<input type="text" class="form-control" id="user.attributes.region" name="user.attributes.region" value="${(account.attributes.region!'')?html}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-2 col-md-2">
|
||||||
|
<label for="user.attributes.postal_code" class="control-label">${msg("postal_code")}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-10 col-md-10">
|
||||||
|
<input type="text" class="form-control" id="user.attributes.postal_code" name="user.attributes.postal_code" value="${(account.attributes.postal_code!'')?html}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-2 col-md-2">
|
||||||
|
<label for="user.attributes.country" class="control-label">${msg("country")}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-10 col-md-10">
|
||||||
|
<input type="text" class="form-control" id="user.attributes.country" name="user.attributes.country" value="${(account.attributes.country!'')?html}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div id="kc-form-buttons" class="col-md-offset-2 col-md-10 submit">
|
||||||
|
<div class="">
|
||||||
|
<#if url.referrerURI??><a href="${url.referrerURI}">${msg("backToApplication")}/a></#if>
|
||||||
|
<button type="submit" class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" name="submitAction" value="Save">${msg("doSave")}</button>
|
||||||
|
<button type="submit" class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!}" name="submitAction" value="Cancel">${msg("doCancel")}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</@layout.mainLayout>
|
|
@ -0,0 +1 @@
|
||||||
|
parent=keycloak
|
|
@ -0,0 +1,55 @@
|
||||||
|
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li><a href="#/realms/{{realm.realm}}/users">Users</a></li>
|
||||||
|
<li>{{user.username}}</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<kc-tabs-user></kc-tabs-user>
|
||||||
|
|
||||||
|
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageUsers">
|
||||||
|
<div class="form-group clearfix block">
|
||||||
|
<label class="col-md-2 control-label" for="street">Street</label>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input ng-model="user.attributes.street" class="form-control" type="text" name="street" id="street" />
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>Street address.</kc-tooltip>
|
||||||
|
</div>
|
||||||
|
<div class="form-group clearfix block">
|
||||||
|
<label class="col-md-2 control-label" for="locality">City or Locality</label>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input ng-model="user.attributes.locality" class="form-control" type="text" name="locality" id="locality" />
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>City or locality.</kc-tooltip>
|
||||||
|
</div>
|
||||||
|
<div class="form-group clearfix block">
|
||||||
|
<label class="col-md-2 control-label" for="region">State, Province, or Region</label>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input ng-model="user.attributes.region" class="form-control" type="text" name="region" id="region" />
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>State, province, prefecture, or region.</kc-tooltip>
|
||||||
|
</div>
|
||||||
|
<div class="form-group clearfix block">
|
||||||
|
<label class="col-md-2 control-label" for="postal_code">Zip or Postal code</label>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input ng-model="user.attributes.postal_code" class="form-control" type="text" name="postal_code" id="postal_code" />
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>Zip code or postal code.</kc-tooltip>
|
||||||
|
</div>
|
||||||
|
<div class="form-group clearfix block">
|
||||||
|
<label class="col-md-2 control-label" for="country">Country</label>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input ng-model="user.attributes.country" class="form-control" type="text" name="country" id="country" />
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>Country name.</kc-tooltip>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group" data-ng-show="access.manageUsers">
|
||||||
|
<div class="col-md-10 col-md-offset-2">
|
||||||
|
<button kc-save data-ng-disabled="!changed">Save</button>
|
||||||
|
<button kc-reset data-ng-disabled="!changed">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<kc-menu></kc-menu>
|
|
@ -0,0 +1 @@
|
||||||
|
parent=keycloak
|
|
@ -0,0 +1,95 @@
|
||||||
|
<#import "template.ftl" as layout>
|
||||||
|
<@layout.registrationLayout; section>
|
||||||
|
<#if section = "title">
|
||||||
|
${msg("loginProfileTitle")}
|
||||||
|
<#elseif section = "header">
|
||||||
|
${msg("loginProfileTitle")}
|
||||||
|
<#elseif section = "form">
|
||||||
|
<form id="kc-update-profile-form" class="${properties.kcFormClass!}" action="${url.loginUpdateProfileUrl}" method="post">
|
||||||
|
<div class="${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('email',properties.kcFormGroupErrorClass!)}">
|
||||||
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="email" class="${properties.kcLabelClass!}">${msg("email")}</label>
|
||||||
|
</div>
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<input type="text" id="email" name="email" value="${(user.email!'')?html}" class="${properties.kcInputClass!}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('firstName',properties.kcFormGroupErrorClass!)}">
|
||||||
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="firstName" class="${properties.kcLabelClass!}">${msg("firstName")}</label>
|
||||||
|
</div>
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<input type="text" id="firstName" name="firstName" value="${(user.firstName!'')?html}" class="${properties.kcInputClass!}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('lastName',properties.kcFormGroupErrorClass!)}">
|
||||||
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="lastName" class="${properties.kcLabelClass!}">${msg("lastName")}</label>
|
||||||
|
</div>
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<input type="text" id="lastName" name="lastName" value="${(user.lastName!'')?html}" class="${properties.kcInputClass!}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="user.attributes.street" class="${properties.kcLabelClass!}">${msg("street")}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.street" name="user.attributes.street" value="${(user.attributes.street!'')?html}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="user.attributes.locality" class="${properties.kcLabelClass!}">${msg("locality")}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.locality" name="user.attributes.locality" value="${(user.attributes.locality!'')?html}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="user.attributes.region" class="${properties.kcLabelClass!}">${msg("region")}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.region" name="user.attributes.region" value="${(user.attributes.region!'')?html}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="user.attributes.postal_code" class="${properties.kcLabelClass!}">${msg("postal_code")}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.postal_code" name="user.attributes.postal_code" value="${(user.attributes.postal_code!'')?html}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="user.attributes.country" class="${properties.kcLabelClass!}">${msg("country")}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.country" name="user.attributes.country" value="${(user.attributes.country!'')?html}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="${properties.kcFormGroupClass!}">
|
||||||
|
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
|
||||||
|
<div class="${properties.kcFormOptionsWrapperClass!}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="kc-form-buttons" class="${properties.kcFormButtonsClass!}">
|
||||||
|
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</#if>
|
||||||
|
</@layout.registrationLayout>
|
131
examples/themes/src/main/resources/theme/address/login/register.ftl
Executable file
131
examples/themes/src/main/resources/theme/address/login/register.ftl
Executable file
|
@ -0,0 +1,131 @@
|
||||||
|
<#import "template.ftl" as layout>
|
||||||
|
<@layout.registrationLayout; section>
|
||||||
|
<#if section = "title">
|
||||||
|
${msg("registerWithTitle",(realm.name!''))}
|
||||||
|
<#elseif section = "header">
|
||||||
|
${msg("registerWithTitleHtml",(realm.name!''))}
|
||||||
|
<#elseif section = "form">
|
||||||
|
<form id="kc-register-form" class="${properties.kcFormClass!}" action="${url.registrationAction}" method="post">
|
||||||
|
<#if !realm.registrationEmailAsUsername>
|
||||||
|
<div class="${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('username',properties.kcFormGroupErrorClass!)}">
|
||||||
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="username" class="${properties.kcLabelClass!}">${msg("username")}</label>
|
||||||
|
</div>
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<input type="text" id="username" class="${properties.kcInputClass!}" name="username" value="${(register.formData.username!'')?html}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</#if>
|
||||||
|
<div class="${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('firstName',properties.kcFormGroupErrorClass!)}">
|
||||||
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="firstName" class="${properties.kcLabelClass!}">${msg("firstName")}</label>
|
||||||
|
</div>
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<input type="text" id="firstName" class="${properties.kcInputClass!}" name="firstName" value="${(register.formData.firstName!'')?html}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('lastName',properties.kcFormGroupErrorClass!)}">
|
||||||
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="lastName" class="${properties.kcLabelClass!}">${msg("lastName")}</label>
|
||||||
|
</div>
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<input type="text" id="lastName" class="${properties.kcInputClass!}" name="lastName" value="${(register.formData.lastName!'')?html}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('email',properties.kcFormGroupErrorClass!)}">
|
||||||
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="email" class="${properties.kcLabelClass!}">${msg("email")}</label>
|
||||||
|
</div>
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<input type="text" id="email" class="${properties.kcInputClass!}" name="email" value="${(register.formData.email!'')?html}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<#if passwordRequired>
|
||||||
|
<div class="${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('password',properties.kcFormGroupErrorClass!)}">
|
||||||
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="password" class="${properties.kcLabelClass!}">${msg("password")}</label>
|
||||||
|
</div>
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<input type="password" id="password" class="${properties.kcInputClass!}" name="password" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('password-confirm',properties.kcFormGroupErrorClass!)}">
|
||||||
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="password-confirm" class="${properties.kcLabelClass!}">${msg("passwordConfirm")}</label>
|
||||||
|
</div>
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<input type="password" id="password-confirm" class="${properties.kcInputClass!}" name="password-confirm" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</#if>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="user.attributes.street" class="${properties.kcLabelClass!}">${msg("street")}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.street" name="user.attributes.street" value="${(register.formData['user.attributes.street']!'')?html}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="user.attributes.locality" class="${properties.kcLabelClass!}">${msg("locality")}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.locality" name="user.attributes.locality" value="${(register.formData['user.attributes.locality']!'')?html}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="user.attributes.region" class="${properties.kcLabelClass!}">${msg("region")}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.region" name="user.attributes.region" value="${(register.formData['user.attributes.region']!'')?html}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="user.attributes.postal_code" class="${properties.kcLabelClass!}">${msg("postal_code")}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.postal_code" name="user.attributes.postal_code" value="${(register.formData['user.attributes.postal_code']!'')?html}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="user.attributes.country" class="${properties.kcLabelClass!}">${msg("country")}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.country" name="user.attributes.country" value="${(register.formData['user.attributes.country']!'')?html}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<#if recaptchaRequired??>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<div class="g-recaptcha" data-size="compact" data-sitekey="${recaptchaSiteKey}"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<div class="${properties.kcFormGroupClass!}">
|
||||||
|
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
|
||||||
|
<div class="${properties.kcFormOptionsWrapperClass!}">
|
||||||
|
<span><a href="${url.loginUrl}">${msg("backToLogin")}</a></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="kc-form-buttons" class="${properties.kcFormButtonsClass!}">
|
||||||
|
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doRegister")}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</#if>
|
||||||
|
</@layout.registrationLayout>
|
|
@ -0,0 +1 @@
|
||||||
|
parent=keycloak
|
|
@ -54,52 +54,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="col-sm-2 col-md-2">
|
|
||||||
<label for="user.attributes.street" class="control-label">${msg("street")}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-10 col-md-10">
|
|
||||||
<input type="text" class="form-control" id="user.attributes.street" name="user.attributes.street" value="${(account.attributes.street!'')?html}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="col-sm-2 col-md-2">
|
|
||||||
<label for="user.attributes.locality" class="control-label">${msg("locality")}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-10 col-md-10">
|
|
||||||
<input type="text" class="form-control" id="user.attributes.locality" name="user.attributes.locality" value="${(account.attributes.locality!'')?html}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="col-sm-2 col-md-2">
|
|
||||||
<label for="user.attributes.region" class="control-label">${msg("region")}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-10 col-md-10">
|
|
||||||
<input type="text" class="form-control" id="user.attributes.region" name="user.attributes.region" value="${(account.attributes.region!'')?html}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="col-sm-2 col-md-2">
|
|
||||||
<label for="user.attributes.postal_code" class="control-label">${msg("postal_code")}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-10 col-md-10">
|
|
||||||
<input type="text" class="form-control" id="user.attributes.postal_code" name="user.attributes.postal_code" value="${(account.attributes.postal_code!'')?html}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="col-sm-2 col-md-2">
|
|
||||||
<label for="user.attributes.country" class="control-label">${msg("country")}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-10 col-md-10">
|
|
||||||
<input type="text" class="form-control" id="user.attributes.country" name="user.attributes.country" value="${(account.attributes.country!'')?html}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div id="kc-form-buttons" class="col-md-offset-2 col-md-10 submit">
|
<div id="kc-form-buttons" class="col-md-offset-2 col-md-10 submit">
|
||||||
<div class="">
|
<div class="">
|
||||||
|
|
|
@ -345,6 +345,18 @@ module.config([ '$routeProvider', function($routeProvider) {
|
||||||
},
|
},
|
||||||
controller : 'UserDetailCtrl'
|
controller : 'UserDetailCtrl'
|
||||||
})
|
})
|
||||||
|
.when('/realms/:realm/users/:user/user-attributes', {
|
||||||
|
templateUrl : resourceUrl + '/partials/user-attributes.html',
|
||||||
|
resolve : {
|
||||||
|
realm : function(RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
user : function(UserLoader) {
|
||||||
|
return UserLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller : 'UserDetailCtrl'
|
||||||
|
})
|
||||||
.when('/realms/:realm/users/:user/user-credentials', {
|
.when('/realms/:realm/users/:user/user-credentials', {
|
||||||
templateUrl : resourceUrl + '/partials/user-credentials.html',
|
templateUrl : resourceUrl + '/partials/user-credentials.html',
|
||||||
resolve : {
|
resolve : {
|
||||||
|
|
|
@ -450,6 +450,15 @@ module.controller('UserDetailCtrl', function($scope, realm, user, BruteForceUser
|
||||||
$scope.cancel = function() {
|
$scope.cancel = function() {
|
||||||
$location.url("/realms/" + realm.realm + "/users");
|
$location.url("/realms/" + realm.realm + "/users");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.addAttribute = function() {
|
||||||
|
$scope.user.attributes[$scope.newAttribute.key] = $scope.newAttribute.value;
|
||||||
|
delete $scope.newAttribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.removeAttribute = function(key) {
|
||||||
|
delete $scope.user.attributes[key];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
module.controller('UserCredentialsCtrl', function($scope, realm, user, User, UserCredentials, Notifications, Dialog) {
|
module.controller('UserCredentialsCtrl', function($scope, realm, user, User, UserCredentials, Notifications, Dialog) {
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
<fieldset>
|
|
||||||
<legend collapsed><span class="text">Contact Information</span> <kc-tooltip>Expand this section to configure user's contact information.</kc-tooltip></legend>
|
|
||||||
<div class="form-group clearfix block">
|
|
||||||
<label class="col-md-2 control-label" for="street">Street</label>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<input ng-model="user.attributes.street" class="form-control" type="text" name="street" id="street" />
|
|
||||||
</div>
|
|
||||||
<kc-tooltip>Street address.</kc-tooltip>
|
|
||||||
</div>
|
|
||||||
<div class="form-group clearfix block">
|
|
||||||
<label class="col-md-2 control-label" for="locality">City or Locality</label>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<input ng-model="user.attributes.locality" class="form-control" type="text" name="locality" id="locality" />
|
|
||||||
</div>
|
|
||||||
<kc-tooltip>City or locality.</kc-tooltip>
|
|
||||||
</div>
|
|
||||||
<div class="form-group clearfix block">
|
|
||||||
<label class="col-md-2 control-label" for="region">State, Province, or Region</label>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<input ng-model="user.attributes.region" class="form-control" type="text" name="region" id="region" />
|
|
||||||
</div>
|
|
||||||
<kc-tooltip>State, province, prefecture, or region.</kc-tooltip>
|
|
||||||
</div>
|
|
||||||
<div class="form-group clearfix block">
|
|
||||||
<label class="col-md-2 control-label" for="postal_code">Zip or Postal code</label>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<input ng-model="user.attributes.postal_code" class="form-control" type="text" name="postal_code" id="postal_code" />
|
|
||||||
</div>
|
|
||||||
<kc-tooltip>Zip code or postal code.</kc-tooltip>
|
|
||||||
</div>
|
|
||||||
<div class="form-group clearfix block">
|
|
||||||
<label class="col-md-2 control-label" for="country">Country</label>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<input ng-model="user.attributes.country" class="form-control" type="text" name="country" id="country" />
|
|
||||||
</div>
|
|
||||||
<kc-tooltip>Country name.</kc-tooltip>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li><a href="#/realms/{{realm.realm}}/users">Users</a></li>
|
||||||
|
<li>{{user.username}}</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<kc-tabs-user></kc-tabs-user>
|
||||||
|
|
||||||
|
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageUsers">
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Key</th>
|
||||||
|
<th>Value</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr ng-repeat="(key, value) in (user.attributes | filter:search)">
|
||||||
|
<td>{{key}}</td>
|
||||||
|
<td><input ng-model="user.attributes[key]" class="form-control" type="text" name="{{key}}" id="attribute-{{key}}" /></td>
|
||||||
|
<td class="kc-action-cell">
|
||||||
|
<button class="btn btn-default btn-block btn-sm" data-ng-click="removeAttribute(key)">Delete</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><input ng-model="newAttribute.key" class="form-control" type="text" id="newAttributeKey" /></td>
|
||||||
|
<td><input ng-model="newAttribute.value" class="form-control" type="text" id="newAttributeValue" /></td>
|
||||||
|
<td class="kc-action-cell">
|
||||||
|
<button class="btn btn-default btn-block btn-sm" data-ng-click="addAttribute()">Add</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="form-group" data-ng-show="access.manageUsers">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<button kc-save data-ng-disabled="!changed">Save</button>
|
||||||
|
<button kc-reset data-ng-disabled="!changed">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<kc-menu></kc-menu>
|
|
@ -123,8 +123,6 @@
|
||||||
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<div data-ng-include data-src="resourceUrl + '/partials/user-attribute-entry.html'"></div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-md-10 col-md-offset-2" data-ng-show="create && access.manageUsers">
|
<div class="col-md-10 col-md-offset-2" data-ng-show="create && access.manageUsers">
|
||||||
<button kc-save data-ng-show="changed">Save</button>
|
<button kc-save data-ng-show="changed">Save</button>
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
<h1 data-ng-show="create">Add User</h1>
|
<h1 data-ng-show="create">Add User</h1>
|
||||||
|
|
||||||
<ul class="nav nav-tabs" data-ng-show="!create">
|
<ul class="nav nav-tabs" data-ng-show="!create">
|
||||||
<li ng-class="{active: !path[4] && path[0] != 'create'}"><a href="#/realms/{{realm.realm}}/users/{{user.id}}">Attributes</a></li>
|
<li ng-class="{active: !path[4] && path[0] != 'create'}"><a href="#/realms/{{realm.realm}}/users/{{user.id}}">Details</a></li>
|
||||||
|
<li ng-class="{active: path[4] == 'user-attributes'}"><a href="#/realms/{{realm.realm}}/users/{{user.id}}/user-attributes">Attributes</a></li>
|
||||||
<li ng-class="{active: path[4] == 'user-credentials'}" data-ng-show="access.manageUsers"><a href="#/realms/{{realm.realm}}/users/{{user.id}}/user-credentials">Credentials</a></li>
|
<li ng-class="{active: path[4] == 'user-credentials'}" data-ng-show="access.manageUsers"><a href="#/realms/{{realm.realm}}/users/{{user.id}}/user-credentials">Credentials</a></li>
|
||||||
<li ng-class="{active: path[4] == 'role-mappings'}" ><a href="#/realms/{{realm.realm}}/users/{{user.id}}/role-mappings">Role Mappings</a></li>
|
<li ng-class="{active: path[4] == 'role-mappings'}" ><a href="#/realms/{{realm.realm}}/users/{{user.id}}/role-mappings">Role Mappings</a></li>
|
||||||
<li ng-class="{active: path[4] == 'consents'}"><a href="#/realms/{{realm.realm}}/users/{{user.id}}/consents">Consents</a></li>
|
<li ng-class="{active: path[4] == 'consents'}"><a href="#/realms/{{realm.realm}}/users/{{user.id}}/consents">Consents</a></li>
|
||||||
|
|
|
@ -33,53 +33,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="${properties.kcLabelWrapperClass!}">
|
|
||||||
<label for="user.attributes.street" class="${properties.kcLabelClass!}">${msg("street")}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
|
||||||
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.street" name="user.attributes.street" value="${(user.attributes.street!'')?html}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="${properties.kcLabelWrapperClass!}">
|
|
||||||
<label for="user.attributes.locality" class="${properties.kcLabelClass!}">${msg("locality")}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
|
||||||
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.locality" name="user.attributes.locality" value="${(user.attributes.locality!'')?html}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="${properties.kcLabelWrapperClass!}">
|
|
||||||
<label for="user.attributes.region" class="${properties.kcLabelClass!}">${msg("region")}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
|
||||||
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.region" name="user.attributes.region" value="${(user.attributes.region!'')?html}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="${properties.kcLabelWrapperClass!}">
|
|
||||||
<label for="user.attributes.postal_code" class="${properties.kcLabelClass!}">${msg("postal_code")}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
|
||||||
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.postal_code" name="user.attributes.postal_code" value="${(user.attributes.postal_code!'')?html}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="${properties.kcLabelWrapperClass!}">
|
|
||||||
<label for="user.attributes.country" class="${properties.kcLabelClass!}">${msg("country")}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
|
||||||
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.country" name="user.attributes.country" value="${(user.attributes.country!'')?html}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
<div class="${properties.kcFormGroupClass!}">
|
||||||
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
|
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
|
||||||
<div class="${properties.kcFormOptionsWrapperClass!}">
|
<div class="${properties.kcFormOptionsWrapperClass!}">
|
||||||
|
|
|
@ -62,51 +62,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</#if>
|
</#if>
|
||||||
<div class="form-group">
|
|
||||||
<div class="${properties.kcLabelWrapperClass!}">
|
|
||||||
<label for="user.attributes.street" class="${properties.kcLabelClass!}">${msg("street")}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
|
||||||
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.street" name="user.attributes.street" value="${(register.formData['user.attributes.street']!'')?html}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="${properties.kcLabelWrapperClass!}">
|
|
||||||
<label for="user.attributes.locality" class="${properties.kcLabelClass!}">${msg("locality")}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
|
||||||
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.locality" name="user.attributes.locality" value="${(register.formData['user.attributes.locality']!'')?html}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="${properties.kcLabelWrapperClass!}">
|
|
||||||
<label for="user.attributes.region" class="${properties.kcLabelClass!}">${msg("region")}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
|
||||||
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.region" name="user.attributes.region" value="${(register.formData['user.attributes.region']!'')?html}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="${properties.kcLabelWrapperClass!}">
|
|
||||||
<label for="user.attributes.postal_code" class="${properties.kcLabelClass!}">${msg("postal_code")}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
|
||||||
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.postal_code" name="user.attributes.postal_code" value="${(register.formData['user.attributes.postal_code']!'')?html}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="${properties.kcLabelWrapperClass!}">
|
|
||||||
<label for="user.attributes.country" class="${properties.kcLabelClass!}">${msg("country")}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
|
||||||
<input type="text" class="${properties.kcInputClass!}" id="user.attributes.country" name="user.attributes.country" value="${(register.formData['user.attributes.country']!'')?html}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<#if recaptchaRequired??>
|
<#if recaptchaRequired??>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
|
|
@ -261,7 +261,7 @@
|
||||||
throw 'Not authenticated';
|
throw 'Not authenticated';
|
||||||
}
|
}
|
||||||
|
|
||||||
var expiresIn = kc.tokenParsed['exp'] - (new Date().getTime() / 1000);
|
var expiresIn = kc.tokenParsed['exp'] - (new Date().getTime() / 1000) + kc.timeSkew;
|
||||||
if (minValidity) {
|
if (minValidity) {
|
||||||
expiresIn -= minValidity;
|
expiresIn -= minValidity;
|
||||||
}
|
}
|
||||||
|
@ -299,11 +299,18 @@
|
||||||
params += '&client_id=' + encodeURIComponent(kc.clientId);
|
params += '&client_id=' + encodeURIComponent(kc.clientId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var timeLocal = new Date().getTime();
|
||||||
|
|
||||||
req.onreadystatechange = function () {
|
req.onreadystatechange = function () {
|
||||||
if (req.readyState == 4) {
|
if (req.readyState == 4) {
|
||||||
if (req.status == 200) {
|
if (req.status == 200) {
|
||||||
|
timeLocal = (timeLocal + new Date().getTime()) / 2;
|
||||||
|
|
||||||
var tokenResponse = JSON.parse(req.responseText);
|
var tokenResponse = JSON.parse(req.responseText);
|
||||||
setToken(tokenResponse['access_token'], tokenResponse['refresh_token'], tokenResponse['id_token']);
|
setToken(tokenResponse['access_token'], tokenResponse['refresh_token'], tokenResponse['id_token']);
|
||||||
|
|
||||||
|
kc.timeSkew = Math.floor(timeLocal / 1000) - kc.tokenParsed.iat;
|
||||||
|
|
||||||
kc.onAuthRefreshSuccess && kc.onAuthRefreshSuccess();
|
kc.onAuthRefreshSuccess && kc.onAuthRefreshSuccess();
|
||||||
for (var p = refreshQueue.pop(); p != null; p = refreshQueue.pop()) {
|
for (var p = refreshQueue.pop(); p != null; p = refreshQueue.pop()) {
|
||||||
p.setSuccess(true);
|
p.setSuccess(true);
|
||||||
|
@ -385,11 +392,18 @@
|
||||||
|
|
||||||
req.withCredentials = true;
|
req.withCredentials = true;
|
||||||
|
|
||||||
|
var timeLocal = new Date().getTime();
|
||||||
|
|
||||||
req.onreadystatechange = function() {
|
req.onreadystatechange = function() {
|
||||||
if (req.readyState == 4) {
|
if (req.readyState == 4) {
|
||||||
if (req.status == 200) {
|
if (req.status == 200) {
|
||||||
|
timeLocal = (timeLocal + new Date().getTime()) / 2;
|
||||||
|
|
||||||
var tokenResponse = JSON.parse(req.responseText);
|
var tokenResponse = JSON.parse(req.responseText);
|
||||||
setToken(tokenResponse['access_token'], tokenResponse['refresh_token'], tokenResponse['id_token']);
|
setToken(tokenResponse['access_token'], tokenResponse['refresh_token'], tokenResponse['id_token']);
|
||||||
|
|
||||||
|
kc.timeSkew = Math.floor(timeLocal / 1000) - kc.tokenParsed.iat;
|
||||||
|
|
||||||
kc.onAuthSuccess && kc.onAuthSuccess();
|
kc.onAuthSuccess && kc.onAuthSuccess();
|
||||||
promise && promise.setSuccess();
|
promise && promise.setSuccess();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -116,7 +116,7 @@ public class RealmEntity {
|
||||||
Collection<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
|
Collection<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
|
||||||
|
|
||||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true)
|
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true)
|
||||||
@JoinTable(name="FED_PROVIDERS")
|
@JoinTable(name="FED_PROVIDERS", joinColumns={ @JoinColumn(name="REALM_ID") })
|
||||||
List<UserFederationProviderEntity> userFederationProviders = new ArrayList<UserFederationProviderEntity>();
|
List<UserFederationProviderEntity> userFederationProviders = new ArrayList<UserFederationProviderEntity>();
|
||||||
|
|
||||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
|
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
|
||||||
|
|
|
@ -111,13 +111,9 @@ public class JWTClientAuthenticator extends AbstractClientAuthenticator {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate other things
|
// Validate other things
|
||||||
String audience = token.getAudience();
|
|
||||||
String expectedAudience = Urls.realmIssuer(context.getUriInfo().getBaseUri(), realm.getName());
|
String expectedAudience = Urls.realmIssuer(context.getUriInfo().getBaseUri(), realm.getName());
|
||||||
if (audience == null) {
|
if (!token.hasAudience(expectedAudience)) {
|
||||||
throw new RuntimeException("Audience is null on JWT");
|
throw new RuntimeException("Token audience doesn't match domain. Realm audience is '" + expectedAudience + "' but audience from token is '" + token.getAudience() + "'");
|
||||||
}
|
|
||||||
if (!audience.equals(expectedAudience)) {
|
|
||||||
throw new RuntimeException("Token audience doesn't match domain. Realm audience is '" + expectedAudience + "' but audience from token is '" + audience + "'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!token.isActive()) {
|
if (!token.isActive()) {
|
||||||
|
|
|
@ -191,8 +191,8 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
|
||||||
|
|
||||||
if (authResult != null) {
|
if (authResult != null) {
|
||||||
AccessToken token = authResult.getToken();
|
AccessToken token = authResult.getToken();
|
||||||
String audience = token.getAudience();
|
String[] audience = token.getAudience();
|
||||||
ClientModel clientModel = this.realmModel.getClientByClientId(audience);
|
ClientModel clientModel = this.realmModel.getClientByClientId(audience[0]);
|
||||||
|
|
||||||
if (clientModel == null) {
|
if (clientModel == null) {
|
||||||
return badRequest("Invalid client.");
|
return badRequest("Invalid client.");
|
||||||
|
|
|
@ -562,7 +562,7 @@ public class AccountTest {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
loginPage.clickRegister();
|
loginPage.clickRegister();
|
||||||
|
|
||||||
registerPage.register("view", "log", "view-log@localhost", "view-log", "password", "password", null);
|
registerPage.register("view", "log", "view-log@localhost", "view-log", "password", "password");
|
||||||
|
|
||||||
expectedEvents.add(events.poll());
|
expectedEvents.add(events.poll());
|
||||||
expectedEvents.add(events.poll());
|
expectedEvents.add(events.poll());
|
||||||
|
@ -609,7 +609,7 @@ public class AccountTest {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
loginPage.clickRegister();
|
loginPage.clickRegister();
|
||||||
|
|
||||||
registerPage.register("view", "sessions", "view-sessions@localhost", "view-sessions", "password", "password", null);
|
registerPage.register("view", "sessions", "view-sessions@localhost", "view-sessions", "password", "password");
|
||||||
|
|
||||||
Event registerEvent = events.expectRegister("view-sessions", "view-sessions@localhost").assertEvent();
|
Event registerEvent = events.expectRegister("view-sessions", "view-sessions@localhost").assertEvent();
|
||||||
String userId = registerEvent.getUserId();
|
String userId = registerEvent.getUserId();
|
||||||
|
|
|
@ -145,7 +145,7 @@ public class RequiredActionEmailVerificationTest {
|
||||||
public void verifyEmailRegister() throws IOException, MessagingException {
|
public void verifyEmailRegister() throws IOException, MessagingException {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
loginPage.clickRegister();
|
loginPage.clickRegister();
|
||||||
registerPage.register("firstName", "lastName", "email@mail.com", "verifyEmail", "password", "password", null);
|
registerPage.register("firstName", "lastName", "email@mail.com", "verifyEmail", "password", "password");
|
||||||
|
|
||||||
String userId = events.expectRegister("verifyEmail", "email@mail.com").assertEvent().getUserId();
|
String userId = events.expectRegister("verifyEmail", "email@mail.com").assertEvent().getUserId();
|
||||||
|
|
||||||
|
|
|
@ -121,7 +121,7 @@ public class RequiredActionMultipleActionsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String updateProfile(String sessionId) {
|
public String updateProfile(String sessionId) {
|
||||||
updateProfilePage.update("New first", "New last", "new@email.com", null);
|
updateProfilePage.update("New first", "New last", "new@email.com");
|
||||||
|
|
||||||
AssertEvents.ExpectedEvent expectedEvent = events.expectRequiredAction(EventType.UPDATE_PROFILE);
|
AssertEvents.ExpectedEvent expectedEvent = events.expectRequiredAction(EventType.UPDATE_PROFILE);
|
||||||
if (sessionId != null) {
|
if (sessionId != null) {
|
||||||
|
|
|
@ -25,21 +25,16 @@ import org.junit.Assert;
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.constants.KerberosConstants;
|
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.events.Event;
|
import org.keycloak.events.Event;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.ClientModel;
|
|
||||||
import org.keycloak.models.OTPPolicy;
|
import org.keycloak.models.OTPPolicy;
|
||||||
import org.keycloak.models.ProtocolMapperModel;
|
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RequiredActionProviderModel;
|
import org.keycloak.models.RequiredActionProviderModel;
|
||||||
import org.keycloak.models.RoleModel;
|
|
||||||
import org.keycloak.models.UserCredentialModel;
|
import org.keycloak.models.UserCredentialModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.utils.HmacOTP;
|
import org.keycloak.models.utils.HmacOTP;
|
||||||
import org.keycloak.models.utils.TimeBasedOTP;
|
import org.keycloak.models.utils.TimeBasedOTP;
|
||||||
import org.keycloak.protocol.oidc.mappers.UserSessionNoteMapper;
|
|
||||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.testsuite.AssertEvents;
|
import org.keycloak.testsuite.AssertEvents;
|
||||||
|
@ -117,7 +112,7 @@ public class RequiredActionTotpSetupTest {
|
||||||
public void setupTotpRegister() {
|
public void setupTotpRegister() {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
loginPage.clickRegister();
|
loginPage.clickRegister();
|
||||||
registerPage.register("firstName", "lastName", "email@mail.com", "setupTotp", "password", "password", null);
|
registerPage.register("firstName", "lastName", "email@mail.com", "setupTotp", "password", "password");
|
||||||
|
|
||||||
String userId = events.expectRegister("setupTotp", "email@mail.com").assertEvent().getUserId();
|
String userId = events.expectRegister("setupTotp", "email@mail.com").assertEvent().getUserId();
|
||||||
|
|
||||||
|
@ -170,7 +165,7 @@ public class RequiredActionTotpSetupTest {
|
||||||
// Register new user
|
// Register new user
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
loginPage.clickRegister();
|
loginPage.clickRegister();
|
||||||
registerPage.register("firstName2", "lastName2", "email2@mail.com", "setupTotp2", "password2", "password2", null);
|
registerPage.register("firstName2", "lastName2", "email2@mail.com", "setupTotp2", "password2", "password2");
|
||||||
|
|
||||||
String userId = events.expectRegister("setupTotp2", "email2@mail.com").assertEvent().getUserId();
|
String userId = events.expectRegister("setupTotp2", "email2@mail.com").assertEvent().getUserId();
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ public class RequiredActionUpdateProfileTest {
|
||||||
|
|
||||||
updateProfilePage.assertCurrent();
|
updateProfilePage.assertCurrent();
|
||||||
|
|
||||||
updateProfilePage.update("New first", "New last", "new@email.com", "mystreet");
|
updateProfilePage.update("New first", "New last", "new@email.com");
|
||||||
|
|
||||||
String sessionId = events.expectRequiredAction(EventType.UPDATE_PROFILE).assertEvent().getSessionId();
|
String sessionId = events.expectRequiredAction(EventType.UPDATE_PROFILE).assertEvent().getSessionId();
|
||||||
events.expectRequiredAction(EventType.UPDATE_EMAIL).session(sessionId).detail(Details.PREVIOUS_EMAIL, "test-user@localhost").detail(Details.UPDATED_EMAIL, "new@email.com").assertEvent();
|
events.expectRequiredAction(EventType.UPDATE_EMAIL).session(sessionId).detail(Details.PREVIOUS_EMAIL, "test-user@localhost").detail(Details.UPDATED_EMAIL, "new@email.com").assertEvent();
|
||||||
|
@ -101,7 +101,6 @@ public class RequiredActionUpdateProfileTest {
|
||||||
Assert.assertEquals("New first", user.getFirstName());
|
Assert.assertEquals("New first", user.getFirstName());
|
||||||
Assert.assertEquals("New last", user.getLastName());
|
Assert.assertEquals("New last", user.getLastName());
|
||||||
Assert.assertEquals("new@email.com", user.getEmail());
|
Assert.assertEquals("new@email.com", user.getEmail());
|
||||||
Assert.assertEquals("mystreet", user.getAttributesAsListValues().get("street").get(0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -112,7 +111,7 @@ public class RequiredActionUpdateProfileTest {
|
||||||
|
|
||||||
updateProfilePage.assertCurrent();
|
updateProfilePage.assertCurrent();
|
||||||
|
|
||||||
updateProfilePage.update("", "New last", "new@email.com", "mystreet");
|
updateProfilePage.update("", "New last", "new@email.com");
|
||||||
|
|
||||||
updateProfilePage.assertCurrent();
|
updateProfilePage.assertCurrent();
|
||||||
|
|
||||||
|
@ -120,7 +119,6 @@ public class RequiredActionUpdateProfileTest {
|
||||||
Assert.assertEquals("", updateProfilePage.getFirstName());
|
Assert.assertEquals("", updateProfilePage.getFirstName());
|
||||||
Assert.assertEquals("New last", updateProfilePage.getLastName());
|
Assert.assertEquals("New last", updateProfilePage.getLastName());
|
||||||
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
|
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
|
||||||
Assert.assertEquals("mystreet", updateProfilePage.getAttributeStreet());
|
|
||||||
|
|
||||||
Assert.assertEquals("Please specify first name.", updateProfilePage.getError());
|
Assert.assertEquals("Please specify first name.", updateProfilePage.getError());
|
||||||
|
|
||||||
|
@ -135,7 +133,7 @@ public class RequiredActionUpdateProfileTest {
|
||||||
|
|
||||||
updateProfilePage.assertCurrent();
|
updateProfilePage.assertCurrent();
|
||||||
|
|
||||||
updateProfilePage.update("New first", "", "new@email.com", null);
|
updateProfilePage.update("New first", "", "new@email.com");
|
||||||
|
|
||||||
updateProfilePage.assertCurrent();
|
updateProfilePage.assertCurrent();
|
||||||
|
|
||||||
|
@ -143,7 +141,6 @@ public class RequiredActionUpdateProfileTest {
|
||||||
Assert.assertEquals("New first", updateProfilePage.getFirstName());
|
Assert.assertEquals("New first", updateProfilePage.getFirstName());
|
||||||
Assert.assertEquals("", updateProfilePage.getLastName());
|
Assert.assertEquals("", updateProfilePage.getLastName());
|
||||||
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
|
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
|
||||||
Assert.assertEquals("", updateProfilePage.getAttributeStreet());
|
|
||||||
|
|
||||||
Assert.assertEquals("Please specify last name.", updateProfilePage.getError());
|
Assert.assertEquals("Please specify last name.", updateProfilePage.getError());
|
||||||
|
|
||||||
|
@ -158,7 +155,7 @@ public class RequiredActionUpdateProfileTest {
|
||||||
|
|
||||||
updateProfilePage.assertCurrent();
|
updateProfilePage.assertCurrent();
|
||||||
|
|
||||||
updateProfilePage.update("New first", "New last", "", "mystreet");
|
updateProfilePage.update("New first", "New last", "");
|
||||||
|
|
||||||
updateProfilePage.assertCurrent();
|
updateProfilePage.assertCurrent();
|
||||||
|
|
||||||
|
@ -166,7 +163,6 @@ public class RequiredActionUpdateProfileTest {
|
||||||
Assert.assertEquals("New first", updateProfilePage.getFirstName());
|
Assert.assertEquals("New first", updateProfilePage.getFirstName());
|
||||||
Assert.assertEquals("New last", updateProfilePage.getLastName());
|
Assert.assertEquals("New last", updateProfilePage.getLastName());
|
||||||
Assert.assertEquals("", updateProfilePage.getEmail());
|
Assert.assertEquals("", updateProfilePage.getEmail());
|
||||||
Assert.assertEquals("mystreet", updateProfilePage.getAttributeStreet());
|
|
||||||
|
|
||||||
Assert.assertEquals("Please specify email.", updateProfilePage.getError());
|
Assert.assertEquals("Please specify email.", updateProfilePage.getError());
|
||||||
|
|
||||||
|
@ -181,7 +177,7 @@ public class RequiredActionUpdateProfileTest {
|
||||||
|
|
||||||
updateProfilePage.assertCurrent();
|
updateProfilePage.assertCurrent();
|
||||||
|
|
||||||
updateProfilePage.update("New first", "New last", "invalidemail", null);
|
updateProfilePage.update("New first", "New last", "invalidemail");
|
||||||
|
|
||||||
updateProfilePage.assertCurrent();
|
updateProfilePage.assertCurrent();
|
||||||
|
|
||||||
|
@ -189,7 +185,6 @@ public class RequiredActionUpdateProfileTest {
|
||||||
Assert.assertEquals("New first", updateProfilePage.getFirstName());
|
Assert.assertEquals("New first", updateProfilePage.getFirstName());
|
||||||
Assert.assertEquals("New last", updateProfilePage.getLastName());
|
Assert.assertEquals("New last", updateProfilePage.getLastName());
|
||||||
Assert.assertEquals("invalidemail", updateProfilePage.getEmail());
|
Assert.assertEquals("invalidemail", updateProfilePage.getEmail());
|
||||||
Assert.assertEquals("", updateProfilePage.getAttributeStreet());
|
|
||||||
|
|
||||||
Assert.assertEquals("Invalid email address.", updateProfilePage.getError());
|
Assert.assertEquals("Invalid email address.", updateProfilePage.getError());
|
||||||
|
|
||||||
|
@ -204,7 +199,7 @@ public class RequiredActionUpdateProfileTest {
|
||||||
|
|
||||||
updateProfilePage.assertCurrent();
|
updateProfilePage.assertCurrent();
|
||||||
|
|
||||||
updateProfilePage.update("New first", "New last", "keycloak-user@localhost", null);
|
updateProfilePage.update("New first", "New last", "keycloak-user@localhost");
|
||||||
|
|
||||||
updateProfilePage.assertCurrent();
|
updateProfilePage.assertCurrent();
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ import org.keycloak.testsuite.pages.VerifyEmailPage;
|
||||||
import org.keycloak.testsuite.rule.GreenMailRule;
|
import org.keycloak.testsuite.rule.GreenMailRule;
|
||||||
import org.keycloak.testsuite.rule.WebResource;
|
import org.keycloak.testsuite.rule.WebResource;
|
||||||
import org.keycloak.testsuite.rule.WebRule;
|
import org.keycloak.testsuite.rule.WebRule;
|
||||||
|
import org.keycloak.util.JsonSerialization;
|
||||||
import org.openqa.selenium.By;
|
import org.openqa.selenium.By;
|
||||||
import org.openqa.selenium.NoSuchElementException;
|
import org.openqa.selenium.NoSuchElementException;
|
||||||
import org.openqa.selenium.WebDriver;
|
import org.openqa.selenium.WebDriver;
|
||||||
|
@ -451,7 +452,7 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
doAfterProviderAuthentication();
|
doAfterProviderAuthentication();
|
||||||
|
|
||||||
this.updateProfilePage.assertCurrent();
|
this.updateProfilePage.assertCurrent();
|
||||||
this.updateProfilePage.update("Test", "User", "psilva@redhat.com", null);
|
this.updateProfilePage.update("Test", "User", "psilva@redhat.com");
|
||||||
|
|
||||||
WebElement element = this.driver.findElement(By.className("kc-feedback-text"));
|
WebElement element = this.driver.findElement(By.className("kc-feedback-text"));
|
||||||
|
|
||||||
|
@ -460,7 +461,7 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
assertEquals("Email already exists.", element.getText());
|
assertEquals("Email already exists.", element.getText());
|
||||||
|
|
||||||
this.updateProfilePage.assertCurrent();
|
this.updateProfilePage.assertCurrent();
|
||||||
this.updateProfilePage.update("Test", "User", "test-user@redhat.com", null);
|
this.updateProfilePage.update("Test", "User", "test-user@redhat.com");
|
||||||
|
|
||||||
assertTrue(this.driver.getCurrentUrl().startsWith("http://localhost:8081/test-app"));
|
assertTrue(this.driver.getCurrentUrl().startsWith("http://localhost:8081/test-app"));
|
||||||
|
|
||||||
|
@ -724,7 +725,7 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
|
|
||||||
// update profile
|
// update profile
|
||||||
this.updateProfilePage.assertCurrent();
|
this.updateProfilePage.assertCurrent();
|
||||||
this.updateProfilePage.update(userFirstName, userLastName, userEmail, null);
|
this.updateProfilePage.update(userFirstName, userLastName, userEmail);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -801,10 +802,9 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
UserSessionStatus sessionStatus = null;
|
UserSessionStatus sessionStatus = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
|
||||||
String pageSource = this.driver.getPageSource();
|
String pageSource = this.driver.getPageSource();
|
||||||
|
|
||||||
sessionStatus = objectMapper.readValue(pageSource.getBytes(), UserSessionStatus.class);
|
sessionStatus = JsonSerialization.readValue(pageSource.getBytes(), UserSessionStatus.class);
|
||||||
} catch (IOException ignore) {
|
} catch (IOException ignore) {
|
||||||
ignore.printStackTrace();
|
ignore.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
|
@ -245,7 +245,6 @@ public class FederationProvidersIntegrationTest {
|
||||||
Assert.assertEquals("John", profilePage.getFirstName());
|
Assert.assertEquals("John", profilePage.getFirstName());
|
||||||
Assert.assertEquals("Doe", profilePage.getLastName());
|
Assert.assertEquals("Doe", profilePage.getLastName());
|
||||||
Assert.assertEquals("john@email.org", profilePage.getEmail());
|
Assert.assertEquals("john@email.org", profilePage.getEmail());
|
||||||
Assert.assertEquals("1234", profilePage.getPostalCode());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -296,12 +295,12 @@ public class FederationProvidersIntegrationTest {
|
||||||
registerPage.assertCurrent();
|
registerPage.assertCurrent();
|
||||||
|
|
||||||
// check existing username
|
// check existing username
|
||||||
registerPage.register("firstName", "lastName", "email@mail.cz", "existing", "Password1", "Password1", null);
|
registerPage.register("firstName", "lastName", "email@mail.cz", "existing", "Password1", "Password1");
|
||||||
registerPage.assertCurrent();
|
registerPage.assertCurrent();
|
||||||
Assert.assertEquals("Username already exists.", registerPage.getError());
|
Assert.assertEquals("Username already exists.", registerPage.getError());
|
||||||
|
|
||||||
// Check existing email
|
// Check existing email
|
||||||
registerPage.register("firstName", "lastName", "existing@email.org", "nonExisting", "Password1", "Password1", null);
|
registerPage.register("firstName", "lastName", "existing@email.org", "nonExisting", "Password1", "Password1");
|
||||||
registerPage.assertCurrent();
|
registerPage.assertCurrent();
|
||||||
Assert.assertEquals("Email already exists.", registerPage.getError());
|
Assert.assertEquals("Email already exists.", registerPage.getError());
|
||||||
}
|
}
|
||||||
|
@ -312,7 +311,7 @@ public class FederationProvidersIntegrationTest {
|
||||||
loginPage.clickRegister();
|
loginPage.clickRegister();
|
||||||
registerPage.assertCurrent();
|
registerPage.assertCurrent();
|
||||||
|
|
||||||
registerPage.register("firstName", "lastName", "email2@check.cz", "registerUserSuccess2", "Password1", "Password1", null);
|
registerPage.register("firstName", "lastName", "email2@check.cz", "registerUserSuccess2", "Password1", "Password1");
|
||||||
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||||
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
KeycloakSession session = keycloakRule.startSession();
|
||||||
|
|
|
@ -77,7 +77,7 @@ public class RegisterTest {
|
||||||
loginPage.clickRegister();
|
loginPage.clickRegister();
|
||||||
registerPage.assertCurrent();
|
registerPage.assertCurrent();
|
||||||
|
|
||||||
registerPage.register("firstName", "lastName", "registerExistingUser@email", "test-user@localhost", "password", "password", "mystreet");
|
registerPage.register("firstName", "lastName", "registerExistingUser@email", "test-user@localhost", "password", "password");
|
||||||
|
|
||||||
registerPage.assertCurrent();
|
registerPage.assertCurrent();
|
||||||
Assert.assertEquals("Username already exists.", registerPage.getError());
|
Assert.assertEquals("Username already exists.", registerPage.getError());
|
||||||
|
@ -89,7 +89,6 @@ public class RegisterTest {
|
||||||
Assert.assertEquals("", registerPage.getUsername());
|
Assert.assertEquals("", registerPage.getUsername());
|
||||||
Assert.assertEquals("", registerPage.getPassword());
|
Assert.assertEquals("", registerPage.getPassword());
|
||||||
Assert.assertEquals("", registerPage.getPasswordConfirm());
|
Assert.assertEquals("", registerPage.getPasswordConfirm());
|
||||||
Assert.assertEquals("mystreet", registerPage.getAttributeStreet());
|
|
||||||
|
|
||||||
events.expectRegister("test-user@localhost", "registerExistingUser@email")
|
events.expectRegister("test-user@localhost", "registerExistingUser@email")
|
||||||
.removeDetail(Details.EMAIL)
|
.removeDetail(Details.EMAIL)
|
||||||
|
@ -102,7 +101,7 @@ public class RegisterTest {
|
||||||
loginPage.clickRegister();
|
loginPage.clickRegister();
|
||||||
registerPage.assertCurrent();
|
registerPage.assertCurrent();
|
||||||
|
|
||||||
registerPage.register("firstName", "lastName", "registerUserInvalidPasswordConfirm@email", "registerUserInvalidPasswordConfirm", "password", "invalid", null);
|
registerPage.register("firstName", "lastName", "registerUserInvalidPasswordConfirm@email", "registerUserInvalidPasswordConfirm", "password", "invalid");
|
||||||
|
|
||||||
registerPage.assertCurrent();
|
registerPage.assertCurrent();
|
||||||
Assert.assertEquals("Password confirmation doesn't match.", registerPage.getError());
|
Assert.assertEquals("Password confirmation doesn't match.", registerPage.getError());
|
||||||
|
@ -114,7 +113,6 @@ public class RegisterTest {
|
||||||
Assert.assertEquals("registerUserInvalidPasswordConfirm", registerPage.getUsername());
|
Assert.assertEquals("registerUserInvalidPasswordConfirm", registerPage.getUsername());
|
||||||
Assert.assertEquals("", registerPage.getPassword());
|
Assert.assertEquals("", registerPage.getPassword());
|
||||||
Assert.assertEquals("", registerPage.getPasswordConfirm());
|
Assert.assertEquals("", registerPage.getPasswordConfirm());
|
||||||
Assert.assertEquals("", registerPage.getAttributeStreet());
|
|
||||||
|
|
||||||
events.expectRegister("registerUserInvalidPasswordConfirm", "registerUserInvalidPasswordConfirm@email")
|
events.expectRegister("registerUserInvalidPasswordConfirm", "registerUserInvalidPasswordConfirm@email")
|
||||||
.removeDetail(Details.USERNAME)
|
.removeDetail(Details.USERNAME)
|
||||||
|
@ -128,7 +126,7 @@ public class RegisterTest {
|
||||||
loginPage.clickRegister();
|
loginPage.clickRegister();
|
||||||
registerPage.assertCurrent();
|
registerPage.assertCurrent();
|
||||||
|
|
||||||
registerPage.register("firstName", "lastName", "registerUserMissingPassword@email", "registerUserMissingPassword", null, null, null);
|
registerPage.register("firstName", "lastName", "registerUserMissingPassword@email", "registerUserMissingPassword", null, null);
|
||||||
|
|
||||||
registerPage.assertCurrent();
|
registerPage.assertCurrent();
|
||||||
Assert.assertEquals("Please specify password.", registerPage.getError());
|
Assert.assertEquals("Please specify password.", registerPage.getError());
|
||||||
|
@ -153,7 +151,7 @@ public class RegisterTest {
|
||||||
loginPage.clickRegister();
|
loginPage.clickRegister();
|
||||||
registerPage.assertCurrent();
|
registerPage.assertCurrent();
|
||||||
|
|
||||||
registerPage.register("firstName", "lastName", "registerPasswordPolicy@email", "registerPasswordPolicy", "pass", "pass", null);
|
registerPage.register("firstName", "lastName", "registerPasswordPolicy@email", "registerPasswordPolicy", "pass", "pass");
|
||||||
|
|
||||||
registerPage.assertCurrent();
|
registerPage.assertCurrent();
|
||||||
Assert.assertEquals("Invalid password: minimum length 8.", registerPage.getError());
|
Assert.assertEquals("Invalid password: minimum length 8.", registerPage.getError());
|
||||||
|
@ -163,7 +161,7 @@ public class RegisterTest {
|
||||||
.removeDetail(Details.EMAIL)
|
.removeDetail(Details.EMAIL)
|
||||||
.user((String) null).error("invalid_registration").assertEvent();
|
.user((String) null).error("invalid_registration").assertEvent();
|
||||||
|
|
||||||
registerPage.register("firstName", "lastName", "registerPasswordPolicy@email", "registerPasswordPolicy", "password", "password", null);
|
registerPage.register("firstName", "lastName", "registerPasswordPolicy@email", "registerPasswordPolicy", "password", "password");
|
||||||
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||||
|
|
||||||
String userId = events.expectRegister("registerPasswordPolicy", "registerPasswordPolicy@email").assertEvent().getUserId();
|
String userId = events.expectRegister("registerPasswordPolicy", "registerPasswordPolicy@email").assertEvent().getUserId();
|
||||||
|
@ -185,7 +183,7 @@ public class RegisterTest {
|
||||||
loginPage.clickRegister();
|
loginPage.clickRegister();
|
||||||
registerPage.assertCurrent();
|
registerPage.assertCurrent();
|
||||||
|
|
||||||
registerPage.register("firstName", "lastName", "registerUserMissingUsername@email", null, "password", "password", null);
|
registerPage.register("firstName", "lastName", "registerUserMissingUsername@email", null, "password", "password");
|
||||||
|
|
||||||
registerPage.assertCurrent();
|
registerPage.assertCurrent();
|
||||||
Assert.assertEquals("Please specify username.", registerPage.getError());
|
Assert.assertEquals("Please specify username.", registerPage.getError());
|
||||||
|
@ -202,14 +200,14 @@ public class RegisterTest {
|
||||||
loginPage.clickRegister();
|
loginPage.clickRegister();
|
||||||
registerPage.assertCurrent();
|
registerPage.assertCurrent();
|
||||||
|
|
||||||
registerPage.register("firstName", "lastName", null, "registerUserMissingEmail", "password", "password", null);
|
registerPage.register("firstName", "lastName", null, "registerUserMissingEmail", "password", "password");
|
||||||
registerPage.assertCurrent();
|
registerPage.assertCurrent();
|
||||||
Assert.assertEquals("Please specify email.", registerPage.getError());
|
Assert.assertEquals("Please specify email.", registerPage.getError());
|
||||||
events.expectRegister("registerUserMissingEmail", null)
|
events.expectRegister("registerUserMissingEmail", null)
|
||||||
.removeDetail("email")
|
.removeDetail("email")
|
||||||
.error("invalid_registration").assertEvent();
|
.error("invalid_registration").assertEvent();
|
||||||
|
|
||||||
registerPage.register("firstName", "lastName", "registerUserInvalidEmailemail", "registerUserInvalidEmail", "password", "password", null);
|
registerPage.register("firstName", "lastName", "registerUserInvalidEmailemail", "registerUserInvalidEmail", "password", "password");
|
||||||
registerPage.assertCurrent();
|
registerPage.assertCurrent();
|
||||||
Assert.assertEquals("Invalid email address.", registerPage.getError());
|
Assert.assertEquals("Invalid email address.", registerPage.getError());
|
||||||
events.expectRegister("registerUserInvalidEmail", "registerUserInvalidEmailemail")
|
events.expectRegister("registerUserInvalidEmail", "registerUserInvalidEmailemail")
|
||||||
|
@ -222,7 +220,7 @@ public class RegisterTest {
|
||||||
loginPage.clickRegister();
|
loginPage.clickRegister();
|
||||||
registerPage.assertCurrent();
|
registerPage.assertCurrent();
|
||||||
|
|
||||||
registerPage.register("firstName", "lastName", "registerUserSuccess@email", "registerUserSuccess", "password", "password", "myStreet");
|
registerPage.register("firstName", "lastName", "registerUserSuccess@email", "registerUserSuccess", "password", "password");
|
||||||
|
|
||||||
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||||
|
|
||||||
|
@ -239,7 +237,6 @@ public class RegisterTest {
|
||||||
Assert.assertEquals("registerusersuccess@email", user.getEmail());
|
Assert.assertEquals("registerusersuccess@email", user.getEmail());
|
||||||
Assert.assertEquals("firstName", user.getFirstName());
|
Assert.assertEquals("firstName", user.getFirstName());
|
||||||
Assert.assertEquals("lastName", user.getLastName());
|
Assert.assertEquals("lastName", user.getLastName());
|
||||||
Assert.assertEquals("myStreet", user.getAttribute("street").get(0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected UserModel getUser(String userId) {
|
protected UserModel getUser(String userId) {
|
||||||
|
|
|
@ -47,9 +47,6 @@ public class AccountUpdateProfilePage extends AbstractAccountPage {
|
||||||
@FindBy(id = "email")
|
@FindBy(id = "email")
|
||||||
private WebElement emailInput;
|
private WebElement emailInput;
|
||||||
|
|
||||||
@FindBy(id = "user.attributes.postal_code")
|
|
||||||
private WebElement postalCodeInput;
|
|
||||||
|
|
||||||
|
|
||||||
@FindBy(id = "referrer")
|
@FindBy(id = "referrer")
|
||||||
private WebElement backToApplicationLink;
|
private WebElement backToApplicationLink;
|
||||||
|
@ -107,10 +104,6 @@ public class AccountUpdateProfilePage extends AbstractAccountPage {
|
||||||
return lastNameInput.getAttribute("value");
|
return lastNameInput.getAttribute("value");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPostalCode() {
|
|
||||||
return postalCodeInput.getAttribute("value");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEmail() {
|
public String getEmail() {
|
||||||
return emailInput.getAttribute("value");
|
return emailInput.getAttribute("value");
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,25 +38,19 @@ public class LoginUpdateProfilePage extends AbstractPage {
|
||||||
@FindBy(id = "email")
|
@FindBy(id = "email")
|
||||||
private WebElement emailInput;
|
private WebElement emailInput;
|
||||||
|
|
||||||
@FindBy(id = "user.attributes.street")
|
|
||||||
private WebElement attributeStreetInput;
|
|
||||||
|
|
||||||
@FindBy(css = "input[type=\"submit\"]")
|
@FindBy(css = "input[type=\"submit\"]")
|
||||||
private WebElement submitButton;
|
private WebElement submitButton;
|
||||||
|
|
||||||
@FindBy(className = "feedback-error")
|
@FindBy(className = "feedback-error")
|
||||||
private WebElement loginErrorMessage;
|
private WebElement loginErrorMessage;
|
||||||
|
|
||||||
public void update(String firstName, String lastName, String email, String attributeStreet) {
|
public void update(String firstName, String lastName, String email) {
|
||||||
firstNameInput.clear();
|
firstNameInput.clear();
|
||||||
firstNameInput.sendKeys(firstName);
|
firstNameInput.sendKeys(firstName);
|
||||||
lastNameInput.clear();
|
lastNameInput.clear();
|
||||||
lastNameInput.sendKeys(lastName);
|
lastNameInput.sendKeys(lastName);
|
||||||
emailInput.clear();
|
emailInput.clear();
|
||||||
emailInput.sendKeys(email);
|
emailInput.sendKeys(email);
|
||||||
attributeStreetInput.clear();
|
|
||||||
if (attributeStreet != null)
|
|
||||||
attributeStreetInput.sendKeys(attributeStreet);
|
|
||||||
submitButton.click();
|
submitButton.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,10 +70,6 @@ public class LoginUpdateProfilePage extends AbstractPage {
|
||||||
return emailInput.getAttribute("value");
|
return emailInput.getAttribute("value");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAttributeStreet() {
|
|
||||||
return attributeStreetInput.getAttribute("value");
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCurrent() {
|
public boolean isCurrent() {
|
||||||
return driver.getTitle().equals("Update Account Information");
|
return driver.getTitle().equals("Update Account Information");
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,16 +51,13 @@ public class RegisterPage extends AbstractPage {
|
||||||
@FindBy(id = "password-confirm")
|
@FindBy(id = "password-confirm")
|
||||||
private WebElement passwordConfirmInput;
|
private WebElement passwordConfirmInput;
|
||||||
|
|
||||||
@FindBy(id = "user.attributes.street")
|
|
||||||
private WebElement attributeStreetInput;
|
|
||||||
|
|
||||||
@FindBy(css = "input[type=\"submit\"]")
|
@FindBy(css = "input[type=\"submit\"]")
|
||||||
private WebElement submitButton;
|
private WebElement submitButton;
|
||||||
|
|
||||||
@FindBy(className = "feedback-error")
|
@FindBy(className = "feedback-error")
|
||||||
private WebElement loginErrorMessage;
|
private WebElement loginErrorMessage;
|
||||||
|
|
||||||
public void register(String firstName, String lastName, String email, String username, String password, String passwordConfirm, String attributeStreet) {
|
public void register(String firstName, String lastName, String email, String username, String password, String passwordConfirm) {
|
||||||
firstNameInput.clear();
|
firstNameInput.clear();
|
||||||
if (firstName != null) {
|
if (firstName != null) {
|
||||||
firstNameInput.sendKeys(firstName);
|
firstNameInput.sendKeys(firstName);
|
||||||
|
@ -91,11 +88,6 @@ public class RegisterPage extends AbstractPage {
|
||||||
passwordConfirmInput.sendKeys(passwordConfirm);
|
passwordConfirmInput.sendKeys(passwordConfirm);
|
||||||
}
|
}
|
||||||
|
|
||||||
attributeStreetInput.clear();
|
|
||||||
if (attributeStreet != null) {
|
|
||||||
attributeStreetInput.sendKeys(attributeStreet);
|
|
||||||
}
|
|
||||||
|
|
||||||
submitButton.click();
|
submitButton.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,10 +155,6 @@ public class RegisterPage extends AbstractPage {
|
||||||
return passwordConfirmInput.getAttribute("value");
|
return passwordConfirmInput.getAttribute("value");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAttributeStreet() {
|
|
||||||
return attributeStreetInput.getAttribute("value");
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCurrent() {
|
public boolean isCurrent() {
|
||||||
return driver.getTitle().equals("Register with test");
|
return driver.getTitle().equals("Register with test");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue