Some unit tests
This commit is contained in:
parent
51d2990eb9
commit
f0f2092fb4
|
@ -135,7 +135,6 @@ def unwrap_pagination(data, output_schema):
|
|||
marshaled_data = {'total': len(data)}
|
||||
marshaled_data['items'] = output_schema.dump(data, many=True).data
|
||||
return marshaled_data
|
||||
|
||||
return output_schema.dump(data).data
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import json
|
||||
|
||||
from flask import current_app
|
||||
from lemur import database
|
||||
from lemur.dns_providers.models import DnsProviders
|
||||
|
||||
|
@ -31,3 +34,10 @@ def delete(dns_provider_id):
|
|||
:param dns_provider_id: Lemur assigned ID
|
||||
"""
|
||||
database.delete(get(dns_provider_id))
|
||||
|
||||
|
||||
def get_types():
|
||||
provider_config = current_app.config.get('ACME_DNS_PROVIDER_TYPES')
|
||||
if not provider_config:
|
||||
raise Exception("No DNS Provider configuration specified.")
|
||||
return provider_config
|
||||
|
|
|
@ -78,10 +78,24 @@ class DnsProvidersList(AuthenticatedResource):
|
|||
args['user'] = g.user
|
||||
return service.render(args)
|
||||
|
||||
|
||||
@admin_permission.require(http_exception=403)
|
||||
def delete(self, dns_provider_id):
|
||||
service.delete(dns_provider_id)
|
||||
return {'result': True}
|
||||
|
||||
|
||||
class DnsProviderTypes(AuthenticatedResource):
|
||||
""" Defines the 'dns_provider_types' endpoint """
|
||||
|
||||
def __init__(self):
|
||||
self.reqparse = reqparse.RequestParser()
|
||||
super(DnsProviderTypes, self).__init__()
|
||||
|
||||
def get(self):
|
||||
return service.get_types()
|
||||
|
||||
|
||||
api.add_resource(DnsProvidersList, '/dns_providers', endpoint='dns_providers')
|
||||
api.add_resource(DnsProvidersList, '/dns_providers/<int:dns_provider_id>', endpoint='dns_provider')
|
||||
api.add_resource(DnsProviderTypes, '/dns_provider_types', endpoint='dns_provider_types')
|
||||
|
|
|
@ -113,13 +113,11 @@ def setup_acme_client(authority):
|
|||
if not authority.options:
|
||||
raise Exception("Invalid authority. Options not set")
|
||||
options = {}
|
||||
for o in json.loads(authority.options):
|
||||
print(o)
|
||||
options[o.get("name")] = o.get("value")
|
||||
email = options.get('email', current_app.config.get('ACME_EMAIL'))
|
||||
tel = options.get('telephone', current_app.config.get('ACME_TEL'))
|
||||
directory_url = options.get('acme_url', current_app.config.get('ACME_DIRECTORY_URL'))
|
||||
contact = ('mailto:{}'.format(email), 'tel:{}'.format(tel))
|
||||
authority_options = json.loads(authority.options)
|
||||
options[authority_options.get("name")] = authority_options.get("value")
|
||||
email = authority_options.get('email', current_app.config.get('ACME_EMAIL'))
|
||||
tel = authority_options.get('telephone', current_app.config.get('ACME_TEL'))
|
||||
directory_url = authority_options.get('acme_url', current_app.config.get('ACME_DIRECTORY_URL'))
|
||||
|
||||
key = jose.JWKRSA(key=generate_private_key('RSA2048'))
|
||||
|
||||
|
|
|
@ -1,4 +1,119 @@
|
|||
import unittest
|
||||
|
||||
from acme import challenges
|
||||
|
||||
from lemur.plugins.lemur_acme import plugin, route53, cloudflare
|
||||
from lemur.plugins.base import plugins
|
||||
from mock import MagicMock, Mock, patch
|
||||
|
||||
|
||||
class TestAcme(unittest.TestCase):
|
||||
|
||||
@patch('lemur.plugins.lemur_acme.plugin.len', return_value=1)
|
||||
def test_find_dns_challenge(self, mock_len):
|
||||
assert mock_len
|
||||
|
||||
from acme import challenges
|
||||
c = challenges.DNS01()
|
||||
|
||||
mock_authz = Mock()
|
||||
mock_authz.body.resolved_combinations = []
|
||||
mock_entry = Mock()
|
||||
mock_entry.chall = c
|
||||
mock_authz.body.resolved_combinations.append(mock_entry)
|
||||
result = yield plugin.find_dns_challenge(mock_authz)
|
||||
self.assertEqual(result, mock_entry)
|
||||
|
||||
def test_authz_record(self):
|
||||
a = plugin.AuthorizationRecord("host", "authz", "challenge", "id")
|
||||
self.assertEqual(type(a), plugin.AuthorizationRecord)
|
||||
|
||||
@patch('acme.client.Client')
|
||||
@patch('lemur.plugins.lemur_acme.plugin.current_app')
|
||||
@patch('lemur.plugins.lemur_acme.plugin.len', return_value=1)
|
||||
@patch('lemur.plugins.lemur_acme.plugin.find_dns_challenge')
|
||||
def test_start_dns_challenge(self, mock_find_dns_challenge, mock_len, mock_app, mock_acme):
|
||||
assert mock_len
|
||||
mock_app.logger.debug = Mock()
|
||||
mock_authz = Mock()
|
||||
mock_authz.body.resolved_combinations = []
|
||||
mock_entry = MagicMock()
|
||||
from acme import challenges
|
||||
c = challenges.DNS01()
|
||||
mock_entry.chall = c
|
||||
mock_authz.body.resolved_combinations.append(mock_entry)
|
||||
mock_acme.request_domain_challenges = Mock(return_value=mock_authz)
|
||||
mock_dns_provider = Mock()
|
||||
mock_dns_provider.create_txt_record = Mock(return_value=1)
|
||||
|
||||
values = [mock_entry]
|
||||
iterable = mock_find_dns_challenge.return_value
|
||||
iterator = iter(values)
|
||||
iterable.__iter__.return_value = iterator
|
||||
result = plugin.start_dns_challenge(mock_acme, "accountid", "host", mock_dns_provider)
|
||||
self.assertEqual(type(result), plugin.AuthorizationRecord)
|
||||
|
||||
@patch('acme.client.Client')
|
||||
def test_complete_dns_challenge_success(self, mock_acme):
|
||||
mock_dns_provider = Mock()
|
||||
mock_dns_provider.wait_for_dns_change = Mock(return_value=True)
|
||||
|
||||
mock_authz = Mock()
|
||||
mock_authz.dns_challenge.response = Mock()
|
||||
mock_authz.dns_challenge.response.simple_verify = Mock(return_value=True)
|
||||
|
||||
plugin.complete_dns_challenge(mock_acme, "accountid", mock_authz, mock_dns_provider)
|
||||
|
||||
@patch('acme.client.Client')
|
||||
def test_complete_dns_challenge_fail(self, mock_acme):
|
||||
mock_dns_provider = Mock()
|
||||
mock_dns_provider.wait_for_dns_change = Mock(return_value=True)
|
||||
|
||||
mock_authz = Mock()
|
||||
mock_authz.dns_challenge.response = Mock()
|
||||
mock_authz.dns_challenge.response.simple_verify = Mock(return_value=False)
|
||||
self.assertRaises(
|
||||
ValueError,
|
||||
plugin.complete_dns_challenge(mock_acme, "accountid", mock_authz, mock_dns_provider)
|
||||
)
|
||||
|
||||
@patch('acme.client.Client')
|
||||
@patch('OpenSSL.crypto', return_value="mock_cert")
|
||||
@patch('josepy.util.ComparableX509')
|
||||
@patch('lemur.plugins.lemur_acme.plugin.find_dns_challenge')
|
||||
@patch('lemur.plugins.lemur_acme.plugin.current_app')
|
||||
def test_request_certificate(self, mock_current_app, mock_find_dns_challenge, mock_jose, mock_crypto, mock_acme):
|
||||
mock_cert_response = Mock()
|
||||
mock_cert_response.body = "123"
|
||||
mock_cert_response_full = [mock_cert_response, True]
|
||||
mock_acme.poll_and_request_issuance = Mock(return_value=mock_cert_response_full)
|
||||
mock_authz = []
|
||||
mock_authz_record = MagicMock()
|
||||
mock_authz_record.authz = Mock()
|
||||
mock_authz.append(mock_authz_record)
|
||||
mock_acme.fetch_chain = Mock(return_value="mock_chain")
|
||||
mock_crypto.dump_certificate = Mock(return_value=b'chain')
|
||||
|
||||
plugin.request_certificate(mock_acme, [], "mock_csr")
|
||||
|
||||
def test_setup_acme_client_fail(self):
|
||||
mock_authority = Mock()
|
||||
mock_authority.options = []
|
||||
with self.assertRaises(Exception):
|
||||
plugin.setup_acme_client(mock_authority)
|
||||
|
||||
@patch('lemur.plugins.lemur_acme.plugin.Client')
|
||||
@patch('lemur.plugins.lemur_acme.plugin.current_app')
|
||||
def test_setup_acme_client_success(self, mock_current_app, mock_acme):
|
||||
mock_authority = Mock()
|
||||
mock_authority.options = '{"o": "mock_name", "v": "mock_value"}'
|
||||
mock_client = Mock()
|
||||
mock_registration = Mock()
|
||||
mock_registration.uri = "http://test.com"
|
||||
mock_client.register = mock_registration
|
||||
mock_client.agree_to_tos = Mock(return_value=True)
|
||||
mock_acme.return_value = mock_client
|
||||
result_client, result_registration = plugin.setup_acme_client(mock_authority)
|
||||
assert result_client
|
||||
assert result_registration
|
||||
|
||||
def test_get_certificates(app):
|
||||
from lemur.plugins.base import plugins
|
||||
p = plugins.get('acme-issuer')
|
||||
|
|
|
@ -5,6 +5,10 @@ angular.module('lemur')
|
|||
.controller('DnsProviderCreateController', function ($scope, $uibModalInstance, PluginService, DnsProviderService, LemurRestangular, toaster) {
|
||||
$scope.dns_provider = LemurRestangular.restangularizeElement(null, {}, 'dns_providers');
|
||||
|
||||
PluginService.getByName('acme-issuer').then(function (acme) {
|
||||
$scope.acme = acme;
|
||||
});
|
||||
|
||||
PluginService.getByType('dns_provider').then(function (plugins) {
|
||||
$scope.plugins = plugins;
|
||||
});
|
||||
|
@ -45,30 +49,13 @@ angular.module('lemur')
|
|||
DnsProviderApi.get(editId).then(function (dns_provider) {
|
||||
$scope.dns_provider = dns_provider;
|
||||
|
||||
PluginService.getByType('dns_provider').then(function (plugins) {
|
||||
$scope.plugins = plugins;
|
||||
PluginService.getByName('acme-issuer').then(function (acme) {
|
||||
$scope.acme = acme;
|
||||
|
||||
_.each($scope.plugins, function (plugin) {
|
||||
if (plugin.slug === $scope.dns_provider.plugin.slug) {
|
||||
plugin.pluginOptions = $scope.dns_provider.plugin.pluginOptions;
|
||||
$scope.dns_provider.plugin = plugin;
|
||||
_.each($scope.dns_provider.plugin.pluginOptions, function (option) {
|
||||
if (option.type === 'export-plugin') {
|
||||
PluginService.getByType('export').then(function (plugins) {
|
||||
$scope.exportPlugins = plugins;
|
||||
|
||||
_.each($scope.exportPlugins, function (plugin) {
|
||||
if (plugin.slug === option.value.slug) {
|
||||
plugin.pluginOptions = option.value.pluginOptions;
|
||||
option.value = plugin;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
_.each($scope.acme, function (opts) {
|
||||
console.log(opts);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$scope.save = function (dns_provider) {
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
<button type="button" class="close" ng-click="cancel()" aria-label="Close"><span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<h3><span ng-show="!dns_provider.fromServer">Create</span><span ng-show="dns_provider.fromServer">Edit</span>
|
||||
DnsProvider <span class="text-muted"><small>oh the places you will go!</small></span></h3>
|
||||
Dns Provider <span class="text-muted"><small>route all the things</small></span></h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form name="createForm" class="form-horizontal" role="form" novalidate>
|
||||
<div class="form-group"
|
||||
ng-class="{'has-error': createForm.label.$invalid, 'has-success': !createForm.label.$invalid&&createForm.label.$dirty}">
|
||||
<label class="control-label col-sm-2">
|
||||
Label
|
||||
Name
|
||||
</label>
|
||||
<div class="col-sm-10">
|
||||
<input name="label" ng-model="dns_provider.label" placeholder="Label" class="form-control" required/>
|
||||
<input name="name" ng-model="dns_provider.name" placeholder="Name" class="form-control" required/>
|
||||
<p ng-show="createForm.label.$invalid && !createForm.label.$pristine" class="help-block">You must enter an
|
||||
dns_provider label</p>
|
||||
dns_provider name</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
@ -22,16 +22,16 @@
|
|||
Description
|
||||
</label>
|
||||
<div class="col-sm-10">
|
||||
<textarea name="comments" ng-model="dns_provider.description" placeholder="Something elegant"
|
||||
<textarea name="description" ng-model="dns_provider.description" placeholder="Something elegant"
|
||||
class="form-control"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2">
|
||||
Plugin
|
||||
Provider Type
|
||||
</label>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-control" ng-model="dns_provider.plugin" ng-options="plugin.title for plugin in plugins"
|
||||
<select class="form-control" ng-model="dns_provider.provider_type" ng-options="plugin for plugin in ['route53', 'cloudflare']"
|
||||
required></select>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -50,7 +50,7 @@ angular.module('lemur')
|
|||
var uibModalInstance = $uibModal.open({
|
||||
animation: true,
|
||||
templateUrl: '/angular/dns_providers/dns_provider/dns_provider.tpl.html',
|
||||
controller: 'DnsProvidersEditController',
|
||||
controller: 'DnsProviderEditController',
|
||||
size: 'lg',
|
||||
backdrop: 'static',
|
||||
resolve: {
|
||||
|
@ -69,7 +69,7 @@ angular.module('lemur')
|
|||
$scope.create = function () {
|
||||
var uibModalInstance = $uibModal.open({
|
||||
animation: true,
|
||||
controller: 'DnsProvidersCreateController',
|
||||
controller: 'DnsProviderCreateController',
|
||||
templateUrl: '/angular/dns_providers/dns_provider/dns_provider.tpl.html',
|
||||
size: 'lg',
|
||||
backdrop: 'static'
|
||||
|
|
|
@ -29,12 +29,6 @@
|
|||
<li>{{ dns_provider.providerType }}</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td data-title="'Domains'" sortable="'domains'" filter="{ 'domains': 'text' }">
|
||||
<ul class="list-unstyled">
|
||||
<li>{{ dns_provider.domains }}</li>
|
||||
<li><span class="text-muted">{{ dns_provider.description }}</span></li>
|
||||
</ul>
|
||||
</td>
|
||||
<td data-title="''">
|
||||
<div class="btn-group-vertical pull-right">
|
||||
<button uib-tooltip="Edit DNS Provider" ng-click="edit(dns_provider.id)" class="btn btn-sm btn-info">
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
asn1crypto==0.24.0 # via cryptography
|
||||
attrs==17.4.0 # via pytest
|
||||
aws-xray-sdk==0.95 # via moto
|
||||
boto3==1.7.6 # via moto
|
||||
boto3==1.7.8 # via moto
|
||||
boto==2.48.0 # via moto
|
||||
botocore==1.10.6 # via boto3, moto, s3transfer
|
||||
botocore==1.10.8 # via boto3, moto, s3transfer
|
||||
certifi==2018.4.16 # via requests
|
||||
cffi==1.11.5 # via cryptography
|
||||
chardet==3.0.4 # via requests
|
||||
|
@ -43,7 +43,7 @@ pycparser==2.18 # via cffi
|
|||
pyflakes==1.6.0
|
||||
pytest-flask==0.10.0
|
||||
pytest-mock==1.9.0
|
||||
pytest==3.5.0
|
||||
pytest==3.5.1
|
||||
python-dateutil==2.6.1 # via botocore, faker, freezegun, moto
|
||||
pytz==2018.4 # via moto
|
||||
pyyaml==3.12 # via pyaml
|
||||
|
|
|
@ -4,6 +4,7 @@ acme
|
|||
alembic-autogenerate-enums
|
||||
arrow
|
||||
boto3
|
||||
CloudFlare
|
||||
cryptography
|
||||
Flask-Bcrypt==0.7.1
|
||||
Flask-Mail==0.9.1
|
||||
|
|
|
@ -12,10 +12,11 @@ arrow==0.12.1
|
|||
asn1crypto==0.24.0 # via cryptography
|
||||
bcrypt==3.1.4 # via flask-bcrypt, paramiko
|
||||
blinker==1.4 # via flask-mail, flask-principal, raven
|
||||
boto3==1.7.6
|
||||
botocore==1.10.6 # via boto3, s3transfer
|
||||
boto3==1.7.8
|
||||
botocore==1.10.8 # via boto3, s3transfer
|
||||
cffi==1.11.5 # via bcrypt, cryptography, pynacl
|
||||
click==6.7 # via flask
|
||||
cloudflare==2.1.0
|
||||
cryptography==2.2.2
|
||||
docutils==0.14 # via botocore
|
||||
flask-bcrypt==0.7.1
|
||||
|
@ -35,13 +36,14 @@ itsdangerous==0.24 # via flask
|
|||
jinja2==2.10
|
||||
jmespath==0.9.3 # via boto3, botocore
|
||||
josepy==1.1.0 # via acme
|
||||
jsonlines==1.2.0 # via cloudflare
|
||||
lockfile==0.12.2
|
||||
mako==1.0.7 # via alembic
|
||||
markupsafe==1.0 # via jinja2, mako
|
||||
marshmallow-sqlalchemy==0.13.2
|
||||
marshmallow==2.15.0
|
||||
mock==2.0.0 # via acme
|
||||
ndg-httpsclient==0.4.4
|
||||
ndg-httpsclient==0.5.0
|
||||
paramiko==2.4.1
|
||||
pbr==4.0.2 # via mock
|
||||
pem==17.1.0
|
||||
|
@ -57,6 +59,7 @@ python-dateutil==2.7.2 # via alembic, arrow, botocore
|
|||
python-editor==1.0.3 # via alembic
|
||||
python-ldap==3.0.0
|
||||
pytz==2018.4 # via acme, flask-restful, pyrfc3339
|
||||
pyyaml==3.12 # via cloudflare
|
||||
raven[flask]==6.7.0
|
||||
requests[security]==2.11.1
|
||||
retrying==1.3.3
|
||||
|
|
Loading…
Reference in New Issue