required creds
This commit is contained in:
parent
3480cb5646
commit
993fc5c301
81 changed files with 5771 additions and 400 deletions
|
@ -111,7 +111,7 @@ public class AbstractOAuthClient {
|
|||
.param("grant_type", "authorization_code")
|
||||
.param("code", code)
|
||||
.param("client_id", clientId)
|
||||
.param("Password", password)
|
||||
.param("password", password)
|
||||
.param("redirect_uri", redirectUri);
|
||||
Response res = client.target(codeUrl).request().header(HttpHeaders.AUTHORIZATION, authHeader).post(Entity.form(codeForm));
|
||||
try {
|
||||
|
|
|
@ -5,9 +5,13 @@ package org.keycloak.representations.idm;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class CredentialRepresentation {
|
||||
public static final String PASSWORD = "password";
|
||||
public static final String TOTP = "totp";
|
||||
public static final String CLIENT_CERT = "cert";
|
||||
|
||||
protected String type;
|
||||
protected String value;
|
||||
protected boolean hashed;
|
||||
protected String device;
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
|
@ -25,11 +29,11 @@ public class CredentialRepresentation {
|
|||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean isHashed() {
|
||||
return hashed;
|
||||
public String getDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
public void setHashed(boolean hashed) {
|
||||
this.hashed = hashed;
|
||||
public void setDevice(String device) {
|
||||
this.device = device;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,9 +20,9 @@ public class RealmRepresentation {
|
|||
protected String privateKey;
|
||||
protected String publicKey;
|
||||
protected List<RoleRepresentation> roles;
|
||||
protected List<RequiredCredentialRepresentation> requiredCredentials;
|
||||
protected List<RequiredCredentialRepresentation> requiredResourceCredentials;
|
||||
protected List<RequiredCredentialRepresentation> requiredOAuthClientCredentials;
|
||||
protected List<String> requiredCredentials;
|
||||
protected List<String> requiredResourceCredentials;
|
||||
protected List<String> requiredOAuthClientCredentials;
|
||||
protected List<UserRepresentation> users;
|
||||
protected List<RoleMappingRepresentation> roleMappings;
|
||||
protected List<ScopeMappingRepresentation> scopeMappings;
|
||||
|
@ -141,27 +141,27 @@ public class RealmRepresentation {
|
|||
return mapping;
|
||||
}
|
||||
|
||||
public List<RequiredCredentialRepresentation> getRequiredCredentials() {
|
||||
public List<String> getRequiredCredentials() {
|
||||
return requiredCredentials;
|
||||
}
|
||||
|
||||
public void setRequiredCredentials(List<RequiredCredentialRepresentation> requiredCredentials) {
|
||||
public void setRequiredCredentials(List<String> requiredCredentials) {
|
||||
this.requiredCredentials = requiredCredentials;
|
||||
}
|
||||
|
||||
public List<RequiredCredentialRepresentation> getRequiredResourceCredentials() {
|
||||
public List<String> getRequiredResourceCredentials() {
|
||||
return requiredResourceCredentials;
|
||||
}
|
||||
|
||||
public void setRequiredResourceCredentials(List<RequiredCredentialRepresentation> requiredResourceCredentials) {
|
||||
public void setRequiredResourceCredentials(List<String> requiredResourceCredentials) {
|
||||
this.requiredResourceCredentials = requiredResourceCredentials;
|
||||
}
|
||||
|
||||
public List<RequiredCredentialRepresentation> getRequiredOAuthClientCredentials() {
|
||||
public List<String> getRequiredOAuthClientCredentials() {
|
||||
return requiredOAuthClientCredentials;
|
||||
}
|
||||
|
||||
public void setRequiredOAuthClientCredentials(List<RequiredCredentialRepresentation> requiredOAuthClientCredentials) {
|
||||
public void setRequiredOAuthClientCredentials(List<String> requiredOAuthClientCredentials) {
|
||||
this.requiredOAuthClientCredentials = requiredOAuthClientCredentials;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
package org.keycloak.representations.idm;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class RequiredCredentialRepresentation {
|
||||
public static final String PASSWORD = "Password";
|
||||
public static final String TOTP = "TOTP";
|
||||
public static final String CLIENT_CERT = "CLIENT_CERT";
|
||||
public static final String CALLER_PRINCIPAL = "CALLER_PRINCIPAL";
|
||||
protected String type;
|
||||
protected boolean input;
|
||||
protected boolean secret;
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public boolean isInput() {
|
||||
return input;
|
||||
}
|
||||
|
||||
public void setInput(boolean input) {
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public boolean isSecret() {
|
||||
return secret;
|
||||
}
|
||||
|
||||
public void setSecret(boolean secret) {
|
||||
this.secret = secret;
|
||||
}
|
||||
}
|
|
@ -123,12 +123,11 @@ public class ResourceRepresentation {
|
|||
this.credentials = credentials;
|
||||
}
|
||||
|
||||
public ResourceRepresentation credential(String type, String value, boolean hashed) {
|
||||
public ResourceRepresentation credential(String type, String value) {
|
||||
if (this.credentials == null) credentials = new ArrayList<CredentialRepresentation>();
|
||||
CredentialRepresentation cred = new CredentialRepresentation();
|
||||
cred.setType(type);
|
||||
cred.setValue(value);
|
||||
cred.setHashed(hashed);
|
||||
credentials.add(cred);
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,9 @@ public class UserRepresentation {
|
|||
protected String self; // link
|
||||
protected String username;
|
||||
protected boolean enabled;
|
||||
protected String firstName;
|
||||
protected String lastName;
|
||||
protected String email;
|
||||
protected Map<String, String> attributes;
|
||||
protected List<CredentialRepresentation> credentials;
|
||||
|
||||
|
@ -25,6 +28,30 @@ public class UserRepresentation {
|
|||
this.self = self;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
@ -55,12 +82,11 @@ public class UserRepresentation {
|
|||
this.credentials = credentials;
|
||||
}
|
||||
|
||||
public UserRepresentation credential(String type, String value, boolean hashed) {
|
||||
public UserRepresentation credential(String type, String value) {
|
||||
if (this.credentials == null) credentials = new ArrayList<CredentialRepresentation>();
|
||||
CredentialRepresentation cred = new CredentialRepresentation();
|
||||
cred.setType(type);
|
||||
cred.setValue(value);
|
||||
cred.setHashed(hashed);
|
||||
credentials.add(cred);
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -1,33 +1,15 @@
|
|||
{
|
||||
"realm" : "demo",
|
||||
"enabled" : true,
|
||||
"tokenLifespan" : 10,
|
||||
"accessCodeLifespan" : 10,
|
||||
"sslNotRequired" : true,
|
||||
"cookieLoginAllowed" : true,
|
||||
"privateKey" : "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
|
||||
"publicKey" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
||||
"requiredCredentials" : [
|
||||
{
|
||||
"type" : "Password",
|
||||
"input" : true,
|
||||
"secret" : true
|
||||
}
|
||||
],
|
||||
"requiredResourceCredentials" : [
|
||||
{
|
||||
"type" : "Password",
|
||||
"input" : true,
|
||||
"secret" : true
|
||||
}
|
||||
],
|
||||
"requiredOAuthClientCredentials" : [
|
||||
{
|
||||
"type" : "Password",
|
||||
"input" : true,
|
||||
"secret" : true
|
||||
}
|
||||
],
|
||||
"realm": "demo",
|
||||
"enabled": true,
|
||||
"tokenLifespan": 300,
|
||||
"accessCodeLifespan": 10,
|
||||
"sslNotRequired": true,
|
||||
"cookieLoginAllowed": true,
|
||||
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
|
||||
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
||||
"requiredCredentials": [ "password" ],
|
||||
"requiredResourceCredentials": [ "password" ],
|
||||
"requiredOAuthClientCredentials": [ "password" ],
|
||||
"users" : [
|
||||
{
|
||||
"username" : "bburke@redhat.com",
|
||||
|
@ -36,7 +18,7 @@
|
|||
"email" : "bburke@redhat.com"
|
||||
},
|
||||
"credentials" : [
|
||||
{ "type" : "Password",
|
||||
{ "type" : "password",
|
||||
"value" : "password" }
|
||||
]
|
||||
},
|
||||
|
@ -44,50 +26,60 @@
|
|||
"username" : "third-party",
|
||||
"enabled" : true,
|
||||
"credentials" : [
|
||||
{ "type" : "Password",
|
||||
{ "type" : "password",
|
||||
"value" : "password" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"roles" : [
|
||||
{ "name" : "user", "description" : "Have User privileges" },
|
||||
{ "name" : "admin", "description" : "Have Administrator privileges" }
|
||||
],
|
||||
"roleMappings" : [
|
||||
"roles": [
|
||||
{
|
||||
"username" : "bburke@redhat.com",
|
||||
"roles" : ["user"]
|
||||
"name": "user",
|
||||
"description": "Have User privileges"
|
||||
},
|
||||
{
|
||||
"username" : "third-party",
|
||||
"roles" : ["KEYCLOAK_IDENTITY_REQUESTER"]
|
||||
"name": "admin",
|
||||
"description": "Have Administrator privileges"
|
||||
}
|
||||
],
|
||||
"scopeMappings" : [
|
||||
"roleMappings": [
|
||||
{
|
||||
"username" : "third-party",
|
||||
"roles" : ["user"]
|
||||
"username": "bburke@redhat.com",
|
||||
"roles": ["user"]
|
||||
},
|
||||
{
|
||||
"username": "third-party",
|
||||
"roles": ["KEYCLOAK_IDENTITY_REQUESTER"]
|
||||
}
|
||||
],
|
||||
"resources" : [
|
||||
"scopeMappings": [
|
||||
{
|
||||
"name" : "customer-portal",
|
||||
"enabled" : true,
|
||||
"adminUrl" : "http://localhost:8080/customer-portal/j_admin_request",
|
||||
"useRealmMappings" : true,
|
||||
"credentials" : [
|
||||
{ "type" : "Password",
|
||||
"value" : "password" }
|
||||
"username": "third-party",
|
||||
"roles": ["user"]
|
||||
}
|
||||
],
|
||||
"resources": [
|
||||
{
|
||||
"name": "customer-portal",
|
||||
"enabled": true,
|
||||
"adminUrl": "http://localhost:8080/customer-portal/j_admin_request",
|
||||
"useRealmMappings": true,
|
||||
"credentials": [
|
||||
{
|
||||
"type": "password",
|
||||
"value": "password"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "product-portal",
|
||||
"enabled" : true,
|
||||
"adminUrl" : "http://localhost:8080/product-portal/j_admin_request",
|
||||
"useRealmMappings" : true,
|
||||
"credentials" : [
|
||||
{ "type" : "Password",
|
||||
"value" : "password" }
|
||||
"name": "product-portal",
|
||||
"enabled": true,
|
||||
"adminUrl": "http://localhost:8080/product-portal/j_admin_request",
|
||||
"useRealmMappings": true,
|
||||
"credentials": [
|
||||
{
|
||||
"type": "password",
|
||||
"value": "password"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
@ -15,13 +15,20 @@
|
|||
<link href="lib/bootstrap/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="css/admin.css" rel="stylesheet">
|
||||
<link href="css/admin-responsive.css" rel="stylesheet">
|
||||
<link href="lib/select2-3.4.1/select2.css" rel="stylesheet">
|
||||
|
||||
<link href="css/styles.css" rel="stylesheet">
|
||||
|
||||
<script src="lib/jquery/jquery-1.10.2.js" type="text/javascript"></script>
|
||||
<script src="lib/select2-3.4.1/select2.js" type="text/javascript"></script>
|
||||
|
||||
<script src="lib/angular/angular.js"></script>
|
||||
<script src="lib/angular/angular-resource.js"></script>
|
||||
<script src="lib/angular/ui-bootstrap-tpls-0.4.0.js"></script>
|
||||
|
||||
<script src="lib/jquery/jquery.idletimer.js" type="text/javascript"></script>
|
||||
<script src="lib/jquery/jquery.idletimeout.js" type="text/javascript"></script>
|
||||
<script src="lib/angular/select2.js" type="text/javascript"></script>
|
||||
<script src="js/app.js"></script>
|
||||
<script src="js/controllers.js"></script>
|
||||
<script src="js/loaders.js"></script>
|
||||
|
@ -57,9 +64,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<script src="lib/jquery/jquery-1.10.2.js" type="text/javascript"></script>
|
||||
<script src="lib/jquery/jquery.idletimer.js" type="text/javascript"></script>
|
||||
<script src="lib/jquery/jquery.idletimeout.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$.idleTimeout('#idletimeout', '#idletimeout a', {
|
||||
idleAfter: 300,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
var module = angular.module('keycloak', [ 'keycloak.services', 'keycloak.loaders', 'keycloak.controllers', 'ui.bootstrap' ]);
|
||||
var module = angular.module('keycloak', [ 'keycloak.services', 'keycloak.loaders', 'keycloak.controllers', 'ui.bootstrap', 'ui.select2' ]);
|
||||
var resourceRequests = 0;
|
||||
|
||||
module.config([ '$routeProvider', function($routeProvider) {
|
||||
|
@ -197,13 +197,12 @@ module.factory('spinnerInterceptor', function($q, $window, $rootScope, $location
|
|||
};
|
||||
});
|
||||
|
||||
/*
|
||||
module.directive('kcInput', function() {
|
||||
var d = {
|
||||
scope : true,
|
||||
replace : false,
|
||||
link : function(scope, element, attrs) {
|
||||
var form = element.closest('form');
|
||||
var form = element.children('form');
|
||||
var label = element.children('label');
|
||||
var input = element.children('input');
|
||||
|
||||
|
@ -242,7 +241,7 @@ module.directive('kcEnter', function() {
|
|||
});
|
||||
};
|
||||
});
|
||||
*/
|
||||
|
||||
|
||||
module.filter('remove', function() {
|
||||
return function(input, remove, attribute) {
|
||||
|
|
|
@ -93,6 +93,7 @@ module.controller('RealmDetailCtrl', function($scope, Current, Realm, realm, $lo
|
|||
$scope.realm.tokenLifespanUnit = 'SECONDS';
|
||||
$scope.realm.accessCodeLifespan = 300;
|
||||
$scope.realm.accessCodeLifespanUnit = 'SECONDS';
|
||||
$scope.realm.requiredCredentials = ['password'];
|
||||
} else {
|
||||
$scope.realm.name = realm.realm;
|
||||
$scope.realm.requireSsl = !$scope.realm.sslNotRequired;
|
||||
|
@ -100,6 +101,12 @@ module.controller('RealmDetailCtrl', function($scope, Current, Realm, realm, $lo
|
|||
$scope.realm.acessCodeLifespanUnit = 'SECONDS';
|
||||
}
|
||||
|
||||
$scope.userCredentialOptions = {
|
||||
'multiple' : true,
|
||||
'simple_tags' : true,
|
||||
'tags' : ['password', 'totp', 'cert']
|
||||
};
|
||||
|
||||
$scope.changed = $scope.create;
|
||||
|
||||
$scope.$watch('realm', function() {
|
||||
|
@ -168,7 +175,8 @@ module.controller('RealmDetailCtrl', function($scope, Current, Realm, realm, $lo
|
|||
cookieLoginAllowed: $scope.realm.cookieLoginAllowed,
|
||||
sslNotRequired: !$scope.realm.requireSsl,
|
||||
tokenLifespan: $scope.realm.tokenLifespan,
|
||||
accessCodeLifespan: $scope.realm.accessCodeLifespan
|
||||
accessCodeLifespan: $scope.realm.accessCodeLifespan,
|
||||
requiredCredentials: $scope.realm.requiredCredentials
|
||||
|
||||
};
|
||||
|
||||
|
@ -385,7 +393,7 @@ module.controller('ApplicationDetailCtrl', function($scope, realm, applications,
|
|||
application : null
|
||||
};
|
||||
|
||||
selection.applications = angular.copy(applications);
|
||||
selection.applications = applications;
|
||||
|
||||
for (var i=0;i < selection.applications.length; i++) {
|
||||
if (selection.applications[i].name == application.name) {
|
||||
|
@ -396,10 +404,11 @@ module.controller('ApplicationDetailCtrl', function($scope, realm, applications,
|
|||
}
|
||||
|
||||
$scope.selection = selection;
|
||||
|
||||
$scope.application = angular.copy(application);
|
||||
|
||||
|
||||
if (!$scope.create) {
|
||||
$scope.application= selection.application;
|
||||
} else {
|
||||
$scope.application = {};
|
||||
}
|
||||
|
||||
$scope.changeApplication = function() {
|
||||
console.log('ApplicationDetailCtrl.changeApplication() - ' + $scope.selection.application.name);
|
||||
|
@ -407,7 +416,7 @@ module.controller('ApplicationDetailCtrl', function($scope, realm, applications,
|
|||
};
|
||||
|
||||
$scope.$watch('application', function() {
|
||||
if (!angular.equals($scope.application, application)) {
|
||||
if (!angular.equals($scope.selection.application, application)) {
|
||||
$scope.changed = true;
|
||||
}
|
||||
}, true);
|
||||
|
|
195
examples/as7-eap-demo/server/src/main/webapp/saas/admin/lib/angular/select2.js
vendored
Executable file
195
examples/as7-eap-demo/server/src/main/webapp/saas/admin/lib/angular/select2.js
vendored
Executable file
|
@ -0,0 +1,195 @@
|
|||
/**
|
||||
* Enhanced Select2 Dropmenus
|
||||
*
|
||||
* @AJAX Mode - When in this mode, your value will be an object (or array of objects) of the data used by Select2
|
||||
* This change is so that you do not have to do an additional query yourself on top of Select2's own query
|
||||
* @params [options] {object} The configuration options passed to $.fn.select2(). Refer to the documentation
|
||||
*/
|
||||
angular.module('ui.select2', []).value('uiSelect2Config', {}).directive('uiSelect2', ['uiSelect2Config', '$timeout', function (uiSelect2Config, $timeout) {
|
||||
var options = {};
|
||||
if (uiSelect2Config) {
|
||||
angular.extend(options, uiSelect2Config);
|
||||
}
|
||||
return {
|
||||
require: 'ngModel',
|
||||
compile: function (tElm, tAttrs) {
|
||||
var watch,
|
||||
repeatOption,
|
||||
repeatAttr,
|
||||
isSelect = tElm.is('select'),
|
||||
isMultiple = (tAttrs.multiple !== undefined);
|
||||
|
||||
// Enable watching of the options dataset if in use
|
||||
if (tElm.is('select')) {
|
||||
repeatOption = tElm.find('option[ng-repeat], option[data-ng-repeat]');
|
||||
|
||||
if (repeatOption.length) {
|
||||
repeatAttr = repeatOption.attr('ng-repeat') || repeatOption.attr('data-ng-repeat');
|
||||
watch = jQuery.trim(repeatAttr.split('|')[0]).split(' ').pop();
|
||||
}
|
||||
}
|
||||
|
||||
return function (scope, elm, attrs, controller) {
|
||||
// instance-specific options
|
||||
var opts = angular.extend({}, options, scope.$eval(attrs.uiSelect2));
|
||||
|
||||
/*
|
||||
Convert from Select2 view-model to Angular view-model.
|
||||
*/
|
||||
var convertToAngularModel = function(select2_data) {
|
||||
var model;
|
||||
if (opts.simple_tags) {
|
||||
model = []
|
||||
angular.forEach(select2_data, function(value, index) {
|
||||
model.push(value.id)
|
||||
})
|
||||
} else {
|
||||
model = select2_data
|
||||
}
|
||||
return model
|
||||
}
|
||||
|
||||
/*
|
||||
Convert from Angular view-model to Select2 view-model.
|
||||
*/
|
||||
var convertToSelect2Model = function(angular_data) {
|
||||
var model = []
|
||||
if (!angular_data) {
|
||||
return model;
|
||||
}
|
||||
|
||||
if (opts.simple_tags) {
|
||||
model = [];
|
||||
angular.forEach(
|
||||
angular_data,
|
||||
function(value, index) {
|
||||
model.push({'id': value, 'text': value});
|
||||
})
|
||||
} else {
|
||||
model = angular_data;
|
||||
}
|
||||
return model
|
||||
}
|
||||
|
||||
if (isSelect) {
|
||||
// Use <select multiple> instead
|
||||
delete opts.multiple;
|
||||
delete opts.initSelection;
|
||||
} else if (isMultiple) {
|
||||
opts.multiple = true;
|
||||
}
|
||||
|
||||
if (controller) {
|
||||
// Watch the model for programmatic changes
|
||||
scope.$watch(tAttrs.ngModel, function(current, old) {
|
||||
if (!current) {
|
||||
return
|
||||
}
|
||||
if (current == old) {
|
||||
return
|
||||
}
|
||||
controller.$render()
|
||||
}, true)
|
||||
controller.$render = function () {
|
||||
if (isSelect) {
|
||||
elm.select2('val', controller.$viewValue);
|
||||
} else {
|
||||
if (opts.multiple) {
|
||||
elm.select2(
|
||||
'data', convertToSelect2Model(controller.$viewValue));
|
||||
} else {
|
||||
if (angular.isObject(controller.$viewValue)) {
|
||||
elm.select2('data', controller.$viewValue);
|
||||
} else if (!controller.$viewValue) {
|
||||
elm.select2('data', null);
|
||||
} else {
|
||||
elm.select2('val', controller.$viewValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Watch the options dataset for changes
|
||||
if (watch) {
|
||||
scope.$watch(watch, function (newVal, oldVal, scope) {
|
||||
if (!newVal) return;
|
||||
// Delayed so that the options have time to be rendered
|
||||
$timeout(function () {
|
||||
elm.select2('val', controller.$viewValue);
|
||||
// Refresh angular to remove the superfluous option
|
||||
elm.trigger('change');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Update valid and dirty statuses
|
||||
controller.$parsers.push(function (value) {
|
||||
var div = elm.prev()
|
||||
div
|
||||
.toggleClass('ng-invalid', !controller.$valid)
|
||||
.toggleClass('ng-valid', controller.$valid)
|
||||
.toggleClass('ng-invalid-required', !controller.$valid)
|
||||
.toggleClass('ng-valid-required', controller.$valid)
|
||||
.toggleClass('ng-dirty', controller.$dirty)
|
||||
.toggleClass('ng-pristine', controller.$pristine);
|
||||
return value;
|
||||
});
|
||||
|
||||
if (!isSelect) {
|
||||
// Set the view and model value and update the angular template manually for the ajax/multiple select2.
|
||||
elm.bind("change", function () {
|
||||
if (scope.$$phase) return;
|
||||
scope.$apply(function () {
|
||||
controller.$setViewValue(
|
||||
convertToAngularModel(elm.select2('data')));
|
||||
});
|
||||
});
|
||||
|
||||
if (opts.initSelection) {
|
||||
var initSelection = opts.initSelection;
|
||||
opts.initSelection = function (element, callback) {
|
||||
initSelection(element, function (value) {
|
||||
controller.$setViewValue(convertToAngularModel(value));
|
||||
callback(value);
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elm.bind("$destroy", function() {
|
||||
elm.select2("destroy");
|
||||
});
|
||||
|
||||
attrs.$observe('disabled', function (value) {
|
||||
elm.select2('enable', !value);
|
||||
});
|
||||
|
||||
attrs.$observe('readonly', function (value) {
|
||||
elm.select2('readonly', !!value);
|
||||
});
|
||||
|
||||
if (attrs.ngMultiple) {
|
||||
scope.$watch(attrs.ngMultiple, function(newVal) {
|
||||
elm.select2(opts);
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize the plugin late so that the injected DOM does not disrupt the template compiler
|
||||
$timeout(function () {
|
||||
elm.select2(opts);
|
||||
|
||||
// Set initial value - I'm not sure about this but it seems to need to be there
|
||||
elm.val(controller.$viewValue);
|
||||
// important!
|
||||
controller.$render();
|
||||
|
||||
// Not sure if I should just check for !isSelect OR if I should check for 'tags' key
|
||||
if (!opts.initSelection && !isSelect)
|
||||
controller.$setViewValue(
|
||||
convertToAngularModel(elm.select2('data')));
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
}]);
|
|
@ -0,0 +1,18 @@
|
|||
Copyright 2012 Igor Vaynberg
|
||||
|
||||
Version: @@ver@@ Timestamp: @@timestamp@@
|
||||
|
||||
This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU
|
||||
General Public License version 2 (the "GPL License"). You may choose either license to govern your
|
||||
use of this software only upon the condition that you accept all of the terms of either the Apache
|
||||
License or the GPL License.
|
||||
|
||||
You may obtain a copy of the Apache License and the GPL License at:
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
http://www.gnu.org/licenses/gpl-2.0.html
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the Apache License
|
||||
or the GPL Licesnse is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
either express or implied. See the Apache License and the GPL License for the specific language governing
|
||||
permissions and limitations under the Apache License and the GPL License.
|
|
@ -0,0 +1,83 @@
|
|||
Select2
|
||||
=======
|
||||
|
||||
Select2 is a jQuery-based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.
|
||||
|
||||
To get started, checkout examples and documentation at http://ivaynberg.github.com/select2
|
||||
|
||||
Use cases
|
||||
---------
|
||||
|
||||
* Enhancing native selects with search.
|
||||
* Enhancing native selects with a better multi-select interface.
|
||||
* Loading data from JavaScript: easily load items via ajax and have them searchable.
|
||||
* Nesting optgroups: native selects only support one level of nested. Select2 does not have this restriction.
|
||||
* Tagging: ability to add new items on the fly.
|
||||
* Working with large, remote datasets: ability to partially load a dataset based on the search term.
|
||||
* Paging of large datasets: easy support for loading more pages when the results are scrolled to the end.
|
||||
* Templating: support for custom rendering of results and selections.
|
||||
|
||||
Browser compatibility
|
||||
---------------------
|
||||
* IE 8+
|
||||
* Chrome 8+
|
||||
* Firefox 10+
|
||||
* Safari 3+
|
||||
* Opera 10.6+
|
||||
|
||||
Integrations
|
||||
------------
|
||||
|
||||
* [Wicket-Select2](https://github.com/ivaynberg/wicket-select2) (Java / [Apache Wicket](http://wicket.apache.org))
|
||||
* [select2-rails](https://github.com/argerim/select2-rails) (Ruby on Rails)
|
||||
* [AngularUI](http://angular-ui.github.com/#directives-select2) ([AngularJS](angularjs.org))
|
||||
* [Django](https://github.com/applegrew/django-select2)
|
||||
* [Symfony](https://github.com/19Gerhard85/sfSelect2WidgetsPlugin)
|
||||
* [Bootstrap](https://github.com/t0m/select2-bootstrap-css) (CSS skin)
|
||||
* [Yii](https://github.com/tonybolzan/yii-select2)
|
||||
|
||||
Internationalization (i18n)
|
||||
---------------------------
|
||||
|
||||
Select2 supports multiple languages by simply including the right
|
||||
language JS file (`select2_locale_it.js`, `select2_locale_nl.js`, etc.).
|
||||
|
||||
Missing a language? Just copy `select2_locale_en.js.template`, translate
|
||||
it, and make a pull request back to Select2 here on GitHub.
|
||||
|
||||
Bug tracker
|
||||
-----------
|
||||
|
||||
Have a bug? Please create an issue here on GitHub!
|
||||
|
||||
https://github.com/ivaynberg/select2/issues
|
||||
|
||||
Mailing list
|
||||
------------
|
||||
|
||||
Have a question? Ask on our mailing list!
|
||||
|
||||
select2@googlegroups.com
|
||||
|
||||
https://groups.google.com/d/forum/select2
|
||||
|
||||
|
||||
Copyright and license
|
||||
---------------------
|
||||
|
||||
Copyright 2012 Igor Vaynberg
|
||||
|
||||
This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU
|
||||
General Public License version 2 (the "GPL License"). You may choose either license to govern your
|
||||
use of this software only upon the condition that you accept all of the terms of either the Apache
|
||||
License or the GPL License.
|
||||
|
||||
You may obtain a copy of the Apache License and the GPL License in the LICENSE file, or at:
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
http://www.gnu.org/licenses/gpl-2.0.html
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the Apache License
|
||||
or the GPL License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
either express or implied. See the Apache License and the GPL License for the specific language governing
|
||||
permissions and limitations under the Apache License and the GPL License.
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"name": "select2",
|
||||
"version": "3.4.1",
|
||||
"main": ["select2.js", "select2.css", "select2.png", "select2x2.png", "select2-spinner.gif"],
|
||||
"dependencies": {
|
||||
"jquery": ">= 1.7.1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo -n "Enter the version for this release: "
|
||||
|
||||
read ver
|
||||
|
||||
if [ ! $ver ]; then
|
||||
echo "Invalid version."
|
||||
exit
|
||||
fi
|
||||
|
||||
name="select2"
|
||||
js="$name.js"
|
||||
mini="$name.min.js"
|
||||
css="$name.css"
|
||||
release="$name-$ver"
|
||||
tag="$ver"
|
||||
branch="build-$ver"
|
||||
curbranch=`git branch | grep "*" | sed "s/* //"`
|
||||
timestamp=$(date)
|
||||
tokens="s/@@ver@@/$ver/g;s/\@@timestamp@@/$timestamp/g"
|
||||
remote="github"
|
||||
|
||||
echo "Updating Version Identifiers"
|
||||
|
||||
sed -E -e "s/\"version\": \"([0-9\.]+)\",/\"version\": \"$ver\",/g" -i "" component.json select2.jquery.json
|
||||
git add component.json
|
||||
git add select2.jquery.json
|
||||
git commit -m "modified version identifiers in descriptors for release $ver"
|
||||
git push
|
||||
|
||||
git branch "$branch"
|
||||
git checkout "$branch"
|
||||
|
||||
echo "Tokenizing..."
|
||||
|
||||
find . -name "$js" | xargs -I{} sed -e "$tokens" -i "" {}
|
||||
find . -name "$css" | xargs -I{} sed -e "$tokens" -i "" {}
|
||||
sed -e "s/latest/$ver/g" -i "" component.json
|
||||
|
||||
git add "$js"
|
||||
git add "$css"
|
||||
|
||||
echo "Minifying..."
|
||||
|
||||
echo "/*" > "$mini"
|
||||
cat LICENSE | sed "$tokens" >> "$mini"
|
||||
echo "*/" >> "$mini"
|
||||
|
||||
curl -s \
|
||||
--data-urlencode "js_code@$js" \
|
||||
http://marijnhaverbeke.nl/uglifyjs \
|
||||
>> "$mini"
|
||||
|
||||
git add "$mini"
|
||||
|
||||
git commit -m "release $ver"
|
||||
|
||||
echo "Tagging..."
|
||||
git tag -a "$tag" -m "tagged version $ver"
|
||||
git push "$remote" --tags
|
||||
|
||||
echo "Cleaning Up..."
|
||||
|
||||
git checkout "$curbranch"
|
||||
git branch -D "$branch"
|
||||
|
||||
echo "Done"
|
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
|
@ -0,0 +1,680 @@
|
|||
/*
|
||||
Version: 3.4.1 Timestamp: Thu Jun 27 18:02:10 PDT 2013
|
||||
*/
|
||||
.select2-container {
|
||||
margin: 0;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
/* inline-block for ie7 */
|
||||
zoom: 1;
|
||||
*display: inline;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.select2-container,
|
||||
.select2-drop,
|
||||
.select2-search,
|
||||
.select2-search input{
|
||||
/*
|
||||
Force border-box so that % widths fit the parent
|
||||
container without overlap because of margin/padding.
|
||||
|
||||
More Info : http://www.quirksmode.org/css/box.html
|
||||
*/
|
||||
-webkit-box-sizing: border-box; /* webkit */
|
||||
-khtml-box-sizing: border-box; /* konqueror */
|
||||
-moz-box-sizing: border-box; /* firefox */
|
||||
-ms-box-sizing: border-box; /* ie */
|
||||
box-sizing: border-box; /* css3 */
|
||||
}
|
||||
|
||||
.select2-container .select2-choice {
|
||||
display: block;
|
||||
height: 26px;
|
||||
padding: 0 0 0 8px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
border: 1px solid #aaa;
|
||||
white-space: nowrap;
|
||||
line-height: 26px;
|
||||
color: #444;
|
||||
text-decoration: none;
|
||||
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
|
||||
-webkit-background-clip: padding-box;
|
||||
-moz-background-clip: padding;
|
||||
background-clip: padding-box;
|
||||
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
|
||||
background-color: #fff;
|
||||
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.5, white));
|
||||
background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 50%);
|
||||
background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 50%);
|
||||
background-image: -o-linear-gradient(bottom, #eeeeee 0%, #ffffff 50%);
|
||||
background-image: -ms-linear-gradient(top, #ffffff 0%, #eeeeee 50%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#ffffff', endColorstr = '#eeeeee', GradientType = 0);
|
||||
background-image: linear-gradient(top, #ffffff 0%, #eeeeee 50%);
|
||||
}
|
||||
|
||||
.select2-container.select2-drop-above .select2-choice {
|
||||
border-bottom-color: #aaa;
|
||||
|
||||
-webkit-border-radius:0 0 4px 4px;
|
||||
-moz-border-radius:0 0 4px 4px;
|
||||
border-radius:0 0 4px 4px;
|
||||
|
||||
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.9, white));
|
||||
background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 90%);
|
||||
background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 90%);
|
||||
background-image: -o-linear-gradient(bottom, #eeeeee 0%, white 90%);
|
||||
background-image: -ms-linear-gradient(top, #eeeeee 0%,#ffffff 90%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee',GradientType=0 );
|
||||
background-image: linear-gradient(top, #eeeeee 0%,#ffffff 90%);
|
||||
}
|
||||
|
||||
.select2-container.select2-allowclear .select2-choice .select2-chosen {
|
||||
margin-right: 42px;
|
||||
}
|
||||
|
||||
.select2-container .select2-choice > .select2-chosen {
|
||||
margin-right: 26px;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
|
||||
white-space: nowrap;
|
||||
|
||||
-ms-text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.select2-container .select2-choice abbr {
|
||||
display: none;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
position: absolute;
|
||||
right: 24px;
|
||||
top: 8px;
|
||||
|
||||
font-size: 1px;
|
||||
text-decoration: none;
|
||||
|
||||
border: 0;
|
||||
background: url('select2.png') right top no-repeat;
|
||||
cursor: pointer;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.select2-container.select2-allowclear .select2-choice abbr {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.select2-container .select2-choice abbr:hover {
|
||||
background-position: right -11px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.select2-drop-undermask {
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 9998;
|
||||
background-color: transparent;
|
||||
filter: alpha(opacity=0);
|
||||
}
|
||||
|
||||
.select2-drop-mask {
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 9998;
|
||||
/* styles required for IE to work */
|
||||
background-color: #fff;
|
||||
opacity: 0;
|
||||
filter: alpha(opacity=0);
|
||||
}
|
||||
|
||||
.select2-drop {
|
||||
width: 100%;
|
||||
margin-top: -1px;
|
||||
position: absolute;
|
||||
z-index: 9999;
|
||||
top: 100%;
|
||||
|
||||
background: #fff;
|
||||
color: #000;
|
||||
border: 1px solid #aaa;
|
||||
border-top: 0;
|
||||
|
||||
-webkit-border-radius: 0 0 4px 4px;
|
||||
-moz-border-radius: 0 0 4px 4px;
|
||||
border-radius: 0 0 4px 4px;
|
||||
|
||||
-webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
|
||||
-moz-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
|
||||
box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
|
||||
}
|
||||
|
||||
.select2-drop-auto-width {
|
||||
border-top: 1px solid #aaa;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.select2-drop-auto-width .select2-search {
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.select2-drop.select2-drop-above {
|
||||
margin-top: 1px;
|
||||
border-top: 1px solid #aaa;
|
||||
border-bottom: 0;
|
||||
|
||||
-webkit-border-radius: 4px 4px 0 0;
|
||||
-moz-border-radius: 4px 4px 0 0;
|
||||
border-radius: 4px 4px 0 0;
|
||||
|
||||
-webkit-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
|
||||
-moz-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
|
||||
box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
|
||||
}
|
||||
|
||||
.select2-drop-active {
|
||||
border: 1px solid #5897fb;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.select2-drop.select2-drop-above.select2-drop-active {
|
||||
border-top: 1px solid #5897fb;
|
||||
}
|
||||
|
||||
.select2-container .select2-choice .select2-arrow {
|
||||
display: inline-block;
|
||||
width: 18px;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
|
||||
border-left: 1px solid #aaa;
|
||||
-webkit-border-radius: 0 4px 4px 0;
|
||||
-moz-border-radius: 0 4px 4px 0;
|
||||
border-radius: 0 4px 4px 0;
|
||||
|
||||
-webkit-background-clip: padding-box;
|
||||
-moz-background-clip: padding;
|
||||
background-clip: padding-box;
|
||||
|
||||
background: #ccc;
|
||||
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));
|
||||
background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%);
|
||||
background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%);
|
||||
background-image: -o-linear-gradient(bottom, #ccc 0%, #eee 60%);
|
||||
background-image: -ms-linear-gradient(top, #cccccc 0%, #eeeeee 60%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#cccccc', GradientType = 0);
|
||||
background-image: linear-gradient(top, #cccccc 0%, #eeeeee 60%);
|
||||
}
|
||||
|
||||
.select2-container .select2-choice .select2-arrow b {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: url('select2.png') no-repeat 0 1px;
|
||||
}
|
||||
|
||||
.select2-search {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
min-height: 26px;
|
||||
margin: 0;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
|
||||
position: relative;
|
||||
z-index: 10000;
|
||||
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.select2-search input {
|
||||
width: 100%;
|
||||
height: auto !important;
|
||||
min-height: 26px;
|
||||
padding: 4px 20px 4px 5px;
|
||||
margin: 0;
|
||||
|
||||
outline: 0;
|
||||
font-family: sans-serif;
|
||||
font-size: 1em;
|
||||
|
||||
border: 1px solid #aaa;
|
||||
-webkit-border-radius: 0;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
|
||||
background: #fff url('select2.png') no-repeat 100% -22px;
|
||||
background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
|
||||
background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
|
||||
background: url('select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
|
||||
background: url('select2.png') no-repeat 100% -22px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
|
||||
background: url('select2.png') no-repeat 100% -22px, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);
|
||||
background: url('select2.png') no-repeat 100% -22px, linear-gradient(top, #ffffff 85%, #eeeeee 99%);
|
||||
}
|
||||
|
||||
.select2-drop.select2-drop-above .select2-search input {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.select2-search input.select2-active {
|
||||
background: #fff url('select2-spinner.gif') no-repeat 100%;
|
||||
background: url('select2-spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
|
||||
background: url('select2-spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
|
||||
background: url('select2-spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
|
||||
background: url('select2-spinner.gif') no-repeat 100%, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
|
||||
background: url('select2-spinner.gif') no-repeat 100%, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);
|
||||
background: url('select2-spinner.gif') no-repeat 100%, linear-gradient(top, #ffffff 85%, #eeeeee 99%);
|
||||
}
|
||||
|
||||
.select2-container-active .select2-choice,
|
||||
.select2-container-active .select2-choices {
|
||||
border: 1px solid #5897fb;
|
||||
outline: none;
|
||||
|
||||
-webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);
|
||||
-moz-box-shadow: 0 0 5px rgba(0,0,0,.3);
|
||||
box-shadow: 0 0 5px rgba(0,0,0,.3);
|
||||
}
|
||||
|
||||
.select2-dropdown-open .select2-choice {
|
||||
border-bottom-color: transparent;
|
||||
-webkit-box-shadow: 0 1px 0 #fff inset;
|
||||
-moz-box-shadow: 0 1px 0 #fff inset;
|
||||
box-shadow: 0 1px 0 #fff inset;
|
||||
|
||||
-webkit-border-bottom-left-radius: 0;
|
||||
-moz-border-radius-bottomleft: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
|
||||
-webkit-border-bottom-right-radius: 0;
|
||||
-moz-border-radius-bottomright: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
|
||||
background-color: #eee;
|
||||
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, white), color-stop(0.5, #eeeeee));
|
||||
background-image: -webkit-linear-gradient(center bottom, white 0%, #eeeeee 50%);
|
||||
background-image: -moz-linear-gradient(center bottom, white 0%, #eeeeee 50%);
|
||||
background-image: -o-linear-gradient(bottom, white 0%, #eeeeee 50%);
|
||||
background-image: -ms-linear-gradient(top, #ffffff 0%,#eeeeee 50%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff',GradientType=0 );
|
||||
background-image: linear-gradient(top, #ffffff 0%,#eeeeee 50%);
|
||||
}
|
||||
|
||||
.select2-dropdown-open.select2-drop-above .select2-choice,
|
||||
.select2-dropdown-open.select2-drop-above .select2-choices {
|
||||
border: 1px solid #5897fb;
|
||||
border-top-color: transparent;
|
||||
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, white), color-stop(0.5, #eeeeee));
|
||||
background-image: -webkit-linear-gradient(center top, white 0%, #eeeeee 50%);
|
||||
background-image: -moz-linear-gradient(center top, white 0%, #eeeeee 50%);
|
||||
background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%);
|
||||
background-image: -ms-linear-gradient(bottom, #ffffff 0%,#eeeeee 50%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff',GradientType=0 );
|
||||
background-image: linear-gradient(bottom, #ffffff 0%,#eeeeee 50%);
|
||||
}
|
||||
|
||||
.select2-dropdown-open .select2-choice .select2-arrow {
|
||||
background: transparent;
|
||||
border-left: none;
|
||||
filter: none;
|
||||
}
|
||||
.select2-dropdown-open .select2-choice .select2-arrow b {
|
||||
background-position: -18px 1px;
|
||||
}
|
||||
|
||||
/* results */
|
||||
.select2-results {
|
||||
max-height: 200px;
|
||||
padding: 0 0 0 4px;
|
||||
margin: 4px 4px 4px 0;
|
||||
position: relative;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
-webkit-tap-highlight-color: rgba(0,0,0,0);
|
||||
}
|
||||
|
||||
.select2-results ul.select2-result-sub {
|
||||
margin: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.select2-results ul.select2-result-sub > li .select2-result-label { padding-left: 20px }
|
||||
.select2-results ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 40px }
|
||||
.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 60px }
|
||||
.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 80px }
|
||||
.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 100px }
|
||||
.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 110px }
|
||||
.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 120px }
|
||||
|
||||
.select2-results li {
|
||||
list-style: none;
|
||||
display: list-item;
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.select2-results li.select2-result-with-children > .select2-result-label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.select2-results .select2-result-label {
|
||||
padding: 3px 7px 4px;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
|
||||
min-height: 1em;
|
||||
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.select2-results .select2-highlighted {
|
||||
background: #3875d7;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.select2-results li em {
|
||||
background: #feffde;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.select2-results .select2-highlighted em {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.select2-results .select2-highlighted ul {
|
||||
background: white;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
|
||||
.select2-results .select2-no-results,
|
||||
.select2-results .select2-searching,
|
||||
.select2-results .select2-selection-limit {
|
||||
background: #f4f4f4;
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
/*
|
||||
disabled look for disabled choices in the results dropdown
|
||||
*/
|
||||
.select2-results .select2-disabled.select2-highlighted {
|
||||
color: #666;
|
||||
background: #f4f4f4;
|
||||
display: list-item;
|
||||
cursor: default;
|
||||
}
|
||||
.select2-results .select2-disabled {
|
||||
background: #f4f4f4;
|
||||
display: list-item;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.select2-results .select2-selected {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.select2-more-results.select2-active {
|
||||
background: #f4f4f4 url('select2-spinner.gif') no-repeat 100%;
|
||||
}
|
||||
|
||||
.select2-more-results {
|
||||
background: #f4f4f4;
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
/* disabled styles */
|
||||
|
||||
.select2-container.select2-container-disabled .select2-choice {
|
||||
background-color: #f4f4f4;
|
||||
background-image: none;
|
||||
border: 1px solid #ddd;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.select2-container.select2-container-disabled .select2-choice .select2-arrow {
|
||||
background-color: #f4f4f4;
|
||||
background-image: none;
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.select2-container.select2-container-disabled .select2-choice abbr {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/* multiselect */
|
||||
|
||||
.select2-container-multi .select2-choices {
|
||||
height: auto !important;
|
||||
height: 1%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
|
||||
border: 1px solid #aaa;
|
||||
cursor: text;
|
||||
overflow: hidden;
|
||||
|
||||
background-color: #fff;
|
||||
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
|
||||
background-image: -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
|
||||
background-image: -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
|
||||
background-image: -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
|
||||
background-image: -ms-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
|
||||
background-image: linear-gradient(top, #eeeeee 1%, #ffffff 15%);
|
||||
}
|
||||
|
||||
.select2-locked {
|
||||
padding: 3px 5px 3px 5px !important;
|
||||
}
|
||||
|
||||
.select2-container-multi .select2-choices {
|
||||
min-height: 26px;
|
||||
}
|
||||
|
||||
.select2-container-multi.select2-container-active .select2-choices {
|
||||
border: 1px solid #5897fb;
|
||||
outline: none;
|
||||
|
||||
-webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);
|
||||
-moz-box-shadow: 0 0 5px rgba(0,0,0,.3);
|
||||
box-shadow: 0 0 5px rgba(0,0,0,.3);
|
||||
}
|
||||
.select2-container-multi .select2-choices li {
|
||||
float: left;
|
||||
list-style: none;
|
||||
}
|
||||
.select2-container-multi .select2-choices .select2-search-field {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.select2-container-multi .select2-choices .select2-search-field input {
|
||||
padding: 5px;
|
||||
margin: 1px 0;
|
||||
|
||||
font-family: sans-serif;
|
||||
font-size: 100%;
|
||||
color: #666;
|
||||
outline: 0;
|
||||
border: 0;
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.select2-container-multi .select2-choices .select2-search-field input.select2-active {
|
||||
background: #fff url('select2-spinner.gif') no-repeat 100% !important;
|
||||
}
|
||||
|
||||
.select2-default {
|
||||
color: #999 !important;
|
||||
}
|
||||
|
||||
.select2-container-multi .select2-choices .select2-search-choice {
|
||||
padding: 3px 5px 3px 18px;
|
||||
margin: 3px 0 3px 5px;
|
||||
position: relative;
|
||||
|
||||
line-height: 13px;
|
||||
color: #333;
|
||||
cursor: default;
|
||||
border: 1px solid #aaaaaa;
|
||||
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
|
||||
-webkit-box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
|
||||
-moz-box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
|
||||
box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
|
||||
|
||||
-webkit-background-clip: padding-box;
|
||||
-moz-background-clip: padding;
|
||||
background-clip: padding-box;
|
||||
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
|
||||
background-color: #e4e4e4;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#f4f4f4', GradientType=0 );
|
||||
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
|
||||
background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
||||
background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
||||
background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
||||
background-image: -ms-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
||||
background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
||||
}
|
||||
.select2-container-multi .select2-choices .select2-search-choice .select2-chosen {
|
||||
cursor: default;
|
||||
}
|
||||
.select2-container-multi .select2-choices .select2-search-choice-focus {
|
||||
background: #d4d4d4;
|
||||
}
|
||||
|
||||
.select2-search-choice-close {
|
||||
display: block;
|
||||
width: 12px;
|
||||
height: 13px;
|
||||
position: absolute;
|
||||
right: 3px;
|
||||
top: 4px;
|
||||
|
||||
font-size: 1px;
|
||||
outline: none;
|
||||
background: url('select2.png') right top no-repeat;
|
||||
}
|
||||
|
||||
.select2-container-multi .select2-search-choice-close {
|
||||
left: 3px;
|
||||
}
|
||||
|
||||
.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover {
|
||||
background-position: right -11px;
|
||||
}
|
||||
.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close {
|
||||
background-position: right -11px;
|
||||
}
|
||||
|
||||
/* disabled styles */
|
||||
.select2-container-multi.select2-container-disabled .select2-choices{
|
||||
background-color: #f4f4f4;
|
||||
background-image: none;
|
||||
border: 1px solid #ddd;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice {
|
||||
padding: 3px 5px 3px 5px;
|
||||
border: 1px solid #ddd;
|
||||
background-image: none;
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
|
||||
.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close { display: none;
|
||||
background:none;
|
||||
}
|
||||
/* end multiselect */
|
||||
|
||||
|
||||
.select2-result-selectable .select2-match,
|
||||
.select2-result-unselectable .select2-match {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.select2-offscreen, .select2-offscreen:focus {
|
||||
clip: rect(0 0 0 0);
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
outline: 0;
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
.select2-display-none {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.select2-measure-scrollbar {
|
||||
position: absolute;
|
||||
top: -10000px;
|
||||
left: -10000px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
overflow: scroll;
|
||||
}
|
||||
/* Retina-ize icons */
|
||||
|
||||
@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 144dpi) {
|
||||
.select2-search input, .select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice .select2-arrow b {
|
||||
background-image: url('select2x2.png') !important;
|
||||
background-repeat: no-repeat !important;
|
||||
background-size: 60px 40px !important;
|
||||
}
|
||||
.select2-search input {
|
||||
background-position: 100% -21px !important;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"name": "select2",
|
||||
"title": "Select2",
|
||||
"description": "Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.",
|
||||
"keywords": [
|
||||
"select",
|
||||
"autocomplete",
|
||||
"typeahead",
|
||||
"dropdown",
|
||||
"multiselect",
|
||||
"tag",
|
||||
"tagging"
|
||||
],
|
||||
"version": "3.4.1",
|
||||
"author": {
|
||||
"name": "Igor Vaynberg",
|
||||
"url": "https://github.com/ivaynberg"
|
||||
},
|
||||
"licenses": [
|
||||
{
|
||||
"type": "Apache",
|
||||
"url": "http://www.apache.org/licenses/LICENSE-2.0"
|
||||
},
|
||||
{
|
||||
"type": "GPL v2",
|
||||
"url": "http://www.gnu.org/licenses/gpl-2.0.html"
|
||||
}
|
||||
],
|
||||
"bugs": "https://github.com/ivaynberg/select2/issues",
|
||||
"homepage": "http://ivaynberg.github.com/select2",
|
||||
"docs": "http://ivaynberg.github.com/select2/",
|
||||
"download": "https://github.com/ivaynberg/select2/tags",
|
||||
"dependencies": {
|
||||
"jquery": ">=1.7.1"
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
22
examples/as7-eap-demo/server/src/main/webapp/saas/admin/lib/select2-3.4.1/select2.min.js
vendored
Normal file
22
examples/as7-eap-demo/server/src/main/webapp/saas/admin/lib/select2-3.4.1/select2.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 613 B |
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* Select2 Arabic translation.
|
||||
*
|
||||
* Author: Your Name <amedhat3@gmail.com>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "لا توجد نتائج"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "من فضلك أدخل " + n + " حروف أكثر"; },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "من فضلك أحذف " + n + " حروف"; },
|
||||
formatSelectionTooBig: function (limit) { return "يمكنك ان تختار " + limit + " أختيارات فقط"; },
|
||||
formatLoadMore: function (pageNumber) { return "تحمل المذيد من النتائج ..."; },
|
||||
formatSearching: function () { return "جاري البحث ..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* Select2 Catalan translation.
|
||||
*
|
||||
* Author: David Planella <david.planella@gmail.com>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "No s'ha trobat cap coincidència"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Introduïu " + n + " caràcter" + (n == 1 ? "" : "s") + " més"; },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Introduïu " + n + " caràcter" + (n == 1? "" : "s") + "menys"; },
|
||||
formatSelectionTooBig: function (limit) { return "Només podeu seleccionar " + limit + " element" + (limit == 1 ? "" : "s"); },
|
||||
formatLoadMore: function (pageNumber) { return "S'estan carregant més resultats..."; },
|
||||
formatSearching: function () { return "S'està cercant..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* Select2 Czech translation.
|
||||
*
|
||||
* Author: Michal Marek <ahoj@michal-marek.cz>
|
||||
* Author - sklonovani: David Vallner <david@vallner.net>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
// use text for the numbers 2 through 4
|
||||
var smallNumbers = {
|
||||
2: function(masc) { return (masc ? "dva" : "dvě"); },
|
||||
3: function() { return "tři"; },
|
||||
4: function() { return "čtyři"; }
|
||||
}
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Nenalezeny žádné položky"; },
|
||||
formatInputTooShort: function (input, min) {
|
||||
var n = min - input.length;
|
||||
if (n == 1) {
|
||||
return "Prosím zadejte ještě jeden znak";
|
||||
} else if (n <= 4) {
|
||||
return "Prosím zadejte ještě další "+smallNumbers[n](true)+" znaky";
|
||||
} else {
|
||||
return "Prosím zadejte ještě dalších "+n+" znaků";
|
||||
}
|
||||
},
|
||||
formatInputTooLong: function (input, max) {
|
||||
var n = input.length - max;
|
||||
if (n == 1) {
|
||||
return "Prosím zadejte o jeden znak méně";
|
||||
} else if (n <= 4) {
|
||||
return "Prosím zadejte o "+smallNumbers[n](true)+" znaky méně";
|
||||
} else {
|
||||
return "Prosím zadejte o "+n+" znaků méně";
|
||||
}
|
||||
},
|
||||
formatSelectionTooBig: function (limit) {
|
||||
if (limit == 1) {
|
||||
return "Můžete zvolit jen jednu položku";
|
||||
} else if (limit <= 4) {
|
||||
return "Můžete zvolit maximálně "+smallNumbers[limit](false)+" položky";
|
||||
} else {
|
||||
return "Můžete zvolit maximálně "+limit+" položek";
|
||||
}
|
||||
},
|
||||
formatLoadMore: function (pageNumber) { return "Načítají se další výsledky..."; },
|
||||
formatSearching: function () { return "Vyhledávání..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* Select2 Danish translation.
|
||||
*
|
||||
* Author: Anders Jenbo <anders@jenbo.dk>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Ingen resultater fundet"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Angiv venligst " + n + " tegn mere"; },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Angiv venligst " + n + " tegn mindre"; },
|
||||
formatSelectionTooBig: function (limit) { return "Du kan kun vælge " + limit + " emne" + (limit === 1 ? "" : "r"); },
|
||||
formatLoadMore: function (pageNumber) { return "Indlæser flere resultater…"; },
|
||||
formatSearching: function () { return "Søger…"; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Select2 German translation
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Keine Übereinstimmungen gefunden"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Bitte " + n + " Zeichen mehr eingeben"; },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Bitte " + n + " Zeichen weniger eingeben"; },
|
||||
formatSelectionTooBig: function (limit) { return "Sie können nur " + limit + " Eintr" + (limit === 1 ? "ag" : "äge") + " auswählen"; },
|
||||
formatLoadMore: function (pageNumber) { return "Lade mehr Ergebnisse..."; },
|
||||
formatSearching: function () { return "Suche..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* Select2 <Language> translation.
|
||||
*
|
||||
* Author: Your Name <your@email>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Δεν βρέθηκαν αποτελέσματα"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Παρακαλούμε εισάγετε " + n + " περισσότερους χαρακτήρες" + (n == 1 ? "" : "s"); },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Παρακαλούμε διαγράψτε " + n + " χαρακτήρες" + (n == 1 ? "" : "s"); },
|
||||
formatSelectionTooBig: function (limit) { return "Μπορείτε να επιλέξετε μόνο " + limit + " αντικείμενο" + (limit == 1 ? "" : "s"); },
|
||||
formatLoadMore: function (pageNumber) { return "Φόρτωση περισσότερων..."; },
|
||||
formatSearching: function () { return "Αναζήτηση..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* Select2 <Language> translation.
|
||||
*
|
||||
* Author: Your Name <your@email>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "No matches found"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Please enter " + n + " more character" + (n == 1 ? "" : "s"); },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Please delete " + n + " character" + (n == 1 ? "" : "s"); },
|
||||
formatSelectionTooBig: function (limit) { return "You can only select " + limit + " item" + (limit == 1 ? "" : "s"); },
|
||||
formatLoadMore: function (pageNumber) { return "Loading more results..."; },
|
||||
formatSearching: function () { return "Searching..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Select2 Spanish translation
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "No se encontraron resultados"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Por favor adicione " + n + " caracter" + (n == 1? "" : "es"); },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Por favor elimine " + n + " caracter" + (n == 1? "" : "es"); },
|
||||
formatSelectionTooBig: function (limit) { return "Solo puede seleccionar " + limit + " elemento" + (limit == 1 ? "" : "s"); },
|
||||
formatLoadMore: function (pageNumber) { return "Cargando más resultados..."; },
|
||||
formatSearching: function () { return "Buscando..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* Select2 Estonian translation.
|
||||
*
|
||||
* Author: Kuldar Kalvik <kuldar@kalvik.ee>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Tulemused puuduvad"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Sisesta " + n + " täht" + (n == 1 ? "" : "e") + " rohkem"; },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Sisesta " + n + " täht" + (n == 1? "" : "e") + " vähem"; },
|
||||
formatSelectionTooBig: function (limit) { return "Saad vaid " + limit + " tulemus" + (limit == 1 ? "e" : "t") + " valida"; },
|
||||
formatLoadMore: function (pageNumber) { return "Laen tulemusi.."; },
|
||||
formatSearching: function () { return "Otsin.."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* Select2 Basque translation.
|
||||
*
|
||||
* Author: Julen Ruiz Aizpuru <julenx at gmail dot com>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () {
|
||||
return "Ez da bat datorrenik aurkitu";
|
||||
},
|
||||
formatInputTooShort: function (input, min) {
|
||||
var n = min - input.length;
|
||||
if (n === 1) {
|
||||
return "Idatzi karaktere bat gehiago";
|
||||
} else {
|
||||
return "Idatzi " + n + " karaktere gehiago";
|
||||
}
|
||||
},
|
||||
formatInputTooLong: function (input, max) {
|
||||
var n = input.length - max;
|
||||
if (n === 1) {
|
||||
return "Idatzi karaktere bat gutxiago";
|
||||
} else {
|
||||
return "Idatzi " + n + " karaktere gutxiago";
|
||||
}
|
||||
},
|
||||
formatSelectionTooBig: function (limit) {
|
||||
if (limit === 1 ) {
|
||||
return "Elementu bakarra hauta dezakezu";
|
||||
} else {
|
||||
return limit + " elementu hauta ditzakezu soilik";
|
||||
}
|
||||
},
|
||||
formatLoadMore: function (pageNumber) {
|
||||
return "Emaitza gehiago kargatzen...";
|
||||
},
|
||||
formatSearching: function () {
|
||||
return "Bilatzen...";
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* Select2 Finnish translation
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () {
|
||||
return "Ei tuloksia";
|
||||
},
|
||||
formatInputTooShort: function (input, min) {
|
||||
var n = min - input.length;
|
||||
return "Ole hyvä ja anna " + n + " merkkiä lisää.";
|
||||
},
|
||||
formatInputTooLong: function (input, max) {
|
||||
var n = input.length - max;
|
||||
return "Ole hyvä ja annar " + n + " merkkiä vähemmän.";
|
||||
},
|
||||
formatSelectionTooBig: function (limit) {
|
||||
return "Voit valita ainoastaan " + limit + " kpl";
|
||||
},
|
||||
formatLoadMore: function (pageNumber) {
|
||||
return "Ladataan lisää tuloksia...";
|
||||
},
|
||||
formatSearching: function () {
|
||||
return "Etsitään...";
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Select2 French translation
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Aucun résultat trouvé"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Merci de saisir " + n + " caractère" + (n == 1? "" : "s") + " de plus"; },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Merci de supprimer " + n + " caractère" + (n == 1? "" : "s"); },
|
||||
formatSelectionTooBig: function (limit) { return "Vous pouvez seulement sélectionner " + limit + " élément" + (limit == 1 ? "" : "s"); },
|
||||
formatLoadMore: function (pageNumber) { return "Chargement de résultats supplémentaires..."; },
|
||||
formatSearching: function () { return "Recherche en cours..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* Select2 Galician translation
|
||||
*
|
||||
* Author: Leandro Regueiro <leandro.regueiro@gmail.com>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () {
|
||||
return "Non se atoparon resultados";
|
||||
},
|
||||
formatInputTooShort: function (input, min) {
|
||||
var n = min - input.length;
|
||||
if (n === 1) {
|
||||
return "Engada un carácter";
|
||||
} else {
|
||||
return "Engada " + n + " caracteres";
|
||||
}
|
||||
},
|
||||
formatInputTooLong: function (input, max) {
|
||||
var n = input.length - max;
|
||||
if (n === 1) {
|
||||
return "Elimine un carácter";
|
||||
} else {
|
||||
return "Elimine " + n + " caracteres";
|
||||
}
|
||||
},
|
||||
formatSelectionTooBig: function (limit) {
|
||||
if (limit === 1 ) {
|
||||
return "Só pode seleccionar un elemento";
|
||||
} else {
|
||||
return "Só pode seleccionar " + limit + " elementos";
|
||||
}
|
||||
},
|
||||
formatLoadMore: function (pageNumber) {
|
||||
return "Cargando máis resultados...";
|
||||
},
|
||||
formatSearching: function () {
|
||||
return "Buscando...";
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* Select2 Hebrew translation.
|
||||
*
|
||||
* Author: Yakir Sitbon <http://www.yakirs.net/>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "לא נמצאו התאמות"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "נא להזין עוד " + n + " תווים נוספים"; },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "נא להזין פחות " + n + " תווים"; },
|
||||
formatSelectionTooBig: function (limit) { return "ניתן לבחור " + limit + " פריטים"; },
|
||||
formatLoadMore: function (pageNumber) { return "טוען תוצאות נוספות..."; },
|
||||
formatSearching: function () { return "מחפש..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* Select2 Croatian translation.
|
||||
*
|
||||
* Author: Edi Modrić <edi.modric@gmail.com>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
var specialNumbers = {
|
||||
1: function(n) { return (n % 100 != 11 ? "znak" : "znakova"); },
|
||||
2: function(n) { return (n % 100 != 12 ? "znaka" : "znakova"); },
|
||||
3: function(n) { return (n % 100 != 13 ? "znaka" : "znakova"); },
|
||||
4: function(n) { return (n % 100 != 14 ? "znaka" : "znakova"); }
|
||||
};
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Nema rezultata"; },
|
||||
formatInputTooShort: function (input, min) {
|
||||
var n = min - input.length;
|
||||
var nMod10 = n % 10;
|
||||
|
||||
if (nMod10 > 0 && nMod10 < 5) {
|
||||
return "Unesite još " + n + " " + specialNumbers[nMod10](n);
|
||||
}
|
||||
|
||||
return "Unesite još " + n + " znakova";
|
||||
},
|
||||
formatInputTooLong: function (input, max) {
|
||||
var n = input.length - max;
|
||||
var nMod10 = n % 10;
|
||||
|
||||
if (nMod10 > 0 && nMod10 < 5) {
|
||||
return "Unesite " + n + " " + specialNumbers[nMod10](n) + " manje";
|
||||
}
|
||||
|
||||
return "Unesite " + n + " znakova manje";
|
||||
},
|
||||
formatSelectionTooBig: function (limit) { return "Maksimalan broj odabranih stavki je " + limit; },
|
||||
formatLoadMore: function (pageNumber) { return "Učitavanje rezultata..."; },
|
||||
formatSearching: function () { return "Pretraga..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Select2 Hungarian translation
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Nincs találat."; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Túl rövid. Még " + n + " karakter hiányzik."; },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Túl hosszú. " + n + " kerekterrel több mint kellene."; },
|
||||
formatSelectionTooBig: function (limit) { return "Csak " + limit + " elemet lehet kiválasztani."; },
|
||||
formatLoadMore: function (pageNumber) { return "Töltés..."; },
|
||||
formatSearching: function () { return "Keresés..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* Select2 Indonesian translation.
|
||||
*
|
||||
* Author: Ibrahim Yusuf <ibrahim7usuf@gmail.com>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Tidak ada data yang sesuai"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Masukkan " + n + " huruf lagi" + (n == 1 ? "" : "s"); },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Hapus " + n + " huruf" + (n == 1 ? "" : "s"); },
|
||||
formatSelectionTooBig: function (limit) { return "Anda hanya dapat memilih " + limit + " pilihan" + (limit == 1 ? "" : "s"); },
|
||||
formatLoadMore: function (pageNumber) { return "Mengambil data..."; },
|
||||
formatSearching: function () { return "Mencari..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* Select2 Icelandic translation.
|
||||
*
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Ekkert fannst"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Vinsamlegast skrifið " + n + " staf" + (n == 1 ? "" : "i") + " í viðbót"; },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Vinsamlegast styttið texta um " + n + " staf" + (n == 1 ? "" : "i"); },
|
||||
formatSelectionTooBig: function (limit) { return "Þú getur aðeins valið " + limit + " atriði"; },
|
||||
formatLoadMore: function (pageNumber) { return "Sæki fleiri niðurstöður..."; },
|
||||
formatSearching: function () { return "Leita..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Select2 Italian translation
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Nessuna corrispondenza trovata"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Inserisci ancora " + n + " caratter" + (n == 1? "e" : "i"); },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Inserisci " + n + " caratter" + (n == 1? "e" : "i") + " in meno"; },
|
||||
formatSelectionTooBig: function (limit) { return "Puoi selezionare solo " + limit + " element" + (limit == 1 ? "o" : "i"); },
|
||||
formatLoadMore: function (pageNumber) { return "Caricamento in corso..."; },
|
||||
formatSearching: function () { return "Ricerca..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Select2 Japanese translation.
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "該当なし"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "後" + n + "文字入れてください"; },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "検索文字列が" + n + "文字長すぎます"; },
|
||||
formatSelectionTooBig: function (limit) { return "最多で" + limit + "項目までしか選択できません"; },
|
||||
formatLoadMore: function (pageNumber) { return "読込中・・・"; },
|
||||
formatSearching: function () { return "検索中・・・"; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* Select2 <Language> translation.
|
||||
*
|
||||
* Author: Swen Mun <longfinfunnel@gmail.com>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "결과 없음"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "너무 짧습니다. "+n+"글자 더 입력해주세요."; },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "너무 깁니다. "+n+"글자 지워주세요."; },
|
||||
formatSelectionTooBig: function (limit) { return "최대 "+limit+"개까지만 선택하실 수 있습니다."; },
|
||||
formatLoadMore: function (pageNumber) { return "불러오는 중…"; },
|
||||
formatSearching: function () { return "검색 중…"; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* Select2 lithuanian translation.
|
||||
*
|
||||
* Author: CRONUS Karmalakas <cronus dot karmalakas at gmail dot com>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Atitikmenų nerasta"; },
|
||||
formatInputTooShort: function (input, min) {
|
||||
var n = min - input.length,
|
||||
suffix = (n % 10 == 1) && (n % 100 != 11) ? 'į' : (((n % 10 >= 2) && ((n % 100 < 10) || (n % 100 >= 20))) ? 'ius' : 'ių');
|
||||
return "Įrašykite dar " + n + " simbol" + suffix;
|
||||
},
|
||||
formatInputTooLong: function (input, max) {
|
||||
var n = input.length - max,
|
||||
suffix = (n % 10 == 1) && (n % 100 != 11) ? 'į' : (((n % 10 >= 2) && ((n % 100 < 10) || (n % 100 >= 20))) ? 'ius' : 'ių');
|
||||
return "Pašalinkite " + n + " simbol" + suffix;
|
||||
},
|
||||
formatSelectionTooBig: function (limit) {
|
||||
var n = limit,
|
||||
suffix = (n % 10 == 1) && (n % 100 != 11) ? 'ą' : (((n % 10 >= 2) && ((n % 100 < 10) || (n % 100 >= 20))) ? 'us' : 'ų');
|
||||
return "Jūs galite pasirinkti tik " + limit + " element" + suffix;
|
||||
},
|
||||
formatLoadMore: function (pageNumber) { return "Kraunama daugiau rezultatų..."; },
|
||||
formatSearching: function () { return "Ieškoma..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* Select2 Latvian translation
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Sakritību nav"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Lūdzu ievadiet vēl " + n + " simbol" + (n == 11 ? "us" : (/^\d*[1]$/im.test(n)? "u" : "us")); },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Lūdzu ievadiet par " + n + " simbol" + (n == 11 ? "iem" : (/^\d*[1]$/im.test(n)? "u" : "iem")) + " mazāk"; },
|
||||
formatSelectionTooBig: function (limit) { return "Jūs varat izvēlēties ne vairāk kā " + limit + " element" + (limit == 11 ? "us" : (/^\d*[1]$/im.test(limit)? "u" : "us")); },
|
||||
formatLoadMore: function (pageNumber) { return "Datu ielāde..."; },
|
||||
formatSearching: function () { return "Meklēšana..."; }
|
||||
});
|
||||
|
||||
})(jQuery);
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* Select2 Macedonian translation.
|
||||
*
|
||||
* Author: Marko Aleksic <psybaron@gmail.com>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Нема пронајдено совпаѓања"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Ве молиме внесете уште " + n + " карактер" + (n == 1 ? "" : "и"); },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Ве молиме внесете " + n + " помалку карактер" + (n == 1? "" : "и"); },
|
||||
formatSelectionTooBig: function (limit) { return "Можете да изберете само " + limit + " ставк" + (limit == 1 ? "а" : "и"); },
|
||||
formatLoadMore: function (pageNumber) { return "Вчитување резултати..."; },
|
||||
formatSearching: function () { return "Пребарување..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Select2 Dutch translation
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Geen resultaten gevonden"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Vul " + n + " karakter" + (n == 1? "" : "s") + " meer in"; },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Vul " + n + " karakter" + (n == 1? "" : "s") + " minder in"; },
|
||||
formatSelectionTooBig: function (limit) { return "Maximaal " + limit + " item" + (limit == 1 ? "" : "s") + " toegestaan"; },
|
||||
formatLoadMore: function (pageNumber) { return "Meer resultaten laden..."; },
|
||||
formatSearching: function () { return "Zoeken..."; },
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,18 @@
|
|||
/**
|
||||
* Select2 Norwegian translation.
|
||||
*
|
||||
* Author: Torgeir Veimo <torgeir.veimo@gmail.com>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Ingen treff"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Vennligst skriv inn " + n + (n>1 ? " flere tegn" : " tegn til"); },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Vennligst fjern " + n + " tegn"; },
|
||||
formatSelectionTooBig: function (limit) { return "Du kan velge maks " + limit + " elementer"; },
|
||||
formatLoadMore: function (pageNumber) { return "Laster flere resultater..."; },
|
||||
formatSearching: function () { return "Søker..."; }
|
||||
});
|
||||
})(jQuery);
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* Select2 Polish translation.
|
||||
*
|
||||
* Author: Jan Kondratowicz <jan@kondratowicz.pl>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
var pl_suffix = function(n) {
|
||||
if(n == 1) return "";
|
||||
if((n%100 > 1 && n%100 < 5) || (n%100 > 20 && n%10 > 1 && n%10 < 5)) return "i";
|
||||
return "ów";
|
||||
};
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () {
|
||||
return "Brak wyników.";
|
||||
},
|
||||
formatInputTooShort: function (input, min) {
|
||||
var n = min - input.length;
|
||||
return "Wpisz jeszcze " + n + " znak" + pl_suffix(n) + ".";
|
||||
},
|
||||
formatInputTooLong: function (input, max) {
|
||||
var n = input.length - max;
|
||||
return "Wpisana fraza jest za długa o " + n + " znak" + pl_suffix(n) + ".";
|
||||
},
|
||||
formatSelectionTooBig: function (limit) {
|
||||
return "Możesz zaznaczyć najwyżej " + limit + " element" + pl_suffix(limit) + ".";
|
||||
},
|
||||
formatLoadMore: function (pageNumber) {
|
||||
return "Ładowanie wyników...";
|
||||
},
|
||||
formatSearching: function () {
|
||||
return "Szukanie...";
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Select2 Brazilian Portuguese translation
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Nenhum resultado encontrado"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Informe " + n + " caracter" + (n == 1? "" : "es"); },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Apague " + n + " caracter" + (n == 1? "" : "es"); },
|
||||
formatSelectionTooBig: function (limit) { return "Só é possível selecionar " + limit + " elemento" + (limit == 1 ? "" : "s"); },
|
||||
formatLoadMore: function (pageNumber) { return "Carregando mais resultados..."; },
|
||||
formatSearching: function () { return "Buscando..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Select2 Portuguese (Portugal) translation
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Nenhum resultado encontrado"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Introduza " + n + " caracter" + (n == 1 ? "" : "es"); },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Apague " + n + " caracter" + (n == 1 ? "" : "es"); },
|
||||
formatSelectionTooBig: function (limit) { return "Só é possível selecionar " + limit + " elemento" + (limit == 1 ? "" : "s"); },
|
||||
formatLoadMore: function (pageNumber) { return "A carregar mais resultados..."; },
|
||||
formatSearching: function () { return "A pesquisar..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Select2 Romanian translation.
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Nu a fost găsit nimic"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Vă rugăm să introduceți incă " + n + " caracter" + (n == 1 ? "" : "e"); },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Vă rugăm să introduceți mai puțin de " + n + " caracter" + (n == 1? "" : "e"); },
|
||||
formatSelectionTooBig: function (limit) { return "Aveți voie să selectați cel mult " + limit + " element" + (limit == 1 ? "" : "e"); },
|
||||
formatLoadMore: function (pageNumber) { return "Se încarcă..."; },
|
||||
formatSearching: function () { return "Căutare..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Select2 Russian translation
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Совпадений не найдено"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Пожалуйста, введите еще " + n + " символ" + (n == 1 ? "" : ((n > 1)&&(n < 5) ? "а" : "ов")); },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Пожалуйста, введите на " + n + " символ" + (n == 1 ? "" : ((n > 1)&&(n < 5)? "а" : "ов")) + " меньше"; },
|
||||
formatSelectionTooBig: function (limit) { return "Вы можете выбрать не более " + limit + " элемент" + (limit == 1 ? "а" : "ов"); },
|
||||
formatLoadMore: function (pageNumber) { return "Загрузка данных..."; },
|
||||
formatSearching: function () { return "Поиск..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* Select2 Slovak translation.
|
||||
*
|
||||
* Author: David Vallner <david@vallner.net>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
// use text for the numbers 2 through 4
|
||||
var smallNumbers = {
|
||||
2: function(masc) { return (masc ? "dva" : "dve"); },
|
||||
3: function() { return "tri"; },
|
||||
4: function() { return "štyri"; }
|
||||
}
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Nenašli sa žiadne položky"; },
|
||||
formatInputTooShort: function (input, min) {
|
||||
var n = min - input.length;
|
||||
if (n == 1) {
|
||||
return "Prosím zadajte ešte jeden znak";
|
||||
} else if (n <= 4) {
|
||||
return "Prosím zadajte ešte ďalšie "+smallNumbers[n](true)+" znaky";
|
||||
} else {
|
||||
return "Prosím zadajte ešte ďalších "+n+" znakov";
|
||||
}
|
||||
},
|
||||
formatInputTooLong: function (input, max) {
|
||||
var n = input.length - max;
|
||||
if (n == 1) {
|
||||
return "Prosím zadajte o jeden znak menej";
|
||||
} else if (n <= 4) {
|
||||
return "Prosím zadajte o "+smallNumbers[n](true)+" znaky menej";
|
||||
} else {
|
||||
return "Prosím zadajte o "+n+" znakov menej";
|
||||
}
|
||||
},
|
||||
formatSelectionTooBig: function (limit) {
|
||||
if (limit == 1) {
|
||||
return "Môžete zvoliť len jednu položku";
|
||||
} else if (limit <= 4) {
|
||||
return "Môžete zvoliť najviac "+smallNumbers[limit](false)+" položky";
|
||||
} else {
|
||||
return "Môžete zvoliť najviac "+limit+" položiek";
|
||||
}
|
||||
},
|
||||
formatLoadMore: function (pageNumber) { return "Načítavajú sa ďalšie výsledky..."; },
|
||||
formatSearching: function () { return "Vyhľadávanie..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* Select2 Swedish translation.
|
||||
*
|
||||
* Author: Jens Rantil <jens.rantil@telavox.com>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Inga träffar"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Var god skriv in " + n + (n>1 ? " till tecken" : " tecken till"); },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Var god sudda ut " + n + " tecken"; },
|
||||
formatSelectionTooBig: function (limit) { return "Du kan max välja " + limit + " element"; },
|
||||
formatLoadMore: function (pageNumber) { return "Laddar fler resultat..."; },
|
||||
formatSearching: function () { return "Söker..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* Select2 Turkish translation.
|
||||
*
|
||||
* Author: Salim KAYABAŞI <salim.kayabasi@gmail.com>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Sonuç bulunamadı"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "En az " + n + " karakter daha girmelisiniz"; },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return n + " karakter azaltmalısınız"; },
|
||||
formatSelectionTooBig: function (limit) { return "Sadece " + limit + " seçim yapabilirsiniz"; },
|
||||
formatLoadMore: function (pageNumber) { return "Daha fazla..."; },
|
||||
formatSearching: function () { return "Aranıyor..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* Select2 <Language> translation.
|
||||
*
|
||||
* Author: bigmihail <bigmihail@bigmir.net>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Нічого не знайдено"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length, s = ["", "и", "ів"], p = [2,0,1,1,1,2]; return "Введіть буль ласка ще " + n + " символ" + s[ (n%100>4 && n%100<=20)? 2 : p[Math.min(n%10, 5)] ]; },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max, s = ["", "и", "ів"], p = [2,0,1,1,1,2]; return "Введіть буль ласка на " + n + " символ" + s[ (n%100>4 && n%100<=20)? 2 : p[Math.min(n%10, 5)] ] + " менше"; },
|
||||
formatSelectionTooBig: function (limit) {var s = ["", "и", "ів"], p = [2,0,1,1,1,2]; return "Ви можете вибрати лише " + limit + " елемент" + s[ (limit%100>4 && limit%100<=20)? 2 : p[Math.min(limit%10, 5)] ]; },
|
||||
formatLoadMore: function (pageNumber) { return "Завантаження даних..."; },
|
||||
formatSearching: function () { return "Пошук..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,18 @@
|
|||
/**
|
||||
* Select2 Vietnamese translation.
|
||||
*
|
||||
* Author: Long Nguyen <olragon@gmail.com>
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "Không tìm thấy kết quả"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "Vui lòng nhập nhiều hơn " + n + " ký tự" + (n == 1 ? "" : "s"); },
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "Vui lòng nhập ít hơn " + n + " ký tự" + (n == 1? "" : "s"); },
|
||||
formatSelectionTooBig: function (limit) { return "Chỉ có thể chọn được " + limit + " tùy chọn" + (limit == 1 ? "" : "s"); },
|
||||
formatLoadMore: function (pageNumber) { return "Đang lấy thêm kết quả..."; },
|
||||
formatSearching: function () { return "Đang tìm..."; }
|
||||
});
|
||||
})(jQuery);
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* Select2 Chinese translation
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "没有找到匹配项"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "请再输入" + n + "个字符";},
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "请删掉" + n + "个字符";},
|
||||
formatSelectionTooBig: function (limit) { return "你只能选择最多" + limit + "项"; },
|
||||
formatLoadMore: function (pageNumber) { return "加载结果中..."; },
|
||||
formatSearching: function () { return "搜索中..."; }
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* Select2 Traditional Chinese translation
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
$.extend($.fn.select2.defaults, {
|
||||
formatNoMatches: function () { return "沒有找到相符的項目"; },
|
||||
formatInputTooShort: function (input, min) { var n = min - input.length; return "請再輸入" + n + "個字元";},
|
||||
formatInputTooLong: function (input, max) { var n = input.length - max; return "請刪掉" + n + "個字元";},
|
||||
formatSelectionTooBig: function (limit) { return "你只能選擇最多" + limit + "項"; },
|
||||
formatLoadMore: function (pageNumber) { return "載入中..."; },
|
||||
formatSearching: function () { return "搜尋中..."; }
|
||||
});
|
||||
})(jQuery);
|
Binary file not shown.
After Width: | Height: | Size: 845 B |
|
@ -16,10 +16,10 @@
|
|||
</ul>
|
||||
<hr/>
|
||||
<div>
|
||||
<a href="#/realms/{{realm.id}}">Back to realm management...</a>
|
||||
<a href="#/create/application/{{realm.id}}">New Application...</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="#/create/application/{{realm.id}}">New Application...</a>
|
||||
<a href="#/realms/{{realm.id}}">Back to realm management...</a>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
|
@ -17,39 +17,74 @@
|
|||
|
||||
<form class="form-horizontal" name="realmForm" novalidate>
|
||||
<fieldset>
|
||||
<legend>Settings</legend>
|
||||
|
||||
<div data-kc-input>
|
||||
<label>Name</label>
|
||||
<div class="control-group">
|
||||
<label for="realmForm-name" class="control-label">Name</label>
|
||||
|
||||
<div class="controls">
|
||||
<input class="input-xlarge" type="text" name="name" data-ng-model="realm.name" autofocus
|
||||
required>
|
||||
</div>
|
||||
|
||||
<div data-kc-input>
|
||||
<label>Enabled</label>
|
||||
<input class="input-xlarge" type="checkbox" name="enabled" data-ng-model="realm.enabled">
|
||||
</div>
|
||||
|
||||
<div data-kc-input>
|
||||
<label>Social login</label>
|
||||
<input class="input-xlarge" type="checkbox" name="social" data-ng-model="realm.social">
|
||||
</div>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="control-group">
|
||||
<label class="control-label">Enabled</label>
|
||||
|
||||
<div data-kc-input>
|
||||
<label>Require SSL</label>
|
||||
<input class="input-xlarge" type="checkbox" name="requireSsl" data-ng-model="realm.requireSsl">
|
||||
<div class="controls">
|
||||
<input class="input-xlarge" type="checkbox" name="enabled"
|
||||
data-ng-model="realm.enabled">
|
||||
</div>
|
||||
|
||||
<div data-kc-input>
|
||||
<label>Cookie login allowed</label>
|
||||
<input class="input-xlarge" type="checkbox" name="cookieLoginAllowed" data-ng-model="realm.cookieLoginAllowed">
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="control-group">
|
||||
<label class="control-label">Social login</label>
|
||||
|
||||
<div data-kc-input>
|
||||
<label>User registration</label>
|
||||
<div class="controls">
|
||||
<input class="input-xlarge" type="checkbox" name="social"
|
||||
data-ng-model="realm.social">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="control-group">
|
||||
<label class="control-label">Require SSL</label>
|
||||
|
||||
<div class="controls">
|
||||
<input class="input-xlarge" type="checkbox" name="requireSsl"
|
||||
data-ng-model="realm.requireSsl">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="control-group">
|
||||
<label class="control-label">Cookie login allowed</label>
|
||||
|
||||
<div class="controls">
|
||||
<input class="input-xlarge" type="checkbox" name="cookieLoginAllowed"
|
||||
data-ng-model="realm.cookieLoginAllowed">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="control-group">
|
||||
<label class="control-label">User registration</label>
|
||||
|
||||
<div class="controls">
|
||||
<input class="input-xlarge" type="checkbox" name="userRegistration"
|
||||
data-ng-model="realm.userRegistration">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="realmForm-tokenLifespan" class="control-label">Token lifespan</label>
|
||||
|
@ -74,13 +109,21 @@
|
|||
data-ng-model="realm.accessCodeLifespan">
|
||||
<select style="width: auto;" name="accessCodeLifespanUnit"
|
||||
data-ng-model="realm.accessCodeLifespanUnit">
|
||||
<option value="SECONDS" data-ng-selected="!realm.accessCodeLifespanUnit">Seconds</option>
|
||||
<option value="SECONDS" data-ng-selected="!realm.accessCodeLifespanUnit">Seconds
|
||||
</option>
|
||||
<option value="MINUTES">Minutes</option>
|
||||
<option value="HOURS">Hours</option>
|
||||
<option value="DAYS">Days</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">User Required Credentials</label>
|
||||
|
||||
<div class="controls">
|
||||
<input style="width:250px" type="text" ui-select2="userCredentialOptions" ng-model="realm.requiredCredentials">
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="form-actions" data-ng-show="createRealm">
|
||||
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save
|
||||
|
|
|
@ -1,23 +1,22 @@
|
|||
<div data-ng-hide="createRealm">
|
||||
<nav id="local-nav">
|
||||
<ul class="nav nav-list">
|
||||
<li data-ng-class="!path[2] && 'active'"><a href="#/realms/{{realm.id}}">Realm Settings</a></li>
|
||||
<li data-ng-class="path[2] == 'roles' && 'active'"><a href="#/realms/{{realm.id}}/roles">Realm Roles</a>
|
||||
<ul class="sub-items">
|
||||
<li data-ng-class="path[0] == 'create' && path[1] == 'role' && 'active'"><a
|
||||
href="#/create/role/{{realm.id}}">Add Role</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-ng-class="path[2] == 'users' && 'active'"><a href="#/realms/{{realm.id}}/users">Realm Users</a>
|
||||
<li data-ng-class="path[2] == 'users' && 'active'"><a href="#/realms/{{realm.id}}/users">Users</a>
|
||||
<ul class="sub-items">
|
||||
<li data-ng-class="path[0] == 'create' && path[1] == 'user' && 'active'"><a
|
||||
href="#/create/user/{{realm.id}}">Add User</a></li>
|
||||
href="#/create/user/{{realm.id}}">New User</a></li>
|
||||
<li data-ng-class="path[0] == 'find' && path[1] == 'user' && 'active'"><a
|
||||
href="#/find/user/{{realm.id}}">Find User</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-ng-class="path[2] == 'roles' && 'active'"><a href="#/realms/{{realm.id}}/roles">Roles</a>
|
||||
<ul class="sub-items">
|
||||
<li data-ng-class="path[0] == 'create' && path[1] == 'role' && 'active'"><a
|
||||
href="#/create/role/{{realm.id}}">New Role</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-ng-class="path[2] == 'resources' && 'active'"><a href="#/realms/{{realm.id}}/applications">Manage Applications</a></li>
|
||||
|
||||
<li data-ng-class="!path[2] && 'active'"><a href="#/realms/{{realm.id}}">Realm Settings</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
|
@ -6,7 +6,7 @@ import org.keycloak.RealmConfiguration;
|
|||
import org.keycloak.VerificationException;
|
||||
import org.keycloak.representations.AccessTokenResponse;
|
||||
import org.keycloak.representations.SkeletonKeyToken;
|
||||
import org.keycloak.representations.idm.RequiredCredentialRepresentation;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
@ -230,7 +230,7 @@ public class ServletOAuthLogin {
|
|||
form.param("grant_type", "authorization_code")
|
||||
.param("code", code)
|
||||
.param("client_id", client_id)
|
||||
.param(RequiredCredentialRepresentation.PASSWORD, password)
|
||||
.param(CredentialRepresentation.PASSWORD, password)
|
||||
.param("redirect_uri", redirectUri);
|
||||
|
||||
Response res = realmInfo.getCodeUrl().request()
|
||||
|
|
|
@ -153,7 +153,7 @@ public class LoginBean {
|
|||
requiredCredentials = new LinkedList<RequiredCredential>();
|
||||
for (RequiredCredentialModel m : realm.getRequiredCredentials()) {
|
||||
if (m.isInput()) {
|
||||
requiredCredentials.add(new RequiredCredential(m.getType(), m.isSecret()));
|
||||
requiredCredentials.add(new RequiredCredential(m.getType(), m.isSecret(), m.getFormLabel()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -193,10 +193,12 @@ public class LoginBean {
|
|||
public class RequiredCredential {
|
||||
private String type;
|
||||
private boolean secret;
|
||||
private String formLabel;
|
||||
|
||||
public RequiredCredential(String type, boolean secure) {
|
||||
public RequiredCredential(String type, boolean secure, String formLabel) {
|
||||
this.type = type;
|
||||
this.secret = secure;
|
||||
this.formLabel = formLabel;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
@ -204,7 +206,7 @@ public class LoginBean {
|
|||
}
|
||||
|
||||
public String getLabel() {
|
||||
return type;
|
||||
return formLabel;
|
||||
}
|
||||
|
||||
public String getInputType() {
|
||||
|
|
|
@ -8,7 +8,7 @@ import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
|||
import org.keycloak.RSATokenVerifier;
|
||||
import org.keycloak.VerificationException;
|
||||
import org.keycloak.representations.SkeletonKeyToken;
|
||||
import org.keycloak.representations.idm.RequiredCredentialRepresentation;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.keycloak.services.models.RequiredCredentialModel;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
|
@ -206,9 +206,9 @@ public class AuthenticationManager {
|
|||
|
||||
List<RequiredCredentialModel> requiredCredentials = null;
|
||||
if (realm.hasRole(user, RealmManager.RESOURCE_ROLE)) {
|
||||
requiredCredentials = realm.getResourceRequiredCredentials();
|
||||
requiredCredentials = realm.getRequiredResourceCredentials();
|
||||
} else if (realm.hasRole(user, RealmManager.IDENTITY_REQUESTER_ROLE)) {
|
||||
requiredCredentials = realm.getOAuthClientRequiredCredentials();
|
||||
requiredCredentials = realm.getRequiredOAuthClientCredentials();
|
||||
} else {
|
||||
requiredCredentials = realm.getRequiredCredentials();
|
||||
}
|
||||
|
@ -216,21 +216,23 @@ public class AuthenticationManager {
|
|||
types.add(credential.getType());
|
||||
}
|
||||
|
||||
if (types.contains(RequiredCredentialRepresentation.PASSWORD)) {
|
||||
String password = formData.getFirst(RequiredCredentialRepresentation.PASSWORD);
|
||||
if (types.contains(CredentialRepresentation.PASSWORD)) {
|
||||
String password = formData.getFirst(CredentialRepresentation.PASSWORD);
|
||||
if (password == null) {
|
||||
logger.warn("Password not provided");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (types.contains(RequiredCredentialRepresentation.TOTP)) {
|
||||
String token = formData.getFirst(RequiredCredentialRepresentation.TOTP);
|
||||
if (types.contains(CredentialRepresentation.TOTP)) {
|
||||
String token = formData.getFirst(CredentialRepresentation.TOTP);
|
||||
if (token == null) {
|
||||
logger.warn("TOTP token not provided");
|
||||
return false;
|
||||
}
|
||||
logger.info("validating TOTP");
|
||||
return realm.validateTOTP(user, password, token);
|
||||
} else {
|
||||
logger.info("validating password for user: " + user.getLoginName());
|
||||
return realm.validatePassword(user, password);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -2,26 +2,19 @@ package org.keycloak.services.managers;
|
|||
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.RequiredCredentialRepresentation;
|
||||
import org.keycloak.representations.idm.ResourceRepresentation;
|
||||
import org.keycloak.representations.idm.RoleMappingRepresentation;
|
||||
import org.keycloak.representations.idm.RoleRepresentation;
|
||||
import org.keycloak.representations.idm.ScopeMappingRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.keycloak.services.models.RequiredCredentialModel;
|
||||
import org.keycloak.services.models.ResourceModel;
|
||||
import org.keycloak.services.models.RoleModel;
|
||||
import org.keycloak.services.models.UserCredentialModel;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
import org.keycloak.services.models.*;
|
||||
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
|
@ -105,19 +98,19 @@ public class RealmManager {
|
|||
Map<String, UserModel> userMap = new HashMap<String, UserModel>();
|
||||
|
||||
if (rep.getRequiredCredentials() != null) {
|
||||
for (RequiredCredentialRepresentation requiredCred : rep.getRequiredCredentials()) {
|
||||
for (String requiredCred : rep.getRequiredCredentials()) {
|
||||
addRequiredCredential(newRealm, requiredCred);
|
||||
}
|
||||
}
|
||||
|
||||
if (rep.getRequiredResourceCredentials() != null) {
|
||||
for (RequiredCredentialRepresentation requiredCred : rep.getRequiredCredentials()) {
|
||||
for (String requiredCred : rep.getRequiredCredentials()) {
|
||||
addResourceRequiredCredential(newRealm, requiredCred);
|
||||
}
|
||||
}
|
||||
|
||||
if (rep.getRequiredOAuthClientCredentials() != null) {
|
||||
for (RequiredCredentialRepresentation requiredCred : rep.getRequiredCredentials()) {
|
||||
for (String requiredCred : rep.getRequiredCredentials()) {
|
||||
addOAuthClientRequiredCredential(newRealm, requiredCred);
|
||||
}
|
||||
}
|
||||
|
@ -193,29 +186,18 @@ public class RealmManager {
|
|||
return user;
|
||||
}
|
||||
|
||||
public void addRequiredCredential(RealmModel newRealm, RequiredCredentialRepresentation requiredCred) {
|
||||
RequiredCredentialModel credential = initializeCred(requiredCred);
|
||||
newRealm.addRequiredCredential(credential);
|
||||
public void addRequiredCredential(RealmModel newRealm, String requiredCred) {
|
||||
newRealm.addRequiredCredential(requiredCred);
|
||||
}
|
||||
public void addResourceRequiredCredential(RealmModel newRealm, RequiredCredentialRepresentation requiredCred) {
|
||||
RequiredCredentialModel credential = initializeCred(requiredCred);
|
||||
newRealm.addResourceRequiredCredential(credential);
|
||||
public void addResourceRequiredCredential(RealmModel newRealm, String requiredCred) {
|
||||
newRealm.addRequiredResourceCredential(requiredCred);
|
||||
}
|
||||
public void addOAuthClientRequiredCredential(RealmModel newRealm, RequiredCredentialRepresentation requiredCred) {
|
||||
RequiredCredentialModel credential = initializeCred(requiredCred);
|
||||
newRealm.addOAuthClientRequiredCredential(credential);
|
||||
public void addOAuthClientRequiredCredential(RealmModel newRealm, String requiredCred) {
|
||||
newRealm.addRequiredOAuthClientCredential(requiredCred);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private RequiredCredentialModel initializeCred(RequiredCredentialRepresentation requiredCred) {
|
||||
RequiredCredentialModel credential = new RequiredCredentialModel();
|
||||
credential.setType(requiredCred.getType());
|
||||
credential.setInput(requiredCred.isInput());
|
||||
credential.setSecret(requiredCred.isSecret());
|
||||
return credential;
|
||||
}
|
||||
|
||||
protected void createResources(RealmRepresentation rep, RealmModel realm) {
|
||||
RoleModel loginRole = realm.getRole(RealmManager.RESOURCE_ROLE);
|
||||
ResourceManager manager = new ResourceManager(this);
|
||||
|
@ -232,4 +214,39 @@ public class RealmManager {
|
|||
return rep;
|
||||
}
|
||||
|
||||
public RealmRepresentation toRepresentation(RealmModel realm) {
|
||||
RealmRepresentation rep = new RealmRepresentation();
|
||||
rep.setId(realm.getId());
|
||||
rep.setRealm(realm.getName());
|
||||
rep.setEnabled(realm.isEnabled());
|
||||
rep.setSslNotRequired(realm.isSslNotRequired());
|
||||
rep.setCookieLoginAllowed(realm.isCookieLoginAllowed());
|
||||
rep.setPublicKey(realm.getPublicKeyPem());
|
||||
rep.setTokenLifespan(realm.getTokenLifespan());
|
||||
rep.setAccessCodeLifespan(realm.getAccessCodeLifespan());
|
||||
List<RequiredCredentialModel> requiredCredentialModels = realm.getRequiredCredentials();
|
||||
if (requiredCredentialModels.size() > 0) {
|
||||
rep.setRequiredCredentials(new ArrayList<String>());
|
||||
for (RequiredCredentialModel cred : requiredCredentialModels) {
|
||||
rep.getRequiredCredentials().add(cred.getType());
|
||||
}
|
||||
}
|
||||
List<RequiredCredentialModel> requiredResourceCredentialModels = realm.getRequiredResourceCredentials();
|
||||
if (requiredResourceCredentialModels.size() > 0) {
|
||||
rep.setRequiredResourceCredentials(new ArrayList<String>());
|
||||
for (RequiredCredentialModel cred : requiredResourceCredentialModels) {
|
||||
rep.getRequiredResourceCredentials().add(cred.getType());
|
||||
}
|
||||
}
|
||||
List<RequiredCredentialModel> requiredOAuthCredentialModels = realm.getRequiredOAuthClientCredentials();
|
||||
if (requiredOAuthCredentialModels.size() > 0) {
|
||||
rep.setRequiredOAuthClientCredentials(new ArrayList<String>());
|
||||
for (RequiredCredentialModel cred : requiredOAuthCredentialModels) {
|
||||
rep.getRequiredOAuthClientCredentials().add(cred.getType());
|
||||
}
|
||||
}
|
||||
return rep;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ public interface RealmModel {
|
|||
List<RequiredCredentialModel> getRequiredCredentials();
|
||||
|
||||
void addRequiredCredential(RequiredCredentialModel cred);
|
||||
void addRequiredCredential(String cred);
|
||||
|
||||
boolean validatePassword(UserModel user, String password);
|
||||
|
||||
|
@ -101,15 +102,19 @@ public interface RealmModel {
|
|||
|
||||
RoleModel getRoleById(String id);
|
||||
|
||||
void addResourceRequiredCredential(RequiredCredentialModel cred);
|
||||
void addRequiredResourceCredential(RequiredCredentialModel cred);
|
||||
|
||||
List<RequiredCredentialModel> getResourceRequiredCredentials();
|
||||
List<RequiredCredentialModel> getRequiredResourceCredentials();
|
||||
|
||||
void addOAuthClientRequiredCredential(RequiredCredentialModel cred);
|
||||
void addRequiredOAuthClientCredential(RequiredCredentialModel cred);
|
||||
|
||||
List<RequiredCredentialModel> getOAuthClientRequiredCredentials();
|
||||
List<RequiredCredentialModel> getRequiredOAuthClientCredentials();
|
||||
|
||||
boolean hasRole(UserModel user, String role);
|
||||
|
||||
ResourceModel getResourceById(String id);
|
||||
|
||||
void addRequiredOAuthClientCredential(String type);
|
||||
|
||||
void addRequiredResourceCredential(String type);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package org.keycloak.services.models;
|
||||
|
||||
import org.keycloak.representations.idm.RequiredCredentialRepresentation;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -10,16 +14,11 @@ public class RequiredCredentialModel {
|
|||
protected String type;
|
||||
protected boolean input;
|
||||
protected boolean secret;
|
||||
protected String formLabel;
|
||||
|
||||
public RequiredCredentialModel() {
|
||||
}
|
||||
|
||||
public RequiredCredentialModel(String type, boolean input, boolean secret) {
|
||||
this.type = type;
|
||||
this.input = input;
|
||||
this.secret = secret;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
@ -44,5 +43,39 @@ public class RequiredCredentialModel {
|
|||
this.secret = secret;
|
||||
}
|
||||
|
||||
public static final RequiredCredentialModel PASSWORD = new RequiredCredentialModel(RequiredCredentialRepresentation.PASSWORD, true, true);
|
||||
public String getFormLabel() {
|
||||
return formLabel;
|
||||
}
|
||||
|
||||
public void setFormLabel(String formLabel) {
|
||||
this.formLabel = formLabel;
|
||||
}
|
||||
|
||||
public static final Map<String, RequiredCredentialModel> BUILT_IN;
|
||||
public static final RequiredCredentialModel PASSWORD;
|
||||
public static final RequiredCredentialModel TOTP;
|
||||
public static final RequiredCredentialModel CLIENT_CERT;
|
||||
|
||||
static {
|
||||
Map<String, RequiredCredentialModel> map = new HashMap<String, RequiredCredentialModel>();
|
||||
PASSWORD = new RequiredCredentialModel();
|
||||
PASSWORD.setType(CredentialRepresentation.PASSWORD);
|
||||
PASSWORD.setInput(true);
|
||||
PASSWORD.setSecret(true);
|
||||
PASSWORD.setFormLabel("Password");
|
||||
map.put(PASSWORD.getType(), PASSWORD);
|
||||
TOTP = new RequiredCredentialModel();
|
||||
TOTP.setType(CredentialRepresentation.TOTP);
|
||||
TOTP.setInput(true);
|
||||
TOTP.setSecret(false);
|
||||
TOTP.setFormLabel("Authenticator Code");
|
||||
map.put(TOTP.getType(), TOTP);
|
||||
CLIENT_CERT = new RequiredCredentialModel();
|
||||
CLIENT_CERT.setType(CredentialRepresentation.CLIENT_CERT);
|
||||
CLIENT_CERT.setInput(false);
|
||||
CLIENT_CERT.setSecret(false);
|
||||
CLIENT_CERT.setFormLabel("Client Certificate");
|
||||
map.put(CLIENT_CERT.getType(), CLIENT_CERT);
|
||||
BUILT_IN = Collections.unmodifiableMap(map);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ public class UserCredentialModel {
|
|||
|
||||
protected String type;
|
||||
protected String value;
|
||||
protected String device;
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
|
@ -24,4 +25,12 @@ public class UserCredentialModel {
|
|||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
public void setDevice(String device) {
|
||||
this.device = device;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,4 +20,16 @@ public interface UserModel {
|
|||
String getAttribute(String name);
|
||||
|
||||
Map<String, String> getAttributes();
|
||||
|
||||
String getFirstName();
|
||||
|
||||
void setFirstName(String firstName);
|
||||
|
||||
String getLastName();
|
||||
|
||||
void setLastName(String lastName);
|
||||
|
||||
String getEmail();
|
||||
|
||||
void setEmail(String email);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package org.keycloak.services.models.picketlink;
|
|||
|
||||
import org.bouncycastle.openssl.PEMWriter;
|
||||
import org.jboss.resteasy.security.PemUtils;
|
||||
import org.keycloak.representations.idm.RequiredCredentialRepresentation;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
|
@ -259,13 +259,13 @@ public class RealmAdapter implements RealmModel {
|
|||
|
||||
|
||||
@Override
|
||||
public void addResourceRequiredCredential(RequiredCredentialModel cred) {
|
||||
public void addRequiredResourceCredential(RequiredCredentialModel cred) {
|
||||
ResourceRequiredCredentialRelationship relationship = new ResourceRequiredCredentialRelationship();
|
||||
addRequiredCredential(cred, relationship);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RequiredCredentialModel> getResourceRequiredCredentials() {
|
||||
public List<RequiredCredentialModel> getRequiredResourceCredentials() {
|
||||
RelationshipQuery<ResourceRequiredCredentialRelationship> query = getRelationshipManager().createRelationshipQuery(ResourceRequiredCredentialRelationship.class);
|
||||
query.setParameter(ResourceRequiredCredentialRelationship.REALM, realm.getName());
|
||||
List<ResourceRequiredCredentialRelationship> results = query.getResultList();
|
||||
|
@ -273,13 +273,13 @@ public class RealmAdapter implements RealmModel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addOAuthClientRequiredCredential(RequiredCredentialModel cred) {
|
||||
public void addRequiredOAuthClientCredential(RequiredCredentialModel cred) {
|
||||
OAuthClientRequiredCredentialRelationship relationship = new OAuthClientRequiredCredentialRelationship();
|
||||
addRequiredCredential(cred, relationship);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RequiredCredentialModel> getOAuthClientRequiredCredentials() {
|
||||
public List<RequiredCredentialModel> getRequiredOAuthClientCredentials() {
|
||||
RelationshipQuery<OAuthClientRequiredCredentialRelationship> query = getRelationshipManager().createRelationshipQuery(OAuthClientRequiredCredentialRelationship.class);
|
||||
query.setParameter(ResourceRequiredCredentialRelationship.REALM, realm.getName());
|
||||
List<OAuthClientRequiredCredentialRelationship> results = query.getResultList();
|
||||
|
@ -302,6 +302,7 @@ public class RealmAdapter implements RealmModel {
|
|||
model.setInput(relationship.isInput());
|
||||
model.setSecret(relationship.isSecret());
|
||||
model.setType(relationship.getCredentialType());
|
||||
model.setFormLabel(relationship.getFormLabel());
|
||||
rtn.add(model);
|
||||
}
|
||||
return rtn;
|
||||
|
@ -311,9 +312,35 @@ public class RealmAdapter implements RealmModel {
|
|||
relationship.setInput(cred.isInput());
|
||||
relationship.setSecret(cred.isSecret());
|
||||
relationship.setRealm(realm.getName());
|
||||
relationship.setFormLabel(cred.getFormLabel());
|
||||
getRelationshipManager().add(relationship);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRequiredCredential(String type) {
|
||||
RequiredCredentialModel model = initRequiredCredentialModel(type);
|
||||
addRequiredCredential(model);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRequiredOAuthClientCredential(String type) {
|
||||
RequiredCredentialModel model = initRequiredCredentialModel(type);
|
||||
addRequiredOAuthClientCredential(model);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRequiredResourceCredential(String type) {
|
||||
RequiredCredentialModel model = initRequiredCredentialModel(type);
|
||||
addRequiredResourceCredential(model);
|
||||
}
|
||||
|
||||
protected RequiredCredentialModel initRequiredCredentialModel(String type) {
|
||||
RequiredCredentialModel model = RequiredCredentialModel.BUILT_IN.get(type);
|
||||
if (model == null) {
|
||||
throw new RuntimeException("Unknown credential type " + type);
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validatePassword(UserModel user, String password) {
|
||||
|
@ -335,13 +362,14 @@ public class RealmAdapter implements RealmModel {
|
|||
@Override
|
||||
public void updateCredential(UserModel user, UserCredentialModel cred) {
|
||||
IdentityManager idm = getIdm();
|
||||
if (cred.getType().equals(RequiredCredentialRepresentation.PASSWORD)) {
|
||||
if (cred.getType().equals(CredentialRepresentation.PASSWORD)) {
|
||||
Password password = new Password(cred.getValue());
|
||||
idm.updateCredential(((UserAdapter)user).getUser(), password);
|
||||
} else if (cred.getType().equals(RequiredCredentialRepresentation.TOTP)) {
|
||||
} else if (cred.getType().equals(CredentialRepresentation.TOTP)) {
|
||||
TOTPCredential totp = new TOTPCredential(cred.getValue());
|
||||
totp.setDevice(cred.getDevice());
|
||||
idm.updateCredential(((UserAdapter)user).getUser(), totp);
|
||||
} else if (cred.getType().equals(RequiredCredentialRepresentation.CLIENT_CERT)) {
|
||||
} else if (cred.getType().equals(CredentialRepresentation.CLIENT_CERT)) {
|
||||
X509Certificate cert = null;
|
||||
try {
|
||||
cert = org.keycloak.PemUtils.decodeCertificate(cred.getValue());
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.keycloak.services.models.picketlink;
|
|||
import org.keycloak.services.models.UserModel;
|
||||
import org.picketlink.idm.IdentityManager;
|
||||
import org.picketlink.idm.model.Attribute;
|
||||
import org.picketlink.idm.model.annotation.AttributeProperty;
|
||||
import org.picketlink.idm.model.sample.User;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -41,6 +42,39 @@ public class UserAdapter implements UserModel {
|
|||
idm.update(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFirstName() {
|
||||
return user.getFirstName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFirstName(String firstName) {
|
||||
user.setFirstName(firstName);
|
||||
idm.update(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLastName() {
|
||||
return user.getLastName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastName(String lastName) {
|
||||
user.setLastName(lastName);
|
||||
idm.update(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEmail() {
|
||||
return user.getEmail();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEmail(String email) {
|
||||
user.setEmail(email);
|
||||
idm.update(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, String value) {
|
||||
user.setAttribute(new Attribute<String>(name, value));
|
||||
|
|
|
@ -68,4 +68,14 @@ public class RequiredCredentialRelationship extends AbstractAttributedType imple
|
|||
public void setSecret(boolean secret) {
|
||||
setAttribute(new Attribute<Boolean>("secret", secret));
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public String getFormLabel() {
|
||||
return (String)getAttribute("formLabel").getValue();
|
||||
}
|
||||
|
||||
public void setFormLabel(String label) {
|
||||
setAttribute(new Attribute<String>("formLabel", label));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import org.jboss.resteasy.spi.HttpRequest;
|
|||
import org.jboss.resteasy.spi.HttpResponse;
|
||||
import org.jboss.resteasy.spi.NotImplementedYetException;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.representations.idm.RequiredCredentialRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.services.managers.AuthenticationManager;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
|
@ -19,6 +18,7 @@ import org.keycloak.services.resources.admin.RealmsAdminResource;
|
|||
import javax.ws.rs.*;
|
||||
import javax.ws.rs.core.*;
|
||||
import java.net.URI;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -109,7 +109,7 @@ public class SaasService {
|
|||
if (user == null) {
|
||||
return Response.status(401).build();
|
||||
}
|
||||
return Response.ok(new WhoAmI(user.getLoginName(), user.getLoginName())).build();
|
||||
return Response.ok(new WhoAmI(user.getLoginName(), user.getFirstName() + " " + user.getLastName())).build();
|
||||
}
|
||||
}.call();
|
||||
}
|
||||
|
@ -295,7 +295,7 @@ public class SaasService {
|
|||
@Path("registrations")
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
public Response processRegister(final @FormParam("name") String name,
|
||||
public Response processRegister(final @FormParam("name") String fullname,
|
||||
final @FormParam("email") String email,
|
||||
final @FormParam("username") String username,
|
||||
final @FormParam("password") String password,
|
||||
|
@ -312,7 +312,29 @@ public class SaasService {
|
|||
RealmModel defaultRealm = realmManager.defaultRealm();
|
||||
UserRepresentation newUser = new UserRepresentation();
|
||||
newUser.setUsername(username);
|
||||
newUser.credential(RequiredCredentialRepresentation.PASSWORD, password, false);
|
||||
newUser.setEmail(email);
|
||||
if (fullname != null) {
|
||||
StringTokenizer tokenizer = new StringTokenizer(fullname, " ");
|
||||
StringBuffer first = null;
|
||||
String last = "";
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
String token = tokenizer.nextToken();
|
||||
if (tokenizer.hasMoreTokens()) {
|
||||
if (first == null) {
|
||||
first = new StringBuffer();
|
||||
} else {
|
||||
first.append(" ");
|
||||
}
|
||||
first.append(token);
|
||||
} else {
|
||||
last = token;
|
||||
}
|
||||
}
|
||||
if (first == null) first = new StringBuffer();
|
||||
newUser.setFirstName(first.toString());
|
||||
newUser.setLastName(last);
|
||||
}
|
||||
newUser.credential(CredentialRepresentation.PASSWORD, password);
|
||||
UserModel user = registerMe(defaultRealm, newUser);
|
||||
if (user == null) {
|
||||
request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Username already exists.");
|
||||
|
@ -340,6 +362,9 @@ public class SaasService {
|
|||
}
|
||||
|
||||
user = defaultRealm.addUser(newUser.getUsername());
|
||||
user.setFirstName(newUser.getFirstName());
|
||||
user.setLastName(newUser.getLastName());
|
||||
user.setEmail(newUser.getEmail());
|
||||
for (CredentialRepresentation cred : newUser.getCredentials()) {
|
||||
UserCredentialModel credModel = new UserCredentialModel();
|
||||
credModel.setType(cred.getType());
|
||||
|
|
|
@ -7,6 +7,7 @@ import org.keycloak.representations.idm.RoleRepresentation;
|
|||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.keycloak.services.models.RequiredCredentialModel;
|
||||
import org.keycloak.services.models.RoleModel;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
import org.keycloak.services.resources.PublicRealmResource;
|
||||
|
@ -60,21 +61,12 @@ public class RealmAdminResource {
|
|||
return new Transaction() {
|
||||
@Override
|
||||
protected RealmRepresentation callImpl() {
|
||||
RealmRepresentation rep = new RealmRepresentation();
|
||||
rep.setId(realm.getId());
|
||||
rep.setRealm(realm.getName());
|
||||
rep.setEnabled(realm.isEnabled());
|
||||
rep.setSslNotRequired(realm.isSslNotRequired());
|
||||
rep.setCookieLoginAllowed(realm.isCookieLoginAllowed());
|
||||
rep.setPublicKey(realm.getPublicKeyPem());
|
||||
rep.setTokenLifespan(realm.getTokenLifespan());
|
||||
rep.setAccessCodeLifespan(realm.getAccessCodeLifespan());
|
||||
return rep;
|
||||
return new RealmManager(session).toRepresentation(realm);
|
||||
}
|
||||
}.call();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Path("roles")
|
||||
@GET
|
||||
@NoCache
|
||||
|
|
|
@ -6,7 +6,7 @@ import org.junit.Before;
|
|||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.keycloak.representations.idm.RequiredCredentialRepresentation;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.KeycloakSessionFactory;
|
||||
|
@ -19,6 +19,7 @@ import org.keycloak.services.resources.KeycloakApplication;
|
|||
|
||||
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -52,6 +53,16 @@ public class AdapterTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMe() {
|
||||
String hello = "Bill Burke";
|
||||
StringTokenizer tokenizer = new StringTokenizer(hello, " ");
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
System.out.println("token: " + tokenizer.nextToken());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test1CreateRealm() throws Exception {
|
||||
realmModel = adapter.createRealm("JUGGLER");
|
||||
|
@ -77,26 +88,23 @@ public class AdapterTest {
|
|||
@Test
|
||||
public void test2RequiredCredential() throws Exception {
|
||||
test1CreateRealm();
|
||||
RequiredCredentialModel creds = new RequiredCredentialModel();
|
||||
creds.setSecret(true);
|
||||
creds.setType(RequiredCredentialRepresentation.PASSWORD);
|
||||
creds.setInput(true);
|
||||
realmModel.addRequiredCredential(creds);
|
||||
creds = new RequiredCredentialModel();
|
||||
creds.setSecret(true);
|
||||
creds.setType(RequiredCredentialRepresentation.TOTP);
|
||||
creds.setInput(true);
|
||||
realmModel.addRequiredCredential(creds);
|
||||
realmModel.addRequiredCredential(CredentialRepresentation.PASSWORD);
|
||||
realmModel.addRequiredCredential(CredentialRepresentation.TOTP);
|
||||
List<RequiredCredentialModel> storedCreds = realmModel.getRequiredCredentials();
|
||||
Assert.assertEquals(2, storedCreds.size());
|
||||
boolean totp = false;
|
||||
boolean password = false;
|
||||
for (RequiredCredentialModel cred : storedCreds) {
|
||||
if (cred.getType().equals(RequiredCredentialRepresentation.PASSWORD)) password = true;
|
||||
else if (cred.getType().equals(RequiredCredentialRepresentation.TOTP)) totp = true;
|
||||
Assert.assertTrue(cred.isInput());
|
||||
if (cred.getType().equals(CredentialRepresentation.PASSWORD)) {
|
||||
password = true;
|
||||
Assert.assertTrue(cred.isSecret());
|
||||
}
|
||||
else if (cred.getType().equals(CredentialRepresentation.TOTP)) {
|
||||
totp = true;
|
||||
Assert.assertFalse(cred.isSecret());
|
||||
}
|
||||
}
|
||||
Assert.assertTrue(totp);
|
||||
Assert.assertTrue(password);
|
||||
}
|
||||
|
@ -106,7 +114,7 @@ public class AdapterTest {
|
|||
test1CreateRealm();
|
||||
UserModel user = realmModel.addUser("bburke");
|
||||
UserCredentialModel cred = new UserCredentialModel();
|
||||
cred.setType(RequiredCredentialRepresentation.PASSWORD);
|
||||
cred.setType(CredentialRepresentation.PASSWORD);
|
||||
cred.setValue("geheim");
|
||||
realmModel.updateCredential(user, cred);
|
||||
Assert.assertTrue(realmModel.validatePassword(user, "geheim"));
|
||||
|
|
|
@ -70,6 +70,8 @@ public class ImportTest {
|
|||
realm.addRealmAdmin(admin);
|
||||
List<RequiredCredentialModel> creds = realm.getRequiredCredentials();
|
||||
Assert.assertEquals(1, creds.size());
|
||||
RequiredCredentialModel cred = creds.get(0);
|
||||
Assert.assertEquals("Password", cred.getFormLabel());
|
||||
|
||||
UserModel user = realm.getUser("loginclient");
|
||||
Assert.assertNotNull(user);
|
||||
|
@ -83,6 +85,29 @@ public class ImportTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void install2() throws Exception {
|
||||
RealmModel defaultRealm = manager.createRealm(RealmModel.DEFAULT_REALM, RealmModel.DEFAULT_REALM);
|
||||
defaultRealm.setName(RealmModel.DEFAULT_REALM);
|
||||
defaultRealm.setEnabled(true);
|
||||
defaultRealm.setTokenLifespan(300);
|
||||
defaultRealm.setAccessCodeLifespan(60);
|
||||
defaultRealm.setSslNotRequired(false);
|
||||
defaultRealm.setCookieLoginAllowed(true);
|
||||
defaultRealm.setRegistrationAllowed(true);
|
||||
manager.generateRealmKeys(defaultRealm);
|
||||
defaultRealm.addRequiredCredential(RequiredCredentialModel.PASSWORD);
|
||||
RoleModel role = defaultRealm.addRole(SaasService.REALM_CREATOR_ROLE);
|
||||
UserModel admin = defaultRealm.addUser("admin");
|
||||
defaultRealm.grantRole(admin, role);
|
||||
|
||||
RealmRepresentation rep = KeycloakTestBase.loadJson("testrealm-demo.json");
|
||||
RealmModel realm = manager.createRealm("demo", rep.getRealm());
|
||||
manager.importRealm(rep, realm);
|
||||
realm.addRealmAdmin(admin);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ import org.junit.BeforeClass;
|
|||
import org.junit.Test;
|
||||
import org.keycloak.SkeletonKeyContextResolver;
|
||||
import org.keycloak.representations.AccessTokenResponse;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.RequiredCredentialRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.services.managers.AuthenticationManager;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
|
@ -61,7 +61,7 @@ public class RealmCreationTest {
|
|||
public void testRegisterLoginAndCreate() throws Exception {
|
||||
UserRepresentation user = new UserRepresentation();
|
||||
user.setUsername("bburke");
|
||||
user.credential(RequiredCredentialRepresentation.PASSWORD, "geheim", false);
|
||||
user.credential(CredentialRepresentation.PASSWORD, "geheim");
|
||||
|
||||
WebTarget target = client.target(generateURL("/"));
|
||||
Response response = target.path("saas/registrations").request().post(Entity.json(user));
|
||||
|
@ -73,14 +73,14 @@ public class RealmCreationTest {
|
|||
try {
|
||||
Form form = new Form();
|
||||
form.param(AuthenticationManager.FORM_USERNAME, "bburke");
|
||||
form.param(RequiredCredentialRepresentation.PASSWORD, "badpassword");
|
||||
form.param(CredentialRepresentation.PASSWORD, "badpassword");
|
||||
tokenResponse = target.path("realms").path(RealmModel.DEFAULT_REALM).path("tokens/grants/identity-token").request().post(Entity.form(form), AccessTokenResponse.class);
|
||||
Assert.fail();
|
||||
} catch (NotAuthorizedException e) {
|
||||
}
|
||||
Form form = new Form();
|
||||
form.param(AuthenticationManager.FORM_USERNAME, "bburke");
|
||||
form.param(RequiredCredentialRepresentation.PASSWORD, "geheim");
|
||||
form.param(CredentialRepresentation.PASSWORD, "geheim");
|
||||
tokenResponse = target.path("realms").path(RealmModel.DEFAULT_REALM).path("tokens/grants/identity-token").request().post(Entity.form(form), AccessTokenResponse.class);
|
||||
Assert.assertNotNull(tokenResponse);
|
||||
System.out.println(tokenResponse.getToken());
|
||||
|
|
86
services/src/test/resources/testrealm-demo.json
Executable file
86
services/src/test/resources/testrealm-demo.json
Executable file
|
@ -0,0 +1,86 @@
|
|||
{
|
||||
"realm": "demo",
|
||||
"enabled": true,
|
||||
"tokenLifespan": 300,
|
||||
"accessCodeLifespan": 10,
|
||||
"sslNotRequired": true,
|
||||
"cookieLoginAllowed": true,
|
||||
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
|
||||
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
||||
"requiredCredentials": [ "password" ],
|
||||
"requiredResourceCredentials": [ "password" ],
|
||||
"requiredOAuthClientCredentials": [ "password" ],
|
||||
"users" : [
|
||||
{
|
||||
"username" : "bburke@redhat.com",
|
||||
"enabled" : true,
|
||||
"attributes" : {
|
||||
"email" : "bburke@redhat.com"
|
||||
},
|
||||
"credentials" : [
|
||||
{ "type" : "Password",
|
||||
"value" : "password" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"username" : "third-party",
|
||||
"enabled" : true,
|
||||
"credentials" : [
|
||||
{ "type" : "Password",
|
||||
"value" : "password" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"roles": [
|
||||
{
|
||||
"name": "user",
|
||||
"description": "Have User privileges"
|
||||
},
|
||||
{
|
||||
"name": "admin",
|
||||
"description": "Have Administrator privileges"
|
||||
}
|
||||
],
|
||||
"roleMappings": [
|
||||
{
|
||||
"username": "bburke@redhat.com",
|
||||
"roles": ["user"]
|
||||
},
|
||||
{
|
||||
"username": "third-party",
|
||||
"roles": ["KEYCLOAK_IDENTITY_REQUESTER"]
|
||||
}
|
||||
],
|
||||
"scopeMappings": [
|
||||
{
|
||||
"username": "third-party",
|
||||
"roles": ["user"]
|
||||
}
|
||||
],
|
||||
"resources": [
|
||||
{
|
||||
"name": "customer-portal",
|
||||
"enabled": true,
|
||||
"adminUrl": "http://localhost:8080/customer-portal/j_admin_request",
|
||||
"useRealmMappings": true,
|
||||
"credentials": [
|
||||
{
|
||||
"type": "password",
|
||||
"value": "password"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "product-portal",
|
||||
"enabled": true,
|
||||
"adminUrl": "http://localhost:8080/product-portal/j_admin_request",
|
||||
"useRealmMappings": true,
|
||||
"credentials": [
|
||||
{
|
||||
"type": "password",
|
||||
"value": "password"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,118 +1,116 @@
|
|||
{
|
||||
"realm" : "test-realm",
|
||||
"enabled" : true,
|
||||
"tokenLifespan" : 6000,
|
||||
"accessCodeLifespan" : 30,
|
||||
"requiredCredentials" : [
|
||||
"realm": "test-realm",
|
||||
"enabled": true,
|
||||
"tokenLifespan": 6000,
|
||||
"accessCodeLifespan": 30,
|
||||
"requiredCredentials": [ "password" ],
|
||||
"requiredResourceCredentials": [ "password" ],
|
||||
"requiredOAuthClientCredentials": [ "password" ],
|
||||
"users": [
|
||||
{
|
||||
"type" : "Password",
|
||||
"input" : true,
|
||||
"secret" : true
|
||||
}
|
||||
],
|
||||
"requiredResourceCredentials" : [
|
||||
{
|
||||
"type" : "Password",
|
||||
"input" : true,
|
||||
"secret" : true
|
||||
}
|
||||
],
|
||||
"requiredOAuthClientCredentials" : [
|
||||
{
|
||||
"type" : "Password",
|
||||
"input" : true,
|
||||
"secret" : true
|
||||
}
|
||||
],
|
||||
"users" : [
|
||||
{
|
||||
"username" : "wburke",
|
||||
"enabled" : true,
|
||||
"attributes" : {
|
||||
"email" : "bburke@redhat.com"
|
||||
},
|
||||
"credentials" : [
|
||||
{ "type" : "Password",
|
||||
"value" : "userpassword" }
|
||||
]
|
||||
"username": "wburke",
|
||||
"enabled": true,
|
||||
"attributes": {
|
||||
"email": "bburke@redhat.com"
|
||||
},
|
||||
"credentials": [
|
||||
{
|
||||
"username" : "loginclient",
|
||||
"enabled" : true,
|
||||
"credentials" : [
|
||||
{ "type" : "Password",
|
||||
"value" : "clientpassword" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"username" : "admin",
|
||||
"enabled" : true,
|
||||
"credentials" : [
|
||||
{ "type" : "Password",
|
||||
"value" : "adminpassword" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"username" : "oauthclient",
|
||||
"enabled" : true,
|
||||
"credentials" : [
|
||||
{ "type" : "Password",
|
||||
"value" : "clientpassword" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"roleMappings" : [
|
||||
{
|
||||
"username" : "admin",
|
||||
"roles" : ["admin"]
|
||||
}
|
||||
],
|
||||
"scopeMappings" : [
|
||||
{
|
||||
"username" : "loginclient",
|
||||
"roles" : ["*"]
|
||||
}
|
||||
],
|
||||
"resources" : [
|
||||
{
|
||||
"name" : "Application",
|
||||
"enabled" : true,
|
||||
"roles" : [
|
||||
{ "name" : "admin" },
|
||||
{ "name" : "user" }
|
||||
],
|
||||
"roleMappings" : [
|
||||
{
|
||||
"username" : "wburke",
|
||||
"roles" : ["user"]
|
||||
},
|
||||
{
|
||||
"username" : "admin",
|
||||
"roles" : ["admin"]
|
||||
}
|
||||
],
|
||||
"scopeMappings" : [
|
||||
{
|
||||
"username" : "oauthclient",
|
||||
"roles" : ["user"]
|
||||
"type": "password",
|
||||
"value": "userpassword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "OtherApp",
|
||||
"enabled" : true,
|
||||
"roles" : [
|
||||
{ "name" : "admin" },
|
||||
{ "name" : "user" }
|
||||
],
|
||||
"roleMappings" : [
|
||||
"username": "loginclient",
|
||||
"enabled": true,
|
||||
"credentials": [
|
||||
{
|
||||
"username" : "wburke",
|
||||
"roles" : ["user"]
|
||||
"type": "password",
|
||||
"value": "clientpassword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"username" : "admin",
|
||||
"roles" : ["admin"]
|
||||
"username": "admin",
|
||||
"enabled": true,
|
||||
"credentials": [
|
||||
{
|
||||
"type": "password",
|
||||
"value": "adminpassword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"username": "oauthclient",
|
||||
"enabled": true,
|
||||
"credentials": [
|
||||
{
|
||||
"type": "password",
|
||||
"value": "clientpassword"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"roleMappings": [
|
||||
{
|
||||
"username": "admin",
|
||||
"roles": ["admin"]
|
||||
}
|
||||
],
|
||||
"scopeMappings": [
|
||||
{
|
||||
"username": "loginclient",
|
||||
"roles": ["*"]
|
||||
}
|
||||
],
|
||||
"resources": [
|
||||
{
|
||||
"name": "Application",
|
||||
"enabled": true,
|
||||
"roles": [
|
||||
{
|
||||
"name": "admin"
|
||||
},
|
||||
{
|
||||
"name": "user"
|
||||
}
|
||||
],
|
||||
"roleMappings": [
|
||||
{
|
||||
"username": "wburke",
|
||||
"roles": ["user"]
|
||||
},
|
||||
{
|
||||
"username": "admin",
|
||||
"roles": ["admin"]
|
||||
}
|
||||
],
|
||||
"scopeMappings": [
|
||||
{
|
||||
"username": "oauthclient",
|
||||
"roles": ["user"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "OtherApp",
|
||||
"enabled": true,
|
||||
"roles": [
|
||||
{
|
||||
"name": "admin"
|
||||
},
|
||||
{
|
||||
"name": "user"
|
||||
}
|
||||
],
|
||||
"roleMappings": [
|
||||
{
|
||||
"username": "wburke",
|
||||
"roles": ["user"]
|
||||
},
|
||||
{
|
||||
"username": "admin",
|
||||
"roles": ["admin"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue