Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Bill Burke 2016-10-04 20:13:16 -04:00
commit 67d3730c6d
11 changed files with 110 additions and 85 deletions

View file

@ -3,15 +3,19 @@ How to secure Fuse admin services
Fuse admin console authentication
---------------------------------
Fuse admin console is Hawt.io. See [Hawt.io documentation](http://hawt.io/docs/index.html) for more info about how to secure it with keycloak.
Fuse admin console is Hawt.io. See [Hawt.io documentation](http://hawt.io/docs/index.html) for more info about how to secure it with keycloak. The demo realm
has users `root` , `john` and `mary`, which you can test in similar way like described in the [Hawt.io README](https://github.com/hawtio/hawtio/blob/master/sample-keycloak-integration/README.md) .
WARN: Hawt.io version bundled in JBoss Fuse has Keycloak support from JBoss Fuse 6.3.1 . For JBoss Fuse 6.3.0 or older, if you want Keycloak integration, you need to uninstall the provided Hawt.io
version and replace it with the different one, which has Keycloak support. You can ideally use the Hawt.io community version 1.4.66 or newer.
SSH authentication with keycloak credentials on JBoss Fuse 6.1
--------------------------------------------------------------
SSH authentication with keycloak credentials on JBoss Fuse 6.2 or newer
-----------------------------------------------------------------------
Keycloak mainly addresses usecases for authentication of web applications, however if your admin services (like fuse admin console) are protected
with Keycloak, it may be good to protect non-web services like SSH with Keycloak credentials too. It's possible to do it by using JAAS login module, which
allows to remotely connect to Keycloak and verify credentials based on [Direct access grants](http://docs.jboss.org/keycloak/docs/1.1.0.Beta2/userguide/html/direct-access-grants.html).
allows to remotely connect to Keycloak and verify credentials based on [Direct grants](https://keycloak.gitbooks.io/server-adminstration-guide/content/v/2.2/topics/sso-protocols/oidc.html).
Example steps for enable SSH authentication:
@ -32,7 +36,7 @@ This file contains configuration of the client application, which is used by JAA
in [examples readme](../README.md), you can skip this step as `keycloak-jaas` is installed already. Otherwise use those commands (replace Keycloak version in this command with the current version):
```
features:addurl mvn:org.keycloak/keycloak-osgi-features/1.2.0.Beta1/xml/features
features:addurl mvn:org.keycloak/keycloak-osgi-features/2.2.1.Final/xml/features
features:install keycloak-jaas
```
@ -42,11 +46,17 @@ features:install keycloak-jaas
ssh -o PubkeyAuthentication=no -p 8101 admin@localhost
```
6) In JBoss Fuse 6.2 you may need to install `ssh` feature as it doesn't seem to be installed here by default.
```
features:install ssh
```
And login with password `password` . Note that other users from "demo" realm like bburke@redhat.com don't have SSH access as they don't have `admin` role.
JMX authentication with keycloak credentials on JBoss Fuse 6.1
--------------------------------------------------------------
JMX authentication with keycloak credentials on JBoss Fuse 6.2 or newer
-----------------------------------------------------------------------
This may be needed in case if you really want to use jconsole or other external tool to perform remote connection to JMX through RMI. Otherwise it may
be better to use just hawt.io/jolokia as jolokia agent is installed in hawt.io by default.
@ -69,16 +79,7 @@ Note again that users without `admin` role are not able to login as they are not
may be still able to access MBeans remotely via HTTP (Hawtio). So make sure to protect Hawt.io web console with same roles like JMX through RMI to
really protect JMX mbeans.
SSH and JMX on JBoss Fuse 6.2
-----------------------------
For SSH steps are very similar to above for 6.1. In JBoss Fuse 6.2 you may need to install `ssh` feature as it doesn't seem to be installed here by default.
```
features:install ssh
```
For JMX, the steps are similar like for Fuse 6.1, however there is more fine grained authorization for JMX access in Fuse 6.2.
For JMX, there is fine grained authorization for JMX access in Fuse 6.2.
Actually if you login as user `admin`, you have very limited privileges without possibility to do much JMX operations as this user has just `admin` role, which is not allowed to do much in JMX.

View file

@ -75,7 +75,7 @@
<select id="available" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedRealmRoles"
ng-options="r.name for r in realmRoles">
ng-options="r.name for r in realmRoles | orderBy:'name'">
</select>
<button ng-disabled="selectedRealmRoles.length == 0" class="btn btn-default" type="submit" ng-click="addRealmRole()">
{{:: 'add-selected' | translate}} <i class="fa fa-angle-double-right"></i>
@ -87,7 +87,7 @@
<select id="assigned" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedRealmMappings"
ng-options="r.name for r in realmMappings">
ng-options="r.name for r in realmMappings | orderBy:'name'">
</select>
<button ng-disabled="selectedRealmMappings.length == 0" class="btn btn-default" type="submit" ng-click="deleteRealmRole()">
<i class="fa fa-angle-double-left"></i> {{:: 'remove-selected' | translate}}
@ -100,7 +100,7 @@
<div class="form-group" ng-show="clients.length > 0 && !create && (compositeSwitch || role.composite)">
<label class="col-md-2 control-label" class="control-label">
<span>{{:: 'client-roles' | translate}}</span>
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="compositeClient" ng-options="a.clientId for a in clients" ng-disabled="false"></select>
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="compositeClient" ng-options="a.clientId for a in clients | orderBy:'clientId'" ng-disabled="false"></select>
</label>
<div class="col-md-10">
@ -114,7 +114,7 @@
<select id="available-client" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedClientRoles"
ng-options="r.name for r in clientRoles">
ng-options="r.name for r in clientRoles | orderBy:'name'">
</select>
<button ng-disabled="selectedClientRoles.length == 0" class="btn btn-default" type="submit" ng-click="addClientRole()">
{{:: 'add-selected' | translate}} <i class="fa fa-angle-double-right"></i>
@ -126,7 +126,7 @@
<select id="assigned-client" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedClientMappings"
ng-options="r.name for r in clientMappings">
ng-options="r.name for r in clientMappings | orderBy:'name'">
</select>
<button ng-disabled="selectedClientMappings.length == 0" class="btn btn-default" type="submit" ng-click="deleteClientRole()">
<i class="fa fa-angle-double-left"></i> {{:: 'remove-selected' | translate}}

View file

@ -53,7 +53,7 @@
<select id="available" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedRealmRoles"
ng-options="r.name for r in realmRoles">
ng-options="r.name for r in realmRoles | orderBy:'name'">
</select>
<button ng-disabled="selectedRealmRoles.length == 0" class="btn btn-default" type="submit" ng-click="addRealmRole()">
{{:: 'add-selected' | translate}} <i class="fa fa-angle-double-right"></i>
@ -65,7 +65,7 @@
<select id="assigned" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedRealmMappings"
ng-options="r.name for r in realmMappings">
ng-options="r.name for r in realmMappings | orderBy:'name'">
</select>
<button ng-disabled="selectedRealmMappings.length == 0" class="btn btn-default" type="submit" ng-click="deleteRealmRole()">
<i class="fa fa-angle-double-left"></i> {{:: 'remove-selected' | translate}}
@ -77,7 +77,7 @@
<select id="realm-composite" class="form-control" multiple size=5
disabled="true"
ng-model="dummymodel"
ng-options="r.name for r in realmComposite">
ng-options="r.name for r in realmComposite | orderBy:'name'">
</select>
</div>
</div>
@ -87,7 +87,7 @@
<div class="form-group">
<label class="col-md-2 control-label" class="control-label">
<span>{{:: 'client-roles' | translate}}</span>
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="targetClient" ng-options="a.clientId for a in clients" ng-disabled="false"></select>
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="targetClient" ng-options="a.clientId for a in clients | orderBy:'clientId'" ng-disabled="false"></select>
</label>
<div class="col-md-10">
@ -101,7 +101,7 @@
<select id="available-client" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedClientRoles"
ng-options="r.name for r in clientRoles">
ng-options="r.name for r in clientRoles | orderBy:'name'">
</select>
<button ng-disabled="selectedClientRoles.length == 0" class="btn btn-default" type="submit" ng-click="addClientRole()">
{{:: 'add-selected' | translate}} <i class="fa fa-angle-double-right"></i>
@ -113,7 +113,7 @@
<select id="assigned-client" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedClientMappings"
ng-options="r.name for r in clientMappings">
ng-options="r.name for r in clientMappings | orderBy:'name'">
</select>
<button ng-disabled="selectedClientMappings.length == 0" class="btn btn-default" type="submit" ng-click="deleteClientRole()">
<i class="fa fa-angle-double-left"></i> {{:: 'remove-selected' | translate}}
@ -125,7 +125,7 @@
<select id="client-composite" class="form-control" multiple size=5
disabled="true"
ng-model="dummymodel"
ng-options="r.name for r in clientComposite">
ng-options="r.name for r in clientComposite | orderBy:'name'">
</select>
</div>
</div>

View file

@ -22,7 +22,7 @@
<select id="available" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedRealmRoles"
ng-options="r.name for r in realmRoles">
ng-options="r.name for r in realmRoles | orderBy:'name'">
</select>
<button ng-disabled="selectedRealmRoles.length == 0" class="btn btn-default" type="submit" ng-click="addRealmRole()">
{{:: 'add-selected' | translate}} <i class="fa fa-angle-double-right"></i>
@ -34,7 +34,7 @@
<select id="assigned" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedRealmMappings"
ng-options="r.name for r in realmMappings">
ng-options="r.name for r in realmMappings | orderBy:'name'">
</select>
<button ng-disabled="selectedRealmMappings.length == 0" class="btn btn-default" type="submit" ng-click="deleteRealmRole()">
<i class="fa fa-angle-double-left"></i> {{:: 'remove-selected' | translate}}
@ -46,7 +46,7 @@
<select id="realm-composite" class="form-control" multiple size=5
disabled="true"
ng-model="dummymodel"
ng-options="r.name for r in realmComposite">
ng-options="r.name for r in realmComposite | orderBy:'name'">
</select>
</div>
</div>
@ -56,7 +56,7 @@
<div class="form-group">
<label class="col-md-2 control-label" class="control-label">
<span>{{:: 'client-roles' | translate}}</span>
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="targetClient" ng-options="a.clientId for a in clients" ng-disabled="false"></select>
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="targetClient" ng-options="a.clientId for a in clients | orderBy:'clientId'" ng-disabled="false"></select>
</label>
<div class="col-md-10">
@ -70,7 +70,7 @@
<select id="available-client" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedClientRoles"
ng-options="r.name for r in clientRoles">
ng-options="r.name for r in clientRoles | orderBy:'name'">
</select>
<button ng-disabled="selectedClientRoles.length == 0" class="btn btn-default" type="submit" ng-click="addClientRole()">
{{:: 'add-selected' | translate}} <i class="fa fa-angle-double-right"></i>
@ -82,7 +82,7 @@
<select id="assigned-client" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedClientMappings"
ng-options="r.name for r in clientMappings">
ng-options="r.name for r in clientMappings | orderBy:'name'">
</select>
<button ng-disabled="selectedClientMappings.length == 0" class="btn btn-default" type="submit" ng-click="deleteClientRole()">
<i class="fa fa-angle-double-left"></i> {{:: 'remove-selected' | translate}}
@ -94,7 +94,7 @@
<select id="client-composite" class="form-control" multiple size=5
disabled="true"
ng-model="dummymodel"
ng-options="r.name for r in clientComposite">
ng-options="r.name for r in clientComposite | orderBy:'name'">
</select>
</div>
</div>

View file

@ -33,7 +33,7 @@
<select id="available" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedRealmRoles"
ng-options="r.name for r in realmRoles">
ng-options="r.name for r in realmRoles | orderBy:'name'">
</select>
<button ng-disabled="selectedRealmRoles.length == 0" class="btn btn-default" type="submit" ng-click="addRealmRole()">
{{:: 'add-selected' | translate}} <i class="fa fa-angle-double-right"></i>
@ -45,7 +45,7 @@
<select id="assigned" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedRealmMappings"
ng-options="r.name for r in realmMappings">
ng-options="r.name for r in realmMappings | orderBy:'name'">
</select>
<button ng-disabled="selectedRealmMappings.length == 0" class="btn btn-default" type="submit" ng-click="deleteRealmRole()">
<i class="fa fa-angle-double-left"></i> {{:: 'remove-selected' | translate}}
@ -57,7 +57,7 @@
<select id="realm-composite" class="form-control" multiple size=5
disabled="true"
ng-model="dummymodel"
ng-options="r.name for r in realmComposite">
ng-options="r.name for r in realmComposite | orderBy:'name'">
</select>
</div>
</div>
@ -67,7 +67,7 @@
<div class="form-group">
<label class="col-md-2 control-label" class="control-label">
<span>{{:: 'client-roles' | translate}}</span>
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="targetClient" ng-options="a.clientId for a in clients" ng-disabled="false"></select>
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="targetClient" ng-options="a.clientId for a in clients | orderBy:'clientId'" ng-disabled="false"></select>
</label>
<div class="col-md-10">
@ -81,7 +81,7 @@
<select id="available-client" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedClientRoles"
ng-options="r.name for r in clientRoles">
ng-options="r.name for r in clientRoles | orderBy:'name'">
</select>
<button ng-disabled="selectedClientRoles.length == 0" class="btn btn-default" type="submit" ng-click="addClientRole()">
{{:: 'add-selected' | translate}} <i class="fa fa-angle-double-right"></i>
@ -93,7 +93,7 @@
<select id="assigned-client" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedClientMappings"
ng-options="r.name for r in clientMappings">
ng-options="r.name for r in clientMappings | orderBy:'name'">
</select>
<button ng-disabled="selectedClientMappings.length == 0" class="btn btn-default" type="submit" ng-click="deleteClientRole()">
<i class="fa fa-angle-double-left"></i> {{:: 'remove-selected' | translate}}
@ -105,7 +105,7 @@
<select id="client-composite" class="form-control" multiple size=5
disabled="true"
ng-model="dummymodel"
ng-options="r.name for r in clientComposite">
ng-options="r.name for r in clientComposite | orderBy:'name'">
</select>
</div>
</div>

View file

@ -17,7 +17,7 @@
<select id="available" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedRealmRoles"
ng-options="r.name for r in realmRoles">
ng-options="r.name for r in realmRoles | orderBy:'name'">
</select>
<button ng-disabled="selectedRealmRoles.length == 0" ng-disabled="c.length == 0" class="btn btn-default" type="submit" ng-click="addRealmRole()">
{{:: 'add-selected' | translate}} <i class="fa fa-angle-right"></i>
@ -30,7 +30,7 @@
<select id="assigned" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedRealmMappings"
ng-options="r.name for r in realmMappings">
ng-options="r.name for r in realmMappings | orderBy:'name'">
</select>
<button ng-disabled="selectedRealmMappings.length == 0" class="btn btn-default" type="submit" ng-click="deleteRealmRole()">
<i class="fa fa-angle-double-left"></i> {{:: 'remove-selected' | translate}}
@ -42,7 +42,7 @@
<select id="realm-composite" class="form-control" multiple size=5
disabled="true"
ng-model="dummymodel"
ng-options="r.name for r in realmComposite">
ng-options="r.name for r in realmComposite | orderBy:'name'">
</select>
</div>
</div>
@ -52,7 +52,7 @@
<div class="form-group">
<label class="col-md-2 control-label" class="control-label">
<span>{{:: 'client-roles' | translate}}</span>
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="targetClient" ng-options="a.clientId for a in clients" ng-disabled="false"></select>
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="targetClient" ng-options="a.clientId for a in clients | orderBy:'clientId'" ng-disabled="false"></select>
</label>
<div class="col-md-10" kc-read-only="!access.manageUsers">
<div class="row" data-ng-hide="targetClient">
@ -65,7 +65,7 @@
<select id="available-client" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedClientRoles"
ng-options="r.name for r in clientRoles">
ng-options="r.name for r in clientRoles | orderBy:'name'">
</select>
<button ng-disabled="selectedClientRoles.length == 0" class="btn btn-default" type="submit" ng-click="addClientRole()">
{{:: 'add-selected' | translate}} <i class="fa fa-angle-double-right"></i>
@ -77,7 +77,7 @@
<select id="assigned-client" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedClientMappings"
ng-options="r.name for r in clientMappings">
ng-options="r.name for r in clientMappings | orderBy:'name'">
</select>
<button ng-disabled="selectedClientMappings.length == 0" class="btn btn-default" type="submit" ng-click="deleteClientRole()">
<i class="fa fa-angle-double-left"></i> {{:: 'remove-selected' | translate}}
@ -89,7 +89,7 @@
<select id="client-composite" class="form-control" multiple size=5
disabled="true"
ng-model="dummymodel"
ng-options="r.name for r in clientComposite">
ng-options="r.name for r in clientComposite | orderBy:'name'">
</select>
</div>
</div>

View file

@ -42,7 +42,7 @@
<div class="form-group">
<label class="col-md-2 control-label" class="control-label">
<span>{{:: 'client-roles' | translate}}</span>
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="client" ng-options="a.clientId for a in clients" ng-disabled="false"></select>
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="client" ng-options="a.clientId for a in clients | orderBy:'clientId'" ng-disabled="false"></select>
</label>
<div class="col-md-10" data-ng-show="client">
<div class="row" data-ng-hide="client">

View file

@ -5,7 +5,7 @@
<span class="fa fa-exchange"></span>
</div>
<h1>
Identity Providers
{{:: 'identity-providers' | translate}}
</h1>
<p class="">
Through Identity Brokering it's easy to allow users to authenticate to Keycloak using external Identity Providers or Social Networks.<br> We have built-in support for OpenID Connect and SAML 2.0 as well as a number of social networks such as Google, GitHub, Facebook and Twitter.

View file

@ -96,7 +96,7 @@
<div class="form-group">
<label class="col-md-2 control-label" class="control-label">
<span>{{:: 'client-roles' | translate}}</span>
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="compositeClient" ng-options="a.clientId for a in clients" ng-disabled="false"></select>
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="compositeClient" ng-options="a.clientId for a in clients | orderBy:'clientId'" ng-disabled="false"></select>
</label>
<div class="col-md-10">

View file

@ -17,7 +17,7 @@
<select id="available" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedRealmRoles"
ng-options="r.name for r in realmRoles">
ng-options="r.name for r in realmRoles | orderBy:'name'">
</select>
<button ng-disabled="selectedRealmRoles.length == 0" ng-disabled="c.length == 0" class="btn btn-default" type="submit" ng-click="addRealmRole()">
{{:: 'add-selected' | translate}} <i class="fa fa-angle-right"></i>
@ -30,7 +30,7 @@
<select id="assigned" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedRealmMappings"
ng-options="r.name for r in realmMappings">
ng-options="r.name for r in realmMappings | orderBy:'name'">
</select>
<button ng-disabled="selectedRealmMappings.length == 0" class="btn btn-default" type="submit" ng-click="deleteRealmRole()">
<i class="fa fa-angle-double-left"></i> {{:: 'remove-selected' | translate}}
@ -42,7 +42,7 @@
<select id="realm-composite" class="form-control" multiple size=5
disabled="true"
ng-model="dummymodel"
ng-options="r.name for r in realmComposite">
ng-options="r.name for r in realmComposite | orderBy:'name'">
</select>
</div>
</div>
@ -52,7 +52,7 @@
<div class="form-group">
<label class="col-md-2 control-label" class="control-label">
<span>{{:: 'client-roles' | translate}}</span>
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="targetClient" ng-options="a.clientId for a in clients" ng-disabled="false"></select>
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="targetClient" ng-options="a.clientId for a in clients | orderBy:'clientId'" ng-disabled="false"></select>
</label>
<div class="col-md-10" kc-read-only="!access.manageUsers">
<div class="row" data-ng-hide="targetClient">
@ -65,7 +65,7 @@
<select id="available-client" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedClientRoles"
ng-options="r.name for r in clientRoles">
ng-options="r.name for r in clientRoles | orderBy:'name'">
</select>
<button ng-disabled="selectedClientRoles.length == 0" class="btn btn-default" type="submit" ng-click="addClientRole()">
{{:: 'add-selected' | translate}} <i class="fa fa-angle-double-right"></i>
@ -77,7 +77,7 @@
<select id="assigned-client" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedClientMappings"
ng-options="r.name for r in clientMappings">
ng-options="r.name for r in clientMappings | orderBy:'name'">
</select>
<button ng-disabled="selectedClientMappings.length == 0" class="btn btn-default" type="submit" ng-click="deleteClientRole()">
<i class="fa fa-angle-double-left"></i> {{:: 'remove-selected' | translate}}
@ -89,7 +89,7 @@
<select id="client-composite" class="form-control" multiple size=5
disabled="true"
ng-model="dummymodel"
ng-options="r.name for r in clientComposite">
ng-options="r.name for r in clientComposite | orderBy:'name'">
</select>
</div>
</div>

View file

@ -3,39 +3,63 @@
<span>{{:: 'user-federation' | translate}}</span>
</h1>
<table class="table table-striped table-bordered">
<thead>
<tr ng-show="providers.length > 0 && access.manageUsers">
<th colspan="5" class="kc-table-actions">
<div class="pull-right">
<div>
<select class="form-control" ng-model="selectedProvider"
<div class="blank-slate-pf" data-ng-hide="instances && instances.length > 0">
<div class="blank-slate-pf-icon">
<span class="fa fa-database"></span>
</div>
<h1>
{{:: 'user-federation' | translate}}
</h1>
<p>Keycloak can federate external user databases. Out of the box we have support for LDAP and Active Directory.</p>
<p>To get started select a provider from the dropdown below:</p>
<div class="blank-slate-pf-main-action">
<div class="row" data-ng-show="access.manageUsers">
<div class="col-sm-4 col-sm-offset-4">
<div class="form-group">
<select class="selectpicker form-control" ng-model="selectedProvider"
ng-options="p.id for p in providers"
data-ng-change="addProvider(selectedProvider); selectedProvider = null">
<option value="" disabled selected>{{:: 'add-provider.placeholder' | translate}}</option>
</select>
</div>
</div>
</th>
</tr>
<tr data-ng-show="instances && instances.length > 0">
<th>{{:: 'id' | translate}}</th>
<th>{{:: 'provider-name' | translate}}</th>
<th>{{:: 'priority' | translate}}</th>
<th colspan="2">{{:: 'actions' | translate}}</th>
</tr>
</div>
</div>
</div>
<table class="table table-striped table-bordered" data-ng-show="instances && instances.length > 0">
<thead>
<tr ng-show="providers.length > 0 && access.manageUsers">
<th colspan="5" class="kc-table-actions">
<div class="pull-right">
<div>
<select class="form-control" ng-model="selectedProvider"
ng-options="p.id for p in providers"
data-ng-change="addProvider(selectedProvider); selectedProvider = null">
<option value="" disabled selected>{{:: 'add-provider.placeholder' | translate}}</option>
</select>
</div>
</div>
</th>
</tr>
<tr data-ng-show="instances && instances.length > 0">
<th>{{:: 'id' | translate}}</th>
<th>{{:: 'provider-name' | translate}}</th>
<th>{{:: 'priority' | translate}}</th>
<th colspan="2">{{:: 'actions' | translate}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="instance in instances">
<td><a href="#{{getInstanceLink(instance)}}">{{getInstanceName(instance)}}</a></td>
<td>{{getInstanceProvider(instance)|capitalize}}</td>
<td>{{getInstancePriority(instance)}}</td>
<td class="kc-action-cell" kc-open="{{getInstanceLink(instance)}}">{{:: 'edit' | translate}}</td>
<td class="kc-action-cell" data-ng-click="removeInstance(instance)">{{:: 'delete' | translate}}</td>
</tr>
<tr data-ng-show="!instances || instances.length == 0">
<td class="text-muted">{{:: 'no-user-federation-providers-configured' | translate}}</td>
</tr>
<tr ng-repeat="instance in instances">
<td><a href="#{{getInstanceLink(instance)}}">{{getInstanceName(instance)}}</a></td>
<td>{{getInstanceProvider(instance) | capitalize}}</td>
<td>{{getInstancePriority(instance)}}</td>
<td class="kc-action-cell" kc-open="{{getInstanceLink(instance)}}">{{:: 'edit' | translate}}</td>
<td class="kc-action-cell" data-ng-click="removeInstance(instance)">{{:: 'delete' | translate}}</td>
</tr>
<tr data-ng-show="!instances || instances.length == 0">
<td class="text-muted">{{:: 'no-user-federation-providers-configured' | translate}}</td>
</tr>
</tbody>
</table>
</div>