From aece8d8c8bb52d9ab40bed6749b96dde1bb5a37b Mon Sep 17 00:00:00 2001 From: Marcel Dias Date: Tue, 3 Oct 2017 18:42:13 -0300 Subject: [PATCH 1/4] Add SNIs --- src/html/index.html | 5 +++ src/html/snis/form.html | 42 +++++++++++++++++++++++ src/html/snis/index.html | 68 ++++++++++++++++++++++++++++++++++++ src/js/app.js | 21 ++++++++++++ src/js/controllers/sni.js | 56 ++++++++++++++++++++++++++++++ src/js/controllers/snis.js | 70 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 262 insertions(+) create mode 100644 src/html/snis/form.html create mode 100644 src/html/snis/index.html create mode 100644 src/js/controllers/sni.js create mode 100644 src/js/controllers/snis.js diff --git a/src/html/index.html b/src/html/index.html index 68e5cc5..82fac57 100644 --- a/src/html/index.html +++ b/src/html/index.html @@ -32,6 +32,11 @@ extension +
  • + + dns + +
  • diff --git a/src/html/snis/form.html b/src/html/snis/form.html new file mode 100644 index 0000000..89311d3 --- /dev/null +++ b/src/html/snis/form.html @@ -0,0 +1,42 @@ +
    +

    {{title}}

    + +
    +
    +
    +

    + An SNI object represents a many-to-one mapping of hostnames to a certificate. That is, a certificate object can have many hostnames associated with it; when Kong receives an SSL request, it uses the SNI field in the Client Hello to lookup the certificate object based on the SNI associated with the certificate. +

    + +

    + Checkout Kong documentation for the meaning of the form parameters. +

    +
    +
    +
    +
    +
    + + + +
    +
    + + + +
    +
    + +
    +
    + +
    +
    +
    diff --git a/src/html/snis/index.html b/src/html/snis/index.html new file mode 100644 index 0000000..53fa72d --- /dev/null +++ b/src/html/snis/index.html @@ -0,0 +1,68 @@ +
    + + + +

    + SNIs +

    + +

    + +

    + +
    +

    + You haven't defined any SNI in Kong yet. +

    +

    + + add_box + Add SNI + +

    +
    + + + + + + + + + + + + + + + + + + + +
    NameSSL Certificate idCreated
    {{sni.name}}{{sni.ssl_certificate_id}}{{sni.created_at | date}} + + mode_edit + + + delete + +
    +
    + + + diff --git a/src/js/app.js b/src/js/app.js index 4c00918..96fee34 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -146,6 +146,27 @@ var app = angular.module('app', ['ngRoute', 'ngCookies', 'ngAnimate', 'ngSanitiz }] } }) + .when('/snis', { + templateUrl: 'html/snis/index.html', + controller: 'SnisController', + resolve: { + isAppReady: isAppReady + } + }) + .when('/snis/add', { + templateUrl: 'html/snis/form.html', + controller: 'SniController', + resolve: { + isAppReady: isAppReady + } + }) + .when('/snis/:name', { + templateUrl: 'html/snis/form.html', + controller: 'SniController', + resolve: { + isAppReady: isAppReady, + } + }) .otherwise({redirectTo: '/'}); }]) .run(['$rootScope', 'Kong', '$location', function($rootScope, Kong, $location) { diff --git a/src/js/controllers/sni.js b/src/js/controllers/sni.js new file mode 100644 index 0000000..8b1647c --- /dev/null +++ b/src/js/controllers/sni.js @@ -0,0 +1,56 @@ +angular.module('app').controller("SniController", ["$scope", "Kong", "$location", "$routeParams", "Alert", "$route", function ($scope, Kong, $location, $routeParams, Alert, $route) { + + $scope.sni = {}; + $scope.certificates = []; + + onInit(); + + function onInit() { + Kong.get('/certificates').then(function(collection) { + $scope.certificates = collection.data; + }); + + if ($routeParams.name) { + Kong.get('/snis/' + $routeParams.name).then( function(data) { + $scope.sni = data; + }); + $scope.title = "Edit SNI"; + $scope.action = "Save"; + $scope.location = $location; + } else { + $scope.title = "Add a SNI"; + $scope.action = "Create"; + } + + if ($routeParams.certificate_id) { + $scope.sni.ssl_certificate_id = $routeParams.certificate_id; + } + } + + $scope.isEdit = function () { + return $routeParams.name != null; + } + + $scope.save = function () { + if ( $scope.isEdit() ) { + Kong.patch('/snis/' + $scope.sni.name, $scope.sni).then(function () { + Alert.success('SNI updated'); + $scope.error = {}; + }, function (response) { + $scope.error = response.data; + }); + } else { + Kong.post('/snis', $scope.sni).then(function () { + Alert.success('SNI created'); + // clearing inputs. + $scope.sni = {}; + + // clearing errors. + $scope.error = {}; + }, function (response) { + $scope.error = response.data; + }); + } + }; + +}]); diff --git a/src/js/controllers/snis.js b/src/js/controllers/snis.js new file mode 100644 index 0000000..efc46f0 --- /dev/null +++ b/src/js/controllers/snis.js @@ -0,0 +1,70 @@ +angular.module('app').controller("SnisController", ["$scope", "Kong", function ($scope, Kong) { + $scope.snis = []; + $scope.total = null; + $scope.offset = null; + $scope.searchResults = {}; + $scope.searching = false; + + var loaded_pages = []; + + $scope.loadMore = function() { + var page = '/snis?'; + if ($scope.offset) { + page += 'offset=' + $scope.offset + '&'; + } + if (loaded_pages.indexOf(page) !== -1) { + return; + } + loaded_pages.push(page); + + Kong.get(page).then(function(collection) { + if ($scope.total === null) { + $scope.total = 0; + } + $scope.snis.push.apply($scope.snis, collection.data); + $scope.total += collection.total; + $scope.offset = collection.offset ? collection.offset : null; + }); + }; + $scope.loadMore(); + + $scope.showDeleteModal = function (name) { + $scope.current = {name: name}; + $('#deleteSni').openModal(); + }; + + $scope.abortDelete = function () { + $('#deleteSni').closeModal(); + }; + + $scope.performDelete = function () { + $('#deleteSni').closeModal(); + Kong.delete('/snis/' + $scope.current.name).then(function (response) { + $scope.total -= 1; + $scope.snis.forEach(function(element, index) { + if (element.name === $scope.current.name) { + $scope.snis.splice(index, 1); + } + }); + }); + }; + + $scope.searchSnis = function() { + $scope.searchResults = {}; + var input = $scope.searchInput; + if (!input) { + $scope.searching = false; + return; + } + + $scope.searching = true; + + var populateResults = function(response) { + angular.forEach(response.data, function(value) { + $scope.searchResults[value.name] = value.name; + }); + }; + + Kong.get('/snis?name=' + input).then(populateResults); + }; +}]); From a4e8024bc89a6017dae862e7fb441ee0682647cc Mon Sep 17 00:00:00 2001 From: Marcel Dias Date: Tue, 3 Oct 2017 18:43:00 -0300 Subject: [PATCH 2/4] Add certificates --- src/html/certificates/form.html | 65 +++++++++++++++++++++++++ src/html/certificates/index.html | 76 ++++++++++++++++++++++++++++++ src/html/index.html | 5 ++ src/js/app.js | 28 +++++++++++ src/js/controllers/certificate.js | 46 ++++++++++++++++++ src/js/controllers/certificates.js | 70 +++++++++++++++++++++++++++ 6 files changed, 290 insertions(+) create mode 100644 src/html/certificates/form.html create mode 100644 src/html/certificates/index.html create mode 100644 src/js/controllers/certificate.js create mode 100644 src/js/controllers/certificates.js diff --git a/src/html/certificates/form.html b/src/html/certificates/form.html new file mode 100644 index 0000000..3269568 --- /dev/null +++ b/src/html/certificates/form.html @@ -0,0 +1,65 @@ +
    +

    {{title}}

    + +
    +
    +
    +

    + A certificate object represents a public certificate/private key pair for an SSL certificate. These objects are used by Kong + to handle SSL/TLS termination for encrypted requests. Certificates are optionally associated with SNI + objects to tie a cert/key pair to one or more hostnames. +

    + +

    + Checkout Kong documentation for the meaning of the form parameters. +

    +
    +
    +
    +
    + +
    + + + +
    +
    + + + +
    +
    + + + +
    +
    + +
      +
    • {{sni}}
    • +
    + + +
    + + +
    + +
    + +
    + +
    +
    +
    \ No newline at end of file diff --git a/src/html/certificates/index.html b/src/html/certificates/index.html new file mode 100644 index 0000000..9748646 --- /dev/null +++ b/src/html/certificates/index.html @@ -0,0 +1,76 @@ +
    + + + +

    + Certificates +

    + +

    + +

    + +
    +

    + You haven't defined any Certificates in Kong yet. +

    +

    + + add_box + Add Certificate + +

    +
    + + + + + + + + + + + + + + + + + + + + +
    IDCreatedSNIs
    {{certificate.id}}{{certificate.created_at | date}} +
      +
    • {{sni}}
    • +
    +
    + + mode_edit + + + dns + + + delete + +
    +
    + + + diff --git a/src/html/index.html b/src/html/index.html index 82fac57..4ad72cc 100644 --- a/src/html/index.html +++ b/src/html/index.html @@ -37,6 +37,11 @@ dns +
  • + + https + +
  • diff --git a/src/js/app.js b/src/js/app.js index 96fee34..4669f0d 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -167,6 +167,34 @@ var app = angular.module('app', ['ngRoute', 'ngCookies', 'ngAnimate', 'ngSanitiz isAppReady: isAppReady, } }) + .when('/snis/add/:certificate_id', { + templateUrl: 'html/snis/form.html', + controller: 'SniController', + resolve: { + isAppReady: isAppReady + } + }) + .when('/certificates', { + templateUrl: 'html/certificates/index.html', + controller: 'CertificatesController', + resolve: { + isAppReady: isAppReady + } + }) + .when('/certificates/add', { + templateUrl: 'html/certificates/form.html', + controller: 'CertificateController', + resolve: { + isAppReady: isAppReady + } + }) + .when('/certificates/:id', { + templateUrl: 'html/certificates/form.html', + controller: 'CertificateController', + resolve: { + isAppReady: isAppReady, + } + }) .otherwise({redirectTo: '/'}); }]) .run(['$rootScope', 'Kong', '$location', function($rootScope, Kong, $location) { diff --git a/src/js/controllers/certificate.js b/src/js/controllers/certificate.js new file mode 100644 index 0000000..e7309b3 --- /dev/null +++ b/src/js/controllers/certificate.js @@ -0,0 +1,46 @@ +angular.module('app').controller("CertificateController", ["$scope", "Kong", "$location", "$routeParams", "Alert", "$route", function ($scope, Kong, $location, $routeParams, Alert, $route) { + + $scope.certificate = {}; + + onInit(); + + function onInit() { + if ($routeParams.id) { + Kong.get('/certificates/' + $routeParams.id).then( function(data) { + $scope.certificate = data; + }); + $scope.title = "Edit Certificate"; + $scope.action = "Save"; + $scope.location = $location; + } else { + $scope.title = "Add a Certificate"; + $scope.action = "Create"; + } + } + + $scope.isEdit = function () { + return $routeParams.id != null; + } + + $scope.save = function () { + if ( $scope.isEdit() ) { + Kong.patch('/certificates/' + $scope.certificate.id, $scope.certificate).then(function () { + Alert.success('Certificate updated'); + $scope.error = {}; + }, function (response) { + $scope.error = response.data; + }); + } else { + Kong.post('/certificates', $scope.certificate).then(function () { + Alert.success('Certificate created'); + // clearing inputs. + $scope.certificate = {}; + + // clearing errors. + $scope.error = {}; + }, function (response) { + $scope.error = response.data; + }); + } + }; +}]); diff --git a/src/js/controllers/certificates.js b/src/js/controllers/certificates.js new file mode 100644 index 0000000..03e27f7 --- /dev/null +++ b/src/js/controllers/certificates.js @@ -0,0 +1,70 @@ +angular.module('app').controller("CertificatesController", ["$scope", "Kong", function ($scope, Kong) { + $scope.certificates = []; + $scope.total = null; + $scope.offset = null; + $scope.searchResults = {}; + $scope.searching = false; + + var loaded_pages = []; + + $scope.loadMore = function() { + var page = '/certificates?'; + if ($scope.offset) { + page += 'offset=' + $scope.offset + '&'; + } + if (loaded_pages.indexOf(page) !== -1) { + return; + } + loaded_pages.push(page); + + Kong.get(page).then(function(collection) { + if ($scope.total === null) { + $scope.total = 0; + } + $scope.certificates.push.apply($scope.certificates, collection.data); + $scope.total += collection.total; + $scope.offset = collection.offset ? collection.offset : null; + }); + }; + $scope.loadMore(); + + $scope.showDeleteModal = function (id) { + $scope.current = {id: id}; + $('#deleteCertificate').openModal(); + }; + + $scope.abortDelete = function () { + $('#deleteCertificate').closeModal(); + }; + + $scope.performDelete = function () { + $('#deleteCertificate').closeModal(); + Kong.delete('/certificates/' + $scope.current.id).then(function (response) { + $scope.total -= 1; + $scope.certificates.forEach(function(element, index) { + if (element.id === $scope.current.id) { + $scope.certificates.splice(index, 1); + } + }); + }); + }; + + $scope.searchCertificates = function() { + $scope.searchResults = {}; + var input = $scope.searchInput; + if (!input) { + $scope.searching = false; + return; + } + + $scope.searching = true; + + var populateResults = function(response) { + angular.forEach(response.data, function(value) { + $scope.searchResults[value.id] = value.id; + }); + }; + + Kong.get('/certificates?id=' + input).then(populateResults); + }; +}]); From 4f252d5cb481ebdd5fb75136417e03478eb2a6aa Mon Sep 17 00:00:00 2001 From: Marcel Dias Date: Wed, 4 Oct 2017 13:45:12 -0300 Subject: [PATCH 3/4] Hide Certificate ID input when creating it --- src/html/certificates/form.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/html/certificates/form.html b/src/html/certificates/form.html index 3269568..edb0461 100644 --- a/src/html/certificates/form.html +++ b/src/html/certificates/form.html @@ -18,7 +18,7 @@

    {{title}}

    -
    +
    From 466f1f97377b485f3dfc34b7d6b80f8515fe7972 Mon Sep 17 00:00:00 2001 From: Marcel Dias Date: Wed, 4 Oct 2017 13:46:30 -0300 Subject: [PATCH 4/4] Remove unused function --- src/js/controllers/snis.js | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/js/controllers/snis.js b/src/js/controllers/snis.js index efc46f0..a3fb8a5 100644 --- a/src/js/controllers/snis.js +++ b/src/js/controllers/snis.js @@ -48,23 +48,4 @@ angular.module('app').controller("SnisController", ["$scope", "Kong", function ( }); }); }; - - $scope.searchSnis = function() { - $scope.searchResults = {}; - var input = $scope.searchInput; - if (!input) { - $scope.searching = false; - return; - } - - $scope.searching = true; - - var populateResults = function(response) { - angular.forEach(response.data, function(value) { - $scope.searchResults[value.name] = value.name; - }); - }; - - Kong.get('/snis?name=' + input).then(populateResults); - }; }]);