Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Bill Burke 2014-10-29 11:42:36 -04:00
commit d289fa7402
21 changed files with 217 additions and 53 deletions

View file

@ -61,8 +61,8 @@ public class RealmRepresentation {
protected String accountTheme;
protected String adminTheme;
protected String emailTheme;
protected boolean eventsEnabled;
protected long eventsExpiration;
protected Boolean eventsEnabled;
protected Long eventsExpiration;
protected List<String> eventsListeners;
public String getId() {
@ -445,7 +445,7 @@ public class RealmRepresentation {
this.failureFactor = failureFactor;
}
public boolean isEventsEnabled() {
public Boolean isEventsEnabled() {
return eventsEnabled;
}
@ -453,7 +453,7 @@ public class RealmRepresentation {
this.eventsEnabled = eventsEnabled;
}
public long getEventsExpiration() {
public Long getEventsExpiration() {
return eventsExpiration;
}

View file

@ -8,7 +8,7 @@ import java.util.regex.Pattern;
*/
public class UriUtils {
private static final Pattern originPattern = Pattern.compile("(http://|https://)[\\w]+(\\.[\\w]+)*(:[\\d]{2,5})?");
private static final Pattern originPattern = Pattern.compile("(http://|https://)[\\w-]+(\\.[\\w-]+)*(:[\\d]{2,5})?");
public static String getOrigin(URI uri) {
return getOrigin(uri.toString());

View file

@ -24,6 +24,8 @@ public class UriUtilsTest {
assertValid("http://192.168.123.123");
assertValid("https://192.168.123.123");
assertValid("https://192.168.123.123:8080");
assertValid("https://sub-sub.test.com");
assertValid("https://sub.test-test.com");
assertInvalid("https://test/");
assertInvalid("{");

View file

@ -625,29 +625,74 @@ keycloak-war-dist-all-&project.version;/
<literal>X-Forwarded-Proto</literal> headers on the requests made to Keycloak. Next you need to enable
<literal>proxy-address-forwarding</literal> on the Keycloak http connector. Assuming that your reverse
proxy doesn't use port 8443 for SSL you also need to configure what port http traffic is redirected to.
This is done by editing <literal>standalone/configuration/standalone.xml</literal>.
</para>
First add <literal>proxy-address-forwarding</literal> and <literal>redirect-socket</literal> to the <literal>http-listener</literal>
element:
<para>
<section>
<title>WildFly</title>
<para>
Open <literal>standalone/configuration/standalone.xml</literal> in your favorite editor.
</para>
<para>
First add <literal>proxy-address-forwarding</literal> and <literal>redirect-socket</literal> to
the <literal>http-listener</literal> element:
<programlisting><![CDATA[<subsystem xmlns="urn:jboss:domain:undertow:1.1">
...
<http-listener name="default" socket-binding="http" proxy-address-forwarding="true" redirect-socket="proxy-https"/>
<http-listener name="default" socket-binding="http"
proxy-address-forwarding="true" redirect-socket="proxy-https"/>
...
</subsystem>
]]></programlisting>
Then add a new <literal>socket-binding</literal> element to the <literal>socket-binding-group</literal> element:
</para>
<para>
Then add a new <literal>socket-binding</literal> element to the <literal>socket-binding-group</literal> element:
<programlisting><![CDATA[
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
<socket-binding-group name="standard-sockets" default-interface="public"
port-offset="${jboss.socket.binding.port-offset:0}">
...
<socket-binding name="proxy-https" port="443"/>
...
</socket-binding-group>
]]></programlisting>
</para>
<para>
Check the <ulink url="https://docs.jboss.org/author/display/WFLY8/Undertow+(web)+subsystem+configuration">WildFly</ulink> documentation for more information.
</para>
</para>
<para>
Check the <ulink url="https://docs.jboss.org/author/display/WFLY8/Undertow+(web)+subsystem+configuration">WildFly</ulink> documentation for more information.
</para>
</section>
<section>
<title>AS7/EAP</title>
<para>
Open <literal>standalone/configuration/standalone.xml</literal> in your favorite editor.
</para>
<para>
You need to add <literal>redirect-port</literal> to http <literal>connector</literal> element and
add the <literal>RemoteIpValve</literal> valve:
<programlisting><![CDATA[
<subsystem xmlns="urn:jboss:domain:web:1.5"
default-virtual-server="default-host" native="false">
<connector name="http" protocol="HTTP/1.1" scheme="http"
socket-binding="http"
redirect-port="443"/>
<virtual-server name="default-host" enable-welcome-root="true">
<alias name="localhost"/>
<alias name="example.com"/>
</virtual-server>
<valve name="remoteipvalve" module="org.jboss.as.web"
class-name="org.apache.catalina.valves.RemoteIpValve">
<param param-name="protocolHeader" param-value="x-forwarded-proto"/>
</valve>
</subsystem>
]]></programlisting>
</para>
</section>
</section>
<section>

View file

@ -40,9 +40,9 @@ public enum EventType {
SEND_VERIFY_EMAIL_ERROR,
SEND_RESET_PASSWORD,
SEND_RESET_PASSWORD_ERROR,
SOCIAL_LOGIN,
SOCIAL_LOGIN_ERROR,
INVALID_SIGNATURE_ERROR,
REGISTER_NODE,
UNREGISTER_NODE
}

View file

@ -1,4 +1,4 @@
authenticatorCode=One-time-password
authenticatorCode=One-time code
email=Email
errorHeader=Error!
firstName=First name
@ -23,8 +23,8 @@ invalidTotp=Invalid authenticator code
readOnlyUser=You can't update your account as it is read only
readOnlyPassword=You can't update your password as your account is read only
successTotp=Google authenticator configured.
successTotpRemoved=Google authenticator removed.
successTotp=Mobile authenticator configured.
successTotpRemoved=Mobile authenticator removed.
accountUpdated=Your account has been updated
accountPasswordUpdated=Your password has been updated

View file

@ -12,25 +12,32 @@
</thead>
<tbody>
<tr>
<td class="provider"><span class="social googleplus">FreeOTP</span></td>
<td class="provider">Mobile</td>
<td class="action">
<a id="remove-google" href="${url.totpRemoveUrl}"><i class="pficon pficon-delete"></i></a>
<a id="remove-mobile" href="${url.totpRemoveUrl}"><i class="pficon pficon-delete"></i></a>
</td>
</tr>
</tbody>
</table>
<#else>
<h2>Google Authenticator Setup</h2>
<h2>Authenticator</h2>
<hr/>
<ol>
<li>Download the <a href="https://fedorahosted.org/freeotp/" target="_blank">FreeOTP app</a> in your device.</li>
<li>Create an account in FreeOTP and scan the barcode or type in the provided key below.<br/>
<li>
Install <a href="https://fedorahosted.org/freeotp/" target="_blank">FreeOTP</a> or
<a href="http://code.google.com/p/google-authenticator/" target="_blank">Google Authenticator</a>
on your mobile
</li>
<li>
Open the application and scan the barcode or enter the key<br/>
<img src="${totp.totpSecretQrCodeUrl}" alt="Figure: Barcode"><br/>
<span class="code">${totp.totpSecretEncoded}</span>
</li>
<li>Enter the one-time-password provided by FreeOTP below and click Submit to finish the setup.</li>
<li>
Enter the one-time code provided by the application and click Submit to finish the setup.
</li>
</ol>
<hr/>

View file

@ -282,7 +282,7 @@ module.controller('OAuthClientInstallationCtrl', function($scope, realm, install
$scope.installation = installation;
$scope.download = function() {
saveAs(new Blob([$scope.installation], { type: $scope.type }), 'keycloak.json');
saveAs(new Blob([angular.toJson($scope.installation, true)], { type: 'application/json' }), 'keycloak.json');
}
});

View file

@ -1,8 +1,5 @@
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="'partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<ul class="nav nav-tabs nav-tabs-pf">
<li class="active"><a href="">Application List</a></li>
</ul>
<h2></h2>
<div id="content">
<h2><span>{{realm.realm}}</span> Applications <span tooltip-placement="right" tooltip="Applications are trusted browser apps and web services in a realm. These applications can request a login. You can also define application specific roles." class="fa fa-info-circle"></span></h2>

View file

@ -1,8 +1,5 @@
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="'partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<ul class="nav nav-tabs nav-tabs-pf">
<li class="active"><a href="">OAuth List</a></li>
</ul>
<h2></h2>
<div id="content">
<h2><span>{{realm.realm}}</span> OAuth Clients <span tooltip-placement="right" tooltip="OAuth clients are like applicatoins, but are only granted temporary access. In browser apps, users will be queried to explicitly grant access." class="fa fa-info-circle"></span></h2>

View file

@ -1,4 +1,4 @@
<ul class="nav nav-tabs nav-tabs-pf" data-ng-show="!create">
<ul class="nav nav-tabs nav-tabs-pf" data-ng-hide="create && !path[4]">
<li ng-class="{active: !path[4]}"><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">Settings</a></li>
<li ng-class="{active: path[4] == 'credentials'}" data-ng-show="!application.publicClient && application.protocol != 'saml'"><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/credentials">Credentials</a></li>
<li ng-class="{active: path[4] == 'saml'}" data-ng-show="application.protocol == 'saml' && (application.attributes['saml.client.signature'] == 'true' || application.attributes['saml.encrypt'] == 'true')"><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/saml/keys">SAML Keys</a></li>

View file

@ -30,13 +30,16 @@
<#elseif section = "info" >
<ol id="kc-totp-settings">
<li>
<p>${rb.loginTotpStep1_1} <a href="https://fedorahosted.org/freeotp/" target="_blank">${rb.loginTotpStep1_2}</a> ${rb.loginTotpStep1_3}</p>
<p>${rb.loginTotpStep1}</p>
</li>
<li>
<p>${rb.loginTotpStep2}</p>
<img src="${totp.totpSecretQrCodeUrl}" alt="Figure: Barcode"><br/>
<span class="code">${totp.totpSecretEncoded}</span>
</li>
<li>
<p>${rb.loginTotpStep3}</p>
</li>
</ol>
</#if>
</@layout.registrationLayout>

View file

@ -26,7 +26,7 @@ submit=Submit
yes=Yes
no=No
authenticatorCode=One-time-password
authenticatorCode=One-time code
clientCertificate=Client Certificate
invalidUser=Invalid username or password.
@ -47,8 +47,8 @@ invalidPasswordExisting=Invalid existing password
invalidPasswordConfirm=Password confirmation doesn't match
invalidTotp=Invalid authenticator code
successTotp=FreeOTP authenticator configured.
successTotpRemoved=FreeOTP authenticator removed.
successTotp=Mobile authenticator configured.
successTotpRemoved=Mobile authenticator removed.
usernameExists=Username already exists
emailExists=Email already exists
@ -60,13 +60,11 @@ loginOauthTitle=Temporary access.
loginOauthTitleHtml=Temporary access requested. Login to grant access.
loginForgot=Forgot
loginTotpTitle=FreeOTP Authenticator Setup
loginTotpStep1_1=Download the
loginTotpStep1_2=FreeOTP Authenticator app
loginTotpStep1_3=in your device.
loginTotpStep2=Create an account in FreeOTP and scan the barcode or type in the provided key below.
loginTotpStep3=Enter the one-time-password provided by FreeOTP below and click Submit to finish the setup.
loginTotpOneTime=One-time-password
loginTotpTitle=Mobile Authenticator Setup
loginTotpStep1=Install <a href="https://fedorahosted.org/freeotp/" target="_blank">FreeOTP</a> or <a href="http://code.google.com/p/google-authenticator/" target="_blank">Google Authenticator</a> on your mobile
loginTotpStep2=Open the application and scan the barcode or enter the key
loginTotpStep3=Enter the one-time code provided by the application and click Submit to finish the setup
loginTotpOneTime=One-time code
loginProfileTitle=Update Account Information
loginProfileWarning=Your account is not enabled because you need to update your account information.
@ -91,7 +89,7 @@ errorTitle=We're sorry...
errorTitleHtml=We're <strong>sorry</strong> ...
errorGenericMsg=Something happened and we could not process your request.
actionWarningHeader=Your account is not enabled.
actionTotpWarning=You need to set up the FreeOTP Authenticator to activate your account.
actionTotpWarning=You need to set up Mobile Authenticator to activate your account.
actionProfileWarning=You need to update your user profile to activate your account.
actionPasswordWarning=You need to change your password to activate your account.
actionEmailWarning=You need to verify your email address to activate your account.

View file

@ -10,7 +10,7 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-adapter-core</artifactId>
<name>Keycloak AS7 Integration</name>
<name>Keycloak Adapter Core</name>
<description/>
<dependencies>

View file

@ -52,6 +52,9 @@ public class RepresentationToModel {
if (rep.getQuickLoginCheckMilliSeconds() != null) newRealm.setQuickLoginCheckMilliSeconds(rep.getQuickLoginCheckMilliSeconds());
if (rep.getMaxDeltaTimeSeconds() != null) newRealm.setMaxDeltaTimeSeconds(rep.getMaxDeltaTimeSeconds());
if (rep.getFailureFactor() != null) newRealm.setFailureFactor(rep.getFailureFactor());
if (rep.isEventsEnabled() != null) newRealm.setEventsEnabled(rep.isEventsEnabled());
if (rep.getEventsExpiration() != null) newRealm.setEventsExpiration(rep.getEventsExpiration());
if (rep.getEventsListeners() != null) newRealm.setEventsListeners(new HashSet<String>(rep.getEventsListeners()));
if (rep.getNotBefore() != null) newRealm.setNotBefore(rep.getNotBefore());
@ -263,6 +266,9 @@ public class RepresentationToModel {
if (rep.getAccountTheme() != null) realm.setAccountTheme(rep.getAccountTheme());
if (rep.getAdminTheme() != null) realm.setAdminTheme(rep.getAdminTheme());
if (rep.getEmailTheme() != null) realm.setEmailTheme(rep.getEmailTheme());
if (rep.isEventsEnabled() != null) realm.setEventsEnabled(rep.isEventsEnabled());
if (rep.getEventsExpiration() != null) realm.setEventsExpiration(rep.getEventsExpiration());
if (rep.getEventsListeners() != null) realm.setEventsListeners(new HashSet<String>(rep.getEventsListeners()));
if (rep.getPasswordPolicy() != null) realm.setPasswordPolicy(new PasswordPolicy(rep.getPasswordPolicy()));

109
pom.xml
View file

@ -516,6 +516,29 @@
<excludePackageNames>
com.restfully.*:org.jboss.resteasy.examples.*:se.unlogic.*:org.jboss.resteasy.tests.*
</excludePackageNames>
<archive>
<index>true</index>
<manifest>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Implementation-URL>${project.url}</Implementation-URL>
<Java-Version>${java.version}</Java-Version>
<Java-Vendor>${java.vendor}</Java-Vendor>
<Os-Name>${os.name}</Os-Name>
<Os-Arch>${os.arch}</Os-Arch>
<Os-Version>${os.version}</Os-Version>
<Scm-Url>${project.scm.url}</Scm-Url>
<Scm-Connection>${project.scm.connection}</Scm-Connection>
<Scm-Revision>${buildNumber}</Scm-Revision>
<Build-Timestamp>${build.datetime}</Build-Timestamp>
<Specification-Vendor>JBoss (http://www.jboss.org/)</Specification-Vendor>
<Implementation-URL>http://www.jboss.org/</Implementation-URL>
<Implementation-Vendor>JBoss by Red Hat, Inc</Implementation-Vendor>
<Implementation-Vendor-Id>http://www.jboss.org/</Implementation-Vendor-Id>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
@ -530,6 +553,31 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<configuration>
<archive>
<index>true</index>
<manifest>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Implementation-URL>${project.url}</Implementation-URL>
<Java-Version>${java.version}</Java-Version>
<Java-Vendor>${java.vendor}</Java-Vendor>
<Os-Name>${os.name}</Os-Name>
<Os-Arch>${os.arch}</Os-Arch>
<Os-Version>${os.version}</Os-Version>
<Scm-Url>${project.scm.url}</Scm-Url>
<Scm-Connection>${project.scm.connection}</Scm-Connection>
<Scm-Revision>${buildNumber}</Scm-Revision>
<Build-Timestamp>${build.datetime}</Build-Timestamp>
<Specification-Vendor>JBoss (http://www.jboss.org/)</Specification-Vendor>
<Implementation-URL>http://www.jboss.org/</Implementation-URL>
<Implementation-Vendor>JBoss by Red Hat, Inc</Implementation-Vendor>
<Implementation-Vendor-Id>http://www.jboss.org/</Implementation-Vendor-Id>
</manifestEntries>
</archive>
</configuration>
<executions>
<execution>
<phase>verify</phase>
@ -566,6 +614,31 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<configuration>
<archive>
<index>true</index>
<manifest>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Implementation-URL>${project.url}</Implementation-URL>
<Java-Version>${java.version}</Java-Version>
<Java-Vendor>${java.vendor}</Java-Vendor>
<Os-Name>${os.name}</Os-Name>
<Os-Arch>${os.arch}</Os-Arch>
<Os-Version>${os.version}</Os-Version>
<Scm-Url>${project.scm.url}</Scm-Url>
<Scm-Connection>${project.scm.connection}</Scm-Connection>
<Scm-Revision>${buildNumber}</Scm-Revision>
<Build-Timestamp>${build.datetime}</Build-Timestamp>
<Specification-Vendor>JBoss (http://www.jboss.org/)</Specification-Vendor>
<Implementation-URL>http://www.jboss.org/</Implementation-URL>
<Implementation-Vendor>JBoss by Red Hat, Inc</Implementation-Vendor>
<Implementation-Vendor-Id>http://www.jboss.org/</Implementation-Vendor-Id>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
@ -604,6 +677,11 @@
<!-- set to ${liquibase.version} once Liquibase 3.2.3 is released (https://liquibase.jira.com/browse/CORE-1987) -->
<version>3.1.1</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.3</version>
</plugin>
</plugins>
</pluginManagement>
@ -658,6 +736,37 @@
<artifactId>maven-clover2-plugin</artifactId>
<version>3.1.6</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<executions>
<execution>
<id>get-build-timestamp</id>
<phase>initialize</phase>
<goals>
<goal>create-timestamp</goal>
</goals>
<configuration>
<!-- Example date: Wed, 4 Jul 2001 12:08:56 -0700 -->
<timestampFormat>EEE, d MMM yyyy HH:mm:ss Z</timestampFormat>
<timestampPropertyName>build.datetime</timestampPropertyName>
</configuration>
</execution>
<execution>
<id>get-scm-revision</id>
<phase>initialize</phase>
<goals>
<goal>create</goal>
</goals>
<configuration>
<doCheck>false</doCheck>
<doUpdate>false</doUpdate>
<revisionOnScmFailure>UNKNOWN</revisionOnScmFailure>
<getRevisionOnlyOnce>true</getRevisionOnlyOnce>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

View file

@ -121,7 +121,7 @@ public class SocialResource {
RealmModel realm = clientSession.getRealm();
EventBuilder event = new EventsManager(realm, session, clientConnection).createEventBuilder()
.event(EventType.SOCIAL_LOGIN)
.event(EventType.LOGIN)
.client(clientSession.getClient())
.detail(Details.REDIRECT_URI, clientSession.getRedirectUri())
.detail(Details.AUTH_METHOD, authMethod);

View file

@ -125,7 +125,7 @@ public class AssertEvents implements TestRule, EventListenerProviderFactory {
}
public ExpectedEvent expectSocialLogin() {
return expect(EventType.SOCIAL_LOGIN)
return expect(EventType.LOGIN)
.detail(Details.CODE_ID, isCodeId())
.detail(Details.USERNAME, DEFAULT_USERNAME)
.detail(Details.AUTH_METHOD, "form")

View file

@ -348,7 +348,7 @@ public class AccountTest {
totpPage.configure(totp.generate(totpPage.getTotpSecret()));
Assert.assertEquals("Google authenticator configured.", profilePage.getSuccess());
Assert.assertEquals("Mobile authenticator configured.", profilePage.getSuccess());
events.expectAccount(EventType.UPDATE_TOTP).assertEvent();

View file

@ -44,7 +44,7 @@ public class AccountTotpPage extends AbstractAccountPage {
@FindBy(css = "button[type=\"submit\"]")
private WebElement submitButton;
@FindBy(id = "remove-google")
@FindBy(id = "remove-mobile")
private WebElement removeLink;
public void configure(String totp) {

View file

@ -48,7 +48,7 @@ public class LoginConfigTotpPage extends AbstractPage {
}
public boolean isCurrent() {
return driver.getTitle().equals("FreeOTP Authenticator Setup");
return driver.getTitle().equals("Mobile Authenticator Setup");
}
public void open() {