Actually, take all the themes
This commit is contained in:
parent
48076ab3d9
commit
a95dc5d92e
70
base/account/account.ftl
Executable file
70
base/account/account.ftl
Executable file
@ -0,0 +1,70 @@
|
|||||||
|
<#import "template.ftl" as layout>
|
||||||
|
<@layout.mainLayout active='account' bodyClass='user'; section>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h2>${msg("editAccountHtmlTitle")}</h2>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 subtitle">
|
||||||
|
<span class="subtitle"><span class="required">*</span> ${msg("requiredFields")}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form action="${url.accountUrl}" class="form-horizontal" method="post">
|
||||||
|
|
||||||
|
<input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker}">
|
||||||
|
|
||||||
|
<#if !realm.registrationEmailAsUsername>
|
||||||
|
<div class="form-group ${messagesPerField.printIfExists('username','has-error')}">
|
||||||
|
<div class="col-sm-2 col-md-2">
|
||||||
|
<label for="username" class="control-label">${msg("username")}</label> <#if realm.editUsernameAllowed><span class="required">*</span></#if>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-10 col-md-10">
|
||||||
|
<input type="text" class="form-control" id="username" name="username" <#if !realm.editUsernameAllowed>disabled="disabled"</#if> value="${(account.username!'')}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<div class="form-group ${messagesPerField.printIfExists('email','has-error')}">
|
||||||
|
<div class="col-sm-2 col-md-2">
|
||||||
|
<label for="email" class="control-label">${msg("email")}</label> <span class="required">*</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-10 col-md-10">
|
||||||
|
<input type="text" class="form-control" id="email" name="email" autofocus value="${(account.email!'')}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group ${messagesPerField.printIfExists('firstName','has-error')}">
|
||||||
|
<div class="col-sm-2 col-md-2">
|
||||||
|
<label for="firstName" class="control-label">${msg("firstName")}</label> <span class="required">*</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-10 col-md-10">
|
||||||
|
<input type="text" class="form-control" id="firstName" name="firstName" value="${(account.firstName!'')}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group ${messagesPerField.printIfExists('lastName','has-error')}">
|
||||||
|
<div class="col-sm-2 col-md-2">
|
||||||
|
<label for="lastName" class="control-label">${msg("lastName")}</label> <span class="required">*</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-10 col-md-10">
|
||||||
|
<input type="text" class="form-control" id="lastName" name="lastName" value="${(account.lastName!'')}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div id="kc-form-buttons" class="col-md-offset-2 col-md-10 submit">
|
||||||
|
<div class="">
|
||||||
|
<#if url.referrerURI??><a href="${url.referrerURI}">${kcSanitize(msg("backToApplication")?no_esc)}</a></#if>
|
||||||
|
<button type="submit" class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" name="submitAction" value="Save">${msg("doSave")}</button>
|
||||||
|
<button type="submit" class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!}" name="submitAction" value="Cancel">${msg("doCancel")}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</@layout.mainLayout>
|
76
base/account/applications.ftl
Executable file
76
base/account/applications.ftl
Executable file
@ -0,0 +1,76 @@
|
|||||||
|
<#import "template.ftl" as layout>
|
||||||
|
<@layout.mainLayout active='applications' bodyClass='applications'; section>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h2>${msg("applicationsHtmlTitle")}</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form action="${url.applicationsUrl}" method="post">
|
||||||
|
<input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker}">
|
||||||
|
<input type="hidden" id="referrer" name="referrer" value="${stateChecker}">
|
||||||
|
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>${msg("application")}</td>
|
||||||
|
<td>${msg("availableRoles")}</td>
|
||||||
|
<td>${msg("grantedPermissions")}</td>
|
||||||
|
<td>${msg("additionalGrants")}</td>
|
||||||
|
<td>${msg("action")}</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<#list applications.applications as application>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<#if application.effectiveUrl?has_content><a href="${application.effectiveUrl}"></#if>
|
||||||
|
<#if application.client.name?has_content>${advancedMsg(application.client.name)}<#else>${application.client.clientId}</#if>
|
||||||
|
<#if application.effectiveUrl?has_content></a></#if>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<#list application.realmRolesAvailable as role>
|
||||||
|
<#if role.description??>${advancedMsg(role.description)}<#else>${advancedMsg(role.name)}</#if>
|
||||||
|
<#if role_has_next>, </#if>
|
||||||
|
</#list>
|
||||||
|
<#list application.resourceRolesAvailable?keys as resource>
|
||||||
|
<#if application.realmRolesAvailable?has_content>, </#if>
|
||||||
|
<#list application.resourceRolesAvailable[resource] as clientRole>
|
||||||
|
<#if clientRole.roleDescription??>${advancedMsg(clientRole.roleDescription)}<#else>${advancedMsg(clientRole.roleName)}</#if>
|
||||||
|
${msg("inResource")} <strong><#if clientRole.clientName??>${advancedMsg(clientRole.clientName)}<#else>${clientRole.clientId}</#if></strong>
|
||||||
|
<#if clientRole_has_next>, </#if>
|
||||||
|
</#list>
|
||||||
|
</#list>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<#if application.client.consentRequired>
|
||||||
|
<#list application.clientScopesGranted as claim>
|
||||||
|
${advancedMsg(claim)}<#if claim_has_next>, </#if>
|
||||||
|
</#list>
|
||||||
|
<#else>
|
||||||
|
<strong>${msg("fullAccess")}</strong>
|
||||||
|
</#if>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<#list application.additionalGrants as grant>
|
||||||
|
${advancedMsg(grant)}<#if grant_has_next>, </#if>
|
||||||
|
</#list>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<#if (application.client.consentRequired && application.clientScopesGranted?has_content) || application.additionalGrants?has_content>
|
||||||
|
<button type='submit' class='${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!}' id='revoke-${application.client.clientId}' name='clientId' value="${application.client.id}">${msg("revoke")}</button>
|
||||||
|
</#if>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</#list>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</@layout.mainLayout>
|
42
base/account/federatedIdentity.ftl
Executable file
42
base/account/federatedIdentity.ftl
Executable file
@ -0,0 +1,42 @@
|
|||||||
|
<#import "template.ftl" as layout>
|
||||||
|
<@layout.mainLayout active='social' bodyClass='social'; section>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h2>${msg("federatedIdentitiesHtmlTitle")}</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="federated-identities">
|
||||||
|
<#list federatedIdentity.identities as identity>
|
||||||
|
<div class="row margin-bottom">
|
||||||
|
<div class="col-sm-2 col-md-2">
|
||||||
|
<label for="${identity.providerId!}" class="control-label">${identity.displayName!}</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-5 col-md-5">
|
||||||
|
<input disabled="true" class="form-control" value="${identity.userName!}">
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-5 col-md-5">
|
||||||
|
<#if identity.connected>
|
||||||
|
<#if federatedIdentity.removeLinkPossible>
|
||||||
|
<form action="${url.socialUrl}" method="post" class="form-inline">
|
||||||
|
<input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker}">
|
||||||
|
<input type="hidden" id="action" name="action" value="remove">
|
||||||
|
<input type="hidden" id="providerId" name="providerId" value="${identity.providerId!}">
|
||||||
|
<button id="remove-link-${identity.providerId!}" class="btn btn-default">${msg("doRemove")}</button>
|
||||||
|
</form>
|
||||||
|
</#if>
|
||||||
|
<#else>
|
||||||
|
<form action="${url.socialUrl}" method="post" class="form-inline">
|
||||||
|
<input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker}">
|
||||||
|
<input type="hidden" id="action" name="action" value="add">
|
||||||
|
<input type="hidden" id="providerId" name="providerId" value="${identity.providerId!}">
|
||||||
|
<button id="add-link-${identity.providerId!}" class="btn btn-default">${msg("doAdd")}</button>
|
||||||
|
</form>
|
||||||
|
</#if>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</#list>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</@layout.mainLayout>
|
35
base/account/log.ftl
Normal file
35
base/account/log.ftl
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<#import "template.ftl" as layout>
|
||||||
|
<@layout.mainLayout active='log' bodyClass='log'; section>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h2>${msg("accountLogHtmlTitle")}</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>${msg("date")}</td>
|
||||||
|
<td>${msg("event")}</td>
|
||||||
|
<td>${msg("ip")}</td>
|
||||||
|
<td>${msg("client")}</td>
|
||||||
|
<td>${msg("details")}</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<#list log.events as event>
|
||||||
|
<tr>
|
||||||
|
<td>${event.date?datetime}</td>
|
||||||
|
<td>${event.event}</td>
|
||||||
|
<td>${event.ipAddress}</td>
|
||||||
|
<td>${event.client!}</td>
|
||||||
|
<td><#list event.details as detail>${detail.key} = ${detail.value} <#if detail_has_next>, </#if></#list></td>
|
||||||
|
</tr>
|
||||||
|
</#list>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</@layout.mainLayout>
|
376
base/account/messages/messages_en.properties
Executable file
376
base/account/messages/messages_en.properties
Executable file
@ -0,0 +1,376 @@
|
|||||||
|
doSave=Save
|
||||||
|
doCancel=Cancel
|
||||||
|
doLogOutAllSessions=Log out all sessions
|
||||||
|
doRemove=Remove
|
||||||
|
doAdd=Add
|
||||||
|
doSignOut=Sign Out
|
||||||
|
doLogIn=Log In
|
||||||
|
doLink=Link
|
||||||
|
noAccessMessage=Access not allowed
|
||||||
|
|
||||||
|
|
||||||
|
editAccountHtmlTitle=Edit Account
|
||||||
|
personalInfoHtmlTitle=Personal Info
|
||||||
|
federatedIdentitiesHtmlTitle=Federated Identities
|
||||||
|
accountLogHtmlTitle=Account Log
|
||||||
|
changePasswordHtmlTitle=Change Password
|
||||||
|
deviceActivityHtmlTitle=Device Activity
|
||||||
|
sessionsHtmlTitle=Sessions
|
||||||
|
accountManagementTitle=Keycloak Account Management
|
||||||
|
authenticatorTitle=Authenticator
|
||||||
|
applicationsHtmlTitle=Applications
|
||||||
|
linkedAccountsHtmlTitle=Linked Accounts
|
||||||
|
|
||||||
|
accountManagementWelcomeMessage=Welcome to Keycloak Account Management
|
||||||
|
personalInfoIntroMessage=Manage your basic information
|
||||||
|
accountSecurityTitle=Account Security
|
||||||
|
accountSecurityIntroMessage=Control your password and account access
|
||||||
|
applicationsIntroMessage=Track and manage your app permission to access your account
|
||||||
|
resourceIntroMessage=Share your resources among team members
|
||||||
|
passwordLastUpdateMessage=Your password was updated at
|
||||||
|
updatePasswordTitle=Update Password
|
||||||
|
updatePasswordMessageTitle=Make sure you choose a strong password
|
||||||
|
updatePasswordMessage=A strong password contains a mix of numbers, letters, and symbols. It is hard to guess, does not resemble a real word, and is only used for this account.
|
||||||
|
personalSubTitle=Your Personal Info
|
||||||
|
personalSubMessage=Manage this basic information: your first name, last name and email
|
||||||
|
|
||||||
|
authenticatorCode=One-time code
|
||||||
|
email=Email
|
||||||
|
firstName=First name
|
||||||
|
givenName=Given name
|
||||||
|
fullName=Full name
|
||||||
|
lastName=Last name
|
||||||
|
familyName=Family name
|
||||||
|
password=Password
|
||||||
|
currentPassword=Current Password
|
||||||
|
passwordConfirm=Confirmation
|
||||||
|
passwordNew=New Password
|
||||||
|
username=Username
|
||||||
|
address=Address
|
||||||
|
street=Street
|
||||||
|
locality=City or Locality
|
||||||
|
region=State, Province, or Region
|
||||||
|
postal_code=Zip or Postal code
|
||||||
|
country=Country
|
||||||
|
emailVerified=Email verified
|
||||||
|
website=Web page
|
||||||
|
phoneNumber=Phone number
|
||||||
|
phoneNumberVerified=Phone number verified
|
||||||
|
gender=Gender
|
||||||
|
birthday=Birthdate
|
||||||
|
zoneinfo=Time zone
|
||||||
|
gssDelegationCredential=GSS Delegation Credential
|
||||||
|
|
||||||
|
profileScopeConsentText=User profile
|
||||||
|
emailScopeConsentText=Email address
|
||||||
|
addressScopeConsentText=Address
|
||||||
|
phoneScopeConsentText=Phone number
|
||||||
|
offlineAccessScopeConsentText=Offline Access
|
||||||
|
samlRoleListScopeConsentText=My Roles
|
||||||
|
rolesScopeConsentText=User roles
|
||||||
|
|
||||||
|
role_admin=Admin
|
||||||
|
role_realm-admin=Realm Admin
|
||||||
|
role_create-realm=Create realm
|
||||||
|
role_view-realm=View realm
|
||||||
|
role_view-users=View users
|
||||||
|
role_view-applications=View applications
|
||||||
|
role_view-clients=View clients
|
||||||
|
role_view-events=View events
|
||||||
|
role_view-identity-providers=View identity providers
|
||||||
|
role_view-consent=View consents
|
||||||
|
role_manage-realm=Manage realm
|
||||||
|
role_manage-users=Manage users
|
||||||
|
role_manage-applications=Manage applications
|
||||||
|
role_manage-identity-providers=Manage identity providers
|
||||||
|
role_manage-clients=Manage clients
|
||||||
|
role_manage-events=Manage events
|
||||||
|
role_view-profile=View profile
|
||||||
|
role_manage-account=Manage account
|
||||||
|
role_manage-account-links=Manage account links
|
||||||
|
role_manage-consent=Manage consents
|
||||||
|
role_read-token=Read token
|
||||||
|
role_offline-access=Offline access
|
||||||
|
role_uma_authorization=Obtain permissions
|
||||||
|
client_account=Account
|
||||||
|
client_account-console=Account Console
|
||||||
|
client_security-admin-console=Security Admin Console
|
||||||
|
client_admin-cli=Admin CLI
|
||||||
|
client_realm-management=Realm Management
|
||||||
|
client_broker=Broker
|
||||||
|
|
||||||
|
|
||||||
|
requiredFields=Required fields
|
||||||
|
allFieldsRequired=All fields required
|
||||||
|
|
||||||
|
backToApplication=« Back to application
|
||||||
|
backTo=Back to {0}
|
||||||
|
|
||||||
|
date=Date
|
||||||
|
event=Event
|
||||||
|
ip=IP
|
||||||
|
client=Client
|
||||||
|
clients=Clients
|
||||||
|
details=Details
|
||||||
|
started=Started
|
||||||
|
lastAccess=Last Access
|
||||||
|
expires=Expires
|
||||||
|
applications=Applications
|
||||||
|
|
||||||
|
account=Account
|
||||||
|
federatedIdentity=Federated Identity
|
||||||
|
authenticator=Authenticator
|
||||||
|
device-activity=Device Activity
|
||||||
|
sessions=Sessions
|
||||||
|
log=Log
|
||||||
|
|
||||||
|
application=Application
|
||||||
|
availableRoles=Available Roles
|
||||||
|
grantedPermissions=Granted Permissions
|
||||||
|
grantedPersonalInfo=Granted Personal Info
|
||||||
|
additionalGrants=Additional Grants
|
||||||
|
action=Action
|
||||||
|
inResource=in
|
||||||
|
fullAccess=Full Access
|
||||||
|
offlineToken=Offline Token
|
||||||
|
revoke=Revoke Grant
|
||||||
|
|
||||||
|
configureAuthenticators=Configured Authenticators
|
||||||
|
mobile=Mobile
|
||||||
|
totpStep1=Install one of the following applications on your mobile:
|
||||||
|
totpStep2=Open the application and scan the barcode:
|
||||||
|
totpStep3=Enter the one-time code provided by the application and click Save to finish the setup.
|
||||||
|
totpStep3DeviceName=Provide a Device Name to help you manage your OTP devices.
|
||||||
|
|
||||||
|
totpManualStep2=Open the application and enter the key:
|
||||||
|
totpManualStep3=Use the following configuration values if the application allows setting them:
|
||||||
|
totpUnableToScan=Unable to scan?
|
||||||
|
totpScanBarcode=Scan barcode?
|
||||||
|
|
||||||
|
totp.totp=Time-based
|
||||||
|
totp.hotp=Counter-based
|
||||||
|
|
||||||
|
totpType=Type
|
||||||
|
totpAlgorithm=Algorithm
|
||||||
|
totpDigits=Digits
|
||||||
|
totpInterval=Interval
|
||||||
|
totpCounter=Counter
|
||||||
|
totpDeviceName=Device Name
|
||||||
|
|
||||||
|
irreversibleAction=This action is irreversible
|
||||||
|
deletingImplies=Deleting your account implies:
|
||||||
|
errasingData=Erasing all your data
|
||||||
|
loggingOutImmediately=Logging you out immediately
|
||||||
|
accountUnusable=Any subsequent use of the application will not be possible with this account
|
||||||
|
|
||||||
|
missingUsernameMessage=Please specify username.
|
||||||
|
missingFirstNameMessage=Please specify first name.
|
||||||
|
invalidEmailMessage=Invalid email address.
|
||||||
|
missingLastNameMessage=Please specify last name.
|
||||||
|
missingEmailMessage=Please specify email.
|
||||||
|
missingPasswordMessage=Please specify password.
|
||||||
|
notMatchPasswordMessage=Passwords don''t match.
|
||||||
|
invalidUserMessage=Invalid user
|
||||||
|
updateReadOnlyAttributesRejectedMessage=Update of read-only attribute rejected
|
||||||
|
|
||||||
|
missingTotpMessage=Please specify authenticator code.
|
||||||
|
missingTotpDeviceNameMessage=Please specify device name.
|
||||||
|
invalidPasswordExistingMessage=Invalid existing password.
|
||||||
|
invalidPasswordConfirmMessage=Password confirmation doesn''t match.
|
||||||
|
invalidTotpMessage=Invalid authenticator code.
|
||||||
|
|
||||||
|
usernameExistsMessage=Username already exists.
|
||||||
|
emailExistsMessage=Email already exists.
|
||||||
|
|
||||||
|
readOnlyUserMessage=You can''t update your account as it is read-only.
|
||||||
|
readOnlyUsernameMessage=You can''t update your username as it is read-only.
|
||||||
|
readOnlyPasswordMessage=You can''t update your password as your account is read-only.
|
||||||
|
|
||||||
|
successTotpMessage=Mobile authenticator configured.
|
||||||
|
successTotpRemovedMessage=Mobile authenticator removed.
|
||||||
|
|
||||||
|
successGrantRevokedMessage=Grant revoked successfully.
|
||||||
|
|
||||||
|
accountUpdatedMessage=Your account has been updated.
|
||||||
|
accountPasswordUpdatedMessage=Your password has been updated.
|
||||||
|
|
||||||
|
missingIdentityProviderMessage=Identity provider not specified.
|
||||||
|
invalidFederatedIdentityActionMessage=Invalid or missing action.
|
||||||
|
identityProviderNotFoundMessage=Specified identity provider not found.
|
||||||
|
federatedIdentityLinkNotActiveMessage=This identity is not active anymore.
|
||||||
|
federatedIdentityRemovingLastProviderMessage=You can''t remove last federated identity as you don''t have a password.
|
||||||
|
identityProviderRedirectErrorMessage=Failed to redirect to identity provider.
|
||||||
|
identityProviderRemovedMessage=Identity provider removed successfully.
|
||||||
|
identityProviderAlreadyLinkedMessage=Federated identity returned by {0} is already linked to another user.
|
||||||
|
staleCodeAccountMessage=The page expired. Please try one more time.
|
||||||
|
consentDenied=Consent denied.
|
||||||
|
|
||||||
|
accountDisabledMessage=Account is disabled, contact your administrator.
|
||||||
|
|
||||||
|
accountTemporarilyDisabledMessage=Account is temporarily disabled, contact your administrator or try again later.
|
||||||
|
invalidPasswordMinLengthMessage=Invalid password: minimum length {0}.
|
||||||
|
invalidPasswordMinLowerCaseCharsMessage=Invalid password: must contain at least {0} lower case characters.
|
||||||
|
invalidPasswordMinDigitsMessage=Invalid password: must contain at least {0} numerical digits.
|
||||||
|
invalidPasswordMinUpperCaseCharsMessage=Invalid password: must contain at least {0} upper case characters.
|
||||||
|
invalidPasswordMinSpecialCharsMessage=Invalid password: must contain at least {0} special characters.
|
||||||
|
invalidPasswordNotUsernameMessage=Invalid password: must not be equal to the username.
|
||||||
|
invalidPasswordNotEmailMessage=Invalid password: must not be equal to the email.
|
||||||
|
invalidPasswordRegexPatternMessage=Invalid password: fails to match regex pattern(s).
|
||||||
|
invalidPasswordHistoryMessage=Invalid password: must not be equal to any of last {0} passwords.
|
||||||
|
invalidPasswordBlacklistedMessage=Invalid password: password is blacklisted.
|
||||||
|
invalidPasswordGenericMessage=Invalid password: new password doesn''t match password policies.
|
||||||
|
|
||||||
|
# Authorization
|
||||||
|
myResources=My Resources
|
||||||
|
myResourcesSub=My resources
|
||||||
|
doDeny=Deny
|
||||||
|
doRevoke=Revoke
|
||||||
|
doApprove=Approve
|
||||||
|
doRemoveSharing=Remove Sharing
|
||||||
|
doRemoveRequest=Remove Request
|
||||||
|
peopleAccessResource=People with access to this resource
|
||||||
|
resourceManagedPolicies=Permissions granting access to this resource
|
||||||
|
resourceNoPermissionsGrantingAccess=No permissions granting access to this resource
|
||||||
|
anyAction=Any action
|
||||||
|
description=Description
|
||||||
|
name=Name
|
||||||
|
scopes=Scopes
|
||||||
|
resource=Resource
|
||||||
|
user=User
|
||||||
|
peopleSharingThisResource=People sharing this resource
|
||||||
|
shareWithOthers=Share with others
|
||||||
|
needMyApproval=Need my approval
|
||||||
|
requestsWaitingApproval=Your requests waiting approval
|
||||||
|
icon=Icon
|
||||||
|
requestor=Requestor
|
||||||
|
owner=Owner
|
||||||
|
resourcesSharedWithMe=Resources shared with me
|
||||||
|
permissionRequestion=Permission Requestion
|
||||||
|
permission=Permission
|
||||||
|
shares=share(s)
|
||||||
|
notBeingShared=This resource is not being shared.
|
||||||
|
notHaveAnyResource=You don't have any resources
|
||||||
|
noResourcesSharedWithYou=There are no resources shared with you
|
||||||
|
havePermissionRequestsWaitingForApproval=You have {0} permission request(s) waiting for approval.
|
||||||
|
clickHereForDetails=Click here for details.
|
||||||
|
resourceIsNotBeingShared=The resource is not being shared
|
||||||
|
|
||||||
|
locale_ca=Catal\u00e0
|
||||||
|
locale_cs=\u010Ce\u0161tina
|
||||||
|
locale_de=Deutsch
|
||||||
|
locale_en=English
|
||||||
|
locale_es=Espa\u00f1ol
|
||||||
|
locale_fr=Fran\u00e7ais
|
||||||
|
locale_hu=Magyar
|
||||||
|
locale_it=Italiano
|
||||||
|
locale_ja=\u65e5\u672c\u8a9e
|
||||||
|
locale_lt=Lietuvi\u0173
|
||||||
|
locale_nl=Nederlands
|
||||||
|
locale_no=Norsk
|
||||||
|
locale_pl=Polski
|
||||||
|
locale_pt-BR=Portugu\u00eas (Brasil)
|
||||||
|
locale_ru=\u0420\u0443\u0441\u0441\u043a\u0438\u0439
|
||||||
|
locale_sk=Sloven\u010dina
|
||||||
|
locale_sv=Svenska
|
||||||
|
locale_tr=T\u00FCrk\u00E7e
|
||||||
|
locale_zh-CN=\u4e2d\u6587\u7b80\u4f53
|
||||||
|
|
||||||
|
# Applications
|
||||||
|
applicationName=Name
|
||||||
|
applicationType=Application Type
|
||||||
|
applicationInUse=In-use app only
|
||||||
|
clearAllFilter=Clear all filters
|
||||||
|
activeFilters=Active filters
|
||||||
|
filterByName=Filter By Name ...
|
||||||
|
allApps=All applications
|
||||||
|
internalApps=Internal applications
|
||||||
|
thirdpartyApps=Third-Party applications
|
||||||
|
appResults=Results
|
||||||
|
clientNotFoundMessage=Client not found.
|
||||||
|
|
||||||
|
# Linked account
|
||||||
|
authorizedProvider=Authorized Provider
|
||||||
|
authorizedProviderMessage=Authorized Providers linked with your account
|
||||||
|
identityProvider=Identity Provider
|
||||||
|
identityProviderMessage=To link your account with identity providers you have configured
|
||||||
|
socialLogin=Social Login
|
||||||
|
userDefined=User Defined
|
||||||
|
removeAccess=Remove Access
|
||||||
|
removeAccessMessage=You will need to grant access again, if you want to use this app account.
|
||||||
|
|
||||||
|
#Authenticator
|
||||||
|
authenticatorStatusMessage=Two-factor authentication is currently
|
||||||
|
authenticatorFinishSetUpTitle=Your Two-Factor Authentication
|
||||||
|
authenticatorFinishSetUpMessage=Each time you sign in to your Keycloak account, you will be asked to provide a two-factor authentication code.
|
||||||
|
authenticatorSubTitle=Set Up Two-Factor Authentication
|
||||||
|
authenticatorSubMessage=To enhance the security of your account, enable at least one of the available two-factor authentication methods.
|
||||||
|
authenticatorMobileTitle=Mobile Authenticator
|
||||||
|
authenticatorMobileMessage=Use mobile Authenticator to get Verification codes as the two-factor authentication.
|
||||||
|
authenticatorMobileFinishSetUpMessage=The authenticator has been bound to your phone.
|
||||||
|
authenticatorActionSetup=Set up
|
||||||
|
authenticatorSMSTitle=SMS Code
|
||||||
|
authenticatorSMSMessage=Keycloak will send the Verification code to your phone as the two-factor authentication.
|
||||||
|
authenticatorSMSFinishSetUpMessage=Text messages are sent to
|
||||||
|
authenticatorDefaultStatus=Default
|
||||||
|
authenticatorChangePhone=Change Phone Number
|
||||||
|
authenticatorBackupCodesTitle=Backup Codes
|
||||||
|
authenticatorBackupCodesMessage=Get your 8-digit backup codes
|
||||||
|
authenticatorBackupCodesFinishSetUpMessage=12 backup codes were generated at this time. Each one can be used once.
|
||||||
|
|
||||||
|
#Authenticator - Mobile Authenticator setup
|
||||||
|
authenticatorMobileSetupTitle=Mobile Authenticator Setup
|
||||||
|
smscodeIntroMessage=Enter your phone number and a verification code will be sent to your phone.
|
||||||
|
mobileSetupStep1=Install an authenticator application on your phone. The applications listed here are supported.
|
||||||
|
mobileSetupStep2=Open the application and scan the barcode:
|
||||||
|
mobileSetupStep3=Enter the one-time code provided by the application and click Save to finish the setup.
|
||||||
|
scanBarCode=Want to scan the barcode?
|
||||||
|
enterBarCode=Enter the one-time code
|
||||||
|
doCopy=Copy
|
||||||
|
doFinish=Finish
|
||||||
|
|
||||||
|
#Authenticator - SMS Code setup
|
||||||
|
authenticatorSMSCodeSetupTitle=SMS Code Setup
|
||||||
|
chooseYourCountry=Choose your country
|
||||||
|
enterYourPhoneNumber=Enter your phone number
|
||||||
|
sendVerficationCode=Send Verification Code
|
||||||
|
enterYourVerficationCode=Enter your verification code
|
||||||
|
|
||||||
|
#Authenticator - backup Code setup
|
||||||
|
authenticatorBackupCodesSetupTitle=Backup Codes Setup
|
||||||
|
backupcodesIntroMessage=If you lose access to your phone, you can still log into your account through backup codes. Keep them somewhere safe and accessible.
|
||||||
|
realmName=Realm
|
||||||
|
doDownload=Download
|
||||||
|
doPrint=Print
|
||||||
|
backupCodesTips-1=Each backup code can be used once.
|
||||||
|
backupCodesTips-2=These codes were generated on
|
||||||
|
generateNewBackupCodes=Generate New Backup Codes
|
||||||
|
backupCodesTips-3=When you generate new backup codes, the current codes will not work anymore.
|
||||||
|
backtoAuthenticatorPage=Back to Authenticator Page
|
||||||
|
|
||||||
|
|
||||||
|
#Resources
|
||||||
|
resources=Resources
|
||||||
|
sharedwithMe=Shared with Me
|
||||||
|
share=Share
|
||||||
|
sharedwith=Shared with
|
||||||
|
accessPermissions=Access Permissions
|
||||||
|
permissionRequests=Permission Requests
|
||||||
|
approve=Approve
|
||||||
|
approveAll=Approve all
|
||||||
|
people=people
|
||||||
|
perPage=per page
|
||||||
|
currentPage=Current Page
|
||||||
|
sharetheResource=Share the resource
|
||||||
|
group=Group
|
||||||
|
selectPermission=Select Permission
|
||||||
|
addPeople=Add people to share your resource with
|
||||||
|
addTeam=Add team to share your resource with
|
||||||
|
myPermissions=My Permissions
|
||||||
|
waitingforApproval=Waiting for approval
|
||||||
|
anyPermission=Any Permission
|
||||||
|
|
||||||
|
# Openshift messages
|
||||||
|
openshift.scope.user_info=User information
|
||||||
|
openshift.scope.user_check-access=User access information
|
||||||
|
openshift.scope.user_full=Full Access
|
||||||
|
openshift.scope.list-projects=List projects
|
59
base/account/password.ftl
Executable file
59
base/account/password.ftl
Executable file
@ -0,0 +1,59 @@
|
|||||||
|
<#import "template.ftl" as layout>
|
||||||
|
<@layout.mainLayout active='password' bodyClass='password'; section>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h2>${msg("changePasswordHtmlTitle")}</h2>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 subtitle">
|
||||||
|
<span class="subtitle">${msg("allFieldsRequired")}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form action="${url.passwordUrl}" class="form-horizontal" method="post">
|
||||||
|
<input type="text" id="username" name="username" value="${(account.username!'')}" autocomplete="username" readonly="readonly" style="display:none;">
|
||||||
|
|
||||||
|
<#if password.passwordSet>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-2 col-md-2">
|
||||||
|
<label for="password" class="control-label">${msg("password")}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-10 col-md-10">
|
||||||
|
<input type="password" class="form-control" id="password" name="password" autofocus autocomplete="current-password">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker}">
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-2 col-md-2">
|
||||||
|
<label for="password-new" class="control-label">${msg("passwordNew")}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-10 col-md-10">
|
||||||
|
<input type="password" class="form-control" id="password-new" name="password-new" autocomplete="new-password">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-2 col-md-2">
|
||||||
|
<label for="password-confirm" class="control-label" class="two-lines">${msg("passwordConfirm")}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-10 col-md-10">
|
||||||
|
<input type="password" class="form-control" id="password-confirm" name="password-confirm" autocomplete="new-password">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div id="kc-form-buttons" class="col-md-offset-2 col-md-10 submit">
|
||||||
|
<div class="">
|
||||||
|
<button type="submit" class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" name="submitAction" value="Save">${msg("doSave")}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</@layout.mainLayout>
|
277
base/account/resource-detail.ftl
Executable file
277
base/account/resource-detail.ftl
Executable file
@ -0,0 +1,277 @@
|
|||||||
|
<#import "template.ftl" as layout>
|
||||||
|
<@layout.mainLayout active='authorization' bodyClass='authorization'; section>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.search-box,.close-icon,.search-wrapper {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.search-wrapper {
|
||||||
|
width: 500px;
|
||||||
|
margin: auto;
|
||||||
|
margin-top: 50px;
|
||||||
|
}
|
||||||
|
.search-box {
|
||||||
|
font-weight: 600;
|
||||||
|
color: white;
|
||||||
|
border: 1px solid #006e9c;
|
||||||
|
outline: 0;
|
||||||
|
border-radius: 15px;
|
||||||
|
background-color: #0085cf;
|
||||||
|
padding: 2px 5px;
|
||||||
|
|
||||||
|
}
|
||||||
|
.search-box:focus {
|
||||||
|
box-shadow: 0 0 15px 5px #b0e0ee;
|
||||||
|
border: 2px solid #bebede;
|
||||||
|
}
|
||||||
|
.close-icon {
|
||||||
|
border:1px solid transparent;
|
||||||
|
background-color: transparent;
|
||||||
|
display: inline-block;
|
||||||
|
float: right;
|
||||||
|
outline: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.close-icon:after {
|
||||||
|
display: block;
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
background-color: #FA9595;
|
||||||
|
z-index:1;
|
||||||
|
right: 35px;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
margin: auto;
|
||||||
|
padding: 2px;
|
||||||
|
border-radius: 50%;
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 12px;
|
||||||
|
box-shadow: 0 0 2px #E50F0F;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.search-box:not(:valid) ~ .close-icon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
function removeScopeElm(elm) {
|
||||||
|
elm.parentNode.removeChild(elm);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeAllScopes(id) {
|
||||||
|
var scopesElm = document.getElementsByName('removeScope-' + id);
|
||||||
|
|
||||||
|
for (i = 0; i < scopesElm.length; i++) {
|
||||||
|
var td = scopesElm[i].parentNode.parentNode;
|
||||||
|
var tr = td.parentNode;
|
||||||
|
var tbody = tr.parentNode;
|
||||||
|
tbody.removeChild(tr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getChildren(parent, childId) {
|
||||||
|
var childNodes = [];
|
||||||
|
|
||||||
|
for (i = 0; i < parent.childNodes.length; i++) {
|
||||||
|
if (parent.childNodes[i].id == childId) {
|
||||||
|
childNodes.push(parent.childNodes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return childNodes;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h2>
|
||||||
|
<a href="${url.resourceUrl}">${msg("myResources")}</a> <i class="fa fa-angle-right"></i> <#if authorization.resource.displayName??>${authorization.resource.displayName}<#else>${authorization.resource.name}</#if>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<#if authorization.resource.iconUri??>
|
||||||
|
<img src="${authorization.resource.iconUri}">
|
||||||
|
<br/>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h3>
|
||||||
|
${msg("peopleAccessResource")}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>${msg("user")}</th>
|
||||||
|
<th>${msg("permission")}</th>
|
||||||
|
<th>${msg("date")}</th>
|
||||||
|
<th>${msg("action")}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<#if authorization.resource.shares?size != 0>
|
||||||
|
<#list authorization.resource.shares as permission>
|
||||||
|
<form action="${url.getResourceGrant(authorization.resource.id)}" name="revokeForm-${authorization.resource.id}-${permission.requester.username}" method="post">
|
||||||
|
<input type="hidden" name="action" value="revoke">
|
||||||
|
<input type="hidden" name="requester" value="${permission.requester.username}">
|
||||||
|
<input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker}">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<#if permission.requester.email??>${permission.requester.email}<#else>${permission.requester.username}</#if>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<#if permission.scopes?size != 0>
|
||||||
|
<#list permission.scopes as scope>
|
||||||
|
<#if scope.granted && scope.scope??>
|
||||||
|
<div class="search-box">
|
||||||
|
<#if scope.scope.displayName??>
|
||||||
|
${scope.scope.displayName}
|
||||||
|
<#else>
|
||||||
|
${scope.scope.name}
|
||||||
|
</#if>
|
||||||
|
<button class="close-icon" type="button" name="removeScope-${authorization.resource.id}-${permission.requester.username}" onclick="removeScopeElm(this.parentNode);document.forms['revokeForm-${authorization.resource.id}-${permission.requester.username}'].submit();"><i class="fa fa-times" aria-hidden="true"></i></button>
|
||||||
|
<input type="hidden" name="permission_id" value="${scope.id}"/>
|
||||||
|
</div>
|
||||||
|
<#else>
|
||||||
|
${msg("anyPermission")}
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
<#else>
|
||||||
|
Any action
|
||||||
|
</#if>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
${permission.createdDate?datetime}
|
||||||
|
</td>
|
||||||
|
<td width="20%" align="middle" style="vertical-align: middle">
|
||||||
|
<a href="#" id="revoke-${authorization.resource.name}-${permission.requester.username}" onclick="removeAllScopes('${authorization.resource.id}-${permission.requester.username}');document.forms['revokeForm-${authorization.resource.id}-${permission.requester.username}'].submit();" type="submit" class="btn btn-primary">${msg("doRevoke")}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</form>
|
||||||
|
</#list>
|
||||||
|
<#else>
|
||||||
|
<tr>
|
||||||
|
<td colspan="4">${msg("resourceIsNotBeingShared")}</td>
|
||||||
|
</tr>
|
||||||
|
</#if>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h3>
|
||||||
|
${msg("resourceManagedPolicies")}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>${msg("description")}</th>
|
||||||
|
<th>${msg("permission")}</th>
|
||||||
|
<th>${msg("action")}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<#if authorization.resource.policies?size != 0>
|
||||||
|
<#list authorization.resource.policies as permission>
|
||||||
|
<form action="${url.getResourceGrant(authorization.resource.id)}" name="revokePolicyForm-${authorization.resource.id}-${permission.id}" method="post">
|
||||||
|
<input type="hidden" name="action" value="revokePolicy">
|
||||||
|
<input type="hidden" name="permission_id" value="${permission.id}"/>
|
||||||
|
<input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker}">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<#if permission.description??>
|
||||||
|
${permission.description}
|
||||||
|
</#if>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<#if permission.scopes?size != 0>
|
||||||
|
<#list permission.scopes as scope>
|
||||||
|
<div class="search-box">
|
||||||
|
<#if scope.displayName??>
|
||||||
|
${scope.displayName}
|
||||||
|
<#else>
|
||||||
|
${scope.name}
|
||||||
|
</#if>
|
||||||
|
<button class="close-icon" type="button" name="removePolicyScope-${authorization.resource.id}-${permission.id}-${scope.id}" onclick="removeScopeElm(this.parentNode);document.forms['revokePolicyForm-${authorization.resource.id}-${permission.id}'].submit();"><i class="fa fa-times" aria-hidden="true"></i></button>
|
||||||
|
<input type="hidden" name="permission_id" value="${permission.id}:${scope.id}"/>
|
||||||
|
</div>
|
||||||
|
</#list>
|
||||||
|
<#else>
|
||||||
|
${msg("anyAction")}
|
||||||
|
</#if>
|
||||||
|
</td>
|
||||||
|
<td width="20%" align="middle" style="vertical-align: middle">
|
||||||
|
<a href="#" id="revokePolicy-${authorization.resource.name}-${permission.id}" onclick="document.forms['revokePolicyForm-${authorization.resource.id}-${permission.id}']['action'].value = 'revokePolicyAll';document.forms['revokePolicyForm-${authorization.resource.id}-${permission.id}'].submit();" type="submit" class="btn btn-primary">${msg("doRevoke")}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</form>
|
||||||
|
</#list>
|
||||||
|
<#else>
|
||||||
|
<tr>
|
||||||
|
<td colspan="3">
|
||||||
|
${msg("resourceNoPermissionsGrantingAccess")}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</#if>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h3>
|
||||||
|
${msg("shareWithOthers")}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<form action="${url.getResourceShare(authorization.resource.id)}" name="shareForm" method="post">
|
||||||
|
<input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker}">
|
||||||
|
<div class="col-sm-3 col-md-3">
|
||||||
|
<label for="password" class="control-label">${msg("username")} or ${msg("email")} </label> <span class="required">*</span>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-8 col-md-8">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<input type="text" class="form-control" id="user_id" name="user_id" autofocus autocomplete="off">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<br/>
|
||||||
|
<#list authorization.resource.scopes as scope>
|
||||||
|
<div id="scope" class="search-box">
|
||||||
|
<#if scope.displayName??>
|
||||||
|
${scope.displayName}
|
||||||
|
<#else>
|
||||||
|
${scope.name}
|
||||||
|
</#if>
|
||||||
|
<button class="close-icon" id="share-remove-scope-${authorization.resource.name}-${scope.name}" type="button" onclick="if (getChildren(this.parentNode.parentNode, 'scope').length > 1) {removeScopeElm(this.parentNode)}"><i class="fa fa-times" aria-hidden="true"></i></button>
|
||||||
|
<input type="hidden" name="scope_id" value="${scope.id}"/>
|
||||||
|
</div>
|
||||||
|
</#list>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<br/>
|
||||||
|
<a href="#" onclick="document.forms['shareForm'].submit()" type="submit" id="share-button" class="btn btn-primary">${msg("share")}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
</@layout.mainLayout>
|
403
base/account/resources.ftl
Executable file
403
base/account/resources.ftl
Executable file
@ -0,0 +1,403 @@
|
|||||||
|
<#import "template.ftl" as layout>
|
||||||
|
<@layout.mainLayout active='authorization' bodyClass='authorization'; section>
|
||||||
|
<style>
|
||||||
|
.search-box,.close-icon,.search-wrapper {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.search-wrapper {
|
||||||
|
width: 500px;
|
||||||
|
margin: auto;
|
||||||
|
margin-top: 50px;
|
||||||
|
}
|
||||||
|
.search-box {
|
||||||
|
font-weight: 600;
|
||||||
|
color: white;
|
||||||
|
border: 1px solid #006e9c;
|
||||||
|
outline: 0;
|
||||||
|
border-radius: 15px;
|
||||||
|
background-color: #0085cf;
|
||||||
|
padding: 2px 5px;
|
||||||
|
}
|
||||||
|
.search-box:focus {
|
||||||
|
box-shadow: 0 0 15px 5px #b0e0ee;
|
||||||
|
border: 2px solid #bebede;
|
||||||
|
}
|
||||||
|
.close-icon {
|
||||||
|
border:1px solid transparent;
|
||||||
|
background-color: transparent;
|
||||||
|
display: inline-block;
|
||||||
|
float: right;
|
||||||
|
outline: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.close-icon:after {
|
||||||
|
display: block;
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
background-color: #FA9595;
|
||||||
|
z-index:1;
|
||||||
|
right: 35px;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
margin: auto;
|
||||||
|
padding: 2px;
|
||||||
|
border-radius: 50%;
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 12px;
|
||||||
|
box-shadow: 0 0 2px #E50F0F;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.search-box:not(:valid) ~ .close-icon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
function showHideActions(elm) {
|
||||||
|
if (elm.style.display == 'none') {
|
||||||
|
elm.style.display = '';
|
||||||
|
} else {
|
||||||
|
elm.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function removeScopeElm(elm) {
|
||||||
|
var td = elm.parentNode;
|
||||||
|
var tr = td.parentNode;
|
||||||
|
var tbody = tr.parentNode;
|
||||||
|
|
||||||
|
td.removeChild(elm);
|
||||||
|
|
||||||
|
var childCount = td.childNodes.length - 1;
|
||||||
|
|
||||||
|
for (i = 0; i < td.childNodes.length; i++) {
|
||||||
|
if (!td.childNodes[i].tagName || td.childNodes[i].tagName.toUpperCase() != 'DIV') {
|
||||||
|
td.removeChild(td.childNodes[i]);
|
||||||
|
childCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (childCount <= 0) {
|
||||||
|
tbody.removeChild(tr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeAllScopes(id) {
|
||||||
|
var scopesElm = document.getElementsByName('removeScope-' + id);
|
||||||
|
|
||||||
|
for (i = 0; i < scopesElm.length; i++) {
|
||||||
|
var td = scopesElm[i].parentNode.parentNode;
|
||||||
|
var tr = td.parentNode;
|
||||||
|
var tbody = tr.parentNode;
|
||||||
|
tbody.removeChild(tr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectAllCheckBoxes(formName, elm, name) {
|
||||||
|
var shares = document.forms[formName].getElementsByTagName('input');
|
||||||
|
|
||||||
|
for (i = 0; i < shares.length; i++) {
|
||||||
|
if (shares[i].name == name) {
|
||||||
|
shares[i].checked = elm.checked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h2>
|
||||||
|
${msg("myResources")}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<#if authorization.resourcesWaitingApproval?size != 0>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h3>
|
||||||
|
${msg("needMyApproval")}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>${msg("resource")}</th>
|
||||||
|
<th>${msg("requestor")}</th>
|
||||||
|
<th>${msg("permissionRequestion")}</th>
|
||||||
|
<th>${msg("action")}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<#list authorization.resourcesWaitingApproval as resource>
|
||||||
|
<#list resource.permissions as permission>
|
||||||
|
<form action="${url.getResourceGrant(resource.id)}" name="approveForm-${resource.id}-${permission.requester.username}" method="post">
|
||||||
|
<input type="hidden" name="action" value="grant">
|
||||||
|
<input type="hidden" name="requester" value="${permission.requester.username}">
|
||||||
|
<input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker}">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<#if resource.displayName??>${resource.displayName}<#else>${resource.name}</#if>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<#if permission.requester.email??>${permission.requester.email}<#else>${permission.requester.username}</#if>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<#list permission.scopes as scope>
|
||||||
|
<#if scope.scope??>
|
||||||
|
<div class="search-box">
|
||||||
|
<#if scope.scope.displayName??>
|
||||||
|
${scope.scope.displayName}
|
||||||
|
<#else>
|
||||||
|
${scope.scope.name}
|
||||||
|
</#if>
|
||||||
|
<button class="close-icon" type="button" id="grant-remove-scope-${resource.name}-${permission.requester.username}-${scope.scope.name}" name="removeScope-${resource.id}-${permission.requester.username}" onclick="removeScopeElm(this.parentNode);document.forms['approveForm-${resource.id}-${permission.requester.username}']['action'].value = 'deny';document.forms['approveForm-${resource.id}-${permission.requester.username}'].submit();"><i class="fa fa-times" aria-hidden="true"></i></button>
|
||||||
|
<input type="hidden" name="permission_id" value="${scope.id}"/>
|
||||||
|
</div>
|
||||||
|
<#else>
|
||||||
|
${msg("anyPermission")}
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</td>
|
||||||
|
<td width="20%" align="middle" style="vertical-align: middle">
|
||||||
|
<a href="#" id="grant-${resource.name}-${permission.requester.username}" onclick="document.forms['approveForm-${resource.id}-${permission.requester.username}']['action'].value = 'grant';document.forms['approveForm-${resource.id}-${permission.requester.username}'].submit();" type="submit" class="btn btn-primary">${msg("doApprove")}</a>
|
||||||
|
<a href="#" id="deny-${resource.name}-${permission.requester.username}" onclick="removeAllScopes('${resource.id}-${permission.requester.username}');document.forms['approveForm-${resource.id}-${permission.requester.username}']['action'].value = 'deny';document.forms['approveForm-${resource.id}-${permission.requester.username}'].submit();" type="submit" class="btn btn-danger">${msg("doDeny")}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</form>
|
||||||
|
</#list>
|
||||||
|
</#list>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h3>
|
||||||
|
${msg("myResourcesSub")}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>${msg("resource")}</th>
|
||||||
|
<th>${msg("application")}</th>
|
||||||
|
<th>${msg("peopleSharingThisResource")}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<#if authorization.resources?size != 0>
|
||||||
|
<#list authorization.resources as resource>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a id="detail-${resource.name}" href="${url.getResourceDetailUrl(resource.id)}">
|
||||||
|
<#if resource.displayName??>${resource.displayName}<#else>${resource.name}</#if>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<#if resource.resourceServer.baseUri??>
|
||||||
|
<a href="${resource.resourceServer.baseUri}">${resource.resourceServer.name}</a>
|
||||||
|
<#else>
|
||||||
|
${resource.resourceServer.name}
|
||||||
|
</#if>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<#if resource.shares?size != 0>
|
||||||
|
<a href="${url.getResourceDetailUrl(resource.id)}">${resource.shares?size} <i class="fa fa-users"></i></a>
|
||||||
|
<#else>
|
||||||
|
${msg("notBeingShared")}
|
||||||
|
</#if>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</#list>
|
||||||
|
<#else>
|
||||||
|
<tr>
|
||||||
|
<td colspan="4">${msg("notHaveAnyResource")}</td>
|
||||||
|
</tr>
|
||||||
|
</#if>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h3>
|
||||||
|
${msg("resourcesSharedWithMe")}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<form action="${url.resourceUrl}" name="shareForm" method="post">
|
||||||
|
<input type="hidden" name="action" value="cancel"/>
|
||||||
|
<input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker}">
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th width="5%"><input type="checkbox" onclick="selectAllCheckBoxes('shareForm', this, 'resource_id');" <#if authorization.sharedResources?size == 0>disabled="true"</#if></td>
|
||||||
|
<th>${msg("resource")}</th>
|
||||||
|
<th>${msg("owner")}</th>
|
||||||
|
<th>${msg("application")}</th>
|
||||||
|
<th>${msg("permission")}</th>
|
||||||
|
<th>${msg("date")}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<#if authorization.sharedResources?size != 0>
|
||||||
|
<#list authorization.sharedResources as resource>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" name="resource_id" value="${resource.id}"/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<#if resource.displayName??>${resource.displayName}<#else>${resource.name}</#if>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
${resource.ownerName}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<#if resource.resourceServer.baseUri??>
|
||||||
|
<a href="${resource.resourceServer.baseUri}">${resource.resourceServer.name}</a>
|
||||||
|
<#else>
|
||||||
|
${resource.resourceServer.name}
|
||||||
|
</#if>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<#if resource.permissions?size != 0>
|
||||||
|
<ul>
|
||||||
|
<#list resource.permissions as permission>
|
||||||
|
<#list permission.scopes as scope>
|
||||||
|
<#if scope.granted && scope.scope??>
|
||||||
|
<li>
|
||||||
|
<#if scope.scope.displayName??>
|
||||||
|
${scope.scope.displayName}
|
||||||
|
<#else>
|
||||||
|
${scope.scope.name}
|
||||||
|
</#if>
|
||||||
|
</li>
|
||||||
|
<#else>
|
||||||
|
${msg("anyPermission")}
|
||||||
|
</#if>
|
||||||
|
</#list>
|
||||||
|
</#list>
|
||||||
|
</ul>
|
||||||
|
<#else>
|
||||||
|
Any action
|
||||||
|
</#if>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
${resource.permissions[0].grantedDate?datetime}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</#list>
|
||||||
|
<#else>
|
||||||
|
<tr>
|
||||||
|
<td colspan="6">${msg("noResourcesSharedWithYou")}</td>
|
||||||
|
</tr>
|
||||||
|
</#if>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<#if authorization.sharedResources?size != 0>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<a href="#" onclick="document.forms['shareForm'].submit();" type="submit" class="btn btn-danger">${msg("doRemoveSharing")}</a>
|
||||||
|
</div>
|
||||||
|
</#if>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<#if authorization.resourcesWaitingOthersApproval?size != 0>
|
||||||
|
<br/>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h3>
|
||||||
|
${msg("requestsWaitingApproval")}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<i class="pficon pficon-info"></i> ${msg("havePermissionRequestsWaitingForApproval",authorization.resourcesWaitingOthersApproval?size)}
|
||||||
|
<a href="#" onclick="document.getElementById('waitingApproval').style.display=''">${msg("clickHereForDetails")}</a>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12"></div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12"></div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12"></div>
|
||||||
|
</div>
|
||||||
|
<div class="row" id="waitingApproval" style="display:none">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<form action="${url.resourceUrl}" name="waitingApprovalForm" method="post">
|
||||||
|
<input type="hidden" name="action" value="cancelRequest"/>
|
||||||
|
<input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker}">
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th width="5%"><input type="checkbox" onclick="selectAllCheckBoxes('waitingApprovalForm', this, 'resource_id');" <#if authorization.resourcesWaitingOthersApproval?size == 0>disabled="true"</#if></th>
|
||||||
|
<th>${msg("resource")}</th>
|
||||||
|
<th>${msg("owner")}</th>
|
||||||
|
<th>${msg("action")}</th>
|
||||||
|
<th>${msg("date")}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<#list authorization.resourcesWaitingOthersApproval as resource>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" name="resource_id" value="${resource.id}"/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<#if resource.displayName??>${resource.displayName}<#else>${resource.name}</#if>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
${resource.ownerName}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ul>
|
||||||
|
<#list resource.permissions as permission>
|
||||||
|
<#list permission.scopes as scope>
|
||||||
|
<li>
|
||||||
|
<#if scope.scope??>
|
||||||
|
<#if scope.scope.displayName??>
|
||||||
|
${scope.scope.displayName}
|
||||||
|
<#else>
|
||||||
|
${scope.scope.name}
|
||||||
|
</#if>
|
||||||
|
<#else>
|
||||||
|
${msg("anyPermission")}
|
||||||
|
</#if>
|
||||||
|
</li>
|
||||||
|
</#list>
|
||||||
|
</#list>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
${resource.permissions[0].createdDate?datetime}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</#list>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<a href="#" onclick="document.forms['waitingApprovalForm'].submit();" type="submit" class="btn btn-danger">${msg("doRemoveRequest")}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
</@layout.mainLayout>
|
44
base/account/sessions.ftl
Executable file
44
base/account/sessions.ftl
Executable file
@ -0,0 +1,44 @@
|
|||||||
|
<#import "template.ftl" as layout>
|
||||||
|
<@layout.mainLayout active='sessions' bodyClass='sessions'; section>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h2>${msg("sessionsHtmlTitle")}</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>${msg("ip")}</td>
|
||||||
|
<td>${msg("started")}</td>
|
||||||
|
<td>${msg("lastAccess")}</td>
|
||||||
|
<td>${msg("expires")}</td>
|
||||||
|
<td>${msg("clients")}</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<#list sessions.sessions as session>
|
||||||
|
<tr>
|
||||||
|
<td>${session.ipAddress}</td>
|
||||||
|
<td>${session.started?datetime}</td>
|
||||||
|
<td>${session.lastAccess?datetime}</td>
|
||||||
|
<td>${session.expires?datetime}</td>
|
||||||
|
<td>
|
||||||
|
<#list session.clients as client>
|
||||||
|
${client}<br/>
|
||||||
|
</#list>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</#list>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<form action="${url.sessionsUrl}" method="post">
|
||||||
|
<input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker}">
|
||||||
|
<button id="logout-all-sessions" class="btn btn-default">${msg("doLogOutAllSessions")}</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</@layout.mainLayout>
|
88
base/account/template.ftl
Normal file
88
base/account/template.ftl
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
<#macro mainLayout active bodyClass>
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<meta name="robots" content="noindex, nofollow">
|
||||||
|
|
||||||
|
<title>${msg("accountManagementTitle")}</title>
|
||||||
|
<link rel="icon" href="${url.resourcesPath}/img/favicon.ico">
|
||||||
|
<#if properties.stylesCommon?has_content>
|
||||||
|
<#list properties.stylesCommon?split(' ') as style>
|
||||||
|
<link href="${url.resourcesCommonPath}/${style}" rel="stylesheet" />
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
<#if properties.styles?has_content>
|
||||||
|
<#list properties.styles?split(' ') as style>
|
||||||
|
<link href="${url.resourcesPath}/${style}" rel="stylesheet" />
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
<#if properties.scripts?has_content>
|
||||||
|
<#list properties.scripts?split(' ') as script>
|
||||||
|
<script type="text/javascript" src="${url.resourcesPath}/${script}"></script>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
</head>
|
||||||
|
<body class="admin-console user ${bodyClass}">
|
||||||
|
|
||||||
|
<header class="navbar navbar-default navbar-pf navbar-main header">
|
||||||
|
<nav class="navbar" role="navigation">
|
||||||
|
<div class="navbar-header">
|
||||||
|
<div class="container">
|
||||||
|
<h1 class="navbar-title">Keycloak</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="navbar-collapse navbar-collapse-1">
|
||||||
|
<div class="container">
|
||||||
|
<ul class="nav navbar-nav navbar-utility">
|
||||||
|
<#if realm.internationalizationEnabled>
|
||||||
|
<li>
|
||||||
|
<div class="kc-dropdown" id="kc-locale-dropdown">
|
||||||
|
<a href="#" id="kc-current-locale-link">${locale.current}</a>
|
||||||
|
<ul>
|
||||||
|
<#list locale.supported as l>
|
||||||
|
<li class="kc-dropdown-item"><a href="${l.url}">${l.label}</a></li>
|
||||||
|
</#list>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<li>
|
||||||
|
</#if>
|
||||||
|
<#if referrer?has_content && referrer.url?has_content><li><a href="${referrer.url}" id="referrer">${msg("backTo",referrer.name)}</a></li></#if>
|
||||||
|
<li><a href="${url.logoutUrl}">${msg("doSignOut")}</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="bs-sidebar col-sm-3">
|
||||||
|
<ul>
|
||||||
|
<li class="<#if active=='account'>active</#if>"><a href="${url.accountUrl}">${msg("account")}</a></li>
|
||||||
|
<#if features.passwordUpdateSupported><li class="<#if active=='password'>active</#if>"><a href="${url.passwordUrl}">${msg("password")}</a></li></#if>
|
||||||
|
<li class="<#if active=='totp'>active</#if>"><a href="${url.totpUrl}">${msg("authenticator")}</a></li>
|
||||||
|
<#if features.identityFederation><li class="<#if active=='social'>active</#if>"><a href="${url.socialUrl}">${msg("federatedIdentity")}</a></li></#if>
|
||||||
|
<li class="<#if active=='sessions'>active</#if>"><a href="${url.sessionsUrl}">${msg("sessions")}</a></li>
|
||||||
|
<li class="<#if active=='applications'>active</#if>"><a href="${url.applicationsUrl}">${msg("applications")}</a></li>
|
||||||
|
<#if features.log><li class="<#if active=='log'>active</#if>"><a href="${url.logUrl}">${msg("log")}</a></li></#if>
|
||||||
|
<#if realm.userManagedAccessAllowed && features.authorization><li class="<#if active=='authorization'>active</#if>"><a href="${url.resourceUrl}">${msg("myResources")}</a></li></#if>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-9 content-area">
|
||||||
|
<#if message?has_content>
|
||||||
|
<div class="alert alert-${message.type}">
|
||||||
|
<#if message.type=='success' ><span class="pficon pficon-ok"></span></#if>
|
||||||
|
<#if message.type=='error' ><span class="pficon pficon-error-circle-o"></span></#if>
|
||||||
|
<span class="kc-feedback-text">${kcSanitize(message.summary)?no_esc}</span>
|
||||||
|
</div>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<#nested "content">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</#macro>
|
141
base/account/totp.ftl
Executable file
141
base/account/totp.ftl
Executable file
@ -0,0 +1,141 @@
|
|||||||
|
<#import "template.ftl" as layout>
|
||||||
|
<@layout.mainLayout active='totp' bodyClass='totp'; section>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h2>${msg("authenticatorTitle")}</h2>
|
||||||
|
</div>
|
||||||
|
<#if totp.otpCredentials?size == 0>
|
||||||
|
<div class="col-md-2 subtitle">
|
||||||
|
<span class="subtitle"><span class="required">*</span> ${msg("requiredFields")}</span>
|
||||||
|
</div>
|
||||||
|
</#if>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<#if totp.enabled>
|
||||||
|
<table class="table table-bordered table-striped">
|
||||||
|
<thead>
|
||||||
|
<#if totp.otpCredentials?size gt 1>
|
||||||
|
<tr>
|
||||||
|
<th colspan="4">${msg("configureAuthenticators")}</th>
|
||||||
|
</tr>
|
||||||
|
<#else>
|
||||||
|
<tr>
|
||||||
|
<th colspan="3">${msg("configureAuthenticators")}</th>
|
||||||
|
</tr>
|
||||||
|
</#if>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<#list totp.otpCredentials as credential>
|
||||||
|
<tr>
|
||||||
|
<td class="provider">${msg("mobile")}</td>
|
||||||
|
<#if totp.otpCredentials?size gt 1>
|
||||||
|
<td class="provider">${credential.id}</td>
|
||||||
|
</#if>
|
||||||
|
<td class="provider">${credential.userLabel!}</td>
|
||||||
|
<td class="action">
|
||||||
|
<form action="${url.totpUrl}" method="post" class="form-inline">
|
||||||
|
<input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker}">
|
||||||
|
<input type="hidden" id="submitAction" name="submitAction" value="Delete">
|
||||||
|
<input type="hidden" id="credentialId" name="credentialId" value="${credential.id}">
|
||||||
|
<button id="remove-mobile" class="btn btn-default">
|
||||||
|
<i class="pficon pficon-delete"></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</#list>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<#else>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>
|
||||||
|
<p>${msg("totpStep1")}</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<#list totp.policy.supportedApplications as app>
|
||||||
|
<li>${app}</li>
|
||||||
|
</#list>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<#if mode?? && mode = "manual">
|
||||||
|
<li>
|
||||||
|
<p>${msg("totpManualStep2")}</p>
|
||||||
|
<p><span id="kc-totp-secret-key">${totp.totpSecretEncoded}</span></p>
|
||||||
|
<p><a href="${totp.qrUrl}" id="mode-barcode">${msg("totpScanBarcode")}</a></p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>${msg("totpManualStep3")}</p>
|
||||||
|
<ul>
|
||||||
|
<li id="kc-totp-type">${msg("totpType")}: ${msg("totp." + totp.policy.type)}</li>
|
||||||
|
<li id="kc-totp-algorithm">${msg("totpAlgorithm")}: ${totp.policy.getAlgorithmKey()}</li>
|
||||||
|
<li id="kc-totp-digits">${msg("totpDigits")}: ${totp.policy.digits}</li>
|
||||||
|
<#if totp.policy.type = "totp">
|
||||||
|
<li id="kc-totp-period">${msg("totpInterval")}: ${totp.policy.period}</li>
|
||||||
|
<#elseif totp.policy.type = "hotp">
|
||||||
|
<li id="kc-totp-counter">${msg("totpCounter")}: ${totp.policy.initialCounter}</li>
|
||||||
|
</#if>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<#else>
|
||||||
|
<li>
|
||||||
|
<p>${msg("totpStep2")}</p>
|
||||||
|
<p><img src="data:image/png;base64, ${totp.totpSecretQrCode}" alt="Figure: Barcode"></p>
|
||||||
|
<p><a href="${totp.manualUrl}" id="mode-manual">${msg("totpUnableToScan")}</a></p>
|
||||||
|
</li>
|
||||||
|
</#if>
|
||||||
|
<li>
|
||||||
|
<p>${msg("totpStep3")}</p>
|
||||||
|
<p>${msg("totpStep3DeviceName")}</p>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<form action="${url.totpUrl}" class="form-horizontal" method="post">
|
||||||
|
<input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker}">
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-2 col-md-2">
|
||||||
|
<label for="totp" class="control-label">${msg("authenticatorCode")}</label> <span class="required">*</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-10 col-md-10">
|
||||||
|
<input type="text" class="form-control" id="totp" name="totp" autocomplete="off" autofocus>
|
||||||
|
<input type="hidden" id="totpSecret" name="totpSecret" value="${totp.totpSecret}"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group" ${messagesPerField.printIfExists('userLabel',properties.kcFormGroupErrorClass!)}">
|
||||||
|
<div class="col-sm-2 col-md-2">
|
||||||
|
<label for="userLabel" class="control-label">${msg("totpDeviceName")}</label> <#if totp.otpCredentials?size gte 1><span class="required">*</span></#if>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-10 col-md-10">
|
||||||
|
<input type="text" class="form-control" id="userLabel" name="userLabel" autocomplete="off">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div id="kc-form-buttons" class="col-md-offset-2 col-md-10 submit">
|
||||||
|
<div class="">
|
||||||
|
<button type="submit"
|
||||||
|
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}"
|
||||||
|
id="saveTOTPBtn" name="submitAction" value="Save">${msg("doSave")}
|
||||||
|
</button>
|
||||||
|
<button type="submit"
|
||||||
|
class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!}"
|
||||||
|
id="cancelTOTPBtn" name="submitAction" value="Cancel">${msg("doCancel")}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
</@layout.mainLayout>
|
101
base/admin/index.ftl
Executable file
101
base/admin/index.ftl
Executable file
@ -0,0 +1,101 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title></title>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<meta name="robots" content="noindex, nofollow">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
|
<link rel="shortcut icon" href="${resourceUrl}/img/favicon.ico">
|
||||||
|
<#if properties.stylesCommon?has_content>
|
||||||
|
<#list properties.stylesCommon?split(' ') as style>
|
||||||
|
<link href="${resourceCommonUrl}/${style}" rel="stylesheet" />
|
||||||
|
</#list>
|
||||||
|
<#list properties.styles?split(' ') as style>
|
||||||
|
<link href="${resourceUrl}/${style}" rel="stylesheet" />
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var authServerUrl = '${authServerUrl}';
|
||||||
|
var authUrl = '${authUrl}';
|
||||||
|
var consoleBaseUrl = '${consoleBaseUrl}';
|
||||||
|
var resourceUrl = '${resourceUrl}';
|
||||||
|
var masterRealm = '${masterRealm}';
|
||||||
|
var resourceVersion = '${resourceVersion}';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Minimized versions (for those that have one) -->
|
||||||
|
<script src="${resourceCommonUrl}/node_modules/jquery/dist/jquery.min.js" type="text/javascript"></script>
|
||||||
|
<script src="${resourceCommonUrl}/node_modules/select2/select2.js" type="text/javascript"></script>
|
||||||
|
<script src="${resourceCommonUrl}/node_modules/angular/angular.min.js"></script>
|
||||||
|
<script src="${resourceCommonUrl}/node_modules/angular-resource/angular-resource.min.js"></script>
|
||||||
|
<script src="${resourceCommonUrl}/node_modules/angular-route/angular-route.min.js"></script>
|
||||||
|
<script src="${resourceCommonUrl}/node_modules/angular-cookies/angular-cookies.min.js"></script>
|
||||||
|
<script src="${resourceCommonUrl}/node_modules/angular-sanitize/angular-sanitize.min.js"></script>
|
||||||
|
<script src="${resourceCommonUrl}/node_modules/angular-translate/dist/angular-translate.min.js"></script>
|
||||||
|
<script src="${resourceCommonUrl}/node_modules/angular-translate-loader-url/angular-translate-loader-url.min.js"></script>
|
||||||
|
<script src="${resourceCommonUrl}/node_modules/angular-ui-select2/src/select2.js" type="text/javascript"></script>
|
||||||
|
<script src="${resourceCommonUrl}/node_modules/autofill-event/autofill-event.js"></script>
|
||||||
|
|
||||||
|
<!-- Libraries not managed by yarn -->
|
||||||
|
<script src="${resourceCommonUrl}/lib/angular/ui-bootstrap-tpls-0.11.0.js"></script>
|
||||||
|
<script src="${resourceCommonUrl}/lib/angular/treeview/angular.treeview.js"></script>
|
||||||
|
<script src="${resourceCommonUrl}/lib/fileupload/angular-file-upload.min.js"></script>
|
||||||
|
<script src="${resourceCommonUrl}/lib/filesaver/FileSaver.js"></script>
|
||||||
|
<script src="${resourceCommonUrl}/lib/ui-ace/min/ace.js"></script>
|
||||||
|
<script src="${resourceCommonUrl}/lib/ui-ace/ui-ace.min.js"></script>
|
||||||
|
|
||||||
|
<script src="${authUrl}/js/keycloak.js?version=${resourceVersion}" type="text/javascript"></script>
|
||||||
|
|
||||||
|
<script src="${resourceUrl}/js/app.js" type="text/javascript"></script>
|
||||||
|
<script src="${resourceUrl}/js/controllers/realm.js" type="text/javascript"></script>
|
||||||
|
<script src="${resourceUrl}/js/controllers/clients.js" type="text/javascript"></script>
|
||||||
|
<script src="${resourceUrl}/js/controllers/users.js" type="text/javascript"></script>
|
||||||
|
<script src="${resourceUrl}/js/controllers/groups.js" type="text/javascript"></script>
|
||||||
|
<script src="${resourceUrl}/js/controllers/roles.js" type="text/javascript"></script>
|
||||||
|
<script src="${resourceUrl}/js/loaders.js" type="text/javascript"></script>
|
||||||
|
<script src="${resourceUrl}/js/services.js" type="text/javascript"></script>
|
||||||
|
|
||||||
|
<!-- Authorization -->
|
||||||
|
<script src="${resourceUrl}/js/authz/authz-app.js" type="text/javascript"></script>
|
||||||
|
<script src="${resourceUrl}/js/authz/authz-controller.js" type="text/javascript"></script>
|
||||||
|
<script src="${resourceUrl}/js/authz/authz-services.js" type="text/javascript"></script>
|
||||||
|
|
||||||
|
<#if properties.scripts?has_content>
|
||||||
|
<#list properties.scripts?split(' ') as script>
|
||||||
|
<script type="text/javascript" src="${resourceUrl}/${script}"></script>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
</head>
|
||||||
|
<body data-ng-controller="GlobalCtrl" data-ng-cloak data-ng-show="auth.user">
|
||||||
|
|
||||||
|
<nav class="navbar navbar-default navbar-pf" role="navigation" data-ng-include data-src="resourceUrl + '/partials/menu.html'">
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div data-ng-view id="view"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="feedback-aligner" data-ng-show="notification.display">
|
||||||
|
<div class="alert alert-{{notification.type}} alert-dismissable">
|
||||||
|
<button type="button" class="close" data-ng-click="notification.remove()" id="notification-close">
|
||||||
|
<span class="pficon pficon-close"/>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<span class="pficon pficon-ok" ng-show="notification.type == 'success'"></span>
|
||||||
|
<span class="pficon pficon-info" ng-show="notification.type == 'info'"></span>
|
||||||
|
<span class="pficon pficon-warning-triangle-o" ng-show="notification.type == 'warning'"></span>
|
||||||
|
<span class="pficon pficon-error-circle-o" ng-show="notification.type == 'danger'"></span>
|
||||||
|
<strong>{{notification.header}}</strong> {{notification.message}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="loading" class="loading">Loading...</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
1838
base/admin/messages/admin-messages_en.properties
Normal file
1838
base/admin/messages/admin-messages_en.properties
Normal file
File diff suppressed because it is too large
Load Diff
41
base/admin/messages/messages_en.properties
Normal file
41
base/admin/messages/messages_en.properties
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
invalidPasswordMinLengthMessage=Invalid password: minimum length {0}.
|
||||||
|
invalidPasswordMinLowerCaseCharsMessage=Invalid password: must contain at least {0} lower case characters.
|
||||||
|
invalidPasswordMinDigitsMessage=Invalid password: must contain at least {0} numerical digits.
|
||||||
|
invalidPasswordMinUpperCaseCharsMessage=Invalid password: must contain at least {0} upper case characters.
|
||||||
|
invalidPasswordMinSpecialCharsMessage=Invalid password: must contain at least {0} special characters.
|
||||||
|
invalidPasswordNotUsernameMessage=Invalid password: must not be equal to the username.
|
||||||
|
invalidPasswordNotEmailMessage=Invalid password: must not be equal to the email.
|
||||||
|
invalidPasswordRegexPatternMessage=Invalid password: fails to match regex pattern(s).
|
||||||
|
invalidPasswordHistoryMessage=Invalid password: must not be equal to any of last {0} passwords.
|
||||||
|
invalidPasswordBlacklistedMessage=Invalid password: password is blacklisted.
|
||||||
|
invalidPasswordGenericMessage=Invalid password: new password does not match password policies.
|
||||||
|
|
||||||
|
ldapErrorInvalidCustomFilter=Custom configured LDAP filter does not start with "(" or does not end with ")".
|
||||||
|
ldapErrorConnectionTimeoutNotNumber=Connection Timeout must be a number
|
||||||
|
ldapErrorReadTimeoutNotNumber=Read Timeout must be a number
|
||||||
|
ldapErrorMissingClientId=Client ID needs to be provided in config when Realm Roles Mapping is not used.
|
||||||
|
ldapErrorCantPreserveGroupInheritanceWithUIDMembershipType=Not possible to preserve group inheritance and use UID membership type together.
|
||||||
|
ldapErrorCantWriteOnlyForReadOnlyLdap=Can not set write only when LDAP provider mode is not WRITABLE
|
||||||
|
ldapErrorCantWriteOnlyAndReadOnly=Can not set write-only and read-only together
|
||||||
|
ldapErrorCantEnableStartTlsAndConnectionPooling=Can not enable both StartTLS and connection pooling.
|
||||||
|
ldapErrorCantEnableUnsyncedAndImportOff=Can not disable Importing users when LDAP provider mode is UNSYNCED
|
||||||
|
ldapErrorMissingGroupsPathGroup=Groups path group does not exist - please create the group on specified path first
|
||||||
|
|
||||||
|
clientRedirectURIsFragmentError=Redirect URIs must not contain an URI fragment
|
||||||
|
clientRootURLFragmentError=Root URL must not contain an URL fragment
|
||||||
|
clientRootURLIllegalSchemeError=Root URL uses an illegal scheme
|
||||||
|
clientBaseURLIllegalSchemeError=Base URL uses an illegal scheme
|
||||||
|
backchannelLogoutUrlIllegalSchemeError=Backchannel logout URL uses an illegal scheme
|
||||||
|
clientRedirectURIsIllegalSchemeError=A redirect URI uses an illegal scheme
|
||||||
|
clientBaseURLInvalid=Base URL is not a valid URL
|
||||||
|
clientRootURLInvalid=Root URL is not a valid URL
|
||||||
|
clientRedirectURIsInvalid=A redirect URI is not a valid URI
|
||||||
|
backchannelLogoutUrlIsInvalid=Backchannel logout URL is not a valid URL
|
||||||
|
|
||||||
|
|
||||||
|
pairwiseMalformedClientRedirectURI=Client contained an invalid redirect URI.
|
||||||
|
pairwiseClientRedirectURIsMissingHost=Client redirect URIs must contain a valid host component.
|
||||||
|
pairwiseClientRedirectURIsMultipleHosts=Without a configured Sector Identifier URI, client redirect URIs must not contain multiple host components.
|
||||||
|
pairwiseMalformedSectorIdentifierURI=Malformed Sector Identifier URI.
|
||||||
|
pairwiseFailedToGetRedirectURIs=Failed to get redirect URIs from the Sector Identifier URI.
|
||||||
|
pairwiseRedirectURIsMismatch=Client redirect URIs does not match redirect URIs fetched from the Sector Identifier URI.
|
3495
base/admin/resources/js/app.js
Executable file
3495
base/admin/resources/js/app.js
Executable file
File diff suppressed because it is too large
Load Diff
549
base/admin/resources/js/authz/authz-app.js
Normal file
549
base/admin/resources/js/authz/authz-app.js
Normal file
@ -0,0 +1,549 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.requires.push('ui.ace');
|
||||||
|
|
||||||
|
module.config(['$routeProvider', function ($routeProvider) {
|
||||||
|
$routeProvider
|
||||||
|
.when('/realms/:realm/authz', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/resource-server-list.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/create', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/resource-server-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
},
|
||||||
|
clients: function (ClientListLoader) {
|
||||||
|
return ClientListLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/resource-server-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
},
|
||||||
|
clients: function (ClientListLoader) {
|
||||||
|
return ClientListLoader();
|
||||||
|
},
|
||||||
|
serverInfo: function (ServerInfoLoader) {
|
||||||
|
return ServerInfoLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/export-settings', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/resource-server-export-settings.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
},
|
||||||
|
clients: function (ClientListLoader) {
|
||||||
|
return ClientListLoader();
|
||||||
|
},
|
||||||
|
serverInfo: function (ServerInfoLoader) {
|
||||||
|
return ServerInfoLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/evaluate', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/policy/resource-server-policy-evaluate.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
},
|
||||||
|
clients: function (ClientListLoader) {
|
||||||
|
return ClientListLoader();
|
||||||
|
},
|
||||||
|
roles: function (RoleListLoader) {
|
||||||
|
return new RoleListLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'PolicyEvaluateCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/evaluate/result', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/policy/resource-server-policy-evaluate-result.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
controller: 'PolicyEvaluateCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/resource', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/resource-server-resource-list.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerResourceCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/resource/create', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/resource-server-resource-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerResourceDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/resource/:rsrid', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/resource-server-resource-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerResourceDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/scope', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/resource-server-scope-list.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerScopeCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/scope/create', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/resource-server-scope-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerScopeDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/scope/:id', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/resource-server-scope-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerScopeDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/permission', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/permission/resource-server-permission-list.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPermissionCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/policy', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/policy/resource-server-policy-list.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/permission/resource/create', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/permission/provider/resource-server-policy-resource-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyResourceDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/permission/resource/:id', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/permission/provider/resource-server-policy-resource-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyResourceDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/permission/scope/create', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/permission/provider/resource-server-policy-scope-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyScopeDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/permission/scope/:id', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/permission/provider/resource-server-policy-scope-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyScopeDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/policy/user/create', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/policy/provider/resource-server-policy-user-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyUserDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/policy/user/:id', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/policy/provider/resource-server-policy-user-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyUserDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/policy/client/create', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/policy/provider/resource-server-policy-client-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyClientDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/policy/client/:id', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/policy/provider/resource-server-policy-client-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyClientDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/policy/role/create', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/policy/provider/resource-server-policy-role-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyRoleDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/policy/role/:id', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/policy/provider/resource-server-policy-role-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyRoleDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/policy/group/create', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/policy/provider/resource-server-policy-group-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyGroupDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/policy/group/:id', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/policy/provider/resource-server-policy-group-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyGroupDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/policy/js/create', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/policy/provider/resource-server-policy-js-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
},
|
||||||
|
serverInfo : function(ServerInfoLoader) {
|
||||||
|
return ServerInfoLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyJSDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/policy/js/:id', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/policy/provider/resource-server-policy-js-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
},
|
||||||
|
serverInfo : function(ServerInfoLoader) {
|
||||||
|
return ServerInfoLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyJSDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/policy/time/create', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/policy/provider/resource-server-policy-time-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyTimeDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/policy/time/:id', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/policy/provider/resource-server-policy-time-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyTimeDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/policy/aggregate/create', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/policy/provider/resource-server-policy-aggregate-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyAggregateDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/policy/aggregate/:id', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/policy/provider/resource-server-policy-aggregate-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyAggregateDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/policy/client-scope/create', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/policy/provider/resource-server-policy-client-scope-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyClientScopeDetailCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/authz/resource-server/policy/client-scope/:id', {
|
||||||
|
templateUrl: resourceUrl + '/partials/authz/policy/provider/resource-server-policy-client-scope-detail.html',
|
||||||
|
resolve: {
|
||||||
|
realm: function (RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: 'ResourceServerPolicyClientScopeDetailCtrl'
|
||||||
|
}).when('/realms/:realm/roles/:role/permissions', {
|
||||||
|
templateUrl : resourceUrl + '/partials/authz/mgmt/realm-role-permissions.html',
|
||||||
|
resolve : {
|
||||||
|
realm : function(RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
role : function(RoleLoader) {
|
||||||
|
return RoleLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller : 'RealmRolePermissionsCtrl'
|
||||||
|
}).when('/realms/:realm/clients/:client/roles/:role/permissions', {
|
||||||
|
templateUrl : resourceUrl + '/partials/authz/mgmt/client-role-permissions.html',
|
||||||
|
resolve : {
|
||||||
|
realm : function(RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
},
|
||||||
|
role : function(RoleLoader) {
|
||||||
|
return RoleLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller : 'ClientRolePermissionsCtrl'
|
||||||
|
}).when('/realms/:realm/users-permissions', {
|
||||||
|
templateUrl : resourceUrl + '/partials/authz/mgmt/users-permissions.html',
|
||||||
|
resolve : {
|
||||||
|
realm : function(RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller : 'UsersPermissionsCtrl'
|
||||||
|
})
|
||||||
|
.when('/realms/:realm/clients/:client/permissions', {
|
||||||
|
templateUrl : resourceUrl + '/partials/authz/mgmt/client-permissions.html',
|
||||||
|
resolve : {
|
||||||
|
realm : function(RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
client : function(ClientLoader) {
|
||||||
|
return ClientLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller : 'ClientPermissionsCtrl'
|
||||||
|
})
|
||||||
|
.when('/realms/:realm/groups/:group/permissions', {
|
||||||
|
templateUrl : resourceUrl + '/partials/authz/mgmt/group-permissions.html',
|
||||||
|
resolve : {
|
||||||
|
realm : function(RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
group : function(GroupLoader) {
|
||||||
|
return GroupLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller : 'GroupPermissionsCtrl'
|
||||||
|
})
|
||||||
|
.when('/realms/:realm/identity-provider-settings/provider/:provider_id/:alias/permissions', {
|
||||||
|
templateUrl : function(params){ return resourceUrl + '/partials/authz/mgmt/broker-permissions.html'; },
|
||||||
|
resolve : {
|
||||||
|
realm : function(RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
identityProvider : function(IdentityProviderLoader) {
|
||||||
|
return IdentityProviderLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller : 'IdentityProviderPermissionCtrl'
|
||||||
|
})
|
||||||
|
;
|
||||||
|
}]);
|
||||||
|
|
||||||
|
module.directive('kcTabsResourceServer', function () {
|
||||||
|
return {
|
||||||
|
scope: true,
|
||||||
|
restrict: 'E',
|
||||||
|
replace: true,
|
||||||
|
templateUrl: resourceUrl + '/templates/authz/kc-tabs-resource-server.html'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.filter('unique', function () {
|
||||||
|
|
||||||
|
return function (items, filterOn) {
|
||||||
|
|
||||||
|
if (filterOn === false) {
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((filterOn || angular.isUndefined(filterOn)) && angular.isArray(items)) {
|
||||||
|
var hashCheck = {}, newItems = [];
|
||||||
|
|
||||||
|
var extractValueToCompare = function (item) {
|
||||||
|
if (angular.isObject(item) && angular.isString(filterOn)) {
|
||||||
|
return item[filterOn];
|
||||||
|
} else {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
angular.forEach(items, function (item) {
|
||||||
|
var valueToCheck, isDuplicate = false;
|
||||||
|
|
||||||
|
for (var i = 0; i < newItems.length; i++) {
|
||||||
|
if (angular.equals(extractValueToCompare(newItems[i]), extractValueToCompare(item))) {
|
||||||
|
isDuplicate = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isDuplicate) {
|
||||||
|
newItems.push(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
items = newItems;
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
module.filter('toCamelCase', function () {
|
||||||
|
return function (input) {
|
||||||
|
input = input || '';
|
||||||
|
return input.replace(/\w\S*/g, function (txt) {
|
||||||
|
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
})
|
3013
base/admin/resources/js/authz/authz-controller.js
Normal file
3013
base/admin/resources/js/authz/authz-controller.js
Normal file
File diff suppressed because it is too large
Load Diff
218
base/admin/resources/js/authz/authz-services.js
Normal file
218
base/admin/resources/js/authz/authz-services.js
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
module.factory('ResourceServer', function($resource) {
|
||||||
|
return $resource(authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server', {
|
||||||
|
realm : '@realm',
|
||||||
|
client: '@client'
|
||||||
|
}, {
|
||||||
|
'update' : {method : 'PUT'},
|
||||||
|
'import' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/import', method : 'POST'},
|
||||||
|
'settings' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/settings', method : 'GET'}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ResourceServerResource', function($resource) {
|
||||||
|
return $resource(authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/resource/:rsrid', {
|
||||||
|
realm : '@realm',
|
||||||
|
client: '@client',
|
||||||
|
rsrid : '@rsrid'
|
||||||
|
}, {
|
||||||
|
'update' : {method : 'PUT'},
|
||||||
|
'search' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/resource/search', method : 'GET'},
|
||||||
|
'scopes' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/resource/:rsrid/scopes', method : 'GET', isArray: true},
|
||||||
|
'permissions' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/resource/:rsrid/permissions', method : 'GET', isArray: true}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ResourceServerScope', function($resource) {
|
||||||
|
return $resource(authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/scope/:id', {
|
||||||
|
realm : '@realm',
|
||||||
|
client: '@client',
|
||||||
|
id : '@id'
|
||||||
|
}, {
|
||||||
|
'update' : {method : 'PUT'},
|
||||||
|
'search' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/scope/search', method : 'GET'},
|
||||||
|
'resources' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/scope/:id/resources', method : 'GET', isArray: true},
|
||||||
|
'permissions' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/scope/:id/permissions', method : 'GET', isArray: true},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ResourceServerPolicy', function($resource) {
|
||||||
|
return $resource(authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/policy/:type/:id', {
|
||||||
|
realm : '@realm',
|
||||||
|
client: '@client',
|
||||||
|
id : '@id',
|
||||||
|
type: '@type'
|
||||||
|
}, {
|
||||||
|
'update' : {method : 'PUT'},
|
||||||
|
'search' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/policy/search', method : 'GET'},
|
||||||
|
'associatedPolicies' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/policy/:id/associatedPolicies', method : 'GET', isArray: true},
|
||||||
|
'dependentPolicies' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/policy/:id/dependentPolicies', method : 'GET', isArray: true},
|
||||||
|
'scopes' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/policy/:id/scopes', method : 'GET', isArray: true},
|
||||||
|
'resources' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/policy/:id/resources', method : 'GET', isArray: true}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ResourceServerPermission', function($resource) {
|
||||||
|
return $resource(authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/permission/:type/:id', {
|
||||||
|
realm : '@realm',
|
||||||
|
client: '@client',
|
||||||
|
type: '@type',
|
||||||
|
id : '@id'
|
||||||
|
}, {
|
||||||
|
'update' : {method : 'PUT'},
|
||||||
|
'search' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/permission/search', method : 'GET'},
|
||||||
|
'searchPolicies' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/policy', method : 'GET', isArray: true},
|
||||||
|
'associatedPolicies' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/policy/:id/associatedPolicies', method : 'GET', isArray: true},
|
||||||
|
'dependentPolicies' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/policy/:id/dependentPolicies', method : 'GET', isArray: true},
|
||||||
|
'scopes' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/permission/:id/scopes', method : 'GET', isArray: true},
|
||||||
|
'resources' : {url: authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/permission/:id/resources', method : 'GET', isArray: true}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('PolicyProvider', function($resource) {
|
||||||
|
return $resource(authUrl + '/admin/realms/:realm/clients/:client/authz/resource-server/policy/providers', {
|
||||||
|
realm : '@realm',
|
||||||
|
client: '@client'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.service('AuthzDialog', function($modal) {
|
||||||
|
var dialog = {};
|
||||||
|
|
||||||
|
var openDialog = function(title, message, btns, template) {
|
||||||
|
var controller = function($scope, $modalInstance, $sce, title, message, btns) {
|
||||||
|
$scope.title = title;
|
||||||
|
$scope.message = $sce.trustAsHtml(message);
|
||||||
|
$scope.btns = btns;
|
||||||
|
|
||||||
|
$scope.ok = function () {
|
||||||
|
$modalInstance.close();
|
||||||
|
};
|
||||||
|
$scope.cancel = function () {
|
||||||
|
$modalInstance.dismiss('cancel');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return $modal.open({
|
||||||
|
templateUrl: resourceUrl + template,
|
||||||
|
controller: controller,
|
||||||
|
resolve: {
|
||||||
|
title: function() {
|
||||||
|
return title;
|
||||||
|
},
|
||||||
|
message: function() {
|
||||||
|
return message;
|
||||||
|
},
|
||||||
|
btns: function() {
|
||||||
|
return btns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).result;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.confirmDeleteWithMsg = function(name, type, msg, success) {
|
||||||
|
var title = 'Delete ' + type;
|
||||||
|
msg += 'Are you sure you want to permanently delete the ' + type + ' <strong>' + name + '</strong> ?';
|
||||||
|
var btns = {
|
||||||
|
ok: {
|
||||||
|
label: 'Delete',
|
||||||
|
cssClass: 'btn btn-danger'
|
||||||
|
},
|
||||||
|
cancel: {
|
||||||
|
label: 'Cancel',
|
||||||
|
cssClass: 'btn btn-default'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
openDialog(title, msg, btns, '/templates/authz/kc-authz-modal.html').then(success);
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.confirmDelete = function(name, type, success) {
|
||||||
|
var title = 'Delete ' + type;
|
||||||
|
var msg = 'Are you sure you want to permanently delete the ' + type + ' <strong>' + name + '</strong> ?';
|
||||||
|
var btns = {
|
||||||
|
ok: {
|
||||||
|
label: 'Delete',
|
||||||
|
cssClass: 'btn btn-danger'
|
||||||
|
},
|
||||||
|
cancel: {
|
||||||
|
label: 'Cancel',
|
||||||
|
cssClass: 'btn btn-default'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
openDialog(title, msg, btns, '/templates/authz/kc-authz-modal.html').then(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dialog;
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('RoleManagementPermissions', function($resource) {
|
||||||
|
return $resource(authUrl + '/admin/realms/:realm/roles-by-id/:role/management/permissions', {
|
||||||
|
realm : '@realm',
|
||||||
|
role : '@role'
|
||||||
|
}, {
|
||||||
|
update: {
|
||||||
|
method: 'PUT'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('UsersManagementPermissions', function($resource) {
|
||||||
|
return $resource(authUrl + '/admin/realms/:realm/users-management-permissions', {
|
||||||
|
realm : '@realm'
|
||||||
|
}, {
|
||||||
|
update: {
|
||||||
|
method: 'PUT'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ClientManagementPermissions', function($resource) {
|
||||||
|
return $resource(authUrl + '/admin/realms/:realm/clients/:client/management/permissions', {
|
||||||
|
realm : '@realm',
|
||||||
|
client : '@client'
|
||||||
|
}, {
|
||||||
|
update: {
|
||||||
|
method: 'PUT'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('IdentityProviderManagementPermissions', function($resource) {
|
||||||
|
return $resource(authUrl + '/admin/realms/:realm/identity-provider/instances/:alias/management/permissions', {
|
||||||
|
realm : '@realm',
|
||||||
|
alias : '@alias'
|
||||||
|
}, {
|
||||||
|
update: {
|
||||||
|
method: 'PUT'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('GroupManagementPermissions', function($resource) {
|
||||||
|
return $resource(authUrl + '/admin/realms/:realm/groups/:group/management/permissions', {
|
||||||
|
realm : '@realm',
|
||||||
|
group : '@group'
|
||||||
|
}, {
|
||||||
|
update: {
|
||||||
|
method: 'PUT'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('policyViewState', [function () {
|
||||||
|
return {
|
||||||
|
model: {
|
||||||
|
state: {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}]);
|
||||||
|
|
||||||
|
module.factory('viewState', [function () {
|
||||||
|
return {
|
||||||
|
model: {
|
||||||
|
state: {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}]);
|
||||||
|
|
3693
base/admin/resources/js/controllers/clients.js
Executable file
3693
base/admin/resources/js/controllers/clients.js
Executable file
File diff suppressed because it is too large
Load Diff
625
base/admin/resources/js/controllers/groups.js
Executable file
625
base/admin/resources/js/controllers/groups.js
Executable file
@ -0,0 +1,625 @@
|
|||||||
|
module.controller('GroupListCtrl', function($scope, $route, $q, realm, Groups, GroupsCount, Group, GroupChildren, Notifications, $location, Dialog, ComponentUtils, $translate) {
|
||||||
|
$scope.realm = realm;
|
||||||
|
$scope.groupList = [
|
||||||
|
{
|
||||||
|
"id" : "realm",
|
||||||
|
"name": $translate.instant('groups'),
|
||||||
|
"subGroups" : []
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
$scope.searchCriteria = '';
|
||||||
|
$scope.currentPage = 1;
|
||||||
|
$scope.currentPageInput = $scope.currentPage;
|
||||||
|
$scope.pageSize = 20;
|
||||||
|
$scope.numberOfPages = 1;
|
||||||
|
$scope.tree = [];
|
||||||
|
|
||||||
|
var refreshGroups = function (search) {
|
||||||
|
console.log('refreshGroups');
|
||||||
|
$scope.currentPageInput = $scope.currentPage;
|
||||||
|
|
||||||
|
var first = ($scope.currentPage * $scope.pageSize) - $scope.pageSize;
|
||||||
|
console.log('first:' + first);
|
||||||
|
var queryParams = {
|
||||||
|
realm : realm.realm,
|
||||||
|
first : first,
|
||||||
|
max : $scope.pageSize
|
||||||
|
};
|
||||||
|
var countParams = {
|
||||||
|
realm : realm.realm,
|
||||||
|
top : 'true'
|
||||||
|
};
|
||||||
|
|
||||||
|
if(angular.isDefined(search) && search !== '') {
|
||||||
|
queryParams.search = search;
|
||||||
|
countParams.search = search;
|
||||||
|
}
|
||||||
|
|
||||||
|
var promiseGetGroups = $q.defer();
|
||||||
|
Groups.query(queryParams, function(entry) {
|
||||||
|
promiseGetGroups.resolve(entry);
|
||||||
|
}, function() {
|
||||||
|
promiseGetGroups.reject($translate.instant('group.fetch.fail', {params: queryParams}));
|
||||||
|
});
|
||||||
|
promiseGetGroups.promise.then(function(groups) {
|
||||||
|
$scope.groupList = [
|
||||||
|
{
|
||||||
|
"id" : "realm",
|
||||||
|
"name": $translate.instant('groups'),
|
||||||
|
"subGroups": ComponentUtils.sortGroups('name', groups)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
if (angular.isDefined(search) && search !== '') {
|
||||||
|
// Add highlight for concrete text match
|
||||||
|
setTimeout(function () {
|
||||||
|
document.querySelectorAll('span').forEach(function (element) {
|
||||||
|
if (element.textContent.indexOf(search) != -1) {
|
||||||
|
angular.element(element).addClass('highlight');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
}, function (failed) {
|
||||||
|
Notifications.error(failed);
|
||||||
|
});
|
||||||
|
|
||||||
|
var promiseCount = $q.defer();
|
||||||
|
console.log('countParams: realm[' + countParams.realm);
|
||||||
|
GroupsCount.query(countParams, function(entry) {
|
||||||
|
promiseCount.resolve(entry);
|
||||||
|
}, function() {
|
||||||
|
promiseCount.reject($translate.instant('group.fetch.fail', {params: countParams}));
|
||||||
|
});
|
||||||
|
promiseCount.promise.then(function(entry) {
|
||||||
|
if(angular.isDefined(entry.count) && entry.count > $scope.pageSize) {
|
||||||
|
$scope.numberOfPages = Math.ceil(entry.count/$scope.pageSize);
|
||||||
|
} else {
|
||||||
|
$scope.numberOfPages = 1;
|
||||||
|
}
|
||||||
|
}, function (failed) {
|
||||||
|
Notifications.error(failed);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
refreshGroups();
|
||||||
|
|
||||||
|
$scope.$watch('currentPage', function(newValue, oldValue) {
|
||||||
|
if(parseInt(newValue, 10) !== oldValue) {
|
||||||
|
refreshGroups($scope.searchCriteria);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.clearSearch = function() {
|
||||||
|
$scope.searchCriteria = '';
|
||||||
|
if (parseInt($scope.currentPage, 10) === 1) {
|
||||||
|
refreshGroups();
|
||||||
|
} else {
|
||||||
|
$scope.currentPage = 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.searchGroup = function() {
|
||||||
|
if (parseInt($scope.currentPage, 10) === 1) {
|
||||||
|
refreshGroups($scope.searchCriteria);
|
||||||
|
} else {
|
||||||
|
$scope.currentPage = 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.edit = function(selected) {
|
||||||
|
if (selected.id === 'realm') return;
|
||||||
|
$location.url("/realms/" + realm.realm + "/groups/" + selected.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.cut = function(selected) {
|
||||||
|
$scope.cutNode = selected;
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.isDisabled = function() {
|
||||||
|
if (!$scope.tree.currentNode) return true;
|
||||||
|
return $scope.tree.currentNode.id === 'realm';
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.paste = function(selected) {
|
||||||
|
if (selected === null) return;
|
||||||
|
if ($scope.cutNode === null) return;
|
||||||
|
if (selected.id === $scope.cutNode.id) return;
|
||||||
|
if (selected.id === 'realm') {
|
||||||
|
Groups.save({realm: realm.realm}, {id:$scope.cutNode.id}, function() {
|
||||||
|
$route.reload();
|
||||||
|
Notifications.success($translate.instant('group.move.success'));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
GroupChildren.save({realm: realm.realm, groupId: selected.id}, {id:$scope.cutNode.id}, function() {
|
||||||
|
$route.reload();
|
||||||
|
Notifications.success($translate.instant('group.move.success'));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.remove = function(selected) {
|
||||||
|
if (selected === null) return;
|
||||||
|
Dialog.confirmWithButtonText(
|
||||||
|
$translate.instant('group.remove.confirm.title', {name: selected.name}),
|
||||||
|
$translate.instant('group.remove.confirm.message', {name: selected.name}),
|
||||||
|
$translate.instant('dialogs.delete.confirm'),
|
||||||
|
function() {
|
||||||
|
Group.remove({ realm: realm.realm, groupId : selected.id }, function() {
|
||||||
|
$route.reload();
|
||||||
|
Notifications.success($translate.instant('group.remove.success'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.createGroup = function(selected) {
|
||||||
|
var parent = 'realm';
|
||||||
|
if (selected) {
|
||||||
|
parent = selected.id;
|
||||||
|
}
|
||||||
|
$location.url("/create/group/" + realm.realm + '/parent/' + parent);
|
||||||
|
|
||||||
|
};
|
||||||
|
var isLeaf = function(node) {
|
||||||
|
return node.id !== "realm" && (!node.subGroups || node.subGroups.length === 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.getGroupClass = function(node) {
|
||||||
|
if (node.id === "realm") {
|
||||||
|
return 'pficon pficon-users';
|
||||||
|
}
|
||||||
|
if (isLeaf(node)) {
|
||||||
|
return 'normal';
|
||||||
|
}
|
||||||
|
if (node.subGroups.length && node.collapsed) return 'collapsed';
|
||||||
|
if (node.subGroups.length && !node.collapsed) return 'expanded';
|
||||||
|
return 'collapsed';
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.getSelectedClass = function(node) {
|
||||||
|
if (node.selected) {
|
||||||
|
return 'selected';
|
||||||
|
} else if ($scope.cutNode && $scope.cutNode.id === node.id) {
|
||||||
|
return 'cut';
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
module.controller('GroupCreateCtrl', function($scope, $route, realm, parentId, Groups, Group, GroupChildren, Notifications, $location, $translate) {
|
||||||
|
$scope.realm = realm;
|
||||||
|
$scope.group = {};
|
||||||
|
$scope.save = function() {
|
||||||
|
console.log('save!!!');
|
||||||
|
if (parentId === 'realm') {
|
||||||
|
console.log('realm');
|
||||||
|
Groups.save({realm: realm.realm}, $scope.group, function(data, headers) {
|
||||||
|
var l = headers().location;
|
||||||
|
|
||||||
|
|
||||||
|
var id = l.substring(l.lastIndexOf("/") + 1);
|
||||||
|
|
||||||
|
$location.url("/realms/" + realm.realm + "/groups/" + id);
|
||||||
|
Notifications.success($translate.instant('group.create.success'));
|
||||||
|
})
|
||||||
|
|
||||||
|
} else {
|
||||||
|
GroupChildren.save({realm: realm.realm, groupId: parentId}, $scope.group, function(data, headers) {
|
||||||
|
var l = headers().location;
|
||||||
|
|
||||||
|
|
||||||
|
var id = l.substring(l.lastIndexOf("/") + 1);
|
||||||
|
|
||||||
|
$location.url("/realms/" + realm.realm + "/groups/" + id);
|
||||||
|
Notifications.success($translate.instant('group.create.success'));
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
$scope.cancel = function() {
|
||||||
|
$location.url("/realms/" + realm.realm + "/groups");
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
module.controller('GroupTabCtrl', function(Dialog, $scope, Current, Group, Notifications, $location, $translate) {
|
||||||
|
$scope.removeGroup = function() {
|
||||||
|
Dialog.confirmWithButtonText(
|
||||||
|
$translate.instant('group.remove.confirm.title', {name: $scope.group.name}),
|
||||||
|
$translate.instant('group.remove.confirm.message', {name: $scope.group.name}),
|
||||||
|
$translate.instant('dialogs.delete.confirm'),
|
||||||
|
function() {
|
||||||
|
Group.remove({
|
||||||
|
realm : Current.realm.realm,
|
||||||
|
groupId : $scope.group.id
|
||||||
|
}, function() {
|
||||||
|
$location.url("/realms/" + Current.realm.realm + "/groups");
|
||||||
|
Notifications.success($translate.instant('group.remove.success'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
module.controller('GroupDetailCtrl', function(Dialog, $scope, realm, group, Group, Notifications, $location, $translate) {
|
||||||
|
$scope.realm = realm;
|
||||||
|
|
||||||
|
if (!group.attributes) {
|
||||||
|
group.attributes = {}
|
||||||
|
}
|
||||||
|
convertAttributeValuesToString(group);
|
||||||
|
|
||||||
|
|
||||||
|
$scope.group = angular.copy(group);
|
||||||
|
|
||||||
|
$scope.changed = false; // $scope.create;
|
||||||
|
$scope.$watch('group', function() {
|
||||||
|
if (!angular.equals($scope.group, group)) {
|
||||||
|
$scope.changed = true;
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
$scope.save = function() {
|
||||||
|
convertAttributeValuesToLists();
|
||||||
|
|
||||||
|
Group.update({
|
||||||
|
realm: realm.realm,
|
||||||
|
groupId: $scope.group.id
|
||||||
|
}, $scope.group, function () {
|
||||||
|
$scope.changed = false;
|
||||||
|
convertAttributeValuesToString($scope.group);
|
||||||
|
group = angular.copy($scope.group);
|
||||||
|
Notifications.success($translate.instant('group.edit.success'));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function convertAttributeValuesToLists() {
|
||||||
|
var attrs = $scope.group.attributes;
|
||||||
|
for (var attribute in attrs) {
|
||||||
|
if (typeof attrs[attribute] === "string") {
|
||||||
|
attrs[attribute] = attrs[attribute].split("##");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertAttributeValuesToString(group) {
|
||||||
|
var attrs = group.attributes;
|
||||||
|
for (var attribute in attrs) {
|
||||||
|
if (typeof attrs[attribute] === "object") {
|
||||||
|
attrs[attribute] = attrs[attribute].join("##");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.reset = function() {
|
||||||
|
$scope.group = angular.copy(group);
|
||||||
|
$scope.changed = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.cancel = function() {
|
||||||
|
$location.url("/realms/" + realm.realm + "/groups");
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.addAttribute = function() {
|
||||||
|
$scope.group.attributes[$scope.newAttribute.key] = $scope.newAttribute.value;
|
||||||
|
delete $scope.newAttribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.removeAttribute = function(key) {
|
||||||
|
delete $scope.group.attributes[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.controller('GroupRoleMappingCtrl', function($scope, $http, $route, realm, group, clients, client, Client, Notifications, GroupRealmRoleMapping,
|
||||||
|
GroupClientRoleMapping, GroupAvailableRealmRoleMapping, GroupAvailableClientRoleMapping,
|
||||||
|
GroupCompositeRealmRoleMapping, GroupCompositeClientRoleMapping, $translate) {
|
||||||
|
$scope.realm = realm;
|
||||||
|
$scope.group = group;
|
||||||
|
$scope.selectedRealmRoles = [];
|
||||||
|
$scope.selectedRealmMappings = [];
|
||||||
|
$scope.realmMappings = [];
|
||||||
|
$scope.clients = clients;
|
||||||
|
$scope.client = client;
|
||||||
|
$scope.clientRoles = [];
|
||||||
|
$scope.clientComposite = [];
|
||||||
|
$scope.selectedClientRoles = [];
|
||||||
|
$scope.selectedClientMappings = [];
|
||||||
|
$scope.clientMappings = [];
|
||||||
|
$scope.dummymodel = [];
|
||||||
|
|
||||||
|
$scope.realmMappings = GroupRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
|
$scope.realmRoles = GroupAvailableRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
|
$scope.realmComposite = GroupCompositeRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
|
|
||||||
|
$scope.addRealmRole = function() {
|
||||||
|
$scope.selectedRealmRolesToAdd = JSON.parse('[' + $scope.selectedRealmRoles + ']');
|
||||||
|
$scope.selectedRealmRoles = [];
|
||||||
|
$http.post(authUrl + '/admin/realms/' + realm.realm + '/groups/' + group.id + '/role-mappings/realm',
|
||||||
|
$scope.selectedRealmRolesToAdd).then(function() {
|
||||||
|
$scope.realmMappings = GroupRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
|
$scope.realmRoles = GroupAvailableRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
|
$scope.realmComposite = GroupCompositeRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
|
$scope.selectedRealmMappings = [];
|
||||||
|
$scope.selectRealmRoles = [];
|
||||||
|
if ($scope.selectedClient) {
|
||||||
|
console.log('load available');
|
||||||
|
$scope.clientComposite = GroupCompositeClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.selectedClient.id});
|
||||||
|
$scope.clientRoles = GroupAvailableClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.selectedClient.id});
|
||||||
|
$scope.clientMappings = GroupClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.selectedClient.id});
|
||||||
|
$scope.selectedClientRoles = [];
|
||||||
|
$scope.selectedClientMappings = [];
|
||||||
|
}
|
||||||
|
$scope.selectedRealmRolesToAdd = [];
|
||||||
|
Notifications.success($translate.instant('group.roles.add.success'));
|
||||||
|
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.deleteRealmRole = function() {
|
||||||
|
$scope.selectedRealmMappingsToRemove = JSON.parse('[' + $scope.selectedRealmMappings + ']');
|
||||||
|
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/groups/' + group.id + '/role-mappings/realm',
|
||||||
|
{data : $scope.selectedRealmMappingsToRemove, headers : {"content-type" : "application/json"}}).then(function() {
|
||||||
|
$scope.realmMappings = GroupRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
|
$scope.realmRoles = GroupAvailableRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
|
$scope.realmComposite = GroupCompositeRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
|
$scope.selectedRealmMappings = [];
|
||||||
|
$scope.selectRealmRoles = [];
|
||||||
|
if ($scope.selectedClient) {
|
||||||
|
console.log('load available');
|
||||||
|
$scope.clientComposite = GroupCompositeClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.selectedClient.id});
|
||||||
|
$scope.clientRoles = GroupAvailableClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.selectedClient.id});
|
||||||
|
$scope.clientMappings = GroupClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.selectedClient.id});
|
||||||
|
$scope.selectedClientRoles = [];
|
||||||
|
$scope.selectedClientMappings = [];
|
||||||
|
}
|
||||||
|
$scope.selectedRealmMappingsToRemove = [];
|
||||||
|
Notifications.success($translate.instant('group.roles.remove.success'));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.addClientRole = function() {
|
||||||
|
$scope.selectedClientRolesToAdd = JSON.parse('[' + $scope.selectedClientRoles + ']');
|
||||||
|
$http.post(authUrl + '/admin/realms/' + realm.realm + '/groups/' + group.id + '/role-mappings/clients/' + $scope.selectedClient.id,
|
||||||
|
$scope.selectedClientRolesToAdd).then(function() {
|
||||||
|
$scope.clientMappings = GroupClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.selectedClient.id});
|
||||||
|
$scope.clientRoles = GroupAvailableClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.selectedClient.id});
|
||||||
|
$scope.clientComposite = GroupCompositeClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.selectedClient.id});
|
||||||
|
$scope.selectedClientRoles = [];
|
||||||
|
$scope.selectedClientMappings = [];
|
||||||
|
$scope.realmComposite = GroupCompositeRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
|
$scope.realmRoles = GroupAvailableRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
|
$scope.selectedClientRolesToAdd = [];
|
||||||
|
Notifications.success($translate.instant('group.roles.add.success'));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.deleteClientRole = function() {
|
||||||
|
$scope.selectedClientMappingsToRemove = JSON.parse('[' + $scope.selectedClientMappings + ']');
|
||||||
|
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/groups/' + group.id + '/role-mappings/clients/' + $scope.selectedClient.id,
|
||||||
|
{data : $scope.selectedClientMappingsToRemove, headers : {"content-type" : "application/json"}}).then(function() {
|
||||||
|
$scope.clientMappings = GroupClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.selectedClient.id});
|
||||||
|
$scope.clientRoles = GroupAvailableClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.selectedClient.id});
|
||||||
|
$scope.clientComposite = GroupCompositeClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.selectedClient.id});
|
||||||
|
$scope.selectedClientRoles = [];
|
||||||
|
$scope.selectedClientMappings = [];
|
||||||
|
$scope.realmComposite = GroupCompositeRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
|
$scope.realmRoles = GroupAvailableRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
|
$scope.selectedClientMappingsToRemove = [];
|
||||||
|
Notifications.success($translate.instant('group.roles.remove.success'));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
$scope.changeClient = function(client) {
|
||||||
|
$scope.selectedClient = client;
|
||||||
|
if (!client || !client.id) {
|
||||||
|
$scope.selectedClient = null;
|
||||||
|
$scope.clientRoles = null;
|
||||||
|
$scope.clientMappings = null;
|
||||||
|
$scope.clientComposite = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($scope.selectedClient) {
|
||||||
|
$scope.clientComposite = GroupCompositeClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.selectedClient.id});
|
||||||
|
$scope.clientRoles = GroupAvailableClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.selectedClient.id});
|
||||||
|
$scope.clientMappings = GroupClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.selectedClient.id});
|
||||||
|
}
|
||||||
|
$scope.selectedClientRoles = [];
|
||||||
|
$scope.selectedClientMappings = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
clientSelectControl($scope, $route.current.params.realm, Client);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
module.controller('GroupMembersCtrl', function($scope, realm, group, GroupMembership) {
|
||||||
|
$scope.realm = realm;
|
||||||
|
$scope.page = 0;
|
||||||
|
$scope.group = group;
|
||||||
|
|
||||||
|
$scope.query = {
|
||||||
|
realm: realm.realm,
|
||||||
|
groupId: group.id,
|
||||||
|
max : 5,
|
||||||
|
first : 0
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
$scope.firstPage = function() {
|
||||||
|
$scope.query.first = 0;
|
||||||
|
$scope.searchQuery();
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.previousPage = function() {
|
||||||
|
$scope.query.first -= parseInt($scope.query.max);
|
||||||
|
if ($scope.query.first < 0) {
|
||||||
|
$scope.query.first = 0;
|
||||||
|
}
|
||||||
|
$scope.searchQuery();
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.nextPage = function() {
|
||||||
|
$scope.query.first += parseInt($scope.query.max);
|
||||||
|
$scope.searchQuery();
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.searchQuery = function() {
|
||||||
|
console.log("query.search: " + $scope.query.search);
|
||||||
|
$scope.searchLoaded = false;
|
||||||
|
|
||||||
|
$scope.users = GroupMembership.query($scope.query, function() {
|
||||||
|
console.log('search loaded');
|
||||||
|
$scope.searchLoaded = true;
|
||||||
|
$scope.lastSearch = $scope.query.search;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.searchQuery();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
module.controller('DefaultGroupsCtrl', function($scope, $q, realm, Groups, GroupsCount, DefaultGroups, Notifications, $translate) {
|
||||||
|
$scope.realm = realm;
|
||||||
|
$scope.groupList = [];
|
||||||
|
$scope.selectedGroup = null;
|
||||||
|
$scope.tree = [];
|
||||||
|
|
||||||
|
$scope.searchCriteria = '';
|
||||||
|
$scope.currentPage = 1;
|
||||||
|
$scope.currentPageInput = $scope.currentPage;
|
||||||
|
$scope.pageSize = 20;
|
||||||
|
$scope.numberOfPages = 1;
|
||||||
|
|
||||||
|
var refreshDefaultGroups = function () {
|
||||||
|
DefaultGroups.query({realm: realm.realm}, function(data) {
|
||||||
|
$scope.defaultGroups = data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var refreshAvailableGroups = function (search) {
|
||||||
|
var first = ($scope.currentPage * $scope.pageSize) - $scope.pageSize;
|
||||||
|
$scope.currentPageInput = $scope.currentPage;
|
||||||
|
var queryParams = {
|
||||||
|
realm : realm.realm,
|
||||||
|
first : first,
|
||||||
|
max : $scope.pageSize
|
||||||
|
};
|
||||||
|
var countParams = {
|
||||||
|
realm : realm.realm,
|
||||||
|
top : 'true'
|
||||||
|
};
|
||||||
|
|
||||||
|
if(angular.isDefined(search) && search !== '') {
|
||||||
|
queryParams.search = search;
|
||||||
|
countParams.search = search;
|
||||||
|
}
|
||||||
|
|
||||||
|
var promiseGetGroups = $q.defer();
|
||||||
|
Groups.query(queryParams, function(entry) {
|
||||||
|
promiseGetGroups.resolve(entry);
|
||||||
|
}, function() {
|
||||||
|
promiseGetGroups.reject($translate.instant('group.fetch.fail', {params: queryParams}));
|
||||||
|
});
|
||||||
|
promiseGetGroups.promise.then(function(groups) {
|
||||||
|
$scope.groupList = groups;
|
||||||
|
}, function (failed) {
|
||||||
|
Notifications.success(failed);
|
||||||
|
});
|
||||||
|
|
||||||
|
var promiseCount = $q.defer();
|
||||||
|
GroupsCount.query(countParams, function(entry) {
|
||||||
|
promiseCount.resolve(entry);
|
||||||
|
}, function() {
|
||||||
|
promiseCount.reject($translate.instant('group.fetch.fail', {params: countParams}));
|
||||||
|
});
|
||||||
|
promiseCount.promise.then(function(entry) {
|
||||||
|
if(angular.isDefined(entry.count) && entry.count > $scope.pageSize) {
|
||||||
|
$scope.numberOfPages = Math.ceil(entry.count/$scope.pageSize);
|
||||||
|
}
|
||||||
|
}, function (failed) {
|
||||||
|
Notifications.success(failed);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
refreshAvailableGroups();
|
||||||
|
|
||||||
|
$scope.$watch('currentPage', function(newValue, oldValue) {
|
||||||
|
if(parseInt(newValue, 10) !== parseInt(oldValue, 10)) {
|
||||||
|
refreshAvailableGroups($scope.searchCriteria);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.clearSearch = function() {
|
||||||
|
$scope.searchCriteria = '';
|
||||||
|
if (parseInt($scope.currentPage, 10) === 1) {
|
||||||
|
refreshAvailableGroups();
|
||||||
|
} else {
|
||||||
|
$scope.currentPage = 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.searchGroup = function() {
|
||||||
|
if (parseInt($scope.currentPage, 10) === 1) {
|
||||||
|
refreshAvailableGroups($scope.searchCriteria);
|
||||||
|
} else {
|
||||||
|
$scope.currentPage = 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
refreshDefaultGroups();
|
||||||
|
|
||||||
|
$scope.addDefaultGroup = function() {
|
||||||
|
if (!$scope.tree.currentNode) {
|
||||||
|
Notifications.error($translate.instant('group.default.add.error'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultGroups.update({realm: realm.realm, groupId: $scope.tree.currentNode.id}, function() {
|
||||||
|
refreshDefaultGroups();
|
||||||
|
Notifications.success($translate.instant('group.default.add.success'));
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.removeDefaultGroup = function() {
|
||||||
|
DefaultGroups.remove({realm: realm.realm, groupId: $scope.selectedGroup.id}, function() {
|
||||||
|
refreshDefaultGroups();
|
||||||
|
Notifications.success($translate.instant('group.default.remove.success'));
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var isLeaf = function(node) {
|
||||||
|
return node.id !== "realm" && (!node.subGroups || node.subGroups.length === 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.getGroupClass = function(node) {
|
||||||
|
if (node.id === "realm") {
|
||||||
|
return 'pficon pficon-users';
|
||||||
|
}
|
||||||
|
if (isLeaf(node)) {
|
||||||
|
return 'normal';
|
||||||
|
}
|
||||||
|
if (node.subGroups.length && node.collapsed) return 'collapsed';
|
||||||
|
if (node.subGroups.length && !node.collapsed) return 'expanded';
|
||||||
|
return 'collapsed';
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.getSelectedClass = function(node) {
|
||||||
|
if (node.selected) {
|
||||||
|
return 'selected';
|
||||||
|
} else if ($scope.cutNode && $scope.cutNode.id === node.id) {
|
||||||
|
return 'cut';
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
3229
base/admin/resources/js/controllers/realm.js
Normal file
3229
base/admin/resources/js/controllers/realm.js
Normal file
File diff suppressed because it is too large
Load Diff
48
base/admin/resources/js/controllers/roles.js
Normal file
48
base/admin/resources/js/controllers/roles.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
module.controller('RoleMembersCtrl', function($scope, realm, role, RoleMembership, Dialog, Notifications, $location, RealmRoleRemover) {
|
||||||
|
$scope.realm = realm;
|
||||||
|
$scope.page = 0;
|
||||||
|
$scope.role = role;
|
||||||
|
|
||||||
|
$scope.query = {
|
||||||
|
realm: realm.realm,
|
||||||
|
role: role.name,
|
||||||
|
max : 5,
|
||||||
|
first : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.remove = function() {
|
||||||
|
RealmRoleRemover.remove($scope.role, realm, Dialog, $location, Notifications);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.firstPage = function() {
|
||||||
|
$scope.query.first = 0;
|
||||||
|
$scope.searchQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.previousPage = function() {
|
||||||
|
$scope.query.first -= parseInt($scope.query.max);
|
||||||
|
if ($scope.query.first < 0) {
|
||||||
|
$scope.query.first = 0;
|
||||||
|
}
|
||||||
|
$scope.searchQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.nextPage = function() {
|
||||||
|
$scope.query.first += parseInt($scope.query.max);
|
||||||
|
$scope.searchQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.searchQuery = function() {
|
||||||
|
console.log("query.search: " + $scope.query.search);
|
||||||
|
$scope.searchLoaded = false;
|
||||||
|
|
||||||
|
$scope.users = RoleMembership.query($scope.query, function() {
|
||||||
|
console.log('search loaded');
|
||||||
|
$scope.searchLoaded = true;
|
||||||
|
$scope.lastSearch = $scope.query.search;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.searchQuery();
|
||||||
|
|
||||||
|
});
|
2044
base/admin/resources/js/controllers/users.js
Executable file
2044
base/admin/resources/js/controllers/users.js
Executable file
File diff suppressed because it is too large
Load Diff
570
base/admin/resources/js/loaders.js
Executable file
570
base/admin/resources/js/loaders.js
Executable file
@ -0,0 +1,570 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var module = angular.module('keycloak.loaders', [ 'keycloak.services', 'ngResource' ]);
|
||||||
|
|
||||||
|
module.factory('Loader', function($q) {
|
||||||
|
var loader = {};
|
||||||
|
loader.get = function(service, id) {
|
||||||
|
return function() {
|
||||||
|
var i = id && id();
|
||||||
|
var delay = $q.defer();
|
||||||
|
service.get(i, function(entry) {
|
||||||
|
delay.resolve(entry);
|
||||||
|
}, function() {
|
||||||
|
delay.reject('Unable to fetch ' + i);
|
||||||
|
});
|
||||||
|
return delay.promise;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
loader.query = function(service, id) {
|
||||||
|
return function() {
|
||||||
|
var i = id && id();
|
||||||
|
var delay = $q.defer();
|
||||||
|
service.query(i, function(entry) {
|
||||||
|
delay.resolve(entry);
|
||||||
|
}, function() {
|
||||||
|
delay.reject('Unable to fetch ' + i);
|
||||||
|
});
|
||||||
|
return delay.promise;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return loader;
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('RealmListLoader', function(Loader, Realm, $q) {
|
||||||
|
return Loader.get(Realm);
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ServerInfoLoader', function(Loader, ServerInfo) {
|
||||||
|
return function() {
|
||||||
|
return ServerInfo.promise;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('RealmLoader', function(Loader, Realm, $route, $q) {
|
||||||
|
return Loader.get(Realm, function() {
|
||||||
|
return {
|
||||||
|
id : $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('RealmKeysLoader', function(Loader, RealmKeys, $route, $q) {
|
||||||
|
return Loader.get(RealmKeys, function() {
|
||||||
|
return {
|
||||||
|
id : $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('RealmSpecificLocalesLoader', function(Loader, RealmSpecificLocales, $route, $q) {
|
||||||
|
return Loader.get(RealmSpecificLocales, function() {
|
||||||
|
return {
|
||||||
|
id : $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('RealmSpecificlocalizationTextLoader', function(Loader, RealmSpecificLocalizationText, $route, $q) {
|
||||||
|
return Loader.get(RealmSpecificLocalizationText, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
locale : $route.current.params.locale,
|
||||||
|
key: $route.current.params.key
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('RealmEventsConfigLoader', function(Loader, RealmEventsConfig, $route, $q) {
|
||||||
|
return Loader.get(RealmEventsConfig, function() {
|
||||||
|
return {
|
||||||
|
id : $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('UserListLoader', function(Loader, User, $route, $q) {
|
||||||
|
return Loader.query(User, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('RequiredActionsListLoader', function(Loader, RequiredActions, $route, $q) {
|
||||||
|
return Loader.query(RequiredActions, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('UnregisteredRequiredActionsListLoader', function(Loader, UnregisteredRequiredActions, $route, $q) {
|
||||||
|
return Loader.query(UnregisteredRequiredActions, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('RealmSessionStatsLoader', function(Loader, RealmSessionStats, $route, $q) {
|
||||||
|
return Loader.get(RealmSessionStats, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('RealmClientSessionStatsLoader', function(Loader, RealmClientSessionStats, $route, $q) {
|
||||||
|
return Loader.query(RealmClientSessionStats, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ClientProtocolMapperLoader', function(Loader, ClientProtocolMapper, $route, $q) {
|
||||||
|
return Loader.get(ClientProtocolMapper, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
client : $route.current.params.client,
|
||||||
|
id: $route.current.params.id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ClientScopeProtocolMapperLoader', function(Loader, ClientScopeProtocolMapper, $route, $q) {
|
||||||
|
return Loader.get(ClientScopeProtocolMapper, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
clientScope : $route.current.params.clientScope,
|
||||||
|
id: $route.current.params.id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('UserLoader', function(Loader, User, $route, $q) {
|
||||||
|
return Loader.get(User, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
userId : $route.current.params.user
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ComponentLoader', function(Loader, Components, $route, $q) {
|
||||||
|
return Loader.get(Components, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
componentId: $route.current.params.componentId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('LDAPMapperLoader', function(Loader, Components, $route, $q) {
|
||||||
|
return Loader.get(Components, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
componentId: $route.current.params.mapperId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ComponentsLoader', function(Loader, Components, $route, $q) {
|
||||||
|
var componentsLoader = {};
|
||||||
|
|
||||||
|
componentsLoader.loadComponents = function(parent, componentType) {
|
||||||
|
return Loader.query(Components, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
parent : parent,
|
||||||
|
type: componentType
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
|
||||||
|
return componentsLoader;
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('SubComponentTypesLoader', function(Loader, SubComponentTypes, $route, $q) {
|
||||||
|
var componentsLoader = {};
|
||||||
|
|
||||||
|
componentsLoader.loadComponents = function(parent, componentType) {
|
||||||
|
return Loader.query(SubComponentTypes, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
componentId : parent,
|
||||||
|
type: componentType
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
|
||||||
|
return componentsLoader;
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('UserSessionStatsLoader', function(Loader, UserSessionStats, $route, $q) {
|
||||||
|
return Loader.get(UserSessionStats, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
user : $route.current.params.user
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('UserSessionsLoader', function(Loader, UserSessions, $route, $q) {
|
||||||
|
return Loader.query(UserSessions, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
user : $route.current.params.user
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('UserOfflineSessionsLoader', function(Loader, UserOfflineSessions, $route, $q) {
|
||||||
|
return Loader.query(UserOfflineSessions, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
user : $route.current.params.user,
|
||||||
|
client : $route.current.params.client
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('UserFederatedIdentityLoader', function(Loader, UserFederatedIdentities, $route, $q) {
|
||||||
|
return Loader.query(UserFederatedIdentities, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
user : $route.current.params.user
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('UserConsentsLoader', function(Loader, UserConsents, $route, $q) {
|
||||||
|
return Loader.query(UserConsents, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
user : $route.current.params.user
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module.factory('RoleLoader', function(Loader, RoleById, $route, $q) {
|
||||||
|
return Loader.get(RoleById, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
role : $route.current.params.role
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('RoleListLoader', function(Loader, Role, $route, $q) {
|
||||||
|
return Loader.query(Role, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ClientRoleLoader', function(Loader, RoleById, $route, $q) {
|
||||||
|
return Loader.get(RoleById, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
client : $route.current.params.client,
|
||||||
|
role : $route.current.params.role
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ClientSessionStatsLoader', function(Loader, ClientSessionStats, $route, $q) {
|
||||||
|
return Loader.get(ClientSessionStats, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
client : $route.current.params.client
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ClientSessionCountLoader', function(Loader, ClientSessionCount, $route, $q) {
|
||||||
|
return Loader.get(ClientSessionCount, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
client : $route.current.params.client
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ClientOfflineSessionCountLoader', function(Loader, ClientOfflineSessionCount, $route, $q) {
|
||||||
|
return Loader.get(ClientOfflineSessionCount, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
client : $route.current.params.client
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ClientDefaultClientScopesLoader', function(Loader, ClientDefaultClientScopes, $route, $q) {
|
||||||
|
return Loader.query(ClientDefaultClientScopes, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
client : $route.current.params.client
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ClientOptionalClientScopesLoader', function(Loader, ClientOptionalClientScopes, $route, $q) {
|
||||||
|
return Loader.query(ClientOptionalClientScopes, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
client : $route.current.params.client
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ClientLoader', function(Loader, Client, $route, $q) {
|
||||||
|
return Loader.get(Client, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
client : $route.current.params.client
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ClientListLoader', function(Loader, Client, $route, $q) {
|
||||||
|
return Loader.query(Client, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
first: 0,
|
||||||
|
max: 20
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ClientScopeLoader', function(Loader, ClientScope, $route, $q) {
|
||||||
|
return Loader.get(ClientScope, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
clientScope : $route.current.params.clientScope
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ClientScopeListLoader', function(Loader, ClientScope, $route, $q) {
|
||||||
|
return Loader.query(ClientScope, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('RealmDefaultClientScopesLoader', function(Loader, RealmDefaultClientScopes, $route, $q) {
|
||||||
|
return Loader.query(RealmDefaultClientScopes, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('RealmOptionalClientScopesLoader', function(Loader, RealmOptionalClientScopes, $route, $q) {
|
||||||
|
return Loader.query(RealmOptionalClientScopes, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ClientServiceAccountUserLoader', function(Loader, ClientServiceAccountUser, $route, $q) {
|
||||||
|
return Loader.get(ClientServiceAccountUser, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
client : $route.current.params.client
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
module.factory('RoleMappingLoader', function(Loader, RoleMapping, $route, $q) {
|
||||||
|
var realm = $route.current.params.realm || $route.current.params.client;
|
||||||
|
|
||||||
|
return Loader.query(RoleMapping, function() {
|
||||||
|
return {
|
||||||
|
realm : realm,
|
||||||
|
role : $route.current.params.role
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('IdentityProviderLoader', function(Loader, IdentityProvider, $route, $q) {
|
||||||
|
return Loader.get(IdentityProvider, function () {
|
||||||
|
return {
|
||||||
|
realm: $route.current.params.realm,
|
||||||
|
alias: $route.current.params.alias
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('IdentityProviderFactoryLoader', function(Loader, IdentityProviderFactory, $route, $q) {
|
||||||
|
return Loader.get(IdentityProviderFactory, function () {
|
||||||
|
return {
|
||||||
|
realm: $route.current.params.realm,
|
||||||
|
provider_id: $route.current.params.provider_id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('IdentityProviderMapperTypesLoader', function(Loader, IdentityProviderMapperTypes, $route, $q) {
|
||||||
|
return Loader.get(IdentityProviderMapperTypes, function () {
|
||||||
|
return {
|
||||||
|
realm: $route.current.params.realm,
|
||||||
|
alias: $route.current.params.alias
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('IdentityProviderMappersLoader', function(Loader, IdentityProviderMappers, $route, $q) {
|
||||||
|
return Loader.query(IdentityProviderMappers, function () {
|
||||||
|
return {
|
||||||
|
realm: $route.current.params.realm,
|
||||||
|
alias: $route.current.params.alias
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('IdentityProviderMapperLoader', function(Loader, IdentityProviderMapper, $route, $q) {
|
||||||
|
return Loader.get(IdentityProviderMapper, function () {
|
||||||
|
return {
|
||||||
|
realm: $route.current.params.realm,
|
||||||
|
alias: $route.current.params.alias,
|
||||||
|
mapperId: $route.current.params.mapperId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('AuthenticationFlowsLoader', function(Loader, AuthenticationFlows, $route, $q) {
|
||||||
|
return Loader.query(AuthenticationFlows, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
flow: ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('AuthenticationFormProvidersLoader', function(Loader, AuthenticationFormProviders, $route, $q) {
|
||||||
|
return Loader.query(AuthenticationFormProviders, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('AuthenticationFormActionProvidersLoader', function(Loader, AuthenticationFormActionProviders, $route, $q) {
|
||||||
|
return Loader.query(AuthenticationFormActionProviders, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('AuthenticatorProvidersLoader', function(Loader, AuthenticatorProviders, $route, $q) {
|
||||||
|
return Loader.query(AuthenticatorProviders, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ClientAuthenticatorProvidersLoader', function(Loader, ClientAuthenticatorProviders, $route, $q) {
|
||||||
|
return Loader.query(ClientAuthenticatorProviders, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('AuthenticationFlowLoader', function(Loader, AuthenticationFlows, $route, $q) {
|
||||||
|
return Loader.get(AuthenticationFlows, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
flow: $route.current.params.flow
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('AuthenticationConfigDescriptionLoader', function(Loader, AuthenticationConfigDescription, $route, $q) {
|
||||||
|
return Loader.get(AuthenticationConfigDescription, function () {
|
||||||
|
return {
|
||||||
|
realm: $route.current.params.realm,
|
||||||
|
provider: $route.current.params.provider
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('PerClientAuthenticationConfigDescriptionLoader', function(Loader, PerClientAuthenticationConfigDescription, $route, $q) {
|
||||||
|
return Loader.get(PerClientAuthenticationConfigDescription, function () {
|
||||||
|
return {
|
||||||
|
realm: $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ExecutionIdLoader', function($route) {
|
||||||
|
return function() { return $route.current.params.executionId; };
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('AuthenticationConfigLoader', function(Loader, AuthenticationConfig, $route, $q) {
|
||||||
|
return Loader.get(AuthenticationConfig, function () {
|
||||||
|
return {
|
||||||
|
realm: $route.current.params.realm,
|
||||||
|
config: $route.current.params.config
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('GroupListLoader', function(Loader, Groups, $route, $q) {
|
||||||
|
return Loader.query(Groups, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('GroupCountLoader', function(Loader, GroupsCount, $route, $q) {
|
||||||
|
return Loader.query(GroupsCount, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
top : true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('GroupLoader', function(Loader, Group, $route, $q) {
|
||||||
|
return Loader.get(Group, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
groupId : $route.current.params.group
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ClientInitialAccessLoader', function(Loader, ClientInitialAccess, $route) {
|
||||||
|
return Loader.query(ClientInitialAccess, function() {
|
||||||
|
return {
|
||||||
|
realm: $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('ClientRegistrationPolicyProvidersLoader', function(Loader, ClientRegistrationPolicyProviders, $route) {
|
||||||
|
return Loader.query(ClientRegistrationPolicyProviders, function() {
|
||||||
|
return {
|
||||||
|
realm: $route.current.params.realm
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
2225
base/admin/resources/js/services.js
Executable file
2225
base/admin/resources/js/services.js
Executable file
File diff suppressed because it is too large
Load Diff
83
base/admin/resources/partials/authentication-flow-bindings.html
Executable file
83
base/admin/resources/partials/authentication-flow-bindings.html
Executable file
@ -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>
|
72
base/admin/resources/partials/authentication-flows.html
Executable file
72
base/admin/resources/partials/authentication-flows.html
Executable file
@ -0,0 +1,72 @@
|
|||||||
|
<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="editFlow(flow)">{{:: 'edit-flow' | 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>
|
||||||
|
<i data-ng-hide="!execution.authenticationFlow" class="fa fa-question-circle text-muted" tooltip-trigger="mouseover mouseout" tooltip="{{execution.description}}" tooltip-placement="right"> </i>
|
||||||
|
</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-hide="flow.builtIn || !execution.authenticationFlow"><a href="" ng-click="editExecutionFlow(execution)">{{:: 'edit-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>
|
52
base/admin/resources/partials/authenticator-config.html
Executable file
52
base/admin/resources/partials/authenticator-config.html
Executable file
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -0,0 +1,126 @@
|
|||||||
|
<!--
|
||||||
|
~ JBoss, Home of Professional Open Source.
|
||||||
|
~ Copyright 2021 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-client-scope-policy' | translate}}</li>
|
||||||
|
<li data-ng-hide="create">{{:: 'client-scopes' | translate}}</li>
|
||||||
|
<li data-ng-hide="create">{{originalPolicy.name}}</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<h1 data-ng-show="create">{{:: 'authz-add-client-scope-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="clientScopes">{{:: 'client-scopes' | translate}} <span
|
||||||
|
class="required">*</span></label>
|
||||||
|
|
||||||
|
<div class="col-md-4">
|
||||||
|
<select ui-select2="{ minimumInputLength: 1}" id="clientScopes" data-ng-model="selectedClientScope"
|
||||||
|
data-ng-change="selectClientScope(selectedClientScope);"
|
||||||
|
data-placeholder="{{:: 'select-a-client-scope' | translate}}..."
|
||||||
|
ng-options="clientScope as clientScope.name for clientScope in clientScopes"
|
||||||
|
data-ng-required="selectedClientScopes.length == 0">
|
||||||
|
<option></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<kc-tooltip>{{:: 'authz-policy-client-scope-client-scopes.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">
|
||||||
|
<table class="table table-striped table-bordered" id="selected-client-scopes">
|
||||||
|
<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="clientScope in selectedClientScopes | orderBy:'name'">
|
||||||
|
<td>{{clientScope.name}}</td>
|
||||||
|
<td><input type="checkbox" ng-model="clientScope.required" id="{{clientScope.id}}"></td>
|
||||||
|
<td class="kc-action-cell">
|
||||||
|
<button class="btn btn-default btn-block btn-sm" ng-click="removeFromList(clientScope);">{{::
|
||||||
|
'remove' | translate}}</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr data-ng-show="!selectedClientScopes.length">
|
||||||
|
<td class="text-muted" colspan="3">{{:: 'authz-no-client-scopes-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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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 Permissions</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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
114
base/admin/resources/partials/brute-force.html
Executable file
114
base/admin/resources/partials/brute-force.html
Executable file
@ -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>
|
62
base/admin/resources/partials/ciba-policy.html
Normal file
62
base/admin/resources/partials/ciba-policy.html
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<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="tokendelivery" class="col-md-2 control-label"><span class="required">*</span>{{:: 'ciba-backchannel-tokendelivery-mode' | translate}}</label>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div>
|
||||||
|
<select id="tokendelivery" ng-model="realm.attributes.cibaBackchannelTokenDeliveryMode" class="form-control">
|
||||||
|
<option value="poll">Poll</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'ciba-backchannel-tokendelivery-mode.tooltip' | translate}}</kc-tooltip>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="expiresin" class="col-md-2 control-label"><span class="required">*</span>{{:: 'ciba-expires-in' | translate}}</label>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div>
|
||||||
|
<input id="expiresin" type="number" min="10" max="600" string-to-number ng-model="realm.attributes.cibaExpiresIn" class="form-control"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'ciba-expires-in.tooltip' | translate}}</kc-tooltip>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="interval" class="col-md-2 control-label">{{:: 'ciba-interval' | translate}}</label>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div>
|
||||||
|
<input id="interval"" type="number" min="0" max="600" string-to-number ng-model="realm.attributes.cibaInterval" class="form-control"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'ciba-interval.tooltip' | translate}}</kc-tooltip>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="authRequestedUserHint" class="col-md-2 control-label"><span class="required">*</span>{{:: 'ciba-auth-requested-user-hint' | translate}}</label>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div>
|
||||||
|
<select id="authRequestedUserHint" ng-model="realm.attributes.cibaAuthRequestedUserHint" class="form-control">
|
||||||
|
<option value="login_hint">login_hint</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'ciba-auth-requested-user-hint.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>
|
62
base/admin/resources/partials/claims.html
Executable file
62
base/admin/resources/partials/claims.html
Executable file
@ -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>
|
37
base/admin/resources/partials/client-clustering-node.html
Normal file
37
base/admin/resources/partials/client-clustering-node.html
Normal file
@ -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>
|
76
base/admin/resources/partials/client-clustering.html
Normal file
76
base/admin/resources/partials/client-clustering.html
Normal file
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
89
base/admin/resources/partials/client-credentials-jwt.html
Normal file
89
base/admin/resources/partials/client-credentials-jwt.html
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<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="tokenEndpointAuthSigningAlg">{{:: 'token-endpoint-auth-signing-alg' | translate}}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div>
|
||||||
|
<select class="form-control" id="tokenEndpointAuthSigningAlg"
|
||||||
|
ng-change="switchChange()"
|
||||||
|
ng-model="tokenEndpointAuthSigningAlg">
|
||||||
|
<option value=""></option>
|
||||||
|
<option ng-repeat="provider in serverInfo.listProviderIds('clientSignature')" value="{{provider}}">{{provider}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'token-endpoint-auth-signing-alg.tooltip' | translate}}</kc-tooltip>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<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>
|
@ -0,0 +1,39 @@
|
|||||||
|
<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>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-md-2 control-label" for="tokenEndpointAuthSigningAlg">{{:: 'token-endpoint-auth-signing-alg' | translate}}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div>
|
||||||
|
<select class="form-control" id="tokenEndpointAuthSigningAlg"
|
||||||
|
ng-change="switchChange()"
|
||||||
|
ng-model="tokenEndpointAuthSigningAlg">
|
||||||
|
<option value=""></option>
|
||||||
|
<option ng-repeat="provider in serverInfo.listProviderIds('clientSignature')" value="{{provider}}">{{provider}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'token-endpoint-auth-signing-alg.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 kc-save data-ng-disabled="!changed" data-ng-click="save()">{{:: 'save' | translate}}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
17
base/admin/resources/partials/client-credentials-secret.html
Normal file
17
base/admin/resources/partials/client-credentials-secret.html
Normal file
@ -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>
|
21
base/admin/resources/partials/client-credentials-x509.html
Normal file
21
base/admin/resources/partials/client-credentials-x509.html
Normal file
@ -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>
|
38
base/admin/resources/partials/client-credentials.html
Executable file
38
base/admin/resources/partials/client-credentials.html
Executable file
@ -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>
|
815
base/admin/resources/partials/client-detail.html
Executable file
815
base/admin/resources/partials/client-detail.html
Executable file
@ -0,0 +1,815 @@
|
|||||||
|
<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="oauth2DeviceAuthorizationGrantEnabled">{{::
|
||||||
|
'oauth2-device-authorization-grant-enabled' | translate}}</label>
|
||||||
|
<kc-tooltip>{{:: 'oauth2-device-authorization-grant-enabled.tooltip' | translate}}</kc-tooltip>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input ng-model="oauth2DeviceAuthorizationGrantEnabled" ng-click="switchChange()"
|
||||||
|
name="oauth2DeviceAuthorizationGrantEnabled" id="oauth2DeviceAuthorizationGrantEnabled" 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 && serverInfo.featureEnabled('CIBA')">
|
||||||
|
<label class="col-md-2 control-label" for="oidcCibaGrantEnabled">{{::
|
||||||
|
'oidc-ciba-grant-enabled' | translate}}</label>
|
||||||
|
<kc-tooltip>{{:: 'oidc-ciba-grant-enabled.tooltip' | translate}}</kc-tooltip>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input ng-model="oidcCibaGrantEnabled" ng-click="switchChange()"
|
||||||
|
name="oidcCibaGrantEnabled" id="oidcCibaGrantEnabled" 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="samlArtifactBinding">{{:: 'artifact-binding' | translate}}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input ng-model="samlArtifactBinding" ng-click="switchChange()" name="samlArtifactBinding" id="samlArtifactBinding" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/>
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'artifact-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="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>
|
||||||
|
<div class="form-group" data-ng-show="protocol == 'openid-connect'">
|
||||||
|
<label class="col-md-2 control-label" for="backchannelLogoutUrl">{{:: 'backchannel-logout-url' | translate}}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input class="form-control" type="text" name="backchannelLogoutUrl" id="backchannelLogoutUrl" data-ng-model="clientEdit.attributes['backchannel.logout.url']">
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'backchannel-logout-url.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="backchannelLogoutSessionRequired">{{:: 'backchannel-logout-session-required' | translate}}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input ng-model="backchannelLogoutSessionRequired" name="backchannelLogoutSessionRequired" id="backchannelLogoutSessionRequired" onoffswitch ng-click="switchChange()" on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/>
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'backchannel-logout-session-required.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="backchannelLogoutRevokeOfflineSessions">{{:: 'backchannel-logout-revoke-offline-sessions' | translate}}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input ng-model="backchannelLogoutRevokeOfflineSessions" name="backchannelLogoutRevokeOfflineSessions" id="backchannelLogoutRevokeOfflineSessions" onoffswitch ng-click="switchChange()" on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/>
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'backchannel-logout-revoke-offline-sessions.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="logoutRedirectBinding">{{:: '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>
|
||||||
|
|
||||||
|
<div class="form-group clearfix block" data-ng-show="protocol == 'saml'">
|
||||||
|
<label class="col-md-2 control-label" for="logoutArtifactBinding">{{:: 'logout-service-artifact-binding-url' | translate}}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input ng-model="clientEdit.attributes.saml_single_logout_service_url_artifact" class="form-control" type="text" name="logoutRedirectBinding" id="logoutArtifactBinding" />
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'logout-service-artifact-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="artifactBindingUrl">{{:: 'artifact-binding-url' | translate}}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input ng-model="clientEdit.attributes.saml_artifact_binding_url" class="form-control" type="text" name="artifactBindingUrl" id="artifactBindingUrl" />
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'artifact-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="artifactResolutionServiceUrl">{{:: 'artifact-resolution-service-url' | translate}}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input ng-model="clientEdit.attributes.saml_artifact_resolution_service_url" class="form-control" type="text" name="artifactResolutionServiceUrl" id="artifactResolutionServiceUrl" />
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'artifact-resolution-service-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>
|
||||||
|
<div class="form-group clearfix block" data-ng-show="protocol == 'openid-connect'">
|
||||||
|
<label class="col-md-2 control-label" for="newRequestUri">{{:: 'request-uris' | translate}}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="input-group" ng-repeat="(i, requestUri) in clientEdit.requestUris track by $index">
|
||||||
|
<input class="form-control" ng-model="clientEdit.requestUris[i]">
|
||||||
|
<div class="input-group-btn">
|
||||||
|
<button class="btn btn-default" type="button" data-ng-click="deleteRequestUri($index)"><span class="fa fa-minus"></span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<input class="form-control" ng-model="newRequestUri" id="newRequestUri">
|
||||||
|
<div class="input-group-btn">
|
||||||
|
<button class="btn btn-default" type="button" data-ng-click="newRequestUri.length > 0 && addRequestUri()"><span class="fa fa-plus"></span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'request-uris.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>
|
||||||
|
<div class="form-group clearfix block" data-ng-show="protocol == 'openid-connect'">
|
||||||
|
<label class="col-md-2 control-label" for="useRefreshTokens">{{:: 'use-refresh-tokens' | translate}}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input ng-model="useRefreshTokens" ng-click="switchChange()" name="useRefreshTokens" id="useRefreshTokens"
|
||||||
|
onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" />
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'use-refresh-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="useRefreshTokenForClientCredentialsGrant">{{:: 'use-refresh-token-for-client-credentials-grant' | translate}}</label>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input ng-model="useRefreshTokenForClientCredentialsGrant" ng-click="switchChange()" name="useRefreshTokenForClientCredentialsGrant" id="useRefreshTokenForClientCredentialsGrant" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/>
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'use-refresh-token-for-client-credentials-grant.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" data-ng-show="protocol == 'openid-connect'">
|
||||||
|
<label class="col-md-2 control-label" for="clientOfflineSessionIdleTimeout">{{::
|
||||||
|
'client-offline-session-idle' | translate}}</label>
|
||||||
|
<div class="col-md-6 time-selector">
|
||||||
|
<input class="form-control" type="number" min="0" max="31536000"
|
||||||
|
data-ng-model="clientOfflineSessionIdleTimeout.time" id="clientOfflineSessionIdleTimeout"
|
||||||
|
name="clientOfflineSessionIdleTimeout" data-ng-change="updateClientOfflineSessionIdleTimeout()" /> <select
|
||||||
|
class="form-control" name="clientOfflineSessionIdleTimeoutUnit"
|
||||||
|
data-ng-model="clientOfflineSessionIdleTimeout.unit"
|
||||||
|
data-ng-change="updateClientOfflineSessionIdleTimeout()">
|
||||||
|
<option value="Minutes">{{:: 'minutes' | translate}}</option>
|
||||||
|
<option value="Hours">{{:: 'hours' | translate}}</option>
|
||||||
|
<option value="Days">{{:: 'days' | translate}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'client-offline-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="clientOfflineSessionMaxLifespan">{{::
|
||||||
|
'client-offline-session-max' | translate}}</label>
|
||||||
|
<div class="col-md-6 time-selector">
|
||||||
|
<input class="form-control" type="number" min="0" max="31536000"
|
||||||
|
data-ng-model="clientOfflineSessionMaxLifespan.time" id="clientOfflineSessionMaxLifespan"
|
||||||
|
name="clientOfflineSessionMaxLifespan" data-ng-change="updateClientOfflineSessionMaxLifespan()" /> <select
|
||||||
|
class="form-control" name="clientOfflineSessionMaxLifespanUnit"
|
||||||
|
data-ng-model="clientOfflineSessionMaxLifespan.unit"
|
||||||
|
data-ng-change="updateClientOfflineSessionMaxLifespan()">
|
||||||
|
<option value="Minutes">{{:: 'minutes' | translate}}</option>
|
||||||
|
<option value="Hours">{{:: 'hours' | translate}}</option>
|
||||||
|
<option value="Days">{{:: 'days' | translate}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'client-offline-session-max.tooltip' | translate}}</kc-tooltip>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group"
|
||||||
|
data-ng-show="protocol == 'openid-connect' && !clientEdit.publicClient && !clientEdit.bearerOnly && oauth2DeviceAuthorizationGrantEnabled == true">
|
||||||
|
<label class="col-md-2 control-label" for="oauth2DeviceCodeLifespan">{{:: 'oauth2-device-code-lifespan'
|
||||||
|
| translate}}</label>
|
||||||
|
<div class="col-md-6 time-selector">
|
||||||
|
<input class="form-control" type="number" min="1" max="31536000"
|
||||||
|
data-ng-model="oauth2DeviceCodeLifespan.time" id="oauth2DeviceCodeLifespan"
|
||||||
|
name="oauth2DeviceCodeLifespan" data-ng-change="updateOauth2DeviceCodeLifespan()" /> <select
|
||||||
|
class="form-control" name="oauth2DeviceCodeLifespanUnit" data-ng-model="oauth2DeviceCodeLifespan.unit"
|
||||||
|
data-ng-change="updateOauth2DeviceCodeLifespan()">
|
||||||
|
<option value="Minutes">{{:: 'minutes' | translate}}</option>
|
||||||
|
<option value="Hours">{{:: 'hours' | translate}}</option>
|
||||||
|
<option value="Days">{{:: 'days' | translate}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'oauth2-device-code-lifespan.tooltip' | translate}}</kc-tooltip>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group"
|
||||||
|
data-ng-show="protocol == 'openid-connect' && !clientEdit.publicClient && !clientEdit.bearerOnly && oauth2DeviceAuthorizationGrantEnabled == true">
|
||||||
|
<label class="col-md-2 control-label" for="oauth2DevicePollingInterval">{{::
|
||||||
|
'oauth2-device-polling-interval' | translate}}</label>
|
||||||
|
<div class="col-md-6 time-selector">
|
||||||
|
<input class="form-control" type="number" min="1" max="31536000" data-ng-model="oauth2DevicePollingInterval"
|
||||||
|
id="oauth2DevicePollingInterval" name="oauth2DevicePollingInterval"
|
||||||
|
data-ng-change="updateOauth2DevicePollingInterval()" />
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'oauth2-device-polling-interval.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>
|
46
base/admin/resources/partials/client-import.html
Executable file
46
base/admin/resources/partials/client-import.html
Executable file
@ -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>
|
63
base/admin/resources/partials/client-initial-access-create.html
Executable file
63
base/admin/resources/partials/client-initial-access-create.html
Executable file
@ -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>
|
55
base/admin/resources/partials/client-initial-access.html
Executable file
55
base/admin/resources/partials/client-initial-access.html
Executable file
@ -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:('dateFormat' | translate)}} {{(ia.timestamp * 1000)|date:('timeFormat' | translate)}}</td>
|
||||||
|
<td><span data-ng-show="ia.expiration > 0">{{((ia.timestamp + ia.expiration) * 1000)|date:('dateFormat' | translate)}} {{((ia.timestamp + ia.expiration) * 1000)|date:('timeFormat' | translate)}}</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>
|
36
base/admin/resources/partials/client-installation.html
Executable file
36
base/admin/resources/partials/client-installation.html
Executable file
@ -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>
|
146
base/admin/resources/partials/client-keys.html
Executable file
146
base/admin/resources/partials/client-keys.html
Executable file
@ -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>
|
68
base/admin/resources/partials/client-list.html
Executable file
68
base/admin/resources/partials/client-list.html
Executable file
@ -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>
|
53
base/admin/resources/partials/client-mappers-add.html
Executable file
53
base/admin/resources/partials/client-mappers-add.html
Executable file
@ -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>
|
55
base/admin/resources/partials/client-mappers.html
Executable file
55
base/admin/resources/partials/client-mappers.html
Executable file
@ -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>
|
59
base/admin/resources/partials/client-offline-sessions.html
Normal file
59
base/admin/resources/partials/client-offline-sessions.html
Normal file
@ -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>
|
13
base/admin/resources/partials/client-protocol-mapper-detail.html
Executable file
13
base/admin/resources/partials/client-protocol-mapper-detail.html
Executable file
@ -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>
|
106
base/admin/resources/partials/client-reg-policies.html
Normal file
106
base/admin/resources/partials/client-reg-policies.html
Normal file
@ -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>
|
68
base/admin/resources/partials/client-reg-policy-detail.html
Normal file
68
base/admin/resources/partials/client-reg-policy-detail.html
Normal file
@ -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 || headerTitle}}</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageClients ">
|
||||||
|
<fieldset>
|
||||||
|
<legend><span class="text">{{headerTitle}}</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 data-ng-disabled="!hasValidValues()">{{:: '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>
|
@ -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>
|
@ -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>
|
@ -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>
|
30
base/admin/resources/partials/client-revocation.html
Executable file
30
base/admin/resources/partials/client-revocation.html
Executable file
@ -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>
|
45
base/admin/resources/partials/client-role-attributes.html
Executable file
45
base/admin/resources/partials/client-role-attributes.html
Executable file
@ -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>
|
140
base/admin/resources/partials/client-role-detail.html
Executable file
140
base/admin/resources/partials/client-role-detail.html
Executable file
@ -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 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>
|
64
base/admin/resources/partials/client-role-list.html
Executable file
64
base/admin/resources/partials/client-role-list.html
Executable file
@ -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="client.access.configure">
|
||||||
|
<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>
|
52
base/admin/resources/partials/client-role-users.html
Normal file
52
base/admin/resources/partials/client-role-users.html
Normal file
@ -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>
|
63
base/admin/resources/partials/client-saml-key-export.html
Executable file
63
base/admin/resources/partials/client-saml-key-export.html
Executable file
@ -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>
|
62
base/admin/resources/partials/client-saml-key-import.html
Executable file
62
base/admin/resources/partials/client-saml-key-import.html
Executable file
@ -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>
|
66
base/admin/resources/partials/client-saml-keys.html
Executable file
66
base/admin/resources/partials/client-saml-keys.html
Executable file
@ -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>
|
84
base/admin/resources/partials/client-scope-detail.html
Executable file
84
base/admin/resources/partials/client-scope-detail.html
Executable file
@ -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>
|
60
base/admin/resources/partials/client-scope-list.html
Executable file
60
base/admin/resources/partials/client-scope-list.html
Executable file
@ -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>
|
53
base/admin/resources/partials/client-scope-mappers-add.html
Executable file
53
base/admin/resources/partials/client-scope-mappers-add.html
Executable file
@ -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>
|
55
base/admin/resources/partials/client-scope-mappers.html
Executable file
55
base/admin/resources/partials/client-scope-mappers.html
Executable file
@ -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>
|
127
base/admin/resources/partials/client-scope-mappings.html
Executable file
127
base/admin/resources/partials/client-scope-mappings.html
Executable file
@ -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>
|
13
base/admin/resources/partials/client-scope-protocol-mapper-detail.html
Executable file
13
base/admin/resources/partials/client-scope-protocol-mapper-detail.html
Executable file
@ -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>
|
116
base/admin/resources/partials/client-scope-scope-mappings.html
Executable file
116
base/admin/resources/partials/client-scope-scope-mappings.html
Executable file
@ -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>
|
268
base/admin/resources/partials/client-scopes-evaluate.html
Normal file
268
base/admin/resources/partials/client-scopes-evaluate.html
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
<!--
|
||||||
|
~ 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="isAccessTokenAvailable()">
|
||||||
|
<a href="">{{:: 'generated-access-token' | translate}}</a>
|
||||||
|
<kc-tooltip>{{:: 'generated-access-token.tooltip' | translate}}</kc-tooltip>
|
||||||
|
</li>
|
||||||
|
<li class="{{tabCss.tab4}}" data-ng-click="showTab(4)" data-ng-show="isIDTokenAvailable()">
|
||||||
|
<a href="">{{:: 'generated-id-token' | translate}}</a>
|
||||||
|
<kc-tooltip>{{:: 'generated-id-token.tooltip' | translate}}</kc-tooltip>
|
||||||
|
</li>
|
||||||
|
<li class="{{tabCss.tab5}}" data-ng-click="showTab(5)" data-ng-show="isUserInfoAvailable()">
|
||||||
|
<a href="">{{:: 'generated-user-info' | translate}}</a>
|
||||||
|
<kc-tooltip>{{:: 'generated-user-info.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>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Example content: One of Access token, ID token or User Info -->
|
||||||
|
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.viewClients" data-ng-show="exampleTabInfo().isShown">
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-md-10 col-md-offset-1">
|
||||||
|
<textarea class="form-control" rows="20" kc-select-action="click" readonly>{{exampleTabInfo().value}}</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<kc-menu></kc-menu>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user