saml key refactor

This commit is contained in:
Bill Burke
2014-10-24 10:58:32 -04:00
parent ad7e2cd12e
commit ce76270ad8
26 changed files with 1688 additions and 130 deletions

View File

@@ -476,8 +476,8 @@ module.config([ '$routeProvider', function($routeProvider) {
},
controller : 'ApplicationClusteringNodeCtrl'
})
.when('/realms/:realm/applications/:application/certificate', {
templateUrl : 'partials/application-keys.html',
.when('/realms/:realm/applications/:application/saml/keys', {
templateUrl : 'partials/application-saml-keys.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
@@ -486,7 +486,31 @@ module.config([ '$routeProvider', function($routeProvider) {
return ApplicationLoader();
}
},
controller : 'ApplicationCertificateCtrl'
controller : 'ApplicationSamlKeyCtrl'
})
.when('/realms/:realm/applications/:application/saml/:keyType/import/:attribute', {
templateUrl : 'partials/application-saml-key-import.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
}
},
controller : 'ApplicationCertificateImportCtrl'
})
.when('/realms/:realm/applications/:application/saml/:keyType/export/:attribute', {
templateUrl : 'partials/application-saml-key-export.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
}
},
controller : 'ApplicationCertificateExportCtrl'
})
.when('/realms/:realm/applications/:application/roles', {
templateUrl : 'partials/application-role-list.html',

View File

@@ -43,6 +43,193 @@ module.controller('ApplicationCredentialsCtrl', function($scope, $location, real
});
});
module.controller('ApplicationSamlKeyCtrl', function($scope, $location, $http, $upload, realm, application,
ApplicationCertificate, ApplicationCertificateGenerate,
ApplicationCertificateDownload, Notifications) {
$scope.realm = realm;
$scope.application = application;
var signingKeyInfo = ApplicationCertificate.get({ realm : realm.realm, application : application.id, attribute: 'saml.signing' },
function() {
$scope.signingKeyInfo = signingKeyInfo;
}
);
$scope.generateSigningKey = function() {
var keyInfo = ApplicationCertificateGenerate.generate({ realm : realm.realm, application : application.id, attribute: 'saml.signing' },
function() {
Notifications.success('Signing key has been regenerated.');
$scope.signingKeyInfo = keyInfo;
},
function() {
Notifications.error("Signing key was not regenerated.");
}
);
};
$scope.importSigningKey = function() {
$location.url("/realms/" + realm.realm + "/applications/" + application.id + "/saml/Signing/import/saml.signing");
};
$scope.exportSigningKey = function() {
$location.url("/realms/" + realm.realm + "/applications/" + application.id + "/saml/Signing/export/saml.signing");
};
var encryptionKeyInfo = ApplicationCertificate.get({ realm : realm.realm, application : application.id, attribute: 'saml.encryption' },
function() {
$scope.encryptionKeyInfo = encryptionKeyInfo;
}
);
$scope.generateEncryptionKey = function() {
var keyInfo = ApplicationCertificateGenerate.generate({ realm : realm.realm, application : application.id, attribute: 'saml.encryption' },
function() {
Notifications.success('Encryption key has been regenerated.');
$scope.encryptionKeyInfo = keyInfo;
},
function() {
Notifications.error("Encryption key was not regenerated.");
}
);
};
$scope.importEncryptionKey = function() {
$location.url("/realms/" + realm.realm + "/applications/" + application.id + "/saml/Encryption/import/saml.encryption");
};
$scope.exportEncryptionKey = function() {
$location.url("/realms/" + realm.realm + "/applications/" + application.id + "/saml/Encryption/export/saml.encryption");
};
$scope.$watch(function() {
return $location.path();
}, function() {
$scope.path = $location.path().substring(1).split("/");
});
});
module.controller('ApplicationCertificateImportCtrl', function($scope, $location, $http, $upload, realm, application, $routeParams,
ApplicationCertificate, ApplicationCertificateGenerate,
ApplicationCertificateDownload, Notifications) {
var keyType = $routeParams.keyType;
var attribute = $routeParams.attribute;
$scope.realm = realm;
$scope.application = application;
$scope.keyType = keyType;
$scope.files = [];
$scope.onFileSelect = function($files) {
$scope.files = $files;
};
$scope.clearFileSelect = function() {
$scope.files = null;
}
$scope.keyFormats = [
"JKS",
"PKCS12"
];
$scope.uploadKeyFormat = $scope.keyFormats[0];
$scope.uploadFile = function() {
//$files: an array of files selected, each file has name, size, and type.
for (var i = 0; i < $scope.files.length; i++) {
var $file = $scope.files[i];
$scope.upload = $upload.upload({
url: authUrl + '/admin/realms/' + realm.realm + '/applications-by-id/' + application.id + '/certificates/' + attribute + '/upload',
// method: POST or PUT,
// headers: {'headerKey': 'headerValue'}, withCredential: true,
data: {keystoreFormat: $scope.uploadKeyFormat,
keyAlias: $scope.uploadKeyAlias,
keyPassword: $scope.uploadKeyPassword,
storePassword: $scope.uploadStorePassword
},
file: $file
/* set file formData name for 'Content-Desposition' header. Default: 'file' */
//fileFormDataName: myFile,
/* customize how data is added to formData. See #40#issuecomment-28612000 for example */
//formDataAppender: function(formData, key, val){}
}).progress(function(evt) {
console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
}).success(function(data, status, headers) {
Notifications.success("Keystore uploaded successfully.");
$location.url("/realms/" + realm.realm + "/applications/" + application.id + "/saml/keys");
})
.error(function() {
Notifications.error("The key store can not be uploaded. Please verify the file.");
});
//.then(success, error, progress);
}
};
$scope.$watch(function() {
return $location.path();
}, function() {
$scope.path = $location.path().substring(1).split("/");
});
});
module.controller('ApplicationCertificateExportCtrl', function($scope, $location, $http, $upload, realm, application, $routeParams,
ApplicationCertificate, ApplicationCertificateGenerate,
ApplicationCertificateDownload, Notifications) {
var keyType = $routeParams.keyType;
var attribute = $routeParams.attribute;
$scope.realm = realm;
$scope.application = application;
$scope.keyType = keyType;
var jks = {
keyAlias: application.name,
realmAlias: realm.realm
};
$scope.keyFormats = [
"JKS",
"PKCS12"
];
var keyInfo = ApplicationCertificate.get({ realm : realm.realm, application : application.id, attribute: attribute },
function() {
$scope.keyInfo = keyInfo;
}
);
$scope.jks = jks;
$scope.jks.format = $scope.keyFormats[0];
$scope.download = function() {
$http({
url: authUrl + '/admin/realms/' + realm.realm + '/applications-by-id/' + application.id + '/certificates/' + attribute + '/download',
method: 'POST',
responseType: 'arraybuffer',
data: $scope.jks,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/octet-stream'
}
}).success(function(data){
var blob = new Blob([data], {
type: 'application/octet-stream'
});
var ext = ".jks";
if ($scope.jks.format == 'PKCS12') ext = ".p12";
saveAs(blob, 'keystore' + ext);
}).error(function(){
Notifications.error("Error downloading.");
});
}
$scope.$watch(function() {
return $location.path();
}, function() {
$scope.path = $location.path().substring(1).split("/");
});
});
module.controller('ApplicationCertificateCtrl', function($scope, $location, $http, $upload, realm, application,
ApplicationCertificate, ApplicationCertificateGenerate,
ApplicationCertificateDownload, Notifications) {

View File

@@ -708,16 +708,18 @@ module.factory('ApplicationTestNodesAvailable', function($resource) {
});
module.factory('ApplicationCertificate', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/certificates', {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/certificates/:attribute', {
realm : '@realm',
application : "@application"
application : "@application",
attribute: "@attribute"
});
});
module.factory('ApplicationCertificateGenerate', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/certificates/generate', {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/certificates/:attribute/generate', {
realm : '@realm',
application : "@application"
application : "@application",
attribute: "@attribute"
},
{
generate : {
@@ -727,9 +729,10 @@ module.factory('ApplicationCertificateGenerate', function($resource) {
});
module.factory('ApplicationCertificateDownload', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/certificates/download', {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/certificates/:attribute/download', {
realm : '@realm',
application : "@application"
application : "@application",
attribute: "@attribute"
},
{
download : {

View File

@@ -0,0 +1,62 @@
<div class="bs-sidebar col-sm-3 " data-ng-include data-src="'partials/realm-menu.html'"></div>
<div id="content-area" class="col-sm-9" role="main">
<kc-navigation-application></kc-navigation-application>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/saml/keys">SAML Keys</a></li>
<li class="active">SAML {{keyType}} Key Export</li>
</ol>
<h2><span>{{application.name}}</span> SAML {{keyType}} Key Export <span tooltip-placement="right" tooltip="Export Appliations key and certificate to file." class="fa fa-info-circle"></span></h2>
<form class="form-horizontal" name="keyForm" novalidate kc-read-only="!access.manageRealm">
<fieldset class="form-group col-sm-10">
<div class="form-group">
<label class="col-sm-2 control-label" for="downloadKeyFormat">Archive Format</label>
<div class="col-sm-6">
<div class="select-kc">
<select id="downloadKeyFormat"
ng-model="jks.format"
ng-options="f for f in keyFormats">
</select>
</div>
</div>
<span tooltip-placement="right" tooltip="Java keystore or PKCS12 archive format." class="fa fa-info-circle"></span>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="keyAlias">Key Alias</label>
<div class="col-sm-4">
<input class="form-control" type="text" id="keyAlias" name="keyAlias" data-ng-model="jks.keyAlias" autofocus required>
</div>
<span tooltip-placement="right" tooltip="Archive alias for your private key and certificate." class="fa fa-info-circle"></span>
</div>
<div class="form-group" data-ng-hide="!keyInfo.privateKey">
<label class="col-sm-2 control-label" for="keyPassword">Key Password</label>
<div class="col-sm-4">
<input class="form-control" type="password" id="keyPassword" name="keyPassword" data-ng-model="jks.keyPassword" autofocus required>
</div>
<span tooltip-placement="right" tooltip="Password to access the private key in the archive" class="fa fa-info-circle"></span>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="realmAlias">Realm Certificate Alias</label>
<div class="col-sm-4">
<input class="form-control" type="text" id="realmAlias" name="realmAlias" data-ng-model="jks.realmAlias" autofocus required>
</div>
<span tooltip-placement="right" tooltip="Realm certificate is stored in archive too. This is the alias to it." class="fa fa-info-circle"></span>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="storePassword">Store Password</label>
<div class="col-sm-4">
<input class="form-control" type="password" id="storePassword" name="storePassword" data-ng-model="jks.storePassword" autofocus required>
</div>
<span tooltip-placement="right" tooltip="Password to access the archive itself" class="fa fa-info-circle"></span>
</div>
<div class="form-group" data-ng-show="access.manageRealm">
<div class="pull-right">
<button class="btn btn-primary" type="submit" data-ng-click="download()">Download</button>
</div>
</div>
</fieldset>
</form>
</div>
</div>

View File

@@ -0,0 +1,59 @@
<div class="bs-sidebar col-sm-3 " data-ng-include data-src="'partials/realm-menu.html'"></div>
<div id="content-area" class="col-sm-9" role="main">
<kc-navigation-application></kc-navigation-application>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/saml/keys">SAML Keys</a></li>
<li class="active">SAML {{keyType}} Key Import</li>
</ol>
<h2><span>{{application.name}}</span> SAML {{keyType}} Key Import <span tooltip-placement="right" tooltip="Upload Key." class="fa fa-info-circle"></span></h2>
<form class="form-horizontal" name="keyForm" novalidate kc-read-only="!access.manageRealm">
<fieldset>
<div class="form-group">
<label class="col-sm-2 control-label" for="uploadKeyFormat">Archive Format</label>
<div class="col-sm-6">
<div class="select-kc">
<select id="uploadKeyFormat"
ng-model="uploadKeyFormat"
ng-options="f for f in keyFormats">
</select>
</div>
</div>
<span tooltip-placement="right" tooltip="Java keystore or PKCS12 archive format." class="fa fa-info-circle"></span>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="uploadKeyAlias">Key Alias</label>
<div class="col-sm-4">
<input class="form-control" type="text" id="uploadKeyAlias" name="uploadKeyAlias" data-ng-model="uploadKeyAlias" autofocus required>
</div>
<span tooltip-placement="right" tooltip="Archive alias for your certificate." class="fa fa-info-circle"></span>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="uploadStorePassword">Store Password</label>
<div class="col-sm-4">
<input class="form-control" type="password" id="uploadStorePassword" name="uploadStorePassword" data-ng-model="uploadStorePassword" autofocus required>
</div>
<span tooltip-placement="right" tooltip="Password to access the archive itself" class="fa fa-info-circle"></span>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Import File </label>
<div class="col-sm-4">
<div class="controls kc-button-input-file" data-ng-show="!files || files.length == 0">
<a href="#" class="btn btn-default"><span class="kc-icon-upload">Icon: Upload</span>Choose a File...</a>
<input id="import-file" type="file" class="transparent" ng-file-select="onFileSelect($files)">
</div>
<span class="kc-uploaded-file" data-ng-show="files.length > 0">
{{files[0].name}}
</span>
</div>
</div>
<div class="pull-right form-actions" data-ng-show="files.length > 0">
<button type="submit" data-ng-click="clearFileSelect()" class="btn btn-lg btn-default">Cancel</button>
<button type="submit" data-ng-click="uploadFile()" class="btn btn-lg btn-primary">Import</button>
</div>
</fieldset>
</form>
</div>
</div>

View File

@@ -0,0 +1,66 @@
<div class="bs-sidebar col-sm-3 " data-ng-include data-src="'partials/realm-menu.html'"></div>
<div id="content-area" class="col-sm-9" role="main">
<kc-navigation-application></kc-navigation-application>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li class="active">SAML Keys</li>
</ol>
<h2><span>{{application.name}}</span> SAML Keys <span tooltip-placement="right" tooltip="Application certificates used to sign and encrypt documents." class="fa fa-info-circle"></span></h2>
<form class="form-horizontal" name="keyForm" novalidate kc-read-only="!access.manageRealm">
<fieldset class="form-group col-sm-10" data-ng-show="application.attributes['saml.client.signature'] == 'true'">
<legend uncollapsed><span class="text">Signing Key</span> <span tooltip-placement="right" tooltip="SAML Signing Key." class="fa fa-info-circle"></span></legend>
<div class="form-group" data-ng-hide="!signingKeyInfo.privateKey">
<label class="col-sm-2 control-label" for="signingPrivateKey">Private key</label>
<div class="col-sm-10">
<textarea type="text" id="signingPrivateKey" name="signingPrivateKey" class="form-control" rows="5"
kc-select-action="click" readonly>{{signingKeyInfo.privateKey}}</textarea>
</div>
</div>
<div class="form-group" data-ng-hide="!signingKeyInfo.certificate">
<label class="col-sm-2 control-label" for="signingCert">Certificate</label>
<div class="col-sm-10">
<textarea type="text" id="signingCert" name="signingCert" class="form-control" rows="5"
kc-select-action="click" readonly>{{signingKeyInfo.certificate}}</textarea>
</div>
</div>
<div class="form-group" data-ng-show="access.manageRealm">
<div class="pull-right">
<button class="btn btn-primary" type="submit" data-ng-click="generateSigningKey()">Generate new keys</button>
<button class="btn btn-primary" type="submit" data-ng-click="importSigningKey()">Import</button>
<button class="btn btn-primary" type="submit" data-ng-hide="!signingKeyInfo.certificate" data-ng-click="exportSigningKey()">Export</button>
</div>
</div>
</fieldset>
<fieldset class="form-group col-sm-10" data-ng-show="application.attributes['saml.encrypt'] == 'true'">
<legend uncollapsed><span class="text">Encryption Key</span> <span tooltip-placement="right" tooltip="SAML Encryption Key." class="fa fa-info-circle"></span></legend>
<div class="form-group" data-ng-hide="!encryptionKeyInfo.privateKey">
<label class="col-sm-2 control-label" for="encryptionPrivateKey">Private key</label>
<div class="col-sm-10">
<textarea type="text" id="encryptionPrivateKey" name="encryptionPrivateKey" class="form-control" rows="5"
kc-select-action="click" readonly>{{encryptionKeyInfo.privateKey}}</textarea>
</div>
</div>
<div class="form-group" data-ng-hide="!encryptionKeyInfo.certificate">
<label class="col-sm-2 control-label" for="encryptionCert">Certificate</label>
<div class="col-sm-10">
<textarea type="text" id="encryptionCert" name="encryptionCert" class="form-control" rows="5"
kc-select-action="click" readonly>{{encryptionKeyInfo.certificate}}</textarea>
</div>
</div>
<div class="form-group" data-ng-show="access.manageRealm">
<div class="pull-right">
<button class="btn btn-primary" type="submit" data-ng-click="generateEncryptionKey()">Generate new keys</button>
<button class="btn btn-primary" type="submit" data-ng-click="importEncryptionKey()">Import</button>
<button class="btn btn-primary" type="submit" data-ng-hide="!encryptionKeyInfo.certificate" data-ng-click="exportEncryptionKey()">Export</button>
</div>
</div>
</fieldset>
</form>
</div>
</div>

View File

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