diff options
Diffstat (limited to 'admin/resources/partials')
185 files changed, 14367 insertions, 0 deletions
diff --git a/admin/resources/partials/authentication-flow-bindings.html b/admin/resources/partials/authentication-flow-bindings.html new file mode 100644 index 0000000..6bf39f3 --- /dev/null +++ b/admin/resources/partials/authentication-flow-bindings.html @@ -0,0 +1,83 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1>{{:: 'authentication' | translate}}</h1> + + <kc-tabs-authentication></kc-tabs-authentication> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <div class="form-group"> + <label for="browser" class="col-md-2 control-label">{{:: 'browser-flow' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="browser" ng-model="realm.browserFlow" class="form-control" ng-options="flow.alias as flow.alias for flow in flows"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'browser-flow.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label for="registration" class="col-md-2 control-label">{{:: 'registration-flow' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="registration" ng-model="realm.registrationFlow" class="form-control" ng-options="flow.alias as flow.alias for flow in flows"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'registration-flow.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label for="grant" class="col-md-2 control-label">{{:: 'direct-grant-flow' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="grant" ng-model="realm.directGrantFlow" class="form-control" ng-options="flow.alias as flow.alias for flow in flows"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'direct-grant-flow.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="resetCredentials" class="col-md-2 control-label">{{:: 'reset-credentials' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="resetCredentials" ng-model="realm.resetCredentialsFlow" class="form-control" ng-options="flow.alias as flow.alias for flow in flows"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'reset-credentials.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="clientAuthentication" class="col-md-2 control-label">{{:: 'client-authentication' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="clientAuthentication" ng-model="realm.clientAuthenticationFlow" class="form-control" ng-options="flow.alias as flow.alias for flow in clientFlows"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'client-authentication.tooltip' | translate}}</kc-tooltip> + </div> + + + <div class="form-group" data-ng-show="serverInfo.featureEnabled('DOCKER')"> + <label for="dockerAuth" class="col-md-2 control-label">{{:: 'docker-auth' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="dockerAuth" ng-model="realm.dockerAuthenticationFlow" class="form-control" ng-options="flow.alias as flow.alias for flow in flows"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'docker-auth.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group" data-ng-show="access.manageRealm"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> + +</div> + + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authentication-flows.html b/admin/resources/partials/authentication-flows.html new file mode 100644 index 0000000..3ef54b3 --- /dev/null +++ b/admin/resources/partials/authentication-flows.html @@ -0,0 +1,69 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1>{{:: 'authentication' | translate}}</h1> + + <kc-tabs-authentication></kc-tabs-authentication> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th colspan="{{levelmax + 1 + choicesmax + 4}}" class="kc-table-actions"> + <div class="dropdown pull-left"> + <select class="form-control" ng-model="flow" + ng-options="(flow.alias|capitalize) for flow in flows" + data-ng-change="selectFlow(flow)"> + </select> + </div> + <i class="fa fa-question-circle text-muted" tooltip-trigger="mouseover mouseout" tooltip="{{flow.description}}" tooltip-placement="right"> </i> + <div class="pull-right" data-ng-show="access.manageRealm"> + <button class="btn btn-default" data-ng-click="createFlow()">{{:: 'new' | translate}}</button> + <button class="btn btn-default" data-ng-click="copyFlow()">{{:: 'copy' | translate}}</button> + <button class="btn btn-default" data-ng-hide="flow.builtIn" data-ng-click="deleteFlow()">{{:: 'delete' | translate}}</button> + <button class="btn btn-default" data-ng-hide="flow.builtIn" data-ng-click="addExecution()">{{:: 'add-execution' | translate}}</button> + <button class="btn btn-default" data-ng-hide="flow.builtIn || flow.providerId === 'client-flow'" data-ng-click="addFlow()">{{:: 'add-flow' | translate}}</button> + </div> + </th> + </tr> + <tr data-ng-hide="executions.length == 0"> + <th colspan="{{levelmax + 1}}">{{:: 'auth-type' | translate}}</th> + <th colspan="{{choicesmax}}">{{:: 'requirement' | translate}}</th> + <th> </th> + </tr> + </thead> + <tbody> + <tr ng-repeat="execution in executions" data-ng-show="executions.length > 0"> + <td ng-repeat="lev in execution.preLevels"></td> + <td class="kc-sorter"> + <button data-ng-hide="flow.builtIn" data-ng-disabled="$first" class="btn btn-default btn-sm" data-ng-click="raisePriority(execution)"><i class="fa fa-angle-up"></i></button> + <button data-ng-hide="flow.builtIn" data-ng-disabled="$last" class="btn btn-default btn-sm" data-ng-click="lowerPriority(execution)"><i class="fa fa-angle-down"></i></button> + <span>{{execution.displayName|capitalize}}<span ng-if="execution.alias">({{execution.alias}})</span></span> + </td> + <td ng-repeat="lev in execution.postLevels"></td> + <td ng-repeat="choice in execution.requirementChoices"> + <label> + <input type="radio" ng-model="execution.requirement" ng-value="choice" ng-change="updateExecution(execution)"> + {{choice}} + </label> + + </td> + <td ng-repeat="emptee in execution.empties"></td> + <td> + <div class="dropdown" data-ng-hide="flow.builtIn && !execution.configurable"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">{{:: 'actions' | translate}} <b class="caret"></b></a> + <ul class="dropdown-menu" > + <li data-ng-hide="flow.builtIn"><a href="" ng-click="removeExecution(execution)">{{:: 'delete' | translate}}</a></li> + <li data-ng-hide="flow.builtIn || !execution.authenticationFlow"><a href="" ng-click="addSubFlowExecution(execution)">{{:: 'add-execution' | translate}}</a></li> + <li data-ng-hide="flow.builtIn || !execution.authenticationFlow"><a href="" ng-click="addSubFlow(execution)">{{:: 'add-flow' | translate}}</a></li> + <li data-ng-show="execution.configurable && execution.authenticationConfig == null"><a href="#/create/authentication/{{realm.realm}}/flows/{{flow.id}}/execution/{{execution.id}}/provider/{{execution.providerId}}">{{:: 'config' | translate}}</a></li> + <li data-ng-show="execution.configurable && execution.authenticationConfig != null"><a href="#/realms/{{realm.realm}}/authentication/flows/{{flow.id}}/config/{{execution.providerId}}/{{execution.authenticationConfig}}">{{:: 'config' | translate}}</a></li> + </ul> + </div> + </td> + </tr> + <tr data-ng-show="executions.length == 0"> + <td>{{:: 'no-executions-available' | translate}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authenticator-config.html b/admin/resources/partials/authenticator-config.html new file mode 100644 index 0000000..1b34406 --- /dev/null +++ b/admin/resources/partials/authenticator-config.html @@ -0,0 +1,52 @@ +<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}}/authentication/flows">{{:: 'authentication-flows' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/authentication/flows/{{flow.alias}}">{{flow.alias | capitalize}}</a></li> + <li class="active" data-ng-show="create">{{:: 'create-authenticator-config' | translate}}</li> + <li class="active" data-ng-show="!create && config.alias">{{config.alias}}</li> + <li class="active" data-ng-show="!create && !config.alias">{{config.id}}</li> + </ol> + + <h1 data-ng-show="create">{{:: 'create-authenticator-config' | translate}}</h1> + <h1 data-ng-hide="create"> + <span data-ng-show="config.alias">{{config.alias|capitalize}}</span> + <span data-ng-show="!config.alias">{{config.id}}</span> + <a><i class="pficon pficon-delete clickable" data-ng-show="!create && access.manageRealm" data-ng-hide="changed" data-ng-click="remove()"></i></a> + </h1> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <fieldset> + <div class="form-group clearfix" data-ng-show="!create"> + <label class="col-md-2 control-label" for="configId">{{:: 'id' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="configId" type="text" ng-model="config.id" readonly> + </div> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="name">{{:: 'alias' | translate}}</label> + <div class="col-md-6"> + <input kc-no-reserved-chars class="form-control" id="name" type="text" ng-model="config.alias" data-ng-readonly="!create"> + </div> + <kc-tooltip>{{:: 'authenticator.alias.tooltip' | translate}}</kc-tooltip> + </div> + <kc-provider-config realm="realm" config="config.config" properties="configType.properties"></kc-provider-config> + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="create && access.manageRealm"> + <button kc-save>{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="!create && access.manageRealm"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/mgmt/broker-permissions.html b/admin/resources/partials/authz/mgmt/broker-permissions.html new file mode 100644 index 0000000..2e389ff --- /dev/null +++ b/admin/resources/partials/authz/mgmt/broker-permissions.html @@ -0,0 +1,40 @@ +<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}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li> + <li data-ng-show="!newIdentityProvider && identityProvider.displayName">{{identityProvider.displayName}}</li> + <li data-ng-show="!newIdentityProvider && !identityProvider.displayName">{{identityProvider.alias}}</li> + </ol> + + <kc-tabs-identity-provider></kc-tabs-identity-provider> + + <form class=form-horizontal" name="enableForm" novalidate kc-read-only="!access.manageIdentityProviders || !access.manageAuthorization"> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="permissionsEnabled">{{:: 'permissions-enabled-role' | translate}}</label> + <div class="col-md-6"> + <input ng-model="permissions.enabled" name="permissionsEnabled" id="permissionsEnabled" ng-disabled="!access.manageAuthorization" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'permissions-enabled-role.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + </form> + <table class="datatable table table-striped table-bordered dataTable no-footer" data-ng-show="permissions.enabled"> + <thead> + <tr> + <th>{{:: 'scope-name' | translate}}</th> + <th>{{:: 'description' | translate}}</th> + <th colspan="2">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="(scopeName, scopeId) in permissions.scopePermissions"> + <td><a href="#/realms/{{realm.realm}}/clients/{{realmManagementClientId}}/authz/resource-server/permission/scope/{{scopeId}}">{{scopeName}}</a></td> + <td translate="{{scopeName}}-authz-idp-scope-description"></td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/clients/{{realmManagementClientId}}/authz/resource-server/permission/scope/{{scopeId}}">{{:: 'edit' | translate}}</td> + </tr> + </tbody> + </table> + +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/mgmt/client-permissions.html b/admin/resources/partials/authz/mgmt/client-permissions.html new file mode 100644 index 0000000..7f29fd7 --- /dev/null +++ b/admin/resources/partials/authz/mgmt/client-permissions.html @@ -0,0 +1,39 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li>{{client.clientId}}</li> + </ol> + + <kc-tabs-client></kc-tabs-client> + + <form class=form-horizontal" name="enableForm" novalidate kc-read-only="!client.access.manage || !access.manageAuthorization"> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="permissionsEnabled">{{:: 'permissions-enabled-role' | translate}}</label> + <div class="col-md-6"> + <input ng-model="permissions.enabled" name="permissionsEnabled" id="permissionsEnabled" ng-disabled="!access.manageAuthorization" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'permissions-enabled-role.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + </form> + <table class="datatable table table-striped table-bordered dataTable no-footer" data-ng-show="permissions.enabled"> + <thead> + <tr> + <th>{{:: 'scope-name' | translate}}</th> + <th>{{:: 'description' | translate}}</th> + <th colspan="2">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="(scopeName, scopeId) in permissions.scopePermissions"> + <td><a href="#/realms/{{realm.realm}}/clients/{{realmManagementClientId}}/authz/resource-server/permission/scope/{{scopeId}}">{{scopeName}}</a></td> + <td translate="{{scopeName}}-authz-client-scope-description"></td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/clients/{{realmManagementClientId}}/authz/resource-server/permission/scope/{{scopeId}}">{{:: 'edit' | translate}}</td> + </tr> + </tbody> + </table> + +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/mgmt/client-role-permissions.html b/admin/resources/partials/authz/mgmt/client-role-permissions.html new file mode 100644 index 0000000..c76ecec --- /dev/null +++ b/admin/resources/partials/authz/mgmt/client-role-permissions.html @@ -0,0 +1,40 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li>{{role.name}}</li> + </ol> + + <kc-tabs-client-role></kc-tabs-client-role> + + <form class=form-horizontal" name="enableForm" novalidate kc-read-only="!client.access.manage || !access.manageAuthorization"> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="permissionsEnabled">{{:: 'permissions-enabled-role' | translate}}</label> + <div class="col-md-6"> + <input ng-model="permissions.enabled" name="permissionsEnabled" id="permissionsEnabled" ng-disabled="!access.manageAuthorization" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'permissions-enabled-role.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + </form> + <table class="datatable table table-striped table-bordered dataTable no-footer" data-ng-show="permissions.enabled"> + <thead> + <tr> + <th>{{:: 'scope-name' | translate}}</th> + <th>{{:: 'description' | translate}}</th> + <th colspan="2">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="(scopeName, scopeId) in permissions.scopePermissions"> + <td><a href="#/realms/{{realm.realm}}/clients/{{realmManagementClientId}}/authz/resource-server/permission/scope/{{scopeId}}">{{scopeName}}</a></td> + <td translate="{{scopeName}}-authz-role-scope-description"></td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/clients/{{realmManagementClientId}}/authz/resource-server/permission/scope/{{scopeId}}">{{:: 'edit' | translate}}</td> + </tr> + </tbody> + </table> + +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/mgmt/group-permissions.html b/admin/resources/partials/authz/mgmt/group-permissions.html new file mode 100644 index 0000000..f2be6d9 --- /dev/null +++ b/admin/resources/partials/authz/mgmt/group-permissions.html @@ -0,0 +1,39 @@ +<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}}/groups">{{:: 'groups' | translate}}</a></li> + <li>{{group.name}}</li> + </ol> + + <kc-tabs-group></kc-tabs-group> + + <form class=form-horizontal" name="enableForm" novalidate kc-read-only="!group.access.manage || !access.manageAuthorization"> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="permissionsEnabled">{{:: 'permissions-enabled-role' | translate}}</label> + <div class="col-md-6"> + <input ng-model="permissions.enabled" name="permissionsEnabled" id="permissionsEnabled" ng-disabled="!access.manageAuthorization" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'permissions-enabled-role.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + </form> + <table class="datatable table table-striped table-bordered dataTable no-footer" data-ng-show="permissions.enabled"> + <thead> + <tr> + <th>{{:: 'scope-name' | translate}}</th> + <th>{{:: 'description' | translate}}</th> + <th colspan="2">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="(scopeName, scopeId) in permissions.scopePermissions"> + <td><a href="#/realms/{{realm.realm}}/clients/{{realmManagementClientId}}/authz/resource-server/permission/scope/{{scopeId}}">{{scopeName}}</a></td> + <td translate="{{scopeName}}-authz-group-scope-description"></td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/clients/{{realmManagementClientId}}/authz/resource-server/permission/scope/{{scopeId}}">{{:: 'edit' | translate}}</td> + </tr> + </tbody> + </table> + +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/mgmt/realm-role-permissions.html b/admin/resources/partials/authz/mgmt/realm-role-permissions.html new file mode 100644 index 0000000..e21ee63 --- /dev/null +++ b/admin/resources/partials/authz/mgmt/realm-role-permissions.html @@ -0,0 +1,39 @@ +<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}}/roles">{{:: 'roles' | translate}}</a></li> + <li>{{role.name}}</li> + </ol> + + <kc-tabs-role></kc-tabs-role> + + <form class=form-horizontal" name="enableForm" novalidate kc-read-only="!access.manageAuthorization"> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="permissionsEnabled">{{:: 'permissions-enabled-role' | translate}}</label> + <div class="col-md-6"> + <input ng-model="permissions.enabled" name="permissionsEnabled" id="permissionsEnabled" ng-disabled="!access.manageAuthorization" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'permissions-enabled-role.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + </form> + <table class="datatable table table-striped table-bordered dataTable no-footer" data-ng-show="permissions.enabled"> + <thead> + <tr> + <th>{{:: 'scope-name' | translate}}</th> + <th>{{:: 'description' | translate}}</th> + <th colspan="2">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="(scopeName, scopeId) in permissions.scopePermissions"> + <td><a href="#/realms/{{realm.realm}}/clients/{{realmManagementClientId}}/authz/resource-server/permission/scope/{{scopeId}}">{{scopeName}}</a></td> + <td translate="{{scopeName}}-authz-role-scope-description"></td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/clients/{{realmManagementClientId}}/authz/resource-server/permission/scope/{{scopeId}}">{{:: 'edit' | translate}}</td> + </tr> + </tbody> + </table> + +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/mgmt/users-permissions.html b/admin/resources/partials/authz/mgmt/users-permissions.html new file mode 100644 index 0000000..2665bba --- /dev/null +++ b/admin/resources/partials/authz/mgmt/users-permissions.html @@ -0,0 +1,35 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + + <kc-tabs-users></kc-tabs-users> + + <form class=form-horizontal" name="enableForm" novalidate kc-read-only="!access.manageAuthorization"> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="permissionsEnabled">{{:: 'permissions-enabled-users' | translate}}</label> + <div class="col-md-6"> + <input ng-model="permissions.enabled" name="permissionsEnabled" id="permissionsEnabled" ng-disabled="!access.manageAuthorization" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'permissions-enabled-users.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + </form> + <table class="datatable table table-striped table-bordered dataTable no-footer" data-ng-show="permissions.enabled"> + <thead> + <tr> + <th>{{:: 'scope-name' | translate}}</th> + <th>{{:: 'description' | translate}}</th> + <th colspan="2">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="(scopeName, scopeId) in permissions.scopePermissions"> + <td><a href="#/realms/{{realm.realm}}/clients/{{realmManagementClientId}}/authz/resource-server/permission/scope/{{scopeId}}">{{scopeName}}</a></td> + <td translate="{{scopeName}}-authz-users-scope-description"></td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/clients/{{realmManagementClientId}}/authz/resource-server/permission/scope/{{scopeId}}">{{:: 'edit' | translate}}</td> + </tr> + </tbody> + </table> + +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/permission/provider/resource-server-policy-resource-detail.html b/admin/resources/partials/authz/permission/provider/resource-server-policy-resource-detail.html new file mode 100644 index 0000000..af5aace --- /dev/null +++ b/admin/resources/partials/authz/permission/provider/resource-server-policy-resource-detail.html @@ -0,0 +1,131 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/permission">{{:: 'authz-permissions' | translate}}</a></li> + <li data-ng-show="create">{{:: 'authz-add-resource-permission' | translate}}</li> + <li data-ng-hide="create">{{originalPolicy.name}}</li> + </ol> + + <h1 data-ng-show="create">{{:: 'authz-add-resource-permission' | translate}}</h1> + <h1 data-ng-hide="create">{{originalPolicy.name|capitalize}}<i class="pficon pficon-delete clickable" data-ng-click="remove()"></i></h1> + + <form class="form-horizontal" name="clientForm" novalidate> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="name">{{:: 'name' | translate}} <span class="required">*</span></label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="name" name="name" data-ng-model="policy.name" autofocus required data-ng-blur="checkNewNameAvailability()"> + </div> + <kc-tooltip>{{:: 'authz-permission-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="description">{{:: 'description' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="description" name="description" data-ng-model="policy.description"> + </div> + <kc-tooltip>{{:: 'authz-permission-description.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="applyToResourceTypeFlag">{{:: 'authz-permission-resource-apply-to-resource-type' | translate}}</label> + <div class="col-md-6"> + <input ng-model="applyToResourceTypeFlag" id="applyToResourceTypeFlag" onoffswitch data-ng-click="applyToResourceType()"/> + </div> + <kc-tooltip>{{:: 'authz-permission-resource-apply-to-resource-type.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-hide="applyToResourceTypeFlag"> + <label class="col-md-2 control-label" for="resources">{{:: 'authz-resources' | translate}} <span class="required">*</span></label> + + <div class="col-md-6"> + <input type="hidden" ui-select2="resourcesUiSelect" id="resources" data-ng-model="selectedResource" data-placeholder="{{:: 'authz-select-resource' | translate}}..." data-ng-required="!applyToResourceTypeFlag"/> + </div> + <kc-tooltip>{{:: 'authz-permission-resource-resource.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="applyToResourceTypeFlag"> + <label class="col-md-2 control-label" for="resourceType">{{:: 'authz-resource-type' | translate}} <span class="required">*</span></label> + + <div class="col-md-6"> + <input class="form-control" type="text" id="resourceType" name="policy.resourceType" data-ng-model="policy.resourceType" data-ng-required="applyToResourceTypeFlag"> + </div> + + <kc-tooltip>{{:: 'authz-permission-resource-type.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="policies">{{:: 'authz-policy-apply-policy' | translate}}</label> + <div class="col-sm-6"> + <table class="table table-striped table-bordered" style="margin-top: 0px" id="selected-policies"> + <thead> + <tr> + <th class="kc-table-actions" colspan="2"> + <div class="form-inline col-md-12" style="width: 107%"> + <div class="form-group" style="width: 100%"> + <div class="input-group" style="width: 100%"> + <input type="hidden" ui-select2="policiesUiSelect" id="policies" data-ng-change="selectPolicy(selectedPolicy);" data-ng-model="selectedPolicy" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..."/> + </div> + </div> + </div> + </th> + <th class="kc-table-actions"> + <div class="pull-right" style="width: 100%"> + <select id="create-policy" class="form-control" ng-model="policyType" + ng-options="p.name for p in policyProviders track by p.type" + data-ng-change="addPolicy(policyType);" + data-ng-hide="historyBackOnSaveOrCancel"> + <option value="" disabled selected>{{:: 'authz-create-policy' | translate}}...</option> + </select> + </div> + </th> + </tr> + <tr data-ng-hide="!selectedPolicies || selectedPolicies.length == 0"> + <th>{{:: 'name' | translate}}</th> + <th>{{:: 'description' | translate}}</th> + <th width="20%">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="policy in selectedPolicies"> + <td data-ng-hide="historyBackOnSaveOrCancel"><a href="" data-ng-click="detailPolicy(policy)">{{policy.name}}</a></td> + <td data-ng-show="historyBackOnSaveOrCancel">{{policy.name}}</td> + <td>{{policy.description}}</td> + <td class="kc-action-cell" ng-click="removePolicy(selectedPolicies, policy);" style="vertical-align: middle"> + {{:: 'remove' | translate}} + </td> + </tr> + <tr data-ng-show="!selectedPolicies || selectedPolicies.length == 0"> + <td class="text-muted" colspan="3">{{:: 'authz-no-policies-assigned' | translate}}</td> + </tr> + </tbody> + </table> + </div> + <kc-tooltip>{{:: 'authz-policy-apply-policy.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="decisionStrategy">{{:: 'authz-policy-decision-strategy' | translate}}</label> + + <div class="col-sm-2"> + <select class="form-control" id="decisionStrategy" + data-ng-model="policy.decisionStrategy" + ng-change="selectDecisionStrategy()"> + <option value="UNANIMOUS">{{:: 'authz-policy-decision-strategy-unanimous' | translate}}</option> + <option value="AFFIRMATIVE">{{:: 'authz-policy-decision-strategy-affirmative' | translate}}</option> + <option value="CONSENSUS">{{:: 'authz-policy-decision-strategy-consensus' | translate}}</option> + </select> + </div> + + <kc-tooltip>{{:: 'authz-policy-decision-strategy.tooltip' | translate}}</kc-tooltip> + </div> + <input type="hidden" data-ng-model="policy.type"/> + </fieldset> + + <div class="form-group" data-ng-show="access.manageAuthorization"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html b/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html new file mode 100644 index 0000000..17ee7cb --- /dev/null +++ b/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html @@ -0,0 +1,134 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/permission">{{:: 'authz-permissions' | translate}}</a></li> + <li data-ng-show="create">{{:: 'authz-add-scope-permission' | translate}}</li> + <li data-ng-hide="create">{{originalPolicy.name}}</li> + </ol> + + <h1 data-ng-show="create">{{:: 'authz-add-scope-permission' | translate}}</h1> + <h1 data-ng-hide="create">{{originalPolicy.name|capitalize}}<i class="pficon pficon-delete clickable" data-ng-click="remove()"></i></h1> + + <form class="form-horizontal" name="clientForm" novalidate> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="name">{{:: 'name' | translate}} <span class="required">*</span></label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="name" name="name" data-ng-model="policy.name" autofocus required data-ng-blur="checkNewNameAvailability()"> + </div> + <kc-tooltip>{{:: 'authz-permission-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="description">{{:: 'description' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="description" name="description" data-ng-model="policy.description"> + </div> + <kc-tooltip>{{:: 'authz-permission-description.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="resources">{{:: 'authz-resource' | translate}}</label> + + <div class="col-md-6"> + <input type="hidden" ui-select2="resourcesUiSelect" data-ng-change="selectResource()" id="resources" data-ng-model="selectedResource" data-placeholder="{{:: 'authz-any-resource' | translate}}..." /> + </div> + <kc-tooltip>{{:: 'authz-permission-scope-resource.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="selectedResource"> + <label class="col-md-2 control-label" for="resourceScopes">{{:: 'authz-scopes' | translate}} <span class="required">*</span></label> + <div class="col-md-6"> + <select ui-select2 id="resourceScopes" + data-ng-model="selectedScopes" + data-placeholder="{{:: 'authz-any-scope' | translate}}..." multiple + data-ng-required="selectedResource != null"> + <option ng-repeat="scope in resourceScopes" value="{{scope.id}}">{{scope.name}}</option> + </select> + </div> + <kc-tooltip>{{:: 'authz-permission-scope-scope.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="!selectedResource"> + <label class="col-md-2 control-label" for="scopes">{{:: 'authz-scopes' | translate}} <span class="required">*</span></label> + + <div class="col-md-6"> + <input type="hidden" ui-select2="scopesUiSelect" id="scopes" data-ng-model="selectedScopes" data-placeholder="{{:: 'authz-any-scope' | translate}}..." multiple data-ng-required="selectedResource == null" /> + </div> + <kc-tooltip>{{:: 'authz-permission-scope-scope.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="policies">{{:: 'authz-policy-apply-policy' | translate}}</label> + <div class="col-sm-6"> + <table class="table table-striped table-bordered" style="margin-top: 0px" id="selected-policies"> + <thead> + <tr> + <th class="kc-table-actions" colspan="2"> + <div class="form-inline col-md-12" style="width: 107%"> + <div class="form-group" style="width: 100%"> + <div class="input-group" style="width: 100%"> + <input type="hidden" ui-select2="policiesUiSelect" id="policies" data-ng-change="selectPolicy(selectedPolicy);" data-ng-model="selectedPolicy" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..."/> + </div> + </div> + </div> + </th> + <th class="kc-table-actions"> + <div class="pull-right" style="width: 100%"> + <select id="create-policy" class="form-control" ng-model="policyType" + ng-options="p.name for p in policyProviders track by p.type" + data-ng-change="addPolicy(policyType);" + data-ng-hide="historyBackOnSaveOrCancel"> + <option value="" disabled selected>{{:: 'authz-create-policy' | translate}}...</option> + </select> + </div> + </th> + </tr> + <tr data-ng-hide="!selectedPolicies || selectedPolicies.length == 0"> + <th>{{:: 'name' | translate}}</th> + <th>{{:: 'description' | translate}}</th> + <th width="20%">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="policy in selectedPolicies"> + <td data-ng-hide="historyBackOnSaveOrCancel"><a href="" data-ng-click="detailPolicy(policy)">{{policy.name}}</a></td> + <td data-ng-show="historyBackOnSaveOrCancel">{{policy.name}}</td> + <td>{{policy.description}}</td> + <td class="kc-action-cell" ng-click="removePolicy(selectedPolicies, policy);" style="vertical-align: middle"> + {{:: 'remove' | translate}} + </td> + </tr> + <tr data-ng-show="!selectedPolicies || selectedPolicies.length == 0"> + <td class="text-muted" colspan="3">{{:: 'authz-no-policies-assigned' | translate}}</td> + </tr> + </tbody> + </table> + </div> + <kc-tooltip>{{:: 'authz-policy-apply-policy.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="decisionStrategy">{{:: 'authz-policy-decision-strategy' | translate}}</label> + + <div class="col-sm-2"> + <select class="form-control" id="decisionStrategy" + data-ng-model="policy.decisionStrategy" + ng-change="selectDecisionStrategy()"> + <option value="UNANIMOUS">{{:: 'authz-policy-decision-strategy-unanimous' | translate}}</option> + <option value="AFFIRMATIVE">{{:: 'authz-policy-decision-strategy-affirmative' | translate}}</option> + <option value="CONSENSUS">{{:: 'authz-policy-decision-strategy-consensus' | translate}}</option> + </select> + </div> + + <kc-tooltip>{{:: 'authz-policy-decision-strategy.tooltip' | translate}}</kc-tooltip> + </div> + <input type="hidden" data-ng-model="policy.type"/> + </fieldset> + <div class="form-group" data-ng-show="access.manageAuthorization"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/permission/resource-server-permission-list.html b/admin/resources/partials/authz/permission/resource-server-permission-list.html new file mode 100644 index 0000000..40dfacd --- /dev/null +++ b/admin/resources/partials/authz/permission/resource-server-permission-list.html @@ -0,0 +1,118 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/permission">{{:: 'authz-permissions' | translate}}</a></li> + </ol> + + <kc-tabs-resource-server></kc-tabs-resource-server> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="5"> + <div class="form-inline"> + <div class="form-group"> + {{:: 'filter' | translate}}: + <div class="input-group"> + <input type="text" placeholder="{{:: 'name' | translate}}" data-ng-model="query.name" class="form-control search" onkeydown="if (event.keyCode == 13) document.getElementById('policySearch').click()"> + <div class="input-group-addon"> + <i class="fa fa-search" id="policySearch" type="submit" data-ng-click="firstPage()"></i> + </div> + </div> + <div class="input-group"> + <input type="text" placeholder="{{:: 'authz-resource' | translate}}" data-ng-model="query.resource" class="form-control search" onkeydown="if (event.keyCode == 13) document.getElementById('policySearch').click()"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit" data-ng-click="firstPage()"></i> + </div> + </div> + <div class="input-group"> + <input type="text" placeholder="{{:: 'authz-scope' | translate}}" data-ng-model="query.scope" class="form-control search" onkeydown="if (event.keyCode == 13) document.getElementById('policySearch').click()"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit" data-ng-click="firstPage()"></i> + </div> + </div> + <div class="input-group"> + <select class="form-control search" data-ng-model="query.type" + ng-options="p.type as p.name group by p.group for p in policyProviders track by p.type" data-ng-change="firstPage()"> + <option value="" selected ng-click="query.type = ''">{{:: 'authz-all-types' | translate}}</option> + </select> + </div> + </div> + <div class="pull-right"> + <select class="form-control" ng-model="policyType" + ng-options="p.name for p in policyProviders track by p.type" + id="create-permission" + data-ng-change="addPolicy(policyType);"> + <option value="" disabled selected>{{:: 'authz-create-permission' | translate}}...</option> + </select> + </div> + </div> + </th> + </tr> + <tr data-ng-hide="policies.length == 0"> + <th width="1%"></th> + <th>{{:: 'name' | translate}}</th> + <th>{{:: 'description' | translate}}</th> + <th width="7%">{{:: 'type' | translate}}</th> + <th width="6%" style="text-align: center;">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tfoot data-ng-show="policies && (policies.length >= query.max || query.first > 0)"> + <tr> + <td colspan="5"> + <div class="table-nav"> + <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button> + <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button> + <button data-ng-click="nextPage()" class="next" ng-disabled="policies.length < query.max">{{:: 'next-page' | translate}}</button> + </div> + </td> + </tr> + </tfoot> + <tbody> + <tr ng-repeat-start="policy in policies | filter: {name: search.name, type: search.type} | orderBy:'name'" data-ng-click="showDetails(policy, $event);" style="cursor: pointer"> + <td> + <span ng-if="!policy.details || !policy.details.loaded" class="fa fa-angle-right"></span> + <span ng-if="policy.details && policy.details.loaded" class="fa fa-angle-right fa-angle-down"></span> + </td> + <td><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/permission/{{policy.type}}/{{policy.id}}">{{policy.name}}</a></td> + <td>{{policy.description}}</td> + <td>{{policy.type}}</td> + <td align="center"> + <div class="dropdown dropdown-kebab-pf"> + <button class="btn btn-default" ng-click="delete(policy);">{{:: 'delete' | translate}} + </button> + </div> + </td> + </tr> + <tr ng-if="policy.details && policy.details.loaded" ng-repeat-end=""> + <td colspan="5" style="background-color: #ffffff"> + <div class="list-group-item-container container-fluid"> + <div class="close" data-ng-click="showDetails(policy, $event);" style="padding-top: 10px"> + <span class="pficon pficon-close"></span> + </div> + <div class="row"> + <div class="col-md-12"> + <dl class="dl-horizontal"> + <dt>{{:: 'authz-associated-policies' | translate}}</dt> + <dd> + <span data-ng-show="policy.associatedPolicies && !policy.associatedPolicies.length">{{:: 'authz-no-policies-available' | translate}}</span> + <span ng-repeat="dep in policy.associatedPolicies" data-ng-show="policy.associatedPolicies.length > 0"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/{{dep.type == 'scope' || dep.type == 'resource' ? 'permission' : 'policy'}}/{{dep.type}}/{{dep.id}}">{{dep.name}}</a>{{$last ? '' : ', '}}</span> + </dd> + </dl> + </div> + </div> + </div> + </td> + </tr> + <tr data-ng-show="(policies | filter:search).length == 0"> + <td class="text-muted" colspan="3" data-ng-show="search.name">{{:: 'no-results' | translate}}</td> + <td class="text-muted" colspan="3" data-ng-hide="search.name">{{:: 'authz-no-permissions-available' | translate}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/policy/provider/resource-server-policy-aggregate-detail.html b/admin/resources/partials/authz/policy/provider/resource-server-policy-aggregate-detail.html new file mode 100644 index 0000000..25be65b --- /dev/null +++ b/admin/resources/partials/authz/policy/provider/resource-server-policy-aggregate-detail.html @@ -0,0 +1,123 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/policy">{{:: 'authz-policies' | translate}}</a></li> + <li data-ng-show="policyState.state.policy.name != null && historyBackOnSaveOrCancel">{{policyState.state.policy.name}}</li> + <li data-ng-show="policyState.state.policy.name == null && historyBackOnSaveOrCancel">{{:: policyState.state.previousPage.name | translate}}</li> + <li data-ng-show="create">{{:: 'authz-add-aggregated-policy' | translate}}</li> + <li data-ng-hide="create">{{:: 'authz-aggregated' | translate}}</li> + <li data-ng-hide="create">{{originalPolicy.name}}</li> + </ol> + + <h1 data-ng-show="create">{{:: 'authz-add-aggregated-policy' | translate}}</h1> + <h1 data-ng-hide="create">{{originalPolicy.name|capitalize}}<i class="pficon pficon-delete clickable" data-ng-show="!create" + data-ng-click="remove()"></i></h1> + + <form class="form-horizontal" name="clientForm" novalidate> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="name">{{:: 'name' | translate}} <span class="required">*</span></label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="name" name="name" data-ng-model="policy.name" autofocus required data-ng-blur="checkNewNameAvailability()"> + </div> + <kc-tooltip>{{:: 'authz-policy-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="description">{{:: 'description' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="description" name="description" data-ng-model="policy.description"> + </div> + <kc-tooltip>{{:: 'authz-policy-description.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="policies">{{:: 'authz-policy-apply-policy' | translate}} <span class="required">*</span></label> + <div class="col-sm-6"> + <table class="table table-striped table-bordered" style="margin-top: 0px" id="selected-policies"> + <thead> + <tr> + <th class="kc-table-actions" colspan="2"> + <div class="form-inline col-md-12" style="width: 107%"> + <div class="form-group" style="width: 100%"> + <div class="input-group" style="width: 100%"> + <input type="hidden" ui-select2="policiesUiSelect" id="policies" data-ng-change="selectPolicy(selectedPolicy);" data-ng-model="selectedPolicy" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..." data-ng-required="!selectedPolicies || selectedPolicies.length == 0"/> + </div> + </div> + </div> + </th> + <th class="kc-table-actions"> + <div class="pull-right" style="width: 100%"> + <select id="create-policy" class="form-control" ng-model="policyType" + ng-options="p.name for p in policyProviders track by p.type" + data-ng-change="addPolicy(policyType);" + data-ng-hide="historyBackOnSaveOrCancel"> + <option value="" disabled selected>{{:: 'authz-create-policy' | translate}}...</option> + </select> + </div> + </th> + </tr> + <tr data-ng-hide="!selectedPolicies || selectedPolicies.length == 0"> + <th>{{:: 'name' | translate}}</th> + <th>{{:: 'description' | translate}}</th> + <th width="20%">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="policy in selectedPolicies"> + <td data-ng-hide="historyBackOnSaveOrCancel"><a href="" data-ng-click="detailPolicy(policy)">{{policy.name}}</a></td> + <td data-ng-show="historyBackOnSaveOrCancel">{{policy.name}}</td> + <td>{{policy.description}}</td> + <td class="kc-action-cell" ng-click="removePolicy(selectedPolicies, policy);" style="vertical-align: middle"> + {{:: 'remove' | translate}} + </td> + </tr> + <tr data-ng-show="!selectedPolicies || selectedPolicies.length == 0"> + <td class="text-muted" colspan="3">{{:: 'authz-no-policies-assigned' | translate}}</td> + </tr> + </tbody> + </table> + </div> + <kc-tooltip>{{:: 'authz-policy-apply-policy.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="policy.decisionStrategy">{{:: 'authz-policy-decision-strategy' | translate}}</label> + <div class="col-sm-2"> + <select class="form-control" id="policy.decisionStrategy" + data-ng-model="policy.decisionStrategy" + ng-change="selectDecisionStrategy()"> + <option value="UNANIMOUS">{{:: 'authz-policy-decision-strategy-unanimous' | translate}}</option> + <option value="AFFIRMATIVE">{{:: 'authz-policy-decision-strategy-affirmative' | translate}}</option> + <option value="CONSENSUS">{{:: 'authz-policy-decision-strategy-consensus' | translate}}</option> + </select> + </div> + + <kc-tooltip>{{:: 'authz-policy-decision-strategy.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="logic">{{:: 'authz-policy-logic' | translate}}</label> + + <div class="col-sm-1"> + <select class="form-control" id="logic" name="logic" + data-ng-model="policy.logic"> + <option value="POSITIVE">{{:: 'authz-policy-logic-positive' | translate}}</option> + <option value="NEGATIVE">{{:: 'authz-policy-logic-negative' | translate}}</option> + </select> + </div> + + <kc-tooltip>{{:: 'authz-policy-logic.tooltip' | translate}}</kc-tooltip> + </div> + <input type="hidden" data-ng-model="policy.type"/> + </fieldset> + + <div class="form-group" data-ng-show="access.manageAuthorization"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed || (selectedPolicies == null || selectedPolicies.length == 0)">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/policy/provider/resource-server-policy-client-detail.html b/admin/resources/partials/authz/policy/provider/resource-server-policy-client-detail.html new file mode 100644 index 0000000..9c5630a --- /dev/null +++ b/admin/resources/partials/authz/policy/provider/resource-server-policy-client-detail.html @@ -0,0 +1,93 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/policy">{{:: 'authz-policies' | translate}}</a></li> + <li data-ng-show="policyState.state.policy.name != null && historyBackOnSaveOrCancel">{{policyState.state.policy.name}}</li> + <li data-ng-show="policyState.state.policy.name == null && historyBackOnSaveOrCancel">{{:: policyState.state.previousPage.name | translate}}</li> + <li data-ng-show="create">{{:: 'authz-add-client-policy' | translate}}</li> + <li data-ng-hide="create">{{:: 'client' | translate}}</li> + <li data-ng-hide="create">{{originalPolicy.name}}</li> + </ol> + + <h1 data-ng-show="create">{{:: 'authz-add-client-policy' | translate}}</h1> + <h1 data-ng-hide="create">{{originalPolicy.name|capitalize}}<i class="pficon pficon-delete clickable" data-ng-show="!create" + data-ng-click="remove()"></i></h1> + + <form class="form-horizontal" name="clientForm" novalidate> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="name">{{:: 'name' | translate}} <span class="required">*</span></label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="name" name="name" data-ng-model="policy.name" autofocus required data-ng-blur="checkNewNameAvailability()"> + </div> + <kc-tooltip>{{:: 'authz-policy-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="description">{{:: 'description' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="description" name="description" data-ng-model="policy.description"> + </div> + <kc-tooltip>{{:: 'authz-policy-description.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="clients">{{:: 'clients' | translate}} <span class="required">*</span></label> + + <div class="col-md-6"> + <input type="hidden" ui-select2="clientsUiSelect" id="clients" data-ng-model="selectedClient" data-ng-change="selectClient(selectedClient);" data-placeholder="Select an client..." data-ng-required="selectedClients.length == 0"> + </input> + </div> + <kc-tooltip>{{:: 'authz-policy-client-clients.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" style="margin-top: -15px;"> + <label class="col-md-2 control-label"></label> + <div class="col-sm-3"> + <table class="table table-striped table-bordered" id="selected-clients"> + <thead> + <tr data-ng-hide="!selectedClients.length"> + <th>{{:: 'clientId' | translate}}</th> + <th>{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="client in selectedClients | orderBy:'clientId'"> + <td>{{client.clientId}}</td> + <td class="kc-action-cell"> + <button class="btn btn-default btn-block btn-sm" ng-click="removeFromList(client);">{{:: 'remove' | translate}}</button> + </td> + </tr> + <tr data-ng-show="!selectedClients.length"> + <td class="text-muted" colspan="3">{{:: 'authz-no-clients-assigned' | translate}}</td> + </tr> + </tbody> + </table> + </div> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="logic">{{:: 'authz-policy-logic' | translate}}</label> + + <div class="col-sm-1"> + <select class="form-control" id="logic" + data-ng-model="policy.logic"> + <option value="POSITIVE">{{:: 'authz-policy-logic-positive' | translate}}</option> + <option value="NEGATIVE">{{:: 'authz-policy-logic-negative' | translate}}</option> + </select> + </div> + + <kc-tooltip>{{:: 'authz-policy-logic.tooltip' | translate}}</kc-tooltip> + </div> + <input type="hidden" data-ng-model="policy.type"/> + </fieldset> + + <div class="form-group" data-ng-show="access.manageAuthorization"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/policy/provider/resource-server-policy-group-detail.html b/admin/resources/partials/authz/policy/provider/resource-server-policy-group-detail.html new file mode 100644 index 0000000..cc1353b --- /dev/null +++ b/admin/resources/partials/authz/policy/provider/resource-server-policy-group-detail.html @@ -0,0 +1,126 @@ +<!-- + ~ * Copyright 2017 Red Hat, Inc. and/or its affiliates + ~ * and other contributors as indicated by the @author tags. + ~ * + ~ * Licensed under the Apache License, Version 2.0 (the "License"); + ~ * you may not use this file except in compliance with the License. + ~ * You may obtain a copy of the License at + ~ * + ~ * http://www.apache.org/licenses/LICENSE-2.0 + ~ * + ~ * Unless required by applicable law or agreed to in writing, software + ~ * distributed under the License is distributed on an "AS IS" BASIS, + ~ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ * See the License for the specific language governing permissions and + ~ * limitations under the License. + --> + +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/policy">{{:: 'authz-policies' | translate}}</a></li> + <li data-ng-show="policyState.state.policy.name != null && historyBackOnSaveOrCancel">{{policyState.state.policy.name}}</li> + <li data-ng-show="policyState.state.policy.name == null && historyBackOnSaveOrCancel">{{:: policyState.state.previousPage.name | translate}}</li> + <li data-ng-show="create">{{:: 'authz-add-group-policy' | translate}}</li> + <li data-ng-hide="create">{{:: 'groups' | translate}}</li> + <li data-ng-hide="create">{{originalPolicy.name}}</li> + </ol> + + <h1 data-ng-show="create">{{:: 'authz-add-group-policy' | translate}}</h1> + <h1 data-ng-hide="create">{{originalPolicy.name|capitalize}}<i class="pficon pficon-delete clickable" data-ng-show="!create" + data-ng-click="remove()"></i></h1> + + <form class="form-horizontal" name="groupPolicyForm" novalidate> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="name">{{:: 'name' | translate}} <span class="required">*</span></label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="name" name="name" data-ng-model="policy.name" autofocus required data-ng-blur="checkNewNameAvailability()"> + </div> + <kc-tooltip>{{:: 'authz-policy-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="description">{{:: 'description' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="description" name="description" data-ng-model="policy.description"> + </div> + <kc-tooltip>{{:: 'authz-policy-description.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="groupsClaim">{{:: 'authz-policy-group-claim' | translate}}</label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="groupsClaim" name="groupsClaim" data-ng-model="policy.groupsClaim"> + </div> + <kc-tooltip>{{:: 'authz-policy-group-claim.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="selectedGroups">{{:: 'groups' | translate}} <span class="required">*</span></label> + <div class="col-md-6"> + <div tree-id="tree" + angular-treeview="true" + tree-model="groupList" + node-id="id" + node-label="name" + node-children="subGroups" > + </div> + <button data-ng-click="selectGroup(tree.currentNode)" id="selectGroup" class="btn btn-primary" data-ng-disabled="tree.currentNode == null">Select</button> + <input class="form-control" type="text" id="selectedGroups" name="selectedGroups" data-ng-model="noop" data-ng-required="selectedGroups.length <= 0" autofocus required data-ng-show="false"> + </div> + <kc-tooltip>{{:: 'authz-policy-user-users.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-if="selectedGroups.length > 0"> + <label class="col-md-2 control-label"></label> + <div class="col-md-5"> + <table class="table table-striped table-bordered" id="selected-groups"> + <thead> + <tr> + <th>{{:: 'path' | translate}}</th> + <th class="col-sm-3">Extend to Children</th> + <th>{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="group in selectedGroups | orderBy:'name' track by $index"> + <td>{{group.path}}</td> + <td> + <input type="checkbox" ng-model="group.extendChildren" id="{{role.id}}" data-ng-click="extendChildren()"> + </td> + <td class="kc-action-cell"> + <button class="btn btn-default btn-block btn-sm" ng-click="removeFromList(group);">{{:: 'remove' | translate}}</button> + </td> + </tr> + <tr data-ng-show="!selectedGroups.length"> + <td class="text-muted" colspan="3">{{:: 'authz-no-groups-assigned' | translate}}</td> + </tr> + </tbody> + </table> + </div> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="logic">{{:: 'authz-policy-logic' | translate}}</label> + + <div class="col-sm-1"> + <select class="form-control" id="logic" + data-ng-model="policy.logic"> + <option value="POSITIVE">{{:: 'authz-policy-logic-positive' | translate}}</option> + <option value="NEGATIVE">{{:: 'authz-policy-logic-negative' | translate}}</option> + </select> + </div> + + <kc-tooltip>{{:: 'authz-policy-logic.tooltip' | translate}}</kc-tooltip> + </div> + <input type="hidden" data-ng-model="policy.type"/> + </fieldset> + <div class="form-group" data-ng-show="access.manageAuthorization"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/policy/provider/resource-server-policy-js-detail.html b/admin/resources/partials/authz/policy/provider/resource-server-policy-js-detail.html new file mode 100644 index 0000000..172c2b6 --- /dev/null +++ b/admin/resources/partials/authz/policy/provider/resource-server-policy-js-detail.html @@ -0,0 +1,69 @@ +<style> + .ace_editor { height: 200px; } +</style> +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/policy">{{:: 'authz-policies' | translate}}</a></li> + <li data-ng-show="policyState.state.policy.name != null && historyBackOnSaveOrCancel">{{policyState.state.policy.name}}</li> + <li data-ng-show="policyState.state.policy.name == null && historyBackOnSaveOrCancel">{{:: policyState.state.previousPage.name | translate}}</li> + <li data-ng-show="create">{{:: 'authz-add-js-policy' | translate}}</li> + <li data-ng-hide="create">JavaScript</li> + <li data-ng-hide="create">{{originalPolicy.name}}</li> + </ol> + + <h1 data-ng-show="create">{{:: 'authz-add-js-policy' | translate}}</h1> + <h1 data-ng-hide="create">{{originalPolicy.name|capitalize}}<i class="pficon pficon-delete clickable" data-ng-click="remove()"></i></h1> + + <form class="form-horizontal" name="clientForm" novalidate> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="name">{{:: 'name' | translate}} <span class="required">*</span></label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="name" name="name" data-ng-model="policy.name" autofocus required data-ng-blur="checkNewNameAvailability()" data-ng-disabled="readOnly"> + </div> + <kc-tooltip>{{:: 'authz-policy-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="description">{{:: 'description' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="description" name="description" data-ng-model="policy.description" data-ng-disabled="readOnly"> + </div> + <kc-tooltip>{{:: 'authz-policy-description.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="code">{{:: 'authz-policy-js-code' | translate}} </label> + <div class="col-sm-6"> + <div ui-ace="{ onLoad : initEditor }" id="code" data-ng-model="policy.code"></div> + </div> + <kc-tooltip>{{:: 'authz-policy-js-code.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="logic">{{:: 'authz-policy-logic' | translate}}</label> + + <div class="col-sm-1"> + <select class="form-control" id="logic" + data-ng-model="policy.logic" data-ng-disabled="readOnly"> + <option value="POSITIVE">{{:: 'authz-policy-logic-positive' | translate}}</option> + <option value="NEGATIVE">{{:: 'authz-policy-logic-negative' | translate}}</option> + </select> + </div> + + <kc-tooltip>{{:: 'authz-policy-logic.tooltip' | translate}}</kc-tooltip> + </div> + <input type="hidden" data-ng-model="policy.type"/> + </fieldset> + + <div class="form-group" data-ng-show="access.manageAuthorization"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/policy/provider/resource-server-policy-role-detail.html b/admin/resources/partials/authz/policy/provider/resource-server-policy-role-detail.html new file mode 100644 index 0000000..9448682 --- /dev/null +++ b/admin/resources/partials/authz/policy/provider/resource-server-policy-role-detail.html @@ -0,0 +1,169 @@ +<!-- + ~ JBoss, Home of Professional Open Source. + ~ Copyright 2016 Red Hat, Inc., and individual contributors + ~ as indicated by the @author tags. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/policy">{{:: 'authz-policies' | translate}}</a></li> + <li data-ng-show="policyState.state.policy.name != null && historyBackOnSaveOrCancel">{{policyState.state.policy.name}}</li> + <li data-ng-show="policyState.state.policy.name == null && historyBackOnSaveOrCancel">{{:: policyState.state.previousPage.name | translate}}</li> + <li data-ng-show="create">{{:: 'authz-add-role-policy' | translate}}</li> + <li data-ng-hide="create">{{:: 'roles' | translate}}</li> + <li data-ng-hide="create">{{originalPolicy.name}}</li> + </ol> + + <h1 data-ng-show="create">{{:: 'authz-add-role-policy' | translate}}</h1> + <h1 data-ng-hide="create">{{originalPolicy.name|capitalize}}<i class="pficon pficon-delete clickable" data-ng-show="!create" + data-ng-click="remove()"></i></h1> + + <form class="form-horizontal" name="clientForm" novalidate> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="name">{{:: 'name' | translate}} <span class="required">*</span></label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="name" name="name" data-ng-model="policy.name" autofocus required data-ng-blur="checkNewNameAvailability()"> + </div> + <kc-tooltip>{{:: 'authz-policy-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="description">{{:: 'description' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="description" name="description" data-ng-model="policy.description"> + </div> + <kc-tooltip>{{:: 'authz-policy-description.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="roles">{{:: 'realm-roles' | translate}} <span class="required">*</span></label> + + <div class="col-md-4"> + <select ui-select2="{ minimumInputLength: 1}" id="roles" data-ng-model="selectedRole" data-ng-change="selectRole(selectedRole);" data-placeholder="{{:: 'select-a-role' | translate}}..." + ng-options="role as role.name for role in roles" data-ng-required="selectedRoles.length == 0"> + <option></option> + </select> + </div> + + <kc-tooltip>{{:: 'authz-policy-role-realm-roles.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" style="margin-top: -15px;"> + <label class="col-md-2 control-label"></label> + <div class="col-sm-4" data-ng-show="hasRealmRole()"> + <table class="table table-striped table-bordered" id="selected-realm-roles"> + <thead> + <tr> + <th class="col-sm-5">{{:: 'name' | translate}}</th> + <th>{{:: 'authz-required' | translate}}</th> + <th>{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="role in selectedRoles | orderBy:'name'" ng-if="!role.clientRole"> + <td>{{role.name}}</td> + <td><input type="checkbox" ng-model="role.required" id="{{role.id}}"></td> + <td class="kc-action-cell"> + <button class="btn btn-default btn-block btn-sm" ng-click="removeFromList(role);">{{:: 'remove' | translate}}</button> + </td> + </tr> + <tr data-ng-show="!selectedRoles.length"> + <td class="text-muted" colspan="3">{{:: 'authz-no-roles-assigned' | translate}}</td> + </tr> + </tbody> + </table> + </div> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="clients">{{:: 'clients' | translate}}</label> + + <div class="col-md-4"> + <select class="form-control" id="clients" + ng-model="selectedClient" + ng-change="selectClient()" + data-ng-options="current as current.clientId for current in clients"> + <option value="">{{:: 'selectOne' | translate}}...</option> + </select> + </div> + <kc-tooltip>{{:: 'authz-policy-role-clients.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="clientRoles">{{:: 'client-roles' | translate}} <span class="required">*</span></label> + + <div class="col-md-4"> + <select ui-select2="{ minimumInputLength: 1}" id="clientRoles" data-ng-model="selectedRole" data-ng-change="selectRole(selectedRole);" data-placeholder="{{:: 'select-a-role' | translate}}..." + ng-options="role as role.name for role in clientRoles" data-ng-required="selectedRoles.length == 0" data-ng-disabled="!selectedClient"> + <option></option> + </select> + </div> + + <kc-tooltip>{{:: 'authz-policy-role-client-roles.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" style="margin-top: -15px;"> + <label class="col-md-2 control-label"></label> + <div class="col-sm-4" data-ng-show="hasClientRole()"> + <table class="table table-striped table-bordered" id="selected-client-roles"> + <thead> + <tr> + <th class="col-sm-5">{{:: 'name' | translate}}</th> + <th class="col-sm-5">{{:: 'client' | translate}}</th> + <th>{{:: 'authz-required' | translate}}</th> + <th>{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="role in selectedRoles | orderBy:'name'" ng-if="role.clientRole"> + <td>{{role.name}}</td> + <td>{{role.container.name}}</td> + <td><input type="checkbox" ng-model="role.required" id="{{role.id}}"></td> + <td class="kc-action-cell"> + <button class="btn btn-default btn-block btn-sm" ng-click="removeFromList(role);">{{:: 'remove' | translate}}</button> + </td> + </tr> + <tr data-ng-show="!selectedRoles.length"> + <td class="text-muted" colspan="3">{{:: 'authz-no-roles-assigned' | translate}}</td> + </tr> + </tbody> + </table> + </div> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="logic">{{:: 'authz-policy-logic' | translate}}</label> + + <div class="col-sm-1"> + <select class="form-control" id="logic" + data-ng-model="policy.logic"> + <option value="POSITIVE">{{:: 'authz-policy-logic-positive' | translate}}</option> + <option value="NEGATIVE">{{:: 'authz-policy-logic-negative' | translate}}</option> + </select> + </div> + + <kc-tooltip>{{:: 'authz-policy-logic.tooltip' | translate}}</kc-tooltip> + </div> + <input type="hidden" data-ng-model="policy.type"/> + </fieldset> + <div class="form-group" data-ng-show="access.manageAuthorization"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed && !historyBackOnSaveOrCancel">{{:: 'cancel' | translate}}</button> + </div> + </div> + {{policyState.page.previous}} + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/policy/provider/resource-server-policy-time-detail.html b/admin/resources/partials/authz/policy/provider/resource-server-policy-time-detail.html new file mode 100644 index 0000000..4af9014 --- /dev/null +++ b/admin/resources/partials/authz/policy/provider/resource-server-policy-time-detail.html @@ -0,0 +1,119 @@ +<style> + .ace_editor { height: 200px; } +</style> +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/policy">{{:: 'authz-policies' | translate}}</a></li> + <li data-ng-show="policyState.state.policy.name != null && historyBackOnSaveOrCancel">{{policyState.state.policy.name}}</li> + <li data-ng-show="policyState.state.policy.name == null && historyBackOnSaveOrCancel">{{:: policyState.state.previousPage.name | translate}}</li> + <li data-ng-show="create">{{:: 'authz-add-time-policy' | translate}}</li> + <li data-ng-hide="create">{{:: 'time' | translate}}</li> + <li data-ng-hide="create">{{originalPolicy.name}}</li> + </ol> + + + <h1 data-ng-show="create">{{:: 'authz-add-time-policy' | translate}}</h1> + <h1 data-ng-hide="create">{{originalPolicy.name|capitalize}}<i class="pficon pficon-delete clickable" data-ng-click="remove()"></i></h1> + + <form class="form-horizontal" name="clientForm" novalidate> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="name">{{:: 'name' | translate}} <span class="required">*</span></label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="name" name="name" data-ng-model="policy.name" autofocus required data-ng-blur="checkNewNameAvailability()"> + </div> + <kc-tooltip>{{:: 'authz-policy-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="description">{{:: 'description' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="description" name="description" data-ng-model="policy.description"> + </div> + <kc-tooltip>{{:: 'authz-policy-description.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="notBefore">{{:: 'not-before' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" style="width: 150px" type="text" id="notBefore" name="notBefore" data-ng-model="policy.notBefore" placeholder="yyyy-MM-dd hh:mm:ss" data-ng-required="isRequired()"> + </div> + <kc-tooltip>{{:: 'authz-policy-time-not-before.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="notOnOrAfter">{{:: 'authz-policy-time-not-on-after' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" style="width: 150px" type="text" id="notOnOrAfter" name="notOnOrAfter" data-ng-model="policy.notOnOrAfter" placeholder="yyyy-MM-dd hh:mm:ss" data-ng-required="isRequired()"> + </div> + <kc-tooltip>{{:: 'authz-policy-time-not-on-after.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="dayMonth">{{:: 'authz-policy-time-day-month' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" min="1" max="31" data-ng-model="policy.dayMonth" id="dayMonth" name="dayMonth" data-ng-required="isRequired()"/> to <input class="form-control" type="number" min="{{policy.dayMonth}}" max="31" data-ng-model="policy.dayMonthEnd" id="dayMonthEnd" name="dayMonthEnd"/> + </div> + <kc-tooltip>{{:: 'authz-policy-time-day-month.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="month">{{:: 'authz-policy-time-month' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" min="1" max="12" data-ng-model="policy.month" id="month" name="month" data-ng-required="isRequired()"/> to <input class="form-control" type="number" min="{{policy.month}}" max="12" data-ng-model="policy.monthEnd" id="monthEnd" name="monthEnd"/> + </div> + <kc-tooltip>{{:: 'authz-policy-time-month.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="year">{{:: 'authz-policy-time-year' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" data-ng-model="policy.year" id="year" name="year" data-ng-required="isRequired()"/> to <input class="form-control" type="number" min="{{policy.year}}" max="2050" data-ng-model="policy.yearEnd" id="yearEnd" name="yearEnd"/> + </div> + <kc-tooltip>{{:: 'authz-policy-time-year.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="hour">{{:: 'authz-policy-time-hour' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" min="0" max="23" data-ng-model="policy.hour" id="hour" name="hour" data-ng-required="isRequired()"/> to <input class="form-control" type="number" min="{{policy.hour}}" max="23" data-ng-model="policy.hourEnd" id="hourEnd" name="hourEnd"/> + </div> + <kc-tooltip>{{:: 'authz-policy-time-hour.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="minute">{{:: 'authz-policy-time-minute' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" min="0" max="59" data-ng-model="policy.minute" id="minute" name="minute" data-ng-required="isRequired()"/> to <input class="form-control" type="number" min="{{policy.minute}}" max="59" data-ng-model="policy.minuteEnd" id="minuteEnd" name="minuteEnd"/> + </div> + <kc-tooltip>{{:: 'authz-policy-time-minute.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="logic">{{:: 'authz-policy-logic' | translate}}</label> + + <div class="col-sm-1"> + <select class="form-control" id="logic" + data-ng-model="policy.logic"> + <option value="POSITIVE">{{:: 'authz-policy-logic-positive' | translate}}</option> + <option value="NEGATIVE">{{:: 'authz-policy-logic-negative' | translate}}</option> + </select> + </div> + + <kc-tooltip>{{:: 'authz-policy-logic.tooltip' | translate}}</kc-tooltip> + </div> + <input type="hidden" data-ng-model="policy.type"/> + </fieldset> + + <div class="form-group" data-ng-show="access.manageAuthorization"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/policy/provider/resource-server-policy-user-detail.html b/admin/resources/partials/authz/policy/provider/resource-server-policy-user-detail.html new file mode 100644 index 0000000..80d81ac --- /dev/null +++ b/admin/resources/partials/authz/policy/provider/resource-server-policy-user-detail.html @@ -0,0 +1,93 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/policy">{{:: 'authz-policies' | translate}}</a></li> + <li data-ng-show="policyState.state.policy.name != null && historyBackOnSaveOrCancel">{{policyState.state.policy.name}}</li> + <li data-ng-show="policyState.state.policy.name == null && historyBackOnSaveOrCancel">{{:: policyState.state.previousPage.name | translate}}</li> + <li data-ng-show="create">{{:: 'authz-add-user-policy' | translate}}</li> + <li data-ng-hide="create">{{:: 'user' | translate}}</li> + <li data-ng-hide="create">{{originalPolicy.name}}</li> + </ol> + + <h1 data-ng-show="create">{{:: 'authz-add-user-policy' | translate}}</h1> + <h1 data-ng-hide="create">{{originalPolicy.name|capitalize}}<i class="pficon pficon-delete clickable" data-ng-show="!create" + data-ng-click="remove()"></i></h1> + + <form class="form-horizontal" name="clientForm" novalidate> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="name">{{:: 'name' | translate}} <span class="required">*</span></label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="name" name="name" data-ng-model="policy.name" autofocus required data-ng-blur="checkNewNameAvailability()"> + </div> + <kc-tooltip>{{:: 'authz-policy-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="description">{{:: 'description' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="description" name="description" data-ng-model="policy.description"> + </div> + <kc-tooltip>{{:: 'authz-policy-description.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="users">{{:: 'users' | translate}} <span class="required">*</span></label> + + <div class="col-md-6"> + <input type="hidden" ui-select2="usersUiSelect" id="users" data-ng-model="selectedUser" data-ng-change="selectUser(selectedUser);" data-placeholder="Select an user..." data-ng-required="selectedUsers.length == 0""> + </input> + </div> + <kc-tooltip>{{:: 'authz-policy-user-users.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" style="margin-top: -15px;"> + <label class="col-md-2 control-label"></label> + <div class="col-sm-3"> + <table class="table table-striped table-bordered" id="selected-users"> + <thead> + <tr data-ng-hide="!selectedUsers.length"> + <th>{{:: 'username' | translate}}</th> + <th>{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="user in selectedUsers | orderBy:'username'"> + <td>{{user.username}}</td> + <td class="kc-action-cell"> + <button class="btn btn-default btn-block btn-sm" ng-click="removeFromList(selectedUsers, user);">{{:: 'remove' | translate}}</button> + </td> + </tr> + <tr data-ng-show="!selectedUsers.length"> + <td class="text-muted" colspan="3">{{:: 'authz-no-users-assigned' | translate}}</td> + </tr> + </tbody> + </table> + </div> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="logic">{{:: 'authz-policy-logic' | translate}}</label> + + <div class="col-sm-1"> + <select class="form-control" id="logic" + data-ng-model="policy.logic"> + <option value="POSITIVE">{{:: 'authz-policy-logic-positive' | translate}}</option> + <option value="NEGATIVE">{{:: 'authz-policy-logic-negative' | translate}}</option> + </select> + </div> + + <kc-tooltip>{{:: 'authz-policy-logic.tooltip' | translate}}</kc-tooltip> + </div> + <input type="hidden" data-ng-model="policy.type"/> + </fieldset> + + <div class="form-group" data-ng-show="access.manageAuthorization"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed && !historyBackOnSaveOrCancel">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/policy/resource-server-policy-evaluate-result.html b/admin/resources/partials/authz/policy/resource-server-policy-evaluate-result.html new file mode 100644 index 0000000..19ff720 --- /dev/null +++ b/admin/resources/partials/authz/policy/resource-server-policy-evaluate-result.html @@ -0,0 +1,72 @@ +<fieldset> + <form class="form-horizontal" name="clientForm" novalidate> + <span data-ng-show="evaluationResult.results.length == 0"><strong>{{:: 'authz-evaluation-no-result' | translate}}</strong></span> + <fieldset class="border-top" data-ng-repeat="result in evaluationResult.results"> + <legend collapsed><span class="text">{{result.resource.name}}</span> + </legend> + <div class="form-group"> + <label class="col-md-2 control-label">{{:: 'authz-result' | translate}}</label> + + <div class="col-sm-2"> + <div> + <span style="color: green" + data-ng-show="result.status == 'PERMIT'"><strong>{{result.status}}</strong></span> + <span style="color: red" + data-ng-hide="result.status == 'PERMIT'"><strong>{{result.status}}</strong></span> + </div> + </div> + <kc-tooltip>{{:: 'authz-evaluation-result.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label">{{:: 'authz-scopes' | translate}}</label> + + <div class="col-sm-2"> + <span data-ng-show="result.allowedScopes.length == 0">{{:: 'authz-no-scopes-available' | translate}}</span> + + <div> + <ul> + <li data-ng-repeat="scope in result.allowedScopes"> + {{scope.name}} + </li> + </ul> + </div> + </div> + <kc-tooltip>{{:: 'authz-evaluation-scopes.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="!evaluationResult.entitlements"> + <label class="col-md-2 control-label">{{:: 'authz-policies' | translate}}</label> + + <div class="col-sm-6"> + <span data-ng-show="result.policies.length == 0">{{:: 'authz-evaluation-no-policies-resource' | translate}}</span> + <div> + <div> + <li data-ng-repeat="policyResult in result.policies"> + <strong> + <a data-ng-show="policyResult.policy.type != 'uma'" + href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/permission/{{policyResult.policy.type}}/{{policyResult.policy.id}}">{{policyResult.policy.name}}</a> + <a data-ng-show="policyResult.policy.type == 'uma'" + href=""> + {{policyResult.policy.description}} + </a> + </strong> + decision was <span style="color: green" data-ng-show="policyResult.status == 'PERMIT'"><strong>{{policyResult.status}}</strong></span> + <span style="color: red" data-ng-hide="policyResult.status == 'PERMIT'"><strong>{{policyResult.status}}</strong></span> + by <strong>{{policyResult.policy.decisionStrategy}}</strong> decision. {{policyResult.policy.scopes.length > 0 ? (policyResult.status == 'DENY' ? 'Denied Scopes:' : 'Granted Scopes:') : ''}} <span data-ng-repeat="scope in policyResult.policy.scopes"><strong style="color: {{(policyResult.status == 'DENY' ? 'red' : 'green')}}">{{scope}}{{$last ? '' : ', '}}</strong></span>{{policyResult.policy.scopes.length > 0 ? '.' : ''}} + <ul data-ng-show="policyResult.policy.type != 'uma'"> + <li data-ng-repeat="subPolicy in policyResult.associatedPolicies"> + <strong><a + href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/policy/{{subPolicy.policy.type}}/{{subPolicy.policy.id}}">{{subPolicy.policy.name}}</a></strong> + voted to <span style="color: green" + data-ng-show="subPolicy.status == 'PERMIT'"><strong>{{subPolicy.status}}</strong></span> + <span style="color: red" data-ng-hide="subPolicy.status == 'PERMIT'"><strong>{{subPolicy.status}}</strong></span>.</a> + </li> + </ul> + </li> + </ul> + </div> + </div> + <kc-tooltip>{{:: 'authz-evaluation-policies.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + </form> +</fieldset>
\ No newline at end of file diff --git a/admin/resources/partials/authz/policy/resource-server-policy-evaluate.html b/admin/resources/partials/authz/policy/resource-server-policy-evaluate.html new file mode 100644 index 0000000..aedbdea --- /dev/null +++ b/admin/resources/partials/authz/policy/resource-server-policy-evaluate.html @@ -0,0 +1,267 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/evaluate">{{:: 'authz-policy-evaluation' | translate}}</a></li> + </ol> + + <kc-tabs-resource-server></kc-tabs-resource-server> + + <div data-ng-show="showResult"> + <br> + <a href="" data-ng-click="showRequestTab()">{{:: 'back' | translate}}</a> + | + <a href="" data-ng-click="reevaluate()">{{:: 'authz-evaluation-re-evaluate' | translate}}</a> + | + <a href="" data-ng-click="showAuthzData()">{{:: 'authz-show-authorization-data' | translate}}</a> + </div> + + <div data-ng-show="evaluationResult && !showResult"> + <br> + <a href="" data-ng-click="showResultTab()">{{:: 'authz-evaluation-previous' | translate}}</a> + </div> + + <div data-ng-show="showRpt"> + <div class="form-group"> + <label class="col-sm-1 control-label" for="rpt">{{:: 'authz-evaluation-authorization-data' | translate}}</label> + <div class="col-md-6"> + <textarea id="rpt" class="form-control" rows="20">{{evaluationResult.rpt | json}}</textarea> + </div> + <kc-tooltip>{{:: 'authz-evaluation-authorization-data.tooltip' | translate}}</kc-tooltip> + </div> + </div> + + <div data-ng-hide="showResult"> + <form class="form-horizontal" name="clientForm" novalidate> + <fieldset> + <fieldset class="border-top"> + <legend><span class="text">{{:: 'authz-evaluation-identity-information' | translate}}</span> + <kc-tooltip>{{:: 'authz-evaluation-identity-information.tooltip' | translate}}</kc-tooltip> + </legend> + <div class="form-group"> + <label class="col-md-2 control-label" for="client">{{:: 'client' | translate}}</label> + + <div class="col-sm-2"> + <div> + <select class="form-control" id="client" + ng-model="authzRequest.clientId" + ng-options="client.id as client.clientId for client in clients track by client.id"> + <option value="">{{:: 'authz-select-client' | translate}}...</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'authz-evaluation-client.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="users">{{:: 'user' | translate}} <span class="required" + data-ng-show="!authzRequest.roleIds || authzRequest.roleIds.length == 0">*</span></label> + + <div class="col-md-6"> + <input type="hidden" ui-select2="usersUiSelect" id="users" data-ng-model="selectedUser" data-ng-change="selectUser(selectedUser);" data-placeholder="{{:: 'authz-select-user' | translate}}..." + data-ng-required="!authzRequest.roleIds || authzRequest.roleIds.length == 0"> + </input> + </div> + + <kc-tooltip>{{:: 'authz-evaluation-user.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="reqActions">{{:: 'roles' | translate}} <span class="required" + data-ng-show="!authzRequest.userId || authzRequest.userId == null">*</span></label> + + <div class="col-md-6"> + <select ui-select2="{ minimumInputLength: 1}" + data-ng-model="authzRequest.roleIds" + data-placeholder="{{:: 'authz-any-role' | translate}}..." multiple + data-ng-required="!authzRequest.userId || authzRequest.userId == null"> + <option ng-repeat="role in roles track by role.id" value="{{role.name}}">{{role.name}} + </option> + </select> + </div> + + <kc-tooltip>{{:: 'authz-evaluation-role.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + <fieldset> + <legend collapsed><span class="text">{{:: 'authz-evaluation-contextual-info' | translate}}</span> + <kc-tooltip>{{:: 'authz-evaluation-contextual-info.tooltip' | translate}}</kc-tooltip> + </legend> + <div class="form-group clearfix block"> + <label class="col-md-2 control-label" for="newRedirectUri">{{:: 'authz-evaluation-contextual-attributes' | translate}}</label> + + <div class="col-sm-6"> + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th>{{:: 'key' | translate}}</th> + <th>{{:: 'value' | translate}}</th> + <th>{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="(key, value) in (authzRequest.context.attributes)"> + <td>{{getContextAttributeName(key)}}</td> + <td> + <select class="form-control" id="attribute-{{key}}" + data-ng-model="authzRequest.context.attributes[key]" + data-ng-show="getContextAttribute(key).values" + ng-options="value1.key as value1.name for value1 in getContextAttribute(key).values"> + </select> + <input ng-model="authzRequest.context.attributes[key]" class="form-control" + type="text" name="{{key}}" id="attribute-{{key}}" + data-ng-hide="getContextAttribute(key).values"/> + </td> + <td class="kc-action-cell"> + <button class="btn btn-default btn-block btn-sm" + data-ng-click="removeContextAttribute(key)">{{:: 'delete' | translate}} + </button> + </td> + </tr> + <tr> + <td> + <select class="form-control" id="newContextAttribute.key" + data-ng-model="newContextAttribute" + ng-change="selectDefaultContextAttribute()" + data-ng-hide="!isDefaultContextAttribute()" + ng-options="attribute as attribute.name for attribute in defaultContextAttributes track by attribute.key"> + </select> + <input ng-model="newContextAttribute.key" class="form-control" type="text" + id="newAttributeKey" data-ng-hide="isDefaultContextAttribute()"/> + </td> + <td> + <select class="form-control" id="newContextAttribute.value" + data-ng-model="newContextAttribute.value" + data-ng-show="newContextAttribute.values" + ng-options="value.key as value.name for value in newContextAttribute.values track by value.key"> + </select> + <input ng-model="newContextAttribute.value" class="form-control" type="text" + id="newAttributeValue" data-ng-show="!newContextAttribute.values"/> + </td> + <td class="kc-action-cell"> + <button class="btn btn-default btn-block btn-sm" + data-ng-click="addContextAttribute()" + data-ng-disabled="!newContextAttribute.key || newContextAttribute.key == ''"> + {{:: 'add' | translate}} + </button> + </td> + </tr> + </tbody> + </table> + </div> + + <kc-tooltip>{{:: 'authz-evaluation-contextual-attributes.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + <fieldset> + <legend><span class="text">{{:: 'authz-permissions' | translate}}</span> + <kc-tooltip>{{:: 'authz-evaluation-permissions.tooltip' | translate}}</kc-tooltip> + </legend> + <div class="form-group"> + <label class="col-md-2 control-label" for="applyResourceType">{{:: 'authz-permission-resource-apply-to-resource-type' | translate}}</label> + + <div class="col-md-6"> + <input ng-model="applyResourceType" id="applyResourceType" onoffswitch + data-ng-click="setApplyToResourceType()"/> + </div> + <kc-tooltip>{{:: 'authz-permission-resource-apply-to-resource-type.tooltip' | translate}} + </kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-hide="applyResourceType"> + <label class="col-md-2 control-label" for="reqActions">{{:: 'authz-resources' | translate}} <span class="required">*</span></label> + + <div class="col-md-6"> + <input type="hidden" ui-select2="resourcesUiSelect" id="reqActions3" data-ng-change="resolveScopes()" data-ng-model="newResource" data-placeholder="{{:: 'authz-select-resource' | translate}}..." data-ng-required="!applyResourceType && authzRequest.resources.length == 0 && !authzRequest.entitlements" /> + </div> + <kc-tooltip>{{:: 'authz-permission-resource-resource.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="applyResourceType"> + <label class="col-md-2 control-label" for="newResource.type">{{:: 'authz-resource-type' | translate}} <span + class="required">*</span></label> + + <div class="col-md-6"> + <input class="form-control" type="text" id="newResource.type" name="newResource.type" + data-ng-model="authzRequest.resources[0].type" + data-ng-required="applyResourceType && !authzRequest.resources[0].type && !authzRequest.entitlements"> + </div> + + <kc-tooltip>{{:: 'authz-permission-resource-type.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="applyResourceType || newResource._id == null"> + <label class="col-md-2 control-label" for="newResource.scopes">{{:: 'authz-scopes' | translate}}</label> + + <div class="col-md-6"> + <input type="hidden" ui-select2="scopesUiSelect" id="reqActions" data-ng-model="newScopes" data-placeholder="{{:: 'authz-any-scope' | translate}}..." multiple /> + </div> + + <kc-tooltip>{{:: 'authz-permission-scope-scope.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="newResource._id != null"> + <label class="col-md-2 control-label" for="newResource.scopes">{{:: 'authz-scopes' | translate}}</label> + + <div class="col-md-6"> + <select ui-select2 + id="newResource.scopes" + data-ng-model="newScopes" + data-placeholder="{{:: 'authz-any-scope' | translate}}..." multiple> + <option ng-repeat="scope in scopes" value="{{scope.name}}">{{scope.name}}</option> + </select> + </div> + + <kc-tooltip>{{:: 'authz-permission-scope-scope.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="!applyResourceType"> + <label class="col-md-2 control-label" for="newRedirectUri"></label> + + <div class="col-sm-6"> + <button data-ng-click="addResource()" class="btn btn-primary">Add</button> + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th>{{:: 'authz-resource' | translate}}</th> + <th>{{:: 'authz-scopes' | translate}}</th> + <th>{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr data-ng-show="!authzRequest.resources || authzRequest.resources.length == 0"> + <td colspan="3"> + {{:: 'authz-no-resources' | translate}} + </td> + </tr> + <tr ng-repeat="resource in authzRequest.resources"> + <td>{{resource.name ? resource.name : 'authz-evaluation-any-resource-with-scopes' | translate}}</td> + <td> + <span data-ng-show="!resource.scopes.length">{{:: 'authz-any-scope' | translate}}.</span> + <span data-ng-show="resource.scopes.length > 0"> + <span ng-repeat="scope in resource.scopes"> + {{scope.name ? scope.name : scope}} {{$last ? '' : ', '}} + </span> + </span> + </td> + <td class="kc-action-cell"> + <button class="btn btn-default btn-block btn-sm" + data-ng-click="removeResource($index)">{{:: 'delete' | translate}} + </button> + </td> + </tr> + </tbody> + </table> + </div> + </div> + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-click="evaluate()">{{:: 'authz-evaluation-evaluate' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'reset' | translate}}</button> + </div> + </div> + </fieldset> + </form> + </div> + <div data-ng-include="resultUrl" data-ng-show="showResult && !showRpt"/> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/policy/resource-server-policy-list.html b/admin/resources/partials/authz/policy/resource-server-policy-list.html new file mode 100644 index 0000000..d6f220f --- /dev/null +++ b/admin/resources/partials/authz/policy/resource-server-policy-list.html @@ -0,0 +1,117 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/policy">{{:: 'authz-policies' | translate}}</a></li> + </ol> + + <kc-tabs-resource-server></kc-tabs-resource-server> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="5"> + <div class="form-inline"> + <div class="form-group"> + {{:: 'filter' | translate}}: + <div class="input-group"> + <input type="text" placeholder="{{:: 'name' | translate}}" data-ng-model="query.name" class="form-control search" onkeydown="if (event.keyCode == 13) document.getElementById('policySearch').click()"> + <div class="input-group-addon"> + <i class="fa fa-search" id="policySearch" type="submit" data-ng-click="firstPage()"></i> + </div> + </div> + <div class="input-group"> + <input type="text" placeholder="{{:: 'authz-resource' | translate}}" data-ng-model="query.resource" class="form-control search" onkeydown="if (event.keyCode == 13) document.getElementById('policySearch').click()"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit" data-ng-click="firstPage()"></i> + </div> + </div> + <div class="input-group"> + <input type="text" placeholder="{{:: 'authz-scope' | translate}}" data-ng-model="query.scope" class="form-control search" onkeydown="if (event.keyCode == 13) document.getElementById('policySearch').click()"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit" data-ng-click="firstPage()"></i> + </div> + </div> + <div class="input-group"> + <select class="form-control search" data-ng-model="query.type" + ng-options="p.type as p.name for p in policyProviders track by p.type" data-ng-change="firstPage()"> + <option value="" selected ng-click="query.type = ''">{{:: 'authz-all-types' | translate}}</option> + </select> + </div> + </div> + <div class="pull-right"> + <select id="create-policy" class="form-control" ng-model="policyType" + ng-options="p.name for p in policyProviders track by p.type" + data-ng-change="addPolicy(policyType);"> + <option value="" disabled selected>{{:: 'authz-create-policy' | translate}}...</option> + </select> + </div> + </div> + </th> + </tr> + <tr data-ng-hide="policies.length == 0"> + <th width="1%"></th> + <th>{{:: 'name' | translate}}</th> + <th>{{:: 'description' | translate}}</th> + <th width="7%">{{:: 'type' | translate}}</th> + <th width="6%" style="text-align: center;">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tfoot data-ng-show="policies && (policies.length >= query.max || query.first > 0)"> + <tr> + <td colspan="5"> + <div class="table-nav"> + <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button> + <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button> + <button data-ng-click="nextPage()" class="next" ng-disabled="policies.length < query.max">{{:: 'next-page' | translate}}</button> + </div> + </td> + </tr> + </tfoot> + <tbody> + <tr ng-repeat-start="policy in policies | filter: {name: search.name, type: search.type} | orderBy:'name'" data-ng-click="showDetails(policy, $event);" style="cursor: pointer"> + <td> + <span ng-if="!policy.details || !policy.details.loaded" class="fa fa-angle-right"></span> + <span ng-if="policy.details && policy.details.loaded" class="fa fa-angle-right fa-angle-down"></span> + </td> + <td><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/policy/{{policy.type.endsWith('.js') ? 'js': policy.type}}/{{policy.id}}">{{policy.name}}</a></td> + <td>{{policy.description}}</td> + <td>{{policy.type}}</td> + <td align="center"> + <div class="dropdown dropdown-kebab-pf"> + <button class="btn btn-default" ng-click="delete(policy);">{{:: 'delete' | translate}} + </button> + </div> + </td> + </tr> + <tr ng-if="policy.details && policy.details.loaded" ng-repeat-end=""> + <td colspan="5" style="background-color: #ffffff"> + <div class="list-group-item-container container-fluid"> + <div class="close" data-ng-click="showDetails(policy, $event);" style="padding-top: 10px"> + <span class="pficon pficon-close"></span> + </div> + <div class="row"> + <div class="col-md-12"> + <dl class="dl-horizontal"> + <dt>Dependent Policies</dt> + <dd> + <span data-ng-show="policy.dependentPolicies && !policy.dependentPolicies.length">{{:: 'authz-no-policies-available' | translate}}</span> + <span ng-repeat="dep in policy.dependentPolicies" data-ng-show="policy.dependentPolicies.length > 0"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/{{dep.type == 'scope' || dep.type == 'resource' ? 'permission' : 'policy'}}/{{dep.type}}/{{dep.id}}">{{dep.name}}</a>{{$last ? '' : ', '}}</span> + </dd> + </dl> + </div> + </div> + </div> + </td> + </tr> + <tr data-ng-show="(policies | filter:search).length == 0"> + <td class="text-muted" colspan="3" data-ng-show="search.name">{{:: 'no-results' | translate}}</td> + <td class="text-muted" colspan="3" data-ng-hide="search.name">{{:: 'authz-no-policies-available' | translate}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/resource-server-detail.html b/admin/resources/partials/authz/resource-server-detail.html new file mode 100644 index 0000000..5bf7d88 --- /dev/null +++ b/admin/resources/partials/authz/resource-server-detail.html @@ -0,0 +1,77 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'settings' | translate}}</a></li> + </ol> + + <kc-tabs-resource-server></kc-tabs-resource-server> + + <form class="form-horizontal" name="clientForm" novalidate> + <fieldset> + <div class="form-group"> + <label for="import-file" class="col-sm-2 control-label">{{:: 'import' | translate}}</label> + <div class="col-md-6"> + <div class="controls kc-button-input-file" data-ng-show="!importing"> + <label for="import-file" class="btn btn-default">{{:: 'select-file' | translate}} <i class="pficon pficon-import"></i></label> + <input id="import-file" type="file" class="hidden" kc-on-read-file="onFileSelect($fileContent)"> + </div> + <div class="col-md-6" data-ng-show="importing"> + <input type="button" class="btn btn-default" data-ng-click="viewImportDetails()" value="{{:: 'view-details' | translate}}"/> + </div> + </div> + <kc-tooltip>{{:: 'authz-import-config.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="importing"> + <button class="btn btn-default" data-ng-click="import()" data-ng-disabled="!changed">Import</button> + <button kc-cancel data-ng-click="reset()">Cancel</button> + </div> + </div> + </fieldset> + <fieldset class="border-top" data-ng-hide="importing"> + <div class="form-group"> + <label class="col-md-2 control-label" for="server.policyEnforcementMode">{{:: 'authz-policy-enforcement-mode' | translate}}</label> + <div class="col-md-2"> + <select class="form-control" id="server.policyEnforcementMode" data-ng-model="server.policyEnforcementMode"> + <option value="ENFORCING">{{:: 'authz-policy-enforcement-mode-enforcing' | translate}}</option> + <option value="PERMISSIVE">{{:: 'authz-policy-enforcement-mode-permissive' | translate}}</option> + <option value="DISABLED">{{:: 'authz-policy-enforcement-mode-disabled' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'authz-policy-enforcement-mode.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="server.decisionStrategy">{{:: 'authz-policy-decision-strategy' | translate}}</label> + + <div class="col-sm-2"> + <select class="form-control" id="server.decisionStrategy" + data-ng-model="server.decisionStrategy" + ng-change="selectDecisionStrategy()"> + <option value="UNANIMOUS">{{:: 'authz-policy-decision-strategy-unanimous' | translate}}</option> + <option value="AFFIRMATIVE">{{:: 'authz-policy-decision-strategy-affirmative' | translate}}</option> + </select> + </div> + + <kc-tooltip>{{:: 'authz-server-decision-strategy.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="server.allowRemoteResourceManagement">{{:: 'authz-remote-resource-management' | translate}}</label> + <div class="col-md-6"> + <input ng-model="server.allowRemoteResourceManagement" id="server.allowRemoteResourceManagement" onoffswitch /> + </div> + <kc-tooltip>{{:: 'authz-remote-resource-management.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="access.manageAuthorization"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </fieldset> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/resource-server-export-settings.html b/admin/resources/partials/authz/resource-server-export-settings.html new file mode 100644 index 0000000..86505db --- /dev/null +++ b/admin/resources/partials/authz/resource-server-export-settings.html @@ -0,0 +1,35 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'export-settings' | translate}}</a></li> + </ol> + + <kc-tabs-resource-server></kc-tabs-resource-server> + + <form class="form-horizontal" name="exportForm" novalidate> + <fieldset> + <div class="form-group"> + <label class="col-md-2 control-label">{{:: 'authz-export-settings' | translate}}</label> + <div class="col-md-6"> + <button data-ng-click="export()" class="btn btn-primary" data-ng-hide="settings">{{:: 'export' | translate}}</button> + <button data-ng-click="downloadSettings()" class="btn btn-primary" data-ng-show="settings">{{:: 'download' | translate}}</button> + <button data-ng-click="cancelExport()" class="btn btn-primary" data-ng-show="settings">{{:: 'cancel' | translate}}</button> + </div> + <kc-tooltip>{{:: 'authz-export-settings.tooltip' | translate}}</kc-tooltip> + </div> + <fieldset class="margin-top"> + <div class="form-group" ng-show="settings"> + <div class="col-sm-12"> + <a class="btn btn-primary btn-lg" data-ng-click="download()" type="submit" ng-show="installation">{{:: 'download' | translate}}</a> + <textarea class="form-control" rows="20" kc-select-action="click">{{settings}}</textarea> + </div> + </div> + </fieldset> + </fieldset> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/resource-server-list.html b/admin/resources/partials/authz/resource-server-list.html new file mode 100644 index 0000000..3b4130e --- /dev/null +++ b/admin/resources/partials/authz/resource-server-list.html @@ -0,0 +1,49 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1> + <span>Resource Servers</span> + <kc-tooltip>Resource Servers are applications serving resources to their users. These resources can be a RESTFul API, web pages or any other kind of resource that must be managed and protected by a set of authorization policies.</kc-tooltip> + </h1> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="5"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="Search..." data-ng-model="search.clientId" class="form-control search" onkeyup="if(event.keyCode == 13){$(this).next('I').click();}"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit"></i> + </div> + </div> + </div> + + <div class="pull-right"> + <a id="createServer" class="btn btn-default" href="#/realms/{{realm.realm}}/authz/resource-server/create">Create</a> + </div> + </div> + </th> + </tr> + <tr data-ng-hide="servers.length == 0"> + <th>Name</th> + <th>Policy Enforcement Mode</th> + <th>Allows Remote Resource Management ?</th> + <th>Allows Entitlement ?</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="server in servers | filter:search | orderBy:'clientId'"> + <td><a href="#/realms/{{realm.realm}}/authz/resource-server/{{server.id}}">{{server.name}}</a></td> + <td>{{server.policyEnforcementMode | toCamelCase}}</td> + <td>{{server.allowRemoteResourceManagement}}</td> + <td>{{server.allowEntitlements}}</td> + </tr> + <tr data-ng-show="(servers | filter:search).length == 0"> + <td class="text-muted" colspan="3" data-ng-show="search.clientId">No results</td> + <td class="text-muted" colspan="3" data-ng-hide="search.clientId">No servers available</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/resource-server-resource-detail.html b/admin/resources/partials/authz/resource-server-resource-detail.html new file mode 100644 index 0000000..b3d6eca --- /dev/null +++ b/admin/resources/partials/authz/resource-server-resource-detail.html @@ -0,0 +1,126 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/resource">{{:: 'authz-resources' | translate}}</a></li> + <li data-ng-show="create">{{:: 'authz-add-resource' | translate}}</li> + <li data-ng-hide="create">{{originalResource.name}}</li> + </ol> + + <h1 data-ng-show="create">{{:: 'authz-add-resource' | translate}}</h1> + <h1 data-ng-hide="create">{{originalResource.name|capitalize}}<i class="pficon pficon-delete clickable" data-ng-show="!create" + data-ng-click="remove()"></i></h1> + + <form class="form-horizontal" name="clientForm" novalidate> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="name">{{:: 'name' | translate}} <span class="required" data-ng-show="create">*</span></label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="name" name="name" data-ng-model="resource.name" autofocus required data-ng-blur="checkNewNameAvailability()"> + </div> + <kc-tooltip>{{:: 'authz-resource-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="name">{{:: 'displayName' | translate}} <span class="required" data-ng-show="create">*</span></label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="displayName" name="displayName" data-ng-model="resource.displayName"> + </div> + <kc-tooltip>{{:: 'authz-resource-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-hide="create"> + <label class="col-md-2 control-label" for="resource.owner.name">{{:: 'authz-owner' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="resource.owner.name" name="name" data-ng-model="resource.owner.name" autofocus disabled> + </div> + <kc-tooltip>{{:: 'authz-resource-owner.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="type">{{:: 'type' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="type" name="name" data-ng-model="resource.type" autofocus> + </div> + <kc-tooltip>{{:: 'authz-resource-type.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="newUri">{{:: 'authz-uri' | translate}} </label> + <div class="col-sm-6"> + <div class="input-group" ng-repeat="(i, uri) in resource.uris track by $index"> + <input class="form-control" ng-model="resource.uris[i]"> + <div class="input-group-btn"> + <button class="btn btn-default" type="button" data-ng-click="deleteUri($index)"><span class="fa fa-minus"></span></button> + </div> + </div> + + <div class="input-group"> + <input class="form-control" ng-model="newUri" id="newUri"> + <div class="input-group-btn"> + <button class="btn btn-default" type="button" data-ng-click="newUri.length > 0 && addUri()"><span class="fa fa-plus"></span></button> + </div> + </div> + </div> + <kc-tooltip>{{:: 'authz-resource-uri.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="scopes">{{:: 'authz-scopes' | translate}}</label> + + <div class="col-md-6"> + <input type="hidden" ui-select2="scopesUiSelect" id="scopes" data-ng-model="resource.scopes" data-placeholder="{{:: 'authz-select-scope' | translate}}..." multiple/> + </div> + + <kc-tooltip>{{:: 'authz-resource-scopes.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="iconUri">{{:: 'authz-icon-uri' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="iconUri" name="name" data-ng-model="resource.icon_uri" autofocus> + </div> + <kc-tooltip>{{:: 'authz-icon-uri.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="resource.ownerManagedAccess">{{:: 'authz-resource-user-managed-access-enabled' | translate}}</label> + <div class="col-md-6"> + <input ng-model="resource.ownerManagedAccess" id="resource.ownerManagedAccess" onoffswitch /> + </div> + <kc-tooltip>{{:: 'authz-resource-user-managed-access-enabled.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label">{{:: 'authz-resource-attributes' | translate}}</label> + <div class="col-md-6"> + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th>{{:: 'key' | translate}}</th> + <th>{{:: 'value' | translate}}</th> + <th>{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="(key, value) in resource.attributes | toOrderedMapSortedByKey"> + <td>{{key}}</td> + <td><input ng-model="resource.attributes[key]" class="form-control" type="text" name="{{key}}" id="attribute-{{key}}" /></td> + <td class="kc-action-cell" id="removeAttribute" data-ng-click="removeAttribute(key)">{{:: 'delete' | translate}}</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" id="addAttribute" data-ng-click="addAttribute()" data-ng-disabled="!newAttribute.key.length || !newAttribute.value.length">{{:: 'add' | translate}}</td> + </tr> + </tbody> + </table> + </div> + <kc-tooltip>{{:: 'authz-resource-attributes.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <div class="form-group" data-ng-show="access.manageAuthorization"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/resource-server-resource-list.html b/admin/resources/partials/authz/resource-server-resource-list.html new file mode 100644 index 0000000..dce000e --- /dev/null +++ b/admin/resources/partials/authz/resource-server-resource-list.html @@ -0,0 +1,169 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | + translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/resource">{{:: + 'authz-resources' | translate}}</a></li> + </ol> + + <kc-tabs-resource-server></kc-tabs-resource-server> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="6"> + <div class="form-inline"> + {{:: 'filter' | translate}}: + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'name' | translate}}" data-ng-model="query.name" + class="form-control search" + onkeydown="if (event.keyCode == 13) document.getElementById('resourceSearch').click()"> + <div class="input-group-addon"> + <i class="fa fa-search" id="resourceSearch" type="submit" + data-ng-click="firstPage()"></i> + </div> + </div> + <div class="input-group"> + <input type="text" placeholder="{{:: 'type' | translate}}" data-ng-model="query.type" + class="form-control search" + onkeydown="if (event.keyCode == 13) document.getElementById('resourceSearch').click()"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit" data-ng-click="firstPage()"></i> + </div> + </div> + <div class="input-group"> + <input type="text" placeholder="{{:: 'authz-uri' | translate}}" data-ng-model="query.uri" + class="form-control search" + onkeydown="if (event.keyCode == 13) document.getElementById('resourceSearch').click()"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit" data-ng-click="firstPage()"></i> + </div> + </div> + <div class="input-group"> + <input type="text" placeholder="{{:: 'authz-owner' | translate}}" + data-ng-model="query.owner" class="form-control search" + onkeydown="if (event.keyCode == 13) document.getElementById('resourceSearch').click()"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit" data-ng-click="firstPage()"></i> + </div> + </div> + <div class="input-group"> + <input type="text" placeholder="{{:: 'authz-scope' | translate}}" + data-ng-model="query.scope" class="form-control search" + onkeydown="if (event.keyCode == 13) document.getElementById('resourceSearch').click()"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit" data-ng-click="firstPage()"></i> + </div> + </div> + </div> + <div class="pull-right"> + <a id="createResource" class="btn btn-default" + href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/resource/create">{{:: + 'create' | translate}}</a> + </div> + </div> + </th> + </tr> + <tr data-ng-hide="resources.length == 0"> + <th width="1%"></th> + <th>{{:: 'name' | translate}}</th> + <th>{{:: 'type' | translate}}</th> + <th>{{:: 'authz-uris' | translate}}</th> + <th>{{:: 'authz-owner' | translate}}</th> + <th width="11%" style="text-align: center">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tfoot data-ng-show="resources && (resources.length >= query.max || query.first > 0)"> + <tr> + <td colspan="6"> + <div class="table-nav"> + <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | + translate}} + </button> + <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: + 'previous-page' | translate}} + </button> + <button data-ng-click="nextPage()" class="next" ng-disabled="resources.length < query.max">{{:: + 'next-page' | translate}} + </button> + </div> + </td> + </tr> + </tfoot> + <tbody> + <tr ng-repeat-start="resource in resources | filter:search | orderBy:'name'" data-ng-click="showDetails(resource, $event);" style="cursor: pointer;"> + <td> + <span ng-if="!resource.details || !resource.details.loaded" class="fa fa-angle-right"></span> + <span ng-if="resource.details && resource.details.loaded" class="fa fa-angle-right fa-angle-down"></span> + </td> + <td> + <a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/resource/{{resource._id}}">{{resource.name}}</a> + </td> + <td> + <span data-ng-show="resource.type">{{resource.type}}</span> + <span data-ng-show="!resource.type">{{:: 'authz-no-type-defined' | translate}}</span> + </td> + <td> + <span data-ng-show="resource.uris.length == 0">{{:: 'authz-no-uri-defined' | translate}}</span> + <span data-ng-show="resource.uris.length == 1">{{resource.uris[0]}}</span> + <span data-ng-show="resource.uris.length > 1">{{resource.uris.length}} {{:: 'authz-uris' | translate}}</span> + </td> + <td>{{resource.owner.name}}</td> + <td align="center"> + <div class="dropdown dropdown-kebab-pf"> + <button class="btn btn-default" ng-click="createPolicy(resource);">{{:: 'authz-create-permission' | translate}} + </button> + <button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown" + aria-haspopup="true" aria-expanded="true"> + <span class="fa fa-ellipsis-v"></span></button> + <ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownKebabRight"> + <li><a href="" ng-click="delete(resource);">{{:: 'delete' | translate}}</a></li> + </ul> + </div> + </td> + </tr> + <tr ng-if="resource.details && resource.details.loaded" ng-repeat-end=""> + <td colspan="6" style="background-color: #ffffff"> + <div class="list-group-item-container container-fluid"> + <div class="close" data-ng-click="showDetails(resource, $event);" style="padding-top: 10px"> + <span class="pficon pficon-close"></span> + </div> + <div class="row"> + <div class="col-md-12"> + <dl class="dl-horizontal"> + <dt>{{:: 'authz-scopes' | translate}}</dt> + <dd> + <span data-ng-show="resource.scopes && !resource.scopes.length">{{:: 'authz-no-scopes-assigned' | translate}}</span> + <span ng-repeat="scope in resource.scopes" data-ng-show="resource.scopes.length > 0"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/scope/{{scope.id}}">{{scope.name}}</a>{{$last ? '' : ', '}} </span> + </dd> + <dt>{{:: 'authz-associated-permissions' | translate}}</dt> + <dd> + <span data-ng-show="resource.policies && !resource.policies.length">{{:: 'authz-no-permission-assigned' | translate}}</span> + <span ng-repeat="policy in resource.policies" data-ng-show="resource.policies.length > 0"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/permission/{{policy.type}}/{{policy.id}}">{{policy.name}}</a>{{$last ? '' : ', '}}</span> + </dd> + <dt>{{:: 'authz-uris' | translate}}</dt> + <dd> + <span data-ng-show="resource.uris && !resource.uris.length">{{:: 'authz-no-uri-defined' | translate}}</span> + <span ng-repeat="uri in resource.uris" data-ng-show="resource.uris.length > 0">{{uri}}{{$last ? '' : ', '}}</span> + </dd> + </dl> + </div> + </div> + </div> + </td> + </tr> + <tr data-ng-show="(resources | filter:search).length == 0"> + <td class="text-muted" colspan="6" data-ng-show="search.name">{{:: 'no-results' | translate}}</td> + <td class="text-muted" colspan="6" data-ng-hide="search.name">{{:: 'authz-no-resources-available' | + translate}} + </td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/authz/resource-server-scope-detail.html b/admin/resources/partials/authz/resource-server-scope-detail.html new file mode 100644 index 0000000..d296abd --- /dev/null +++ b/admin/resources/partials/authz/resource-server-scope-detail.html @@ -0,0 +1,50 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/scope">{{:: 'authz-scopes' | translate}}</a></li> + <li data-ng-show="create">{{:: 'authz-add-scope' | translate}}</li> + <li data-ng-hide="create">{{originalScope.name}}</li> + </ol> + + <h1 data-ng-show="create">{{:: 'authz-add-scope' | translate}}</h1> + <h1 data-ng-hide="create">{{originalScope.name|capitalize}}<i class="pficon pficon-delete clickable" data-ng-show="!create" + data-ng-hide="changed" data-ng-click="remove()"></i></h1> + + <form class="form-horizontal" name="clientForm" novalidate> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="name">{{:: 'name' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="name" name="name" data-ng-model="scope.name" autofocus data-ng-blur="checkNewNameAvailability()"> + </div> + <kc-tooltip>{{:: 'authz-scope-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="displayName">{{:: 'displayName' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="displayName" name="displayName" data-ng-model="scope.displayName"> + </div> + <kc-tooltip>{{:: 'authz-scope-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="name">{{:: 'authz-icon-uri' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="iconUri" name="name" data-ng-model="scope.iconUri" autofocus> + </div> + <kc-tooltip>{{:: 'authz-icon-uri.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <div class="form-group" data-ng-show="access.manageAuthorization"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/authz/resource-server-scope-list.html b/admin/resources/partials/authz/resource-server-scope-list.html new file mode 100644 index 0000000..22c7f38 --- /dev/null +++ b/admin/resources/partials/authz/resource-server-scope-list.html @@ -0,0 +1,102 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server">{{:: 'authz-authorization' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/scope">{{:: 'authz-scopes' | translate}}</a></li> + </ol> + + <kc-tabs-resource-server></kc-tabs-resource-server> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="3"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'name' | translate}}" data-ng-model="query.name" class="form-control search" onkeydown="if (event.keyCode == 13) document.getElementById('scopeSearch').click()"> + <div class="input-group-addon"> + <i class="fa fa-search" id="scopeSearch" type="submit" data-ng-click="firstPage()"></i> + </div> + </div> + </div> + <div class="pull-right"> + <a id="createScope" class="btn btn-default" href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/scope/create">{{:: 'create' | translate}}</a> + </div> + </div> + </th> + </tr> + <tr data-ng-hide="scopes.length == 0"> + <th width="1%"></th> + <th>{{:: 'name' | translate}}</th> + <th width="11%" style="text-align: center">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tfoot data-ng-show="scopes && (scopes.length >= query.max || query.first > 0)"> + <tr> + <td colspan="3"> + <div class="table-nav"> + <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button> + <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button> + <button data-ng-click="nextPage()" class="next" ng-disabled="scopes.length < query.max">{{:: 'next-page' | translate}}</button> + </div> + </td> + </tr> + </tfoot> + <tbody> + <tr ng-repeat-start="scope in scopes | filter:search | orderBy:'name'" data-ng-click="showDetails(scope, $event);" style="cursor: pointer"> + <td> + <span ng-if="!scope.details || !scope.details.loaded" class="fa fa-angle-right"></span> + <span ng-if="scope.details && scope.details.loaded" class="fa fa-angle-right fa-angle-down"></span> + </td> + <td><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/scope/{{scope.id}}">{{scope.name}}</a></td> + <td align="center"> + <div class="dropdown dropdown-kebab-pf"> + <button class="btn btn-default" ng-click="createPolicy(scope);">{{:: 'authz-create-permission' | + translate}} + </button> + <button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown" + aria-haspopup="true" aria-expanded="true"> + <span class="fa fa-ellipsis-v"></span></button> + <ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownKebabRight"> + <li><a href="" ng-click="delete(scope);">{{:: 'delete' | translate}}</a></li> + </ul> + </div> + </td> + </tr> + <tr ng-if="scope.details && scope.details.loaded" ng-repeat-end=""> + <td colspan="3" style="background-color: #ffffff"> + <div class="list-group-item-container container-fluid"> + <div class="close" data-ng-click="showDetails(scope, $event);" style="padding-top: 10px"> + <span class="pficon pficon-close"></span> + </div> + <div class="row"> + <div class="col-md-12"> + <dl class="dl-horizontal"> + <dt>{{:: 'authz-resources' | translate}}</dt> + <dd> + <span data-ng-show="scope.resources && !scope.resources.length">{{:: 'authz-no-resources-assigned' | translate}}</span> + <span ng-repeat="resource in scope.resources" data-ng-show="scope.resources.length > 0"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/resource/{{resource._id}}">{{resource.name}}</a>{{$last ? '' : ', '}}</span> + </dd> + <dt>{{:: 'authz-associated-permissions' | translate}}</dt> + <dd> + <span data-ng-show="scope.policies && !scope.policies.length">{{:: 'authz-no-permission-assigned' | translate}}</span> + <span ng-repeat="policy in scope.policies" data-ng-show="scope.policies.length > 0"><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/authz/resource-server/permission/{{policy.type}}/{{policy.id}}">{{policy.name}}</a>{{$last ? '' : ', '}}</span> + </dd> + </dl> + </div> + </div> + </div> + </td> + </tr> + <tr data-ng-show="(scopes | filter:search).length == 0"> + <td class="text-muted" colspan="3" data-ng-show="search.name">{{:: 'no-results' | translate}}</td> + <td class="text-muted" colspan="3" data-ng-hide="search.name">{{:: 'authz-no-scopes-available' | translate}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/brute-force.html b/admin/resources/partials/brute-force.html new file mode 100644 index 0000000..6ab0092 --- /dev/null +++ b/admin/resources/partials/brute-force.html @@ -0,0 +1,114 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <kc-tabs-realm></kc-tabs-realm> + + <ul class="nav nav-tabs nav-tabs-pf"> + <li><a href="#/realms/{{realm.realm}}/defense/headers">{{:: 'headers' | translate}}</a></li> + <li class="active"><a href="#/realms/{{realm.realm}}/defense/brute-force">{{:: 'brute-force-detection' | translate}}</a></li> + </ul> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="bruteForceProtected">{{:: 'enabled' | translate}}</label> + <div class="col-md-6"> + <input ng-model="realm.bruteForceProtected" name="bruteForceProtected" id="bruteForceProtected" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <div class="form-group" data-ng-show="realm.bruteForceProtected"> + <label class="col-md-2 control-label" for="permanentLockout">{{:: 'permanent-lockout' | translate}}</label> + <div class="col-md-6"> + <input ng-model="realm.permanentLockout" name="permanentLockout" id="permanentLockout" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'permanent-lockout.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group" data-ng-show="realm.bruteForceProtected"> + <label class="col-md-2 control-label" for="failureFactor">{{:: 'max-login-failures' | translate}}</label> + + <div class="col-md-6"> + <input class="form-control" type="number" min="1" max="31536000" id="failureFactor" name="failureFactor" data-ng-model="realm.failureFactor" autofocus + required> + </div> + <kc-tooltip>{{:: 'max-login-failures.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="realm.bruteForceProtected && !realm.permanentLockout"> + <label class="col-md-2 control-label" for="waitIncrement">{{:: 'wait-increment' | translate}}</label> + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="1" + max="31536000" data-ng-model="realm.waitIncrement" + id="waitIncrement" name="waitIncrement"/> + <select class="form-control" name="waitIncrementUnit" data-ng-model="realm.waitIncrementUnit" > + <option data-ng-selected="!realm.waitIncrementUnit" value="Seconds">{{:: 'seconds' | translate}}</option> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'wait-increment.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="realm.bruteForceProtected"> + <label class="col-md-2 control-label" for="quickLoginCheckMilliSeconds">{{:: 'quick-login-check-millis' | translate}}</label> + + <div class="col-md-6"> + <input class="form-control" type="number" min="1" max="31536000" id="quickLoginCheckMilliSeconds" name="quickLoginCheckMilliSeconds" data-ng-model="realm.quickLoginCheckMilliSeconds" autofocus + required> + </div> + <kc-tooltip>{{:: 'quick-login-check-millis.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="realm.bruteForceProtected"> + <label class="col-md-2 control-label" for="minimumQuickLoginWait">{{:: 'min-quick-login-wait' | translate}}</label> + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="1" + max="31536000" data-ng-model="realm.minimumQuickLoginWait" + id="minimumQuickLoginWait" name="minimumQuickLoginWait"/> + <select class="form-control" name="minimumQuickLoginWaitUnit" data-ng-model="realm.minimumQuickLoginWaitUnit" > + <option data-ng-selected="!realm.minimumQuickLoginWaitUnit" value="Seconds">{{:: 'seconds' | translate}}</option> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'min-quick-login-wait.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="realm.bruteForceProtected && !realm.permanentLockout"> + <label class="col-md-2 control-label" for="maxFailureWait">{{:: 'max-wait' | translate}}</label> + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="1" + max="31536000" data-ng-model="realm.maxFailureWait" + id="maxFailureWait" name="maxFailureWait"/> + <select class="form-control" name="maxFailureWaitUnit" data-ng-model="realm.maxFailureWaitUnit" > + <option data-ng-selected="!realm.maxFailureWaitUnit" value="Seconds">{{:: 'seconds' | translate}}</option> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'max-wait.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="realm.bruteForceProtected && !realm.permanentLockout"> + <label class="col-md-2 control-label" for="maxDeltaTime">{{:: 'failure-reset-time' | translate}}</label> + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="1" + max="31536000" data-ng-model="realm.maxDeltaTime" + id="maxDeltaTime" name="maxDeltaTime"/> + <select class="form-control" name="maxDeltaTimeUnit" data-ng-model="realm.maxDeltaTimeUnit" > + <option data-ng-selected="!realm.maxDeltaTimeUnit" value="Seconds">{{:: 'seconds' | translate}}</option> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'failure-reset-time.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <div class="form-group" data-ng-show="access.manageRealm"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/claims.html b/admin/resources/partials/claims.html new file mode 100644 index 0000000..27357ca --- /dev/null +++ b/admin/resources/partials/claims.html @@ -0,0 +1,62 @@ + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="username">{{:: 'username' | translate}}</label> + <div class="col-md-6"> + <input ng-model="claims.username" name="username" id="username" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="claimName">{{:: 'name' | translate}}</label> + <div class="col-md-6"> + <input ng-model="claims.name" name="claimName" id="claimName" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="email">{{:: 'email' | translate}}</label> + <div class="col-md-6"> + <input ng-model="claims.email" name="email" id="email" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="gender">{{:: 'gender' | translate}}</label> + <div class="col-md-6"> + <input ng-model="claims.gender" name="gender" id="gender" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="address">{{:: 'address' | translate}}</label> + <div class="col-md-6"> + <input ng-model="claims.address" name="address" id="address" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="locale">{{:: 'locale' | translate}}</label> + <div class="col-md-6"> + <input ng-model="claims.locale" name="locale" id="locale" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="phone">{{:: 'phone' | translate}}</label> + <div class="col-md-6"> + <input ng-model="claims.phone" name="phone" id="phone" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="profile">{{:: 'profile-url' | translate}}</label> + <div class="col-md-6"> + <input ng-model="claims.profile" name="profile" id="profile" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="picture">{{:: 'picture-url' | translate}}</label> + <div class="col-md-6"> + <input ng-model="claims.picture" name="picture" id="picture" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="website">{{:: 'website' | translate}}</label> + <div class="col-md-6"> + <input ng-model="claims.website" name="website" id="website" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + </fieldset>
\ No newline at end of file diff --git a/admin/resources/partials/client-clustering-node.html b/admin/resources/partials/client-clustering-node.html new file mode 100644 index 0000000..56eb9db --- /dev/null +++ b/admin/resources/partials/client-clustering-node.html @@ -0,0 +1,37 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/clustering">{{:: 'cluster-nodes' | translate}}</a></li> + <li data-ng-show="create">{{:: 'add-node' | translate}}</li> + <li data-ng-hide="create">{{node.host|capitalize}}</li> + </ol> + + <h1 data-ng-show="create">{{:: 'add-node' | translate}}</h1> + <h1 data-ng-hide="create"> + {{node.host|capitalize}} + <i id="removeClient" class="pficon pficon-delete clickable" data-ng-show="client.access.configure" data-ng-click="unregisterNode()"></i> + </h1> + + <form class="form-horizontal" name="clusteringForm" novalidate kc-read-only="!client.access.configure" data-ng-show="create || registered"> + <div class="form-group"> + <label class="col-md-2 control-label" for="host">{{:: 'host' | translate}}</label> + <div class="col-sm-6"> + <input kc-no-reserved-chars ng-disabled="!create" class="form-control" type="text" id="host" name="host" data-ng-model="node.host" required> + </div> + </div> + <div ng-hide="create" class="form-group"> + <label class="col-md-2 control-label" for="lastRegistration">{{:: 'last-registration' | translate}}</label> + <div class="col-sm-6"> + {{node.lastRegistration}} + </div> + </div> + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="client.access.configure"> + <button data-kc-save data-ng-show="create">{{:: 'save' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-clustering.html b/admin/resources/partials/client-clustering.html new file mode 100644 index 0000000..72ff437 --- /dev/null +++ b/admin/resources/partials/client-clustering.html @@ -0,0 +1,76 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li>{{client.clientId}}</li> + </ol> + + <kc-tabs-client></kc-tabs-client> + + <form class="form-horizontal" name="clusteringForm" novalidate kc-read-only="!client.access.configure"> + <legend><span class="text">{{:: 'basic-configuration' | translate}}</span></legend> + <fieldset > + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="nodeReRegistrationTimeout">{{:: 'node-reregistration-timeout' | translate}}</label> + <div class="col-sm-5"> + <div class="row"> + <div class="col-md-6 form-inline"> + <input class="form-control" type="number" required + max="31536000" data-ng-model="client.nodeReRegistrationTimeout" + id="nodeReRegistrationTimeout" name="nodeReRegistrationTimeout"/> + <select class="form-control" name="nodeReRegistrationTimeoutUnit" data-ng-model="client.nodeReRegistrationTimeoutUnit" > + <option data-ng-selected="!client.nodeReRegistrationTimeoutUnit" value="Seconds">{{:: 'seconds' | translate}}</option> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + </div> + </div> + <kc-tooltip>{{:: 'node-reregistration-timeout.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="client.access.configure"> + <button data-kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button data-kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </fieldset> + + <fieldset> + <legend><span class="text">{{:: 'registered-cluster-nodes' | translate}}</span></legend> + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="5" data-ng-show="client.access.configure"> + <div class="pull-right"> + <a class="btn btn-default" tooltip="Manually register cluster node. This is usually not needed as cluster node should be registered automatically by adapter" + tooltip-trigger="mouseover mouseout" tooltip-placement="bottom" href="#/register-node/realms/{{realm.realm}}/clients/{{client.id}}/clustering">{{:: 'register-node-manually' | translate}}</a> + <a class="btn btn-default" data-ng-click="testNodesAvailable()" data-ng-show="nodeRegistrations && nodeRegistrations.length > 0">{{:: 'test-cluster-availability' | translate}}</a> + </div> + </th> + </tr> + <tr data-ng-hide="!nodeRegistrations || nodeRegistrations.length == 0"> + <th>{{:: 'node-host' | translate}}</th> + <th>{{:: 'last-registration' | translate}}</th> + <th colspan="2">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="node in nodeRegistrations"> + <td><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/clustering/{{node.host}}">{{node.host}}</a></td> + <td>{{node.lastRegistration}}</td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/clients/{{client.id}}/clustering/{{node.host}}">{{:: 'edit' | translate}}</td> + <td class="kc-action-cell" data-ng-click="removeNode(node)">{{:: 'delete' | translate}}</td> + </tr> + <tr data-ng-show="!nodeRegistrations || nodeRegistrations.length == 0"> + <td class="text-muted">{{:: 'no-registered-cluster-nodes' | translate}}</td> + </tr> + </tbody> + </table> + </fieldset> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-credentials-generic.html b/admin/resources/partials/client-credentials-generic.html new file mode 100644 index 0000000..39e9ebc --- /dev/null +++ b/admin/resources/partials/client-credentials-generic.html @@ -0,0 +1,14 @@ +<div> + <form class="form-horizontal no-margin-top" name="credentialForm" novalidate kc-read-only="!client.access.configure" data-ng-show="currentAuthenticatorConfigProperties.length > 0" data-ng-controller="ClientGenericCredentialsCtrl"> + <fieldset> + <kc-provider-config realm="realm" config="client.attributes" properties="currentAuthenticatorConfigProperties"></kc-provider-config> + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="client.access.configure"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div>
\ No newline at end of file diff --git a/admin/resources/partials/client-credentials-jwt-key-export.html b/admin/resources/partials/client-credentials-jwt-key-export.html new file mode 100644 index 0000000..a1da8c1 --- /dev/null +++ b/admin/resources/partials/client-credentials-jwt-key-export.html @@ -0,0 +1,57 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/credentials">{{:: 'credentials' | translate}}</a></li> + <li class="active">{{:: 'gen-client-private-key' | translate}}</li> + </ol> + + <h1>{{:: 'generate-private-key' | translate}}</h1> + + <form class="form-horizontal" name="keyForm" novalidate kc-read-only="!client.access.configure"> + <fieldset class="form-group col-sm-10"> + <div class="form-group"> + <label class="col-md-2 control-label" for="downloadKeyFormat">{{:: 'archive-format' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="downloadKeyFormat" + ng-model="jks.format" + ng-options="f for f in keyFormats"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'archive-format.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="keyAlias">{{:: 'key-alias' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" id="keyAlias" name="keyAlias" data-ng-model="jks.keyAlias" autofocus required> + </div> + <kc-tooltip>{{:: 'key-alias.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="keyPas">{{:: 'key-password' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" kc-password id="keyPas" name="keyPas" data-ng-model="jks.keyPassword" autofocus required> + </div> + <kc-tooltip>{{:: 'key-password.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="storePas">{{:: 'store-password' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" kc-password id="storePas" name="storePassword" data-ng-model="jks.storePassword" autofocus required> + </div> + <kc-tooltip>{{:: 'store-password.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="client.access.configure"> + <button class="btn btn-primary" type="submit" data-ng-click="download()">{{:: 'generate-and-download' | translate}}</button> + <button class="btn btn-default" type="submit" data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + </fieldset> + </form> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/client-credentials-jwt-key-import.html b/admin/resources/partials/client-credentials-jwt-key-import.html new file mode 100644 index 0000000..6ea0118 --- /dev/null +++ b/admin/resources/partials/client-credentials-jwt-key-import.html @@ -0,0 +1,62 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/credentials">{{:: 'credentials' | translate}}</a></li> + <li class="active">{{:: 'client-certificate-import' | translate}}</li> + </ol> + + <h1>{{:: 'import-client-certificate' | translate}}</h1> + + <form class="form-horizontal" name="keyForm" novalidate kc-read-only="!client.access.configure"> + <fieldset> + <div class="form-group"> + <label class="col-md-2 control-label" for="uploadKeyFormat">{{:: 'archive-format' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="uploadKeyFormat" + ng-model="uploadKeyFormat" + ng-options="f for f in keyFormats"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'archive-format.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-hide="hideKeystoreSettings()"> + <label class="col-md-2 control-label" for="uploadKeyAlias">{{:: 'key-alias' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" id="uploadKeyAlias" name="uploadKeyAlias" data-ng-model="uploadKeyAlias" autofocus required> + </div> + <kc-tooltip>{{:: 'jwt-import.key-alias.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-hide="hideKeystoreSettings()"> + <label class="col-md-2 control-label" for="uploadStorePas">{{:: 'store-password' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" kc-password id="uploadStorePas" name="uploadStorePas" data-ng-model="uploadStorePassword" autofocus required> + </div> + <kc-tooltip>{{:: 'store-password.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label">{{:: 'import-file' | translate}} </label> + <div class="col-md-6"> + <div class="controls kc-button-input-file" data-ng-show="!files || files.length == 0"> + <label for="import-file" class="btn btn-default">{{:: 'select-file' | translate}} <i class="pficon pficon-import"></i></label> + <input id="import-file" type="file" class="hidden" ng-file-select="onFileSelect($files)"> + </div> + <span class="kc-uploaded-file" data-ng-show="files.length > 0"> + {{files[0].name}} + </span> + </div> + </div> + <div class="form-group"> + <div class="col-md-10 col-md-offset-2"> + <button type="submit" data-ng-click="uploadFile()" data-ng-disabled="files.length == 0" class="btn btn-primary">{{:: 'import' | translate}}</button> + <button type="submit" data-ng-click="cancel()" class="btn btn-default">{{:: 'cancel' | translate}}</button> + </div> + </div> + </fieldset> + </form> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/client-credentials-jwt.html b/admin/resources/partials/client-credentials-jwt.html new file mode 100644 index 0000000..b2a5bf4 --- /dev/null +++ b/admin/resources/partials/client-credentials-jwt.html @@ -0,0 +1,74 @@ + <div class="form-horizontal no-margin-top" name="keyForm" novalidate kc-read-only="!client.access.configure" data-ng-controller="ClientSignedJWTCtrl"> + + <div class="form-group"> + <label class="col-md-2 control-label" for="useJwksUrl">{{:: 'use-jwks-url' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="useJwksUrl" name="useJwksUrl" id="useJwksUrl" ng-click="switchChange()" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'use-jwks-url.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group" data-ng-show="useJwksUrl"> + <label class="col-md-2 control-label" for="jwksUrl">{{:: 'jwks-url' | translate}}</label> + <div class="col-sm-6"> + <input class="form-control" type="text" name="jwksUrl" id="jwksUrl" data-ng-model="client.attributes['jwks.url']"> + </div> + <kc-tooltip>{{:: 'jwks-url.tooltip' | translate}}</kc-tooltip> + </div> + + <div data-ng-show="!useJwksUrl"> + + <div class="form-group" data-ng-show="signingKeyInfo.certificate"> + <label class="col-md-2 control-label" for="signingCert">{{:: 'certificate' | translate}}</label> + <kc-tooltip>{{:: 'certificate.tooltip' | translate}}</kc-tooltip> + + <div class="col-sm-10" data-ng-show="signingKeyInfo.certificate"> + <textarea type="text" id="signingCert" name="signingCert" class="form-control" rows="5" kc-select-action="click" readonly>{{signingKeyInfo.certificate}}</textarea> + </div> + </div> + + <div class="form-group" data-ng-show="signingKeyInfo.publicKey"> + <label class="col-md-2 control-label" for="publicKey">{{:: 'publicKey' | translate}}</label> + <kc-tooltip>{{:: 'publicKey.tooltip' | translate}}</kc-tooltip> + + <div class="col-sm-10" data-ng-show="signingKeyInfo.publicKey"> + <textarea type="text" id="publicKey" name="publicKey" class="form-control" rows="5" kc-select-action="click" readonly>{{signingKeyInfo.publicKey}}</textarea> + </div> + </div> + + <div class="form-group" data-ng-show="signingKeyInfo.kid"> + <label class="col-md-2 control-label" for="kid">{{:: 'kid' | translate}}</label> + <kc-tooltip>{{:: 'kid.tooltip' | translate}}</kc-tooltip> + + <div class="col-sm-6"> + <div class="row"> + <div class="col-sm-6"> + <input readonly kc-select-action="click" class="form-control" type="text" id="kid" name="kid" data-ng-model="signingKeyInfo.kid"> + </div> + </div> + </div> + </div> + + <div class="form-group" data-ng-hide="signingKeyInfo.certificate || signingKeyInfo.publicKey"> + <label class="col-md-2 control-label"></label> + <div class="col-sm-6"> + <div class="row"> + <div class="col-sm-6"> + {{:: 'no-client-certificate-configured' | translate}} + </div> + </div> + </div> + </div> + + </div> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="client.access.configure"> + <button class="btn btn-default" type="submit" data-ng-click="generateSigningKey()">{{:: 'gen-new-keys-and-cert' | translate}}</button> + <button data-ng-disabled="useJwksUrl" class="btn btn-default" type="submit" data-ng-click="importCertificate()">{{:: 'import-certificate' | translate}}</button> + <button kc-save data-ng-disabled="!changed" data-ng-click="save()">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed" data-ng-click="reset()">{{:: 'cancel' | translate}}</button> + </div> + </div> + +</div>
\ No newline at end of file diff --git a/admin/resources/partials/client-credentials-secret-jwt.html b/admin/resources/partials/client-credentials-secret-jwt.html new file mode 100644 index 0000000..7cf5bf1 --- /dev/null +++ b/admin/resources/partials/client-credentials-secret-jwt.html @@ -0,0 +1,17 @@ +<div> + <form class="form-horizontal no-margin-top" name="credentialForm" novalidate kc-read-only="!client.access.configure" data-ng-controller="ClientSecretCtrl"> + <div class="form-group"> + <label class="col-md-2 control-label" for="secret">{{:: 'secret' | translate}}</label> + <div class="col-sm-6"> + <div class="row"> + <div class="col-sm-6"> + <input readonly kc-select-action="click" class="form-control" type="text" id="secret" name="secret" data-ng-model="secret"> + </div> + <div class="col-sm-6" data-ng-show="client.access.configure"> + <button type="submit" data-ng-click="changePassword()" class="btn btn-default">{{:: 'regenerate-secret' | translate}}</button> + </div> + </div> + </div> + </div> + </form> +</div> diff --git a/admin/resources/partials/client-credentials-secret.html b/admin/resources/partials/client-credentials-secret.html new file mode 100644 index 0000000..7cf5bf1 --- /dev/null +++ b/admin/resources/partials/client-credentials-secret.html @@ -0,0 +1,17 @@ +<div> + <form class="form-horizontal no-margin-top" name="credentialForm" novalidate kc-read-only="!client.access.configure" data-ng-controller="ClientSecretCtrl"> + <div class="form-group"> + <label class="col-md-2 control-label" for="secret">{{:: 'secret' | translate}}</label> + <div class="col-sm-6"> + <div class="row"> + <div class="col-sm-6"> + <input readonly kc-select-action="click" class="form-control" type="text" id="secret" name="secret" data-ng-model="secret"> + </div> + <div class="col-sm-6" data-ng-show="client.access.configure"> + <button type="submit" data-ng-click="changePassword()" class="btn btn-default">{{:: 'regenerate-secret' | translate}}</button> + </div> + </div> + </div> + </div> + </form> +</div> diff --git a/admin/resources/partials/client-credentials-x509.html b/admin/resources/partials/client-credentials-x509.html new file mode 100644 index 0000000..c3ee5f1 --- /dev/null +++ b/admin/resources/partials/client-credentials-x509.html @@ -0,0 +1,21 @@ +<div> + <form class="form-horizontal no-margin-top" name="credentialForm" novalidate kc-read-only="!client.access.configure" data-ng-controller="ClientX509Ctrl"> + <div class="form-group"> + <label class="col-md-2 control-label" for="subjectdn"><span class="required">*</span>{{:: 'subjectdn' | translate}}</label> + <kc-tooltip>{{:: 'subjectdn-tooltip' | translate}}</kc-tooltip> + <div class="col-sm-6"> + <div class="row"> + <div class="col-sm-6"> + <input class="form-control" type="text" id="subjectdn" data-ng-model="client.attributes['x509.subjectdn']"> + </div> + </div> + </div> + </div> + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="client.access.configure"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> diff --git a/admin/resources/partials/client-credentials.html b/admin/resources/partials/client-credentials.html new file mode 100644 index 0000000..e6865a3 --- /dev/null +++ b/admin/resources/partials/client-credentials.html @@ -0,0 +1,38 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li>{{client.clientId}}</li> + </ol> + + <kc-tabs-client></kc-tabs-client> + + <form class="form-horizontal" name="clientForm" novalidate kc-read-only="!client.access.configure"> + <fieldset class="border-top"> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="clientAuthenticatorType"> {{:: 'client-authenticator' | translate}}</label> + <div class="col-md-2"> + <div> + <select class="form-control" id="clientAuthenticatorType" + ng-model="client.clientAuthenticatorType" + ng-options="authenticator.id as authenticator.displayName for authenticator in clientAuthenticatorProviders" + required> + </select> + </div> + </div> + <kc-tooltip>{{:: 'client-authenticator.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + </form> + + <div data-ng-include="resourceUrl + '/partials/' + clientAuthenticatorConfigPartial"> + </div> + + <hr/> + + <div data-ng-include="resourceUrl + '/partials/client-registration-access-token.html'"> + </div> + +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/client-detail.html b/admin/resources/partials/client-detail.html new file mode 100644 index 0000000..4c726b8 --- /dev/null +++ b/admin/resources/partials/client-detail.html @@ -0,0 +1,640 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li>{{client.clientId}}</li> + </ol> + + <kc-tabs-client></kc-tabs-client> + + <form class="form-horizontal" name="clientForm" novalidate kc-read-only="!client.access.configure"> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="clientId">{{:: 'client-id' | translate}}</label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="clientId" name="clientId" data-ng-model="clientEdit.clientId" autofocus required> + </div> + <kc-tooltip>{{:: 'client-id.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="name">{{:: 'name' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="name" name="name" data-ng-model="clientEdit.name" autofocus> + </div> + <kc-tooltip>{{:: 'client.name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="description">{{:: 'description' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="description" name="description" data-ng-model="clientEdit.description"> + </div> + <kc-tooltip>{{:: 'client.description.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block"> + <label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="clientEdit.enabled" name="enabled" id="enabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'client.enabled.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="serverInfo.featureEnabled('ACCOUNT2') && !(accessType === 'bearer-only' && protocol === 'openid-connect')"> + <label class="col-md-2 control-label" for="alwaysDisplayInConsole">{{:: 'alwaysDisplayInConsole' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="clientEdit.alwaysDisplayInConsole" name="alwaysDisplayInConsole" id="alwaysDisplayInConsole" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'alwaysDisplayInConsole.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="client.origin"> + <label class="col-md-2 control-label">{{:: 'client-origin-link' | translate}}</label> + <div class="col-md-6"> + {{originName}} + </div> + <kc-tooltip>{{:: 'client-origin.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group clearfix block" data-ng-show="protocol != 'docker-v2'"> + <label class="col-md-2 control-label" for="consentRequired">{{:: 'consent-required' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="clientEdit.consentRequired" name="consentRequired" id="consentRequired" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'consent-required.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="clientEdit.consentRequired && protocol != 'docker-v2'"> + <label class="col-md-2 control-label" for="displayOnConsentScreen">{{:: 'client.display-on-consent-screen' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="displayOnConsentScreen" ng-click="switchChange()" name="displayOnConsentScreen" id="displayOnConsentScreen" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'client.display-on-consent-screen.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="clientEdit.consentRequired && protocol != 'docker-v2' && displayOnConsentScreen"> + <label class="col-md-2 control-label" for="consentScreenText">{{:: 'client.consent-screen-text' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="consentScreenText" name="consentScreenText" data-ng-model="clientEdit.attributes['consent.screen.text']"> + </div> + <kc-tooltip>{{:: 'client.consent-screen-text.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="loginTheme">{{:: 'login-theme' | translate}}</label> + <div class="col-sm-6"> + <select class="form-control" id="loginTheme" + ng-model="clientEdit.attributes['login_theme']" + ng-options="o.name as o.name for o in serverInfo.themes.login"> + <option value="" selected></option> + </select> + </div> + <kc-tooltip>{{:: 'login-theme.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="protocol">{{:: 'client-protocol' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="protocol" + ng-change="changeProtocol()" + ng-model="protocol" + ng-options="aProtocol for aProtocol in protocols"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'client-protocol.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="protocol == 'openid-connect'"> + <label class="col-md-2 control-label" for="accessType">{{:: 'access-type' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="accessType" + ng-change="changeAccessType()" + ng-model="accessType" + ng-options="aType for aType in accessTypes"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'access-type.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="protocol == 'openid-connect' && !clientEdit.bearerOnly"> + <label class="col-md-2 control-label" for="standardFlowEnabled">{{:: 'standard-flow-enabled' | translate}}</label> + <kc-tooltip>{{:: 'standard-flow-enabled.tooltip' | translate}}</kc-tooltip> + <div class="col-md-6"> + <input ng-model="clientEdit.standardFlowEnabled" name="standardFlowEnabled" id="standardFlowEnabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <div class="form-group" data-ng-show="protocol == 'openid-connect' && !clientEdit.bearerOnly"> + <label class="col-md-2 control-label" for="implicitFlowEnabled">{{:: 'implicit-flow-enabled' | translate}}</label> + <kc-tooltip>{{:: 'implicit-flow-enabled.tooltip' | translate}}</kc-tooltip> + <div class="col-md-6"> + <input ng-model="clientEdit.implicitFlowEnabled" name="implicitFlowEnabled" id="implicitFlowEnabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <div class="form-group" data-ng-show="protocol == 'openid-connect' && !clientEdit.bearerOnly"> + <label class="col-md-2 control-label" for="directAccessGrantsEnabled">{{:: 'direct-access-grants-enabled' | translate}}</label> + <kc-tooltip>{{:: 'direct-access-grants-enabled.tooltip' | translate}}</kc-tooltip> + <div class="col-md-6"> + <input ng-model="clientEdit.directAccessGrantsEnabled" name="directAccessGrantsEnabled" id="directAccessGrantsEnabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <div class="form-group" data-ng-show="protocol == 'openid-connect' && !clientEdit.publicClient && !clientEdit.bearerOnly"> + <label class="col-md-2 control-label" for="serviceAccountsEnabled">{{:: 'service-accounts-enabled' | translate}}</label> + <kc-tooltip>{{:: 'service-accounts-enabled.tooltip' | translate}}</kc-tooltip> + <div class="col-md-6"> + <input ng-model="clientEdit.serviceAccountsEnabled" name="serviceAccountsEnabled" id="serviceAccountsEnabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <div class="form-group" data-ng-show="protocol == 'openid-connect' && !clientEdit.publicClient && !clientEdit.bearerOnly"> + <label class="col-md-2 control-label" for="authorizationServicesEnabled">{{:: 'authz-authorization-services-enabled' | translate}}</label> + <kc-tooltip>{{:: 'authz-authorization-services-enabled.tooltip' | translate}}</kc-tooltip> + <div class="col-md-6"> + <input ng-model="clientEdit.authorizationServicesEnabled" name="authorizationServicesEnabled" id="authorizationServicesEnabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <div class="form-group clearfix block" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="samlAuthnStatement">{{:: 'include-authnstatement' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="samlAuthnStatement" ng-click="switchChange()" name="samlAuthnStatement" id="samlAuthnStatement" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'include-authnstatement.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="samlOneTimeUseCondition">{{:: 'include-onetimeuse-condition' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="samlOneTimeUseCondition" ng-click="switchChange()" name="samlOneTimeUseCondition" id="samlOneTimeUseCondition" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'include-onetimeuse-condition.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="samlServerSignature">{{:: 'sign-documents' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="samlServerSignature" ng-click="switchChange()" name="samlServerSignature" id="samlServerSignature" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'sign-documents.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="protocol == 'saml' && samlServerSignature == true"> + <label class="col-md-2 control-label" for="samlServerSignatureEnableKeyInfoExtension">{{:: 'sign-documents-redirect-enable-key-info-ext' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="samlServerSignatureEnableKeyInfoExtension" ng-click="switchChange()" name="samlServerSignatureEnableKeyInfoExtension" id="samlServerSignatureEnableKeyInfoExtension" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'sign-documents-redirect-enable-key-info-ext.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="samlAssertionSignature">{{:: 'sign-assertions' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="samlAssertionSignature" ng-click="switchChange()" name="samlAssertionSignature" id="samlAssertionSignature" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'sign-assertions.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="(samlAssertionSignature || samlServerSignature) && protocol == 'saml'"> + <label class="col-md-2 control-label" for="signatureAlgorithm">{{:: 'signature-algorithm' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="signatureAlgorithm" + ng-change="changeAlgorithm()" + ng-model="signatureAlgorithm" + ng-options="alg for alg in signatureAlgorithms"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'signature-algorithm.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="(samlAssertionSignature || samlServerSignature) && protocol == 'saml'"> + <label class="col-md-2 control-label" for="samlSigKeyNameTranformer">{{:: 'saml-signature-keyName-transformer' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="xmlKeyNameTranformer" + ng-change="changeSamlSigKeyNameTranformer()" + ng-model="samlXmlKeyNameTranformer" + ng-options="alg for alg in xmlKeyNameTranformers"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'saml-signature-keyName-transformer.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="(samlAssertionSignature || samlServerSignature) && protocol == 'saml'"> + <label class="col-md-2 control-label" for="canonicalization">{{:: 'canonicalization-method' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="canonicalization" + ng-model="clientEdit.attributes['saml_signature_canonicalization_method']" + ng-options="canon.value as canon.name for canon in canonicalization"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'canonicalization-method.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="samlEncrypt">{{:: 'encrypt-assertions' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="samlEncrypt" ng-click="switchChange()" name="samlEncrypt" id="samlEncrypt" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'encrypt-assertions.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="samlClientSignature">{{:: 'client-signature-required' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="samlClientSignature" ng-click="switchChange()" name="samlClientSignature" id="samlClientSignature" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'client-signature-required.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="samlForcePostBinding">{{:: 'force-post-binding' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="samlForcePostBinding" ng-click="switchChange()" name="samlForcePostBinding" id="samlForcePostBinding" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'force-post-binding.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="frontchannelLogout">{{:: 'front-channel-logout' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="clientEdit.frontchannelLogout" name="frontchannelLogout" id="frontchannelLogout" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'front-channel-logout.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="samlForceNameIdFormat">{{:: 'force-name-id-format' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="samlForceNameIdFormat" ng-click="switchChange()" name="samlForceNameIdFormat" id="samlForceNameIdFormat" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'force-name-id-format.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="samlNameIdFormat">{{:: 'name-id-format' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="samlNameIdFormat" + ng-change="changeNameIdFormat()" + ng-model="nameIdFormat" + ng-options="format for format in nameIdFormats"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'name-id-format.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group" data-ng-show="!clientEdit.bearerOnly && protocol != 'docker-v2'"> + <label class="col-md-2 control-label" for="rootUrl">{{:: 'root-url' | translate}}</label> + <div class="col-sm-6"> + <input class="form-control" type="text" name="rootUrl" id="rootUrl" data-ng-model="clientEdit.rootUrl"> + </div> + <kc-tooltip>{{:: 'root-url.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group clearfix block" data-ng-hide="clientEdit.bearerOnly || (!clientEdit.standardFlowEnabled && !clientEdit.implicitFlowEnabled) || protocol == 'docker-v2'"> + <label class="col-md-2 control-label" for="newRedirectUri"><span class="required" data-ng-show="protocol != 'saml'">*</span> {{:: 'valid-redirect-uris' | translate}}</label> + + <div class="col-sm-6"> + <div class="input-group" ng-repeat="(i, redirectUri) in clientEdit.redirectUris track by $index"> + <input class="form-control" ng-model="clientEdit.redirectUris[i]"> + <div class="input-group-btn"> + <button class="btn btn-default" type="button" data-ng-click="deleteRedirectUri($index)"><span class="fa fa-minus"></span></button> + </div> + </div> + + <div class="input-group"> + <input class="form-control" ng-model="newRedirectUri" id="newRedirectUri"> + <div class="input-group-btn"> + <button class="btn btn-default" type="button" data-ng-click="newRedirectUri.length > 0 && addRedirectUri()"><span class="fa fa-plus"></span></button> + </div> + </div> + </div> + + <kc-tooltip>{{:: 'valid-redirect-uris.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group" data-ng-show="!clientEdit.bearerOnly && protocol != 'docker-v2'"> + <label class="col-md-2 control-label" for="baseUrl">{{:: 'base-url' | translate}}</label> + <div class="col-sm-6"> + <input class="form-control" type="text" name="baseUrl" id="baseUrl" data-ng-model="clientEdit.baseUrl"> + </div> + <kc-tooltip>{{:: 'base-url.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-hide="protocol == 'saml' || protocol == 'docker-v2'"> + <label class="col-md-2 control-label" for="adminUrl">{{:: 'admin-url' | translate}}</label> + <div class="col-sm-6"> + <input class="form-control" type="text" name="adminUrl" id="adminUrl" + data-ng-model="clientEdit.adminUrl"> + </div> + <kc-tooltip>{{:: 'admin-url.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="masterSamlUrl">{{:: 'master-saml-processing-url' | translate}}</label> + <div class="col-sm-6"> + <input class="form-control" type="text" name="masterSamlUrl" id="masterSamlUrl" + data-ng-model="clientEdit.adminUrl"> + </div> + <kc-tooltip>{{:: 'master-saml-processing-url.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="urlReferenceName">{{:: 'idp-sso-url-ref' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="clientEdit.attributes.saml_idp_initiated_sso_url_name" class="form-control" type="text" name="urlReferenceName" id="urlReferenceName" /> + <div data-ng-show="clientEdit.attributes.saml_idp_initiated_sso_url_name"> + {{:: 'idp-sso-url-ref.urlhint' | translate}} {{samlIdpInitiatedUrl(clientEdit.attributes.saml_idp_initiated_sso_url_name)}} + </div> + </div> + <kc-tooltip>{{:: 'idp-sso-url-ref.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="idpInitiatedRelayState">{{:: 'idp-sso-relay-state' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="clientEdit.attributes.saml_idp_initiated_sso_relay_state" class="form-control" type="text" name="idpInitiatedRelayState" id="idpInitiatedRelayState" /> + </div> + <kc-tooltip>{{:: 'idp-sso-relay-state.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="(!clientEdit.bearerOnly && protocol == 'openid-connect') && (clientEdit.standardFlowEnabled || clientEdit.directAccessGrantsEnabled || clientEdit.implicitFlowEnabled)"> + <label class="col-md-2 control-label" for="newWebOrigin">{{:: 'web-origins' | translate}}</label> + + <div class="col-sm-6"> + <div class="input-group" ng-repeat="(i, webOrigin) in clientEdit.webOrigins track by $index"> + <input class="form-control" ng-model="clientEdit.webOrigins[i]"> + <div class="input-group-btn"> + <button class="btn btn-default" type="button" data-ng-click="deleteWebOrigin($index)"><span class="fa fa-minus"></span></button> + </div> + </div> + + <div class="input-group"> + <input class="form-control" ng-model="newWebOrigin" id="newWebOrigin"> + <div class="input-group-btn"> + <button class="btn btn-default" type="button" data-ng-click="newWebOrigin.length > 0 && addWebOrigin()"><span class="fa fa-plus"></span></button> + </div> + </div> + </div> + + <kc-tooltip>{{:: 'web-origins.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + <fieldset data-ng-show="protocol == 'saml'"> + <legend collapsed><span class="text">{{:: 'fine-saml-endpoint-conf' | translate}}</span> <kc-tooltip>{{:: 'fine-saml-endpoint-conf.tooltip' | translate}}</kc-tooltip></legend> + <div class="form-group clearfix block" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="consumerServicePost">{{:: 'assertion-consumer-post-binding-url' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="clientEdit.attributes.saml_assertion_consumer_url_post" class="form-control" type="text" name="consumerServicePost" id="consumerServicePost" /> + </div> + <kc-tooltip>{{:: 'assertion-consumer-post-binding-url.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="consumerServiceRedirect">{{:: 'assertion-consumer-redirect-binding-url' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="clientEdit.attributes.saml_assertion_consumer_url_redirect" class="form-control" type="text" name="consumerServiceRedirect" id="consumerServiceRedirect" /> + </div> + <kc-tooltip>{{:: 'assertion-consumer-redirect-binding-url.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="logoutPostBinding">{{:: 'logout-service-post-binding-url' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="clientEdit.attributes.saml_single_logout_service_url_post" class="form-control" type="text" name="logoutPostBinding" id="logoutPostBinding" /> + </div> + <kc-tooltip>{{:: 'logout-service-post-binding-url.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="logoutPostBinding">{{:: 'logout-service-redir-binding-url' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="clientEdit.attributes.saml_single_logout_service_url_redirect" class="form-control" type="text" name="logoutRedirectBinding" id="logoutRedirectBinding" /> + </div> + <kc-tooltip>{{:: 'logout-service-redir-binding-url.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <fieldset data-ng-show="protocol == 'openid-connect'"> + <legend collapsed><span class="text">{{:: 'fine-oidc-endpoint-conf' | translate}}</span> <kc-tooltip>{{:: 'fine-oidc-endpoint-conf.tooltip' | translate}}</kc-tooltip></legend> + + <div class="form-group clearfix block"> + <label class="col-md-2 control-label" for="accessTokenSignedResponseAlg">{{:: 'access-token-signed-response-alg' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="accessTokenSignedResponseAlg" + ng-change="changeAccessTokenSignedResponseAlg()" + ng-model="accessTokenSignedResponseAlg"> + <option value=""></option> + <option ng-repeat="provider in serverInfo.listProviderIds('signature')" value="{{provider}}">{{provider}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'access-token-signed-response-alg.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group clearfix block"> + <label class="col-md-2 control-label" for="idTokenSignedResponseAlg">{{:: 'id-token-signed-response-alg' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="idTokenSignedResponseAlg" + ng-change="changeIdTokenSignedResponseAlg()" + ng-model="idTokenSignedResponseAlg"> + <option value=""></option> + <option ng-repeat="provider in serverInfo.listProviderIds('signature')" value="{{provider}}">{{provider}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'id-token-signed-response-alg.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group clearfix block"> + <label class="col-md-2 control-label" for="idTokenEncryptedResponseAlg">{{:: 'id-token-encrypted-response-alg' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="idTokenEncryptedResponseAlg" + ng-change="changeIdTokenEncryptedResponseAlg()" + ng-model="idTokenEncryptedResponseAlg"> + <option value=""></option> + <option ng-repeat="provider in serverInfo.listProviderIds('cekmanagement')" value="{{provider}}">{{provider}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'id-token-encrypted-response-alg.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group clearfix block"> + <label class="col-md-2 control-label" for="idTokenEncryptedResponseEnc">{{:: 'id-token-encrypted-response-enc' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="idTokenEncryptedResponseEnc" + ng-change="changeIdTokenEncryptedResponseEnc()" + ng-model="idTokenEncryptedResponseEnc"> + <option value=""></option> + <option ng-repeat="provider in serverInfo.listProviderIds('contentencryption')" value="{{provider}}">{{provider}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'id-token-encrypted-response-enc.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group clearfix block"> + <label class="col-md-2 control-label" for="userInfoSignedResponseAlg">{{:: 'user-info-signed-response-alg' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="userInfoSignedResponseAlg" + ng-change="changeUserInfoSignedResponseAlg()" + ng-model="userInfoSignedResponseAlg"> + <option value="unsigned">unsigned</option> + <option ng-repeat="provider in serverInfo.listProviderIds('signature')" value="{{provider}}">{{provider}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'user-info-signed-response-alg.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="protocol == 'openid-connect'"> + <label class="col-md-2 control-label" for="requestObjectSignatureAlg">{{:: 'request-object-signature-alg' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="requestObjectSignatureAlg" + ng-change="changeRequestObjectSignatureAlg()" + ng-model="requestObjectSignatureAlg"> + <option value="any">any</option> + <option value="none">none</option> + <option ng-repeat="provider in serverInfo.listProviderIds('clientSignature')" value="{{provider}}">{{provider}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'request-object-signature-alg.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="protocol == 'openid-connect'"> + <label class="col-md-2 control-label" for="changeRequestObjectRequired">{{:: 'request-object-required' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="requestObjectRequired" + ng-change="changeRequestObjectRequired()" + ng-model="requestObjectRequired" + ng-options="sig for sig in requestObjectRequiredOptions"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'request-object-required.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <fieldset data-ng-show="protocol == 'openid-connect'"> + <legend collapsed><span class="text">{{:: 'oidc-compatibility-modes' | translate}}</span> <kc-tooltip>{{:: 'oidc-compatibility-modes.tooltip' | translate}}</kc-tooltip></legend> + <div class="form-group clearfix block" data-ng-show="protocol == 'openid-connect'"> + <label class="col-md-2 control-label" for="excludeSessionStateFromAuthResponse">{{:: 'exclude-session-state-from-auth-response' | translate}}</label> + <div class="col-md-6"> + <input ng-model="excludeSessionStateFromAuthResponse" ng-click="switchChange()" name="excludeSessionStateFromAuthResponse" id="excludeSessionStateFromAuthResponse" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'exclude-session-state-from-auth-response.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <fieldset> + <legend collapsed><span class="text">{{:: 'advanced-client-settings' | translate}}</span> <kc-tooltip>{{:: 'advanced-client-settings.tooltip' | translate}}</kc-tooltip></legend> + + <div class="form-group" data-ng-show="protocol == 'openid-connect'"> + <label class="col-md-2 control-label" for="accessTokenLifespan">{{:: 'access-token-lifespan' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" min="-1" + max="31536000" data-ng-model="accessTokenLifespan.time" + id="accessTokenLifespan" name="accessTokenLifespan" + data-ng-change="updateTimeouts()"/> + <select class="form-control" name="accessTokenLifespanUnit" data-ng-model="accessTokenLifespan.unit" data-ng-change="updateTimeouts()"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'access-token-lifespan.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="samlAssertionLifespan">{{:: 'saml-assertion-lifespan' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" min="1" + max="31536000" data-ng-model="samlAssertionLifespan.time" + id="samlAssertionLifespan" name="samlAssertionLifespan" + data-ng-change="updateAssertionLifespan()"/> + <select class="form-control" name="samlAssertionLifespanUnit" data-ng-model="samlAssertionLifespan.unit" data-ng-change="updateAssertionLifespan()"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'saml-assertion-lifespan.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group" data-ng-show="protocol == 'openid-connect'"> + <label class="col-md-2 control-label" for="clientSessionIdleTimeout">{{:: 'client-session-idle' | translate}}</label> + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" min="0" + max="31536000" data-ng-model="clientSessionIdleTimeout.time" + id="clientSessionIdleTimeout" name="clientSessionIdleTimeout" + data-ng-change="updateClientSessionIdleTimeout()"/> + <select class="form-control" name="clientSessionIdleTimeoutUnit" data-ng-model="clientSessionIdleTimeout.unit" data-ng-change="updateClientSessionIdleTimeout()"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'client-session-idle.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group" data-ng-show="protocol == 'openid-connect'"> + <label class="col-md-2 control-label" for="clientSessionMaxLifespan">{{:: 'client-session-max' | translate}}</label> + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" min="0" + max="31536000" data-ng-model="clientSessionMaxLifespan.time" + id="clientSessionMaxLifespan" name="clientSessionMaxLifespan" + data-ng-change="updateClientSessionMaxLifespan()"/> + <select class="form-control" name="clientSessionMaxLifespanUnit" data-ng-model="clientSessionMaxLifespan.unit" data-ng-change="updateClientSessionMaxLifespan()"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'client-session-max.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group clearfix block" data-ng-show="protocol == 'openid-connect'"> + <label class="col-md-2 control-label" for="tlsClientCertificateBoundAccessTokens">{{:: 'tls-client-certificate-bound-access-tokens' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="tlsClientCertificateBoundAccessTokens" ng-click="switchChange()" name="tlsClientCertificateBoundAccessTokens" id="tlsClientCertificateBoundAccessTokens" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'tls-client-certificate-bound-access-tokens.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group clearfix block" data-ng-show="protocol == 'openid-connect'"> + <label class="col-md-2 control-label" for="changePkceCodeChallengeMethod">{{:: 'pkce-code-challenge-method' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="pkceCodeChallengeMethod" + ng-change="changePkceCodeChallengeMethod()" + ng-model="pkceCodeChallengeMethod" + ng-options="method for method in changePkceCodeChallengeMethodOptions"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'pkce-code-challenge-method.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <fieldset> + <legend collapsed><span class="text">{{:: 'client-flow-bindings' | translate}}</span> <kc-tooltip>{{:: 'client-flow-bindings.tooltip' | translate}}</kc-tooltip></legend> + <div class="form-group"> + <label for="browser" class="col-md-2 control-label">{{:: 'browser-flow' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="browser" data-ng-model="clientEdit.authenticationFlowBindingOverrides['browser']" class="form-control" ng-options="flow.id as flow.alias for flow in flows"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'browser-flow.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="protocol == 'openid-connect'"> + <label for="grant" class="col-md-2 control-label">{{:: 'direct-grant-flow' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="grant" ng-model="clientEdit.authenticationFlowBindingOverrides['direct_grant']" class="form-control" ng-options="flow.id as flow.alias for flow in flows"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'direct-grant-flow.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="client.access.configure"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/client-import.html b/admin/resources/partials/client-import.html new file mode 100644 index 0000000..18ec93c --- /dev/null +++ b/admin/resources/partials/client-import.html @@ -0,0 +1,46 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li>{{:: 'import-client' | translate}}</li> + </ol> + + <h1>{{:: 'import-client' | translate}}</h1> + + <form class="form-horizontal" name="realmForm" novalidate> + <fieldset class="border-top"> + <div class="form-group input-select"> + <label class="col-md-2 control-label" for="configFormats">{{:: 'format-option' | translate}}</label> + <div class="col-md-6"> + <div class="input-group"> + <div> + <select class="form-control" id="configFormats" name="configFormats" ng-model="configFormat" ng-options="format.name for format in configFormats"> + <option value="" selected> {{:: 'select-format' | translate}} </option> + </select> + </div> + </div> + </div> + </div> + <div class="form-group"> + <label class="col-md-2 control-label">{{:: 'import-file' | translate}} </label> + <div class="col-md-6"> + <div class="controls kc-button-input-file" data-ng-show="!files || files.length == 0"> + <label for="import-file" class="btn btn-default">{{:: 'select-file' | translate}} <i class="pficon pficon-import"></i></label> + <input id="import-file" type="file" class="hidden" ng-file-select="onFileSelect($files)"> + </div> + <span class="kc-uploaded-file" data-ng-show="files.length > 0"> + {{files[0].name}} + </span> + </div> + </div> + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="files.length > 0"> + <button type="submit" data-ng-click="uploadFile()" class="btn btn-primary">{{:: 'import' | translate}}</button> + <button type="submit" data-ng-click="clearFileSelect()" class="btn btn-default">{{:: 'cancel' | translate}}</button> + </div> + </div> + </fieldset> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-initial-access-create.html b/admin/resources/partials/client-initial-access-create.html new file mode 100644 index 0000000..8c0cb19 --- /dev/null +++ b/admin/resources/partials/client-initial-access-create.html @@ -0,0 +1,63 @@ +<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}}/client-registration/client-initial-access">{{:: 'initial-access-tokens' | translate}}</a></li> + <li>{{:: 'add-initial-access-tokens' | translate}}</li> + </ol> + + <h1 data-ng-show="create">{{:: 'add-client' | translate}}</h1> + + <form class="form-horizontal" name="createForm" novalidate kc-read-only="!access.manageRealm" data-ng-hide="token"> + + <div class="form-group"> + <label class="col-md-2 control-label" for="expiration">{{:: 'expiration' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="0" max="31536000" data-ng-model="expiration" id="expiration" + name="expiration"/> + <select class="form-control" name="expirationUnit" data-ng-model="expirationUnit"> + <option data-ng-selected="!expirationUnit" value="Seconds">{{:: 'seconds' | translate}}</option> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'expiration.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="count">{{:: 'count' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="count" name="count" required min="1" max="100" data-ng-model="count"> + </div> + <kc-tooltip>{{:: 'count.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="access.manageRealm"> + <button kc-save>{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> + + <form name="displayForm" data-ng-show="token"> + <div class="form-group"> + <label for="initialAccessToken">{{:: 'initial-access-token' | translate}}</label> + + <div> + <textarea type="text" id="initialAccessToken" name="initialAccessToken" class="form-control" rows="6" kc-select-action="click">{{token}}</textarea> + </div> + + <kc-tooltip>{{:: 'initial-access.copyPaste.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <div> + <button class="btn btn-default" data-ng-click="done()">{{:: 'back' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-initial-access.html b/admin/resources/partials/client-initial-access.html new file mode 100644 index 0000000..cfb6a68 --- /dev/null +++ b/admin/resources/partials/client-initial-access.html @@ -0,0 +1,55 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <kc-tabs-realm></kc-tabs-realm> + + <ul class="nav nav-tabs nav-tabs-pf"> + <li class="active"><a href="#/realms/{{realm.realm}}/client-registration/client-initial-access">{{:: 'initial-access-tokens' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/client-registration/client-reg-policies">{{:: 'client-reg-policies' | translate}}</a></li> + </ul> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="6"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" data-ng-model="search2.id" class="form-control search" onkeyup="if(event.keyCode == 13){$(this).next('I').click();}"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit"></i> + </div> + </div> + </div> + + <div class="pull-right" data-ng-show="access.manageClients"> + <a id="createClient" class="btn btn-default" href="#/realms/{{realm.realm}}/client-registration/client-initial-access/create">{{:: 'create' | translate}}</a> + </div> + </div> + </th> + </tr> + <tr data-ng-hide="clientInitialAccess.length == 0"> + <th>{{:: 'id' | translate}}</th> + <th>{{:: 'created' | translate}}</th> + <th>{{:: 'expires' | translate}}</th> + <th>{{:: 'count' | translate}}</th> + <th>{{:: 'remainingCount' | translate}}</th> + <th>{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="ia in clientInitialAccess | filter:search2 | orderBy:'timestamp'"> + <td>{{ia.id}}</td> + <td>{{(ia.timestamp * 1000)|date:'shortDate'}} {{(ia.timestamp * 1000)|date:'mediumTime'}}</td> + <td><span data-ng-show="ia.expiration > 0">{{((ia.timestamp + ia.expiration) * 1000)|date:'shortDate'}} {{((ia.timestamp + ia.expiration) * 1000)|date:'mediumTime'}}</span></td> + <td>{{ia.count}}</td> + <td>{{ia.remainingCount}}</td> + <td class="kc-action-cell" data-ng-click="remove(ia.id)">{{:: 'delete' | translate}}</td> + </tr> + <tr data-ng-show="(clientInitialAccess | filter:search2).length == 0"> + <td class="text-muted" colspan="3" data-ng-show="search2.id">{{:: 'no-results' | translate}}</td> + <td class="text-muted" colspan="3" data-ng-hide="search2.id">{{:: 'no-initial-access-available' | translate}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-installation.html b/admin/resources/partials/client-installation.html new file mode 100644 index 0000000..d03fdd2 --- /dev/null +++ b/admin/resources/partials/client-installation.html @@ -0,0 +1,36 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li>{{client.clientId}}</li> + </ol> + + <kc-tabs-client></kc-tabs-client> + + <form class="form" name="realmForm" novalidate> + <fieldset> + <div class="form-group input-select"> + <label class="col-md-1 control-label" for="configFormats">{{:: 'format-option' | translate}}</label> + <div class="col-md-6"> + <div class="input-group"> + <div> + <select class="form-control" id="configFormats" name="configFormats" ng-change="changeFormat()" ng-model="configFormat" ng-options="a.displayType for a in configFormats"> + <option value="" selected> {{:: 'select-a-format' | translate}} </option> + </select> + </div> + </div> + </div> + </div> + </fieldset> + <fieldset class="margin-top"> + <div class="form-group" ng-show="installation"> + <div class="col-sm-12"> + <a class="btn btn-primary btn-lg" data-ng-click="download()" type="submit" ng-show="installation">{{:: 'download' | translate}}</a> + <textarea class="form-control" rows="20" kc-select-action="click" data-ng-hide="configFormat.downloadOnly">{{installation}}</textarea> + </div> + </div> + </fieldset> + </form> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/client-keys.html b/admin/resources/partials/client-keys.html new file mode 100644 index 0000000..c412e27 --- /dev/null +++ b/admin/resources/partials/client-keys.html @@ -0,0 +1,146 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li>{{client.clientId}}</li> + </ol> + + <kc-tabs-client></kc-tabs-client> + + <form class="form-horizontal" name="keyForm" novalidate kc-read-only="!client.access.configure"> + <fieldset> + <legend collapsed><span class="text">{{:: 'import-keys-and-cert' | translate}}</span> <kc-tooltip>{{:: 'import-keys-and-cert.tooltip' | translate}}</kc-tooltip></legend> + <div class="form-group"> + <label class="col-md-2 control-label" for="uploadKeyFormat">{{:: 'archive-format' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="uploadKeyFormat" + ng-model="uploadKeyFormat" + ng-options="f for f in keyFormats"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'archive-format.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="uploadKeyAlias">{{:: 'key-alias' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" id="uploadKeyAlias" name="uploadKeyAlias" data-ng-model="uploadKeyAlias" autofocus required> + </div> + <kc-tooltip>{{:: 'key-alias.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="uploadKeyPas">{{:: 'key-password' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" kc-password id="uploadKeyPas" name="uploadKeyPassword" data-ng-model="uploadKeyPassword" autofocus required> + </div> + <kc-tooltip>{{:: 'key-password.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="uploadStorePas">{{:: 'store-password' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" kc-password id="uploadStorePas" name="uploadStorePas" data-ng-model="uploadStorePassword" autofocus required> + </div> + <kc-tooltip>{{:: 'store-password.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label">{{:: 'upload-keys' | translate}} </label> + <div class="col-md-6"> + <div class="controls kc-button-input-file" data-ng-show="!files || files.length == 0"> + <a href="#" class="btn btn-default"><span class="kc-icon-upload">Icon: Upload</span>{{:: 'choose-a-file.placeholder' | translate}}</a> + <input id="import-file" type="file" class="transparent" ng-file-select="onFileSelect($files)"> + </div> + <span class="kc-uploaded-file" data-ng-show="files.length > 0"> + {{files[0].name}} + </span> + </div> + </div> + <div class="pull-right form-actions" data-ng-show="files.length > 0"> + <button type="submit" data-ng-click="clearFileSelect()" class="btn btn-lg btn-default">{{:: 'cancel' | translate}}</button> + <button type="submit" data-ng-click="uploadFile()" class="btn btn-lg btn-primary">{{:: 'upload' | translate}}</button> + </div> + </fieldset> + <fieldset class="form-group col-sm-10" data-ng-hide="!keyInfo.privateKey"> + <legend collapsed><span class="text">{{:: 'download-keys-and-cert' | translate}}</span> <kc-tooltip>Client key pair, cert, and realm certificate will be stuffed into a PKCS12 or Java keystore that you can use in your clients.</kc-tooltip></legend> + <div class="form-group"> + <label class="col-md-2 control-label" for="downloadKeyFormat">{{:: 'archive-format' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="downloadKeyFormat" + ng-model="jks.format" + ng-options="f for f in keyFormats"> + </select> + </div> + </div> + <kc-tooltip>Java keystore or PKCS12 archive format.</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="keyAlias">Key Alias</label> + <div class="col-md-6"> + <input class="form-control" type="text" id="keyAlias" name="keyAlias" data-ng-model="jks.keyAlias" autofocus required> + </div> + <kc-tooltip>Archive alias for your private key and certificate.</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="keyPas">Key Password</label> + <div class="col-md-6"> + <input class="form-control" kc-password id="keyPas" name="keyPas" data-ng-model="jks.keyPassword" autofocus required> + </div> + <kc-tooltip>Password to access the private key in the archive</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="realmAlias">Realm Certificate Alias</label> + <div class="col-md-6"> + <input class="form-control" type="text" id="realmAlias" name="realmAlias" data-ng-model="jks.realmAlias" autofocus required> + </div> + <kc-tooltip>Realm certificate is stored in archive too. This is the alias to it.</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="storePas">Store Password</label> + <div class="col-md-6"> + <input class="form-control" kc-password id="storePas" name="storePas" data-ng-model="jks.storePassword" autofocus required> + </div> + <kc-tooltip>Password to access the archive itself</kc-tooltip> + </div> + <div class="form-group" data-ng-show="access.manageRealm"> + <div class="pull-right"> + <button class="btn btn-primary" type="submit" data-ng-click="downloadJKS()">Download</button> + </div> + </div> + </fieldset> + <fieldset class="form-group col-sm-10"> + <legend><span class="text">Keys and Certificate</span> <kc-tooltip>Keys and cert in PEM format.</kc-tooltip></legend> + <div class="form-group" data-ng-hide="!keyInfo.privateKey"> + <label class="col-md-2 control-label" for="publicKey">Private key</label> + + <div class="col-sm-10"> + <textarea type="text" id="Private" name="publicKey" class="form-control" rows="5" + kc-select-action="click" readonly>{{keyInfo.privateKey}}</textarea> + </div> + </div> + <div class="form-group" data-ng-hide="!keyInfo.privateKey"> + <label class="col-md-2 control-label" for="publicKey">Public key</label> + + <div class="col-sm-10"> + <textarea type="text" id="publicKey" name="publicKey" class="form-control" rows="5" + kc-select-action="click" readonly>{{keyInfo.publicKey}}</textarea> + </div> + </div> + <div class="form-group" data-ng-hide="!keyInfo.privateKey"> + <label class="col-md-2 control-label" for="publicKey">Certificate</label> + + <div class="col-sm-10"> + <textarea type="text" id="certificate" name="certificate" class="form-control" rows="5" + kc-select-action="click" readonly>{{keyInfo.certificate}}</textarea> + </div> + </div> + <div class="form-group" data-ng-show="client.access.configure"> + <div class="pull-right"> + <button class="btn btn-primary" type="submit" data-ng-click="generate()">Generate new keys</button> + </div> + </div> + </fieldset> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-list.html b/admin/resources/partials/client-list.html new file mode 100644 index 0000000..6640d5a --- /dev/null +++ b/admin/resources/partials/client-list.html @@ -0,0 +1,68 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2" ng-init="init()"> + + <kc-tabs-clients></kc-tabs-clients> + + <table class="datatable table table-striped table-bordered dataTable no-footer"> + <thead> + <tr> + <th class="kc-table-actions" colspan="6"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" data-ng-model="query.clientId" class="form-control search" onkeydown="if (event.keyCode == 13) document.getElementById('clientSearch').click()"> + <div class="input-group-addon"> + <i class="fa fa-search" id="clientSearch" data-ng-click="firstPage()"></i> + </div> + </div> + </div> + + <div class="pull-right" data-ng-show="access.manageClients"> + <a id="createClient" class="btn btn-default" href="#/create/client/{{realm.realm}}">{{:: 'create' | translate}}</a> + <a id="importClient" class="btn btn-default" href="#/import/client/{{realm.realm}}" data-ng-show="importButton">{{:: 'import' | translate}}</a> + </div> + </div> + <div data-ng-show="!searchLoaded" class="form-inline"> + {{:: 'search.loading' | translate }} + </div> + </th> + </tr> + <tr data-ng-hide="clients.length == 0"> + <th>{{:: 'client-id' | translate}}</th> + <th>{{:: 'enabled' | translate}}</th> + <th>{{:: 'base-url' | translate}}</th> + <th colspan="3">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tfoot data-ng-show="clients && (clients.length >= query.max || query.first > 0)"> + <tr> + <td colspan="6"> + <div class="table-nav"> + <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button> + <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button> + <button data-ng-click="nextPage()" class="next" ng-disabled="clients.length < query.max">{{:: 'next-page' | translate}}</button> + </div> + </td> + </tr> + </tfoot> + <tbody> + <tr ng-repeat="client in clients"> + <td><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></td> + <td translate="{{client.enabled}}"></td> + <td ng-class="{'text-muted': !client.baseUrl}"> + <a href="{{client.rootUrl | resolveClientRootUrl}}{{client.baseUrl}}" target="_blank" data-ng-show="client.baseUrl">{{client.rootUrl | resolveClientRootUrl}}{{client.baseUrl}}</a> + <span data-ng-hide="client.baseUrl">{{:: 'not-defined' | translate}}</span> + </td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/clients/{{client.id}}">{{:: 'edit' | translate}}</td> + <td class="kc-action-cell" data-ng-click="exportClient(client)">{{:: 'export' | translate}}</td> + <td class="kc-action-cell" data-ng-show="client.access.manage" data-ng-click="removeClient(client)">{{:: 'delete' | translate}}</td> + </tr> + <tr data-ng-show="!clients || clients.length == 0"> + <td class="text-muted" data-ng-show="!clients" colspan="6">{{:: 'clients.instruction' | translate}}</td> + <td class="text-muted" data-ng-show="searchLoaded && clients.length == 0 && lastSearch != null">{{:: 'no-results' | translate}}</td> + <td class="text-muted" data-ng-show="searchLoaded && clients.length == 0 && lastSearch == null">{{:: 'no-clients-available' | translate}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-mappers-add.html b/admin/resources/partials/client-mappers-add.html new file mode 100644 index 0000000..6537779 --- /dev/null +++ b/admin/resources/partials/client-mappers-add.html @@ -0,0 +1,53 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/mappers">{{:: 'mappers' | translate}}</a></li> + <li class="active">{{:: 'add-builtin-protocol-mappers' | translate}}</li> + </ol> + + <h1>{{:: 'add-builtin-protocol-mapper' | translate}}</h1> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="4"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" data-ng-model="search.name" class="form-control search" onkeyup="if(event.keyCode == 13){$(this).next('I').click();}"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit"></i> + </div> + </div> + </div> + </div> + </th> + </tr> + <tr data-ng-hide="mappers.length == 0"> + <th>{{:: 'name' | translate}}</th> + <th>{{:: 'category' | translate}}</th> + <th>{{:: 'type' | translate}}</th> + <th>{{:: 'add' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="mapper in mappers | filter:search"> + <td>{{mapper.name}}</td> + <td>{{mapperTypes[mapper.protocolMapper].category}}</td> + <td>{{mapperTypes[mapper.protocolMapper].name}}</td> + <td><input type="checkbox" ng-model="mapper.isChecked" id="{{mapper.protocolMapper}}"></td> + </tr> + <tr data-ng-show="mappers.length == 0"> + <td>{{:: 'no-mappers-available' | translate}}</td> + </tr> + </tbody> + </table> + + <div data-ng-show="client.access.manage"> + <button class="btn btn-primary" data-ng-click="add()">{{:: 'add-selected' | translate}}</button> + </div> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-mappers.html b/admin/resources/partials/client-mappers.html new file mode 100644 index 0000000..83123c2 --- /dev/null +++ b/admin/resources/partials/client-mappers.html @@ -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}}/clients">{{:: 'clients' | translate}}</a></li> + <li>{{client.clientId}}</li> + </ol> + + <kc-tabs-client></kc-tabs-client> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="6"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" data-ng-model="search.name" class="form-control search" onkeyup="if(event.keyCode == 13){$(this).next('I').click();}"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit"></i> + </div> + </div> + </div> + + <div class="pull-right" data-ng-show="client.access.manage"> + <a class="btn btn-default" href="#/create/client/{{realm.realm}}/{{client.id}}/mappers">{{:: 'create' | translate}}</a> + <a class="btn btn-default" href="#/realms/{{realm.realm}}/clients/{{client.id}}/add-mappers">{{:: 'add-builtin' | translate}}</a> + </div> + </div> + </th> + </tr> + <tr data-ng-hide="mappers.length == 0"> + <th>{{:: 'name' | translate}}</th> + <th>{{:: 'category' | translate}}</th> + <th>{{:: 'type' | translate}}</th> + <th>{{:: 'priority-order' | translate}}</th> + <th colspan="2">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="mapper in mappers | filter:search | orderBy:sortMappersByPriority"> + <td><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/mappers/{{mapper.id}}">{{mapper.name}}</a></td> + <td>{{mapperTypes[mapper.protocolMapper].category}}</td> + <td>{{mapperTypes[mapper.protocolMapper].name}}</td> + <td>{{mapperTypes[mapper.protocolMapper].priority}}</td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/clients/{{client.id}}/mappers/{{mapper.id}}">{{:: 'edit' | translate}}</td> + <td class="kc-action-cell" data-ng-show="client.access.manage" data-ng-click="removeMapper(mapper)">{{:: 'delete' | translate}}</td> + </tr> + <tr data-ng-show="mappers.length == 0"> + <td>{{:: 'no-mappers-available' | translate}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-offline-sessions.html b/admin/resources/partials/client-offline-sessions.html new file mode 100644 index 0000000..3d2aaf7 --- /dev/null +++ b/admin/resources/partials/client-offline-sessions.html @@ -0,0 +1,59 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li>{{client.clientId}}</li> + </ol> + + <kc-tabs-client></kc-tabs-client> + + <form class="form-horizontal" name="sessionStats"> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="activeSessions">{{:: 'offline-tokens' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" id="activeSessions" name="activeSessions" data-ng-model="count" ng-disabled="true"> + </div> + <kc-tooltip>{{:: 'offline-tokens.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + </form> + <table class="table table-striped table-bordered" data-ng-show="count > 0"> + <thead> + <tr> + <th class="kc-table-actions" colspan="4"> + <div class="pull-right"> + <a class="btn btn-default" ng-click="loadUsers()" tooltip-placement="left" tooltip-trigger="mouseover mouseout" tooltip="{{:: 'show-offline-tokens.tooltip' | translate}}">{{:: 'show-offline-tokens' | translate}}</a> + </div> + </th> + </tr> + <tr data-ng-show="sessions"> + <th>{{:: 'user' | translate}}</th> + <th>{{:: 'from-ip' | translate}}</th> + <th>{{:: 'token-issued' | translate}}</th> + <th>{{:: 'last-refresh' | translate}}</th> + </tr> + </thead> + <tfoot data-ng-show="sessions && (sessions.length >= 5 || query.first != 0)"> + <tr> + <td colspan="7"> + <div class="table-nav"> + <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button> + <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button> + <button data-ng-click="nextPage()" class="next" ng-disabled="sessions.length < query.max">{{:: 'next-page' | translate}}</button> + </div> + </td> + </tr> + </tfoot> + <tbody> + <tr data-ng-repeat="session in sessions"> + <td><a href="#/realms/{{realm.realm}}/users/{{session.userId}}">{{session.username}}</a></td> + <td>{{session.ipAddress}}</td> + <td>{{session.start | date:'medium'}}</td> + <td>{{session.lastAccess | date:'medium'}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-protocol-mapper-detail.html b/admin/resources/partials/client-protocol-mapper-detail.html new file mode 100644 index 0000000..b2af24a --- /dev/null +++ b/admin/resources/partials/client-protocol-mapper-detail.html @@ -0,0 +1,13 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + + <ol class="breadcrumb"> + <li><a href="#/realms/{{model.realm.realm}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{model.realm.realm}}/clients/{{model.client.id}}">{{model.client.clientId}}</a></li> + <li><a href="#/realms/{{model.realm.realm}}/clients/{{model.client.id}}/mappers">{{:: 'mappers' | translate}}</a></li> + <li class="active" data-ng-show="model.create">{{:: 'create-protocol-mappers' | translate}}</li> + <li class="active" data-ng-hide="model.create">{{model.mapper.name}}</li> + </ol> + <div ng-include="resourceUrl + '/partials/protocol-mapper-detail.html'"/> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-reg-policies.html b/admin/resources/partials/client-reg-policies.html new file mode 100644 index 0000000..9ca912f --- /dev/null +++ b/admin/resources/partials/client-reg-policies.html @@ -0,0 +1,106 @@ +<!-- + ~ Copyright 2016 Red Hat, Inc. and/or its affiliates + ~ and other contributors as indicated by the @author tags. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <kc-tabs-realm></kc-tabs-realm> + + <ul class="nav nav-tabs nav-tabs-pf"> + <li><a href="#/realms/{{realm.realm}}/client-registration/client-initial-access">{{:: 'initial-access-tokens' | translate}}</a></li> + <li class="active"><a href="#/realms/{{realm.realm}}/client-registration/client-reg-policies">{{:: 'client-reg-policies' | translate}}</a></li> + </ul> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + + <fieldset> + <legend><span class="text">{{:: 'anonymous-policies' | translate}}</span></legend><kc-tooltip>{{:: 'anonymous-policies.tooltip' | translate}}</kc-tooltip> + <table class="table table-striped table-bordered"> + <thead> + <tr ng-show="providers.length > 0 && access.manageClients"> + <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('anonymous', selectedProvider); selectedProvider = null"> + <option value="" disabled selected>{{:: 'add-provider.placeholder' | translate}}</option> + </select> + </div> + </div> + </th> + </tr> + <tr data-ng-show="anonPolicies && anonPolicies.length > 0"> + <th>{{:: 'policy-name' | translate}}</th> + <th>{{:: 'provider-id' | translate}}</th> + <th colspan="2">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="instance in anonPolicies"> + <td><a href="#{{getInstanceLink(instance)}}">{{instance.name}}</a></td> + <td>{{instance.providerId}}</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="!anonPolicies || anonPolicies.length == 0"> + <td class="text-muted">{{:: 'no-client-reg-policies-configured' | translate}}</td> + </tr> + </tbody> + </table> + </fieldset> + + <fieldset> + <legend><span class="text">{{:: 'auth-policies' | translate}}</span></legend><kc-tooltip>{{:: 'auth-policies.tooltip' | translate}}</kc-tooltip> + <table class="table table-striped table-bordered"> + <thead> + <tr ng-show="providers.length > 0 && access.manageClients"> + <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('authenticated', selectedProvider); selectedProvider = null"> + <option value="" disabled selected>{{:: 'add-provider.placeholder' | translate}}</option> + </select> + </div> + </div> + </th> + </tr> + <tr data-ng-show="authPolicies && authPolicies.length > 0"> + <th>{{:: 'policy-name' | translate}}</th> + <th>{{:: 'provider-id' | translate}}</th> + <th colspan="2">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="instance in authPolicies"> + <td><a href="#{{getInstanceLink(instance)}}">{{instance.name}}</a></td> + <td>{{instance.providerId}}</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="!authPolicies || authPolicies.length == 0"> + <td class="text-muted">{{:: 'no-client-reg-policies-configured' | translate}}</td> + </tr> + </tbody> + </table> + </fieldset> + + + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-reg-policy-detail.html b/admin/resources/partials/client-reg-policy-detail.html new file mode 100644 index 0000000..c0fd074 --- /dev/null +++ b/admin/resources/partials/client-reg-policy-detail.html @@ -0,0 +1,68 @@ +<!-- + ~ Copyright 2016 Red Hat, Inc. and/or its affiliates + ~ and other contributors as indicated by the @author tags. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<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}}/client-registration/client-reg-policies">{{:: 'client-reg-policies' | translate}}</a></li> + <li>{{instance.name}}</li> + </ol> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageClients "> + <fieldset> + <legend><span class="text">{{instance.name}}</span></legend><kc-tooltip>{{:: providerType.helpText | translate}}</kc-tooltip> + <div class="form-group clearfix" data-ng-show="!create"> + <label class="col-md-2 control-label" for="instanceId">{{:: 'id' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="instanceId" type="text" ng-model="instance.id" readonly> + </div> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="name">{{:: 'name' | translate}} <span class="required">*</span></label> + <div class="col-md-6"> + <input class="form-control" id="name" type="text" ng-model="instance.name" required> + </div> + <kc-tooltip>{{:: 'client-reg-policy.name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="policyType">{{:: 'provider' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="policyType" type="text" ng-model="providerType.id" data-ng-readonly="true"> + </div> + <kc-tooltip>{{providerType.helpText}}</kc-tooltip> + </div> + <kc-component-config config="instance.config" properties="providerType.properties" realm="realm"></kc-component-config> + </fieldset> + + <div class="form-group" data-ng-show="create && access.manageClients"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save>{{:: 'save' | translate}}</button> + <button kc-reset>{{:: 'cancel' | translate}}</button> + </div> + </div> + + <div class="form-group" data-ng-show="!create && access.manageClients"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> + +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-reg-trusted-host-create.html b/admin/resources/partials/client-reg-trusted-host-create.html new file mode 100644 index 0000000..cb07613 --- /dev/null +++ b/admin/resources/partials/client-reg-trusted-host-create.html @@ -0,0 +1,55 @@ +<!-- + ~ Copyright 2016 Red Hat, Inc. and/or its affiliates + ~ and other contributors as indicated by the @author tags. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<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}}/client-initial-access">{{:: 'initial-access-tokens' | translate}}</a></li> + <li>{{:: 'add-client-reg-trusted-host' | translate}}</li> + </ol> + + <h1>{{:: 'add-client-reg-trusted-host' | translate}}</h1> + + <form class="form-horizontal" name="createForm" novalidate kc-read-only="!access.manageRealm"> + + <div class="form-group"> + <label class="col-md-2 control-label" for="hostName">{{:: 'hostname' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="hostName" name="hostName" data-ng-model="hostName"> + </div> + <kc-tooltip>{{:: 'client-reg-hostname.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="count">{{:: 'count' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="count" name="count" required min="1" max="10000" data-ng-model="count"> + </div> + <kc-tooltip>{{:: 'client-reg-count.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="access.manageRealm"> + <button kc-save>{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> + +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-reg-trusted-host-detail.html b/admin/resources/partials/client-reg-trusted-host-detail.html new file mode 100644 index 0000000..5644fc1 --- /dev/null +++ b/admin/resources/partials/client-reg-trusted-host-detail.html @@ -0,0 +1,64 @@ +<!-- + ~ Copyright 2016 Red Hat, Inc. and/or its affiliates + ~ and other contributors as indicated by the @author tags. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<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}}/client-initial-access">{{:: 'initial-access-tokens' | translate}}</a></li> + <li>{{hostName}}</li> + </ol> + + <h1>{{hostName}}</h1> + + <form class="form-horizontal" name="createForm" novalidate kc-read-only="!access.manageRealm"> + + <div class="form-group"> + <label class="col-md-2 control-label" for="hostName">{{:: 'hostname' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="hostName" name="hostName" data-ng-model="hostName" readonly> + </div> + <kc-tooltip>{{:: 'client-reg-hostname.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="count">{{:: 'count' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="count" name="count" required min="1" max="10000" data-ng-model="count"> + </div> + <kc-tooltip>{{:: 'client-reg-count.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="remainingCount">{{:: 'remainingCount' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="remainingCount" name="remainingCount" data-ng-model="remainingCount" readonly> + </div> + <kc-tooltip>{{:: 'client-reg-remainingCount.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="access.manageRealm"> + <button class="btn btn-primary" data-ng-click="resetRemainingCount()" data-ng-hide="changed">{{:: 'reset-remaining-count' | translate}}</button> + <button data-ng-show="changed" kc-save>{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> + +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-registration-access-token.html b/admin/resources/partials/client-registration-access-token.html new file mode 100644 index 0000000..327b70d --- /dev/null +++ b/admin/resources/partials/client-registration-access-token.html @@ -0,0 +1,18 @@ +<div> + <form class="form-horizontal" name="registrationAccessTokenForm" novalidate kc-read-only="!client.access.configure"> + <div class="form-group"> + <label class="col-md-2 control-label" for="registrationAccessToken">{{:: 'registrationAccessToken' | translate}}</label> + <div class="col-sm-6"> + <div class="row"> + <div class="col-sm-6"> + <input readonly kc-select-action="click" class="form-control" type="text" id="registrationAccessToken" name="registrationAccessToken" data-ng-model="client.registrationAccessToken"> + </div> + <div class="col-sm-6" data-ng-show="client.access.configure"> + <button type="submit" data-ng-click="regenerateRegistrationAccessToken()" class="btn btn-default">{{:: 'registrationAccessToken.regenerate' | translate}}</button> + </div> + </div> + </div> + <kc-tooltip>{{:: 'registrationAccessToken.tooltip' | translate}}</kc-tooltip> + </div> + </form> +</div> diff --git a/admin/resources/partials/client-revocation.html b/admin/resources/partials/client-revocation.html new file mode 100644 index 0000000..95db767 --- /dev/null +++ b/admin/resources/partials/client-revocation.html @@ -0,0 +1,30 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li>{{client.clientId}}</li> + </ol> + + <kc-tabs-client></kc-tabs-client> + + <form class="form-horizontal" name="credentialForm" novalidate kc-read-only="!client.access.configure"> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="notBefore">{{:: 'not-before' | translate}}</label> + <div class="col-md-6"> + <input ng-disabled="true" class="form-control" type="text" id="notBefore" name="notBefore" data-ng-model="notBefore" autofocus> + </div> + <kc-tooltip>{{:: 'client-revoke.not-before.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="client.access.configure"> + <button type="submit" data-ng-click="clear()" class="btn btn-default">{{:: 'clear' | translate}}</button> + <button type="submit" data-ng-click="setNotBeforeNow()" class="btn btn-default">{{:: 'set-to-now' | translate}}</button> + <button type="submit" data-ng-click="pushRevocation()" class="btn btn-primary" tooltip-trigger="mouseover mouseout" tooltip="{{:: 'client-revoke.push.tooltip' | translate}}" tooltip-placement="bottom">{{:: 'push' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/client-role-attributes.html b/admin/resources/partials/client-role-attributes.html new file mode 100644 index 0000000..47ef416 --- /dev/null +++ b/admin/resources/partials/client-role-attributes.html @@ -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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/roles">{{:: 'roles' | translate}}</a></li> + <li>{{role.name}}</li> + </ol> + + <kc-tabs-client-role></kc-tabs-client-role> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!client.access.configure"> + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th>{{:: 'key' | translate}}</th> + <th>{{:: 'value' | translate}}</th> + <th>{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + + <tr ng-repeat="(key, value) in role.attributes | toOrderedMapSortedByKey"> + <td>{{key}}</td> + <td><input ng-model="role.attributes[key]" class="form-control" type="text" name="{{key}}" id="attribute-{{key}}" /></td> + <td class="kc-action-cell" data-ng-click="removeAttribute(key)">{{:: 'delete' | translate}}</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" data-ng-click="addAttribute()" data-ng-disabled="!newAttribute.key.length || !newAttribute.value.length">{{:: 'add' | translate}}</td> + </tr> + </tbody> + </table> + + <div class="form-group" data-ng-show="client.access.configure"> + <div class="col-md-12"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/client-role-detail.html b/admin/resources/partials/client-role-detail.html new file mode 100644 index 0000000..ab45838 --- /dev/null +++ b/admin/resources/partials/client-role-detail.html @@ -0,0 +1,140 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/roles">{{:: 'roles' | translate}}</a></li> + <li data-ng-show="create">{{:: 'add-role' | translate}}</li> + <li data-ng-hide="create">{{role.name}}</li> + </ol> + + <kc-tabs-client-role></kc-tabs-client-role> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!client.access.configure"> + + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="name">{{:: 'role-name' | translate}} <span class="required" data-ng-show="create">*</span></label> + + <div class="col-md-6"> + <input kc-no-reserved-chars class="form-control" type="text" id="name" name="name" data-ng-model="role.name" autofocus + required data-ng-readonly="!create"> + </div> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="description">{{:: 'description' | translate}} </label> + + <div class="col-md-6"> + <textarea class="form-control" rows="5" cols="50" id="description" name="description" data-ng-model="role.description"></textarea> + <!-- Replaced by the textarea above <input type="text" id="description" name="description" data-ng-model="role.description" autofocus + required> --> + </div> + </div> + <div class="form-group clearfix block" data-ng-hide="create"> + <label class="col-md-2 control-label" for="compositeSwitch" class="control-label">{{:: 'composite-roles' | translate}}</label> + <div class="col-md-6"> + <input ng-model="compositeSwitch" name="compositeSwitch" id="compositeSwitch" ng-disabled="compositeSwitchDisabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'composite-roles.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="create && client.access.configure"> + <button kc-save>{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="!create && client.access.configure"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + + <fieldset data-ng-show="!create && (compositeSwitch || role.composite)"> + <legend uncollapsed><span class="text">{{:: 'composite-roles' | translate}}</span> </legend> + + <div class="form-group"> + <label class="col-md-2 control-label" class="control-label">{{:: 'realm-roles' | translate}}</label> + + <div class="col-md-10"> + <div class="row"> + <div class="col-md-4"> + <label class="control-label" for="available">{{:: 'available-roles' | translate}}</label> + <kc-tooltip>{{:: 'composite.available-realm-roles.tooltip' | translate}}</kc-tooltip> + <select id="available" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedRealmRoles"> + <option ng-repeat="r in realmRoles | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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> + </button> + </div> + <div class="col-md-4"> + <label class="control-label" for="assigned">{{:: 'associated-roles' | translate}}</label> + <kc-tooltip>{{:: 'composite.associated-realm-roles.tooltip' | translate}}</kc-tooltip> + <select id="assigned" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedRealmMappings"> + <option ng-repeat="r in realmMappings | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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}} + </button> + </div> + </div> + </div> + </div> + + <div class="form-group" ng-show="!create && (compositeSwitch || role.composite)"> + <label class="col-md-2 control-label" for="clients">{{:: 'client-roles' | translate}}</label> + <div class="col-md-6"> + <input type="hidden" ui-select2="clientsUiSelect" id="clients" data-ng-model="selectedClient" data-ng-change="changeClient(selectedClient);" data-placeholder="{{:: 'authz-select-client' | translate}}..."> + </input> + </div> + + + <div class="col-md-10 col-md-push-2"> + <div class="row" data-ng-show="selectedClient"> + <div class="col-md-4"> + <label class="control-label" for="available-client">{{:: 'available-roles' | translate}}</label> + <kc-tooltip>{{:: 'available-roles.tooltip' | translate}}</kc-tooltip> + <select id="available-client" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedClientRoles"> + <option ng-repeat="r in clientRoles | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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> + </button> + </div> + <div class="col-md-4"> + <label class="control-label" for="assigned-client">{{:: 'associated-roles' | translate}}</label> + <kc-tooltip>{{:: 'client.associated-roles.tooltip' | translate}}</kc-tooltip> + <select id="assigned-client" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedClientMappings"> + <option ng-repeat="r in clientMappings | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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}} + </button> + </div> + </div> + </div> + </div> + </fieldset> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-role-list.html b/admin/resources/partials/client-role-list.html new file mode 100644 index 0000000..eeb833f --- /dev/null +++ b/admin/resources/partials/client-role-list.html @@ -0,0 +1,64 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li>{{client.clientId}}</li> + </ol> + + <kc-tabs-client></kc-tabs-client> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="5"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" data-ng-model="query.search" ng-model-options="{debounce: 500}" class="form-control search"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit" data-ng-click="firstPage()"></i> + </div> + </div> + </div> + <button id="viewAllRoles" class="btn btn-default" ng-click="query.search = null; firstPage()">{{:: 'view-all-roles' | translate}}</button> + <div class="pull-right" data-ng-show="access.manageRealm"> + <a class="btn btn-default" href="#/create/role/{{realm.realm}}/clients/{{client.id}}">{{:: 'add-role' | translate}}</a> + </div> + </div> + </th> + </tr> + <tr data-ng-hide="!roles || roles.length == 0"> + <th>{{:: 'role-name' | translate}}</th> + <th>{{:: 'composite' | translate}}</th> + <th>{{:: 'description' | translate}}</th> + <th colspan="2">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="role in roles"> + <td><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/roles/{{role.id}}">{{role.name}}</a></td> + <td translate="{{role.composite}}"></td> + <td>{{role.description}}</td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/clients/{{client.id}}/roles/{{role.id}}">{{:: 'edit' | translate}}</td> + <td class="kc-action-cell" data-ng-show="client.access.configure" data-ng-click="removeRole(role)">{{:: 'delete' | translate}}</td> + </tr> + <tr data-ng-show="(roles | filter:{name: query.search}).length == 0"> + <td class="text-muted" colspan="4" data-ng-show="searchLoaded && roles.length == 0 && lastSearch != null">{{:: 'no-results' | translate}}</td> + <td class="text-muted" colspan="4" data-ng-show="searchLoaded && roles.length == 0 && lastSearch == null">{{:: 'no-client-roles-available' | translate}}</td> + </tr> + </tbody> + <tfoot data-ng-show="roles && (roles.length >= query.max || query.first > 0)"> + <tr> + <td colspan="5"> + <div class="table-nav"> + <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button> + <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button> + <button data-ng-click="nextPage()" class="next" ng-disabled="roles.length < query.max">{{:: 'next-page' | translate}}</button> + </div> + </td> + </tr> + </tfoot> + </table> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/client-role-users.html b/admin/resources/partials/client-role-users.html new file mode 100644 index 0000000..5349171 --- /dev/null +++ b/admin/resources/partials/client-role-users.html @@ -0,0 +1,52 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/roles">{{:: 'roles' | translate}}</a></li> + <li>{{role.name}}</li> + </ol> + + <kc-tabs-client-role></kc-tabs-client-role> + + <table class="table table-striped table-bordered"> + <caption data-ng-show="users" class="hidden">{{:: 'table-of-role-members' | translate}}</caption> + <thead> + <tr> + <tr data-ng-show="searchLoaded && users.length > 0"> + <th>{{:: 'username' | translate}}</th> + <th>{{:: 'last-name' | translate}}</th> + <th>{{:: 'first-name' | translate}}</th> + <th>{{:: 'email' | translate}}</th> + <th></th> + </tr> + </tr> + </thead> + <tfoot data-ng-show="users && (users.length >= query.max || query.first > 0)"> + <tr> + <td colspan="7"> + <div class="table-nav"> + <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button> + <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button> + <button data-ng-click="nextPage()" class="next" ng-disabled="users.length < query.max">{{:: 'next-page' | translate}}</button> + </div> + </td> + </tr> + </tfoot> + <tbody> + <tr ng-repeat="user in users"> + <td><a href="#/realms/{{realm.realm}}/users/{{user.id}}">{{user.username}}</a></td> + <td>{{user.lastName}}</td> + <td>{{user.firstName}}</td> + <td>{{user.email}}</td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/users/{{user.id}}">{{:: 'edit' | translate}}</td> + </tr> + <tr data-ng-show="!users || users.length == 0"> + <td class="text-muted" data-ng-show="searchLoaded && users.length == 0 && lastSearch != null">{{:: 'no-role-members' | translate}}</td> + <td class="text-muted" data-ng-show="searchLoaded && users.length == 0 && lastSearch == null">{{:: 'no-role-members' | translate}}</td> + </tr> + </tbody> + </table> + +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/client-saml-key-export.html b/admin/resources/partials/client-saml-key-export.html new file mode 100644 index 0000000..1c8f737 --- /dev/null +++ b/admin/resources/partials/client-saml-key-export.html @@ -0,0 +1,63 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/saml/keys">{{:: 'saml-keys' | translate}}</a></li> + <li class="active">SAML {{keyType}} {{:: 'key-export' | translate}}</li> + </ol> + + <h1>{{:: 'export-saml-key' | translate}} {{client.clientId|capitalize}}</h1> + + <form class="form-horizontal" name="keyForm" novalidate kc-read-only="!client.access.configure"> + <fieldset class="form-group col-sm-10"> + <div class="form-group"> + <label class="col-md-2 control-label" for="downloadKeyFormat">{{:: 'archive-format' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="downloadKeyFormat" + ng-model="jks.format" + ng-options="f for f in keyFormats"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'archive-format.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="keyAlias">{{:: 'key-alias' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" id="keyAlias" name="keyAlias" data-ng-model="jks.keyAlias" autofocus required> + </div> + <kc-tooltip>{{:: 'key-alias.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-hide="!keyInfo.privateKey"> + <label class="col-md-2 control-label" for="keyPas">{{:: 'key-password' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" kc-password id="keyPas" name="keyPas" data-ng-model="jks.keyPassword" autofocus required> + </div> + <kc-tooltip>{{:: 'key-password.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="realmAlias">{{:: 'realm-certificate-alias' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" id="realmAlias" name="realmAlias" data-ng-model="jks.realmAlias" autofocus required> + </div> + <kc-tooltip>{{:: 'realm-certificate-alias.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="storePas">{{:: 'store-password' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" kc-password id="storePas" name="storePas" data-ng-model="jks.storePassword" autofocus required> + </div> + <kc-tooltip>{{:: 'store-password.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="client.access.configure"> + <button class="btn btn-primary" type="submit" data-ng-click="download()">{{:: 'download' | translate}}</button> + </div> + </div> + </fieldset> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-saml-key-import.html b/admin/resources/partials/client-saml-key-import.html new file mode 100644 index 0000000..5b14c24 --- /dev/null +++ b/admin/resources/partials/client-saml-key-import.html @@ -0,0 +1,62 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li> + <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/saml/keys">{{:: 'saml-keys' | translate}}</a></li> + <li class="active">SAML {{keyType}} {{:: 'key-import' | translate}}</li> + </ol> + + <h1>{{:: 'import-saml-key' | translate}} {{client.clientId|capitalize}}</h1> + + <form class="form-horizontal" name="keyForm" novalidate kc-read-only="!client.access.configure"> + <fieldset> + <div class="form-group"> + <label class="col-md-2 control-label" for="uploadKeyFormat">{{:: 'archive-format' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="uploadKeyFormat" + ng-model="uploadKeyFormat" + ng-options="f for f in keyFormats"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'archive-format.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-hide="hideKeystoreSettings()"> + <label class="col-md-2 control-label" for="uploadKeyAlias">{{:: 'key-alias' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" id="uploadKeyAlias" name="uploadKeyAlias" data-ng-model="uploadKeyAlias" autofocus required> + </div> + <kc-tooltip>{{:: 'key-alias.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-hide="hideKeystoreSettings()"> + <label class="col-md-2 control-label" for="uploadStorePas">{{:: 'store-password' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" kc-password id="uploadStorePas" name="uploadStorePas" data-ng-model="uploadStorePassword" autofocus required> + </div> + <kc-tooltip>{{:: 'store-password.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label">{{:: 'import-file' | translate}} </label> + <div class="col-md-6"> + <div class="controls kc-button-input-file" data-ng-show="!files || files.length == 0"> + <label for="import-file" class="btn btn-default">Select file <i class="pficon pficon-import"></i></label> + <input id="import-file" type="file" class="hidden" ng-file-select="onFileSelect($files)"> + </div> + <span class="kc-uploaded-file" data-ng-show="files.length > 0"> + {{files[0].name}} + </span> + </div> + </div> + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="files.length > 0"> + <button type="submit" data-ng-click="uploadFile()" class="btn btn-primary">{{:: 'import' | translate}}</button> + <button type="submit" data-ng-click="clearFileSelect()" class="btn btn-default">{{:: 'cancel' | translate}}</button> + </div> + </div> + </fieldset> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-saml-keys.html b/admin/resources/partials/client-saml-keys.html new file mode 100644 index 0000000..776349d --- /dev/null +++ b/admin/resources/partials/client-saml-keys.html @@ -0,0 +1,66 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li>{{client.clientId}}</li> + </ol> + + <kc-tabs-client></kc-tabs-client> + + <form class="form-horizontal" name="keyForm" novalidate kc-read-only="!client.access.configure"> + <fieldset class="form-group col-sm-10" data-ng-show="client.attributes['saml.client.signature'] == 'true'"> + <legend uncollapsed><span class="text">{{:: 'signing-key' | translate}}</span> <kc-tooltip>{{:: 'saml-signing-key' | translate}}</kc-tooltip></legend> + <div class="form-group" data-ng-hide="!signingKeyInfo.privateKey"> + <label class="col-md-2 control-label" for="signingPrivateKey">{{:: 'private-key' | translate}}</label> + + <div class="col-sm-10"> + <textarea type="text" id="signingPrivateKey" name="signingPrivateKey" class="form-control" rows="5" + kc-select-action="click" readonly>{{signingKeyInfo.privateKey}}</textarea> + </div> + </div> + <div class="form-group" data-ng-hide="!signingKeyInfo.certificate"> + <label class="col-md-2 control-label" for="signingCert">{{:: 'certificate' | translate}}</label> + + <div class="col-sm-10"> + <textarea type="text" id="signingCert" name="signingCert" class="form-control" rows="5" + kc-select-action="click" readonly>{{signingKeyInfo.certificate}}</textarea> + </div> + </div> + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="client.access.configure"> + <button class="btn btn-default" type="submit" data-ng-click="generateSigningKey()">{{:: 'generate-new-keys' | translate}}</button> + <button class="btn btn-default" type="submit" data-ng-click="importSigningKey()">{{:: 'import' | translate}}</button> + <button class="btn btn-default" type="submit" data-ng-hide="!signingKeyInfo.certificate" data-ng-click="exportSigningKey()">{{:: 'export' | translate}}</button> + </div> + </div> + </fieldset> + <fieldset class="form-group col-sm-10" data-ng-show="client.attributes['saml.encrypt'] == 'true'"> + <legend uncollapsed><span class="text">{{:: 'encryption-key' | translate}}</span> <kc-tooltip>{{:: 'saml-encryption-key.tooltip' | translate}}</kc-tooltip></legend> + <div class="form-group" data-ng-hide="!encryptionKeyInfo.privateKey"> + <label class="col-md-2 control-label" for="encryptionPrivateKey">{{:: 'private-key' | translate}}</label> + + <div class="col-sm-10"> + <textarea type="text" id="encryptionPrivateKey" name="encryptionPrivateKey" class="form-control" rows="5" + kc-select-action="click" readonly>{{encryptionKeyInfo.privateKey}}</textarea> + </div> + </div> + <div class="form-group" data-ng-hide="!encryptionKeyInfo.certificate"> + <label class="col-md-2 control-label" for="encryptionCert">{{:: 'certificate' | translate}}</label> + + <div class="col-sm-10"> + <textarea type="text" id="encryptionCert" name="encryptionCert" class="form-control" rows="5" + kc-select-action="click" readonly>{{encryptionKeyInfo.certificate}}</textarea> + </div> + </div> + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="client.access.configure"> + <button class="btn btn-default" type="submit" data-ng-click="generateEncryptionKey()">{{:: 'generate-new-keys' | translate}}</button> + <button class="btn btn-default" type="submit" data-ng-click="importEncryptionKey()">{{:: 'import' | translate}}</button> + <button class="btn btn-default" type="submit" data-ng-hide="!encryptionKeyInfo.certificate" data-ng-click="exportEncryptionKey()">{{:: 'export' | translate}}</button> + </div> + </div> + </fieldset> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-scope-detail.html b/admin/resources/partials/client-scope-detail.html new file mode 100644 index 0000000..88c3216 --- /dev/null +++ b/admin/resources/partials/client-scope-detail.html @@ -0,0 +1,84 @@ +<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}}/client-scopes">{{:: 'client-scopes' | translate}}</a></li> + <li data-ng-show="create">{{:: 'add-client-scope' | translate}}</li> + <li data-ng-hide="create">{{clientScope.name}}</li> + </ol> + + <kc-tabs-client-scope></kc-tabs-client-scope> + + <form class="form-horizontal" name="clientForm" novalidate kc-read-only="!access.manageClients"> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="name">{{:: 'name' | translate}} <span class="required">*</span></label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="name" name="name" data-ng-model="clientScope.name" autofocus required> + </div> + <kc-tooltip>{{:: 'client-scope.name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="description">{{:: 'description' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="description" name="description" data-ng-model="clientScope.description"> + </div> + <kc-tooltip>{{:: 'client-scope.description.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="protocol">{{:: 'protocol' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="protocol" + ng-change="changeProtocol()" + ng-model="protocol" + ng-options="aProtocol for aProtocol in protocols"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'client-scope.protocol.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group clearfix block" data-ng-show="protocol != 'docker-v2'"> + <label class="col-md-2 control-label" for="displayOnConsentScreen">{{:: 'client-scope.display-on-consent-screen' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="displayOnConsentScreen" ng-click="switchChange()" name="displayOnConsentScreen" id="displayOnConsentScreen" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'client-scope.display-on-consent-screen.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="protocol != 'docker-v2' && displayOnConsentScreen"> + <label class="col-md-2 control-label" for="consentScreenText">{{:: 'client-scope.consent-screen-text' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="consentScreenText" name="consentScreenText" data-ng-model="clientScope.attributes['consent.screen.text']"> + </div> + <kc-tooltip>{{:: 'client-scope.consent-screen-text.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="protocol == 'openid-connect'"> + <label class="col-md-2 control-label" for="includeInTokenScope">{{:: 'client-scope.include-in-token-scope' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="includeInTokenScope" ng-click="switchChange()" name="displayOnConsentScreen" id="includeInTokenScope" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'client-scope.include-in-token-scope.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="guiOrder">{{:: 'client-scope.gui-order' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="guiOrder" name="guiOrder" data-ng-model="clientScope.attributes['gui.order']"> + </div> + <kc-tooltip>{{:: 'client-scope.gui-order.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="create && access.manageClients"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + <div class="col-md-10 col-md-offset-2" data-ng-show="!create && access.manageClients"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-scope-list.html b/admin/resources/partials/client-scope-list.html new file mode 100644 index 0000000..1f945fc --- /dev/null +++ b/admin/resources/partials/client-scope-list.html @@ -0,0 +1,60 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1> + <span>{{:: 'client-scopes' | translate}}</span> + <kc-tooltip>{{:: 'client-scopes.tooltip' | translate}}</kc-tooltip> + </h1> + + <ul class="nav nav-tabs"> + <li class="active"> + <a href="#/realms/{{realm.realm}}/client-scopes">{{:: 'client-scopes' | translate}}</a> + <kc-tooltip>{{:: 'client-scopes.tooltip' | translate}}</kc-tooltip> + </li> + <li> + <a href="#/realms/{{realm.realm}}/default-client-scopes">{{:: 'default-client-scopes' | translate}}</a> + <kc-tooltip>{{:: 'default-client-scopes.tooltip' | translate}}</kc-tooltip> + </li> + </ul> + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="5"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" data-ng-model="search.name" class="form-control search" onkeyup="if(event.keyCode == 13){$(this).next('I').click();}"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit"></i> + </div> + </div> + </div> + + <div class="pull-right" data-ng-show="access.manageClients"> + <a id="createClient" class="btn btn-default" href="#/create/client-scope/{{realm.realm}}">{{:: 'create' | translate}}</a> + </div> + </div> + </th> + </tr> + <tr data-ng-hide="clients.length == 0"> + <th>{{:: 'name' | translate}}</th> + <th>{{:: 'protocol' | translate}}</th> + <th width="15%">{{:: 'gui-order' | translate}}</th> + <th colspan="2" class="w-25">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="clientScope in clientScopes | filter:search | orderBy:'name'"> + <td><a href="#/realms/{{realm.realm}}/client-scopes/{{clientScope.id}}">{{clientScope.name}}</a></td> + <td>{{clientScope.protocol}}</td> + <td>{{clientScope.attributes['gui.order']}}</td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/client-scopes/{{clientScope.id}}">{{:: 'edit' | translate}}</td> + <td class="kc-action-cell" data-ng-click="removeClientScope(clientScope)">{{:: 'delete' | translate}}</td> + </tr> + <tr data-ng-show="(clients | filter:search).length == 0"> + <td class="text-muted" colspan="3" data-ng-show="search.name">{{:: 'no-results' | translate}}</td> + <td class="text-muted" colspan="3" data-ng-hide="search.name">{{:: 'no-clients-available' | translate}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-scope-mappers-add.html b/admin/resources/partials/client-scope-mappers-add.html new file mode 100644 index 0000000..413c065 --- /dev/null +++ b/admin/resources/partials/client-scope-mappers-add.html @@ -0,0 +1,53 @@ +<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}}/client-scopes">{{:: 'client-scopes' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/client-scopes/{{clientScope.id}}">{{clientScope.name}}</a></li> + <li><a href="#/realms/{{realm.realm}}/client-scopes/{{clientScope.id}}/mappers">{{:: 'mappers' | translate}}</a></li> + <li class="active">{{:: 'add-builtin-protocol-mappers' | translate}}</li> + </ol> + + <h1>{{:: 'add-builtin-protocol-mapper' | translate}}</h1> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="4"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" data-ng-model="search.name" class="form-control search" onkeyup="if(event.keyCode == 13){$(this).next('I').click();}"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit"></i> + </div> + </div> + </div> + </div> + </th> + </tr> + <tr data-ng-hide="mappers.length == 0"> + <th>{{:: 'name' | translate}}</th> + <th>{{:: 'category' | translate}}</th> + <th>{{:: 'type' | translate}}</th> + <th>{{:: 'add' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="mapper in mappers | filter:search"> + <td>{{mapper.name}}</td> + <td>{{mapperTypes[mapper.protocolMapper].category}}</td> + <td>{{mapperTypes[mapper.protocolMapper].name}}</td> + <td><input type="checkbox" ng-model="mapper.isChecked" id="{{mapper.protocolMapper}}"></td> + </tr> + <tr data-ng-show="mappers.length == 0"> + <td>{{:: 'no-mappers-available' | translate}}</td> + </tr> + </tbody> + </table> + + <div data-ng-show="access.manageRealm"> + <button class="btn btn-primary" data-ng-click="add()">{{:: 'add-selected' | translate}}</button> + </div> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-scope-mappers.html b/admin/resources/partials/client-scope-mappers.html new file mode 100644 index 0000000..3b95910 --- /dev/null +++ b/admin/resources/partials/client-scope-mappers.html @@ -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}}/client-scopes">{{:: 'client-scopes' | translate}}</a></li> + <li>{{clientScope.name}}</li> + </ol> + + <kc-tabs-client-scope></kc-tabs-client-scope> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="6"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" data-ng-model="search.name" class="form-control search" onkeyup="if(event.keyCode == 13){$(this).next('I').click();}"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit"></i> + </div> + </div> + </div> + + <div class="pull-right" data-ng-show="access.manageClients"> + <a class="btn btn-default" href="#/create/client-scope/{{realm.realm}}/{{clientScope.id}}/mappers">{{:: 'create' | translate}}</a> + <a class="btn btn-default" href="#/realms/{{realm.realm}}/client-scopes/{{clientScope.id}}/add-mappers">{{:: 'add-builtin' | translate}}</a> + </div> + </div> + </th> + </tr> + <tr data-ng-hide="mappers.length == 0"> + <th>{{:: 'name' | translate}}</th> + <th>{{:: 'category' | translate}}</th> + <th>{{:: 'type' | translate}}</th> + <th>{{:: 'priority-order' | translate}}</th> + <th colspan="2">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="mapper in mappers | filter:search | orderBy:sortMappersByPriority"> + <td><a href="#/realms/{{realm.realm}}/client-scopes/{{clientScope.id}}/mappers/{{mapper.id}}">{{mapper.name}}</a></td> + <td>{{mapperTypes[mapper.protocolMapper].category}}</td> + <td>{{mapperTypes[mapper.protocolMapper].name}}</td> + <td>{{mapperTypes[mapper.protocolMapper].priority}}</td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/client-scopes/{{clientScope.id}}/mappers/{{mapper.id}}">{{:: 'edit' | translate}}</td> + <td class="kc-action-cell" data-ng-click="removeMapper(mapper)">{{:: 'delete' | translate}}</td> + </tr> + <tr data-ng-show="mappers.length == 0"> + <td>{{:: 'no-mappers-available' | translate}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-scope-mappings.html b/admin/resources/partials/client-scope-mappings.html new file mode 100644 index 0000000..1343f1b --- /dev/null +++ b/admin/resources/partials/client-scope-mappings.html @@ -0,0 +1,127 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li>{{client.clientId}}</li> + </ol> + + <kc-tabs-client></kc-tabs-client> + + <h2><span>{{client.clientId}}</span> {{:: 'scope-mappings' | translate}} </h2> + <p class="subtitle"></p> + <form class="form-horizontal" name="allowScope" novalidate kc-read-only="!client.access.manage"> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="fullScopeAllowed">{{:: 'full-scope-allowed' | translate}}</label> + <kc-tooltip>{{:: 'full-scope-allowed.tooltip' | translate}}</kc-tooltip> + <div class="col-md-6"> + <input kc-read-only="!client.access.manage" ng-model="client.fullScopeAllowed" ng-click="changeFlag()" name="fullScopeAllowed" id="fullScopeAllowed" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + </div> + </fieldset> + </form> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!client.access.manage" data-ng-hide="hideRoleSelector()"> + <div class="form-group"> + <label class="col-md-2 control-label" class="control-label">{{:: 'realm-roles' | translate}}</label> + <div class="col-md-10"> + <div class="row"> + <div class="col-md-3"> + <label class="control-label" for="available">{{:: 'available-roles' | translate}}</label> + <kc-tooltip>{{:: 'scope.available-roles.tooltip' | translate}}</kc-tooltip> + + <select id="available" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedRealmRoles"> + <option ng-repeat="r in realmRoles | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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> + </button> + </div> + <div class="col-md-3"> + <label class="control-label" for="assigned">{{:: 'assigned-roles' | translate}}</label> + <kc-tooltip>{{:: 'assigned-roles.tooltip' | translate}}</kc-tooltip> + <select id="assigned" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedRealmMappings"> + <option ng-repeat="r in realmMappings | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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}} + </button> + </div> + <div class="col-md-3"> + <label class="control-label" for="realm-composite">{{:: 'effective-roles' | translate}} </label> + <kc-tooltip>{{:: 'realm.effective-roles.tooltip' | translate}}</kc-tooltip> + <select id="realm-composite" class="form-control overflow-select" multiple size=5 + disabled="true" + ng-model="dummymodel"> + <option ng-repeat="r in realmComposite | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + </div> + </div> + </div> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="clients">{{:: 'client-roles' | translate}}</label> + <div class="col-md-6"> + <input type="hidden" ui-select2="clientsUiSelect" id="clients" data-ng-model="selectedClient" data-ng-change="selectClient(selectedClient);" data-placeholder="{{:: 'authz-select-client' | translate}}..."> + </input> + </div> + + <div class="col-md-10 col-md-offset-2"> + <div class="row" data-ng-show="selectedClient"> + <div class="col-md-3"> + <label class="control-label" for="available-client">{{:: 'available-roles' | translate}}</label> + <kc-tooltip>{{:: 'assign.available-roles.tooltip' | translate}}</kc-tooltip> + <select id="available-client" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedClientRoles"> + <option ng-repeat="r in clientRoles | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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> + </button> + </div> + <div class="col-md-3"> + <label class="control-label" for="assigned-client">{{:: 'assigned-roles' | translate}}</label> + <kc-tooltip>{{:: 'client.assigned-roles.tooltip' | translate}}</kc-tooltip> + <select id="assigned-client" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedClientMappings"> + <option ng-repeat="r in clientMappings | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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}} + </button> + </div> + <div class="col-md-3"> + <label class="control-label" for="client-composite">{{:: 'effective-roles' | translate}}</label> + <kc-tooltip>{{:: 'client.effective-roles.tooltip' | translate}}</kc-tooltip> + <select id="client-composite" class="form-control overflow-select" multiple size=5 + disabled="true" + ng-model="dummymodel"> + <option ng-repeat="r in clientComposite | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + </div> + </div> + </div> + </div> + </form> + </div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-scope-protocol-mapper-detail.html b/admin/resources/partials/client-scope-protocol-mapper-detail.html new file mode 100644 index 0000000..0f6cb5c --- /dev/null +++ b/admin/resources/partials/client-scope-protocol-mapper-detail.html @@ -0,0 +1,13 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + + <ol class="breadcrumb"> + <li><a href="#/realms/{{model.realm.realm}}/client-scopes">{{:: 'client-scopes' | translate}}</a></li> + <li><a href="#/realms/{{model.realm.realm}}/client-scopes/{{model.clientScope.id}}">{{model.clientScope.name}}</a></li> + <li><a href="#/realms/{{model.realm.realm}}/client-scopes/{{model.clientScope.id}}/mappers">{{:: 'mappers' | translate}}</a></li> + <li class="active" data-ng-show="model.create">{{:: 'create-protocol-mappers' | translate}}</li> + <li class="active" data-ng-hide="model.create">{{model.mapper.name}}</li> + </ol> + <div ng-include="resourceUrl + '/partials/protocol-mapper-detail.html'"/> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-scope-scope-mappings.html b/admin/resources/partials/client-scope-scope-mappings.html new file mode 100644 index 0000000..3180826 --- /dev/null +++ b/admin/resources/partials/client-scope-scope-mappings.html @@ -0,0 +1,116 @@ +<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}}/client-scopes">{{:: 'client-scopes' | translate}}</a></li> + <li>{{clientScope.name}}</li> + </ol> + + <kc-tabs-client-scope></kc-tabs-client-scope> + + <h2><span>{{clientScope.name}}</span> {{:: 'scope-mappings' | translate}} </h2> + <p class="subtitle"></p> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageClients"> + <div class="form-group"> + <label class="col-md-2 control-label" class="control-label">{{:: 'realm-roles' | translate}}</label> + <div class="col-md-10"> + <div class="row"> + <div class="col-md-3"> + <label class="control-label" for="available">{{:: 'available-roles' | translate}}</label> + <kc-tooltip>{{:: 'scope.available-roles.tooltip' | translate}}</kc-tooltip> + + <select id="available" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedRealmRoles"> + <option ng-repeat="r in realmRoles | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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> + </button> + </div> + <div class="col-md-3"> + <label class="control-label" for="assigned">{{:: 'assigned-roles' | translate}}</label> + <kc-tooltip>{{:: 'assigned-roles.tooltip' | translate}}</kc-tooltip> + <select id="assigned" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedRealmMappings"> + <option ng-repeat="r in realmMappings | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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}} + </button> + </div> + <div class="col-md-3"> + <label class="control-label" for="realm-composite">{{:: 'effective-roles' | translate}} </label> + <kc-tooltip>{{:: 'realm.effective-roles.tooltip' | translate}}</kc-tooltip> + <select id="realm-composite" class="form-control overflow-select" multiple size=5 + disabled="true" + ng-model="dummymodel"> + <option ng-repeat="r in realmComposite | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + </div> + </div> + </div> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="clients">{{:: 'client-roles' | translate}}</label> + <div class="col-md-6"> + <input type="hidden" ui-select2="clientsUiSelect" id="clients" data-ng-model="selectedClient" data-ng-change="changeClient(selectedClient);" data-placeholder="{{:: 'authz-select-client' | translate}}..."> + </input> + </div> + + <div class="col-md-10 col-md-push-2"> + <div class="row" data-ng-show="selectedClient"> + <div class="col-md-3"> + <label class="control-label" for="available-client">{{:: 'available-roles' | translate}}</label> + <kc-tooltip>{{:: 'assign.available-roles.tooltip' | translate}}</kc-tooltip> + <select id="available-client" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedClientRoles"> + <option ng-repeat="r in clientRoles | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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> + </button> + </div> + <div class="col-md-3"> + <label class="control-label" for="assigned-client">{{:: 'assigned-roles' | translate}}</label> + <kc-tooltip>{{:: 'client.assigned-roles.tooltip' | translate}}</kc-tooltip> + <select id="assigned-client" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedClientMappings"> + <option ng-repeat="r in clientMappings | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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}} + </button> + </div> + <div class="col-md-3"> + <label class="control-label" for="client-composite">{{:: 'effective-roles' | translate}}</label> + <kc-tooltip>{{:: 'client.effective-roles.tooltip' | translate}}</kc-tooltip> + <select id="client-composite" class="form-control overflow-select" multiple size=5 + disabled="true" + ng-model="dummymodel"> + <option ng-repeat="r in clientComposite | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + </div> + </div> + </div> + </div> + </form> + </div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-scopes-evaluate.html b/admin/resources/partials/client-scopes-evaluate.html new file mode 100644 index 0000000..cd8785e --- /dev/null +++ b/admin/resources/partials/client-scopes-evaluate.html @@ -0,0 +1,260 @@ +<!-- + ~ Copyright 2017 Red Hat, Inc. and/or its affiliates + ~ and other contributors as indicated by the @author tags. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li>{{client.clientId}}</li> + </ol> + + <kc-tabs-client></kc-tabs-client> + + <ul class="nav nav-tabs nav-tabs-pf"> + <li> + <a href="#/realms/{{realm.realm}}/clients/{{client.id}}/client-scopes/setup-scopes">{{:: 'client-scopes.setup' | translate}}</a> + <kc-tooltip>{{:: 'client-scopes.setup.tooltip' | translate}}</kc-tooltip> + </li> + <li class="active"> + <a href="#/realms/{{realm.realm}}/clients/{{client.id}}/client-scopes/evaluate-scopes">{{:: 'client-scopes.evaluate' | translate}}</a> + <kc-tooltip>{{:: 'client-scopes.evaluate.tooltip' | translate}}</kc-tooltip> + </li> + </ul> + + <form class="form-horizontal" name="evaluateForm" novalidate kc-read-only="!access.viewClients"> + <fieldset> + <div class="form-group clearfix" data-ng-show="client.protocol == 'openid-connect'"> + <label class="col-md-2 control-label" for="scopeParam">{{:: 'scope-parameter' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="scopeParam" type="text" value="{{scopeParam}}" readonly kc-select-action="click"> + </div> + <kc-tooltip>{{:: 'scope-parameter.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <div class="form-group"> + <label class="col-md-2 control-label" class="control-label">{{:: 'client-scopes.evaluate.scopes' | translate}}</label> + <kc-tooltip>{{:: 'client-scopes.evaluate.scopes.tooltip' | translate}}</kc-tooltip> + + <div class="col-md-10"> + <div class="row"> + <div class="col-md-4"> + <label class="control-label" for="available">{{:: 'client-scopes.evaluate.scopes.available' | translate}}</label> + <kc-tooltip>{{:: 'client-scopes.evaluate.scopes.available.tooltip' | translate}}</kc-tooltip> + <select id="available" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedClientScopes"> + <option ng-repeat="r in availableClientScopes | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + <button ng-disabled="selectedClientScopes.length == 0" class="btn btn-default" type="submit" ng-click="addAppliedClientScope()"> + {{:: 'add-selected' | translate}} <i class="fa fa-angle-double-right"></i> + </button> + </div> + <div class="col-md-4"> + <label class="control-label" for="assigned">{{:: 'client-scopes.evaluate.scopes.assigned' | translate}}</label> + <kc-tooltip>{{:: 'client-scopes.evaluate.scopes.assigned.tooltip' | translate}}</kc-tooltip> + <select id="assigned" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedDefClientScopes"> + <option ng-repeat="r in assignedClientScopes | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + <button ng-disabled="selectedDefClientScopes.length == 0" class="btn btn-default" type="submit" ng-click="deleteAppliedClientScope()"> + <i class="fa fa-angle-double-left"></i> {{:: 'remove-selected' | translate}} + </button> + </div> + <div class="col-md-4"> + <label class="control-label" for="assigned">{{:: 'client-scopes.evaluate.scopes.effective' | translate}}</label> + <kc-tooltip>{{:: 'client-scopes.evaluate.scopes.effective.tooltip' | translate}}</kc-tooltip> + <select id="effective" class="form-control overflow-select" multiple size=5 + disabled="true" + ng-model="dummymodel"> + <option ng-repeat="r in effectiveClientScopes | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + </div> + </div> + </div> + </div> + + <div class="form-group clearfix" data-ng-show="access.viewUsers"> + <label class="col-md-2 control-label" for="users">{{:: 'user' | translate}}</label> + + <div class="col-md-6"> + <input type="hidden" ui-select2="usersUiSelect" id="users" data-ng-model="selectedUser" data-ng-change="selectUser(selectedUser);" data-placeholder="{{:: 'authz-select-user' | translate}}..."> + </input> + </div> + + <kc-tooltip>{{:: 'client-scopes.evaluate.user.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group clearfix"> + <div class="col-md-10 col-md-offset-1" data-ng-show="client.access.view"> + <button type="submit" data-ng-click="sendEvaluationRequest()" class="btn btn-primary" tooltip-trigger="mouseover mouseout" tooltip="{{:: 'send-evaluation-request.tooltip' | translate}}" tooltip-placement="bottom">{{:: 'send-evaluation-request' | translate}}</button> + </div> + </div> + </form> + + + <ul class="nav nav-tabs nav-tabs-pf" data-ng-show="isResponseAvailable()"> + <li class="{{tabCss.tab1}}" data-ng-click="showTab(1)"> + <a href="">{{:: 'evaluated-protocol-mappers' | translate}}</a> + <kc-tooltip>{{:: 'evaluated-protocol-mappers.tooltip' | translate}}</kc-tooltip> + </li> + <li class="{{tabCss.tab2}}" data-ng-click="showTab(2)"> + <a href="">{{:: 'evaluated-roles' | translate}}</a> + <kc-tooltip>{{:: 'evaluated-roles.tooltip' | translate}}</kc-tooltip> + </li> + <li class="{{tabCss.tab3}}" data-ng-click="showTab(3)" data-ng-show="isTokenAvailable()"> + <a href="">{{:: 'generated-access-token' | translate}}</a> + <kc-tooltip>{{:: 'generated-access-token.tooltip' | translate}}</kc-tooltip> + </li> + </ul> + + <!-- Effective protocol mappers --> + <table class="table table-striped table-bordered" data-ng-show="protocolMappersShown()"> + <thead> + <tr> + <th class="kc-table-actions" colspan="4"> + <div class="form-inline"> + <div> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" data-ng-model="search.mapperName" class="form-control search" onkeyup="if(event.keyCode == 13){$(this).next('I').click();}"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit"></i> + </div> + </div> + </div> + </div> + </th> + </tr> + <tr data-ng-hide="protocolMappers.length == 0"> + <th>{{:: 'name' | translate}}</th> + <th>{{:: 'parent-client-scope' | translate}}</th> + <th>{{:: 'category' | translate}}</th> + <th>{{:: 'type' | translate}}</th> + <th>{{:: 'priority-order' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="mapper in protocolMappers | filter:search | orderBy:sortMappersByPriority"> + <td><a href="#/realms/{{realm.realm}}/{{mapper.containerType}}s/{{mapper.containerId}}/mappers/{{mapper.mapperId}}">{{mapper.mapperName}}</a></td> + <td><a href="#/realms/{{realm.realm}}/{{mapper.containerType}}s/{{mapper.containerId}}">{{mapper.containerName}}</a></td> + <td>{{mapperTypes[mapper.protocolMapper].category}}</td> + <td>{{mapperTypes[mapper.protocolMapper].name}}</td> + <td>{{mapperTypes[mapper.protocolMapper].priority}}</td> + </tr> + <tr data-ng-show="mappers.length == 0"> + <td>{{:: 'no-mappers-available' | translate}}</td> + </tr> + </tbody> + </table> + + + <!-- Effective role scope mappings --> + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.viewClients"> + <div class="form-group" data-ng-show="rolesShown()"> + <label class="col-md-2 control-label" class="control-label">{{:: 'realm-roles' | translate}}</label> + <div class="col-md-10"> + <div class="row"> + <div class="col-md-4"> + <label class="control-label" for="available-realm-roles">{{:: 'client-scopes.evaluate.not-granted-roles' | translate}}</label> + <kc-tooltip>{{:: 'client-scopes.evaluate.not-granted-roles.tooltip' | translate}}</kc-tooltip> + + <select id="available-realm-roles" class="form-control overflow-select" multiple size="5" + disabled="true" + ng-model="dummymodel1"> + <option ng-repeat="r in notGrantedRealmRoles | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + </div> + <div class="col-md-4"> + <label class="control-label" for="realm-composite">{{:: 'client-scopes.evaluate.granted-realm-effective-roles' | translate}} </label> + <kc-tooltip>{{:: 'client-scopes.evaluate.granted-realm-effective-roles.tooltip' | translate}}</kc-tooltip> + <select id="realm-composite" class="form-control overflow-select" multiple size=5 + disabled="true" + ng-model="dummymodel2"> + <option ng-repeat="r in grantedRealmRoles | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + </div> + </div> + </div> + </div> + + <div class="form-group" data-ng-show="rolesShown()"> + <label class="col-md-2 control-label" for="clients">{{:: 'client-roles' | translate}}</label> + <div class="col-md-6"> + <input type="hidden" ui-select2="clientsUiSelect" id="clients" data-ng-model="selectedClient" data-ng-change="selectClient(selectedClient);" data-placeholder="{{:: 'authz-select-client' | translate}}..."> + </input> + </div> + + <div class="col-md-10 col-md-offset-2"> + <div class="row" data-ng-show="selectedClient"> + <div class="col-md-4"> + <label class="control-label" for="available-client">{{:: 'client-scopes.evaluate.not-granted-roles' | translate}}</label> + <kc-tooltip>{{:: 'client-scopes.evaluate.not-granted-roles.tooltip' | translate}}</kc-tooltip> + <select id="available-client" class="form-control overflow-select" multiple size="5" + disabled="true" + ng-model="dummymodel"> + <option ng-repeat="r in notGrantedClientRoles | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + </div> + <div class="col-md-4"> + <label class="control-label" for="client-composite">{{:: 'client-scopes.evaluate.granted-client-effective-roles' | translate}}</label> + <kc-tooltip>{{:: 'client-scopes.evaluate.granted-realm-effective-roles.tooltip' | translate}}</kc-tooltip> + <select id="client-composite" class="form-control overflow-select" multiple size=5 + disabled="true" + ng-model="dummymodel"> + <option ng-repeat="r in grantedClientRoles | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + </div> + </div> + </div> + </div> + </form> + + + <!-- Access token --> + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.viewClients"> + <div class="form-group"> + <div class="col-md-10 col-md-offset-1" data-ng-show="tokenShown()"> + <textarea class="form-control" rows="20" kc-select-action="click" readonly>{{oidcAccessToken}}</textarea> + </div> + </div> + </form> + +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-scopes-realm-default.html b/admin/resources/partials/client-scopes-realm-default.html new file mode 100644 index 0000000..e30570a --- /dev/null +++ b/admin/resources/partials/client-scopes-realm-default.html @@ -0,0 +1,99 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1> + <span>{{:: 'default-client-scopes' | translate}}</span> + <kc-tooltip>{{:: 'default-client-scopes.tooltip' | translate}}</kc-tooltip> + </h1> + + <ul class="nav nav-tabs"> + <li> + <a href="#/realms/{{realm.realm}}/client-scopes">{{:: 'client-scopes' | translate}}</a> + <kc-tooltip>{{:: 'client-scopes.tooltip' | translate}}</kc-tooltip> + </li> + <li class="active"> + <a href="#/realms/{{realm.realm}}/default-client-scopes">{{:: 'default-client-scopes' | translate}}</a> + <kc-tooltip>{{:: 'default-client-scopes.tooltip' | translate}}</kc-tooltip> + </li> + </ul> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageClients"> + <div class="form-group"> + <label class="col-md-2 control-label" class="control-label">{{:: 'default-client-scopes.default' | translate}}</label> + <kc-tooltip>{{:: 'default-client-scopes.default.tooltip' | translate}}</kc-tooltip> + + <div class="col-md-10"> + <div class="row"> + <div class="col-md-4"> + <label class="control-label" for="available">{{:: 'default-client-scopes.default.available' | translate}}</label> + <kc-tooltip>{{:: 'default-client-scopes.default.available.tooltip' | translate}}</kc-tooltip> + <select id="available" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedDefaultClientScopes"> + <option ng-repeat="r in availableClientScopes | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + <button ng-disabled="selectedDefaultClientScopes.length == 0" class="btn btn-default" type="submit" ng-click="addDefaultClientScope()"> + {{:: 'add-selected' | translate}} <i class="fa fa-angle-double-right"></i> + </button> + </div> + <div class="col-md-4"> + <label class="control-label" for="assigned">{{:: 'default-client-scopes.default.assigned' | translate}}</label> + <kc-tooltip>{{:: 'default-client-scopes.default.assigned.tooltip' | translate}}</kc-tooltip> + <select id="assigned" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedDefDefaultClientScopes"> + <option ng-repeat="r in realmDefaultClientScopes | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + <button ng-disabled="selectedDefDefaultClientScopes.length == 0" class="btn btn-default" type="submit" ng-click="deleteDefaultClientScope()"> + <i class="fa fa-angle-double-left"></i> {{:: 'remove-selected' | translate}} + </button> + </div> + </div> + </div> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" class="control-label">{{:: 'default-client-scopes.optional' | translate}}</label> + <kc-tooltip>{{:: 'default-client-scopes.optional.tooltip' | translate}}</kc-tooltip> + + <div class="col-md-10"> + <div class="row"> + <div class="col-md-4"> + <label class="control-label" for="available-opt">{{:: 'default-client-scopes.optional.available' | translate}}</label> + <kc-tooltip>{{:: 'default-client-scopes.optional.available.tooltip' | translate}}</kc-tooltip> + <select id="available-opt" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedOptionalClientScopes"> + <option ng-repeat="r in availableClientScopes | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + <button ng-disabled="selectedOptionalClientScopes.length == 0" class="btn btn-default" type="submit" ng-click="addOptionalClientScope()"> + {{:: 'add-selected' | translate}} <i class="fa fa-angle-double-right"></i> + </button> + </div> + <div class="col-md-4"> + <label class="control-label" for="assigned-opt">{{:: 'default-client-scopes.optional.assigned' | translate}}</label> + <kc-tooltip>{{:: 'default-client-scopes.optional.assigned.tooltip' | translate}}</kc-tooltip> + <select id="assigned-opt" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedDefOptionalClientScopes"> + <option ng-repeat="r in realmOptionalClientScopes | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + <button ng-disabled="selectedDefOptionalClientScopes.length == 0" class="btn btn-default" type="submit" ng-click="deleteOptionalClientScope()"> + <i class="fa fa-angle-double-left"></i> {{:: 'remove-selected' | translate}} + </button> + </div> + </div> + </div> + </div> + + </form> + +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-scopes-setup.html b/admin/resources/partials/client-scopes-setup.html new file mode 100644 index 0000000..db39cf0 --- /dev/null +++ b/admin/resources/partials/client-scopes-setup.html @@ -0,0 +1,123 @@ +<!-- + ~ Copyright 2017 Red Hat, Inc. and/or its affiliates + ~ and other contributors as indicated by the @author tags. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li>{{client.clientId}}</li> + </ol> + + <kc-tabs-client></kc-tabs-client> + + <ul class="nav nav-tabs nav-tabs-pf"> + <li class="active"> + <a href="#/realms/{{realm.realm}}/clients/{{client.id}}/client-scopes/setup-scopes">{{:: 'client-scopes.setup' | translate}}</a> + <kc-tooltip>{{:: 'client-scopes.setup.tooltip' | translate}}</kc-tooltip> + </li> + <li> + <a href="#/realms/{{realm.realm}}/clients/{{client.id}}/client-scopes/evaluate-scopes">{{:: 'client-scopes.evaluate' | translate}}</a> + <kc-tooltip>{{:: 'client-scopes.evaluate.tooltip' | translate}}</kc-tooltip> + </li> + </ul> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageClients"> + <div class="form-group"> + <label class="col-md-2 control-label" class="control-label">{{:: 'client-scopes.default' | translate}}</label> + <kc-tooltip>{{:: 'client-scopes.default.tooltip' | translate}}</kc-tooltip> + + <div class="col-md-10"> + <div class="row"> + <div class="col-md-4"> + <label class="control-label" for="available">{{:: 'client-scopes.default.available' | translate}}</label> + <kc-tooltip>{{:: 'client-scopes.default.available.tooltip' | translate}}</kc-tooltip> + <select id="available" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedDefaultClientScopes"> + <option ng-repeat="r in availableClientScopes | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + <button ng-disabled="selectedDefaultClientScopes.length == 0" class="btn btn-default" type="submit" ng-click="addDefaultClientScope()"> + {{:: 'add-selected' | translate}} <i class="fa fa-angle-double-right"></i> + </button> + </div> + <div class="col-md-4"> + <label class="control-label" for="assigned">{{:: 'client-scopes.default.assigned' | translate}}</label> + <kc-tooltip>{{:: 'client-scopes.default.assigned.tooltip' | translate}}</kc-tooltip> + <select id="assigned" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedDefDefaultClientScopes"> + <option ng-repeat="r in clientDefaultClientScopes | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + <button ng-disabled="selectedDefDefaultClientScopes.length == 0" class="btn btn-default" type="submit" ng-click="deleteDefaultClientScope()"> + <i class="fa fa-angle-double-left"></i> {{:: 'remove-selected' | translate}} + </button> + </div> + </div> + </div> + </div> + + <div class="form-group" data-ng-show="client.protocol == 'openid-connect'"> + <label class="col-md-2 control-label" class="control-label">{{:: 'client-scopes.optional' | translate}}</label> + <kc-tooltip>{{:: 'client-scopes.optional.tooltip' | translate}}</kc-tooltip> + + <div class="col-md-10"> + <div class="row"> + <div class="col-md-4"> + <label class="control-label" for="available-opt">{{:: 'client-scopes.optional.available' | translate}}</label> + <kc-tooltip>{{:: 'client-scopes.optional.available.tooltip' | translate}}</kc-tooltip> + <select id="available-opt" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedOptionalClientScopes"> + <option ng-repeat="r in availableClientScopes | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + <button ng-disabled="selectedOptionalClientScopes.length == 0" class="btn btn-default" type="submit" ng-click="addOptionalClientScope()"> + {{:: 'add-selected' | translate}} <i class="fa fa-angle-double-right"></i> + </button> + </div> + <div class="col-md-4"> + <label class="control-label" for="assigned-opt">{{:: 'client-scopes.optional.assigned' | translate}}</label> + <kc-tooltip>{{:: 'client-scopes.optional.assigned.tooltip' | translate}}</kc-tooltip> + <select id="assigned-opt" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedDefOptionalClientScopes"> + <option ng-repeat="r in clientOptionalClientScopes | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + <button ng-disabled="selectedDefOptionalClientScopes.length == 0" class="btn btn-default" type="submit" ng-click="deleteOptionalClientScope()"> + <i class="fa fa-angle-double-left"></i> {{:: 'remove-selected' | translate}} + </button> + </div> + </div> + </div> + </div> + + </form> + +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-service-account-roles.html b/admin/resources/partials/client-service-account-roles.html new file mode 100644 index 0000000..bc17f1b --- /dev/null +++ b/admin/resources/partials/client-service-account-roles.html @@ -0,0 +1,127 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li>{{client.clientId}}</li> + </ol> + + <kc-tabs-client></kc-tabs-client> + + <h2><span>{{client.clientId}}</span> {{:: 'service-accounts' | translate}} </h2> + <p class="subtitle"></p> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!client.access.configure" data-ng-show="client.serviceAccountsEnabled"> + <div class="form-group"> + <label class="col-md-2 control-label" class="control-label">{{:: 'realm-roles' | translate}}</label> + <div class="col-md-10"> + <div class="row"> + <div class="col-md-3"> + <label class="control-label" for="available">{{:: 'available-roles' | translate}}</label> + <kc-tooltip>{{:: 'service-account.available-roles.tooltip' | translate}}</kc-tooltip> + + <select id="available" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedRealmRoles"> + <option ng-repeat="r in realmRoles | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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> + </button> + </div> + <div class="col-md-3"> + <label class="control-label" for="assigned">{{:: 'assigned-roles' | translate}}</label> + <kc-tooltip>{{:: 'service-account.assigned-roles.tooltip' | translate}}</kc-tooltip> + <select id="assigned" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedRealmMappings"> + <option ng-repeat="r in realmMappings | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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}} + </button> + </div> + <div class="col-md-3"> + <label class="control-label" for="realm-composite">{{:: 'effective-roles' | translate}} </label> + <kc-tooltip>{{:: 'realm.effective-roles.tooltip' | translate}}</kc-tooltip> + <select id="realm-composite" class="form-control overflow-select" multiple size=5 + disabled="true" + ng-model="dummymodel"> + <option ng-repeat="r in realmComposite | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + </div> + </div> + </div> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="clients">{{:: 'client-roles' | translate}}</label> + <div class="col-md-6"> + <input type="hidden" ui-select2="clientsUiSelect" id="clients" data-ng-model="selectedClient" data-ng-change="changeClient(selectedClient);" data-placeholder="{{:: 'authz-select-client' | translate}}..."> + </input> + </div> + + <div class="col-md-10 col-md-push-2"> + <div class="row" data-ng-show="selectedClient"> + <div class="col-md-3"> + <label class="control-label" for="available-client">{{:: 'available-roles' | translate}}</label> + <kc-tooltip>{{:: 'assign.available-roles.tooltip' | translate}}</kc-tooltip> + <select id="available-client" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedClientRoles"> + <option ng-repeat="r in clientRoles | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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> + </button> + </div> + <div class="col-md-3"> + <label class="control-label" for="assigned-client">{{:: 'assigned-roles' | translate}}</label> + <kc-tooltip>{{:: 'client.assigned-roles.tooltip' | translate}}</kc-tooltip> + <select id="assigned-client" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedClientMappings"> + <option ng-repeat="r in clientMappings | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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}} + </button> + </div> + <div class="col-md-3"> + <label class="control-label" for="client-composite">{{:: 'effective-roles' | translate}}</label> + <kc-tooltip>{{:: 'client.effective-roles.tooltip' | translate}}</kc-tooltip> + <select id="client-composite" class="form-control overflow-select" multiple size=5 + disabled="true" + ng-model="dummymodel"> + <option ng-repeat="r in clientComposite | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + </div> + </div> + </div> + </div> + </form> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!client.access.configure" data-ng-show="!client.serviceAccountsEnabled"> + <legend><span class="text" translate="service-account-is-not-enabled-for" translate-values="{client: client.clientId}"></span></legend> + </form> + +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-sessions.html b/admin/resources/partials/client-sessions.html new file mode 100644 index 0000000..5dbb2af --- /dev/null +++ b/admin/resources/partials/client-sessions.html @@ -0,0 +1,57 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li>{{client.clientId}}</li> + </ol> + + <kc-tabs-client></kc-tabs-client> + + <form class="form-horizontal" name="sessionStats"> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="activeSessions">{{:: 'active-sessions' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" id="activeSessions" name="activeSessions" data-ng-model="count" ng-disabled="true"> + </div> + <kc-tooltip>{{:: 'active-sessions.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + </form> + <table class="table table-striped table-bordered" data-ng-show="count > 0"> + <thead> + <tr> + <th class="kc-table-actions" colspan="3"> + <div class="pull-right"> + <a class="btn btn-default" ng-click="loadUsers()" tooltip-placement="left" tooltip-trigger="mouseover mouseout" tooltip="{{:: 'show-sessions.tooltip' | translate}}">{{:: 'show-sessions' | translate}}</a> + </div> + </th> + </tr> + <tr data-ng-show="sessions"> + <th>{{:: 'user' | translate}}</th> + <th>{{:: 'from-ip' | translate}}</th> + <th>{{:: 'session-start' | translate}}</th> + </tr> + </thead> + <tfoot data-ng-show="sessions && (sessions.length >= 5 || query.first != 0)"> + <tr> + <td colspan="7"> + <div class="table-nav"> + <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button> + <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button> + <button data-ng-click="nextPage()" class="next" ng-disabled="sessions.length < query.max">{{:: 'next-page' | translate}}</button> + </div> + </td> + </tr> + </tfoot> + <tbody> + <tr data-ng-repeat="session in sessions"> + <td><a href="#/realms/{{realm.realm}}/users/{{session.userId}}">{{session.username}}</a></td> + <td>{{session.ipAddress}}</td> + <td>{{session.start | date:'medium'}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-storage-generic.html b/admin/resources/partials/client-storage-generic.html new file mode 100644 index 0000000..90ed088 --- /dev/null +++ b/admin/resources/partials/client-storage-generic.html @@ -0,0 +1,207 @@ +<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}}/client-stores">{{:: 'client-storage' | translate}}</a></li> + <li data-ng-hide="create">{{instance.name|capitalize}}</li> + <li data-ng-show="create">{{:: 'add-client-storage-provider' | translate}}</li> + </ol> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <fieldset> + <legend><span class="text">{{:: 'required-settings' | translate}}</span></legend> + <div class="form-group clearfix" data-ng-show="!create"> + <label class="col-md-2 control-label" for="providerId">{{:: 'provider-id' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="providerId" type="text" ng-model="instance.id" readonly> + </div> + </div> + <div class="form-group clearfix block"> + <label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label> + <div class="col-md-6"> + <input ng-model="instance.config['enabled'][0]" name="enabled" id="enabled" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'client-storage.enabled.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="consoleDisplayName">{{:: 'console-display-name' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="consoleDisplayName" type="text" ng-model="instance.name" placeholder="{{:: 'defaults-to-id' | translate}}"> + </div> + <kc-tooltip>{{:: 'console-display-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="priority">{{:: 'priority' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="priority" type="text" ng-model="instance.config['priority'][0]"> + </div> + <kc-tooltip>{{:: 'priority.tooltip' | translate}}</kc-tooltip> + </div> + + <kc-component-config realm="realm" config="instance.config" properties="providerFactory.properties"></kc-component-config> + + </fieldset> + + <fieldset> + <legend><span class="text">{{:: 'client-storage-cache-policy' | translate}}</span></legend> + <div class="form-group"> + <label for="cachePolicy" class="col-md-2 control-label">{{:: 'clientStorage.cachePolicy' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="cachePolicy" ng-model="instance.config['cachePolicy'][0]" class="form-control"> + <option value="DEFAULT">{{:: 'clientStorage.cachePolicy.option.DEFAULT' | translate}}</option> + <option value="EVICT_DAILY">{{:: 'clientStorage.cachePolicy.option.EVICT_DAILY' | translate}}</option> + <option value="EVICT_WEEKLY">{{:: 'clientStorage.cachePolicy.option.EVICT_WEEKLY' | translate}}</option> + <option value="MAX_LIFESPAN">{{:: 'clientStorage.cachePolicy.option.MAX_LIFESPAN' | translate}}</option> + <option value="NO_CACHE">{{:: 'clientStorage.cachePolicy.option.NO_CACHE' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'clientStorage.cachePolicy.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="instance.config['cachePolicy'][0] == 'EVICT_WEEKLY'"> + <label for="evictionDay" class="col-md-2 control-label">{{:: 'clientStorage.cachePolicy.evictionDay' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="evictionDay" ng-model="instance.config['evictionDay'][0]" class="form-control"> + <option value="1">{{:: 'Sunday' | translate}}</option> + <option value="2">{{:: 'Monday' | translate}}</option> + <option value="3">{{:: 'Tuesday' | translate}}</option> + <option value="4">{{:: 'Wednesday' | translate}}</option> + <option value="5">{{:: 'Thursday' | translate}}</option> + <option value="6">{{:: 'Friday' | translate}}</option> + <option value="7">{{:: 'Saturday' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'clientStorage.cachePolicy.evictionDay.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['cachePolicy'][0] == 'EVICT_WEEKLY' || instance.config['cachePolicy'][0] == 'EVICT_DAILY'"> + <label class="col-md-2 control-label" for="evictionHour">{{:: 'clientStorage.cachePolicy.evictionHour' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="evictionHour" ng-model="instance.config['evictionHour'][0]" class="form-control"> + <option value="0">00</option> + <option value="1">01</option> + <option value="2">02</option> + <option value="3">03</option> + <option value="4">04</option> + <option value="5">05</option> + <option value="6">06</option> + <option value="7">07</option> + <option value="8">08</option> + <option value="9">09</option> + <option value="10">10</option> + <option value="11">11</option> + <option value="12">12</option> + <option value="13">13</option> + <option value="14">14</option> + <option value="15">15</option> + <option value="16">16</option> + <option value="17">17</option> + <option value="18">18</option> + <option value="19">19</option> + <option value="20">20</option> + <option value="21">21</option> + <option value="22">22</option> + <option value="23">23</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'clientStorage.cachePolicy.evictionHour.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['cachePolicy'][0] == 'EVICT_WEEKLY' || instance.config['cachePolicy'][0] == 'EVICT_DAILY'"> + <label class="col-md-2 control-label" for="evictionMinute">{{:: 'clientStorage.cachePolicy.evictionMinute' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="evictionMinute" ng-model="instance.config['evictionMinute'][0]" class="form-control"> + <option value="0">00</option> + <option value="1">01</option> + <option value="2">02</option> + <option value="3">03</option> + <option value="4">04</option> + <option value="5">05</option> + <option value="6">06</option> + <option value="7">07</option> + <option value="8">08</option> + <option value="9">09</option> + <option value="10">10</option> + <option value="11">11</option> + <option value="12">12</option> + <option value="13">13</option> + <option value="14">14</option> + <option value="15">15</option> + <option value="16">16</option> + <option value="17">17</option> + <option value="18">18</option> + <option value="19">19</option> + <option value="20">20</option> + <option value="21">21</option> + <option value="22">22</option> + <option value="23">23</option> + <option value="24">24</option> + <option value="25">25</option> + <option value="26">26</option> + <option value="27">27</option> + <option value="28">28</option> + <option value="29">29</option> + <option value="30">30</option> + <option value="31">31</option> + <option value="32">32</option> + <option value="33">33</option> + <option value="34">34</option> + <option value="35">35</option> + <option value="36">36</option> + <option value="37">37</option> + <option value="38">38</option> + <option value="39">39</option> + <option value="40">40</option> + <option value="41">41</option> + <option value="42">42</option> + <option value="43">43</option> + <option value="44">44</option> + <option value="45">45</option> + <option value="46">46</option> + <option value="47">47</option> + <option value="48">48</option> + <option value="49">49</option> + <option value="50">50</option> + <option value="51">51</option> + <option value="52">52</option> + <option value="53">53</option> + <option value="54">54</option> + <option value="55">55</option> + <option value="56">56</option> + <option value="57">57</option> + <option value="58">58</option> + <option value="59">59</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'clientStorage.cachePolicy.evictionMinute.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['cachePolicy'][0] == 'MAX_LIFESPAN'"> + <label class="col-md-2 control-label" for="maxLifespan">{{:: 'clientStorage.cachePolicy.maxLifespan' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" ng-model="instance.config['maxLifespan'][0]" id="maxLifespan" /> + </div> + <kc-tooltip>{{:: 'clientStorage.cachePolicy.maxLifespan.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="create && access.manageRealm"> + <button kc-save>{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="!create && access.manageRealm"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/client-storage-list.html b/admin/resources/partials/client-storage-list.html new file mode 100644 index 0000000..c111eaa --- /dev/null +++ b/admin/resources/partials/client-storage-list.html @@ -0,0 +1,67 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + + <kc-tabs-clients></kc-tabs-clients> + + <div class="blank-slate-pf" data-ng-hide="!instancesLoaded || (instances && instances.length > 0)"> + <div class="blank-slate-pf-icon"> + <span class="fa fa-database"></span> + </div> + <h1> + {{:: 'client-storage' | translate}} + </h1> + {{:: 'client-storage-list-no-entries' | translate}} + <div class="blank-slate-pf-main-action"> + <div class="row" data-ng-show="access.manageRealm"> + <div class="col-sm-4 col-sm-offset-4"> + <div class="form-group"> + <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> + </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.manageRealm"> + <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>{{:: 'enabled' | 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>{{isProviderEnabled(instance)}}</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-client-storage-providers-configured' | translate}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/create-client.html b/admin/resources/partials/create-client.html new file mode 100644 index 0000000..0c47b31 --- /dev/null +++ b/admin/resources/partials/create-client.html @@ -0,0 +1,72 @@ +<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}}/clients">{{:: 'clients' | translate}}</a></li> + <li>{{:: 'add-client' | translate}}</li> + </ol> + + <kc-tabs-client></kc-tabs-client> + + <form class="form-horizontal" name="clientForm" novalidate kc-read-only="!access.manageClients"> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-sm-2 control-label">{{:: 'import' | translate}}</label> + + <div class="col-md-6" data-ng-hide="importing"> + <label for="import-file" class="btn btn-default">{{:: 'select-file' | translate}} <i class="pficon pficon-import"></i></label> + <input id="import-file" type="file" class="hidden" kc-on-read-file="importFile($fileContent)"> + </div> + + <div class="col-md-6" data-ng-show="importing"> + <button class="btn btn-default" type="button" data-ng-click="viewImportDetails()">{{:: 'view-details' | translate}}</button> + <button class="btn btn-default" type="button" data-ng-click="reset()">{{:: 'clear-import' | translate}}</button> + </div> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="clientId">{{:: 'client-id' | translate}} <span class="required">*</span></label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="clientId" name="clientId" data-ng-model="client.clientId" autofocus required> + </div> + <kc-tooltip>{{:: 'client-id.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="protocol">{{:: 'client-protocol' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="protocol" + ng-change="changeProtocol()" + ng-model="protocol" + ng-options="aProtocol for aProtocol in protocols" + ng-disabled="client.clientTemplate"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'client-protocol.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-hide="protocol == 'saml'"> + <label class="col-md-2 control-label" for="rootUrl">{{:: 'root-url' | translate}}</label> + <div class="col-sm-6"> + <input class="form-control" type="text" name="rootUrl" id="rootUrl" data-ng-model="client.rootUrl"> + </div> + <kc-tooltip>{{:: 'root-url.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="protocol == 'saml'"> + <label class="col-md-2 control-label" for="masterSamlUrl">{{:: 'client-saml-endpoint' | translate}}</label> + <div class="col-sm-6"> + <input class="form-control" type="text" name="masterSamlUrl" id="masterSamlUrl" + data-ng-model="client.adminUrl"> + </div> + <kc-tooltip>{{:: 'master-saml-processing-url.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="access.manageClients"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/create-execution.html b/admin/resources/partials/create-execution.html new file mode 100644 index 0000000..d68dc9c --- /dev/null +++ b/admin/resources/partials/create-execution.html @@ -0,0 +1,31 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + + <div> + <h1 data-ng-show="parentFlow.providerId == 'basic-flow'">{{:: 'create-authenticator-execution' | translate}}</h1> + <h1 data-ng-show="parentFlow.providerId == 'client-flow'">{{:: 'create-authenticator-execution' | translate}}</h1> + <h1 data-ng-show="parentFlow.providerId == 'for-flow'">{{:: 'create-form-action-execution' | translate}}</h1> + </div> + <kc-tabs-authentication></kc-tabs-authentication> + <form class="form-horizontal" name="clientForm" novalidate kc-read-only="!access.manageRealm"> + <div class="form-group"> + <label class="col-md-2 control-label" for="provider">{{:: 'provider' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="provider" + ng-model="provider" + ng-options="provider.displayName|capitalize for provider in providers | orderBy:'displayName'"> + </select> + </div> + </div> + <kc-tooltip>{{provider.description}}</kc-tooltip> + </div> + <div class="form-group"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save>{{:: 'save' | translate}}</button> + <button type="button" class="btn btn-default" ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/create-flow-execution.html b/admin/resources/partials/create-flow-execution.html new file mode 100644 index 0000000..195a7ff --- /dev/null +++ b/admin/resources/partials/create-flow-execution.html @@ -0,0 +1,55 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1>{{:: 'create-execution-flow' | translate}}</h1> + + <kc-tabs-authentication></kc-tabs-authentication> + + <form class="form-horizontal" name="clientForm" novalidate kc-read-only="!access.manageRealm"> + <div class="form-group"> + <label class="col-md-2 control-label" for="alias">{{:: 'alias' | translate}} </label> + <div class="col-sm-6"> + <input class="form-control" type="text" id="alias" name="alias" data-ng-model="flow.alias" autofocus required> + </div> + <kc-tooltip>{{:: 'flow.alias.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="description">{{:: 'description' | translate}} </label> + + <div class="col-md-6"> + <textarea class="form-control" rows="5" cols="50" id="description" name="description" data-ng-model="flow.description"></textarea> + </div> + </div> + <div class="form-group" data-ng-hide="flow.type == 'client-flow'"> + <label class="col-md-2 control-label" for="flowType">{{:: 'flow-type' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="flowType" + ng-model="flow.type"> + <option value="basic-flow">{{:: 'flow.generic.type' | translate}}</option> + <option value="form-flow">{{:: 'flow.form.type' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'flow-type.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="flow.type == 'form-flow'"> + <label class="col-md-2 control-label" for="provider">{{:: 'form-provider' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="provider" + ng-model="provider" + ng-options="provider.id for provider in formProviders"> + </select> + </div> + </div> + <kc-tooltip>{{provider.description}}</kc-tooltip> + </div> + <div class="form-group"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save>{{:: 'save' | translate}}</button> + <button type="button" class="btn btn-default" ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/create-flow.html b/admin/resources/partials/create-flow.html new file mode 100644 index 0000000..efd34e9 --- /dev/null +++ b/admin/resources/partials/create-flow.html @@ -0,0 +1,43 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1>{{:: 'create-top-level-form' | translate}}</h1> + + <kc-tabs-authentication></kc-tabs-authentication> + + <form class="form-horizontal" name="clientForm" novalidate kc-read-only="!access.manageRealm"> + <div class="form-group"> + <label class="col-md-2 control-label" for="alias">{{:: 'alias' | translate}} </label> + <div class="col-sm-6"> + <input kc-no-reserved-chars class="form-control" type="text" id="alias" name="alias" data-ng-model="flow.alias" autofocus required> + </div> + <kc-tooltip>{{:: 'flow.alias.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="description">{{:: 'description' | translate}} </label> + + <div class="col-md-6"> + <textarea class="form-control" rows="5" cols="50" id="description" name="description" data-ng-model="flow.description"></textarea> + </div> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="flowType">{{:: 'top-level-flow-type' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="flowType" + ng-model="flow.providerId"> + <option value="basic-flow">{{:: 'flow.generic' | translate}}</option> + <option value="client-flow">{{:: 'flow.client' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'top-level-flow-type.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save>{{:: 'save' | translate}}</button> + <button type="button" class="btn btn-default" ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/create-group.html b/admin/resources/partials/create-group.html new file mode 100644 index 0000000..255cf32 --- /dev/null +++ b/admin/resources/partials/create-group.html @@ -0,0 +1,25 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <div> + <h1>{{:: 'create-group' | translate}}</h1> + </div> + <form class="form-horizontal" name="clientForm" novalidate> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label"for="name">{{:: 'name' | translate}} <span class="required">*</span></label> + <div class="col-md-6"> + <input class="form-control" type="text" id="name" name="name" data-ng-model="group.name" autofocus + required > + </div> + </div> + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save>{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/default-groups.html b/admin/resources/partials/default-groups.html new file mode 100644 index 0000000..8d0866e --- /dev/null +++ b/admin/resources/partials/default-groups.html @@ -0,0 +1,91 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <kc-tabs-group-list></kc-tabs-group-list> + + <form class="form-horizontal" name="realmForm" novalidate> + <div class="form-group" kc-read-only="!access.manageRealm"> + <label class="col-md-1 control-label" class="control-label"></label> + + <div class="col-md-8" > + <div class="row"> + <div class="col-md-5"> + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="5"> + <div class="form-inline"> + <label class="control-label">{{:: 'default-groups' | translate}}</label> + <kc-tooltip>{{:: 'default-groups.tooltip' | translate}}</kc-tooltip> + + <div class="pull-right" data-ng-show="access.manageRealm"> + <button id="removeDefaultGroup" class="btn btn-default" ng-click="removeDefaultGroup()">{{:: 'remove' | translate}}</button> + </div> + </div> + </th> + </tr> + </thead> + <tbody> + <tr> + <td> + <select id="defaultGroups" class="form-control" size=5 + ng-model="selectedGroup" + ng-options="r.path for r in defaultGroups"> + <option style="display:none" value="">{{:: 'select-a-type.placeholder' | translate}}</option> + </select> + </td> + </tr> + </tbody> + </table> + </div> + <div class="col-md-5"> + <table class="table table-striped table-bordered" style="margin-bottom: 0"> + <thead> + <tr> + <th class="kc-table-actions" colspan="5"> + <div class="form-inline"> + <div> + <label class="control-label">{{:: 'available-groups' | translate}}</label> + <kc-tooltip>{{:: 'available-groups.tooltip' | translate}}</kc-tooltip> + </div> + <div class="pull-left"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" ng-model="searchCriteria" class="form-control search" onkeydown="if (event.keyCode == 13) document.getElementById('groupSearch').click()"> + <div class="input-group-addon"> + <i class="fa fa-search" id="groupSearch" ng-click="searchGroup()"></i> + </div> + </div> + </div> + + <button id="viewAllGroups" class="btn btn-default" ng-click="clearSearch()">{{:: 'view-all-groups' | translate}}</button> + <div class="pull-right" data-ng-show="access.manageRealm"> + <button id="addDefaultGroup" class="btn btn-default" ng-click="addDefaultGroup()">{{:: 'add' | translate}}</button> + </div> + </div> + </th> + </tr> + </thead> + <tbody> + <tr> + <td> + <div + tree-id="tree" + angular-treeview="true" + tree-model="groupList" + node-id="id" + node-label="name" + node-children="subGroups" > + </div> + </td> + </tr> + </tbody> + </table> + <div style="margin-bottom: 50px"> + <kc-paging current-page="currentPage" number-of-pages="numberOfPages" current-page-input="currentPageInput"></kc-paging> + </div> + </div> + </div> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/defense-headers.html b/admin/resources/partials/defense-headers.html new file mode 100644 index 0000000..51acdf1 --- /dev/null +++ b/admin/resources/partials/defense-headers.html @@ -0,0 +1,71 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <kc-tabs-realm></kc-tabs-realm> + + <ul class="nav nav-tabs nav-tabs-pf"> + <li class="active"><a href="#/realms/{{realm.realm}}/defense/headers">{{:: 'headers' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/defense/brute-force">{{:: 'brute-force-detection' | translate}}</a></li> + </ul> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="xFrameOptions"><a href="http://tools.ietf.org/html/rfc7034" target="_blank">{{:: 'x-frame-options' | translate}}</a></label> + <div class="col-sm-6"> + <input class="form-control" id="xFrameOptions" type="text" ng-model="realm.browserSecurityHeaders.xFrameOptions"> + </div> + <kc-tooltip>{{:: 'x-frame-options-tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="contentSecurityPolicy"><a href="http://www.w3.org/TR/CSP/" target="_blank">{{:: 'content-sec-policy' | translate}}</a></label> + <div class="col-sm-6"> + <input class="form-control" id="contentSecurityPolicy" type="text" ng-model="realm.browserSecurityHeaders.contentSecurityPolicy"> + </div> + <kc-tooltip>{{:: 'content-sec-policy-tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="contentSecurityPolicyReportOnly"><a href="http://www.w3.org/TR/CSP/" target="_blank">{{:: 'content-sec-policy-report-only' | translate}}</a></label> + <div class="col-sm-6"> + <input class="form-control" id="contentSecurityPolicyReportOnly" type="text" ng-model="realm.browserSecurityHeaders.contentSecurityPolicyReportOnly"> + </div> + <kc-tooltip>{{:: 'content-sec-policy-report-only-tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="xContentTypeOptions"><a href="https://www.owasp.org/index.php/List_of_useful_HTTP_headers" target="_blank">{{:: 'content-type-options' | translate}}</a></label> + <div class="col-sm-6"> + <input class="form-control" id="xContentTypeOptions" type="text" ng-model="realm.browserSecurityHeaders.xContentTypeOptions"> + </div> + <kc-tooltip>{{:: 'content-type-options-tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="xContentTypeOptions"><a href="https://developers.google.com/webmasters/control-crawl-index/docs/robots_meta_tag" target="_blank">{{:: 'robots-tag' | translate}}</a></label> + <div class="col-sm-6"> + <input class="form-control" id="xRobotsTag" type="text" ng-model="realm.browserSecurityHeaders.xRobotsTag"> + </div> + <kc-tooltip>{{:: 'robots-tag-tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="xXSSProtection"><a href="https://www.owasp.org/index.php/OWASP_Secure_Headers_Project#xxxsp" target="_blank">{{:: 'x-xss-protection' | translate}}</a></label> + <div class="col-sm-6"> + <input class="form-control" id="xXSSProtection" type="text" ng-model="realm.browserSecurityHeaders.xXSSProtection"> + </div> + <kc-tooltip>{{:: 'x-xss-protection-tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="strictTransportSecurity"><a href="https://www.owasp.org/index.php/OWASP_Secure_Headers_Project#hsts" target="_blank">{{:: 'strict-transport-security' | translate}}</a></label> + <div class="col-sm-6"> + <input class="form-control" id="strictTransportSecurity" type="text" ng-model="realm.browserSecurityHeaders.strictTransportSecurity"> + </div> + <kc-tooltip>{{:: 'strict-transport-security-tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + <div class="form-group" data-ng-show="access.manageRealm"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/forbidden.html b/admin/resources/partials/forbidden.html new file mode 100644 index 0000000..b40f2e7 --- /dev/null +++ b/admin/resources/partials/forbidden.html @@ -0,0 +1,7 @@ +<div id="content-area" class="col-sm-12" role="main"> + <div class="error-container"> + <h2>Forbidden</h2> + <p class="instruction">You don't have access to the requested resource.</p> + <a href="#" class="link-right">Go to the home page »</a> + </div> +</div>
\ No newline at end of file diff --git a/admin/resources/partials/group-attributes.html b/admin/resources/partials/group-attributes.html new file mode 100644 index 0000000..e12c553 --- /dev/null +++ b/admin/resources/partials/group-attributes.html @@ -0,0 +1,41 @@ +<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}}/groups">Groups</a></li> + <li>{{group.name}}</li> + </ol> + + <kc-tabs-group></kc-tabs-group> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!group.access.manage"> + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th>{{:: 'key' | translate}}</th> + <th>{{:: 'value' | translate}}</th> + <th>{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="(key, value) in group.attributes"> + <td>{{key}}</td> + <td><input ng-model="group.attributes[key]" class="form-control" type="text" name="{{key}}" id="attribute-{{key}}" /></td> + <td class="kc-action-cell" data-ng-click="removeAttribute(key)">{{:: 'delete' | translate}}</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" data-ng-click="addAttribute()" data-ng-disabled="!newAttribute.key.length || !newAttribute.value.length">{{:: 'add' | translate}}</td> + </tr> + </tbody> + </table> + + <div class="form-group" data-ng-show="group.access.manage"> + <div class="col-md-12"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/group-detail.html b/admin/resources/partials/group-detail.html new file mode 100644 index 0000000..8fd6461 --- /dev/null +++ b/admin/resources/partials/group-detail.html @@ -0,0 +1,28 @@ +<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}}/groups">{{:: 'groups' | translate}}</a></li> + <li>{{group.name}}</li> + </ol> + + <kc-tabs-group></kc-tabs-group> + <form class="form-horizontal" name="clientForm" novalidate> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label"for="name">{{:: 'name' | translate}} <span class="required">*</span></label> + <div class="col-md-6"> + <input class="form-control" type="text" id="name" name="name" data-ng-model="group.name" autofocus + required > + </div> + </div> + </fieldset> + + <div class="form-group" data-ng-show="group.access.manage"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed" data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/group-list.html b/admin/resources/partials/group-list.html new file mode 100644 index 0000000..731e28d --- /dev/null +++ b/admin/resources/partials/group-list.html @@ -0,0 +1,50 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <kc-tabs-group-list></kc-tabs-group-list> + + <table class="table table-striped table-bordered" style="margin-bottom: 0"> + <thead> + <tr> + <th class="kc-table-actions" colspan="5"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" autofocus placeholder="{{:: 'search.placeholder' | translate}}" ng-model="searchCriteria" class="form-control search" onkeydown="if (event.keyCode == 13) document.getElementById('groupSearch').click()"> + <div class="input-group-addon"> + <i class="fa fa-search" id="groupSearch" ng-click="searchGroup()"></i> + </div> + </div> + </div> + <button id="viewAllGroups" class="btn btn-default" ng-click="clearSearch()">{{:: 'view-all-groups' | translate}}</button> + <div class="pull-right" data-ng-show="access.manageUsers"> + <div class="form-inline"> + <button id="createGroup" class="btn btn-default" ng-click="createGroup(tree.currentNode)">{{:: 'new' | translate}}</button> + <button id="editGroup" ng-disabled="isDisabled()" class="btn btn-default" ng-click="edit(tree.currentNode)">{{:: 'edit' | translate}}</button> + <button id="cutGroup" ng-disabled="isDisabled()" class="btn btn-default" ng-click="cut(tree.currentNode)">{{:: 'cut' | translate}}</button> + <button id="pasteGroup" ng-disabled="!cutNode" class="btn btn-default" ng-click="paste(tree.currentNode)">{{:: 'paste' | translate}}</button> + <button id="removeGroup" ng-disabled="isDisabled()" class="btn btn-default" ng-click="remove(tree.currentNode)">{{:: 'delete' | translate}}</button> + </div> + </div> + </div> + </th> + </tr> + </thead> + <tbody> + <tr> + <td> + <div tree-id="tree" + angular-treeview="true" + tree-model="groupList" + node-id="id" + node-label="name" + node-children="subGroups" > + </div> + </td> + </tr> + </tbody> + </table> + <div style="margin-bottom: 50px"> + <kc-paging current-page="currentPage" number-of-pages="numberOfPages" current-page-input="currentPageInput"></kc-paging> + </div> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/group-members.html b/admin/resources/partials/group-members.html new file mode 100644 index 0000000..ffdf362 --- /dev/null +++ b/admin/resources/partials/group-members.html @@ -0,0 +1,48 @@ +<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}}/groups">{{:: 'groups' | translate}}</a></li> + <li>{{group.name}}</li> + </ol> + <kc-tabs-group></kc-tabs-group> + + <table class="table table-striped table-bordered"> + <caption data-ng-show="users" class="hidden">{{:: 'table-of-group-members' | translate}}</caption> + <thead> + <tr> + <tr data-ng-show="searchLoaded && users.length > 0"> + <th>{{:: 'username' | translate}}</th> + <th>{{:: 'last-name' | translate}}</th> + <th>{{:: 'first-name' | translate}}</th> + <th>{{:: 'email' | translate}}</th> + <th></th> + </tr> + </tr> + </thead> + <tfoot data-ng-show="users && (users.length >= query.max || query.first > 0)"> + <tr> + <td colspan="7"> + <div class="table-nav"> + <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button> + <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button> + <button data-ng-click="nextPage()" class="next" ng-disabled="users.length < query.max">{{:: 'next-page' | translate}}</button> + </div> + </td> + </tr> + </tfoot> + <tbody> + <tr ng-repeat="user in users"> + <td><a href="#/realms/{{realm.realm}}/users/{{user.id}}">{{user.username}}</a></td> + <td>{{user.lastName}}</td> + <td>{{user.firstName}}</td> + <td>{{user.email}}</td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/users/{{user.id}}">{{:: 'edit' | translate}}</td> + </tr> + <tr data-ng-show="!users || users.length == 0"> + <td class="text-muted" data-ng-show="searchLoaded && users.length == 0 && lastSearch != null">{{:: 'no-group-members' | translate}}</td> + <td class="text-muted" data-ng-show="searchLoaded && users.length == 0 && lastSearch == null">{{:: 'no-group-members' | translate}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/group-role-mappings.html b/admin/resources/partials/group-role-mappings.html new file mode 100644 index 0000000..fc3f6ee --- /dev/null +++ b/admin/resources/partials/group-role-mappings.html @@ -0,0 +1,111 @@ +<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}}/groups">{{:: 'groups' | translate}}</a></li> + <li>{{group.name}}</li> + </ol> + + <kc-tabs-group></kc-tabs-group> + + <form class="form-horizontal" name="realmForm" novalidate> + <div class="form-group" kc-read-only="!group.access.manage"> + <label class="col-md-2 control-label" class="control-label">{{:: 'realm-roles' | translate}}</label> + + <div class="col-md-10"> + <div class="row"> + <div class="col-md-3"> + <label class="control-label" for="available">{{:: 'available-roles' | translate}}</label> + <select id="available" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedRealmRoles"> + <option ng-repeat="r in realmRoles | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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> + </button> + <kc-tooltip>{{:: 'group.add-selected.tooltip' | translate}}</kc-tooltip> + </div> + <div class="col-md-3"> + <label class="control-label" for="assigned">{{:: 'assigned-roles' | translate}}</label> + <kc-tooltip>{{:: 'group.assigned-roles.tooltip' | translate}}</kc-tooltip> + <select id="assigned" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedRealmMappings"> + <option ng-repeat="r in realmMappings | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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}} + </button> + </div> + <div class="col-md-3"> + <label class="control-label" for="realm-composite">{{:: 'effective-roles' | translate}}</label> + <kc-tooltip>{{:: 'group.effective-roles.tooltip' | translate}}</kc-tooltip> + <select id="realm-composite" class="form-control overflow-select" multiple size=5 + disabled="true" + ng-model="dummymodel"> + <option ng-repeat="r in realmComposite | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + </div> + </div> + </div> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="clients">{{:: 'client-roles' | translate}}</label> + <div class="col-md-6"> + <input type="hidden" ui-select2="clientsUiSelect" id="clients" data-ng-model="selectedClient" data-ng-change="changeClient(selectedClient);" data-placeholder="{{:: 'authz-select-client' | translate}}..."> + </input> + </div> + <div class="col-md-10 col-md-push-2"> + <div class="row" data-ng-show="selectedClient" > + <div class="col-md-3"> + <label class="control-label" for="available-client">{{:: 'available-roles' | translate}}</label> + <kc-tooltip>{{:: 'group.available-roles.tooltip' | translate}}</kc-tooltip> + <select id="available-client" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedClientRoles"> + <option ng-repeat="r in clientRoles | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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> + </button> + </div> + <div class="col-md-3"> + <label class="control-label" for="assigned-client">{{:: 'assigned-roles' | translate}}</label> + <kc-tooltip>{{:: 'group.assigned-roles-client.tooltip' | translate}}</kc-tooltip> + <select id="assigned-client" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedClientMappings"> + <option ng-repeat="r in clientMappings | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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}} + </button> + </div> + <div class="col-md-3"> + <label class="control-label" for="client-composite">{{:: 'effective-roles' | translate}}</label> + <kc-tooltip>{{:: 'group.effective-roles-client.tooltip' | translate}}</kc-tooltip> + <select id="client-composite" class="form-control overflow-select" multiple size=5 + disabled="true" + ng-model="dummymodel"> + <option ng-repeat="r in clientComposite | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + </div> + </div> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/home.html b/admin/resources/partials/home.html new file mode 100644 index 0000000..dc2471b --- /dev/null +++ b/admin/resources/partials/home.html @@ -0,0 +1,4 @@ +<div id="wrapper" class="container"> + <div class="row"> + </div> +</div>
\ No newline at end of file diff --git a/admin/resources/partials/identity-provider-mapper-detail.html b/admin/resources/partials/identity-provider-mapper-detail.html new file mode 100644 index 0000000..7e62b14 --- /dev/null +++ b/admin/resources/partials/identity-provider-mapper-detail.html @@ -0,0 +1,84 @@ +<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}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li> + <li ng-show="identityProvider.diaplayName"><a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">{{identityProvider.displayName}}</a></li> + <li ng-show="!identityProvider.diaplayName"><a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">{{identityProvider.alias}}</a></li> + <li><a href="#/realms/{{realm.realm}}/identity-provider-mappers/{{identityProvider.alias}}/mappers">{{:: 'identity-provider-mappers' | translate}}</a></li> + <li class="active" data-ng-show="create">{{:: 'create-identity-provider-mapper' | translate}}</li> + <li class="active" data-ng-hide="create">{{mapper.name|capitalize}}</li> + </ol> + + <h1 data-ng-hide="create">{{mapper.name|capitalize}}<i class="pficon pficon-delete clickable" data-ng-show="!create && access.manageIdentityProviders" + data-ng-hide="changed" data-ng-click="remove()"></i></h1> + <h1 data-ng-show="create">{{:: 'add-identity-provider-mapper' | translate}}</h1> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageIdentityProviders"> + <fieldset> + <div class="form-group clearfix" data-ng-show="!create"> + <label class="col-md-2 control-label" for="mapperId">{{:: 'id' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="mapperId" type="text" ng-model="mapper.id" readonly> + </div> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="name">{{:: 'name' | translate}} <span class="required">*</span></label> + <div class="col-md-6"> + <input class="form-control" id="name" type="text" ng-model="mapper.name" data-ng-readonly="!create" required> + </div> + <kc-tooltip>{{:: 'mapper.name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="syncMode">{{:: 'sync-mode-override' | translate}} <span class="required">*</span></label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="syncMode" + ng-model="mapper.config.syncMode" + required> + <option id="syncMode_inherit" name="syncMode" value="INHERIT">{{:: 'sync-mode.inherit' | translate}}</option> + <option id="syncMode_legacy" name="syncMode" value="LEGACY">{{:: 'sync-mode.legacy' | translate}}</option> + <option id="syncMode_import" name="syncMode" value="IMPORT">{{:: 'sync-mode.import' | translate}}</option> + <option id="syncMode_force" name="syncMode" value="FORCE">{{:: 'sync-mode.force' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'sync-mode-override.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="create"> + <label class="col-md-2 control-label" for="mapperTypeCreate">{{:: 'mapper-type' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="mapperTypeCreate" + ng-model="mapperType" + ng-options="mapperType.name for (mapperKey, mapperType) in mapperTypes"> + </select> + </div> + </div> + <kc-tooltip>{{mapperType.helpText}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-hide="create"> + <label class="col-md-2 control-label" for="mapperType">{{:: 'mapper-type' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="mapperType" type="text" ng-model="mapperType.name" data-ng-readonly="true"> + </div> + <kc-tooltip>{{mapperType.helpText}}</kc-tooltip> + </div> + <kc-provider-config config="mapper.config" properties="mapperType.properties" realm="realm"></kc-provider-config> + </fieldset> + + <div class="form-group" data-ng-show="create && access.manageIdentityProviders"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save>{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + + <div class="form-group" data-ng-show="!create && access.manageIdentityProviders"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/identity-provider-mappers.html b/admin/resources/partials/identity-provider-mappers.html new file mode 100644 index 0000000..c7c136b --- /dev/null +++ b/admin/resources/partials/identity-provider-mappers.html @@ -0,0 +1,49 @@ +<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}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li> + <li data-ng-show="identityProvider.displayName"><a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">{{identityProvider.displayName}}</a></li> + <li data-ng-show="!identityProvider.displayName"><a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">{{identityProvider.alias}}</a></li> + <li>{{:: 'mappers' | translate}}</li> + </ol> + + <kc-tabs-identity-provider></kc-tabs-identity-provider> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="4"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" data-ng-model="search.name" class="form-control search" onkeyup="if(event.keyCode == 13){$(this).next('I').click();}"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit"></i> + </div> + </div> + </div> + <div class="pull-right" data-ng-show="access.manageIdentityProviders"> + <a class="btn btn-primary" href="#/create/identity-provider-mappers/{{realm.realm}}/{{identityProvider.alias}}">{{:: 'create' | translate}}</a> + </div> + </div> + </th> + </tr> + <tr data-ng-hide="mappers.length == 0"> + <th>{{:: 'name' | translate}}</th> + <th>{{:: 'category' | translate}}</th> + <th>{{:: 'type' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="mapper in mappers | filter:search"> + <td><a href="#/realms/{{realm.realm}}/identity-provider-mappers/{{identityProvider.alias}}/mappers/{{mapper.id}}">{{mapper.name}}</a></td> + <td>{{mapperTypes[mapper.identityProviderMapper].category}}</td> + <td>{{mapperTypes[mapper.identityProviderMapper].name}}</td> + </tr> + <tr data-ng-show="mappers.length == 0"> + <td>{{:: 'no-mappers-available' | translate}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/menu.html b/admin/resources/partials/menu.html new file mode 100644 index 0000000..dc41323 --- /dev/null +++ b/admin/resources/partials/menu.html @@ -0,0 +1,26 @@ +<div class="navbar-header"> + <button type="button" class="navbar-toggle" ng-init="navCollapsed = true" ng-click="navCollapsed = !navCollapsed"> + <span class="sr-only">{{:: 'toggle-navigation' | translate}}</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="#" onclick="location.href = authUrl"></a> +</div> + +<div class="collapse navbar-collapse" collapse="navCollapsed"> + <ul class="nav navbar-nav navbar-utility"> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown"> + <span class="pficon pficon-user"></span> + {{auth.user.displayName|capitalize}} <b class="caret"></b> + </a> + <ul class="dropdown-menu"> + <li><a data-ng-click="auth.authz.accountManagement()" href="">{{:: 'manage-account' | translate}}</a></li> + <li><a href="#/server-info">{{:: 'server-info' | translate}}</a></li> + <li class="divider"></li> + <li><a href="" ng-click="auth.authz.logout()">{{:: 'sign-out' | translate}}</a></li> + </ul> + </li> + </ul> +</div>
\ No newline at end of file diff --git a/admin/resources/partials/modal/realm-events-admin-auth.html b/admin/resources/partials/modal/realm-events-admin-auth.html new file mode 100644 index 0000000..c8da93e --- /dev/null +++ b/admin/resources/partials/modal/realm-events-admin-auth.html @@ -0,0 +1,8 @@ +<div style="padding: 20px 20px 0 20px"> +<table class="table table-striped table-bordered"> + <tr><td width="100px">{{:: 'realm' | translate}}</td><td>{{event.authDetails.realmId}}</td></tr> + <tr><td width="100px">{{:: 'client' | translate}}</td><td>{{event.authDetails.clientId}}</td></tr> + <tr><td width="100px">{{:: 'user' | translate}}</td><td>{{event.authDetails.userId}}</td></tr> + <tr><td width="100px">{{:: 'ip-address' | translate}}</td><td>{{event.authDetails.ipAddress}}</td></tr> +</table> +</div>
\ No newline at end of file diff --git a/admin/resources/partials/modal/realm-events-admin-representation.html b/admin/resources/partials/modal/realm-events-admin-representation.html new file mode 100644 index 0000000..837a164 --- /dev/null +++ b/admin/resources/partials/modal/realm-events-admin-representation.html @@ -0,0 +1,3 @@ +<div style="padding: 20px 20px 10px 20px"> + <pre ng-bind = "{{event.representation}} | json"></pre> +</div>
\ No newline at end of file diff --git a/admin/resources/partials/modal/role-selector.html b/admin/resources/partials/modal/role-selector.html new file mode 100644 index 0000000..b4dd43f --- /dev/null +++ b/admin/resources/partials/modal/role-selector.html @@ -0,0 +1,39 @@ +<div class="modal-header"> + <button type="button" class="close" ng-click="cancel()"> + <span class="pficon pficon-close"></span> + </button> + <h4 class="modal-title">{{:: 'role-selector' | translate}}</h4> +</div> +<div style="padding: 0 15px 15px 15px;"> + <form> + <div data-ng-show="realmRoles.length > 0" style="margin-bottom: 30px;"> + <label class="control-label" for="available">{{:: 'realm-roles' | translate}}</label> + <kc-tooltip>{{:: 'realm-roles.tooltip' | translate}}</kc-tooltip> + <select id="available" class="form-control" size="5" + ng-dblclick="selectRealmRole()" + ng-model="selectedRealmRole.role" + ng-options="r.name for r in realmRoles | orderBy:'toString()'"> + <option style="display:none" value="">{{:: 'select-a-role' | translate}}</option> + </select> + <button class="btn btn-default" type="submit" data-ng-disabled="!selectedRealmRole.role" ng-click="selectRealmRole()" tooltip-trigger="mouseover mouseout" tooltip="Select realm role" tooltip-placement="right"> + {{:: 'select-realm-role' | translate}}</i> + </button> + </div> + <div> + <label class="control-label" for="clients">{{:: 'client-roles' | translate}} + <kc-tooltip>{{:: 'client-roles.tooltip' | translate}}</kc-tooltip> + </label> + <input type="hidden" style="margin-bottom: 10px;"ui-select2="clientsUiSelect" id="clients" data-ng-model="selectedClient" data-ng-change="changeClient(selectedClient);" data-placeholder="{{:: 'authz-select-client' | translate}}..."> + </input> + <select id="available-client" class="form-control" size="5" + ng-dblclick="selectClientRole()" + ng-model="selectedClientRole.role" + ng-options="r.name for r in clientRoles | orderBy:'toString()'"> + <option style="display:none" value="">{{:: 'select-a-role' | translate}}</option> + </select> + <button class="btn btn-default" type="submit" data-ng-disabled="!selectedClientRole.role" ng-click="selectClientRole()" tooltip-trigger="mouseover mouseout" tooltip="Select client role" tooltip-placement="right"> + {{:: 'select-client-role' | translate}} + </button> + </div> + </form> +</div> diff --git a/admin/resources/partials/modal/unregistered-required-action-selector.html b/admin/resources/partials/modal/unregistered-required-action-selector.html new file mode 100644 index 0000000..bc9995f --- /dev/null +++ b/admin/resources/partials/modal/unregistered-required-action-selector.html @@ -0,0 +1,21 @@ +<div class="modal-header"> + <button type="button" class="close" ng-click="cancel()"> + <span class="pficon pficon-close"></span> + </button> + <h4 class="modal-title">{{:: 'register-required-action' | translate}}</h4> +</div> +<div class="modal-body"> + <form> + <div> + <label class="control-label" for="selector">{{:: 'required-action' | translate}}</label> + <select id="selector" class="form-control" + ng-model="selected.selected" + ng-options="r.name for r in unregisteredRequiredActions"> + </select> + </div> + </form> +</div> +<div class="modal-footer"> + <button type="button" class="btn btn-default" ng-click="cancel()">{{:: 'cancel' | translate}}</button> + <button type="button" class="btn btn-primary" ng-click="ok()">{{:: 'ok' | translate}}</button> +</div>
\ No newline at end of file diff --git a/admin/resources/partials/modal/view-key.html b/admin/resources/partials/modal/view-key.html new file mode 100644 index 0000000..5d53d3f --- /dev/null +++ b/admin/resources/partials/modal/view-key.html @@ -0,0 +1,18 @@ +<!-- + ~ Copyright 2016 Red Hat, Inc. and/or its affiliates + ~ and other contributors as indicated by the @author tags. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<div style="padding: 20px 20px 20px 20px; word-wrap: break-word;">{{key}}</div>
\ No newline at end of file diff --git a/admin/resources/partials/modal/view-object.html b/admin/resources/partials/modal/view-object.html new file mode 100644 index 0000000..ee50aee --- /dev/null +++ b/admin/resources/partials/modal/view-object.html @@ -0,0 +1,3 @@ +<div style="padding: 20px 20px 10px 20px"> + <pre ng-bind = "{{object}} | json"></pre> +</div>
\ No newline at end of file diff --git a/admin/resources/partials/notfound.html b/admin/resources/partials/notfound.html new file mode 100644 index 0000000..62a1a5b --- /dev/null +++ b/admin/resources/partials/notfound.html @@ -0,0 +1,7 @@ +<div id="content-area" class="col-sm-12" role="main"> + <div class="error-container"> + <h2 translate="resource-not-found"></h2> + <p class="instruction">{{:: 'resource-not-found.instruction' | translate}}</p> + <a href="#/" class="link-right" translate="go-to-the-home-page"></a> + </div> +</div>
\ No newline at end of file diff --git a/admin/resources/partials/otp-policy.html b/admin/resources/partials/otp-policy.html new file mode 100644 index 0000000..0fdb946 --- /dev/null +++ b/admin/resources/partials/otp-policy.html @@ -0,0 +1,88 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1>{{:: 'authentication' | translate}}</h1> + + <kc-tabs-authentication></kc-tabs-authentication> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <div class="form-group"> + <label for="type" class="col-md-2 control-label">{{:: 'otp-type' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="type" ng-model="realm.otpPolicyType" class="form-control"> + <option value="totp">{{:: 'time-based' | translate}}</option> + <option value="hotp">{{:: 'counter-based' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'otp-type.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label for="alg" class="col-md-2 control-label">{{:: 'otp-hash-algorithm' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="alg" ng-model="realm.otpPolicyAlgorithm" class="form-control"> + <option value="HmacSHA1">SHA1</option> + <option value="HmacSHA256">SHA256</option> + <option value="HmacSHA512">SHA512</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'otp-hash-algorithm.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="digits">{{:: 'number-of-digits' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="digits" ng-model="realm.otpPolicyDigits" class="form-control" ng-options="item as item for item in optionsDigits"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'otp.number-of-digits.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="lookAhead">{{:: 'look-ahead-window' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="number" required min="0" max="120" id="lookAhead" name="lookAhead" data-ng-model="realm.otpPolicyLookAheadWindow" autofocus> + </div> + <kc-tooltip>{{:: 'otp.look-ahead-window.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group" data-ng-if="realm.otpPolicyType == 'hotp'"> + <label class="col-md-2 control-label" for="counter">{{:: 'initial-counter' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="number" data-ng-required="realm.otpPolicyType == 'hotp'" min="1" max="120" id="counter" name="counter" data-ng-model="realm.otpPolicyInitialCounter" autofocus> + </div> + <kc-tooltip>{{:: 'otp.initial-counter.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group" data-ng-if="realm.otpPolicyType == 'totp'"> + <label class="col-md-2 control-label" for="counter">{{:: 'otp-token-period' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="number" data-ng-required="realm.otpPolicyType == 'totp'" min="1" max="120" id="period" name="period" data-ng-model="realm.otpPolicyPeriod"> + </div> + <kc-tooltip>{{:: 'otp-token-period.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label">{{:: 'otp-supported-applications' | translate}}</label> + <div class="col-md-6"> + {{realm.otpSupportedApplications.join(', ')}} + </div> + <kc-tooltip>{{:: 'otp-supported-applications.tooltip' | translate}}</kc-tooltip> + </div> + + + <div class="form-group" data-ng-show="access.manageRealm"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> + +</div> + + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/pagenotfound.html b/admin/resources/partials/pagenotfound.html new file mode 100644 index 0000000..c15a051 --- /dev/null +++ b/admin/resources/partials/pagenotfound.html @@ -0,0 +1,7 @@ +<div id="content-area" class="col-sm-12" role="main"> + <div class="error-container"> + <h2 translate="page-not-found"></h2> + <p class="instruction">{{:: 'page-not-found.instruction' | translate}}</p> + <a href="#" class="link-right" translate="go-to-the-home-page"></a> + </div> +</div>
\ No newline at end of file diff --git a/admin/resources/partials/partial-export.html b/admin/resources/partials/partial-export.html new file mode 100644 index 0000000..1ceed8c --- /dev/null +++ b/admin/resources/partials/partial-export.html @@ -0,0 +1,34 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + + <h1> + <span>{{:: 'partial-export' | translate}}</span> + <kc-tooltip>{{:: 'partial-export.tooltip' | translate}}</kc-tooltip> + </h1> + + <form class="form-horizontal" name="partialExportForm" novalidate> + <fieldset class="border-top"> + + <div class="form-group"> + <label class="col-md-2 control-label" for="exportGroupsAndRoles">{{:: 'export-groups-and-roles' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="exportGroupsAndRoles" name="exportGroupsAndRoles" id="exportGroupsAndRoles" onoffswitch on-text="{{:: 'onText'| translate}}" off-text="{{:: 'offText'| translate}}"/> + </div> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="exportClients">{{:: 'export-clients' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="exportClients" name="exportClients" id="exportClients" onoffswitch on-text="{{:: 'onText'| translate}}" off-text="{{:: 'offText'| translate}}"/> + </div> + </div> + + <div class="col-sm-12"> + <button class="btn btn-primary" data-ng-click="export()" type="submit">{{:: 'export' | translate}}</button> + </div> + + </fieldset> + + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/partial-import.html b/admin/resources/partials/partial-import.html new file mode 100644 index 0000000..4df1207 --- /dev/null +++ b/admin/resources/partials/partial-import.html @@ -0,0 +1,130 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + + <h1> + <span>{{:: 'partial-import' | translate}}</span> + <kc-tooltip>{{:: 'partial-import.tooltip' | translate}}</kc-tooltip> + </h1> + + <form class="form-horizontal" name="partialImportForm" novalidate> + <fieldset class="border-top"> + <div class="form-group"> + <label for="name" class="col-sm-2 control-label">{{:: 'exported-json-file' | translate}}</label> + + <div class="col-md-6" data-ng-hide="importing"> + <label for="import-file" class="btn btn-default">{{:: 'select-file'| translate}} <i class="pficon pficon-import"></i></label> + <input id="import-file" type="file" class="hidden" kc-on-read-file="importFile($fileContent)"/> + </div> + + <div class="col-md-6" data-ng-show="importing"> + <button class="btn btn-default" data-ng-click="viewImportDetails()">{{:: 'view-details'| translate}}</button> + <button class="btn btn-default" data-ng-click="reset()">{{:: 'clear-import'| translate}}</button> + </div> + </div> + + <div class="form-group" data-ng-show="importing && isMultiRealm && !hasResults()"> + <label for="fromRealm" class="col-md-2 control-label">{{:: 'import-from-realm' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="fromRealm" ng-model="fileContent" class="form-control" + ng-options="item as item.realm for item in rawContent"> + </select> + </div> + </div> + </div> + + <div class="form-group" data-ng-show="importing && hasArray('users') && !hasResults()"> + <label class="col-md-2 control-label" for="importUsers">{{:: 'import-users' | translate}} ({{itemCount('users')}})</label> + <div class="col-sm-6"> + <input ng-model="importUsers" name="importUsers" id="importUsers" onoffswitch on-text="{{:: 'onText'| translate}}" off-text="{{:: 'offText'| translate}}"/> + </div> + </div> + + <div class="form-group" data-ng-show="importing && hasArray('groups') && !hasResults()"> + <label class="col-md-2 control-label" for="importGroups">{{:: 'import-groups' | translate}} ({{itemCount('groups')}})</label> + <div class="col-sm-6"> + <input ng-model="importGroups" name="importGroups" id="importGroups" onoffswitch on-text="{{:: 'onText'| translate}}" off-text="{{:: 'offText'| translate}}"/> + </div> + </div> + + <div class="form-group" data-ng-show="importing && hasArray('clients') && !hasResults()"> + <label class="col-md-2 control-label" for="importClients">{{:: 'import-clients' | translate}} ({{itemCount('clients')}})</label> + <div class="col-sm-6"> + <input ng-model="importClients" name="importClients" id="importClients" onoffswitch on-text="{{:: 'onText'| translate}}" off-text="{{:: 'offText'| translate}}"/> + </div> + </div> + + <div class="form-group" data-ng-show="importing && hasArray('identityProviders') && !hasResults()"> + <label class="col-md-2 control-label" for="importIdentityProviders">{{:: 'import-identity-providers' | translate}} ({{itemCount('identityProviders')}})</label> + <div class="col-sm-6"> + <input ng-model="importIdentityProviders" name="importIdentityProviders" id="importIdentityProviders" onoffswitch on-text="{{:: 'onText'| translate}}" off-text="{{:: 'offText'| translate}}"/> + </div> + </div> + + <div class="form-group" data-ng-show="importing && hasRealmRoles() && !hasResults()"> + <label class="col-md-2 control-label" for="importRealmRoles">{{:: 'import-realm-roles' | translate}} ({{itemCount('roles.realm')}})</label> + <div class="col-sm-6"> + <input ng-model="importRealmRoles" name="importRealmRoles" id="importRealmRoles" onoffswitch on-text="{{:: 'onText'| translate}}" off-text="{{:: 'offText'| translate}}"/> + </div> + </div> + + <div class="form-group" data-ng-show="importing && hasClientRoles() && !hasResults()"> + <label class="col-md-2 control-label" for="importClientRoles">{{:: 'import-client-roles' | translate}} ({{itemCount('roles.client')}})</label> + <div class="col-sm-6"> + <input ng-model="importClientRoles" name="importClientRoles" id="importClientRoles" onoffswitch on-text="{{:: 'onText'| translate}}" off-text="{{:: 'offText'| translate}}"/> + </div> + </div> + + <div class="form-group" data-ng-show="importing && hasResources() && !hasResults()"> + <label for="ifResourceExists" class="col-md-2 control-label">{{:: 'if-resource-exists' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="ifResourceExists" ng-model="ifResourceExists" class="form-control"> + <option value="FAIL">{{:: 'fail' | translate}}</option> + <option value="SKIP">{{:: 'skip' | translate}}</option> + <option value="OVERWRITE">{{:: 'overwrite' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'if-resource-exists.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <div class="form-group" data-ng-show="importing && hasResources() && !hasResults()"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'import'| translate}}</button> + </div> + </div> + + <div class="form-group" data-ng-show="hasResults()"> + {{successMessage()}} + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th>{{:: 'action' | translate}}</th> + <th>{{:: 'type' | translate}}</th> + <th>{{:: 'name' | translate}}</th> + <th>{{:: 'id' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="result in resultsPage()" > + <td ng-show="result.action == 'OVERWRITTEN'"><span class="label label-danger">{{result.action}}</span></td> + <td ng-show="result.action == 'SKIPPED'"><span class="label label-warning">{{result.action}}</span></td> + <td ng-show="result.action == 'ADDED'"><span class="label label-success">{{result.action}}</span></td> + <td>{{result.resourceType}}</td> + <td>{{result.resourceName}}</td> + <td>{{result.id}}</td> + </tr> + </tbody> + </table> + + <div class="table-nav"> + <button data-ng-click="setFirstPage()" class="first" ng-disabled="">{{:: 'first-page' | translate}}</button> + <button data-ng-click="setPreviousPage()" class="prev" ng-disabled="!hasPrevious()">{{:: 'previous-page' | translate}}</button> + <button data-ng-click="setNextPage()" class="next" ng-disabled="!hasNext()">{{:: 'next-page' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/password-policy.html b/admin/resources/partials/password-policy.html new file mode 100644 index 0000000..f211dba --- /dev/null +++ b/admin/resources/partials/password-policy.html @@ -0,0 +1,51 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1>{{:: 'authentication' | translate}}</h1> + + <kc-tabs-authentication></kc-tabs-authentication> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <table class="table table-striped table-bordered"> + <caption class="hidden">{{:: 'table-of-password-policies' | translate}}</caption> + <thead> + <tr ng-show="(serverInfo.passwordPolicies|removeSelectedPolicies:policy).length > 0"> + <th colspan="5" class="kc-table-actions"> + <div class="pull-right"> + <div> + <select class="form-control" ng-model="selectedPolicy" + ng-options="policy as policy.displayName for policy in (serverInfo.passwordPolicies|removeSelectedPolicies:policy) track by policy.id" + data-ng-change="addPolicy(selectedPolicy); selectedPolicy = null"> + <option value="" disabled selected>{{:: 'add-policy.placeholder' | translate}}</option> + </select> + </div> + </div> + </th> + </tr> + <tr> + <th>{{:: 'policy-type' | translate}}</th> + <th>{{:: 'policy-value' | translate}}</th> + <th>{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="p in policy"> + <td>{{p.displayName}}</td> + <td> + <input type="text" class="form-control" ng-model="p.value" ng-show="p.configType" data-ng-required="p.configType && !p.defaultValue"> + </td> + <td class="kc-action-cell" ng-click="removePolicy($index)">{{:: 'delete' | translate}}</td> + </tr> + </tbody> + </table> + + <div class="form-group" data-ng-show="access.manageRealm"> + <div class="col-md-12"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> + +</div> + + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/protocol-mapper-detail.html b/admin/resources/partials/protocol-mapper-detail.html new file mode 100644 index 0000000..e555aaf --- /dev/null +++ b/admin/resources/partials/protocol-mapper-detail.html @@ -0,0 +1,64 @@ + <h1 data-ng-show="model.create">{{:: 'create-protocol-mapper' | translate}}</h1> + <h1 data-ng-hide="model.create">{{model.mapper.name|capitalize}}<i class="pficon pficon-delete clickable" data-ng-show="!model.create && access.manageClients" + data-ng-hide="model.changed" data-ng-click="remove()"></i></h1> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageClients"> + + <fieldset> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="protocol">{{:: 'protocol' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="protocol" type="text" ng-model="model.protocol" readonly> + </div> + <kc-tooltip>{{:: 'protocol.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="!model.create"> + <label class="col-md-2 control-label" for="mapperId">{{:: 'id' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="mapperId" type="text" ng-model="model.mapper.id" readonly> + </div> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="name">{{:: 'name' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="name" type="text" ng-model="model.mapper.name" data-ng-readonly="!model.create" required> + </div> + <kc-tooltip>{{:: 'mapper.name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="model.create"> + <label class="col-md-2 control-label" for="mapperTypeCreate">{{:: 'mapper-type' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="mapperTypeCreate" + ng-model="model.mapperType" + ng-options="mapperType.name for mapperType in model.mapperTypes" + required> + </select> + </div> + </div> + <kc-tooltip>{{model.mapperType.helpText}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-hide="model.create"> + <label class="col-md-2 control-label" for="mapperType">{{:: 'mapper-type' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="mapperType" type="text" ng-model="model.mapperType.name" data-ng-readonly="true"> + </div> + <kc-tooltip>{{model.mapperType.helpText}}</kc-tooltip> + </div> + <kc-provider-config config="model.mapper.config" properties="model.mapperType.properties" realm="model.realm" clients="clients"></kc-provider-config> + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="model.create && access.manageClients"> + <button kc-save>{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="!model.create && access.manageClients"> + <button kc-save data-ng-disabled="!model.changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!model.changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> diff --git a/admin/resources/partials/realm-cache-settings.html b/admin/resources/partials/realm-cache-settings.html new file mode 100644 index 0000000..53a7987 --- /dev/null +++ b/admin/resources/partials/realm-cache-settings.html @@ -0,0 +1,30 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <kc-tabs-realm></kc-tabs-realm> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <div class="form-group"> + <label class="col-md-2 control-label">{{:: 'realm-cache-clear' | translate}}</label> + <div class="col-md-6"> + <button type="submit" data-ng-click="clearRealmCache()" class="btn btn-default">{{:: 'clear' | translate}}</button> + </div> + + <kc-tooltip>{{:: 'realm-cache-clear.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label">{{:: 'user-cache-clear' | translate}}</label> + <div class="col-md-6"> + <button type="submit" data-ng-click="clearUserCache()" class="btn btn-default">{{:: 'clear' | translate}}</button> + </div> + <kc-tooltip>{{:: 'user-cache-clear.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label">{{:: 'keys-cache-clear' | translate}}</label> + <div class="col-md-6"> + <button type="submit" data-ng-click="clearKeysCache()" class="btn btn-default">{{:: 'clear' | translate}}</button> + </div> + <kc-tooltip>{{:: 'keys-cache-clear.tooltip' | translate}}</kc-tooltip> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-create.html b/admin/resources/partials/realm-create.html new file mode 100644 index 0000000..f156c3b --- /dev/null +++ b/admin/resources/partials/realm-create.html @@ -0,0 +1,45 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + + <h1>{{:: 'add-realm' | translate}}</h1> + + <form class="form-horizontal" name="realmForm" novalidate> + <fieldset> + <div class="form-group"> + <label for="name" class="col-sm-2 control-label">{{:: 'import' | translate}}</label> + + <div class="col-md-6" data-ng-hide="importing"> + <label for="import-file" class="btn btn-default">{{:: 'select-file' | translate}} <i class="pficon pficon-import"></i></label> + <input id="import-file" type="file" class="hidden" kc-on-read-file="importFile($fileContent)"> + </div> + + <div class="col-md-6" data-ng-show="importing"> + <input type="button" class="btn btn-default" data-ng-click="viewImportDetails()" value="{{:: 'view-details' | translate}}"/> + <input type="button" class="btn btn-default" data-ng-click="reset()" value="{{:: 'clear-import' | translate}}"/> + </div> + </div> + + <div class="form-group"> + <label for="name" class="col-sm-2 control-label">{{:: 'name' | translate}} <span class="required">*</span></label> + + <div class="col-md-6"> + <input class="form-control" kc-no-reserved-chars type="text" id="name" name="name" data-ng-model="realm.realm" autofocusrequired> + </div> + </div> + <div class="form-group"> + <label for="enabled" class="col-md-2 control-label">{{:: 'enabled' | translate}}</label> + <div class="col-md-6"> + <input ng-model="realm.enabled" name="enabled" id="enabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'create' | translate}}</button> + <button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-default-roles.html b/admin/resources/partials/realm-default-roles.html new file mode 100644 index 0000000..819151d --- /dev/null +++ b/admin/resources/partials/realm-default-roles.html @@ -0,0 +1,88 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1>{{:: 'roles' | translate}}</h1> + + <ul class="nav nav-tabs"> + <li><a href="#/realms/{{realm.realm}}/roles">{{:: 'realm-roles' | translate}}</a></li> + <li class="active"><a href="#/realms/{{realm.realm}}/default-roles">{{:: 'default-roles' | translate}}</a></li> + </ul> + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <div class="form-group"> + <label class="col-md-2 control-label" class="control-label">{{:: 'realm-roles' | translate}}</label> + + <div class="col-md-10"> + <div class="row"> + <div class="col-md-4"> + <label class="control-label" for="available">{{:: 'available-roles' | translate}}</label> + <kc-tooltip>{{:: 'default.available-roles.tooltip' | translate}}</kc-tooltip> + <select id="available" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedRealmRoles"> + <option ng-repeat="r in availableRealmRoles | orderBy:'toString()'" value="{{r}}" title="{{r.toString()}}"> + {{r.toString()}} + </option> + </select> + <button ng-disabled="selectedRealmRoles.length == 0" class="btn btn-default" type="submit" ng-click="addRealmDefaultRole()"> + {{:: 'add-selected' | translate}} <i class="fa fa-angle-double-right"></i> + </button> + </div> + <div class="col-md-4"> + <label class="control-label" for="assigned">{{:: 'realm-default-roles' | translate}}</label> + <kc-tooltip>{{:: 'realm-default-roles.tooltip' | translate}}</kc-tooltip> + <select id="assigned" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedRealmDefRoles"> + <option ng-repeat="r in realm.defaultRoles | orderBy:'toString()'" value="{{r}}" title="{{r.toString()}}"> + {{r.toString()}} + </option> + </select> + <button ng-disabled="selectedRealmDefRoles.length == 0" class="btn btn-default" type="submit" ng-click="deleteRealmDefaultRole()"> + <i class="fa fa-angle-double-left"></i> {{:: 'remove-selected' | translate}} + </button> + </div> + </div> + </div> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="clients">{{:: 'client-roles' | translate}}</label> + <div class="col-md-6"> + <input type="hidden" ui-select2="clientsUiSelect" id="clients" data-ng-model="selectedClient" data-ng-change="changeClient(selectedClient);" data-placeholder="{{:: 'authz-select-client' | translate}}..."> + </input> + </div> + <div class="col-md-10 col-md-push-2"> + <div class="row" data-ng-show="selectedClient"> + <div class="col-md-4"> + <label class="control-label" for="available-client">{{:: 'available-roles' | translate}}</label> + <kc-tooltip>{{:: 'default.available-roles-client.tooltip' | translate}}</kc-tooltip> + <select id="available-client" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedClientRoles"> + <option ng-repeat="r in availableClientRoles | orderBy:'toString()'" value="{{r}}" title="{{r.toString()}}"> + {{r.toString()}} + </option> + </select> + <button ng-disabled="selectedClientRoles.length == 0" class="btn btn-default" type="submit" ng-click="addClientDefaultRole()"> + {{:: 'add-selected' | translate}} <i class="fa fa-angle-double-right"></i> + </button> + </div> + <div class="col-md-4"> + <label class="control-label" for="assigned-client">{{:: 'client-default-roles' | translate}}</label> + <kc-tooltip>{{:: 'client-default-roles.tooltip' | translate}}</kc-tooltip> + <select id="assigned-client" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedClientDefRoles"> + <option ng-repeat="r in selectedClient.defaultRoles | orderBy:'toString()'" value="{{r}}" title="{{r.toString()}}"> + {{r.toString()}} + </option> + </select> + <button ng-disabled="selectedClientDefRoles.length == 0" class="btn btn-default" type="submit" ng-click="rmClientDefaultRole()"> + <i class="fa fa-angle-double-left"></i> {{:: 'remove-selected' | translate}} + </button> + </div> + </div> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-detail.html b/admin/resources/partials/realm-detail.html new file mode 100644 index 0000000..6719a98 --- /dev/null +++ b/admin/resources/partials/realm-detail.html @@ -0,0 +1,82 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <kc-tabs-realm></kc-tabs-realm> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <div class="form-group"> + <label class="col-md-2 control-label" for="name"><span class="required">*</span> {{:: 'name' | translate}}</label> + <div class="col-md-6"> + <input kc-no-reserved-chars class="form-control" data-ng-disabled="disableRename" type="text" id="name" name="name" data-ng-model="realmName" autofocus required> + </div> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="name">{{:: 'displayName' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" id="displayName" name="displayName" data-ng-model="realm.displayName"> + </div> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="name">{{:: 'displayNameHtml' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" id="displayNameHtml" name="displayNameHtml" data-ng-model="realm.displayNameHtml"> + </div> + </div> + + <div class="form-group" data-ng-show="serverInfo.listProviderIds('hostname').includes('default')"> + <label class="col-md-2 control-label" for="name">{{:: 'realm-detail.frontendUrl' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" id="frontendUrl" name="frontendUrl" data-ng-model="realm.attributes.frontendUrl"> + </div> + <kc-tooltip>{{:: 'realm-detail.frontendUrl.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group" data-ng-show="serverInfo.listProviderIds('hostname').includes('fixed')"> + <label class="col-md-2 control-label" for="name">{{:: 'realm-detail.hostname' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" id="hostname" name="hostname" data-ng-model="realm.attributes.hostname"> + </div> + <kc-tooltip>{{:: 'realm-detail.hostname.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label> + <div class="col-md-6"> + <input ng-model="realm.enabled" name="enabled" id="enabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'realm-detail.enabled.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="userManagedAccessAllowed">{{:: 'userManagedAccess' | translate}}</label> + <div class="col-md-6"> + <input ng-model="realm.userManagedAccessAllowed" name="userManagedAccessAllowed" id="userManagedAccessAllowed" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'realm-detail.userManagedAccess.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label">{{:: 'endpoints' | translate}}</label> + <div class="col-md-6"> + <a class="form-control" ng-href="{{authServerUrl}}/realms/{{realm.realm}}/.well-known/openid-configuration" target="_blank">{{:: 'realm-detail.protocol-endpoints.oidc' | translate}}</a> + + <a class="form-control" ng-href="{{authServerUrl}}/realms/{{realm.realm}}/protocol/saml/descriptor" target="_blank">{{:: 'realm-detail.protocol-endpoints.saml' | translate}}</a> + </div> + <kc-tooltip>{{:: 'realm-detail.protocol-endpoints.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="createRealm && access.manageRealm"> + <button kc-save data-ng-show="changed">{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + + <div class="col-md-10 col-md-offset-2" data-ng-show="!createRealm && access.manageRealm"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-events-admin.html b/admin/resources/partials/realm-events-admin.html new file mode 100644 index 0000000..0bfd649 --- /dev/null +++ b/admin/resources/partials/realm-events-admin.html @@ -0,0 +1,134 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1> + <span>{{:: 'admin-events' | translate}}</span> + <kc-tooltip>{{:: 'admin-events.tooltip' | translate}}</kc-tooltip> + </h1> + + <ul class="nav nav-tabs"> + <li data-ng-class="(path[2] == 'events') && 'active'"><a href="#/realms/{{realm.realm}}/events">{{:: 'login-events' | translate}}</a></li> + <li data-ng-class="(path[2] == 'admin-events') && 'active'"><a href="#/realms/{{realm.realm}}/admin-events">{{:: 'admin-events' | translate}}</a></li> + <li data-ng-class="(path[2] == 'events-settings') && 'active'"><a href="#/realms/{{realm.realm}}/events-settings">{{:: 'config' | translate}}</a></li> + </ul> + <h2></h2> + + <div id="content"> + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="5"> + <div class="pull-right"> + <select data-ng-model="query.max" + data-ng-click="update()" + data-ng-options="itemCount for itemCount in [5,10,50,100]" + class="btn btn-default"> + </select> + <button class="btn btn-default" data-ng-click="filter = !filter"> + <span class="glyphicon glyphicon-plus" data-ng-show="!filter"></span> + <span class="glyphicon glyphicon-minus" data-ng-show="filter"></span> + {{:: 'filter' | translate}} + </button> + <button class="btn btn-default btn-default" data-ng-click="update()">{{:: 'update' | translate}}</button> + <button class="btn btn-default btn-default" data-ng-click="reset()">{{:: 'reset' | translate}}</button> + </div> + <form class="form-horizontal" data-ng-show="filter"> + <div class="form-group"> + <label class="col-sm-2 control-label" for="adminEnabledEventOperations">{{:: 'operation-types' | translate}}</label> + <div class="col-sm-5" onkeypress="return false;" ng-paste="disablePaste($event)"> + <input ui-select2="adminEnabledEventOperationsOptions" id="adminEnabledEventOperations" ng-model="query.operationTypes" data-placeholder="{{:: 'select-operations.placeholder' | translate}}"/> + </div> + </div> + <div class="form-group"> + <label class="col-sm-2 control-label" for="adminEnabledEventResourceTypes">{{:: 'resource-types' | translate}}</label> + <div class="col-sm-5" onkeypress="return false;" ng-paste="disablePaste($event)"> + <input ui-select2="adminEnabledEventResourceTypesOptions" id="adminEnabledEventResourceTypes" ng-model="query.resourceTypes" data-placeholder="{{:: 'select-resource-types.placeholder' | translate}}"/> + </div> + </div> + <div class="form-group"> + <label class="col-sm-2 control-label" for="resource">{{:: 'resource-path' | translate}}</label> + <kc-tooltip>{{:: 'resource-path.tooltip' | translate}}</kc-tooltip> + <div class="col-sm-4"> + <input class="form-control" type="text" id="resource" name="resource" data-ng-model="query.resourcePath"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-2 control-label" for="dateFrom">{{:: 'date-(from)' | translate}}</label> + <div class="col-sm-4"> + <input class="form-control" type="text" id="dateFrom" name="dateFrom" data-ng-model="query.dateFrom" placeholder="yyyy-MM-dd"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-2 control-label" for="dateTo">{{:: 'date-(to)' | translate}}</label> + <div class="col-sm-4"> + <input class="form-control" type="text" id="dateTo" name="dateTo" data-ng-model="query.dateTo" placeholder="yyyy-MM-dd"> + </div> + </div> + + <fieldset> + <legend><span class="text">{{:: 'authentication-details' | translate}}</span></legend> + + <div class="form-group"> + <label class="col-sm-2 control-label" for="realm">{{:: 'realm' | translate}}</label> + <div class="col-sm-4"> + <input class="form-control" type="text" id="realm" name="realm" data-ng-model="query.authRealm"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-2 control-label" for="client">{{:: 'client' | translate}}</label> + <div class="col-sm-4"> + <input class="form-control" type="text" id="client" name="client" data-ng-model="query.authClient"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-2 control-label" for="user">{{:: 'user' | translate}}</label> + <div class="col-sm-4"> + <input class="form-control" type="text" id="user" name="user" data-ng-model="query.authUser"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-2 control-label" for="ipAddress">{{:: 'ip-address' | translate}}</label> + <div class="col-sm-4"> + <input class="form-control" type="text" id="ipAddress" name="ipAddress" data-ng-model="query.authIpAddress"> + </div> + </div> + </fieldset> + + </form> + </th> + </tr> + <tr> + <th width="100px">{{:: 'time' | translate}}</th> + <th width="180px">{{:: 'operation-type' | translate}}</th> + <th width="180px">{{:: 'resource-type' | translate}}</th> + <th width="180px">{{:: 'resource-path' | translate}}</th> + <th>{{:: 'details' | translate}}</th> + </tr> + </thead> + <tfoot> + <tr> + <td colspan="7"> + <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0"><i data-ng-class="query.first == 0 && 'text-muted'" class="fa fa-angle-double-left"></i></button> + <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0"><i data-ng-class="query.first == 0 && 'text-muted'" class="fa fa-angle-left"></i></button> + <button data-ng-click="nextPage()" class="next" ng-disabled="events.length < query.max"><i data-ng-class="events.length < query.max && 'text-muted'" class="fa fa-angle-right"></i></button> + </td> + </tr> + </tfoot> + <tbody> + <tr data-ng-repeat="event in events"> + <td>{{event.time|date:'shortDate'}}<br>{{event.time|date:'mediumTime'}}</td> + <td data-ng-class="events-error">{{event.operationType}}</td> + <td data-ng-class="events-error">{{event.resourceType}}</td> + <td>{{event.resourcePath}}</td> + <td> + <button type="button" class="btn btn-default btn-xs" data-ng-click="viewAuth(event)"> + {{:: 'auth' | translate}} + </button> + <button type="button" class="btn btn-default btn-xs" data-ng-click="viewRepresentation(event)" data-ng-show="event.representation"> + {{:: 'representation' | translate}} + </button> + </td> + </tr> + </tbody> + </table> + </div> +</div> +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-events-config.html b/admin/resources/partials/realm-events-config.html new file mode 100644 index 0000000..b47d6e1 --- /dev/null +++ b/admin/resources/partials/realm-events-config.html @@ -0,0 +1,106 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1> + <span>{{:: 'events-config' | translate}}</span> + <kc-tooltip>{{:: 'events-config.tooltip' | translate}}</kc-tooltip> + </h1> + + <ul class="nav nav-tabs"> + <li data-ng-class="(path[2] == 'events') && 'active'"><a href="#/realms/{{realm.realm}}/events">{{:: 'login-events' | translate}}</a></li> + <li data-ng-class="(path[2] == 'admin-events') && 'active'"><a href="#/realms/{{realm.realm}}/admin-events">{{:: 'admin-events' | translate}}</a></li> + <li data-ng-class="(path[2] == 'events-settings') && 'active'"><a href="#/realms/{{realm.realm}}/events-settings">{{:: 'config' | translate}}</a></li> + </ul> + <div id="content"> + <h2>{{:: 'events-config' | translate}}</h2> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageEvents"> + + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="eventsListeners" class="control-label">{{:: 'event-listeners' | translate}}</label> + <kc-tooltip>{{:: 'event-listeners.tooltip' | translate}}</kc-tooltip> + <div class="col-md-6"> + <input ui-select2="eventsConfigSelectOptions" id="eventsListeners" ng-model="eventsConfig.eventsListeners" data-placeholder="{{:: 'select-an-action.placeholder' | translate}}"/> + </div> + </div> + </fieldset> + + <fieldset> + <legend><span class="text">{{:: 'login-events-settings' | translate}}</span></legend> + + <div class="form-group"> + <label class="col-md-2 control-label" for="enabled">{{:: 'save-events' | translate}}</label> + <kc-tooltip>{{:: 'login.save-events.tooltip' | translate}}</kc-tooltip> + <div class="col-md-6"> + <input ng-model="eventsConfig.eventsEnabled" name="enabled" id="enabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + + <div class="form-group" data-ng-show="eventsConfig.eventsEnabled"> + <label class="col-md-2 control-label" for="enabledEventTypes" class="control-label">{{:: 'saved-types' | translate}}</label> + <kc-tooltip>{{:: 'saved-types.tooltip' | translate}}</kc-tooltip> + <div class="col-md-6"> + <input ui-select2="eventSelectOptions" id="enabledEventTypes" ng-model="eventsConfig.enabledEventTypes" data-placeholder="{{:: 'select-event-types.placeholder' | translate}}"/> + </div> + </div> + + <div class="form-group" data-ng-show="access.manageEvents && eventsConfig.eventsEnabled"> + <label class="col-md-2 control-label" for="password">{{:: 'clear-events' | translate}}</label> + <kc-tooltip>{{:: 'clear-events.tooltip' | translate}}</kc-tooltip> + <div class="col-md-6"> + <button class="btn btn-danger" type="submit" data-ng-click="clearEvents()" >{{:: 'clear-events' | translate}}</button> + </div> + </div> + <div class="form-group" data-ng-show="eventsConfig.eventsEnabled"> + <label class="col-md-2 control-label" for="expiration">{{:: 'expiration' | translate}}</label> + <kc-tooltip>{{:: 'events.expiration.tooltip' | translate}}</kc-tooltip> + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" data-ng-model="eventsConfig.eventsExpiration" id="expiration" name="expiration" min="0"/> + <select class="form-control" name="expirationUnit" data-ng-model="eventsConfig.expirationUnit"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + </div> + </fieldset> + + + <fieldset> + <legend><span class="text">{{:: 'admin-events-settings' | translate}}</span></legend> + + <div class="form-group"> + <label class="col-md-2 control-label" for="adminEventsEnabled">{{:: 'save-events' | translate}}</label> + <kc-tooltip>{{:: 'admin.save-events.tooltip' | translate}}</kc-tooltip> + <div class="col-md-6"> + <input ng-model="eventsConfig.adminEventsEnabled" name="adminEventsEnabled" id="adminEventsEnabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + + <div class="form-group" data-ng-show="eventsConfig.adminEventsEnabled"> + <label class="col-md-2 control-label" for="adminEventsDetailsEnabled">{{:: 'include-representation' | translate}}</label> + <kc-tooltip>{{:: 'include-representation.tooltip' | translate}}</kc-tooltip> + <div class="col-md-6"> + <input ng-model="eventsConfig.adminEventsDetailsEnabled" name="adminEventsDetailsEnabled" id="adminEventsDetailsEnabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + + <div class="form-group" data-ng-show="access.manageEvents && eventsConfig.adminEventsEnabled"> + <label class="col-md-2 control-label" for="password">{{:: 'clear-admin-events' | translate}}</label> + <kc-tooltip>{{:: 'clear-admin-events.tooltip' | translate}}</kc-tooltip> + <div class="col-md-6"> + <button class="btn btn-danger" type="submit" data-ng-click="clearAdminEvents()" >{{:: 'clear-admin-events' | translate}}</button> + </div> + </div> + + </fieldset> + + <div class="form-group" data-ng-show="access.manageEvents"> + <div class="col-md-10 col-md-offset-2"> + <button data-kc-reset data-ng-disabled="!changed">{{:: 'clear-changes' | translate}}</button> + <button data-kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + </div> + </div> + </form> + </div> +</div> +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-events.html b/admin/resources/partials/realm-events.html new file mode 100644 index 0000000..21369b4 --- /dev/null +++ b/admin/resources/partials/realm-events.html @@ -0,0 +1,124 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1> + <span>{{:: 'events' | translate}}</span> + <kc-tooltip>{{:: 'events.tooltip' | translate}}</kc-tooltip> + </h1> + + <ul class="nav nav-tabs"> + <li data-ng-class="(path[2] == 'events') && 'active'"><a href="#/realms/{{realm.realm}}/events">{{:: 'login-events' | translate}}</a></li> + <li data-ng-class="(path[2] == 'admin-events') && 'active'"><a href="#/realms/{{realm.realm}}/admin-events">{{:: 'admin-events' | translate}}</a></li> + <li data-ng-class="(path[2] == 'events-settings') && 'active'"><a href="#/realms/{{realm.realm}}/events-settings">{{:: 'config' | translate}}</a></li> + </ul> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="4"> + <div class="pull-right"> + <select data-ng-model="query.max" + data-ng-click="update()" + data-ng-options="itemCount for itemCount in [5,10,50,100]" + class="btn btn-default"> + </select> + <button class="btn btn-default" data-ng-click="filter = !filter"> + <span class="glyphicon glyphicon-plus" data-ng-show="!filter"></span> + <span class="glyphicon glyphicon-minus" data-ng-show="filter"></span> + {{:: 'filter' | translate}} + </button> + <button class="btn btn-default btn-default" data-ng-click="update()">{{:: 'update' | translate}}</button> + <button class="btn btn-default btn-default" data-ng-click="reset()">{{:: 'reset' | translate}}</button> + </div> + <form class="form-horizontal"> + <div class="form-group" data-ng-show="filter"> + <label class="col-md-2 control-label" for="eventTypes">{{:: 'event-type' | translate}}</label> + <div class="col-sm-5" onkeypress="return false;" ng-paste="disablePaste($event)"> + <input ui-select2="eventSelectOptions" id="eventTypes" ng-model="query.type" data-placeholder="{{:: 'select-event-types.placeholder' | translate}}"/> + </div> + </div> + <div class="form-group" data-ng-show="filter"> + <label class="col-md-2 control-label" for="client">{{:: 'client' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" id="client" name="client" data-ng-model="query.client"> + </div> + </div> + <div class="form-group" data-ng-show="filter"> + <label class="col-md-2 control-label" for="user">{{:: 'user' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" id="user" name="user" data-ng-model="query.user"> + </div> + </div> + + <div class="form-group" data-ng-show="filter"> + <label class="col-md-2 control-label" for="dateFrom">{{:: 'date-(from)' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" id="dateFrom" name="dateFrom" data-ng-model="query.dateFrom" placeholder="yyyy-MM-dd"> + </div> + </div> + <div class="form-group" data-ng-show="filter"> + <label class="col-md-2 control-label" for="dateTo">{{:: 'date-(to)' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" id="dateTo" name="dateTo" data-ng-model="query.dateTo" placeholder="yyyy-MM-dd"> + </div> + </div> + + </form> + </th> + </tr> + <tr> + <th width="100px">{{:: 'time' | translate}}</th> + <th width="180px">{{:: 'event-type' | translate}}</th> + <th>{{:: 'details' | translate}}</th> + </tr> + </thead> + <tfoot> + <tr> + <td colspan="7"> + <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0"><i data-ng-class="query.first == 0 && 'text-muted'" class="fa fa-angle-double-left"></i></button> + <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0"><i data-ng-class="query.first == 0 && 'text-muted'" class="fa fa-angle-left"></i></button> + <button data-ng-click="nextPage()" class="next" ng-disabled="events.length < query.max"><i data-ng-class="events.length < query.max && 'text-muted'" class="fa fa-angle-right"></i></button> + </td> + </tr> + </tfoot> + <tbody> + <tr ng-repeat="event in events"> + <td>{{event.time|date:'shortDate'}}<br>{{event.time|date:'mediumTime'}}</td> + <td>{{event.type}}</td> + <td> + <table class="table table-striped table-bordered"> + <tr><td width="100px">{{:: 'client' | translate}}</td><td>{{event.clientId}}</td></tr> + <tr><td>{{:: 'user' | translate}}</td><td>{{event.userId}}</td></tr> + <tr><td>{{:: 'ip-address' | translate}}</td><td>{{event.ipAddress}}</td></tr> + <tr data-ng-show="event.error"><td>{{:: 'error' | translate}}</td><td>{{event.error}}</td></tr> + <tr> + <td>{{:: 'details' | translate}}</td> + <td> + <button type="button" class="btn btn-default btn-xs" ng-click="event.collapse = !event.collapse"> + <span class="glyphicon glyphicon-plus" data-ng-show="!event.collapse"></span> + <span class="glyphicon glyphicon-minus" data-ng-show="event.collapse"></span> + </button> + <table data-ng-show="event.collapse" class="table table-striped table-bordered"> + <tr ng-repeat="(key, value) in event.details"> + <td>{{key}}</td> + <td>{{value}}</td> + </tr> + </table> + </td> + </tr> + <tr data-ng-show="event.representation"> + <td>{{:: 'representation' | translate}}</td> + <td> + <button type="button" class="btn btn-default btn-xs" ng-click="collapseRep = !collapseRep"> + <span class="glyphicon glyphicon-plus" data-ng-show="!collapseRep"></span> + <span class="glyphicon glyphicon-minus" data-ng-show="collapseRep"></span> + </button> + <pre data-ng-show="collapseRep">{{event.representation}}</pre> + </td> + </tr> + </table> + </td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-identity-provider-bitbucket.html b/admin/resources/partials/realm-identity-provider-bitbucket.html new file mode 100644 index 0000000..fab751e --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-bitbucket.html @@ -0,0 +1,142 @@ +<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}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li> + <li data-ng-hide="newIdentityProvider">{{provider.name}}</li> + <li data-ng-show="newIdentityProvider">{{:: 'add-identity-provider' | translate}}</li> + </ol> + + <kc-tabs-identity-provider></kc-tabs-identity-provider> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageIdentityProviders"> + <fieldset> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="redirectUri">{{:: 'redirect-uri' | translate}}</label> + <div class="col-sm-6"> + <input class="form-control" id="redirectUri" type="text" value="{{callbackUrl}}{{identityProvider.alias}}/endpoint" readonly kc-select-action="click"> + </div> + <kc-tooltip>{{:: 'redirect-uri.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + <fieldset> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="clientId"><span class="required">*</span> {{:: 'bitbucket-consumer-key' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="clientId" type="text" ng-model="identityProvider.config.clientId" required> + </div> + <kc-tooltip>{{:: 'bitbucket.key.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="clientSecret"><span class="required">*</span> {{:: 'bitbucket-consumer-secret' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="clientSecret" kc-password ng-model="identityProvider.config.clientSecret" required> + </div> + <kc-tooltip>{{:: 'bitbucket.secret.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="defaultScope">{{:: 'default-scopes' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="defaultScope" type="text" ng-model="identityProvider.config.defaultScope"> + </div> + <kc-tooltip>{{:: 'bitbucket.default-scopes.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="enabled">{{:: 'store-tokens' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.storeToken" id="storeToken" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.store-tokens.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="storedTokensReadable">{{:: 'stored-tokens-readable' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.addReadTokenRoleOnCreate" id="storedTokensReadable" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.stored-tokens-readable.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.enabled" id="enabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.enabled.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="trustEmail">{{:: 'trust-email' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.trustEmail" name="identityProvider.trustEmail" id="trustEmail" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'trust-email.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="linkOnly">{{:: 'link-only' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.linkOnly" name="identityProvider.trustEmail" id="linkOnly" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'link-only.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="hideOnLoginPage">{{:: 'hide-on-login-page' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.hideOnLoginPage" name="identityProvider.config.hideOnLoginPage" id="hideOnLoginPage" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'hide-on-login-page.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="guiOrder">{{:: 'gui-order' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="guiOrder" type="text" ng-model="identityProvider.config.guiOrder"> + </div> + <kc-tooltip>{{:: 'gui-order.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="firstBrokerLoginFlowAlias">{{:: 'first-broker-login-flow' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="firstBrokerLoginFlowAlias" + ng-model="identityProvider.firstBrokerLoginFlowAlias" + ng-options="flow.alias as flow.alias for flow in authFlows" + required> + </select> + </div> + </div> + <kc-tooltip>{{:: 'first-broker-login-flow.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="postBrokerLoginFlowAlias">{{:: 'post-broker-login-flow' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="postBrokerLoginFlowAlias" + ng-model="identityProvider.postBrokerLoginFlowAlias" + ng-options="flow.alias as flow.alias for flow in postBrokerAuthFlows"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'post-broker-login-flow.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="syncMode">{{:: 'sync-mode' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="syncMode" + ng-model="identityProvider.config.syncMode" + required> + <option id="syncMode_import" name="syncMode" value="IMPORT">{{:: 'sync-mode.import' | translate}}</option> + <option id="syncMode_legacy" name="syncMode" value="LEGACY">{{:: 'sync-mode.legacy' | translate}}</option> + <option id="syncMode_force" name="syncMode" value="FORCE">{{:: 'sync-mode.force' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'sync-mode.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()" data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-identity-provider-export.html b/admin/resources/partials/realm-identity-provider-export.html new file mode 100644 index 0000000..742cdf4 --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-export.html @@ -0,0 +1,23 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2" data-ng-init="initProvider()"> + <ol class="breadcrumb"> + <li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li> + <li data-ng-show="identityProvider.displayName"><a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">{{identityProvider.displayName}}</a></li> + <li data-ng-show="!identityProvider.displayName"><a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">{{identityProvider.alias}}</a></li> + <li>{{:: 'export' | translate}}</li> + </ol> + + <kc-tabs-identity-provider></kc-tabs-identity-provider> + + <form class="form-horizontal" name="realmForm" novalidate> + <fieldset class="border-top"> + <div class="form-group"> + <div class="col-sm-12"> + <a class="btn btn-primary" data-ng-click="download()" type="submit">{{:: 'download' | translate}}</a> + <textarea class="form-control" rows="20" kc-select-action="click">{{exported}}</textarea> + </div> + </div> + </fieldset> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-identity-provider-facebook-ext.html b/admin/resources/partials/realm-identity-provider-facebook-ext.html new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-facebook-ext.html diff --git a/admin/resources/partials/realm-identity-provider-facebook.html b/admin/resources/partials/realm-identity-provider-facebook.html new file mode 100644 index 0000000..a4630ac --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-facebook.html @@ -0,0 +1 @@ +<div data-ng-include data-src="resourceUrl + '/partials/realm-identity-provider-social.html'"></div>
\ No newline at end of file diff --git a/admin/resources/partials/realm-identity-provider-github-ext.html b/admin/resources/partials/realm-identity-provider-github-ext.html new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-github-ext.html diff --git a/admin/resources/partials/realm-identity-provider-github.html b/admin/resources/partials/realm-identity-provider-github.html new file mode 100644 index 0000000..a4630ac --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-github.html @@ -0,0 +1 @@ +<div data-ng-include data-src="resourceUrl + '/partials/realm-identity-provider-social.html'"></div>
\ No newline at end of file diff --git a/admin/resources/partials/realm-identity-provider-gitlab.html b/admin/resources/partials/realm-identity-provider-gitlab.html new file mode 100644 index 0000000..00c0e94 --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-gitlab.html @@ -0,0 +1,142 @@ +<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}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li> + <li data-ng-hide="newIdentityProvider">{{provider.name}}</li> + <li data-ng-show="newIdentityProvider">{{:: 'add-identity-provider' | translate}}</li> + </ol> + + <kc-tabs-identity-provider></kc-tabs-identity-provider> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageIdentityProviders"> + <fieldset> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="redirectUri">{{:: 'redirect-uri' | translate}}</label> + <div class="col-sm-6"> + <input class="form-control" id="redirectUri" type="text" value="{{callbackUrl}}{{identityProvider.alias}}/endpoint" readonly kc-select-action="click"> + </div> + <kc-tooltip>{{:: 'redirect-uri.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + <fieldset> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="clientId"><span class="required">*</span> {{:: 'gitlab-application-id' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="clientId" type="text" ng-model="identityProvider.config.clientId" required> + </div> + <kc-tooltip>{{:: 'gitlab.application-id.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="clientSecret"><span class="required">*</span> {{:: 'gitlab-application-secret' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="clientSecret" kc-password ng-model="identityProvider.config.clientSecret" required> + </div> + <kc-tooltip>{{:: 'gitlab.application-secret.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="defaultScope">{{:: 'default-scopes' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="defaultScope" type="text" ng-model="identityProvider.config.defaultScope"> + </div> + <kc-tooltip>{{:: 'gitlab.default-scopes.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="enabled">{{:: 'store-tokens' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.storeToken" id="storeToken" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.store-tokens.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="storedTokensReadable">{{:: 'stored-tokens-readable' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.addReadTokenRoleOnCreate" id="storedTokensReadable" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.stored-tokens-readable.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.enabled" id="enabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.enabled.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="trustEmail">{{:: 'trust-email' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.trustEmail" name="identityProvider.trustEmail" id="trustEmail" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'trust-email.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="linkOnly">{{:: 'link-only' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.linkOnly" name="identityProvider.trustEmail" id="linkOnly" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'link-only.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="hideOnLoginPage">{{:: 'hide-on-login-page' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.hideOnLoginPage" name="identityProvider.config.hideOnLoginPage" id="hideOnLoginPage" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'hide-on-login-page.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="guiOrder">{{:: 'gui-order' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="guiOrder" type="text" ng-model="identityProvider.config.guiOrder"> + </div> + <kc-tooltip>{{:: 'gui-order.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="firstBrokerLoginFlowAlias">{{:: 'first-broker-login-flow' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="firstBrokerLoginFlowAlias" + ng-model="identityProvider.firstBrokerLoginFlowAlias" + ng-options="flow.alias as flow.alias for flow in authFlows" + required> + </select> + </div> + </div> + <kc-tooltip>{{:: 'first-broker-login-flow.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="postBrokerLoginFlowAlias">{{:: 'post-broker-login-flow' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="postBrokerLoginFlowAlias" + ng-model="identityProvider.postBrokerLoginFlowAlias" + ng-options="flow.alias as flow.alias for flow in postBrokerAuthFlows"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'post-broker-login-flow.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="syncMode">{{:: 'sync-mode' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="syncMode" + ng-model="identityProvider.config.syncMode" + required> + <option id="syncMode_import" name="syncMode" value="IMPORT">{{:: 'sync-mode.import' | translate}}</option> + <option id="syncMode_legacy" name="syncMode" value="LEGACY">{{:: 'sync-mode.legacy' | translate}}</option> + <option id="syncMode_force" name="syncMode" value="FORCE">{{:: 'sync-mode.force' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'sync-mode.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()" data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-identity-provider-google-ext.html b/admin/resources/partials/realm-identity-provider-google-ext.html new file mode 100644 index 0000000..4f313a8 --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-google-ext.html @@ -0,0 +1,21 @@ +<div class="form-group"> + <label class="col-md-2 control-label" for="hostedDomain">{{:: 'hostedDomain' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.hostedDomain" id="hostedDomain" class="form-control" /> + </div> + <kc-tooltip>{{:: 'identity-provider.google-hostedDomain.tooltip' | translate}}</kc-tooltip> +</div> +<div class="form-group"> + <label class="col-md-2 control-label" for="userIp">{{:: 'userIp' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.userIp" id="userIp" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.google-userIp.tooltip' | translate}}</kc-tooltip> +</div> +<div class="form-group"> + <label class="col-md-2 control-label" for="offlineAccess">{{:: 'offlineAccess' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.offlineAccess" id="offlineAccess" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.google-offlineAccess.tooltip' | translate}}</kc-tooltip> +</div> diff --git a/admin/resources/partials/realm-identity-provider-google.html b/admin/resources/partials/realm-identity-provider-google.html new file mode 100644 index 0000000..a4630ac --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-google.html @@ -0,0 +1 @@ +<div data-ng-include data-src="resourceUrl + '/partials/realm-identity-provider-social.html'"></div>
\ No newline at end of file diff --git a/admin/resources/partials/realm-identity-provider-instagram-ext.html b/admin/resources/partials/realm-identity-provider-instagram-ext.html new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-instagram-ext.html diff --git a/admin/resources/partials/realm-identity-provider-instagram.html b/admin/resources/partials/realm-identity-provider-instagram.html new file mode 100644 index 0000000..a4630ac --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-instagram.html @@ -0,0 +1 @@ +<div data-ng-include data-src="resourceUrl + '/partials/realm-identity-provider-social.html'"></div>
\ No newline at end of file diff --git a/admin/resources/partials/realm-identity-provider-keycloak-oidc.html b/admin/resources/partials/realm-identity-provider-keycloak-oidc.html new file mode 100644 index 0000000..d380749 --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-keycloak-oidc.html @@ -0,0 +1 @@ +<div data-ng-include data-src="resourceUrl + '/partials/realm-identity-provider-oidc.html'"></div>
\ No newline at end of file diff --git a/admin/resources/partials/realm-identity-provider-linkedin-ext.html b/admin/resources/partials/realm-identity-provider-linkedin-ext.html new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-linkedin-ext.html diff --git a/admin/resources/partials/realm-identity-provider-linkedin.html b/admin/resources/partials/realm-identity-provider-linkedin.html new file mode 100644 index 0000000..a4630ac --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-linkedin.html @@ -0,0 +1 @@ +<div data-ng-include data-src="resourceUrl + '/partials/realm-identity-provider-social.html'"></div>
\ No newline at end of file diff --git a/admin/resources/partials/realm-identity-provider-microsoft-ext.html b/admin/resources/partials/realm-identity-provider-microsoft-ext.html new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-microsoft-ext.html diff --git a/admin/resources/partials/realm-identity-provider-microsoft.html b/admin/resources/partials/realm-identity-provider-microsoft.html new file mode 100644 index 0000000..a4630ac --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-microsoft.html @@ -0,0 +1 @@ +<div data-ng-include data-src="resourceUrl + '/partials/realm-identity-provider-social.html'"></div>
\ No newline at end of file diff --git a/admin/resources/partials/realm-identity-provider-oidc.html b/admin/resources/partials/realm-identity-provider-oidc.html new file mode 100644 index 0000000..19cfcb5 --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-oidc.html @@ -0,0 +1,355 @@ +<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}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li> + <li data-ng-show="!newIdentityProvider && identityProvider.displayName">{{identityProvider.displayName}}</li> + <li data-ng-show="!newIdentityProvider && !identityProvider.displayName">{{identityProvider.alias}}</li> + <li data-ng-show="newIdentityProvider">{{:: 'add-identity-provider' | translate}}</li> + </ol> + + <kc-tabs-identity-provider></kc-tabs-identity-provider> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageIdentityProviders"> + <fieldset> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="redirectUri">{{:: 'redirect-uri' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="redirectUri" type="text" value="{{callbackUrl}}{{identityProvider.alias}}/endpoint" readonly kc-select-action="click"> + </div> + <kc-tooltip>{{:: 'redirect-uri.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + <fieldset> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="identifier"><span class="required">*</span> {{:: 'alias' | translate}}</label> + <div class="col-md-6"> + <input kc-no-reserved-chars class="form-control" id="identifier" type="text" ng-model="identityProvider.alias" data-ng-readonly="!newIdentityProvider" required> + </div> + <kc-tooltip>{{:: 'identity-provider.alias.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="displayName"> {{:: 'display-name' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="displayName" type="text" ng-model="identityProvider.displayName"> + </div> + <kc-tooltip>{{:: 'identity-provider.display-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.enabled" id="enabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.enabled.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="storeToken">{{:: 'store-tokens' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.storeToken" id="storeToken" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.store-tokens.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="storedTokensReadable">{{:: 'stored-tokens-readable' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.addReadTokenRoleOnCreate" id="storedTokensReadable" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.stored-tokens-readable.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="trustEmail">{{:: 'trust-email' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.trustEmail" name="identityProvider.trustEmail" id="trustEmail" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'trust-email.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="linkOnly">{{:: 'link-only' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.linkOnly" name="identityProvider.trustEmail" id="linkOnly" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'link-only.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="hideOnLoginPage">{{:: 'hide-on-login-page' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.hideOnLoginPage" name="identityProvider.config.hideOnLoginPage" id="hideOnLoginPage" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'hide-on-login-page.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="guiOrder">{{:: 'gui-order' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="guiOrder" type="text" ng-model="identityProvider.config.guiOrder"> + </div> + <kc-tooltip>{{:: 'gui-order.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="firstBrokerLoginFlowAlias">{{:: 'first-broker-login-flow' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="firstBrokerLoginFlowAlias" + ng-model="identityProvider.firstBrokerLoginFlowAlias" + ng-options="flow.alias as flow.alias for flow in authFlows" + required> + </select> + </div> + </div> + <kc-tooltip>{{:: 'first-broker-login-flow.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="postBrokerLoginFlowAlias">{{:: 'post-broker-login-flow' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="postBrokerLoginFlowAlias" + ng-model="identityProvider.postBrokerLoginFlowAlias" + ng-options="flow.alias as flow.alias for flow in postBrokerAuthFlows"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'post-broker-login-flow.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="syncMode">{{:: 'sync-mode' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="syncMode" + ng-model="identityProvider.config.syncMode" + required> + <option id="syncMode_import" name="syncMode" value="IMPORT">{{:: 'sync-mode.import' | translate}}</option> + <option id="syncMode_legacy" name="syncMode" value="LEGACY">{{:: 'sync-mode.legacy' | translate}}</option> + <option id="syncMode_force" name="syncMode" value="FORCE">{{:: 'sync-mode.force' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'sync-mode.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + <fieldset> + <legend uncollapsed><span class="text">{{:: 'openid-connect-config' | translate}}</span> <kc-tooltip>{{:: 'openid-connect-config.tooltip' | translate}}</kc-tooltip></legend> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="authorizationUrl"><span class="required">*</span> {{:: 'authorization-url' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="authorizationUrl" type="text" ng-model="identityProvider.config.authorizationUrl" required> + </div> + <kc-tooltip>{{:: 'authorization-url.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-sm-2 control-label" for="loginHint">{{:: 'loginHint' | translate}}</label> + <div class="col-sm-4"> + <input ng-model="identityProvider.config.loginHint" id="loginHint" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'loginHint.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-sm-2 control-label" for="uiLocales">{{:: 'uiLocales' | translate}}</label> + <div class="col-sm-4"> + <input ng-model="identityProvider.config.uiLocales" id="uiLocales" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'uiLocales.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="tokenUrl"><span class="required">*</span> {{:: 'token-url' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="tokenUrl" type="text" ng-model="identityProvider.config.tokenUrl" required> + </div> + <kc-tooltip>{{:: 'token-url.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="userInfoUrl">{{:: 'logout-url' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="logoutUrl" type="text" ng-model="identityProvider.config.logoutUrl"> + </div> + <kc-tooltip>{{:: 'identity-provider.logout-url.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-sm-2 control-label" for="backchannelSupported">{{:: 'backchannel-logout' | translate}}</label> + <div class="col-sm-4"> + <input ng-model="identityProvider.config.backchannelSupported" id="backchannelSupported" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'backchannel-logout.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="disableUserInfo">{{:: 'disableUserInfo' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.disableUserInfo" id="disableUserInfo" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.disableUserInfo.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="userInfoUrl">{{:: 'user-info-url' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="userInfoUrl" type="text" ng-model="identityProvider.config.userInfoUrl"> + </div> + <kc-tooltip>{{:: 'user-info-url.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="clientAuth"><span class="required">*</span> {{:: 'client-auth' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="clientAuth" + ng-model="identityProvider.config.clientAuthMethod" + required> + <option id="clientAuth_post" name="clientAuth" value="client_secret_post" selected>{{:: 'client-auth.client_secret_post' | translate}}</option> + <option id="clientAuth_basic" name="clientAuth" value="client_secret_basic">{{:: 'client-auth.client_secret_basic' | translate}}</option> + <option id="clientAuth_secret_jwt" name="clientAuth" value="client_secret_jwt">{{:: 'client-auth.client_secret_jwt' | translate}}</option> + <option id="clientAuth_privatekey_jwt" name="clientAuth" value="private_key_jwt">{{:: 'client-auth.private_key_jwt' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'client-auth.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="clientId"><span class="required">*</span> {{:: 'client-id' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="clientId" type="text" ng-model="identityProvider.config.clientId" required> + </div> + <kc-tooltip>{{:: 'identity-provider.client-id.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="clientSecret"><span data-ng-show="identityProvider.config.clientAuthMethod != 'private_key_jwt'" class="required">*</span> {{:: 'client-secret' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="clientSecret" kc-password ng-model="identityProvider.config.clientSecret" ng-required="identityProvider.config.clientAuthMethod != 'private_key_jwt'"> + </div> + <kc-tooltip>{{:: 'client-secret.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="issuer">{{:: 'issuer' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="issuer" type="text" ng-model="identityProvider.config.issuer"> + </div> + <kc-tooltip>{{:: 'issuer.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="defaultScope">{{:: 'default-scopes' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="defaultScope" type="text" ng-model="identityProvider.config.defaultScope"> + </div> + <kc-tooltip>{{:: 'identity-provider.default-scopes.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="prompt">{{:: 'prompt' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="prompt" ng-model="identityProvider.config.prompt"> + <option value="">{{:: 'unspecified.option' | translate}}</option> + <option value="none">{{:: 'none.option' | translate}}</option> + <option value="consent">{{:: 'consent.option' | translate}}</option> + <option value="login">{{:: 'login.option' | translate}}</option> + <option value="select_account">{{:: 'select-account.option' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'prompt.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="acceptsPromptNoneForwardFromClient">{{:: 'accepts-prompt-none-forward-from-client' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.acceptsPromptNoneForwardFromClient" id="acceptsPromptNoneForwardFromClient" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'accepts-prompt-none-forward-from-client.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="validateSignature">{{:: 'validate-signatures' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.validateSignature" id="validateSignature" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.validate-signatures.tooltip' | translate}}</kc-tooltip> + </div> + + <div data-ng-show="identityProvider.config.validateSignature == 'true'"> + + <div class="form-group"> + <label class="col-md-2 control-label" for="useJwksUrl">{{:: 'use-jwks-url' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.useJwksUrl" id="useJwksUrl" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.use-jwks-url.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group clearfix" data-ng-show="identityProvider.config.useJwksUrl == 'true'"> + <label class="col-md-2 control-label" for="jwksUrl">{{:: 'jwks-url' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="jwksUrl" type="text" ng-model="identityProvider.config.jwksUrl"> + </div> + <kc-tooltip>{{:: 'identity-provider.jwks-url.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group clearfix" data-ng-hide="identityProvider.config.useJwksUrl == 'true'"> + <label class="col-md-2 control-label" for="publicKeySignatureVerifierKey">{{:: 'validating-public-key' | translate}}</label> + <div class="col-md-6"> + <textarea class="form-control" id="publicKeySignatureVerifier" ng-model="identityProvider.config.publicKeySignatureVerifier"/> + </div> + <kc-tooltip>{{:: 'identity-provider.validating-public-key.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group clearfix" data-ng-hide="identityProvider.config.useJwksUrl == 'true'"> + <label class="col-md-2 control-label" for="publicKeySignatureVerifierKeyId">{{:: 'validating-public-key-id' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="publicKeySignatureVerifierKeyId" ng-model="identityProvider.config.publicKeySignatureVerifierKeyId"/> + </div> + <kc-tooltip>{{:: 'identity-provider.validating-public-key-id.tooltip' | translate}}</kc-tooltip> + </div> + + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="allowedClockSkew">{{:: 'allowed-clock-skew' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.allowedClockSkew" id="allowedClockSkew" type="text" class="form-control"/> + </div> + <kc-tooltip>{{:: 'identity-provider.allowed-clock-skew.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="forwardParameters">{{:: 'forwarded-query-parameters' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="forwardParameters" type="text" ng-model="identityProvider.config.forwardParameters"/> + </div> + <kc-tooltip>{{:: 'identity-provider.forwarded-query-parameters.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + <fieldset data-ng-show="newIdentityProvider"> + <legend uncollapsed><span class="text">{{:: 'import-external-idp-config' | translate}}</span> <kc-tooltip>{{:: 'import-external-idp-config.tooltip' | translate}}</kc-tooltip></legend> + <div class="form-group" data-ng-show="newIdentityProvider"> + <label class="col-md-2 control-label" for="fromUrl">{{:: 'import-from-url' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="fromUrl" type="text" ng-model="fromUrl.data"> + </div> + <kc-tooltip>{{:: 'identity-provider.import-from-url.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="importFrom"></label> + <div class="col-md-6"> + <button id="importFrom" type="button" data-ng-click="importFrom()" data-ng-show="importUrl" class="btn btn-primary">{{:: 'import' | translate}}</button> + </div> + </div> + <div class="form-group" data-ng-show="newIdentityProvider"> + <label class="col-md-2 control-label">{{:: 'import-from-file' | translate}}</label> + <kc-tooltip>{{:: 'identity-provider.import-from-file.tooltip' | translate}}</kc-tooltip> + <div class="col-md-6"> + <div class="controls kc-button-input-file" data-ng-show="!files || files.length == 0"> + <label for="import-file" class="btn btn-default">{{:: 'select-file' | translate}} <i class="pficon pficon-import"></i></label> + <input id="import-file" type="file" class="hidden" ng-file-select="onFileSelect($files)"> + </div> + <span class="kc-uploaded-file" data-ng-show="files.length > 0"> + {{files[0].name}} + </span> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="importFile"></label> + <div class="col-md-6" data-ng-show="importFile"> + <button id="importFile" type="button" data-ng-click="uploadFile()" data-ng-show="importFile" class="btn btn-primary">{{:: 'import' | translate}}</button> + </div> + </div> + </div> + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()" data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/realm-identity-provider-openshift-v3-ext.html b/admin/resources/partials/realm-identity-provider-openshift-v3-ext.html new file mode 100644 index 0000000..b1c27de --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-openshift-v3-ext.html @@ -0,0 +1,7 @@ +<div class="form-group clearfix"> + <label class="col-md-2 control-label" for="baseUrl"><span class="required">*</span> {{:: 'openshift.base-url' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="baseUrl" type="text" ng-model="identityProvider.config.baseUrl" required> + </div> + <kc-tooltip>{{:: 'openshift.base-url.tooltip' | translate}}</kc-tooltip> +</div> diff --git a/admin/resources/partials/realm-identity-provider-openshift-v3.html b/admin/resources/partials/realm-identity-provider-openshift-v3.html new file mode 100644 index 0000000..eb42ba1 --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-openshift-v3.html @@ -0,0 +1,164 @@ +<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}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li> + <li data-ng-hide="newIdentityProvider">{{provider.name}}</li> + <li data-ng-show="newIdentityProvider">{{:: 'add-identity-provider' | translate}}</li> + </ol> + + <kc-tabs-identity-provider></kc-tabs-identity-provider> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageIdentityProviders"> + <fieldset> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="redirectUri">{{:: 'redirect-uri' | translate}}</label> + <div class="col-sm-6"> + <input class="form-control" id="redirectUri" type="text" value="{{callbackUrl}}{{identityProvider.alias}}/endpoint" readonly kc-select-action="click"> + </div> + <kc-tooltip>{{:: 'redirect-uri.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + <fieldset> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="identifier"><span class="required">*</span> {{:: 'alias' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="identifier" type="text" ng-model="identityProvider.alias" data-ng-readonly="!newIdentityProvider" required> + </div> + <kc-tooltip>{{:: 'identity-provider.alias.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="displayName"> {{:: 'display-name' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="displayName" type="text" ng-model="identityProvider.displayName"> + </div> + <kc-tooltip>{{:: 'identity-provider.display-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="clientId"><span class="required">*</span> {{:: 'client-id' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="clientId" type="text" ng-model="identityProvider.config.clientId" required> + </div> + <kc-tooltip>{{:: 'social.client-id.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="clientSecret"><span class="required">*</span> {{:: 'client-secret' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="clientSecret" kc-password ng-model="identityProvider.config.clientSecret" required> + </div> + <kc-tooltip>{{:: 'social.client-secret.tooltip' | translate}}</kc-tooltip> + </div> + <div data-ng-include data-src="resourceUrl + '/partials/realm-identity-provider-' + identityProvider.providerId + '-ext.html'"></div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="defaultScope">{{:: 'default-scopes' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="defaultScope" type="text" ng-model="identityProvider.config.defaultScope"> + </div> + <kc-tooltip>{{:: 'social.default-scopes.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="enabled">{{:: 'store-tokens' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.storeToken" id="storeToken" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.store-tokens.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="storedTokensReadable">{{:: 'stored-tokens-readable' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.addReadTokenRoleOnCreate" id="storedTokensReadable" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.stored-tokens-readable.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.enabled" id="enabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.enabled.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="disableUserInfo">{{:: 'disableUserInfo' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.disableUserInfo" id="disableUserInfo" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.disableUserInfo.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="trustEmail">{{:: 'trust-email' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.trustEmail" name="identityProvider.trustEmail" id="trustEmail" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'trust-email.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="linkOnly">{{:: 'link-only' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.linkOnly" name="identityProvider.trustEmail" id="linkOnly" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'link-only.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="hideOnLoginPage">{{:: 'hide-on-login-page' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.hideOnLoginPage" name="identityProvider.config.hideOnLoginPage" id="hideOnLoginPage" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'hide-on-login-page.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="guiOrder">{{:: 'gui-order' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="guiOrder" type="text" ng-model="identityProvider.config.guiOrder"> + </div> + <kc-tooltip>{{:: 'gui-order.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="firstBrokerLoginFlowAlias">{{:: 'first-broker-login-flow' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="firstBrokerLoginFlowAlias" + ng-model="identityProvider.firstBrokerLoginFlowAlias" + ng-options="flow.alias as flow.alias for flow in authFlows" + required> + </select> + </div> + </div> + <kc-tooltip>{{:: 'first-broker-login-flow.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="postBrokerLoginFlowAlias">{{:: 'post-broker-login-flow' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="postBrokerLoginFlowAlias" + ng-model="identityProvider.postBrokerLoginFlowAlias" + ng-options="flow.alias as flow.alias for flow in postBrokerAuthFlows"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'post-broker-login-flow.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="syncMode">{{:: 'sync-mode' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="syncMode" + ng-model="identityProvider.config.syncMode" + required> + <option id="syncMode_import" name="syncMode" value="IMPORT">{{:: 'sync-mode.import' | translate}}</option> + <option id="syncMode_legacy" name="syncMode" value="LEGACY">{{:: 'sync-mode.legacy' | translate}}</option> + <option id="syncMode_force" name="syncMode" value="FORCE">{{:: 'sync-mode.force' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'sync-mode.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()" data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-identity-provider-openshift-v4-ext.html b/admin/resources/partials/realm-identity-provider-openshift-v4-ext.html new file mode 100644 index 0000000..46254be --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-openshift-v4-ext.html @@ -0,0 +1,7 @@ +<div class="form-group clearfix"> + <label class="col-md-2 control-label" for="baseUrl"><span class="required">*</span> {{:: 'openshift4.base-url' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="baseUrl" type="text" ng-model="identityProvider.config.baseUrl" required> + </div> + <kc-tooltip>{{:: 'openshift4.base-url.tooltip' | translate}}</kc-tooltip> +</div> diff --git a/admin/resources/partials/realm-identity-provider-openshift-v4.html b/admin/resources/partials/realm-identity-provider-openshift-v4.html new file mode 100644 index 0000000..9e14154 --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-openshift-v4.html @@ -0,0 +1,164 @@ +<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}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li> + <li data-ng-hide="newIdentityProvider">{{provider.name}}</li> + <li data-ng-show="newIdentityProvider">{{:: 'add-identity-provider' | translate}}</li> + </ol> + + <kc-tabs-identity-provider></kc-tabs-identity-provider> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageIdentityProviders"> + <fieldset> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="redirectUri">{{:: 'redirect-uri' | translate}}</label> + <div class="col-sm-6"> + <input class="form-control" id="redirectUri" type="text" value="{{callbackUrl}}{{identityProvider.alias}}/endpoint" readonly kc-select-action="click"> + </div> + <kc-tooltip>{{:: 'redirect-uri.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + <fieldset> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="identifier"><span class="required">*</span> {{:: 'alias' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="identifier" type="text" ng-model="identityProvider.alias" data-ng-readonly="!newIdentityProvider" required> + </div> + <kc-tooltip>{{:: 'identity-provider.alias.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="displayName"> {{:: 'display-name' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="displayName" type="text" ng-model="identityProvider.displayName"> + </div> + <kc-tooltip>{{:: 'identity-provider.display-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="clientId"><span class="required">*</span> {{:: 'client-id' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="clientId" type="text" ng-model="identityProvider.config.clientId" required> + </div> + <kc-tooltip>{{:: 'social.client-id.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="clientSecret"><span class="required">*</span> {{:: 'client-secret' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="clientSecret" kc-password ng-model="identityProvider.config.clientSecret" required> + </div> + <kc-tooltip>{{:: 'social.client-secret.tooltip' | translate}}</kc-tooltip> + </div> + <div data-ng-include data-src="resourceUrl + '/partials/realm-identity-provider-' + identityProvider.providerId + '-ext.html'"></div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="defaultScope">{{:: 'default-scopes' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="defaultScope" type="text" ng-model="identityProvider.config.defaultScope"> + </div> + <kc-tooltip>{{:: 'social.default-scopes.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="storeToken">{{:: 'store-tokens' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.storeToken" id="storeToken" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.store-tokens.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="storedTokensReadable">{{:: 'stored-tokens-readable' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.addReadTokenRoleOnCreate" id="storedTokensReadable" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.stored-tokens-readable.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.enabled" id="enabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.enabled.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="disableUserInfo">{{:: 'disableUserInfo' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.disableUserInfo" id="disableUserInfo" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.disableUserInfo.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="trustEmail">{{:: 'trust-email' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.trustEmail" name="identityProvider.trustEmail" id="trustEmail" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'trust-email.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="linkOnly">{{:: 'link-only' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.linkOnly" name="identityProvider.trustEmail" id="linkOnly" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'linkOnly.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="hideOnLoginPage">{{:: 'hide-on-login-page' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.hideOnLoginPage" name="identityProvider.config.hideOnLoginPage" id="hideOnLoginPage" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'hide-on-login-page.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="guiOrder">{{:: 'gui-order' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="guiOrder" type="text" ng-model="identityProvider.config.guiOrder"> + </div> + <kc-tooltip>{{:: 'gui-order.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="firstBrokerLoginFlowAlias">{{:: 'first-broker-login-flow' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="firstBrokerLoginFlowAlias" + ng-model="identityProvider.firstBrokerLoginFlowAlias" + ng-options="flow.alias as flow.alias for flow in authFlows" + required> + </select> + </div> + </div> + <kc-tooltip>{{:: 'first-broker-login-flow.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="postBrokerLoginFlowAlias">{{:: 'post-broker-login-flow' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="postBrokerLoginFlowAlias" + ng-model="identityProvider.postBrokerLoginFlowAlias" + ng-options="flow.alias as flow.alias for flow in postBrokerAuthFlows"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'post-broker-login-flow.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="syncMode">{{:: 'sync-mode' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="syncMode" + ng-model="identityProvider.config.syncMode" + required> + <option id="syncMode_import" name="syncMode" value="IMPORT">{{:: 'sync-mode.import' | translate}}</option> + <option id="syncMode_legacy" name="syncMode" value="LEGACY">{{:: 'sync-mode.legacy' | translate}}</option> + <option id="syncMode_force" name="syncMode" value="FORCE">{{:: 'sync-mode.force' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'sync-mode.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()" data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-identity-provider-paypal-ext.html b/admin/resources/partials/realm-identity-provider-paypal-ext.html new file mode 100644 index 0000000..692a078 --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-paypal-ext.html @@ -0,0 +1,7 @@ +<div class="form-group"> + <label class="col-md-2 control-label" for="sandbox">{{:: 'sandbox' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.sandbox" id="sandbox" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.paypal-sandbox.tooltip' | translate}}</kc-tooltip> +</div>
\ No newline at end of file diff --git a/admin/resources/partials/realm-identity-provider-paypal.html b/admin/resources/partials/realm-identity-provider-paypal.html new file mode 100644 index 0000000..62e97ba --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-paypal.html @@ -0,0 +1 @@ +<div data-ng-include data-src="resourceUrl + '/partials/realm-identity-provider-social.html'"></div> diff --git a/admin/resources/partials/realm-identity-provider-saml.html b/admin/resources/partials/realm-identity-provider-saml.html new file mode 100644 index 0000000..7267cee --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-saml.html @@ -0,0 +1,315 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2" data-ng-init="initSamlProvider()"> + <ol class="breadcrumb"> + <li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li> + <li data-ng-show="!newIdentityProvider && identityProvider.displayName">{{identityProvider.displayName}}</li> + <li data-ng-show="!newIdentityProvider && !identityProvider.displayName">{{identityProvider.alias}}</li> + <li data-ng-show="newIdentityProvider">{{:: 'add-identity-provider' | translate}}</li> + </ol> + + <kc-tabs-identity-provider></kc-tabs-identity-provider> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageIdentityProviders"> + <fieldset> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="redirectUri">{{:: 'redirect-uri' | translate}}</label> + <div class="col-sm-6"> + <input class="form-control" id="redirectUri" type="text" value="{{callbackUrl}}{{identityProvider.alias}}/endpoint" readonly kc-select-action="click"> + </div> + <kc-tooltip>{{:: 'redirect-uri.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + <fieldset> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="identifier"><span class="required">*</span> {{:: 'alias' | translate}}</label> + <div class="col-md-6"> + <input kc-no-reserved-chars class="form-control" id="identifier" type="text" ng-model="identityProvider.alias" data-ng-readonly="!newIdentityProvider" required> + </div> + <kc-tooltip>{{:: 'identity-provider.alias.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="displayName"> {{:: 'display-name' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="displayName" type="text" ng-model="identityProvider.displayName"> + </div> + <kc-tooltip>{{:: 'identity-provider.display-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.enabled" id="enabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.enabled.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="storeToken">{{:: 'store-tokens' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.storeToken" id="storeToken" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.store-tokens.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="storedTokensReadable">{{:: 'stored-tokens-readable' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.addReadTokenRoleOnCreate" id="storedTokensReadable" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.stored-tokens-readable.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="trustEmail">{{:: 'trust-email' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.trustEmail" name="identityProvider.trustEmail" id="trustEmail" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'trust-email.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="linkOnly">{{:: 'link-only' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.linkOnly" name="identityProvider.trustEmail" id="linkOnly" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'link-only.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="hideOnLoginPage">{{:: 'hide-on-login-page' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.hideOnLoginPage" name="identityProvider.config.hideOnLoginPage" id="hideOnLoginPage" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'hide-on-login-page.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="guiOrder">{{:: 'gui-order' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="guiOrder" type="text" ng-model="identityProvider.config.guiOrder"> + </div> + <kc-tooltip>{{:: 'gui-order.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="firstBrokerLoginFlowAlias">{{:: 'first-broker-login-flow' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="firstBrokerLoginFlowAlias" + ng-model="identityProvider.firstBrokerLoginFlowAlias" + ng-options="flow.alias as flow.alias for flow in authFlows" + required> + </select> + </div> + </div> + <kc-tooltip>{{:: 'first-broker-login-flow.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="postBrokerLoginFlowAlias">{{:: 'post-broker-login-flow' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="postBrokerLoginFlowAlias" + ng-model="identityProvider.postBrokerLoginFlowAlias" + ng-options="flow.alias as flow.alias for flow in postBrokerAuthFlows"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'post-broker-login-flow.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="syncMode">{{:: 'sync-mode' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="syncMode" + ng-model="identityProvider.config.syncMode" + required> + <option id="syncMode_import" name="syncMode" value="IMPORT">{{:: 'sync-mode.import' | translate}}</option> + <option id="syncMode_legacy" name="syncMode" value="LEGACY">{{:: 'sync-mode.legacy' | translate}}</option> + <option id="syncMode_force" name="syncMode" value="FORCE">{{:: 'sync-mode.force' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'sync-mode.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + <fieldset> + <legend uncollapsed><span class="text">{{:: 'saml-config' | translate}}</span> <kc-tooltip>{{:: 'identity-provider.saml-config.tooltip' | translate}}</kc-tooltip></legend> + + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="singleSignOnServiceUrl"><span class="required">*</span> {{:: 'single-signon-service-url' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="singleSignOnServiceUrl" type="text" ng-model="identityProvider.config.singleSignOnServiceUrl" required> + </div> + <kc-tooltip>{{:: 'saml.single-signon-service-url.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="singleSignOnServiceUrl">{{:: 'single-logout-service-url' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="singleLogoutServiceUrl" type="text" ng-model="identityProvider.config.singleLogoutServiceUrl"> + </div> + <kc-tooltip>{{:: 'saml.single-logout-service-url.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-sm-2 control-label" for="backchannelSupported">{{:: 'backchannel-logout' | translate}}</label> + <div class="col-sm-4"> + <input ng-model="identityProvider.config.backchannelSupported" id="backchannelSupported" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'backchannel-logout.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="nameIDPolicyFormat">{{:: 'nameid-policy-format' | translate}}</label> + <div class="col-md-6"> + <select id="nameIDPolicyFormat" ng-model="identityProvider.config.nameIDPolicyFormat" + ng-options="nameFormat.format as nameFormat.name for nameFormat in nameIdFormats"> + </select> + <!-- <input class="form-control" id="nameIDPolicyFormat" type="text" ng-model="identityProvider.config.nameIDPolicyFormat"> --> + </div> + <kc-tooltip>{{:: 'nameid-policy-format.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="principalType">{{:: 'saml.principal-type' | translate}}</label> + <div class="col-md-6"> + <select id="principalType" ng-model="identityProvider.config.principalType" + ng-options="pType.type as pType.name for pType in principalTypes"> + </select> + </div> + <kc-tooltip>{{:: 'saml.principal-type.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="identityProvider.config.principalType.endsWith('ATTRIBUTE')"> + <label class="col-md-2 control-label" for="principalAttribute">{{:: 'saml.principal-attribute' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="principalAttribute" type="text" ng-model="identityProvider.config.principalAttribute" ng-required="identityProvider.config.principalType.endsWith('ATTRIBUTE')"> + </div> + <kc-tooltip>{{:: 'saml.principal-attribute.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="postBindingResponse">{{:: 'http-post-binding-response' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.postBindingResponse" id="postBindingResponse" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'http-post-binding-response.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="postBindingAuthnRequest">{{:: 'http-post-binding-for-authn-request' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.postBindingAuthnRequest" id="postBindingAuthnRequest" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'http-post-binding-for-authn-request.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="postBindingLogout">{{:: 'http-post-binding-logout' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.postBindingLogout" id="postBindingLogout" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'http-post-binding-logout.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="wantAuthnRequestsSigned">{{:: 'want-authn-requests-signed' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.wantAuthnRequestsSigned" id="wantAuthnRequestsSigned" name="wantAuthnRequestsSigned" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'want-authn-requests-signed.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="wantAssertionsSigned">{{:: 'want-assertions-signed' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.wantAssertionsSigned" id="wantAssertionsSigned" name="wantAssertionsSigned" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'want-assertions-signed.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="wantAssertionsEncrypted">{{:: 'want-assertions-encrypted' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.wantAssertionsEncrypted" id="wantAssertionsEncrypted" name="wantAssertionsEncrypted" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'want-assertions-encrypted.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="identityProvider.config.wantAuthnRequestsSigned == 'true'"> + <label class="col-md-2 control-label" for="signatureAlgorithm">{{:: 'signature-algorithm' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="signatureAlgorithm" + ng-model="identityProvider.config.signatureAlgorithm" + ng-options="alg for alg in signatureAlgorithms"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'signature-algorithm.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="identityProvider.config.wantAuthnRequestsSigned == 'true'"> + <label class="col-md-2 control-label" for="samlSigKeyNameTranformer">{{:: 'saml-signature-keyName-transformer' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="samlSigKeyNameTranformer" + ng-model="identityProvider.config.xmlSigKeyInfoKeyNameTransformer" + ng-options="xmlKeyNameTranformer for xmlKeyNameTranformer in xmlKeyNameTranformers"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'saml-signature-keyName-transformer.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="forceAuthn">{{:: 'force-authentication' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.forceAuthn" id="forceAuthn" name="forceAuthn" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.force-authentication.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="validateSignature">{{:: 'validate-signature' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.validateSignature" id="validateSignature" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'saml.validate-signature.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="identityProvider.config.validateSignature == 'true'"> + <label class="col-md-2 control-label" for="signingCertificate">{{:: 'validating-x509-certificate' | translate}}</label> + <div class="col-md-6"> + <textarea class="form-control" id="signingCertificate" ng-model="identityProvider.config.signingCertificate"/> + </div> + <kc-tooltip>{{:: 'validating-x509-certificate.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="allowedClockSkew">{{:: 'allowed-clock-skew' | translate}}</label> + <div class="col-md-6 time-selector"> + <input class="form-control" string-to-number type="number" min="0" max="2147483" step="1" ng-model="identityProvider.config.allowedClockSkew" id="allowedClockSkew"/> + </div> + <kc-tooltip>{{:: 'identity-provider.allowed-clock-skew.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + <fieldset data-ng-show="newIdentityProvider"> + <legend uncollapsed><span class="text">{{:: 'import-external-idp-config' | translate}}</span> <kc-tooltip>{{:: 'import-external-idp-config.tooltip' | translate}}</kc-tooltip></legend> + <div class="form-group" data-ng-show="newIdentityProvider"> + <label class="col-md-2 control-label" for="fromUrl">{{:: 'import-from-url' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="fromUrl" type="text" ng-model="fromUrl.data"> + </div> + <kc-tooltip>{{:: 'saml.import-from-url.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="importFrom"></label> + <div class="col-md-6"> + <button id="importFrom" type="button" data-ng-click="importFrom()" data-ng-show="importUrl" class="btn btn-primary">{{:: 'import' | translate}}</button> + </div> + </div> + <div class="form-group" data-ng-show="newIdentityProvider"> + <label class="col-md-2 control-label">{{:: 'import-from-file' | translate}}</label> + <div class="col-md-6"> + <div class="controls kc-button-input-file" data-ng-show="!files || files.length == 0"> + <label for="import-file" class="btn btn-default">{{:: 'select-file' | translate}} <i class="pficon pficon-import"></i></label> + <input id="import-file" type="file" class="hidden" ng-file-select="onFileSelect($files)"> + </div> + <span class="kc-uploaded-file" data-ng-show="files.length > 0"> + {{files[0].name}} + </span> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="importFile"></label> + <div class="col-sm-6" data-ng-show="importFile"> + <button id="importFile" type="button" data-ng-click="uploadFile()" data-ng-show="importFile" class="btn btn-primary">{{:: 'import' | translate}}</button> + </div> + </div> + </div> + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()" data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/realm-identity-provider-social.html b/admin/resources/partials/realm-identity-provider-social.html new file mode 100644 index 0000000..b745634 --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-social.html @@ -0,0 +1,157 @@ +<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}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li> + <li data-ng-hide="newIdentityProvider">{{provider.name}}</li> + <li data-ng-show="newIdentityProvider">{{:: 'add-identity-provider' | translate}}</li> + </ol> + + <kc-tabs-identity-provider></kc-tabs-identity-provider> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageIdentityProviders"> + <fieldset> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="redirectUri">{{:: 'redirect-uri' | translate}}</label> + <div class="col-sm-6"> + <input class="form-control" id="redirectUri" type="text" value="{{callbackUrl}}{{identityProvider.alias}}/endpoint" readonly kc-select-action="click"> + </div> + <kc-tooltip>{{:: 'redirect-uri.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + <fieldset> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="clientId"><span class="required">*</span> {{:: 'client-id' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="clientId" type="text" ng-model="identityProvider.config.clientId" required> + </div> + <kc-tooltip>{{:: 'social.client-id.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="clientSecret"><span class="required">*</span> {{:: 'client-secret' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="clientSecret" kc-password ng-model="identityProvider.config.clientSecret" required> + </div> + <kc-tooltip>{{:: 'social.client-secret.tooltip' | translate}}</kc-tooltip> + </div> + <div data-ng-include data-src="resourceUrl + '/partials/realm-identity-provider-' + identityProvider.providerId + '-ext.html'"></div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="defaultScope">{{:: 'default-scopes' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="defaultScope" type="text" ng-model="identityProvider.config.defaultScope"> + </div> + <kc-tooltip>{{:: 'social.default-scopes.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="enabled">{{:: 'store-tokens' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.storeToken" id="storeToken" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.store-tokens.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="storedTokensReadable">{{:: 'stored-tokens-readable' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.addReadTokenRoleOnCreate" id="storedTokensReadable" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.stored-tokens-readable.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.enabled" id="enabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.enabled.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="acceptsPromptNoneForwardFromClient">{{:: 'accepts-prompt-none-forward-from-client' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.acceptsPromptNoneForwardFromClient" id="acceptsPromptNoneForwardFromClient" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'accepts-prompt-none-forward-from-client.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="disableUserInfo">{{:: 'disableUserInfo' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.disableUserInfo" id="disableUserInfo" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'identity-provider.disableUserInfo.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="trustEmail">{{:: 'trust-email' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.trustEmail" name="identityProvider.trustEmail" id="trustEmail" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'trust-email.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="linkOnly">{{:: 'link-only' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.linkOnly" name="identityProvider.trustEmail" id="linkOnly" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'link-only.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="hideOnLoginPage">{{:: 'hide-on-login-page' | translate}}</label> + <div class="col-md-6"> + <input ng-model="identityProvider.config.hideOnLoginPage" name="identityProvider.config.hideOnLoginPage" id="hideOnLoginPage" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'hide-on-login-page.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="guiOrder">{{:: 'gui-order' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="guiOrder" type="text" ng-model="identityProvider.config.guiOrder"> + </div> + <kc-tooltip>{{:: 'gui-order.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="firstBrokerLoginFlowAlias">{{:: 'first-broker-login-flow' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="firstBrokerLoginFlowAlias" + ng-model="identityProvider.firstBrokerLoginFlowAlias" + ng-options="flow.alias as flow.alias for flow in authFlows" + required> + </select> + </div> + </div> + <kc-tooltip>{{:: 'first-broker-login-flow.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="postBrokerLoginFlowAlias">{{:: 'post-broker-login-flow' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="postBrokerLoginFlowAlias" + ng-model="identityProvider.postBrokerLoginFlowAlias" + ng-options="flow.alias as flow.alias for flow in postBrokerAuthFlows"> + </select> + </div> + </div> + <kc-tooltip>{{:: 'post-broker-login-flow.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="syncMode">{{:: 'sync-mode' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="syncMode" + ng-model="identityProvider.config.syncMode" + required> + <option id="syncMode_import" name="syncMode" value="IMPORT">{{:: 'sync-mode.import' | translate}}</option> + <option id="syncMode_legacy" name="syncMode" value="LEGACY">{{:: 'sync-mode.legacy' | translate}}</option> + <option id="syncMode_force" name="syncMode" value="FORCE">{{:: 'sync-mode.force' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'sync-mode.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()" data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-identity-provider-stackoverflow-ext.html b/admin/resources/partials/realm-identity-provider-stackoverflow-ext.html new file mode 100644 index 0000000..5e478f6 --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-stackoverflow-ext.html @@ -0,0 +1,7 @@ +<div class="form-group clearfix"> + <label class="col-md-2 control-label" for="clientId">{{:: 'key' | translate}} <span class="required">*</span></label> + <div class="col-md-6"> + <input class="form-control" id="clientId" type="text" ng-model="identityProvider.config.key" required> + </div> + <kc-tooltip>{{:: 'stackoverflow.key.tooltip' | translate}}</kc-tooltip> +</div> diff --git a/admin/resources/partials/realm-identity-provider-stackoverflow.html b/admin/resources/partials/realm-identity-provider-stackoverflow.html new file mode 100644 index 0000000..a4630ac --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-stackoverflow.html @@ -0,0 +1 @@ +<div data-ng-include data-src="resourceUrl + '/partials/realm-identity-provider-social.html'"></div>
\ No newline at end of file diff --git a/admin/resources/partials/realm-identity-provider-twitter-ext.html b/admin/resources/partials/realm-identity-provider-twitter-ext.html new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-twitter-ext.html diff --git a/admin/resources/partials/realm-identity-provider-twitter.html b/admin/resources/partials/realm-identity-provider-twitter.html new file mode 100644 index 0000000..a4630ac --- /dev/null +++ b/admin/resources/partials/realm-identity-provider-twitter.html @@ -0,0 +1 @@ +<div data-ng-include data-src="resourceUrl + '/partials/realm-identity-provider-social.html'"></div>
\ No newline at end of file diff --git a/admin/resources/partials/realm-identity-provider.html b/admin/resources/partials/realm-identity-provider.html new file mode 100644 index 0000000..3422752 --- /dev/null +++ b/admin/resources/partials/realm-identity-provider.html @@ -0,0 +1,81 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1>{{:: 'identity-providers' | translate}}</h1> + <div class="blank-slate-pf" data-ng-hide="configuredProviders.length > 0"> + <div class="blank-slate-pf-icon"> + <span class="fa fa-exchange"></span> + </div> + <h1> + {{:: '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. + </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.manageIdentityProviders"> + <div class="col-sm-4 col-sm-offset-4"> + <div class="form-group"> + <select class="form-control" ng-model="provider" + ng-options="p.name group by p.groupName for p in allProviders track by p.id" + data-ng-change="addProvider(provider); provider = null"> + <option value="" disabled selected>{{:: 'add-provider.placeholder' | translate}}</option> + </select> + </div> + </div> +</div> +</div> + +</div> + <form name="realmForm" novalidate class="form-horizontal" ng-show="configuredProviders.length > 0"> + <fieldset> + <div> + <table class="table table-striped table-bordered"> + <caption class="hidden">{{:: 'table-of-identity-providers' | translate}}</caption> + <thead> + <tr> + <th colspan="8" class="kc-table-actions"> + <div class="dropdown pull-right" data-ng-show="access.manageIdentityProviders"> + <select class="form-control" ng-model="provider" + ng-options="p.name group by p.groupName for p in allProviders track by p.id" + data-ng-change="addProvider(provider); provider = null"> + <option value="" disabled selected>{{:: 'add-provider.placeholder' | translate}}</option> + </select> + </div> + </th> + </tr> + <tr> + <th>{{:: 'name' | translate}}</th> + <th>{{:: 'provider' | translate}}</th> + <th>{{:: 'enabled' | translate}}</th> + <th>{{:: 'hidden' | translate}}</th> + <th>{{:: 'link-only-column' | translate}}</th> + <th width="15%">{{:: 'gui-order' | translate}}</th> + <th colspan="2">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="identityProvider in configuredProviders"> + <td> + <a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}"> + <span data-ng-show="identityProvider.displayName">{{identityProvider.displayName}}</span> + <span data-ng-show="!identityProvider.displayName && identityProvider.provider.groupName == 'Social'">{{identityProvider.provider.name}}</span> + <span data-ng-show="!identityProvider.displayName && identityProvider.provider.groupName != 'Social'">{{identityProvider.alias}}</span> + </a> + </td> + <td>{{identityProvider.providerId}}</td> + <td translate="{{identityProvider.enabled}}"></td> + <td translate="{{identityProvider.config.hideOnLoginPage == 'true'}}"></td> + <td translate="{{identityProvider.linkOnly}}"></td> + <td>{{identityProvider.config.guiOrder}}</td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">{{:: 'edit' | translate}}</td> + <td class="kc-action-cell" data-ng-show="access.manageIdentityProviders" data-ng-click="removeIdentityProvider(identityProvider)">{{:: 'delete' | translate}}</td> + </tr> + </tbody> + </table> + </div> + </fieldset> + </form> +</div> + + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-keys-disabled.html b/admin/resources/partials/realm-keys-disabled.html new file mode 100644 index 0000000..242c841 --- /dev/null +++ b/admin/resources/partials/realm-keys-disabled.html @@ -0,0 +1,70 @@ +<!-- + ~ Copyright 2016 Red Hat, Inc. and/or its affiliates + ~ and other contributors as indicated by the @author tags. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <kc-tabs-realm></kc-tabs-realm> + + <ul class="nav nav-tabs nav-tabs-pf"> + <li><a href="#/realms/{{realm.realm}}/keys">{{:: 'active' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/keys/passive">{{:: 'passive' | translate}}</a></li> + <li class="active"><a href="#/realms/{{realm.realm}}/keys/disabled">{{:: 'disabled' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/keys/providers">{{:: 'providers' | translate}}</a></li> + </ul> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="7"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" data-ng-model="search" class="form-control search""> + <div class="input-group-addon"> + <i class="fa fa-search"></i> + </div> + </div> + </div> + </div> + </th> + </tr> + <tr> + <th>{{:: 'algorithm' | translate}}</th> + <th>{{:: 'type' | translate}}</th> + <th>{{:: 'kid' | translate}}</th> + <th>{{:: 'priority' | translate}}</th> + <th>{{:: 'provider' | translate}}</th> + <th colspan="2">{{:: 'publicKeys' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="key in keys | filter:search | filter:{status:'DISABLED'}"> + <td>{{key.algorithm}}</td> + <td>{{key.type}}</td> + <td>{{key.kid}}</td> + <td>{{key.providerPriority}}</td> + <td><a href="#/realms/{{realm.realm}}/keys/providers/{{key.provider.providerId}}/{{key.provider.id}}">{{key.provider.name}}</a></td> + + <td data-ng-show="!key.publicKey" colspan="2"></td> + <td class="kc-action-cell" data-ng-show="key.publicKey" class="kc-action-cell" data-ng-click="viewKey(key.publicKey)" colspan="{{key.certificate ? 1 : 2}}">{{:: 'publicKey' | translate}}</td> + <td data-ng-show="key.certificate" class="kc-action-cell" data-ng-click="viewKey(key.certificate)">{{:: 'certificate' | translate}}</td> + </tr> + </tbody> + </table> + +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-keys-generic.html b/admin/resources/partials/realm-keys-generic.html new file mode 100644 index 0000000..dd2017a --- /dev/null +++ b/admin/resources/partials/realm-keys-generic.html @@ -0,0 +1,69 @@ +<!-- + ~ Copyright 2016 Red Hat, Inc. and/or its affiliates + ~ and other contributors as indicated by the @author tags. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <kc-tabs-realm></kc-tabs-realm> + + <ul class="nav nav-tabs nav-tabs-pf"> + <li><a href="#/realms/{{realm.realm}}/keys">{{:: 'active' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/keys/passive">{{:: 'passive' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/keys/disabled">{{:: 'disabled' | translate}}</a></li> + <li class="active"><a href="#/realms/{{realm.realm}}/keys/providers">{{:: 'providers' | translate}}</a></li> + </ul> + + <ol class="breadcrumb"> + <li><a href="#/realms/{{realm.realm}}/keys/providers">{{:: 'keystores' | translate}}</a></li> + <li data-ng-hide="create">{{instance.id}}</li> + <li data-ng-show="create">{{:: 'add-keystore' | translate}}</li> + </ol> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <fieldset> + <div class="form-group clearfix" data-ng-show="!create"> + <label class="col-md-2 control-label" for="providerId">{{:: 'provider-id' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="providerId" type="text" ng-model="instance.id" readonly> + </div> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="consoleDisplayName">{{:: 'console-display-name' | translate}} </label> + <div class="col-md-6"> + <input required class="form-control" id="consoleDisplayName" type="text" ng-model="instance.name" placeholder="{{:: 'defaults-to-id' | translate}}"> + </div> + <kc-tooltip>{{:: 'console-display-name.tooltip' | translate}}</kc-tooltip> + </div> + + <kc-component-config realm="realm" config="instance.config" properties="providerFactory.properties"></kc-component-config> + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="create && access.manageRealm"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-disabled="!changed" data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="!create && access.manageRealm"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-keys-passive.html b/admin/resources/partials/realm-keys-passive.html new file mode 100644 index 0000000..65f934a --- /dev/null +++ b/admin/resources/partials/realm-keys-passive.html @@ -0,0 +1,70 @@ +<!-- + ~ Copyright 2016 Red Hat, Inc. and/or its affiliates + ~ and other contributors as indicated by the @author tags. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <kc-tabs-realm></kc-tabs-realm> + + <ul class="nav nav-tabs nav-tabs-pf"> + <li><a href="#/realms/{{realm.realm}}/keys">{{:: 'active' | translate}}</a></li> + <li class="active"><a href="#/realms/{{realm.realm}}/keys/passive">{{:: 'passive' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/keys/disabled">{{:: 'disabled' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/keys/providers">{{:: 'providers' | translate}}</a></li> + </ul> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="7"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" data-ng-model="search" class="form-control search""> + <div class="input-group-addon"> + <i class="fa fa-search"></i> + </div> + </div> + </div> + </div> + </th> + </tr> + <tr> + <th>{{:: 'algorithm' | translate}}</th> + <th>{{:: 'type' | translate}}</th> + <th>{{:: 'kid' | translate}}</th> + <th>{{:: 'priority' | translate}}</th> + <th>{{:: 'provider' | translate}}</th> + <th colspan="2">{{:: 'publicKeys' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="key in keys | filter:search | filter:{status:'PASSIVE'}"> + <td>{{key.algorithm}}</td> + <td>{{key.type}}</td> + <td>{{key.kid}}</td> + <td>{{key.providerPriority}}</td> + <td><a href="#/realms/{{realm.realm}}/keys/providers/{{key.provider.providerId}}/{{key.provider.id}}">{{key.provider.name}}</a></td> + + <td data-ng-show="!key.publicKey" colspan="2"></td> + <td class="kc-action-cell" data-ng-show="key.publicKey" class="kc-action-cell" data-ng-click="viewKey(key.publicKey)" colspan="{{key.certificate ? 1 : 2}}">{{:: 'publicKey' | translate}}</td> + <td data-ng-show="key.certificate" class="kc-action-cell" data-ng-click="viewKey(key.certificate)">{{:: 'certificate' | translate}}</td> + </tr> + </tbody> + </table> + +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-keys-providers.html b/admin/resources/partials/realm-keys-providers.html new file mode 100644 index 0000000..c303a38 --- /dev/null +++ b/admin/resources/partials/realm-keys-providers.html @@ -0,0 +1,75 @@ +<!-- + ~ Copyright 2016 Red Hat, Inc. and/or its affiliates + ~ and other contributors as indicated by the @author tags. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <kc-tabs-realm></kc-tabs-realm> + + <ul class="nav nav-tabs nav-tabs-pf"> + <li><a href="#/realms/{{realm.realm}}/keys">{{:: 'active' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/keys/passive">{{:: 'passive' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/keys/disabled">{{:: 'disabled' | translate}}</a></li> + <li class="active"><a href="#/realms/{{realm.realm}}/keys/providers">{{:: 'providers' | translate}}</a></li> + </ul> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="7"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" data-ng-model="search" class="form-control search"> + <div class="input-group-addon"> + <i class="fa fa-search"></i> + </div> + </div> + </div> + + <div class="pull-right" data-ng-show="access.manageClients"> + <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-keystore.placeholder' | translate}}</option> + </select> + </div> + </div> + </th> + </tr> + <tr data-ng-show="instances && instances.length > 0"> + <th>{{:: 'name' | translate}}</th> + <th>{{:: 'provider' | translate}}</th> + <th>{{:: 'providerHelpText' | translate}}</th> + <th>{{:: 'priority' | translate}}</th> + <th colspan="2">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="instance in instances | filter:search"> + <td><a href="#/realms/{{realm.realm}}/keys/providers/{{instance.providerId}}/{{instance.id}}">{{instance.name}}</a></td> + <td>{{instance.providerId}}</td> + <td>{{instance.provider.helpText}}</td> + <td>{{instance.config['priority'][0]}}</td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/keys/providers/{{instance.providerId}}/{{instance.id}}">{{:: 'edit' | translate}}</td> + <td class="kc-action-cell" ng-show="instances.length > 1" data-ng-click="removeInstance(instance)">{{:: 'delete' | translate}}</td> + </tr> + </tbody> + </table> + +</div> + + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-keys.html b/admin/resources/partials/realm-keys.html new file mode 100644 index 0000000..3f73682 --- /dev/null +++ b/admin/resources/partials/realm-keys.html @@ -0,0 +1,71 @@ +<!-- + ~ Copyright 2016 Red Hat, Inc. and/or its affiliates + ~ and other contributors as indicated by the @author tags. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <kc-tabs-realm></kc-tabs-realm> + + <ul class="nav nav-tabs nav-tabs-pf"> + <li class="active"><a href="#/realms/{{realm.realm}}/keys">{{:: 'active' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/keys/passive">{{:: 'passive' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/keys/disabled">{{:: 'disabled' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/keys/providers">{{:: 'providers' | translate}}</a></li> + </ul> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="7"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" data-ng-model="search" class="form-control search""> + <div class="input-group-addon"> + <i class="fa fa-search"></i> + </div> + </div> + </div> + </div> + </th> + </tr> + <tr> + <th>{{:: 'algorithm' | translate}}</th> + <th>{{:: 'type' | translate}}</th> + <th>{{:: 'kid' | translate}}</th> + <th>{{:: 'priority' | translate}}</th> + <th>{{:: 'provider' | translate}}</th> + <th colspan="2">{{:: 'publicKeys' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="key in keys | filter:search | filter:{status:'ACTIVE'}"> + <td>{{key.algorithm}}</td> + <td>{{key.type}}</td> + <td>{{key.kid}}</td> + <td>{{key.providerPriority}}</td> + <td><a href="#/realms/{{realm.realm}}/keys/providers/{{key.provider.providerId}}/{{key.provider.id}}">{{key.provider.name}}</a></td> + + <td data-ng-show="!key.publicKey" colspan="2"></td> + <td class="kc-action-cell" data-ng-show="key.publicKey" class="kc-action-cell" data-ng-click="viewKey(key.publicKey)" colspan="{{key.certificate ? 1 : 2}}">{{:: 'publicKey' | translate}}</td> + <td data-ng-show="key.certificate" class="kc-action-cell" data-ng-click="viewKey(key.certificate)">{{:: 'certificate' | translate}}</td> + + </tr> + </tbody> + </table> + +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-list.html b/admin/resources/partials/realm-list.html new file mode 100644 index 0000000..099fe6d --- /dev/null +++ b/admin/resources/partials/realm-list.html @@ -0,0 +1,20 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + + <h1>{{:: 'realms' | translate}}</h1> + + <table class="datatable table table-striped table-bordered"> + <thead> + <tr> + <th>{{:: 'realm' | translate}}</th> + </tr> + </thead> + <tbody> + <tr data-ng-repeat="r in realms"> + <td><a href="#/realms/{{r.realm}}">{{r.realm}}</a></td> + </tr> + </tbody> + </table> +</div> + + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-login-settings.html b/admin/resources/partials/realm-login-settings.html new file mode 100644 index 0000000..c5a084a --- /dev/null +++ b/admin/resources/partials/realm-login-settings.html @@ -0,0 +1,87 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <kc-tabs-realm></kc-tabs-realm> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <fieldset class="border-top"> + <div class="form-group"> + <label for="registrationAllowed" class="col-md-2 control-label">{{:: 'registrationAllowed' | translate}}</label> + <div class="col-md-6"> + <input ng-model="realm.registrationAllowed" name="registrationAllowed" id="registrationAllowed" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'registrationAllowed.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" ng-show="realm.registrationAllowed"> + <label for="registrationEmailAsUsername" class="col-md-2 control-label">{{:: 'registrationEmailAsUsername' | translate}}</label> + <div class="col-md-6"> + <input ng-model="realm.registrationEmailAsUsername" name="registrationEmailAsUsername" id="registrationEmailAsUsername" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'registrationEmailAsUsername.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label for="editUsernameAllowed" class="col-md-2 control-label">{{:: 'editUsernameAllowed' | translate}}</label> + <div class="col-md-6"> + <input ng-model="realm.editUsernameAllowed" name="editUsernameAllowed" id="editUsernameAllowed" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'editUsernameAllowed.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label for="resetPasswordAllowed" class="col-md-2 control-label">{{:: 'resetPasswordAllowed' | translate}}</label> + <div class="col-md-6"> + <input ng-model="realm.resetPasswordAllowed" name="resetPasswordAllowed" id="resetPasswordAllowed" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'resetPasswordAllowed.tooltip' |translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="rememberMe">{{:: 'rememberMe' | translate}}</label> + <div class="col-md-6"> + <input ng-model="realm.rememberMe" name="rememberMe" id="rememberMe" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'rememberMe.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label for="verifyEmail" class="col-md-2 control-label">{{:: 'verifyEmail' | translate}}</label> + <div class="col-md-6"> + <input ng-model="realm.verifyEmail" name="verifyEmail" id="verifyEmail" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'verifyEmail.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label for="loginWithEmailAllowed" class="col-md-2 control-label">{{:: 'loginWithEmailAllowed' | translate}}</label> + <div class="col-md-6"> + <input ng-model="realm.loginWithEmailAllowed" name="loginWithEmailAllowed" id="loginWithEmailAllowed" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'loginWithEmailAllowed.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" ng-show="!realm.loginWithEmailAllowed && !realm.registrationEmailAsUsername"> + <label for="duplicateEmailsAllowed" class="col-md-2 control-label">{{:: 'duplicateEmailsAllowed' | translate}}</label> + <div class="col-md-6"> + <input ng-model="realm.duplicateEmailsAllowed" name="duplicateEmailsAllowed" id="duplicateEmailsAllowed" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'duplicateEmailsAllowed.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label for="sslRequired" class="col-md-2 control-label">{{:: 'sslRequired' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="sslRequired" ng-model="realm.sslRequired" class="form-control"> + <option value="all">{{:: 'sslRequired.option.all' | translate}}</option> + <option value="external">{{:: 'sslRequired.option.external' | translate}}</option> + <option value="none">{{:: 'sslRequired.option.none' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'sslRequired.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <div class="form-group" data-ng-show="access.manageRealm"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-role-users.html b/admin/resources/partials/realm-role-users.html new file mode 100644 index 0000000..11cbbc6 --- /dev/null +++ b/admin/resources/partials/realm-role-users.html @@ -0,0 +1,50 @@ +<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}}/roles">{{:: 'roles' | translate}}</a></li> + <li>{{role.name}}</li> + </ol> + + <kc-tabs-role></kc-tabs-role> + + <table class="table table-striped table-bordered"> + <caption data-ng-show="users" class="hidden">{{:: 'table-of-role-members' | translate}}</caption> + <thead> + <tr> + <tr data-ng-show="searchLoaded && users.length > 0"> + <th>{{:: 'username' | translate}}</th> + <th>{{:: 'last-name' | translate}}</th> + <th>{{:: 'first-name' | translate}}</th> + <th>{{:: 'email' | translate}}</th> + <th></th> + </tr> + </tr> + </thead> + <tfoot data-ng-show="users && (users.length >= query.max || query.first > 0)"> + <tr> + <td colspan="7"> + <div class="table-nav"> + <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button> + <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button> + <button data-ng-click="nextPage()" class="next" ng-disabled="users.length < query.max">{{:: 'next-page' | translate}}</button> + </div> + </td> + </tr> + </tfoot> + <tbody> + <tr ng-repeat="user in users"> + <td><a href="#/realms/{{realm.realm}}/users/{{user.id}}">{{user.username}}</a></td> + <td>{{user.lastName}}</td> + <td>{{user.firstName}}</td> + <td>{{user.email}}</td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/users/{{user.id}}">{{:: 'edit' | translate}}</td> + </tr> + <tr data-ng-show="!users || users.length == 0"> + <td class="text-muted" data-ng-show="searchLoaded && users.length == 0 && lastSearch != null">{{:: 'no-role-members' | translate}}</td> + <td class="text-muted" data-ng-show="searchLoaded && users.length == 0 && lastSearch == null">{{:: 'no-role-members' | translate}}</td> + </tr> + </tbody> + </table> + +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-smtp.html b/admin/resources/partials/realm-smtp.html new file mode 100644 index 0000000..7533071 --- /dev/null +++ b/admin/resources/partials/realm-smtp.html @@ -0,0 +1,96 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <kc-tabs-realm></kc-tabs-realm> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="smtpHost"><span class="required">*</span> {{:: 'host' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="smtpHost" type="text" ng-model="realm.smtpServer.host" placeholder="{{:: 'smtp-host' | translate}}" required> + </div> + <div class="col-sm-4"> + <a class="btn btn-primary" data-ng-click="testConnection()">{{:: 'test-connection' | translate}}</a> + </div> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="smtpPort">{{:: 'port' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="smtpPort" type="number" ng-model="realm.smtpServer.port" placeholder="{{:: 'smtp-port' | translate}}"> + </div> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="smtpFromDisplayName">{{:: 'fromDisplayName' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="smtpFromDisplayName" type="text" ng-model="realm.smtpServer.fromDisplayName" placeholder="{{:: 'sender-email-addr-display' | translate}}"> + </div> + <kc-tooltip>{{:: 'fromDisplayName.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="smtpFrom"><span class="required">*</span> {{:: 'from' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="smtpFrom" type="email" ng-model="realm.smtpServer.from" placeholder="{{:: 'sender-email-addr' | translate}}" required> + </div> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="smtpReplyToDisplayName">{{:: 'replyToDisplayName' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="smtpReplyToDisplayName" type="text" ng-model="realm.smtpServer.replyToDisplayName" placeholder="{{:: 'reply-to-email-addr-display' | translate}}"> + </div> + <kc-tooltip>{{:: 'replyToDisplayName.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="smtpReplyTo">{{:: 'replyTo' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="smtpReplyTo" type="email" ng-model="realm.smtpServer.replyTo" placeholder="{{:: 'reply-to-email-addr' | translate}}"> + </div> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="smtpEnvelopeFrom">{{:: 'envelopeFrom' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="smtpEnvelopeFrom" type="email" ng-model="realm.smtpServer.envelopeFrom" placeholder="{{:: 'sender-envelope-email-addr' | translate}}"> + </div> + <kc-tooltip>{{:: 'envelopeFrom.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="smtpSSL">{{:: 'enable-ssl' | translate}}</label> + <div class="col-md-6"> + <input ng-model="realm.smtpServer.ssl" name="smtpSSL" id="smtpSSL" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="smtpStartTLS">{{:: 'enable-start-tls' | translate}}</label> + <div class="col-md-6"> + <input ng-model="realm.smtpServer.starttls" name="smtpStartTLS" id="smtpStartTLS" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="smtpAuth">{{:: 'enable-auth' | translate}}</label> + <div class="col-md-6"> + <input ng-model="realm.smtpServer.auth" name="smtpAuth" id="smtpAuth" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <div class="form-group clearfix" data-ng-show="realm.smtpServer.auth"> + <label class="col-md-2 control-label" for="smtpUsername"><span class="required">*</span> {{:: 'username' | translate}}</span></label> + <div class="col-md-6"> + <input class="form-control" id="smtpUsername" type="text" ng-model="realm.smtpServer.user" placeholder="{{:: 'login-username' | translate}}" ng-disabled="!realm.smtpServer.auth" ng-required="realm.smtpServer.auth"> + </div> + </div> + <div class="form-group clearfix" data-ng-show="realm.smtpServer.auth"> + <label class="col-md-2 control-label" for="smtpPas"><span class="required">*</span> {{:: 'password' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="smtpPas" kc-password ng-model="realm.smtpServer.password" placeholder="{{:: 'login-password' | translate}}" ng-disabled="!realm.smtpServer.auth" ng-required="realm.smtpServer.auth"> + </div> + <kc-tooltip>{{:: 'smtp-password.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group" data-ng-show="access.manageRealm"> + <div class="col-md-10 col-md-offset-2"> + <button data-kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button data-kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-theme-settings.html b/admin/resources/partials/realm-theme-settings.html new file mode 100644 index 0000000..be74a2a --- /dev/null +++ b/admin/resources/partials/realm-theme-settings.html @@ -0,0 +1,97 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <kc-tabs-realm></kc-tabs-realm> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="loginTheme">{{:: 'login-theme' | translate}}</label> + <div class="col-md-3"> + <div> + <select class="form-control" id="loginTheme" + ng-model="realm.loginTheme" + ng-options="o.name as o.name for o in serverInfo.themes.login"> + <option value="" disabled selected>{{:: 'select-one.placeholder' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'login-theme.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="accountTheme">{{:: 'account-theme' | translate}}</label> + <div class="col-md-3"> + <div> + <select class="form-control" id="accountTheme" + ng-model="realm.accountTheme" + ng-options="o.name as o.name for o in serverInfo.themes.account"> + <option value="" disabled selected>{{:: 'select-one.placeholder' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{ 'account-theme.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="adminTheme">{{:: 'admin-console-theme' | translate}}</label> + <div class="col-md-3"> + <div> + <select class="form-control" id="adminTheme" + ng-model="realm.adminTheme" + ng-options="o.name as o.name for o in serverInfo.themes.admin"> + <option value="" disabled selected>{{:: 'select-one.placeholder' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'select-theme-admin-console' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="emailTheme">{{:: 'email-theme' | translate}}</label> + <div class="col-md-3"> + <div> + <select class="form-control" id="emailTheme" + ng-model="realm.emailTheme" + ng-options="o.name as o.name for o in serverInfo.themes.email"> + <option value="" disabled selected>{{:: 'select-one.placeholder' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'select-theme-email' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="internationalizationEnabled">{{:: 'i18n-enabled' | translate}}</label> + <div class="col-md-3"> + <input ng-model="realm.internationalizationEnabled" name="internationalizationEnabled" id="internationalizationEnabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <div class="form-group" data-ng-show="realm.internationalizationEnabled"> + <label class="col-md-2 control-label" for="supportedLocales" class="control-label two-lines">{{:: 'supported-locales' | translate}}</label> + + <div class="col-md-6"> + <input ui-select2="supportedLocalesOptions" id="supportedLocales" ng-model="realm.supportedLocales" data-placeholder="{{:: 'supported-locales.placeholder' | translate}}"/> + </div> + </div> + <div class="form-group" data-ng-show="realm.internationalizationEnabled"> + <label class="col-md-2 control-label" for="defaultLocale">{{:: 'default-locale' | translate}}</label> + <div class="col-md-3"> + <div> + <select class="form-control" id="defaultLocale" + ng-model="realm.defaultLocale" + ng-options="o as o for o in realm.supportedLocales" + ng-required="realm.internationalizationEnabled" + ng-disabled="!realm.internationalizationEnabled"> + <option value="" disabled selected>{{:: 'select-one.placeholder' | translate}}</option> + </select> + </div> + </div> + </div> + </fieldset> + + <div class="form-group" data-ng-show="access.manageRealm"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/realm-tokens.html b/admin/resources/partials/realm-tokens.html new file mode 100644 index 0000000..6d3bd6b --- /dev/null +++ b/admin/resources/partials/realm-tokens.html @@ -0,0 +1,328 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <kc-tabs-realm></kc-tabs-realm> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + + <div class="form-group"> + <label class="col-md-2 control-label" for="defaultSignatureAlgorithm">{{:: 'default-signature-algorithm' | translate}}</label> + + <div class="col-md-6"> + <select id="defaultSignatureAlgorithm" class="form-control" ng-model="realm.defaultSignatureAlgorithm" + ng-options="provider for provider in serverInfo.listProviderIds('signature')"> + </select> + </div> + + <kc-tooltip>{{:: 'default-signature-algorithm.tooltip' | translate}} + </kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="revokeRefreshToken">{{:: 'revoke-refresh-token' | translate}}</label> + + <div class="col-md-6"> + <input ng-change="" ng-model="realm.revokeRefreshToken" name="revokeRefreshToken" id="revokeRefreshToken" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + + <kc-tooltip>{{:: 'revoke-refresh-token.tooltip' | translate}} + </kc-tooltip> + </div> + + <div class="form-group" data-ng-show="realm.revokeRefreshToken == true"> + <label class="col-md-2 control-label" for="refreshTokenMaxReuse">{{:: 'refresh-token-max-reuse' | translate}}</label> + + <div class="col-md-6"> + <input class="form-control" type="number" required min="0" max="31536000" data-ng-model="realm.refreshTokenMaxReuse" id="refreshTokenMaxReuse" + name="refreshTokenMaxReuse"/> + </div> + + <kc-tooltip>{{:: 'refresh-token-max-reuse.tooltip' | translate}} + </kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="ssoSessionIdleTimeout">{{:: 'sso-session-idle' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="1" max="31536000" data-ng-model="realm.ssoSessionIdleTimeout.time" id="ssoSessionIdleTimeout" + name="ssoSessionIdleTimeout"/> + <select class="form-control" name="ssoSessionIdleTimeoutUnit" data-ng-model="realm.ssoSessionIdleTimeout.unit"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'sso-session-idle.tooltip' | translate}} + </kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="ssoSessionMaxLifespan">{{:: 'sso-session-max' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="1" + max="31536000" data-ng-model="realm.ssoSessionMaxLifespan.time" + id="ssoSessionMaxLifespan" name="ssoSessionMaxLifespan"/> + <select class="form-control" name="ssoSessionMaxLifespanUnit" data-ng-model="realm.ssoSessionMaxLifespan.unit"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'sso-session-max.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="ssoSessionIdleTimeoutRememberMe">{{:: 'sso-session-idle-remember-me' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="0" + max="31536000" data-ng-model="realm.ssoSessionIdleTimeoutRememberMe.time" + id="ssoSessionIdleTimeoutRememberMe" name="ssoSessionIdleTimeoutRememberMe"/> + <select class="form-control" name="ssoSessionIdleTimeoutRememberMe" data-ng-model="realm.ssoSessionIdleTimeoutRememberMe.unit"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'sso-session-idle-remember-me.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="ssoSessionMaxLifespanRememberMe">{{:: 'sso-session-max-remember-me' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="0" + max="31536000" data-ng-model="realm.ssoSessionMaxLifespanRememberMe.time" + id="ssoSessionMaxLifespanRememberMe" name="ssoSessionMaxLifespanRememberMe"/> + <select class="form-control" name="ssoSessionMaxLifespanRememberMeUnit" data-ng-model="realm.ssoSessionMaxLifespanRememberMe.unit"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'sso-session-max-remember-me.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="offlineSessionIdleTimeout">{{:: 'offline-session-idle' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="1" + max="31536000" data-ng-model="realm.offlineSessionIdleTimeout.time" + id="offlineSessionIdleTimeout" name="offlineSessionIdleTimeout"/> + <select class="form-control" name="offlineSessionIdleTimeoutUnit" data-ng-model="realm.offlineSessionIdleTimeout.unit"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'offline-session-idle.tooltip' | translate}}</kc-tooltip> + </div> + + <!-- KEYCLOAK-7688 Offline Session Max for Offline Token --> + <div class="form-group"> + <label class="col-md-2 control-label" for="offlineSessionMaxLifespanEnabled">{{:: 'offline-session-max-limited' | translate}}</label> + <div class="col-md-3"> + <input ng-change="" ng-model="realm.offlineSessionMaxLifespanEnabled" + name="offlineSessionMaxLifespanEnabled" + id="offlineSessionMaxLifespanEnabled" + onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'offline-session-max-limited.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="realm.offlineSessionMaxLifespanEnabled"> + <label class="col-md-2 control-label" for="offlineSessionMaxLifespan">{{:: 'offline-session-max' | translate}}</label> + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="1" + max="31536000" data-ng-model="realm.offlineSessionMaxLifespan.time" + id="offlineSessionMaxLifespan" name="offlineSessionMaxLifespan"/> + <select class="form-control" name="offlineSessionMaxLifespanUnit" data-ng-model="realm.offlineSessionMaxLifespan.unit"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'offline-session-max.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="clientSessionIdleTimeout">{{:: 'client-session-idle' | translate}}</label> + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="0" + max="31536000" data-ng-model="realm.clientSessionIdleTimeout.time" + id="clientSessionIdleTimeout" name="clientSessionIdleTimeout"/> + <select class="form-control" name="clientSessionIdleTimeoutUnit" data-ng-model="realm.clientSessionIdleTimeout.unit"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'client-session-idle.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="clientSessionMaxLifespan">{{:: 'client-session-max' | translate}}</label> + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="0" + max="31536000" data-ng-model="realm.clientSessionMaxLifespan.time" + id="clientSessionMaxLifespan" name="clientSessionMaxLifespan"/> + <select class="form-control" name="clientSessionMaxLifespanUnit" data-ng-model="realm.clientSessionMaxLifespan.unit"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'client-session-max.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="accessTokenLifespan">{{:: 'access-token-lifespan' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="1" + max="31536000" data-ng-model="realm.accessTokenLifespan.time" + id="accessTokenLifespan" name="accessTokenLifespan"/> + <select class="form-control" name="accessTokenLifespanUnit" data-ng-model="realm.accessTokenLifespan.unit"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'access-token-lifespan.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="accessTokenLifespanForImplicitFlow">{{:: 'access-token-lifespan-for-implicit-flow' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="1" + max="31536000" data-ng-model="realm.accessTokenLifespanForImplicitFlow.time" + id="accessTokenLifespanForImplicitFlow" name="accessTokenLifespanForImplicitFlow"/> + <select class="form-control" name="accessTokenLifespanForImplicitFlowUnit" data-ng-model="realm.accessTokenLifespanForImplicitFlow.unit"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'access-token-lifespan-for-implicit-flow.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="accessCodeLifespan">{{:: 'client-login-timeout' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="1" max="31536000" data-ng-model="realm.accessCodeLifespan.time" id="accessCodeLifespan" + name="accessCodeLifespan"> + <select class="form-control" name="accessCodeLifespanUnit" data-ng-model="realm.accessCodeLifespan.unit"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'client-login-timeout.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="accessCodeLifespanLogin" class="two-lines">{{:: 'login-timeout' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="1" max="31536000" data-ng-model="realm.accessCodeLifespanLogin.time" + id="accessCodeLifespanLogin" name="accessCodeLifespanLogin"> + <select class="form-control" name="accessCodeLifespanLoginUnit" data-ng-model="realm.accessCodeLifespanLogin.unit"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'login-timeout.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="accessCodeLifespanUserAction" class="two-lines">{{:: 'login-action-timeout' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="1" max="31536000" data-ng-model="realm.accessCodeLifespanUserAction.time" + id="accessCodeLifespanUserAction" name="accessCodeLifespanUserAction"> + <select class="form-control" name="accessCodeLifespanUserActionUnit" data-ng-model="realm.accessCodeLifespanUserAction.unit"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip> + {{:: 'login-action-timeout.tooltip' | translate}} + </kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="actionTokenGeneratedByUserLifespan" class="two-lines">{{:: 'action-token-generated-by-user-lifespan' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="1" max="31536000" data-ng-model="realm.actionTokenGeneratedByUserLifespan.time" + id="actionTokenGeneratedByUserLifespan" name="actionTokenGeneratedByUserLifespan"> + <select class="form-control" name="actionTokenGeneratedByUserLifespanUnit" data-ng-model="realm.actionTokenGeneratedByUserLifespan.unit"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip> + {{:: 'action-token-generated-by-user-lifespan.tooltip' | translate}} + </kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="actionTokenGeneratedByAdminLifespan" class="two-lines">{{:: 'action-token-generated-by-admin-lifespan' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="1" max="31536000" data-ng-model="realm.actionTokenGeneratedByAdminLifespan.time" + id="actionTokenGeneratedByAdminLifespan" name="actionTokenGeneratedByAdminLifespan"> + <select class="form-control" name="actionTokenGeneratedByAdminLifespanUnit" data-ng-model="realm.actionTokenGeneratedByAdminLifespan.unit"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip> + {{:: 'action-token-generated-by-admin-lifespan.tooltip' | translate}} + </kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="actionTokenAttributeSelect" class="two-lines"> + {{:: 'action-token-generated-by-user.operation' | translate }} </label> + <div class="form-inline col-md-6 time-selector"> + <select class="form-control" name="actionTokenAttributeSelect" id="actionTokenAttributeSelect" + ng-model="actionLifespanId"> + <option value="" disabled selected>{{:: 'select-one.placeholder' | translate}}</option> + <option ng-repeat="(actionTokenId, value) in actionTokenProviders" value="{{actionTokenId}}"> + {{:: 'action-token-generated-by-user.' + actionTokenId | translate }} + </option> + </select> + <input class="form-control" type="number" min="1" max="31536000" data-ng-model="actionTokenAttribute.time" + id="actionTokenAttributeTime" name="actionTokenAttributeTime"> + <select class="form-control" name="actionTokenAttributeUnit" + data-ng-model="actionTokenAttribute.unit"> + <option value="Minutes" ng-selected="true">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + <button data-ng-click="resetToDefaultToken(actionTokenId)">{{:: 'action-token-generated-by-user.reset' | translate}}</button> + </div> + <kc-tooltip> + {{:: 'action-token-generated-by-user.tooltip' | translate}} + </kc-tooltip> + </div> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="access.manageRealm"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + + </form> + +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/required-actions.html b/admin/resources/partials/required-actions.html new file mode 100644 index 0000000..ab16456 --- /dev/null +++ b/admin/resources/partials/required-actions.html @@ -0,0 +1,38 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1>{{:: 'authentication' | translate}}</h1> + + <kc-tabs-authentication></kc-tabs-authentication> + <table class="table table-striped table-bordered"> + <thead> + <tr data-ng-hide="unregisteredRequiredActions.length == 0"> + <th colspan = "3" class="kc-table-actions"> + <div class="pull-right" data-ng-show="access.manageRealm"> + <button class="btn btn-default" data-ng-click="register()">{{:: 'register' | translate}}</button> + </div> + </th> + </tr> + <tr data-ng-hide="requiredActions.length == 0"> + <th>{{:: 'required-action' | translate}}</th> + <th>{{:: 'enabled' | translate}}</th> + <th>{{:: 'default-action' | translate}} <i class="fa fa-question-circle text-muted" tooltip-trigger="mouseover mouseout" tooltip="{{:: 'auth.default-action.tooltip' | translate}}" tooltip-placement="top"></i></th> + </tr> + </thead> + <tbody> + <tr ng-repeat="requiredAction in requiredActions" data-ng-show="requiredActions.length > 0"> + <td class="kc-sorter"> + <button data-ng-hide="flow.builtIn" data-ng-disabled="$first" class="btn btn-default btn-sm" data-ng-click="raisePriority(requiredAction)"><i class="fa fa-angle-up"></i></button> + <button data-ng-hide="flow.builtIn" data-ng-disabled="$last" class="btn btn-default btn-sm" data-ng-click="lowerPriority(requiredAction)"><i class="fa fa-angle-down"></i></button> + <span>{{requiredAction.name}}</span></span> + </td> + <td><input type="checkbox" ng-model="requiredAction.enabled" ng-change="updateRequiredAction(requiredAction)" id="{{requiredAction.alias}}.enabled"></td> + <td><input type="checkbox" ng-model="requiredAction.defaultAction" ng-change="updateRequiredAction(requiredAction)" ng-disabled="!requiredAction.enabled" ng-checked="requiredAction.enabled && requiredAction.defaultAction" id="{{requiredAction.alias}}.defaultAction"></td> + </tr> + <tr data-ng-show="requiredActions.length == 0"> + <td>{{:: 'no-required-actions-configured' | translate}}</td> + </tr> + </tbody> + </table> + +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/role-attributes.html b/admin/resources/partials/role-attributes.html new file mode 100644 index 0000000..b9cbbd7 --- /dev/null +++ b/admin/resources/partials/role-attributes.html @@ -0,0 +1,41 @@ +<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}}/roles">{{:: 'roles' | translate}}</a></li> + <li>{{role.name}}</li> + </ol> + + <kc-tabs-role></kc-tabs-role> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th>{{:: 'key' | translate}}</th> + <th>{{:: 'value' | translate}}</th> + <th>{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="(key, value) in role.attributes | toOrderedMapSortedByKey"> + <td>{{key}}</td> + <td><input ng-model="role.attributes[key]" class="form-control" type="text" name="{{key}}" id="attribute-{{key}}" /></td> + <td class="kc-action-cell" data-ng-click="removeAttribute(key)">{{:: 'delete' | translate}}</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" data-ng-click="addAttribute()" data-ng-disabled="!newAttribute.key.length || !newAttribute.value.length">{{:: 'add' | translate}}</td> + </tr> + </tbody> + </table> + + <div class="form-group" data-ng-show="access.manageRealm"> + <div class="col-md-12"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/role-detail.html b/admin/resources/partials/role-detail.html new file mode 100644 index 0000000..1595970 --- /dev/null +++ b/admin/resources/partials/role-detail.html @@ -0,0 +1,135 @@ +<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}}/roles">{{:: 'roles' | translate}}</a></li> + <li data-ng-hide="create">{{role.name}}</li> + <li data-ng-show="create">{{:: 'add-role' | translate}}</li> + </ol> + + <kc-tabs-role></kc-tabs-role> + + <form class="form-horizontal clearfix" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <fieldset> + <div class="form-group"> + <label class="col-md-2 control-label" for="name"><span class="required" data-ng-show="create">*</span> {{:: 'role-name' | translate}}</label> + + <div class="col-md-6"> + <input kc-no-reserved-chars class="form-control" type="text" id="name" name="name" data-ng-model="role.name" autofocus + required data-ng-readonly="!create"> + </div> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="description">{{:: 'description' | translate}} </label> + + <div class="col-md-6"> + <textarea class="form-control" rows="5" cols="50" id="description" name="description" data-ng-model="role.description"></textarea> + </div> + </div> + <div class="form-group" data-ng-hide="create"> + <label class="col-md-2 control-label" for="compositeSwitch" class="control-label">{{:: 'composite-roles' | translate}}</label> + <div class="col-md-6"> + <input ng-model="compositeSwitch" name="compositeSwitch" id="compositeSwitch" ng-disabled="compositeSwitchDisabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'composite-roles.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="create"> + <button kc-save data-ng-show="changed">{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()" data-ng-show="changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="!create && access.manageRealm"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + + <fieldset data-ng-show="!create && (compositeSwitch || role.composite)"> + <legend uncollapsed class="collapsible"><span class="text">{{:: 'composite-roles' | translate}}</span> </legend> + <div class="form-group"> + <label class="col-md-2 control-label" class="control-label">{{:: 'realm-roles' | translate}}</label> + + <div class="col-md-10"> + <div class="row"> + <div class="col-md-4"> + <label class="control-label">{{:: 'available-roles' | translate}}</label> + <kc-tooltip>{{:: 'composite.available-roles.tooltip' | translate}}</kc-tooltip> + <select id="available" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedRealmRoles"> + <option ng-repeat="r in realmRoles | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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> + </button> + </div> + <div class="col-md-4"> + <label class="control-label">{{:: 'associated-roles' | translate}}</label> + <kc-tooltip>{{:: 'composite.associated-roles.tooltip' | translate}}</kc-tooltip> + <select id="assigned" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedRealmMappings"> + <option ng-repeat="r in realmMappings | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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}} + </button> + </div> + </div> + </div> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="clients">{{:: 'client-roles' | translate}}</label> + <div class="col-md-6"> + <input type="hidden" ui-select2="clientsUiSelect" id="clients" data-ng-model="selectedClient" data-ng-change="changeClient(selectedClient);" data-placeholder="{{:: 'authz-select-client' | translate}}..."> + </input> + </div> + + + <div class="col-md-10 col-md-push-2"> + <div class="row" data-ng-show="selectedClient"> + <div class="col-md-4"> + <label class="control-label" for="available-client">{{:: 'available-roles' | translate}}</label> + <kc-tooltip>{{:: 'composite.available-roles-client.tooltip' | translate}}</kc-tooltip> + <select id="available-client" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedClientRoles"> + <option ng-repeat="r in clientRoles | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + <button ng-disabled="selectedClientRoles.length == 0" class="btn btn-default" type="submit" ng-click="addClientRole()"> + {{:: 'add-selected' | translate}} <i class="fa fa-angle-right"></i> + </button> + </div> + <div class="col-md-4"> + <label class="control-label" for="assigned-client">{{:: 'associated-roles' | translate}}</label> + <kc-tooltip>{{:: 'composite.associated-roles-client.tooltip' | translate}}</kc-tooltip> + <select id="assigned-client" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedClientMappings"> + <option ng-repeat="r in clientMappings | orderBy:'name'" value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + <button ng-disabled="selectedClientMappings.length == 0" class="btn btn-default" type="submit" ng-click="deleteClientRole()"> + <i class="fa fa-angle-left"></i> {{:: 'remove-selected' | translate}} + </button> + </div> + </div> + </div> + </div> + </fieldset> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/role-list.html b/admin/resources/partials/role-list.html new file mode 100644 index 0000000..b2e5d67 --- /dev/null +++ b/admin/resources/partials/role-list.html @@ -0,0 +1,63 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1>Roles</h1> + + <ul class="nav nav-tabs"> + <li class="active"><a href="#/realms/{{realm.realm}}/roles">{{:: 'realm-roles' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/default-roles">{{:: 'default-roles' | translate}}</a></li> + </ul> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="5"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" data-ng-model="query.search" ng-model-options="{debounce: 500}" class="form-control search"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit" data-ng-click="firstPage()"></i> + </div> + </div> + </div> + <button id="viewAllRoles" class="btn btn-default" ng-click="query.search = null; firstPage()">{{:: 'view-all-roles' | translate}}</button> + <div class="pull-right" data-ng-show="access.manageRealm"> + <a id="createRole" class="btn btn-default" href="#/create/role/{{realm.realm}}">{{:: 'add-role' | translate}}</a> + </div> + </div> + </th> + </tr> + <tr data-ng-show="roles && roles.length > 0"> + <th>{{:: 'role-name' | translate}}</th> + <th>{{:: 'composite' | translate}}</th> + <th>{{:: 'description' | translate}}</th> + <th colspan="2">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="role in roles"> + <td><a href="#/realms/{{realm.realm}}/roles/{{role.id}}">{{role.name}}</a></td> + <td translate="{{role.composite}}"></td> + <td>{{role.description}}</td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/roles/{{role.id}}">{{:: 'edit' | translate}}</td> + <td class="kc-action-cell" data-ng-click="removeRole(role)">{{:: 'delete' | translate}}</td> + </tr> + <tr data-ng-show="(roles | filter:{name: query.search}).length == 0"> + <td class="text-muted" colspan="4" data-ng-show="searchLoaded && roles.length == 0 && lastSearch != null">{{:: 'no-results' | translate}}</td> + <td class="text-muted" colspan="4" data-ng-show="searchLoaded && roles.length == 0 && lastSearch == null">{{:: 'no-realm-roles-available' | translate}}</td> + </tr> + </tbody> + <tfoot data-ng-show="roles && (roles.length >= query.max || query.first > 0)"> + <tr> + <td colspan="5"> + <div class="table-nav"> + <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button> + <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button> + <button data-ng-click="nextPage()" class="next" ng-disabled="roles.length < query.max">{{:: 'next-page' | translate}}</button> + </div> + </td> + </tr> + </tfoot> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/role-mappings.html b/admin/resources/partials/role-mappings.html new file mode 100644 index 0000000..184a849 --- /dev/null +++ b/admin/resources/partials/role-mappings.html @@ -0,0 +1,119 @@ +<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' | translate}}</a></li> + <li>{{user.username}}</li> + </ol> + + <kc-tabs-user></kc-tabs-user> + + <form class="form-horizontal" name="realmForm" novalidate> + <div class="form-group" kc-read-only="!user.access.mapRoles"> + <label class="col-md-2 control-label" class="control-label">{{:: 'realm-roles' | translate}}</label> + + <div class="col-md-10"> + <div class="row"> + <div class="col-md-3"> + <label class="control-label" for="available">{{:: 'available-roles' | translate}}</label> + <select id="available" class="form-control overflow-select" multiple size="5" realmMappings + ng-multiple="true" + ng-model="selectedRealmRoles"> + <option ng-repeat="r in realmRoles | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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> + </button> + <kc-tooltip>{{:: 'user.add-selected.tooltip' | translate}}</kc-tooltip> + </div> + <div class="col-md-3"> + <label class="control-label" for="assigned">{{:: 'assigned-roles' | translate}}</label> + <kc-tooltip>{{:: 'user.assigned-roles.tooltip' | translate}}</kc-tooltip> + <select id="assigned" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedRealmMappings"> + <option ng-repeat="r in realmMappings | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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}} + </button> + </div> + <div class="col-md-3"> + <label class="control-label" for="realm-composite">{{:: 'effective-roles' | translate}}</label> + <kc-tooltip>{{:: 'user.effective-roles.tooltip' | translate}}</kc-tooltip> + <select id="realm-composite" class="form-control overflow-select" multiple size="5" + disabled="true" + ng-model="dummymodel"> + <option ng-repeat="r in realmComposite | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + </div> + </div> + </div> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="clients">{{:: 'client-roles' | translate}}</label> + <div class="col-md-6"> + <input type="hidden" ui-select2="clientsUiSelect" id="clients" data-ng-model="selectedClient" data-ng-change="changeClient(selectedClient);" data-placeholder="{{:: 'authz-select-client' | translate}}..."> + </input> + </div> + + + <div class="col-md-10 col-md-push-2" kc-read-only="!user.access.mapRoles"> + <div class="row" data-ng-show="selectedClient"> + <div class="col-md-3"> + <label class="control-label" for="available-client">{{:: 'available-roles' | translate}}</label> + <kc-tooltip>{{:: 'user.available-roles.tooltip' | translate}}</kc-tooltip> + <select id="available-client" class="form-control overflow-select" multiple size="5" + ng-multiple="true" + ng-model="selectedClientRoles"> + <option ng-repeat="r in clientRoles | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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> + </button> + </div> + <div class="col-md-3"> + <label class="control-label" for="assigned-client">{{:: 'assigned-roles' | translate}}</label> + <kc-tooltip>{{:: 'user.assigned-roles-client.tooltip' | translate}}</kc-tooltip> + <select id="assigned-client" class="form-control overflow-select" multiple size=5 + ng-multiple="true" + ng-model="selectedClientMappings"> + <option ng-repeat="r in clientMappings | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </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}} + </button> + </div> + <div class="col-md-3"> + <label class="control-label" for="client-composite">{{:: 'effective-roles' | translate}}</label> + <kc-tooltip>{{:: 'user.effective-roles-client.tooltip' | translate}}</kc-tooltip> + <select id="client-composite" class="form-control overflow-select" multiple size=5 + disabled="true" + ng-model="dummymodel"> + <option ng-repeat="r in clientComposite | orderBy:'name'" + value="{{r}}" title="{{r.name}}"> + {{r.name}} + </option> + </select> + </div> + </div> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/server-info-providers.html b/admin/resources/partials/server-info-providers.html new file mode 100644 index 0000000..be741c1 --- /dev/null +++ b/admin/resources/partials/server-info-providers.html @@ -0,0 +1,55 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1> + {{:: 'server-info' | translate}} + <i id="serverInfoReload" class="pficon pficon-restart clickable" data-ng-click="serverInfoReload()"></i> + </h1> + + <ul class="nav nav-tabs"> + <li><a href="#/server-info">{{:: 'info' | translate}}</a></li> + <li class="active"><a href="#/server-info/providers">{{:: 'providers' | translate}}</a></li> + </ul> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="5"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" data-ng-model="search" class="form-control search" onkeyup="if(event.keyCode == 13){$(this).next('I').click();}"> + </div> + </div> + </div> + </th> + </tr> + <tr> + <th width="20%">{{:: 'spi' | translate}}</th> + <th>{{:: 'providers' | translate}}</th> + </tr> + </thead> + <tbody> + <tr data-ng-repeat="spi in (providers | filter:search)"> + <td>{{spi.name}}</td> + <td> + <div data-ng-repeat="(providerName, provider) in spi.providers"> + {{providerName}} + <span ng-show="provider.operationalInfo"> + <button type="button" class="btn btn-default btn-xs" ng-click="collapseRep = !collapseRep"> + <span class="glyphicon glyphicon-plus" data-ng-show="!collapseRep"></span> + <span class="glyphicon glyphicon-minus" data-ng-show="collapseRep"></span> + </button> + <table ng-show="collapseRep" class="table table-striped table-bordered" style="margin-top: 0px;"> + <tr ng-repeat="(key, value) in provider.operationalInfo"> + <td width="20%">{{key}}</td> + <td>{{value}}</td> + </tr> + </table> + </span> + </div> + </td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/server-info.html b/admin/resources/partials/server-info.html new file mode 100644 index 0000000..6d24419 --- /dev/null +++ b/admin/resources/partials/server-info.html @@ -0,0 +1,135 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1> + {{:: 'server-info' | translate}} + <i id="serverInfoReload" class="pficon pficon-restart clickable" data-ng-click="serverInfoReload()"></i> + </h1> + + <ul class="nav nav-tabs"> + <li class="active"><a href="#/server-info">{{:: 'info' | translate}}</a></li> + <li><a href="#/server-info/providers">{{:: 'providers' | translate}}</a></li> + </ul> + + <table class="table table-striped table-bordered"> + <tr> + <td width="20%">{{:: 'server-version' | translate}}</td> + <td>{{serverInfo.systemInfo.version}}</td> + </tr> + <tr> + <td>{{:: 'server-time' | translate}}</td> + <td>{{serverInfo.systemInfo.serverTime}}</td> + </tr> + <tr> + <td>{{:: 'server-uptime' | translate}}</td> + <td>{{serverInfo.systemInfo.uptime}}</td> + </tr> + </table> + + <table class="table table-striped table-bordered"> + <legend>{{:: 'profile' | translate}}</legend> + + <tr> + <td width="20%">{{:: 'server-profile' | translate}}</td> + <td>{{serverInfo.profileInfo.name | capitalize}}</td> + </tr> + <tr data-ng-if="serverInfo.profileInfo.disabledFeatures.length > 0"> + <td width="20%"> + <span>{{:: 'server-disabled' | translate}}</span> + <kc-tooltip>{{:: 'server-disabled.tooltip' | translate}}</kc-tooltip> + </td> + <td>{{serverInfo.profileInfo.disabledFeatures.sort().join(', ')}}</td> + + </tr> + <tr data-ng-if="serverInfo.profileInfo.previewFeatures.length > 0"> + <td width="20%"> + <span>{{:: 'server-preview' | translate}}</span> + <kc-tooltip>{{:: 'server-preview.tooltip' | translate}}</kc-tooltip> + </td> + <td>{{serverInfo.profileInfo.previewFeatures.sort().join(', ')}}</td> + </tr> + <tr data-ng-if="serverInfo.profileInfo.experimentalFeatures.length > 0"> + <td width="20%"> + <span>{{:: 'server-experimental' | translate}}</span> + <kc-tooltip>{{:: 'server-experimental.tooltip' | translate}}</kc-tooltip> + </td> + <td>{{serverInfo.profileInfo.experimentalFeatures.sort().join(', ')}}</td> + </tr> + </table> + + <fieldset> + <legend>{{:: 'memory' | translate}}</legend> + <table class="table table-striped table-bordered" style="margin-top: 0;"> + <tr> + <td width="20%">{{:: 'total-memory' | translate}}</td> + <td>{{serverInfo.memoryInfo.totalFormated}}</td> + </tr> + <tr> + <td>{{:: 'free-memory' | translate}}</td> + <td>{{serverInfo.memoryInfo.freeFormated}} ({{serverInfo.memoryInfo.freePercentage}}%)</td> + </tr> + <tr> + <td>{{:: 'used-memory' | translate}}</td> + <td>{{serverInfo.memoryInfo.usedFormated}}</td> + </tr> + </table> + </fieldset> + + <fieldset> + <legend>{{:: 'system' | translate}}</legend> + <table class="table table-striped table-bordered" style="margin-top: 0;"> + <tr> + <td width="20%">{{:: 'current-working-directory' | translate}}</td> + <td>{{serverInfo.systemInfo.userDir}}</td> + </tr> + <tr> + <td>{{:: 'java-version' | translate}}</td> + <td>{{serverInfo.systemInfo.javaVersion}}</td> + </tr> + <tr> + <td>{{:: 'java-vendor' | translate}}</td> + <td>{{serverInfo.systemInfo.javaVendor}}</td> + </tr> + <tr> + <td>{{:: 'java-runtime' | translate}}</td> + <td>{{serverInfo.systemInfo.javaRuntime}}</td> + </tr> + <tr> + <td>{{:: 'java-vm' | translate}}</td> + <td>{{serverInfo.systemInfo.javaVm}}</td> + </tr> + <tr> + <td>{{:: 'java-vm-version' | translate}}</td> + <td>{{serverInfo.systemInfo.javaVmVersion}}</td> + </tr> + <tr> + <td>{{:: 'java-home' | translate}}</td> + <td>{{serverInfo.systemInfo.javaHome}}</td> + </tr> + <tr> + <td>{{:: 'user-name' | translate}}</td> + <td>{{serverInfo.systemInfo.userName}}</td> + </tr> + <tr> + <td>{{:: 'user-timezone' | translate}}</td> + <td>{{serverInfo.systemInfo.userTimezone}}</td> + </tr> + <tr> + <td>{{:: 'user-locale' | translate}}</td> + <td>{{serverInfo.systemInfo.userLocale}}</td> + </tr> + <tr> + <td>{{:: 'system-encoding' | translate}}</td> + <td>{{serverInfo.systemInfo.fileEncoding}}</td> + </tr> + <tr> + <td>{{:: 'operating-system' | translate}}</td> + <td>{{serverInfo.systemInfo.osName}} {{serverInfo.systemInfo.osVersion}}</td> + </tr> + <tr> + <td>{{:: 'os-architecture' | translate}}</td> + <td>{{serverInfo.systemInfo.osArchitecture}}</td> + </tr> + </table> + </fieldset> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/session-realm.html b/admin/resources/partials/session-realm.html new file mode 100644 index 0000000..98b2284 --- /dev/null +++ b/admin/resources/partials/session-realm.html @@ -0,0 +1,34 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1>{{:: 'sessions' | translate}}</h1> + + <ul class="nav nav-tabs"> + <li class="active"><a href="#/realms/{{realm.realm}}/sessions/realm">{{:: 'realm-sessions' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/sessions/revocation">{{:: 'revocation' | translate}}</a></li> + </ul> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="3"> + <div class="pull-right"> + <a id="logoutAllSessions" class="btn btn-default" ng-click="logoutAll()">{{:: 'logout-all' | translate}}</a> + </div> + </th> + </tr> + <tr> + <th>{{:: 'client' | translate}}</th> + <th>{{:: 'active-sessions' | translate}}</th> + <th>{{:: 'offline-sessions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr data-ng-repeat="data in stats"> + <td><a href="#/realms/{{realm.realm}}/clients/{{data.id}}/sessions">{{data.clientId}}</a></td> + <td>{{data.active}}</td> + <td>{{data.offline}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/session-revocation.html b/admin/resources/partials/session-revocation.html new file mode 100644 index 0000000..03c6864 --- /dev/null +++ b/admin/resources/partials/session-revocation.html @@ -0,0 +1,30 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1>{{:: 'sessions' | translate}}</h1> + + <ul class="nav nav-tabs"> + <li><a href="#/realms/{{realm.realm}}/sessions/realm">{{:: 'realm-sessions' | translate}}</a></li> + <li class="active"><a href="#/realms/{{realm.realm}}/sessions/revocation">{{:: 'revocation' | translate}}</a></li> + </ul> + + <form class="form-horizontal" name="credentialForm" novalidate kc-read-only="!access.manageRealm"> + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label" for="notBefore">{{:: 'not-before' | translate}}</label> + <div class="col-md-6"> + <input ng-disabled="true" class="form-control" type="text" id="notBefore" name="notBefore" data-ng-model="notBefore" autofocus> + </div> + <kc-tooltip>{{:: 'not-before.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="access.manageClients"> + <button type="submit" data-ng-click="setNotBeforeNow()" class="btn btn-default">{{:: 'set-to-now' | translate}}</button> + <button type="submit" data-ng-click="clear()" class="btn btn-default">{{:: 'clear' | translate}}</button> + <button type="submit" data-ng-click="pushRevocation()" class="btn btn-primary" tooltip-trigger="mouseover mouseout" tooltip="{{:: 'push.tooltip' | translate}}" tooltip-placement="bottom">{{:: 'push' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/user-attributes.html b/admin/resources/partials/user-attributes.html new file mode 100644 index 0000000..10e3d8f --- /dev/null +++ b/admin/resources/partials/user-attributes.html @@ -0,0 +1,41 @@ +<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' | translate}}</a></li> + <li>{{user.username}}</li> + </ol> + + <kc-tabs-user></kc-tabs-user> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!user.access.manage"> + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th>{{:: 'key' | translate}}</th> + <th>{{:: 'value' | translate}}</th> + <th>{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="(key, value) in user.attributes | toOrderedMapSortedByKey"> + <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" data-ng-click="removeAttribute(key)">{{:: 'delete' | translate}}</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" data-ng-click="addAttribute()" data-ng-disabled="!newAttribute.key.length || !newAttribute.value.length">{{:: 'add' | translate}}</td> + </tr> + </tbody> + </table> + + <div class="form-group" data-ng-show="user.access.manage"> + <div class="col-md-12"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/user-consents.html b/admin/resources/partials/user-consents.html new file mode 100644 index 0000000..76eb0a8 --- /dev/null +++ b/admin/resources/partials/user-consents.html @@ -0,0 +1,41 @@ +<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' | translate}}</a></li> + <li>{{user.username}}</li> + </ol> + + <kc-tabs-user></kc-tabs-user> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th>{{:: 'client' | translate}}</th> + <th>{{:: 'granted-client-scopes' | translate}}</th> + <th>{{:: 'additional-grants' | translate}}</th> + <th>{{:: 'consent-created-date' | translate}}</th> + <th>{{:: 'consent-last-updated-date' | translate}}</th> + <th>{{:: 'action' | translate}}</th> + </tr> + </thead> + <tbody> + <tr data-ng-repeat="consent in userConsents"> + <td>{{consent.clientId}}</td> + <td> + <span data-ng-repeat="clientScope in consent.grantedClientScopes"> + <span ng-if="!$first">, </span>{{clientScope}} + </span> + </td> + <td> + <span data-ng-repeat="additionalGrant in consent.additionalGrants"> + <span ng-if="!$first">, </span><a href="#/realms/{{realm.realm}}/users/{{user.id}}/offline-sessions/{{additionalGrant.client}}">{{additionalGrant.key}}</a> + </span> + </td> + <td>{{consent.createdDate | date :'short'}}</td> + <td>{{consent.lastUpdatedDate | date :'short'}}</td> + <td class="kc-action-cell" ng-click="revokeConsent(consent.clientId)">{{:: 'revoke' | translate}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/user-credentials.html b/admin/resources/partials/user-credentials.html new file mode 100644 index 0000000..9015660 --- /dev/null +++ b/admin/resources/partials/user-credentials.html @@ -0,0 +1,179 @@ +<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' | translate}}</a></li> + <li>{{user.username}}</li> + </ol> + + <kc-tabs-user></kc-tabs-user> + + <form class="form-horizontal" name="userForm" novalidate> + + <fieldset class="border-top" data-ng-show="user.federationLink || user.origin"> + <legend> + <span class="text">{{:: 'supported-user-storage-credential-types' | translate}}</span> + <kc-tooltip>{{:: 'supported-user-storage-credential-types.tooltip' | translate}}</kc-tooltip> + </legend> + <table class="datatable table table-bordered dataTable no-footer credentials-table"> + <thead> + <tr> + <th>{{:: 'type' | translate}}</th> + <th>{{:: 'provided-by' | translate}}</th> + </tr> + </thead> + <tr ng-repeat="credential in userStorageCredentialTypes"> + <td> + <b>{{credential}}</b> + </td> + <td> + <a href="{{getUserStorageProviderLink()}}">{{getUserStorageProviderName()}}</a> + </td> + </tr> + </table> + </fieldset> + + <fieldset class="border-top"> + <legend data-ng-show="user.federationLink || user.origin"> + <span class="text">{{:: 'manage-credentials' | translate}}</span> + <kc-tooltip>{{:: 'manage-credentials.tooltip' | translate}}</kc-tooltip> + </legend> + <legend data-ng-hide="user.federationLink || user.origin"> + <span class="text">{{:: 'manage-credentials' | translate}}</span> + </legend> + <table class="datatable table table-bordered dataTable no-footer credentials-table"> + <thead> + <tr> + <th>{{:: 'position' | translate}}</th> + <th>{{:: 'type' | translate}}</th> + <th>{{:: 'user-label' | translate}}</th> + <th>{{:: 'data' | translate}}</th> + <th colspan="2">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tr ng-repeat="credential in credentials"> + <td> + <button data-ng-disabled="$first" class="btn btn-default btn-sm" data-ng-click="moveUp(credentials, $index)"><i class="fa fa-angle-up"></i></button> + <button data-ng-disabled="$last" class="btn btn-default btn-sm" data-ng-click="moveDown(credentials, $index)"><i class="fa fa-angle-down"></i></button> + </td> + <td> + <b>{{credential.type}}</b> + </td> + <td class="credential-label-cell"> + <input type="text" class="form-control" data-ng-model="credential.userLabel"/> + </td> + <td class="credential-data-cell"> + <a data-ng-show="!showData[credential.id]" data-ng-click="showData[credential.id] = true"> + {{:: 'show-data' | translate}} + </a> + <table class="datatable table dataTable no-footer credential-data-table" data-ng-show="showData[credential.id]"> + <tr ng-repeat="key in keys(credential.credentialData) | orderBy"> + <td class="key">{{key}}</td> + <td class="value">{{credential.credentialData[key]}}</td> + </tr> + </table> + </td> + <td class="credential-action-cell" ng-class="{true:'expanded'}[showData[credential.id]]" > + <div class="kc-action-cell" data-ng-click="deleteCredential(credential)"> + {{:: 'delete' | translate}} + </div> + </td> + <td class="credential-action-cell" ng-class="{true:'expanded'}[showData[credential.id]]" > + <div class="kc-action-cell" data-ng-click="updateCredentialLabel(credential)"> + {{:: 'save' | translate}} + </div> + </td> + </tr> + </table> + </fieldset> + + <fieldset class="border-top"> + <legend><span class="text">{{ (hasPassword ? 'reset-password' : 'set-password') | translate }}</span></legend> + <div class="form-group"> + <label class="col-md-2 control-label" for="newPas">{{:: 'password' | translate}} <span class="required" data-ng-show="create">*</span></label> + <div class="col-md-6"> + <input class="form-control" kc-password type="text" id="newPas" name="newPas" data-ng-model="password" required> + </div> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="confirmPas">{{:: 'password-confirmation' | translate}} <span class="required" data-ng-show="create">*</span></label> + <div class="col-md-6"> + <input class="form-control" kc-password id="confirmPas" name="confirmPas" data-ng-model="confirmPassword" required> + </div> + </div> + + <div class="form-group clearfix block"> + <label class="col-md-2 control-label" for="temporaryPassword">{{:: 'temporary' | translate}}</label> + <div class="col-sm-6"> + <input ng-model="temporaryPassword" name="temporaryPassword" id="temporaryPassword" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'credentials.temporary.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2"> + <button data-ng-disabled="!passwordAndConfirmPasswordEntered()" class="btn btn-default" type="submit" data-ng-click="resetPassword(true)">{{ (hasPassword ? 'reset-password' : 'set-password') | translate }}</button> + </div> + </div> + </fieldset> + + <fieldset class="border-top" data-ng-show="user.disableableCredentialTypes && user.disableableCredentialTypes.length > 0"> + <legend><span class="text">{{:: 'disable-credentials' | translate}}</span></legend> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="credentialTypeList">{{:: 'disableable-credential-types' | translate}}</label> + + <div class="col-md-6"> + <select ui-select2 id="credentialTypeList" ng-model="disableableCredentialTypes" data-placeholder="{{:: 'select-a-type.placeholder' | translate}}" multiple> + <option ng-repeat="credType in user.disableableCredentialTypes" value="{{credType}}">{{credType}}</option> + </select> + </div> + <kc-tooltip>{{:: 'credentials.disableable.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="disableCredentialTypes">{{:: 'disable-credential-types' | translate}}</label> + + <div class="col-md-6"> + <button data-ng-disabled="disableableCredentialTypes.length === 0" type="button" id="disableCredentialTypes" class="btn btn-default" data-ng-click="disableCredentialTypes()">{{:: 'disable' | translate}}</button> + </div> + <kc-tooltip>{{:: 'credentials.disable.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <fieldset class="border-top" data-ng-show="user.email"> + <legend><span class="text">{{:: 'credential-reset-actions' | translate}}</span></legend> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="reqActions">{{:: 'reset-actions' | translate}}</label> + + <div class="col-md-6"> + <select ui-select2 id="reqActions" ng-model="emailActions" data-placeholder="{{:: 'select-an-action.placeholder' | translate}}" multiple> + <option ng-repeat="action in userReqActionList" value="{{action.alias}}">{{action.name}} ({{action.alias}})</option> + </select> + </div> + <kc-tooltip>{{:: 'credentials.reset-actions.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="reqActionsEmailTimeout">{{:: 'credential-reset-actions-timeout' | translate}}</label> + + <div class="col-md-6 time-selector"> + <input class="form-control" type="number" required min="1" max="31536000" data-ng-model="emailActionsTimeout.time" + id="reqActionsEmailTimeout" name="reqActionsEmailTimeout"> + <select class="form-control" name="reqActionsEmailTimeoutUnit" data-ng-model="emailActionsTimeout.unit"> + <option value="Minutes">{{:: 'minutes' | translate}}</option> + <option value="Hours">{{:: 'hours' | translate}}</option> + <option value="Days">{{:: 'days' | translate}}</option> + </select> + </div> + <kc-tooltip>{{:: 'credential-reset-actions-timeout.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="reqActionsEmail">{{:: 'reset-actions-email' | translate}}</label> + + <div class="col-md-6"> + <button data-ng-disabled="emailActions.length === 0" type="button" id="reqActionsEmail" class="btn btn-default" data-ng-click="sendExecuteActionsEmail()">{{:: 'send-email' | translate}}</button> + </div> + <kc-tooltip>{{:: 'credentials.reset-actions-email.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + </form> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/user-detail.html b/admin/resources/partials/user-detail.html new file mode 100644 index 0000000..df66351 --- /dev/null +++ b/admin/resources/partials/user-detail.html @@ -0,0 +1,150 @@ +<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' | translate}}</a></li> + <li data-ng-hide="create">{{user.username}}</li> + <li data-ng-show="create">{{:: 'add-user' | translate}}</li> + </ol> + + <kc-tabs-user></kc-tabs-user> + + <form class="form-horizontal" name="userForm" novalidate kc-read-only="!create && !user.access.manage"> + + <fieldset class="border-top"> + <div class="form-group"> + <label class="col-md-2 control-label"for="id">{{:: 'id' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" id="id" name="id" data-ng-model="user.id" autofocus data-ng-readonly="true"> + </div> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label"for="id">{{:: 'created-at' | translate}}</label> + <div class="col-md-6"> + {{user.createdTimestamp|date:'shortDate'}} {{user.createdTimestamp|date:'mediumTime'}} + </div> + </div> + + <div class="form-group" data-ng-hide="emailAsUsername"> + <label class="col-md-2 control-label"for="username">{{:: 'username' | translate}} <span class="required" data-ng-show="create">*</span></label> + <div class="col-md-6"> + <!-- Characters >,<,/,\ are forbidden in username --> + <input class="form-control" type="text" id="username" name="username" data-ng-model="user.username" autofocus + data-ng-required="!emailAsUsername" ng-pattern="/^[^\<\>\\\/]*$/" data-ng-readonly="!editUsername"> + </div> + </div> + + + <div class="form-group"> + <label class="col-md-2 control-label" for="email">{{:: 'email' | translate}}</label> + + <div class="col-md-6"> + <input class="form-control" type="email" name="email" id="email" + data-ng-model="user.email"> + </div> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="firstName">{{:: 'first-name' | translate}}</label> + + <div class="col-md-6"> + <input class="form-control" type="text" name="firstName" id="firstName" + data-ng-model="user.firstName"> + </div> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="lastName">{{:: 'last-name' | translate}}</label> + + <div class="col-md-6"> + <input class="form-control" type="text" name="lastName" id="lastName" + data-ng-model="user.lastName"> + </div> + </div> + + <div class="form-group clearfix block"> + <label class="col-md-2 control-label" for="userEnabled">{{:: 'user-enabled' | translate}}</label> + <div class="col-md-6"> + <input ng-model="user.enabled" name="userEnabled" id="userEnabled" ng-disabled="!create && !user.access.manage" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'user-enabled.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="realm.bruteForceProtected && !create"> + <label class="col-md-2 control-label" for="temporarilyDisabled">{{:: 'user-temporarily-locked' | translate}}</label> + <div class="col-md-1"> + <input ng-model="temporarilyDisabled" name="temporarilyDisabled" id="temporarilyDisabled" data-ng-readonly="true" data-ng-disabled="true" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'user-temporarily-locked.tooltip' | translate}}</kc-tooltip> + <div class="col-sm-2"> + <button type="submit" data-ng-click="unlockUser()" data-ng-show="temporarilyDisabled" class="btn btn-default">{{:: 'unlock-user' | translate}}</button> + </div> + </div> + <div class="form-group clearfix block" data-ng-show="!create && user.federationLink"> + <label class="col-md-2 control-label">{{:: 'federation-link' | translate}}</label> + <div class="col-md-6"> + <a href="{{federationLink}}">{{federationLinkName}}</a> + </div> + <kc-tooltip>{{:: 'user-link.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block" data-ng-show="!create && user.origin"> + <label class="col-md-2 control-label">{{:: 'user-origin-link' | translate}}</label> + <div class="col-md-6"> + <a href="{{originLink}}">{{originName}}</a> + </div> + <kc-tooltip>{{:: 'user-origin.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block"> + <label class="col-md-2 control-label" for="emailVerified">{{:: 'email-verified' | translate}}</label> + <div class="col-md-6"> + <input ng-model="user.emailVerified" name="emailVerified" id="emailVerified" ng-disabled="!create && !user.access.manage" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + <kc-tooltip>{{:: 'email-verified.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="reqActions">{{:: 'required-user-actions' | translate}}</label> + + <div class="col-md-6"> + <select ui-select2 id="reqActions" ng-model="user.requiredActions" data-placeholder="{{:: 'select-an-action.placeholder' | translate}}" multiple> + <option ng-repeat="action in userReqActionList" value="{{action.alias}}">{{action.name}}</option> + </select> + </div> + <kc-tooltip>{{:: 'required-user-actions.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group clearfix" data-ng-if="realm.internationalizationEnabled"> + <label class="col-md-2 control-label" for="locale">{{:: 'locale' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="locale" + ng-model="user.attributes.locale" + ng-options="o as o for o in realm.supportedLocales"> + <option value="" disabled selected>{{:: 'select-one.placeholder' | translate}}</option> + </select> + </div> + </div> + </div> + + <div class="form-group clearfix" data-ng-hide="create || !access.impersonation"> + <label class="col-md-2 control-label" for="impersonate">{{:: 'impersonate-user' | translate}}</label> + + <div class="col-md-6"> + <button id="impersonate" data-ng-show="access.impersonation" kc-read-only-ignore class="btn btn-default" data-ng-click="impersonate()">{{:: 'impersonate' | translate}}</button> + </div> + <kc-tooltip>{{:: 'impersonate-user.tooltip' | translate}}</kc-tooltip> + </div> + + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="create && access.manageUsers"> + <button kc-save data-ng-show="changed">{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + + <div class="col-md-10 col-md-offset-2" data-ng-show="!create && user.access.manage"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + + </form> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/user-federated-identity-detail.html b/admin/resources/partials/user-federated-identity-detail.html new file mode 100644 index 0000000..aa5d049 --- /dev/null +++ b/admin/resources/partials/user-federated-identity-detail.html @@ -0,0 +1,53 @@ +<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' | translate}}</a></li> + <li>{{user.username}}</li> + </ol> + + <h1 data-ng-show="create">{{:: 'add-identity-provider-link' | translate}}</h1> + + <kc-tabs-user></kc-tabs-user> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <fieldset> + <div class="form-group"> + <label class="col-md-2 control-label" for="identityProvider">{{:: 'identity-provider' | translate}} <span class="required">*</span></label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="identityProvider" + ng-model="federatedIdentity.identityProvider" + ng-options="providerAlias for providerAlias in availableProvidersToCreate" + required> + </select> + </div> + </div> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="userId">{{:: 'identity-provider-user-id' | translate}} <span class="required">*</span></label> + <div class="col-md-6"> + <input class="form-control" id="userId" type="text" ng-model="federatedIdentity.userId" required> + </div> + <kc-tooltip>{{:: 'identity-provider-user-id.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="userName">{{:: 'identity-provider-username' | translate}} <span class="required">*</span></label> + <div class="col-md-6"> + <input class="form-control" id="userName" type="text" ng-model="federatedIdentity.userName" required> + </div> + <kc-tooltip>{{:: 'identity-provider-username.tooltip' | translate}}</kc-tooltip> + </div> + + </fieldset> + + + <div class="form-group" data-ng-show="access.manageRealm"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save>{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/user-federated-identity-list.html b/admin/resources/partials/user-federated-identity-list.html new file mode 100644 index 0000000..82f96f6 --- /dev/null +++ b/admin/resources/partials/user-federated-identity-list.html @@ -0,0 +1,41 @@ +<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' | translate}}</a></li> + <li>{{user.username}}</li> + </ol> + + <kc-tabs-user></kc-tabs-user> + + <table class="table table-striped table-bordered"> + <thead> + <tr data-ng-show="hasAnyProvidersToCreate()"> + <th class="kc-table-actions" colspan="4"> + <div class="form-inline"> + <div class="pull-right"> + <a class="btn btn-primary" href="#/create/federated-identity/{{realm.realm}}/{{user.id}}">{{:: 'create' | translate}}</a> + </div> + </div> + </th> + </tr> + <tr data-ng-hide="federatedIdentities.length == 0"> + <th>{{:: 'identity-provider-alias' | translate}}</th> + <th>{{:: 'provider-user-id' | translate}}</th> + <th>{{:: 'provider-username' | translate}}</th> + <th>{{:: 'action' | translate}}</th> + </tr> + </thead> + <tbody> + <tr data-ng-repeat="identity in federatedIdentities"> + <td>{{identity.identityProvider}}</td> + <td>{{identity.userId}}</td> + <td>{{identity.userName}}</td> + <td class="kc-action-cell" ng-click="removeProviderLink(identity)">{{:: 'remove' | translate}}</td> + </tr> + <tr data-ng-show="federatedIdentities.length == 0"> + <td>{{:: 'no-identity-provider-links-available' | translate}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/user-federation.html b/admin/resources/partials/user-federation.html new file mode 100644 index 0000000..4338ea9 --- /dev/null +++ b/admin/resources/partials/user-federation.html @@ -0,0 +1,69 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1> + <span>{{:: 'user-federation' | translate}}</span> + </h1> + + <div class="blank-slate-pf" data-ng-hide="!instancesLoaded || (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.manageRealm"> + <div class="col-sm-4 col-sm-offset-4"> + <div class="form-group"> + <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> + </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.manageRealm"> + <th colspan="6" 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>{{:: 'enabled' | 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>{{isProviderEnabled(instance)}}</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> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/user-group-membership.html b/admin/resources/partials/user-group-membership.html new file mode 100644 index 0000000..abfb237 --- /dev/null +++ b/admin/resources/partials/user-group-membership.html @@ -0,0 +1,114 @@ + <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' | translate}}</a></li> + <li>{{user.username}}</li> + </ol> + + <kc-tabs-user></kc-tabs-user> + + <form class="form-horizontal" name="realmForm" novalidate> + <div class="form-group" kc-read-only="!user.access.manageGroupMembership"> + <label class="col-md-1 control-label" class="control-label"></label> + + <div class="col-md-8" > + <div class="row"> + <div class="col-md-5"> + <table class="table table-striped table-bordered" style="margin-bottom: 0"> + <thead> + <tr> + <th class="kc-table-actions" colspan="5"> + <div class="form-inline"> + <div> + <label class="control-label">{{:: 'group-membership' | translate}}</label> + <kc-tooltip>{{:: 'group-membership.tooltip' | translate}}</kc-tooltip> + </div> + <div class="pull-left"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" ng-model="searchCriteriaMembership" class="form-control search" onkeydown="if (event.keyCode == 13) document.getElementById('groupSearch').click()"> + <div class="input-group-addon"> + <i class="fa fa-search" id="groupSearch" ng-click="searchGroupMembership()"></i> + </div> + </div> + </div> + + <button id="viewAllGroups" class="btn btn-default" ng-click="clearSearchMembership()">{{:: 'view-all-groups' | translate}}</button> + <div class="pull-right" data-ng-show="user.access.manageGroupMembership"> + <button id="leaveGroups" class="btn btn-default" ng-click="leaveGroup()">{{:: 'leave' | translate}}</button> + </div> + </div> + </th> + </tr> + </thead> + <tbody> + <tr> + <td> + <div + tree-id="membershipTree" + angular-treeview="true" + tree-model="groupMemberships" + node-id="id" + node-label="path" + node-children="subGroupsMembership" > + </div> + </td> + </tr> + </tbody> + </table> + <div style="margin-bottom: 50px"> + <kc-paging current-page="currentMembershipPage" number-of-pages="numberOfMembershipPages" current-page-input="currentMembershipPageInput"></kc-paging> + </div> + </div> + <div class="col-md-5"> + <table class="table table-striped table-bordered" style="margin-bottom: 0"> + <thead> + <tr> + <th class="kc-table-actions" colspan="5"> + + <div class="form-inline"> + <div> + <label class="control-label">{{:: 'available-groups' | translate}}</label> + <kc-tooltip>{{:: 'membership.available-groups.tooltip' | translate}}</kc-tooltip> + </div> + <div class="pull-left"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" ng-model="searchCriteria" class="form-control search" onkeydown="if (event.keyCode == 13) document.getElementById('groupSearch_availablegroups').click()"> + <div class="input-group-addon"> + <i class="fa fa-search" id="groupSearch_availablegroups" ng-click="searchGroup()"></i> + </div> + </div> + </div> + + <button id="viewAllGroups" class="btn btn-default" ng-click="clearSearch()">{{:: 'view-all-groups' | translate}}</button> + <div class="pull-right" data-ng-show="user.access.manageGroupMembership"> + <button id="joinGroup" class="btn btn-default" ng-click="joinGroup()">{{:: 'join' | translate}}</button> + </div> + </div> + </th> + </tr> + </thead> + <tbody> + <tr> + <td> + <div + tree-id="tree" + angular-treeview="true" + tree-model="groupList" + node-id="id" + node-label="name" + node-children="subGroups" > + </div> + </td> + </tr> + </tbody> + </table> + <div style="margin-bottom: 50px"> + <kc-paging current-page="currentPage" number-of-pages="numberOfPages" current-page-input="currentPageInput"></kc-paging> + </div> + </div> + </div> + </div> + </div> + </form> + </div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/user-list.html b/admin/resources/partials/user-list.html new file mode 100644 index 0000000..1fc707c --- /dev/null +++ b/admin/resources/partials/user-list.html @@ -0,0 +1,69 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2" ng-init="init()"> + + <kc-tabs-users></kc-tabs-users> + + <table class="table table-striped table-bordered" id="user-table"> + <caption data-ng-show="users" class="hidden">{{:: 'table-of-realm-users' | translate}}</caption> + <thead> + <tr> + <th colspan="{{access.impersonation == true ? '8' : '7'}}"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" data-ng-model="query.search" class="form-control search" onkeydown="if (event.keyCode == 13) document.getElementById('userSearch').click()"> + <div class="input-group-addon"> + <i class="fa fa-search" id="userSearch" data-ng-click="firstPage()"></i> + </div> + </div> + </div> + <button id="viewAllUsers" class="btn btn-default" ng-click="query.search = null; firstPage()">{{:: 'view-all-users' | translate}}</button> + + <div class="pull-right" data-ng-show="access.manageUsers"> + <button data-ng-click="unlockUsers()" class="btn btn-default">{{:: 'unlock-users' | translate}}</button> + <a id="createUser" class="btn btn-default" href="#/create/user/{{realm.realm}}">{{:: 'add-user' | translate}}</a> + </div> + </div> + </th> + </tr> + <tr> + <tr data-ng-show="searchLoaded && users.length > 0"> + <th class="w-15">{{:: 'id' | translate}}</th> + <th class="w-15">{{:: 'username' | translate}}</th> + <th class="w-15">{{:: 'email' | translate}}</th> + <th class="w-15">{{:: 'last-name' | translate}}</th> + <th class="w-15">{{:: 'first-name' | translate}}</th> + <th colspan="{{serverInfo.featureEnabled('IMPERSONATION') && access.impersonation == true ? '3' : '2'}}">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tfoot data-ng-show="users && (users.length >= query.max || query.first > 0)"> + <tr> + <td colspan="7"> + <div class="table-nav"> + <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button> + <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button> + <button data-ng-click="nextPage()" class="next" ng-disabled="users.length < query.max">{{:: 'next-page' | translate}}</button> + </div> + </td> + </tr> + </tfoot> + <tbody> + <tr ng-repeat="user in users"> + <td class="clip"><a href="#/realms/{{realm.realm}}/users/{{user.id}}">{{user.id}}</a></td> + <td class="clip">{{user.username}}</td> + <td class="clip">{{user.email}}</td> + <td class="clip">{{user.lastName}}</td> + <td class="clip">{{user.firstName}}</td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/users/{{user.id}}">{{:: 'edit' | translate}}</td> + <td data-ng-show="serverInfo.featureEnabled('IMPERSONATION') && access.impersonation" class="kc-action-cell" data-ng-click="impersonate(user.id)">{{:: 'impersonate' | translate}}</td> + <td data-ng-show="user.access.manage" class="kc-action-cell" data-ng-click="removeUser(user)">{{:: 'delete' | translate}}</td> + </tr> + <tr data-ng-show="!users || users.length == 0"> + <td class="text-muted" data-ng-show="!users">{{:: 'users.instruction' | translate}}</td> + <td class="text-muted" data-ng-show="searchLoaded && users.length == 0 && lastSearch != null">{{:: 'no-results' | translate}}</td> + <td class="text-muted" data-ng-show="searchLoaded && users.length == 0 && lastSearch == null">{{:: 'no-users-available' | translate}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/user-offline-sessions.html b/admin/resources/partials/user-offline-sessions.html new file mode 100644 index 0000000..0194bca --- /dev/null +++ b/admin/resources/partials/user-offline-sessions.html @@ -0,0 +1,35 @@ +<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' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/users/{{user.id}}">{{user.username}}</a></li> + <li><a href="#/realms/{{realm.realm}}/users/{{user.id}}/consents">{{:: 'consents' | translate}}</a></li> + <li>{{client.clientId}}</li> + </ol> + + <kc-tabs-user></kc-tabs-user> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th>{{:: 'ip-address' | translate}}</th> + <th>{{:: 'started' | translate}}</th> + <th>{{:: 'last-refresh' | translate}}</th> + </tr> + </thead> + <tbody> + <tr data-ng-repeat="session in offlineSessions"> + <td>{{session.ipAddress}}</td> + <td>{{session.start | date:'medium'}}</td> + <td>{{session.lastAccess | date:'medium'}}</td> + </tr> + </tbody> + </table> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2"> + <button kc-cancel data-ng-click="cancel()">{{:: 'back' | translate}}</button> + </div> + </div> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/user-sessions.html b/admin/resources/partials/user-sessions.html new file mode 100644 index 0000000..02c1959 --- /dev/null +++ b/admin/resources/partials/user-sessions.html @@ -0,0 +1,43 @@ + <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' | translate}}</a></li> + <li>{{user.username}}</li> + </ol> + + <kc-tabs-user></kc-tabs-user> + + <table class="table table-striped table-bordered"> + <thead> + <tr data-ng-show="user.access.manage"> + <th class="kc-table-actions" colspan="6"> + <div class="pull-right" data-ng-show="user.access.manage"> + <a id="logoutAllSessions" class="btn btn-default" ng-click="logoutAll()">{{:: 'logout-all-sessions' | translate}}</a> + </div> + </th> + </tr> + <tr> + <th>{{:: 'ip-address' | translate}}</th> + <th>{{:: 'started' | translate}}</th> + <th>{{:: 'last-access' | translate}}</th> + <th>{{:: 'clients' | translate}}</th> + <th data-ng-show="user.access.manage">{{:: 'action' | translate}}</th> + </tr> + </thead> + <tbody> + <tr data-ng-repeat="session in sessions"> + <td>{{session.ipAddress}}</td> + <td>{{session.start | date:'medium'}}</td> + <td>{{session.lastAccess | date:'medium'}}</td> + <td> + <div data-ng-repeat="(id, clientId) in session.clients"> + <a href="#/realms/{{realm.realm}}/clients/{{id}}">{{clientId}}</a> + </div> + </ul> + </td> + <td class="kc-action-cell" data-ng-show="user.access.manage" ng-click="logoutSession(session.id)">{{:: 'logout' | translate}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/user-storage-generic.html b/admin/resources/partials/user-storage-generic.html new file mode 100644 index 0000000..2b2456c --- /dev/null +++ b/admin/resources/partials/user-storage-generic.html @@ -0,0 +1,246 @@ +<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}}/user-federation">{{:: 'user-federation' | translate}}</a></li> + <li data-ng-hide="create">{{instance.name|capitalize}}</li> + <li data-ng-show="create">{{:: 'add-user-storage-provider' | translate}}</li> + </ol> + + <kc-tabs-user-storage></kc-tabs-user-storage> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <fieldset> + <legend><span class="text">{{:: 'required-settings' | translate}}</span></legend> + <div class="form-group clearfix" data-ng-show="!create"> + <label class="col-md-2 control-label" for="providerId">{{:: 'provider-id' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="providerId" type="text" ng-model="instance.id" readonly> + </div> + </div> + <div class="form-group clearfix block"> + <label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label> + <div class="col-md-6"> + <input ng-model="instance.config['enabled'][0]" name="enabled" id="enabled" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'user-storage.enabled.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="consoleDisplayName">{{:: 'console-display-name' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="consoleDisplayName" type="text" ng-model="instance.name" placeholder="{{:: 'defaults-to-id' | translate}}"> + </div> + <kc-tooltip>{{:: 'console-display-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="priority">{{:: 'priority' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="priority" type="text" ng-model="instance.config['priority'][0]"> + </div> + <kc-tooltip>{{:: 'priority.tooltip' | translate}}</kc-tooltip> + </div> + + <kc-component-config realm="realm" config="instance.config" properties="providerFactory.properties"></kc-component-config> + + </fieldset> + + <fieldset ng-show="showSync"> + <legend><span class="text">{{:: 'sync-settings' | translate}}</span></legend> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="fullSyncEnabled">{{:: 'periodic-full-sync' | translate}}</label> + <div class="col-md-6"> + <input ng-model="fullSyncEnabled" name="fullSyncEnabled" id="fullSyncEnabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'periodic-full-sync.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="fullSyncEnabled"> + <label class="col-md-2 control-label" for="fullSyncPeriod">{{:: 'full-sync-period' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" ng-model="instance.config['fullSyncPeriod'][0]" id="fullSyncPeriod" /> + </div> + <kc-tooltip>{{:: 'full-sync-period.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="changedSyncEnabled">{{:: 'periodic-changed-users-sync' | translate}}</label> + <div class="col-md-6"> + <input ng-model="changedSyncEnabled" name="changedSyncEnabled" id="changedSyncEnabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'periodic-changed-users-sync.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="changedSyncEnabled"> + <label class="col-md-2 control-label" for="changedSyncPeriod">{{:: 'changed-users-sync-period' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" ng-model="instance.config['changedSyncPeriod'][0]" id="changedSyncPeriod" /> + </div> + <kc-tooltip>{{:: 'changed-users-sync-period.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + + <fieldset> + <legend><span class="text">{{:: 'user-storage-cache-policy' | translate}}</span></legend> + <div class="form-group"> + <label for="cachePolicy" class="col-md-2 control-label">{{:: 'userStorage.cachePolicy' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="cachePolicy" ng-model="instance.config['cachePolicy'][0]" class="form-control"> + <option value="DEFAULT">{{:: 'userStorage.cachePolicy.option.DEFAULT' | translate}}</option> + <option value="EVICT_DAILY">{{:: 'userStorage.cachePolicy.option.EVICT_DAILY' | translate}}</option> + <option value="EVICT_WEEKLY">{{:: 'userStorage.cachePolicy.option.EVICT_WEEKLY' | translate}}</option> + <option value="MAX_LIFESPAN">{{:: 'userStorage.cachePolicy.option.MAX_LIFESPAN' | translate}}</option> + <option value="NO_CACHE">{{:: 'userStorage.cachePolicy.option.NO_CACHE' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'userStorage.cachePolicy.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="instance.config['cachePolicy'][0] == 'EVICT_WEEKLY'"> + <label for="evictionDay" class="col-md-2 control-label">{{:: 'userStorage.cachePolicy.evictionDay' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="evictionDay" ng-model="instance.config['evictionDay'][0]" class="form-control"> + <option value="1">{{:: 'Sunday' | translate}}</option> + <option value="2">{{:: 'Monday' | translate}}</option> + <option value="3">{{:: 'Tuesday' | translate}}</option> + <option value="4">{{:: 'Wednesday' | translate}}</option> + <option value="5">{{:: 'Thursday' | translate}}</option> + <option value="6">{{:: 'Friday' | translate}}</option> + <option value="7">{{:: 'Saturday' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'userStorage.cachePolicy.evictionDay.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['cachePolicy'][0] == 'EVICT_WEEKLY' || instance.config['cachePolicy'][0] == 'EVICT_DAILY'"> + <label class="col-md-2 control-label" for="evictionHour">{{:: 'userStorage.cachePolicy.evictionHour' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="evictionHour" ng-model="instance.config['evictionHour'][0]" class="form-control"> + <option value="0">00</option> + <option value="1">01</option> + <option value="2">02</option> + <option value="3">03</option> + <option value="4">04</option> + <option value="5">05</option> + <option value="6">06</option> + <option value="7">07</option> + <option value="8">08</option> + <option value="9">09</option> + <option value="10">10</option> + <option value="11">11</option> + <option value="12">12</option> + <option value="13">13</option> + <option value="14">14</option> + <option value="15">15</option> + <option value="16">16</option> + <option value="17">17</option> + <option value="18">18</option> + <option value="19">19</option> + <option value="20">20</option> + <option value="21">21</option> + <option value="22">22</option> + <option value="23">23</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'userStorage.cachePolicy.evictionHour.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['cachePolicy'][0] == 'EVICT_WEEKLY' || instance.config['cachePolicy'][0] == 'EVICT_DAILY'"> + <label class="col-md-2 control-label" for="evictionMinute">{{:: 'userStorage.cachePolicy.evictionMinute' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="evictionMinute" ng-model="instance.config['evictionMinute'][0]" class="form-control"> + <option value="0">00</option> + <option value="1">01</option> + <option value="2">02</option> + <option value="3">03</option> + <option value="4">04</option> + <option value="5">05</option> + <option value="6">06</option> + <option value="7">07</option> + <option value="8">08</option> + <option value="9">09</option> + <option value="10">10</option> + <option value="11">11</option> + <option value="12">12</option> + <option value="13">13</option> + <option value="14">14</option> + <option value="15">15</option> + <option value="16">16</option> + <option value="17">17</option> + <option value="18">18</option> + <option value="19">19</option> + <option value="20">20</option> + <option value="21">21</option> + <option value="22">22</option> + <option value="23">23</option> + <option value="24">24</option> + <option value="25">25</option> + <option value="26">26</option> + <option value="27">27</option> + <option value="28">28</option> + <option value="29">29</option> + <option value="30">30</option> + <option value="31">31</option> + <option value="32">32</option> + <option value="33">33</option> + <option value="34">34</option> + <option value="35">35</option> + <option value="36">36</option> + <option value="37">37</option> + <option value="38">38</option> + <option value="39">39</option> + <option value="40">40</option> + <option value="41">41</option> + <option value="42">42</option> + <option value="43">43</option> + <option value="44">44</option> + <option value="45">45</option> + <option value="46">46</option> + <option value="47">47</option> + <option value="48">48</option> + <option value="49">49</option> + <option value="50">50</option> + <option value="51">51</option> + <option value="52">52</option> + <option value="53">53</option> + <option value="54">54</option> + <option value="55">55</option> + <option value="56">56</option> + <option value="57">57</option> + <option value="58">58</option> + <option value="59">59</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'userStorage.cachePolicy.evictionMinute.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['cachePolicy'][0] == 'MAX_LIFESPAN'"> + <label class="col-md-2 control-label" for="maxLifespan">{{:: 'userStorage.cachePolicy.maxLifespan' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" ng-model="instance.config['maxLifespan'][0]" id="maxLifespan" /> + </div> + <kc-tooltip>{{:: 'userStorage.cachePolicy.maxLifespan.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="create && access.manageRealm"> + <button kc-save>{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="!create && access.manageRealm"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + <button class="btn btn-primary" data-ng-click="triggerChangedUsersSync()" data-ng-hide="changed || !showSync">{{:: 'synchronize-changed-users' | translate}}</button> + <button class="btn btn-primary" data-ng-click="triggerFullSync()" data-ng-hide="changed || !showSync">{{:: 'synchronize-all-users' | translate}}</button> + <button class="btn btn-primary" data-ng-click="removeImportedUsers()" data-ng-hide="changed">{{:: 'remove-imported-users' | translate}}</button> + <button class="btn btn-primary" data-ng-click="unlinkUsers()" data-ng-hide="changed">{{:: 'unlink-users' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/user-storage-kerberos.html b/admin/resources/partials/user-storage-kerberos.html new file mode 100644 index 0000000..b7fa6ef --- /dev/null +++ b/admin/resources/partials/user-storage-kerberos.html @@ -0,0 +1,264 @@ +<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}}/user-federation">{{:: 'user-federation' | translate}}</a></li> + <li data-ng-hide="create">{{instance.name|capitalize}}</li> + <li data-ng-show="create">{{:: 'add-user-storage-provider' | translate}}</li> + </ol> + + <kc-tabs-user-storage></kc-tabs-user-storage> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <fieldset> + <legend><span class="text">{{:: 'required-settings' | translate}}</span></legend> + <div class="form-group clearfix" data-ng-show="!create"> + <label class="col-md-2 control-label" for="providerId">{{:: 'provider-id' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="providerId" type="text" ng-model="instance.id" readonly> + </div> + </div> + <div class="form-group clearfix block"> + <label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label> + <div class="col-md-6"> + <input ng-model="instance.config['enabled'][0]" name="enabled" id="enabled" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'user-storage.enabled.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="consoleDisplayName">{{:: 'console-display-name' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="consoleDisplayName" type="text" ng-model="instance.name" placeholder="{{:: 'defaults-to-id' | translate}}"> + </div> + <kc-tooltip>{{:: 'console-display-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="priority">{{:: 'priority' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="priority" type="text" ng-model="instance.config['priority'][0]"> + </div> + <kc-tooltip>{{:: 'priority.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="kerberosRealm"><span class="required">*</span> {{:: 'kerberos-realm' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="kerberosRealm" type="text" ng-model="instance.config['kerberosRealm'][0]" required> + </div> + <kc-tooltip>{{:: 'kerberos-realm.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="serverPrincipal"><span class="required">*</span> {{:: 'server-principal' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="serverPrincipal" type="text" ng-model="instance.config['serverPrincipal'][0]" required> + </div> + <kc-tooltip>{{:: 'server-principal.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="keyTab"><span class="required">*</span> {{:: 'keytab' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="keyTab" type="text" ng-model="instance.config['keyTab'][0]" required> + </div> + <kc-tooltip>{{:: 'keytab.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="debug">{{:: 'debug' | translate}} </label> + <div class="col-md-6"> + <input ng-model="instance.config['debug'][0]" id="debug" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'debug.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="allowPasswordAuthentication">{{:: 'allow-password-authentication' | translate}} </label> + <div class="col-md-6"> + <input ng-model="instance.config['allowPasswordAuthentication'][0]" id="allowPasswordAuthentication" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'allow-password-authentication.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="instance.config['allowPasswordAuthentication'][0] == 'true'"> + <label class="col-md-2 control-label" for="editMode">{{:: 'edit-mode' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="editMode" + ng-model="instance.config['editMode'][0]"> + <option>READ_ONLY</option> + <option>UNSYNCED</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'edit-mode.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="updateProfileFirstLogin">{{:: 'update-profile-first-login' | translate}} </label> + <div class="col-md-6"> + <input ng-model="instance.config['updateProfileFirstLogin'][0]" id="updateProfileFirstLogin" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'update-profile-first-login.tooltip' | translate}}</kc-tooltip> + </div> + + </fieldset> + + <fieldset> + <legend><span class="text">{{:: 'user-storage-cache-policy' | translate}}</span></legend> + <div class="form-group"> + <label for="cachePolicy" class="col-md-2 control-label">{{:: 'userStorage.cachePolicy' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="cachePolicy" ng-model="instance.config['cachePolicy'][0]" class="form-control"> + <option value="DEFAULT">{{:: 'userStorage.cachePolicy.option.DEFAULT' | translate}}</option> + <option value="EVICT_DAILY">{{:: 'userStorage.cachePolicy.option.EVICT_DAILY' | translate}}</option> + <option value="EVICT_WEEKLY">{{:: 'userStorage.cachePolicy.option.EVICT_WEEKLY' | translate}}</option> + <option value="MAX_LIFESPAN">{{:: 'userStorage.cachePolicy.option.MAX_LIFESPAN' | translate}}</option> + <option value="NO_CACHE">{{:: 'userStorage.cachePolicy.option.NO_CACHE' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'userStorage.cachePolicy.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="instance.config['cachePolicy'][0] == 'EVICT_WEEKLY'"> + <label for="evictionDay" class="col-md-2 control-label">{{:: 'userStorage.cachePolicy.evictionDay' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="evictionDay" ng-model="instance.config['evictionDay'][0]" class="form-control"> + <option value="1">{{:: 'Sunday' | translate}}</option> + <option value="2">{{:: 'Monday' | translate}}</option> + <option value="3">{{:: 'Tuesday' | translate}}</option> + <option value="4">{{:: 'Wednesday' | translate}}</option> + <option value="5">{{:: 'Thursday' | translate}}</option> + <option value="6">{{:: 'Friday' | translate}}</option> + <option value="7">{{:: 'Saturday' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'userStorage.cachePolicy.evictionDay.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['cachePolicy'][0] == 'EVICT_WEEKLY' || instance.config['cachePolicy'][0] == 'EVICT_DAILY'"> + <label class="col-md-2 control-label" for="evictionHour">{{:: 'userStorage.cachePolicy.evictionHour' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="evictionHour" ng-model="instance.config['evictionHour'][0]" class="form-control"> + <option value="0">00</option> + <option value="1">01</option> + <option value="2">02</option> + <option value="3">03</option> + <option value="4">04</option> + <option value="5">05</option> + <option value="6">06</option> + <option value="7">07</option> + <option value="8">08</option> + <option value="9">09</option> + <option value="10">10</option> + <option value="11">11</option> + <option value="12">12</option> + <option value="13">13</option> + <option value="14">14</option> + <option value="15">15</option> + <option value="16">16</option> + <option value="17">17</option> + <option value="18">18</option> + <option value="19">19</option> + <option value="20">20</option> + <option value="21">21</option> + <option value="22">22</option> + <option value="23">23</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'userStorage.cachePolicy.evictionHour.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['cachePolicy'][0] == 'EVICT_WEEKLY' || instance.config['cachePolicy'][0] == 'EVICT_DAILY'"> + <label class="col-md-2 control-label" for="evictionMinute">{{:: 'userStorage.cachePolicy.evictionMinute' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="evictionMinute" ng-model="instance.config['evictionMinute'][0]" class="form-control"> + <option value="0">00</option> + <option value="1">01</option> + <option value="2">02</option> + <option value="3">03</option> + <option value="4">04</option> + <option value="5">05</option> + <option value="6">06</option> + <option value="7">07</option> + <option value="8">08</option> + <option value="9">09</option> + <option value="10">10</option> + <option value="11">11</option> + <option value="12">12</option> + <option value="13">13</option> + <option value="14">14</option> + <option value="15">15</option> + <option value="16">16</option> + <option value="17">17</option> + <option value="18">18</option> + <option value="19">19</option> + <option value="20">20</option> + <option value="21">21</option> + <option value="22">22</option> + <option value="23">23</option> + <option value="24">24</option> + <option value="25">25</option> + <option value="26">26</option> + <option value="27">27</option> + <option value="28">28</option> + <option value="29">29</option> + <option value="30">30</option> + <option value="31">31</option> + <option value="32">32</option> + <option value="33">33</option> + <option value="34">34</option> + <option value="35">35</option> + <option value="36">36</option> + <option value="37">37</option> + <option value="38">38</option> + <option value="39">39</option> + <option value="40">40</option> + <option value="41">41</option> + <option value="42">42</option> + <option value="43">43</option> + <option value="44">44</option> + <option value="45">45</option> + <option value="46">46</option> + <option value="47">47</option> + <option value="48">48</option> + <option value="49">49</option> + <option value="50">50</option> + <option value="51">51</option> + <option value="52">52</option> + <option value="53">53</option> + <option value="54">54</option> + <option value="55">55</option> + <option value="56">56</option> + <option value="57">57</option> + <option value="58">58</option> + <option value="59">59</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'userStorage.cachePolicy.evictionMinute.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['cachePolicy'][0] == 'MAX_LIFESPAN'"> + <label class="col-md-2 control-label" for="maxLifespan">{{:: 'userStorage.cachePolicy.maxLifespan' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" ng-model="instance.config['maxLifespan'][0]" id="maxLifespan" /> + </div> + <kc-tooltip>{{:: 'userStorage.cachePolicy.maxLifespan.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="create && access.manageRealm"> + <button kc-save>{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="!create && access.manageRealm"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/user-storage-ldap-mapper-detail.html b/admin/resources/partials/user-storage-ldap-mapper-detail.html new file mode 100644 index 0000000..88de0ff --- /dev/null +++ b/admin/resources/partials/user-storage-ldap-mapper-detail.html @@ -0,0 +1,64 @@ +<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}}/user-federation">{{:: 'user-federation' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/user-storage/providers/ldap/{{provider.id}}">{{provider.providerId|capitalize}}</a></li> + <li><a href="#/realms/{{realm.realm}}/ldap-mappers/{{provider.id}}">{{:: 'ldap-mappers' | translate}}</a></li> + <li class="active" data-ng-show="create">{{:: 'create-ldap-mapper' | translate}}</li> + <li class="active" data-ng-hide="create">{{mapper.name}}</li> + </ol> + + <h1 data-ng-hide="create">{{mapper.name|capitalize}}<i class="pficon pficon-delete clickable" data-ng-show="!create && access.manageRealm" + data-ng-hide="changed" data-ng-click="remove()"></i></h1> + <h1 data-ng-show="create">{{:: 'add-user-federation-mapper' | translate}}</h1> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <fieldset> + <div class="form-group clearfix" data-ng-show="!create"> + <label class="col-md-2 control-label" for="mapperId">{{:: 'id' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="mapperId" type="text" ng-model="mapper.id" readonly> + </div> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="name">{{:: 'name' | translate}} <span class="required">*</span></label> + <div class="col-md-6"> + <input class="form-control" id="name" type="text" ng-model="mapper.name" data-ng-readonly="!create" required> + </div> + <kc-tooltip>{{:: 'mapper.name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="create"> + <label class="col-md-2 control-label" for="mapperTypeCreate">{{:: 'mapper-type' | translate}}</label> + <div class="col-sm-6"> + <div> + <select class="form-control" id="mapperTypeCreate" + ng-model="mapperType" + ng-options="mapperType.id for mapperType in mapperTypes"> + </select> + </div> + </div> + <kc-tooltip>{{mapperType.helpText}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-hide="create"> + <label class="col-md-2 control-label" for="mapperType">{{:: 'mapper-type' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="mapperType" type="text" ng-model="mapperType.id" data-ng-readonly="true"> + </div> + <kc-tooltip>{{mapperType.helpText}}</kc-tooltip> + </div> + + <kc-component-config realm="realm" clients="clients" config="mapper.config" properties="mapperType.properties"></kc-component-config> + + </fieldset> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="access.manageRealm"> + <button kc-save data-ng-disabled="!changed">Save</button> + <button kc-reset data-ng-disabled="!changed">Cancel</button> + <button class="btn btn-primary" data-ng-click="triggerFedToKeycloakSync()" data-ng-hide="create || !mapperType.metadata.fedToKeycloakSyncSupported" data-ng-disabled="changed">{{:: mapperType.metadata.fedToKeycloakSyncMessage | translate}}</button> + <button class="btn btn-primary" data-ng-click="triggerKeycloakToFedSync()" data-ng-hide="create || !mapperType.metadata.keycloakToFedSyncSupported" data-ng-disabled="changed">{{:: mapperType.metadata.keycloakToFedSyncMessage | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/user-storage-ldap-mappers.html b/admin/resources/partials/user-storage-ldap-mappers.html new file mode 100644 index 0000000..794e83e --- /dev/null +++ b/admin/resources/partials/user-storage-ldap-mappers.html @@ -0,0 +1,46 @@ +<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}}/user-federation">{{:: 'user-federation' | translate}}</a></li> + <li><a href="#/realms/{{realm.realm}}/user-storage/providers/ldap/{{provider.id}}">{{provider.name|capitalize}}</a></li> + <li>{{:: 'ldap-mappers' | translate}}</li> + </ol> + + <kc-tabs-ldap></kc-tabs-ldap> + + <table class="table table-striped table-bordered"> + <thead> + <tr> + <th class="kc-table-actions" colspan="4"> + <div class="form-inline"> + <div class="form-group"> + <div class="input-group"> + <input type="text" placeholder="{{:: 'search.placeholder' | translate}}" data-ng-model="search.name" class="form-control search" onkeyup="if(event.keyCode == 13){$(this).next('I').click();}"> + <div class="input-group-addon"> + <i class="fa fa-search" type="submit"></i> + </div> + </div> + </div> + <div class="pull-right"> + <a class="btn btn-primary" href="#/create/ldap-mappers/{{realm.realm}}/{{provider.id}}">{{:: 'create' | translate}}</a> + </div> + </div> + </th> + </tr> + <tr data-ng-hide="mappers.length == 0"> + <th>{{:: 'name' | translate}}</th> + <th>{{:: 'type' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="mapper in mappers | filter:search"> + <td><a href="#/realms/{{realm.realm}}/ldap-mappers/{{provider.id}}/mappers/{{mapper.id}}">{{mapper.name}}</a></td> + <td>{{mapper.providerId}}</td> + </tr> + <tr data-ng-show="mappers.length == 0"> + <td>{{:: 'no-mappers-available' | translate}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/user-storage-ldap.html b/admin/resources/partials/user-storage-ldap.html new file mode 100644 index 0000000..c57d10d --- /dev/null +++ b/admin/resources/partials/user-storage-ldap.html @@ -0,0 +1,549 @@ +<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}}/user-federation">{{:: 'user-federation' | translate}}</a></li> + <li data-ng-hide="create">{{instance.name|capitalize}}</li> + <li data-ng-show="create">{{:: 'add-user-storage-provider' | translate}}</li> + </ol> + + <kc-tabs-ldap></kc-tabs-ldap> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + <fieldset> + <legend><span class="text">{{:: 'required-settings' | translate}}</span></legend> + <div class="form-group clearfix" data-ng-show="!create"> + <label class="col-md-2 control-label" for="providerId">{{:: 'provider-id' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="providerId" type="text" ng-model="instance.id" readonly> + </div> + </div> + <div class="form-group clearfix block"> + <label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label> + <div class="col-md-6"> + <input ng-model="instance.config['enabled'][0]" name="enabled" id="enabled" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'user-storage.enabled.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="consoleDisplayName">{{:: 'console-display-name' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="consoleDisplayName" type="text" ng-model="instance.name" placeholder="{{:: 'defaults-to-id' | translate}}"> + </div> + <kc-tooltip>{{:: 'console-display-name.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="priority">{{:: 'priority' | translate}} </label> + <div class="col-md-6"> + <input class="form-control" id="priority" type="text" ng-model="instance.config['priority'][0]"> + </div> + <kc-tooltip>{{:: 'priority.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block"> + <label class="col-md-2 control-label" for="importEnabled">{{:: 'import-enabled' | translate}}</label> + <div class="col-md-6"> + <input ng-model="instance.config['importEnabled'][0]" name="importEnabled" id="importEnabled" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'ldap.import-enabled.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label class="col-md-2 control-label" for="editMode">{{:: 'edit-mode' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="editMode" + ng-model="instance.config['editMode'][0]"> + <option>READ_ONLY</option> + <option>WRITABLE</option> + <option>UNSYNCED</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'ldap.edit-mode.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix block"> + <label class="col-md-2 control-label" for="syncRegistrations">{{:: 'sync-registrations' | translate}}</label> + <div class="col-md-6"> + <input ng-model="instance.config['syncRegistrations'][0]" name="syncRegistrations" id="syncRegistrations" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'ldap.sync-registrations.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="vendor"><span class="required">*</span> {{:: 'vendor' | translate}}</label> + <div class="col-md-6"> + <div data-ng-show="create"> + <select class="form-control" id="vendor" + ng-model="instance.config['vendor'][0]" + ng-options="vendor.id as vendor.name for vendor in ldapVendors" + required> + </select> + </div> + <div data-ng-show="!create"> + <input class="form-control" id="vendor-ro" type="text" ng-model="vendorName" readonly> + </div> + </div> + <kc-tooltip>{{:: 'ldap.vendor.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="usernameLDAPAttribute"><span class="required">*</span> {{:: 'username-ldap-attribute' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="usernameLDAPAttribute" type="text" ng-model="instance.config['usernameLDAPAttribute'][0]" placeholder="{{:: 'ldap-attribute-name-for-username' | translate}}" required> + </div> + <kc-tooltip>{{:: 'username-ldap-attribute.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="rdnLDAPAttribute"><span class="required">*</span> {{:: 'rdn-ldap-attribute' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="rdnLDAPAttribute" type="text" ng-model="instance.config['rdnLDAPAttribute'][0]" placeholder="{{:: 'ldap-attribute-name-for-user-rdn' | translate}}" required> + </div> + <kc-tooltip>{{:: 'rdn-ldap-attribute.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="uuidLDAPAttribute"><span class="required">*</span> {{:: 'uuid-ldap-attribute' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="uuidLDAPAttribute" type="text" ng-model="instance.config['uuidLDAPAttribute'][0]" placeholder="{{:: 'ldap-attribute-name-for-uuid' | translate}}" required> + </div> + <kc-tooltip>{{:: 'uuid-ldap-attribute.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="userObjectClasses"><span class="required">*</span> {{:: 'user-object-classes' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="userObjectClasses" type="text" ng-model="instance.config['userObjectClasses'][0]" placeholder="{{:: 'ldap-user-object-classes.placeholder' | translate}}" required> + </div> + <kc-tooltip>{{:: 'ldap.user-object-classes.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="ldapConnectionUrl"><span class="required">*</span> {{:: 'connection-url' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="ldapConnectionUrl" type="text" ng-model="instance.config['connectionUrl'][0]" placeholder="{{:: 'ldap-connection-url' | translate}}" required> + </div> + <kc-tooltip>{{:: 'ldap.connection-url.tooltip' | translate}}</kc-tooltip> + <div class="col-sm-4" data-ng-show="access.manageRealm"> + <a class="btn btn-primary" data-ng-click="testConnection()">{{:: 'test-connection' | translate}}</a> + </div> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="ldapUsersDn"><span class="required">*</span> {{:: 'users-dn' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="ldapUsersDn" type="text" ng-model="instance.config['usersDn'][0]" placeholder="{{:: 'ldap-users-dn' | translate}}" required> + </div> + <kc-tooltip>{{:: 'ldap.users-dn.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="authType"><span class="required">*</span> {{:: 'authentication-type' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="authType" + ng-model="instance.config['authType'][0]" + ng-options="authType.id as authType.name for authType in authTypes" + required> + </select> + </div> + </div> + <kc-tooltip>{{:: 'ldap.authentication-type.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="startTls">{{:: 'enable-start-tls' | translate}}</label> + <div class="col-md-6"> + <input ng-model="instance.config['startTls'][0]" name="startTls" id="startTls" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'ldap.startTls.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-hide="instance.config['authType'][0] == 'none'"> + <label class="col-md-2 control-label" for="ldapBindDn"><span class="required">*</span> {{:: 'bind-dn' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="ldapBindDn" type="text" ng-model="instance.config['bindDn'][0]" placeholder="{{:: 'ldap-bind-dn' | translate}}" data-ng-required="instance.config['authType'][0] != 'none'"> + </div> + <kc-tooltip>{{:: 'ldap.bind-dn.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-hide="instance.config['authType'][0] == 'none'"> + <label class="col-md-2 control-label" for="ldapBindCred"><span class="required">*</span> {{:: 'bind-credential' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="ldapBindCred" kc-password ng-model="instance.config['bindCredential'][0]" placeholder="{{:: 'ldap-bind-credentials' | translate}}" data-ng-required="instance.config['authType'][0] != 'none'"> + </div> + <kc-tooltip>{{:: 'ldap.bind-credential.tooltip' | translate}}</kc-tooltip> + <div class="col-sm-4" data-ng-show="access.manageRealm"> + <a class="btn btn-primary" data-ng-click="testAuthentication()">{{:: 'test-authentication' | translate}}</a> + </div> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="customUserSearchFilter">{{:: 'custom-user-ldap-filter' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="customUserSearchFilter" type="text" ng-model="instance.config['customUserSearchFilter'][0]" placeholder="{{:: 'ldap-filter' | translate}}"> + </div> + <kc-tooltip>{{:: 'ldap.custom-user-ldap-filter.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="searchScope">{{:: 'search-scope' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="searchScope" + ng-model="instance.config['searchScope'][0]" + ng-options="searchScope.id as searchScope.name for searchScope in searchScopes" + required> + </select> + </div> + </div> + <kc-tooltip>{{:: 'ldap.search-scope.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="validatePasswordPolicy">{{:: 'validate-password-policy' | translate}}</label> + <div class="col-md-6"> + <input ng-model="instance.config['validatePasswordPolicy'][0]" name="validatePasswordPolicy" id="validatePasswordPolicy" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'ldap.validate-password-policy.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="trustEmail">{{:: 'trust-email' | translate}}</label> + <div class="col-md-6"> + <input ng-model="instance.config['trustEmail'][0]" name="trustEmail" id="trustEmail" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'trust-email.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group"> + <label class="col-md-2 control-label" for="useTruststoreSpi">{{:: 'use-truststore-spi' | translate}}</label> + <div class="col-md-6"> + <div> + <select class="form-control" id="useTruststoreSpi" + ng-model="instance.config['useTruststoreSpi'][0]" + ng-options="useTruststoreSpi.id as useTruststoreSpi.name for useTruststoreSpi in useTruststoreOptions" + required> + </select> + </div> + </div> + <kc-tooltip>{{:: 'ldap.use-truststore-spi.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="connectionPooling">{{:: 'connection-pooling' | translate}}</label> + <div class="col-md-6"> + <input ng-model="instance.config['connectionPooling'][0]" name="connectionPooling" id="connectionPooling" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'ldap.connection-pooling.tooltip' | translate}}</kc-tooltip> + <div class="col-sm-4" data-ng-show="instance.config['connectionPooling'][0] == 'true'"> + <a class="btn btn-primary" data-ng-init="connectionPoolSettings=false" data-ng-click="connectionPoolSettings=!connectionPoolSettings">{{:: 'connection-pooling-settings' | translate}}</a> + </div> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['connectionPooling'][0] == 'true' && connectionPoolSettings"> + <label class="col-md-2 control-label" for="connectionPoolingAuthentication">{{:: 'connection-pooling-authentication' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="connectionPoolingAuthentication" type="text" ng-model="instance.config['connectionPoolingAuthentication'][0]" placeholder="{{:: 'connection-pooling-authentication-default' | translate}}"/> + </div> + <kc-tooltip>{{:: 'ldap.connection-pooling.authentication.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['connectionPooling'][0] == 'true' && connectionPoolSettings"> + <label class="col-md-2 control-label" for="connectionPoolingDebug">{{:: 'connection-pooling-debug' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="connectionPoolingDebug" type="text" ng-model="instance.config['connectionPoolingDebug'][0]" placeholder="{{:: 'connection-pooling-debug-default' | translate}}"/> + </div> + <kc-tooltip>{{:: 'ldap.connection-pooling.debug.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['connectionPooling'][0] == 'true' && connectionPoolSettings"> + <label class="col-md-2 control-label" for="connectionPoolingInitSize">{{:: 'connection-pooling-initsize' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="connectionPoolingInitSize" type="text" ng-model="instance.config['connectionPoolingInitSize'][0]" placeholder="{{:: 'connection-pooling-initsize-default' | translate}}"/> + </div> + <kc-tooltip>{{:: 'ldap.connection-pooling.initsize.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['connectionPooling'][0] == 'true' && connectionPoolSettings"> + <label class="col-md-2 control-label" for="connectionPoolingMaxSize">{{:: 'connection-pooling-maxsize' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="connectionPoolingMaxSize" type="text" ng-model="instance.config['connectionPoolingMaxSize'][0]" placeholder="{{:: 'connection-pooling-maxsize-default' | translate}}"/> + </div> + <kc-tooltip>{{:: 'ldap.connection-pooling.maxsize.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['connectionPooling'][0] == 'true' && connectionPoolSettings"> + <label class="col-md-2 control-label" for="connectionPoolingPrefSize">{{:: 'connection-pooling-prefsize' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="connectionPoolingPrefSize" type="text" ng-model="instance.config['connectionPoolingPrefSize'][0]" placeholder="{{:: 'connection-pooling-prefsize-default' | translate}}"/> + </div> + <kc-tooltip>{{:: 'ldap.connection-pooling.prefsize.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['connectionPooling'][0] == 'true' && connectionPoolSettings"> + <label class="col-md-2 control-label" for="connectionPoolingProtocol">{{:: 'connection-pooling-protocol' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="connectionPoolingProtocol" type="text" ng-model="instance.config['connectionPoolingProtocol'][0]" placeholder="{{:: 'connection-pooling-protocol-default' | translate}}"/> + </div> + <kc-tooltip>{{:: 'ldap.connection-pooling.protocol.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['connectionPooling'][0] == 'true' && connectionPoolSettings"> + <label class="col-md-2 control-label" for="connectionPoolingTimeout">{{:: 'connection-pooling-timeout' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="connectionPoolingTimeout" type="text" ng-model="instance.config['connectionPoolingTimeout'][0]" placeholder="{{:: 'connection-pooling-timeout-default' | translate}}"/> + </div> + <kc-tooltip>{{:: 'ldap.connection-pooling.timeout.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="connectionTimeout">{{:: 'ldap-connection-timeout' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="connectionTimeout" type="text" ng-model="instance.config['connectionTimeout'][0]" placeholder="{{:: 'ldap-connection-timeout' | translate}}"> + </div> + <kc-tooltip>{{:: 'ldap.connection-timeout.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="readTimeout">{{:: 'ldap-read-timeout' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="readTimeout" type="text" ng-model="instance.config['readTimeout'][0]" placeholder="{{:: 'ldap-read-timeout' | translate}}"> + </div> + <kc-tooltip>{{:: 'ldap.read-timeout.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="pagination">{{:: 'pagination' | translate}}</label> + <div class="col-md-6"> + <input ng-model="instance.config['pagination'][0]" name="pagination" id="pagination" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'ldap.pagination.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <fieldset> + <legend><span class="text">{{:: 'kerberos-integration' | translate}}</span></legend> + <div class="form-group"> + <label class="col-md-2 control-label" for="allowKerberosAuthentication">{{:: 'allow-kerberos-authentication' | translate}} </label> + <div class="col-md-6"> + <input ng-model="instance.config['allowKerberosAuthentication'][0]" name="allowKerberosAuthentication" id="allowKerberosAuthentication" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'ldap.allow-kerberos-authentication.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['allowKerberosAuthentication'][0] == 'true'"> + <label class="col-md-2 control-label" for="kerberosRealm"><span class="required">*</span> {{:: 'kerberos-realm' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="kerberosRealm" type="text" ng-model="instance.config['kerberosRealm'][0]" ng-required="instance.config['allowKerberosAuthentication'][0] == 'true'"> + </div> + <kc-tooltip>{{:: 'kerberos-realm.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['allowKerberosAuthentication'][0] == 'true'"> + <label class="col-md-2 control-label" for="serverPrincipal"><span class="required">*</span> {{:: 'server-principal' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="serverPrincipal" type="text" ng-model="instance.config['serverPrincipal'][0]" ng-required="instance.config['allowKerberosAuthentication'][0] == 'true'"> + </div> + <kc-tooltip>{{:: 'server-principal.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['allowKerberosAuthentication'][0] == 'true'"> + <label class="col-md-2 control-label" for="keyTab"><span class="required">*</span> {{:: 'keytab' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" id="keyTab" type="text" ng-model="instance.config['keyTab'][0]" ng-required="instance.config['allowKerberosAuthentication'][0] == 'true'"> + </div> + <kc-tooltip>{{:: 'keytab.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="instance.config['allowKerberosAuthentication'][0] == 'true'"> + <label class="col-md-2 control-label" for="debug">{{:: 'debug' | translate}} </label> + <div class="col-md-6"> + <input ng-model="instance.config['debug'][0]" name="debug" id="debug" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'debug.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="instance.config['allowKerberosAuthentication'][0]"> + <label class="col-md-2 control-label" for="useKerberosForPasswordAuthentication">{{:: 'use-kerberos-for-password-authentication' | translate}} </label> + <div class="col-md-6"> + <input ng-model="instance.config['useKerberosForPasswordAuthentication'][0]" id="useKerberosForPasswordAuthentication" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'ldap.use-kerberos-for-password-authentication.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <fieldset> + <legend><span class="text">{{:: 'sync-settings' | translate}}</span></legend> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="batchSizeForSync">{{:: 'batch-size' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" ng-model="instance.config['batchSizeForSync'][0]" id="batchSizeForSync" /> + </div> + <kc-tooltip>{{:: 'ldap.batch-size.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="fullSyncEnabled">{{:: 'periodic-full-sync' | translate}}</label> + <div class="col-md-6"> + <input ng-model="fullSyncEnabled" name="fullSyncEnabled" id="fullSyncEnabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'ldap.periodic-full-sync.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="fullSyncEnabled"> + <label class="col-md-2 control-label" for="fullSyncPeriod">{{:: 'full-sync-period' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" ng-model="instance.config['fullSyncPeriod'][0]" id="fullSyncPeriod" /> + </div> + <kc-tooltip>{{:: 'full-sync-period.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix"> + <label class="col-md-2 control-label" for="changedSyncEnabled">{{:: 'periodic-changed-users-sync' | translate}}</label> + <div class="col-md-6"> + <input ng-model="changedSyncEnabled" name="changedSyncEnabled" id="changedSyncEnabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> + </div> + <kc-tooltip>{{:: 'ldap.periodic-changed-users-sync.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="changedSyncEnabled"> + <label class="col-md-2 control-label" for="changedSyncPeriod">{{:: 'changed-users-sync-period' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" ng-model="instance.config['changedSyncPeriod'][0]" id="changedSyncPeriod" /> + </div> + <kc-tooltip>{{:: 'ldap.changed-users-sync-period.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + <fieldset> + <legend><span class="text">{{:: 'user-storage-cache-policy' | translate}}</span></legend> + <div class="form-group"> + <label for="cachePolicy" class="col-md-2 control-label">{{:: 'userStorage.cachePolicy' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="cachePolicy" ng-model="instance.config['cachePolicy'][0]" class="form-control"> + <option value="DEFAULT">{{:: 'userStorage.cachePolicy.option.DEFAULT' | translate}}</option> + <option value="EVICT_DAILY">{{:: 'userStorage.cachePolicy.option.EVICT_DAILY' | translate}}</option> + <option value="EVICT_WEEKLY">{{:: 'userStorage.cachePolicy.option.EVICT_WEEKLY' | translate}}</option> + <option value="MAX_LIFESPAN">{{:: 'userStorage.cachePolicy.option.MAX_LIFESPAN' | translate}}</option> + <option value="NO_CACHE">{{:: 'userStorage.cachePolicy.option.NO_CACHE' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'userStorage.cachePolicy.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group" data-ng-show="instance.config['cachePolicy'][0] == 'EVICT_WEEKLY'"> + <label for="evictionDay" class="col-md-2 control-label">{{:: 'userStorage.cachePolicy.evictionDay' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="evictionDay" ng-model="instance.config['evictionDay'][0]" class="form-control"> + <option value="1">{{:: 'Sunday' | translate}}</option> + <option value="2">{{:: 'Monday' | translate}}</option> + <option value="3">{{:: 'Tuesday' | translate}}</option> + <option value="4">{{:: 'Wednesday' | translate}}</option> + <option value="5">{{:: 'Thursday' | translate}}</option> + <option value="6">{{:: 'Friday' | translate}}</option> + <option value="7">{{:: 'Saturday' | translate}}</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'userStorage.cachePolicy.evictionDay.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['cachePolicy'][0] == 'EVICT_WEEKLY' || instance.config['cachePolicy'][0] == 'EVICT_DAILY'"> + <label class="col-md-2 control-label" for="evictionHour">{{:: 'userStorage.cachePolicy.evictionHour' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="evictionHour" ng-model="instance.config['evictionHour'][0]" class="form-control"> + <option value="0">00</option> + <option value="1">01</option> + <option value="2">02</option> + <option value="3">03</option> + <option value="4">04</option> + <option value="5">05</option> + <option value="6">06</option> + <option value="7">07</option> + <option value="8">08</option> + <option value="9">09</option> + <option value="10">10</option> + <option value="11">11</option> + <option value="12">12</option> + <option value="13">13</option> + <option value="14">14</option> + <option value="15">15</option> + <option value="16">16</option> + <option value="17">17</option> + <option value="18">18</option> + <option value="19">19</option> + <option value="20">20</option> + <option value="21">21</option> + <option value="22">22</option> + <option value="23">23</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'userStorage.cachePolicy.evictionHour.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['cachePolicy'][0] == 'EVICT_WEEKLY' || instance.config['cachePolicy'][0] == 'EVICT_DAILY'"> + <label class="col-md-2 control-label" for="evictionMinute">{{:: 'userStorage.cachePolicy.evictionMinute' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="evictionMinute" ng-model="instance.config['evictionMinute'][0]" class="form-control"> + <option value="0">00</option> + <option value="1">01</option> + <option value="2">02</option> + <option value="3">03</option> + <option value="4">04</option> + <option value="5">05</option> + <option value="6">06</option> + <option value="7">07</option> + <option value="8">08</option> + <option value="9">09</option> + <option value="10">10</option> + <option value="11">11</option> + <option value="12">12</option> + <option value="13">13</option> + <option value="14">14</option> + <option value="15">15</option> + <option value="16">16</option> + <option value="17">17</option> + <option value="18">18</option> + <option value="19">19</option> + <option value="20">20</option> + <option value="21">21</option> + <option value="22">22</option> + <option value="23">23</option> + <option value="24">24</option> + <option value="25">25</option> + <option value="26">26</option> + <option value="27">27</option> + <option value="28">28</option> + <option value="29">29</option> + <option value="30">30</option> + <option value="31">31</option> + <option value="32">32</option> + <option value="33">33</option> + <option value="34">34</option> + <option value="35">35</option> + <option value="36">36</option> + <option value="37">37</option> + <option value="38">38</option> + <option value="39">39</option> + <option value="40">40</option> + <option value="41">41</option> + <option value="42">42</option> + <option value="43">43</option> + <option value="44">44</option> + <option value="45">45</option> + <option value="46">46</option> + <option value="47">47</option> + <option value="48">48</option> + <option value="49">49</option> + <option value="50">50</option> + <option value="51">51</option> + <option value="52">52</option> + <option value="53">53</option> + <option value="54">54</option> + <option value="55">55</option> + <option value="56">56</option> + <option value="57">57</option> + <option value="58">58</option> + <option value="59">59</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'userStorage.cachePolicy.evictionMinute.tooltip' | translate}}</kc-tooltip> + </div> + <div class="form-group clearfix" data-ng-show="instance.config['cachePolicy'][0] == 'MAX_LIFESPAN'"> + <label class="col-md-2 control-label" for="maxLifespan">{{:: 'userStorage.cachePolicy.maxLifespan' | translate}}</label> + <div class="col-md-6"> + <input class="form-control" type="text" ng-model="instance.config['maxLifespan'][0]" id="maxLifespan" /> + </div> + <kc-tooltip>{{:: 'userStorage.cachePolicy.maxLifespan.tooltip' | translate}}</kc-tooltip> + </div> + </fieldset> + + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="create && access.manageRealm"> + <button kc-save>{{:: 'save' | translate}}</button> + <button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button> + </div> + </div> + + <div class="form-group"> + <div class="col-md-10 col-md-offset-2" data-ng-show="!create && access.manageRealm"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + <button class="btn btn-primary" data-ng-click="triggerChangedUsersSync()" data-ng-hide="changed">{{:: 'synchronize-changed-users' | translate}}</button> + <button class="btn btn-primary" data-ng-click="triggerFullSync()" data-ng-hide="changed">{{:: 'synchronize-all-users' | translate}}</button> + <button class="btn btn-primary" data-ng-click="removeImportedUsers()" data-ng-hide="changed">{{:: 'remove-imported-users' | translate}}</button> + <button class="btn btn-primary" data-ng-click="unlinkUsers()" data-ng-hide="changed">{{:: 'unlink-users' | translate}}</button> + </div> + </div> + </form> +</div> + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/user-storage.html b/admin/resources/partials/user-storage.html new file mode 100644 index 0000000..93ca5a9 --- /dev/null +++ b/admin/resources/partials/user-storage.html @@ -0,0 +1,45 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1> + <span>{{:: 'user-storage' | translate}}</span> + </h1> + + <table class="table table-striped table-bordered"> + <thead> + <tr ng-show="providers.length > 0 && access.manageRealm"> + <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>{{:: 'enabled' | translate}}</th> + <th>{{:: 'priority' | translate}}</th> + <th colspan="2">{{:: 'actions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="instance in instances"> + <td><a href="#/realms/{{realm.realm}}/user-storage/providers/{{instance.providerId}}/{{instance.id}}">{{instance.name}}</a></td> + <td>{{instance.providerId|capitalize}}</td> + <td>{{instance.config['enabled'][0]}}</td> + <td>{{instance.config['priority'][0]}}</td> + <td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/user-storage/providers/{{instance.providerId}}/{{instance.id}}">{{:: 'edit' | translate}}</td> + <td class="kc-action-cell" data-ng-click="removeUserStorage(instance)">{{:: 'delete' | translate}}</td> + </tr> + <tr data-ng-show="!instances || instances.length == 0"> + <td class="text-muted">{{:: 'no-user-storage-providers-configured' | translate}}</td> + </tr> + </tbody> + </table> +</div> + +<kc-menu></kc-menu>
\ No newline at end of file diff --git a/admin/resources/partials/webauthn-policy-passwordless.html b/admin/resources/partials/webauthn-policy-passwordless.html new file mode 100644 index 0000000..dbb1e0e --- /dev/null +++ b/admin/resources/partials/webauthn-policy-passwordless.html @@ -0,0 +1,177 @@ +<!-- + ~ Copyright 2019 Red Hat, Inc. and/or its affiliates + ~ and other contributors as indicated by the @author tags. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + --> + +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1>{{:: 'authentication' | translate}}</h1> + + <span data-ng-init="redirectIfWebAuthnDisabled()"></span> + <kc-tabs-authentication></kc-tabs-authentication> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + + <div class="form-group"> + <label for="name" class="col-md-2 control-label"><span class="required">*</span> {{:: 'webauthn-rp-entity-name' | translate}}</label> + <div class="col-md-2"> + <div> + <input id="name" type="text" ng-model="realm.webAuthnPolicyPasswordlessRpEntityName" class="form-control"> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-rp-entity-name.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="sigalg" class="col-md-2 control-label">{{:: 'webauthn-signature-algorithms' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="sigalg" ng-model="realm.webAuthnPolicyPasswordlessSignatureAlgorithms" class="form-control" multiple> + <option value="ES256">ES256</option> + <option value="ES384">ES384</option> + <option value="ES512">ES512</option> + <option value="RS256">RS256</option> + <option value="RS384">RS384</option> + <option value="RS512">RS512</option> + <option value="RS1">RS1</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-signature-algorithms.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="rpid" class="col-md-2 control-label">{{:: 'webauthn-rp-id' | translate}}</label> + <div class="col-md-2"> + <div> + <input id="rpid" type="text" ng-model="realm.webAuthnPolicyPasswordlessRpId" class="form-control"> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-rp-id.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="attpref" class="col-md-2 control-label">{{:: 'webauthn-attestation-conveyance-preference' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="attpref" ng-model="realm.webAuthnPolicyPasswordlessAttestationConveyancePreference" class="form-control"> + <option value="not specified"></option> + <option value="none">none</option> + <option value="indirect">indirect</option> + <option value="direct">direct</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-attestation-conveyance-preference.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="authnatt" class="col-md-2 control-label">{{:: 'webauthn-authenticator-attachment' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="authnatt" ng-model="realm.webAuthnPolicyPasswordlessAuthenticatorAttachment" class="form-control"> + <option value="not specified"></option> + <option value="platform">platform</option> + <option value="cross-platform">cross-platform</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-authenticator-attachment.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="reqresident" class="col-md-2 control-label">{{:: 'webauthn-require-resident-key' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="reqresident" ng-model="realm.webAuthnPolicyPasswordlessRequireResidentKey" class="form-control"> + <option value="not specified"></option> + <option value="Yes">Yes</option> + <option value="No">No</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-require-resident-key.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="usrverify" class="col-md-2 control-label">{{:: 'webauthn-user-verification-requirement' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="usrverify" ng-model="realm.webAuthnPolicyPasswordlessUserVerificationRequirement" class="form-control"> + <option value="not specified"></option> + <option value="required">required</option> + <option value="preferred">preferred</option> + <option value="discouraged">discouraged</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-user-verification-requirement.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="timeout" class="col-md-2 control-label">{{:: 'webauthn-create-timeout' | translate}}</label> + <div class="col-md-2"> + <div> + <input id="timeout" type="number" min="0" max="31536" ng-model="realm.webAuthnPolicyPasswordlessCreateTimeout" class="form-control"/> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-create-timeout.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="avoidsame" class="col-md-2 control-label">{{:: 'webauthn-avoid-same-authenticator-register' | translate}}</label> + <div class="col-md-2"> + <div> + <input id="avoidsame" ng-model="realm.webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-avoid-same-authenticator-register.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="type" class="col-md-2 control-label">{{:: 'webauthn-acceptable-aaguids' | translate}}</label> + <div class="col-sm-4"> + <div class="input-group" ng-repeat="(i, acceptableAaguid) in realm.webAuthnPolicyPasswordlessAcceptableAaguids track by $index"> + <input class="form-control" ng-model="realm.webAuthnPolicyPasswordlessAcceptableAaguids[i]"> + <div class="input-group-btn"> + <button class="btn btn-default" type="button" data-ng-click="deleteAcceptableAaguid($index)"> + <span class="fa fa-minus"></span> + </button> + </div> + </div> + <div class = "input-group"> + <input class="form-control" ng-model="newAcceptableAaguid" id="newAcceptableAaguid"> + <div class="input-group-btn"> + <button class="btn btn-default" type="button" data-ng-click="newAcceptableAaguid.length > 0 && addAcceptableAaguid()"> + <span class="fa fa-plus"></span> + </button> + </div> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-acceptable-aaguids.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group" data-ng-show="access.manageRealm"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> + +</div> + + +<kc-menu></kc-menu> diff --git a/admin/resources/partials/webauthn-policy.html b/admin/resources/partials/webauthn-policy.html new file mode 100644 index 0000000..432eb3d --- /dev/null +++ b/admin/resources/partials/webauthn-policy.html @@ -0,0 +1,159 @@ +<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> + <h1>{{:: 'authentication' | translate}}</h1> + + <span data-ng-init="redirectIfWebAuthnDisabled()"></span> + <kc-tabs-authentication></kc-tabs-authentication> + + <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm"> + + <div class="form-group"> + <label for="name" class="col-md-2 control-label"><span class="required">*</span> {{:: 'webauthn-rp-entity-name' | translate}}</label> + <div class="col-md-2"> + <div> + <input id="name" type="text" ng-model="realm.webAuthnPolicyRpEntityName" class="form-control"> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-rp-entity-name.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="sigalg" class="col-md-2 control-label">{{:: 'webauthn-signature-algorithms' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="sigalg" ng-model="realm.webAuthnPolicySignatureAlgorithms" class="form-control" multiple> + <option value="ES256">ES256</option> + <option value="ES384">ES384</option> + <option value="ES512">ES512</option> + <option value="RS256">RS256</option> + <option value="RS384">RS384</option> + <option value="RS512">RS512</option> + <option value="RS1">RS1</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-signature-algorithms.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="rpid" class="col-md-2 control-label">{{:: 'webauthn-rp-id' | translate}}</label> + <div class="col-md-2"> + <div> + <input id="rpid" type="text" ng-model="realm.webAuthnPolicyRpId" class="form-control"> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-rp-id.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="attpref" class="col-md-2 control-label">{{:: 'webauthn-attestation-conveyance-preference' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="attpref" ng-model="realm.webAuthnPolicyAttestationConveyancePreference" class="form-control"> + <option value="not specified"></option> + <option value="none">none</option> + <option value="indirect">indirect</option> + <option value="direct">direct</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-attestation-conveyance-preference.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="authnatt" class="col-md-2 control-label">{{:: 'webauthn-authenticator-attachment' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="authnatt" ng-model="realm.webAuthnPolicyAuthenticatorAttachment" class="form-control"> + <option value="not specified"></option> + <option value="platform">platform</option> + <option value="cross-platform">cross-platform</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-authenticator-attachment.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="reqresident" class="col-md-2 control-label">{{:: 'webauthn-require-resident-key' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="reqresident" ng-model="realm.webAuthnPolicyRequireResidentKey" class="form-control"> + <option value="not specified"></option> + <option value="Yes">Yes</option> + <option value="No">No</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-require-resident-key.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="usrverify" class="col-md-2 control-label">{{:: 'webauthn-user-verification-requirement' | translate}}</label> + <div class="col-md-2"> + <div> + <select id="usrverify" ng-model="realm.webAuthnPolicyUserVerificationRequirement" class="form-control"> + <option value="not specified"></option> + <option value="required">required</option> + <option value="preferred">preferred</option> + <option value="discouraged">discouraged</option> + </select> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-user-verification-requirement.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="timeout" class="col-md-2 control-label">{{:: 'webauthn-create-timeout' | translate}}</label> + <div class="col-md-2"> + <div> + <input id="timeout" type="number" min="0" max="31536" ng-model="realm.webAuthnPolicyCreateTimeout" class="form-control"/> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-create-timeout.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="avoidsame" class="col-md-2 control-label">{{:: 'webauthn-avoid-same-authenticator-register' | translate}}</label> + <div class="col-md-2"> + <div> + <input id="avoidsame" ng-model="realm.webAuthnPolicyAvoidSameAuthenticatorRegister" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-avoid-same-authenticator-register.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group"> + <label for="type" class="col-md-2 control-label">{{:: 'webauthn-acceptable-aaguids' | translate}}</label> + <div class="col-sm-4"> + <div class="input-group" ng-repeat="(i, acceptableAaguid) in realm.webAuthnPolicyAcceptableAaguids track by $index"> + <input id="type" class="form-control" ng-model="realm.webAuthnPolicyAcceptableAaguids[i]"> + <div class="input-group-btn"> + <button class="btn btn-default" type="button" data-ng-click="deleteAcceptableAaguid($index)"> + <span class="fa fa-minus"></span> + </button> + </div> + </div> + <div class = "input-group"> + <input class="form-control" ng-model="newAcceptableAaguid" id="newAcceptableAaguid"> + <div class="input-group-btn"> + <button class="btn btn-default" type="button" data-ng-click="newAcceptableAaguid.length > 0 && addAcceptableAaguid()"> + <span class="fa fa-plus"></span> + </button> + </div> + </div> + </div> + <kc-tooltip>{{:: 'webauthn-acceptable-aaguids.tooltip' | translate}}</kc-tooltip> + </div> + + <div class="form-group" data-ng-show="access.manageRealm"> + <div class="col-md-10 col-md-offset-2"> + <button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> + <button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> + </div> + </div> + </form> + +</div> + + +<kc-menu></kc-menu> |