Added CSR and SSL Certificate resource and models...still need to plumb components.

This commit is contained in:
John Wood 2013-04-12 23:29:19 -05:00
parent 45d9c956f2
commit dd69458b72
3 changed files with 129 additions and 3 deletions

View File

@ -29,6 +29,10 @@ TENANTS = TenantsResource()
TENANT = TenantResource()
# TBD: SECRETS = SecretsResource()
# TBD: SECRET = SecretResource()
CSRS = CSRsResource()
CSR = CSRResource()
CERTS = CertifcatesResource()
CERT = CertificateResource()
# Routing
application = falcon.API()
@ -38,3 +42,7 @@ api.add_route('/tenants', TENANTS)
api.add_route('/tenants/{tenant_id}', TENANT)
# TBD: api.add_route('/{tenant_id}/secrets', SECRETS)
# TBD: api.add_route('/{tenant_id}/secrets/{secret_id}', SECRET)
api.add_route('/{tenant_id}/csrs', CSRS)
api.add_route('/{tenant_id}/csrs/{csr_id}', CSR)
api.add_route('/{tenant_id}/certificates', CERTS)
api.add_route('/{tenant_id}/certificates/{cert_id}', CERT)

View File

@ -25,8 +25,10 @@ def json_handler(obj):
"""Convert objects into json-friendly equivalents."""
return obj.isoformat() if hasattr(obj, 'isoformat') else obj
class VersionResource(ApiResource):
class VersionResource(ApiResource):
"""Returns service and build version information"""
def on_get(self, req, resp):
resp.status = falcon.HTTP_200
resp.body = json.dumps({'v1': 'current',
@ -34,6 +36,7 @@ class VersionResource(ApiResource):
class TenantsResource(ApiResource):
"""Handles Tenant creation requests"""
def __init__(self, tenant_repo=None):
LOG.debug('Creating TenantsResource')
@ -66,6 +69,7 @@ class TenantsResource(ApiResource):
class TenantResource(ApiResource):
"""Handles Tenant retrieval and deletion requests"""
def __init__(self, tenant_repo=None):
self.repo = tenant_repo or TenantRepo()
@ -81,4 +85,86 @@ class TenantResource(ApiResource):
self.repo.delete_entity(tenant)
resp.status = falcon.HTTP_200
resp.status = falcon.HTTP_200
class CSRsResource(ApiResource):
"""Handles CSR (SSL certificate request) creation and lists requests"""
def __init__(self, csr_repo=None):
LOG.debug('Creating CSRsResource')
self.repo = csr_repo or CSRRepo()
def on_post(self, req, resp, tenent_id):
body = load_body(req)
# TBD: Remove:
print 'Start on_post...%s' % body
requestor = body['requestor']
# LOG.debug('Username is {0}'.format(username))
print 'requestor is %s' % requestor
# TBD: What criteria to restrict multiple concurrent SSL requests per tenant?
# csr = self.repo.find_by_name(name=requestor, suppress_exception=True)
#
#if csr:
# abort(falcon.HTTP_400, 'Tenant with username {0} '
# 'already exists'.format(username))
new_csr = CSR()
new_csr.requestor = requestor
self.repo.create_from(new_csr)
# TBD: Remove:
print '...post create from'
resp.status = falcon.HTTP_201
resp.set_header('Location', '/{0}'.format(new_csr.id))
# TBD: Generate URL...
url = 'http://localhost:8080:/csrs/%s' % new_csr.id
resp.body = json.dumps({'ref': url})
class CSRResource(ApiResource):
"""Handles CSR retrieval and deletion requests"""
def __init__(self, csr_repo=None):
self.repo = csr_repo or CSRRepo()
def on_get(self, req, resp, tenent_id, csr_id):
csr = self.repo.get(entity_id=csr_id)
resp.status = falcon.HTTP_200
resp.body = json.dumps(csr.to_dict_fields(), default=json_handler)
def on_delete(self, req, resp, tenent_id, csr_id):
csr = self.repo.get(entity_id=csr_id)
self.repo.delete_entity(csr)
resp.status = falcon.HTTP_200
class CertificatesResource(ApiResource):
"""Handles Certs (SSL certificates) lists per Tenant requests"""
def __init__(self, cert_repo=None):
LOG.debug('Creating CertificatesResource')
self.repo = cert_repo or CertificateRepo()
def on_post(self, req, resp, tenent_id):
resp.status = falcon.HTTP_405
# TBD: I18n this!
resp.body = u"To create SSL certificates, you must first issue a CSR"
class CertificateResource(ApiResource):
"""Handles Cert (SSL certificates) retrieval and deletion requests"""
def __init__(self, cert_repo=None):
self.repo = cert_repo or CertificateRepo()
def on_get(self, req, resp, tenent_id, cert_id):
cert = self.repo.get(entity_id=cert_id)
resp.status = falcon.HTTP_200
resp.body = json.dumps(cert.to_dict_fields(), default=json_handler)

View File

@ -134,11 +134,43 @@ class Tenant(BASE, ModelBase):
def _do_extra_dict_fields(self):
"""Sub-class hook method: return dict of fields."""
return {'username':self.username}
class CSR(BASE, ModelBase):
"""
Represents a CSR in the datastore
CSRs are requests to create SSL certificates, eventually sent to Certificate
Authorities who generate these certificates.
"""
__tablename__ = 'csrs'
requestor = Column(String(255))
def _do_extra_dict_fields(self):
"""Sub-class hook method: return dict of fields."""
return {'requestor':self.requestor}
class Certificate(BASE, ModelBase):
"""
Represents an SSL Certificate in the datastore, generated by a CA on
behalf of a Tenant.
"""
__tablename__ = 'certificates'
private_key = Column(String(255))
public_key = Column(String(255))
def _do_extra_dict_fields(self):
"""Sub-class hook method: return dict of fields."""
return {'private_key':self.private_key, 'public_key':self.public_key}
# Keep this tuple synchronized with the models in the file
MODELS = [Tenant]
MODELS = [Tenant, CSR, Certificate]
def register_models(engine):