Adding final touches to #125

This commit is contained in:
kevgliss 2015-11-30 09:47:36 -08:00
parent 8eeed821d3
commit ec896461a7
5 changed files with 35 additions and 16 deletions

View File

@ -32,7 +32,8 @@
"angularjs-toaster": "~0.4.14", "angularjs-toaster": "~0.4.14",
"ngletteravatar": "~3.0.1", "ngletteravatar": "~3.0.1",
"angular-ui-router": "~0.2.15", "angular-ui-router": "~0.2.15",
"angular-clipboard": "~1.1.1" "angular-clipboard": "~1.1.1",
"angular-file-saver": "~1.0.1"
}, },
"devDependencies": { "devDependencies": {
"angular-mocks": "~1.3", "angular-mocks": "~1.3",

View File

@ -5,6 +5,7 @@
:license: Apache, see LICENSE for more details. :license: Apache, see LICENSE for more details.
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com> .. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
""" """
import base64
from builtins import str from builtins import str
from flask import Blueprint, make_response, jsonify from flask import Blueprint, make_response, jsonify
@ -817,10 +818,9 @@ class CertificateExport(AuthenticatedResource):
permission = UpdateCertificatePermission(certificate_id, getattr(role, 'name', None)) permission = UpdateCertificatePermission(certificate_id, getattr(role, 'name', None))
if permission.can(): if permission.can():
passphrase, data = service.export(cert, args['export']['plugin']) extension, passphrase, data = service.export(cert, args['export']['plugin'])
response = make_response(data) # we take a hit in message size when b64 encoding
response.headers['content-type'] = 'application/octet-stream' return dict(extension=extension, passphrase=passphrase, data=base64.b64encode(data))
return response
return dict(message='You are not authorized to export this certificate'), 403 return dict(message='You are not authorized to export this certificate'), 403

View File

@ -74,7 +74,7 @@ class JavaExportPlugin(ExportPlugin):
'type': 'str', 'type': 'str',
'required': False, 'required': False,
'helpMessage': 'If no passphrase is given one will be generated for you, we highly recommend this. Minimum length is 8.', 'helpMessage': 'If no passphrase is given one will be generated for you, we highly recommend this. Minimum length is 8.',
'validation': '^.{8}$' 'validation': '^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,}$'
}, },
{ {
'name': 'alias', 'name': 'alias',
@ -105,9 +105,13 @@ class JavaExportPlugin(ExportPlugin):
else: else:
alias = "blah" alias = "blah"
if not key:
raise Exception("Unable to export, no private key found.")
with mktempfile() as cert_tmp: with mktempfile() as cert_tmp:
with open(cert_tmp, 'w') as f: with open(cert_tmp, 'w') as f:
f.write(body) f.write(body)
with mktempfile() as key_tmp: with mktempfile() as key_tmp:
with open(key_tmp, 'w') as f: with open(key_tmp, 'w') as f:
f.write(key) f.write(key)
@ -168,4 +172,4 @@ class JavaExportPlugin(ExportPlugin):
with open(jks_tmp, 'rb') as f: with open(jks_tmp, 'rb') as f:
raw = f.read() raw = f.read()
return passphrase, raw return "jks", passphrase, raw

View File

@ -15,7 +15,8 @@ var lemur = angular
'mgo-angular-wizard', 'mgo-angular-wizard',
'satellizer', 'satellizer',
'ngLetterAvatar', 'ngLetterAvatar',
'angular-clipboard' 'angular-clipboard',
'ngFileSaver'
]) ])
.config(function ($stateProvider, $urlRouterProvider, $authProvider) { .config(function ($stateProvider, $urlRouterProvider, $authProvider) {
$urlRouterProvider.otherwise('/welcome'); $urlRouterProvider.otherwise('/welcome');

View File

@ -1,7 +1,7 @@
'use strict'; 'use strict';
angular.module('lemur') angular.module('lemur')
.controller('CertificateExportController', function ($scope, $modalInstance, CertificateApi, CertificateService, PluginService, toaster, editId) { .controller('CertificateExportController', function ($scope, $modalInstance, CertificateApi, CertificateService, PluginService, FileSaver, Blob, toaster, editId) {
CertificateApi.get(editId).then(function (certificate) { CertificateApi.get(editId).then(function (certificate) {
$scope.certificate = certificate; $scope.certificate = certificate;
}); });
@ -16,13 +16,26 @@ angular.module('lemur')
$scope.save = function (certificate) { $scope.save = function (certificate) {
CertificateService.export(certificate).then( CertificateService.export(certificate).then(
function () { function (response) {
toaster.pop({ var byteCharacters = atob(response.data);
type: 'success', var byteArrays = [];
title: certificate.name,
body: 'Successfully exported!' for (var offset = 0; offset < byteCharacters.length; offset += 512) {
}); var slice = byteCharacters.slice(offset, offset + 512);
$modalInstance.close();
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, {type: 'application/octet-stream'});
saveAs(blob, certificate.name + "." + response.extension);
$scope.passphrase = response.passphrase;
}, },
function (response) { function (response) {
toaster.pop({ toaster.pop({