Merge "Making a few MORE modules hacking 0.9.2 compliant"
This commit is contained in:
commit
bc73494661
@ -16,9 +16,10 @@
|
||||
"""
|
||||
API handler for Cloudkeep's Barbican
|
||||
"""
|
||||
import pkgutil
|
||||
|
||||
from oslo.config import cfg
|
||||
import pecan
|
||||
import pkgutil
|
||||
|
||||
from barbican.common import exception
|
||||
from barbican.common import utils
|
||||
@ -47,6 +48,7 @@ class ApiResource(object):
|
||||
|
||||
def load_body(req, resp=None, validator=None):
|
||||
"""Helper function for loading an HTTP request body from JSON.
|
||||
|
||||
This body is placed into into a Python dictionary.
|
||||
|
||||
:param req: The HTTP request instance to load the body from.
|
||||
@ -61,7 +63,7 @@ def load_body(req, resp=None, validator=None):
|
||||
pecan.abort(500, 'Read Error')
|
||||
|
||||
try:
|
||||
#TODO(jwood): Investigate how to get UTF8 format via openstack
|
||||
# TODO(jwood): Investigate how to get UTF8 format via openstack
|
||||
# jsonutils:
|
||||
# parsed_body = json.loads(raw_json, 'utf-8')
|
||||
parsed_body = json.loads(body)
|
||||
@ -169,9 +171,9 @@ def generate_safe_exception_message(operation_name, excep):
|
||||
|
||||
@pkgutil.simplegeneric
|
||||
def get_items(obj):
|
||||
"""This is used to get items from either
|
||||
a list or a dictionary. While false
|
||||
generator is need to process scalar object
|
||||
"""This is used to get items from either a list or a dictionary.
|
||||
|
||||
While false generator is need to process scalar object
|
||||
"""
|
||||
|
||||
while False:
|
||||
@ -189,9 +191,7 @@ def _json_array(obj):
|
||||
|
||||
|
||||
def strip_whitespace(json_data):
|
||||
"""This function will recursively trim values from the
|
||||
object passed in using the get_items
|
||||
"""
|
||||
"""Recursively trim values from the object passed in using get_items()."""
|
||||
|
||||
for key, value in get_items(json_data):
|
||||
if hasattr(value, 'strip'):
|
||||
|
@ -109,7 +109,9 @@ def handle_exceptions(operation_name=u._('System')):
|
||||
|
||||
|
||||
def _do_enforce_content_types(pecan_req, valid_content_types):
|
||||
"""Check to see that content type in the request is one of the valid
|
||||
"""Content type enforcement
|
||||
|
||||
Check to see that content type in the request is one of the valid
|
||||
types passed in by our caller.
|
||||
"""
|
||||
if pecan_req.content_type not in valid_content_types:
|
||||
|
@ -133,8 +133,9 @@ class ContainerConsumersController(object):
|
||||
new_consumer.tenant_id = tenant.id
|
||||
self.consumer_repo.create_from(new_consumer)
|
||||
|
||||
pecan.response.headers['Location'] = '/{0}/containers/{1}/consumers' \
|
||||
.format(keystone_id, new_consumer.container_id)
|
||||
pecan.response.headers['Location'] = (
|
||||
'/containers/{0}/consumers'.format(new_consumer.container_id)
|
||||
)
|
||||
|
||||
return self._return_container_data(self.container_id, keystone_id)
|
||||
|
||||
|
@ -38,7 +38,7 @@ class ContainerController(object):
|
||||
|
||||
def __init__(self, container_id, tenant_repo=None, container_repo=None,
|
||||
consumer_repo=None):
|
||||
#TODO(rm_work): refactor this to use repo-factory method
|
||||
# TODO(rm_work): refactor this to use repo-factory method
|
||||
self.container_id = container_id
|
||||
self.tenant_repo = tenant_repo or repo.TenantRepo()
|
||||
self.container_repo = container_repo or repo.ContainerRepo()
|
||||
@ -86,7 +86,7 @@ class ContainersController(object):
|
||||
|
||||
def __init__(self, tenant_repo=None, container_repo=None,
|
||||
secret_repo=None, consumer_repo=None):
|
||||
#TODO(rm_work): refactor this to use repo-factory method
|
||||
# TODO(rm_work): refactor this to use repo-factory method
|
||||
self.tenant_repo = tenant_repo or repo.TenantRepo()
|
||||
self.container_repo = container_repo or repo.ContainerRepo()
|
||||
self.secret_repo = secret_repo or repo.SecretRepo()
|
||||
@ -152,7 +152,7 @@ class ContainersController(object):
|
||||
new_container = models.Container(data)
|
||||
new_container.tenant_id = tenant.id
|
||||
|
||||
#TODO(hgedikli): performance optimizations
|
||||
# TODO(hgedikli): performance optimizations
|
||||
for secret_ref in new_container.container_secrets:
|
||||
secret = self.secret_repo.get(entity_id=secret_ref.secret_id,
|
||||
keystone_id=keystone_id,
|
||||
@ -166,8 +166,8 @@ class ContainersController(object):
|
||||
self.container_repo.create_from(new_container)
|
||||
|
||||
pecan.response.status = 201
|
||||
pecan.response.headers['Location'] = '/{0}/containers/{1}'.format(
|
||||
keystone_id, new_container.id
|
||||
pecan.response.headers['Location'] = '/containers/{0}'.format(
|
||||
new_container.id
|
||||
)
|
||||
url = hrefs.convert_container_to_href(new_container.id)
|
||||
return {'container_ref': url}
|
||||
|
@ -174,11 +174,9 @@ class OrdersController(object):
|
||||
LOG.debug('Start orders on_get '
|
||||
'for tenant-ID %s:', keystone_id)
|
||||
|
||||
result = self.order_repo \
|
||||
.get_by_create_date(keystone_id,
|
||||
offset_arg=kw.get('offset', 0),
|
||||
limit_arg=kw.get('limit', None),
|
||||
suppress_exception=True)
|
||||
result = self.order_repo.get_by_create_date(
|
||||
keystone_id, offset_arg=kw.get('offset', 0),
|
||||
limit_arg=kw.get('limit', None), suppress_exception=True)
|
||||
orders, offset, limit, total = result
|
||||
|
||||
if not orders:
|
||||
@ -210,8 +208,8 @@ class OrdersController(object):
|
||||
|
||||
tenant = res.get_or_create_tenant(keystone_id, self.tenant_repo)
|
||||
|
||||
#Note(atiwari): trying to preserve backward compatibility
|
||||
#This will be removed as part of bug1335171
|
||||
# Note(atiwari): trying to preserve backward compatibility
|
||||
# This will be removed as part of bug1335171
|
||||
raw_body = pecan.request.body
|
||||
order_type = None
|
||||
if raw_body:
|
||||
@ -225,7 +223,7 @@ class OrdersController(object):
|
||||
new_order.meta = body.get('meta')
|
||||
new_order.type = order_type
|
||||
|
||||
#TODO(john-wood-w) These are required attributes currently, but
|
||||
# TODO(john-wood-w) These are required attributes currently, but
|
||||
# will eventually be removed once we drop the legacy orders
|
||||
# request.
|
||||
new_order.secret_name = 'N/A'
|
||||
@ -257,7 +255,7 @@ class OrdersController(object):
|
||||
self.order_repo.create_from(new_order)
|
||||
|
||||
# Send to workers to process.
|
||||
#TODO(atiwari) - bug 1335171
|
||||
# TODO(atiwari) - bug 1335171
|
||||
if order_type:
|
||||
self.queue.process_type_order(order_id=new_order.id,
|
||||
keystone_id=keystone_id)
|
||||
|
@ -71,7 +71,7 @@ class SecretController(object):
|
||||
LOG.debug('=== Creating SecretController ===')
|
||||
self.secret_id = secret_id
|
||||
|
||||
#TODO(john-wood-w) Remove passed-in repositories in favor of
|
||||
# TODO(john-wood-w) Remove passed-in repositories in favor of
|
||||
# repository factories and patches in unit tests.
|
||||
self.repos = repo.Repositories(tenant_repo=tenant_repo,
|
||||
secret_repo=secret_repo,
|
||||
@ -215,6 +215,9 @@ class SecretsController(object):
|
||||
@controllers.handle_exceptions(u._('Secret(s) retrieval'))
|
||||
@controllers.enforce_rbac('secrets:get')
|
||||
def index(self, keystone_id, **kw):
|
||||
def secret_fields(field):
|
||||
return putil.mime_types.augment_fields_with_content_types(field)
|
||||
|
||||
LOG.debug('Start secrets on_get '
|
||||
'for tenant-ID %s:', keystone_id)
|
||||
|
||||
@ -247,8 +250,6 @@ class SecretsController(object):
|
||||
secrets_resp_overall = {'secrets': [],
|
||||
'total': total}
|
||||
else:
|
||||
secret_fields = lambda sf: putil.mime_types\
|
||||
.augment_fields_with_content_types(sf)
|
||||
secrets_resp = [
|
||||
hrefs.convert_to_hrefs(secret_fields(s))
|
||||
for s in secrets
|
||||
|
@ -17,6 +17,7 @@
|
||||
Barbican middleware modules.
|
||||
"""
|
||||
import sys
|
||||
|
||||
import webob.dec
|
||||
|
||||
from barbican.common import utils
|
||||
@ -25,7 +26,9 @@ LOG = utils.getLogger(__name__)
|
||||
|
||||
|
||||
class Middleware(object):
|
||||
"""Base WSGI middleware wrapper. These classes require an application to be
|
||||
"""Base WSGI middleware wrapper
|
||||
|
||||
These classes require an application to be
|
||||
initialized that will be called next. By default the middleware will
|
||||
simply call its wrapped app, or you can override __call__ to customize its
|
||||
behavior.
|
||||
@ -66,7 +69,9 @@ class Middleware(object):
|
||||
|
||||
# Brought over from an OpenStack project
|
||||
class Debug(Middleware):
|
||||
"""Helper class that can be inserted into any WSGI application chain
|
||||
"""Debug helper class
|
||||
|
||||
This class can be inserted into any WSGI application chain
|
||||
to get information about the request and response.
|
||||
"""
|
||||
|
||||
@ -89,9 +94,7 @@ class Debug(Middleware):
|
||||
|
||||
@staticmethod
|
||||
def print_generator(app_iter):
|
||||
"""Iterator that prints the contents of a wrapper string iterator
|
||||
when iterated.
|
||||
"""
|
||||
"""Iterator that prints the contents of a wrapper string iterator."""
|
||||
LOG.debug(("*" * 40) + " BODY")
|
||||
for part in app_iter:
|
||||
sys.stdout.write(part)
|
||||
|
@ -14,11 +14,10 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
import webob.exc
|
||||
|
||||
from oslo.config import cfg
|
||||
import webob.exc
|
||||
|
||||
from barbican.api import middleware as mw
|
||||
from barbican.common import utils
|
||||
@ -103,13 +102,13 @@ class ContextMiddleware(BaseContextMiddleware):
|
||||
return barbican.context.RequestContext(**kwargs)
|
||||
|
||||
def _get_authenticated_context(self, req):
|
||||
#NOTE(bcwaldon): X-Roles is a csv string, but we need to parse
|
||||
# NOTE(bcwaldon): X-Roles is a csv string, but we need to parse
|
||||
# it into a list to be useful
|
||||
roles_header = req.headers.get('X-Roles', '')
|
||||
roles = [r.strip().lower() for r in roles_header.split(',')]
|
||||
|
||||
#NOTE(bcwaldon): This header is deprecated in favor of X-Auth-Token
|
||||
#(mkbhanda) keeping this just-in-case for swift
|
||||
# NOTE(bcwaldon): This header is deprecated in favor of X-Auth-Token
|
||||
# NOTE(mkbhanda): keeping this just-in-case for swift
|
||||
deprecated_token = req.headers.get('X-Storage-Token')
|
||||
|
||||
service_catalog = None
|
||||
|
@ -121,7 +121,7 @@ class ProtectedImageDelete(Forbidden):
|
||||
message = u._("Image %(image_id)s is protected and cannot be deleted.")
|
||||
|
||||
|
||||
#NOTE(bcwaldon): here for backwards-compatibility, need to deprecate.
|
||||
# NOTE(bcwaldon): here for backwards-compatibility, need to deprecate.
|
||||
class NotAuthorized(Forbidden):
|
||||
message = u._("You are not authorized to complete this action.")
|
||||
|
||||
|
@ -49,7 +49,7 @@ def convert_transport_key_to_href(transport_key_id):
|
||||
return utils.hostname_for_refs(resource=resource)
|
||||
|
||||
|
||||
#TODO(hgedikli) handle list of fields in here
|
||||
# TODO(hgedikli) handle list of fields in here
|
||||
def convert_to_hrefs(fields):
|
||||
"""Convert id's within a fields dict to HATEOS-style hrefs."""
|
||||
if 'secret_id' in fields:
|
||||
|
@ -121,7 +121,9 @@ def generate_fullname_for(instance):
|
||||
|
||||
|
||||
class TimeKeeper(object):
|
||||
"""Keeps track of elapsed times and then allows for dumping a summary to
|
||||
"""TimeKeeper object
|
||||
|
||||
Keeps track of elapsed times and then allows for dumping a summary to
|
||||
logs. This class can be used to profile a method as a fine grain level.
|
||||
"""
|
||||
|
||||
@ -133,9 +135,9 @@ class TimeKeeper(object):
|
||||
self.elapsed = []
|
||||
|
||||
def mark(self, note=None):
|
||||
"""Mark a moment in time, with an optional note as to what is
|
||||
occurring at the time.
|
||||
:param note: Optional note
|
||||
"""Mark a moment in time, with an optional note
|
||||
|
||||
:param note: Optional note about what is occurring at this time
|
||||
"""
|
||||
time_curr = time.time()
|
||||
self.elapsed.append((time_curr, time_curr - self.time_last, note))
|
||||
|
@ -70,7 +70,9 @@ class ValidatorBase(object):
|
||||
"""
|
||||
|
||||
def _full_name(self, parent_schema=None):
|
||||
"""Returns the full schema name for this validator,
|
||||
"""Validator schema name accessor
|
||||
|
||||
Returns the full schema name for this validator,
|
||||
including parent name.
|
||||
"""
|
||||
schema_name = self.name
|
||||
@ -80,8 +82,7 @@ class ValidatorBase(object):
|
||||
return schema_name
|
||||
|
||||
def _assert_schema_is_valid(self, json_data, schema_name):
|
||||
"""Assert that the JSON structure is valid according to the given
|
||||
schema.
|
||||
"""Assert that the JSON structure is valid for the given schema.
|
||||
|
||||
:raises: InvalidObject exception if the data is not schema compliant.
|
||||
"""
|
||||
@ -190,8 +191,9 @@ class NewSecretValidator(ValidatorBase):
|
||||
return expiration
|
||||
|
||||
def _assert_expiration_is_valid(self, expiration, schema_name):
|
||||
"""Asserts that the given expiration date is valid. Which means that
|
||||
it should not be in the past.
|
||||
"""Asserts that the given expiration date is valid.
|
||||
|
||||
Expiration dates must be in the future, not the past.
|
||||
"""
|
||||
if expiration:
|
||||
# Verify not already expired.
|
||||
@ -202,7 +204,9 @@ class NewSecretValidator(ValidatorBase):
|
||||
|
||||
def _validate_content_parameters(self, content_type, content_encoding,
|
||||
schema_name):
|
||||
"""Check that the content_type, content_encoding and the parameters
|
||||
"""Content parameter validator.
|
||||
|
||||
Check that the content_type, content_encoding and the parameters
|
||||
that they affect are valid.
|
||||
"""
|
||||
self._assert_validity(
|
||||
@ -247,7 +251,7 @@ class NewSecretValidator(ValidatorBase):
|
||||
return payload.strip()
|
||||
|
||||
|
||||
#TODO(atiwari) - Split this validator module and unit tests
|
||||
# TODO(atiwari) - Split this validator module and unit tests
|
||||
# into smaller modules
|
||||
class TypeOrderValidator(ValidatorBase):
|
||||
"""Validate a new typed order."""
|
||||
@ -270,7 +274,7 @@ class TypeOrderValidator(ValidatorBase):
|
||||
self._assert_schema_is_valid(json_data, schema_name)
|
||||
|
||||
order_type = json_data.get('type').lower()
|
||||
#Note(atiwari): No support for certificate so far
|
||||
# Note(atiwari): No support for certificate so far
|
||||
if order_type == models.OrderType.CERTIFICATE:
|
||||
certificate_meta = json_data.get('meta')
|
||||
self._validate_certificate_meta(certificate_meta, schema_name)
|
||||
@ -288,7 +292,7 @@ class TypeOrderValidator(ValidatorBase):
|
||||
return json_data
|
||||
|
||||
def _validate_key_meta(self, key_meta, schema_name):
|
||||
"""validation specific to meta for key type order"""
|
||||
"""Validation specific to meta for key type order."""
|
||||
|
||||
self._assert_validity(key_meta is not None,
|
||||
schema_name,
|
||||
@ -304,8 +308,8 @@ class TypeOrderValidator(ValidatorBase):
|
||||
# Validation secret generation related fields.
|
||||
# TODO(jfwood): Invoke the crypto plugin for this purpose
|
||||
|
||||
if key_meta.get('payload_content_type', '').lower() !=\
|
||||
'application/octet-stream':
|
||||
if (key_meta.get('payload_content_type', '').lower() !=
|
||||
'application/octet-stream'):
|
||||
raise exception.UnsupportedField(field='payload_content_type',
|
||||
schema=schema_name,
|
||||
reason=u._("Only 'application/oc"
|
||||
@ -327,14 +331,14 @@ class TypeOrderValidator(ValidatorBase):
|
||||
self._validate_bit_length(key_meta, schema_name)
|
||||
|
||||
def _validate_asymmetric_meta(self, asymmetric_meta, schema_name):
|
||||
"""validation specific to meta for asymmetric type order"""
|
||||
"""Validation specific to meta for asymmetric type order."""
|
||||
self._assert_validity(asymmetric_meta is not None,
|
||||
schema_name,
|
||||
u._("'meta' attributes is required"), "meta")
|
||||
self._raise_feature_not_implemented('asymmetric', schema_name)
|
||||
|
||||
def _validate_certificate_meta(self, certificate_meta, schema_name):
|
||||
"""validation specific to meta for certificate type order"""
|
||||
"""Validation specific to meta for certificate type order."""
|
||||
self._assert_validity(certificate_meta is not None,
|
||||
schema_name,
|
||||
u._("'meta' attributes is required"), "meta")
|
||||
@ -384,7 +388,7 @@ class TypeOrderValidator(ValidatorBase):
|
||||
.format(order_type))
|
||||
|
||||
|
||||
#TODO(atiwari) - Remove this Validator for bug 1335171
|
||||
# TODO(atiwari) - Remove this Validator for bug 1335171
|
||||
class NewOrderValidator(ValidatorBase):
|
||||
"""Validate a new order."""
|
||||
|
||||
@ -451,7 +455,7 @@ class NewOrderValidator(ValidatorBase):
|
||||
|
||||
|
||||
class ContainerConsumerValidator(ValidatorBase):
|
||||
""" Validate a Consumer"""
|
||||
"""Validate a Consumer."""
|
||||
|
||||
def __init__(self):
|
||||
self.name = 'Consumer'
|
||||
@ -472,7 +476,7 @@ class ContainerConsumerValidator(ValidatorBase):
|
||||
|
||||
|
||||
class ContainerValidator(ValidatorBase):
|
||||
""" Validator for all types of Container"""
|
||||
"""Validator for all types of Container."""
|
||||
|
||||
def __init__(self):
|
||||
self.name = 'Container'
|
||||
@ -482,7 +486,7 @@ class ContainerValidator(ValidatorBase):
|
||||
"name": {"type": "string"},
|
||||
"type": {
|
||||
"type": "string",
|
||||
# TODO: (hgedikli) move this to a common location
|
||||
# TODO(hgedikli): move this to a common location
|
||||
"enum": ["generic", "rsa", "certificate"]
|
||||
},
|
||||
"secret_refs": {
|
||||
|
@ -10,11 +10,9 @@
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import abc
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
import six
|
||||
|
||||
from barbican.common import exception
|
||||
@ -67,7 +65,7 @@ class CryptoPrivateKeyFailureException(exception.BarbicanException):
|
||||
)
|
||||
|
||||
|
||||
#TODO(john-wood-w) Need to harmonize these lower-level constants with the
|
||||
# TODO(john-wood-w) Need to harmonize these lower-level constants with the
|
||||
# higher level constants in secret_store.py.
|
||||
class PluginSupportTypes(object):
|
||||
"""Class to hold the type enumeration that plugins may support."""
|
||||
@ -84,7 +82,9 @@ class PluginSupportTypes(object):
|
||||
|
||||
|
||||
class KEKMetaDTO(object):
|
||||
"""Key Encryption Keys (KEKs) in Barbican are intended to represent a
|
||||
"""Key Encryption Key Meta DTO
|
||||
|
||||
Key Encryption Keys (KEKs) in Barbican are intended to represent a
|
||||
distinct key that is used to perform encryption on secrets for a particular
|
||||
project (tenant).
|
||||
|
||||
@ -140,9 +140,9 @@ class KEKMetaDTO(object):
|
||||
"""
|
||||
|
||||
def __init__(self, kek_datum):
|
||||
"""kek_datum is typically a barbican.model.models.EncryptedDatum
|
||||
instance. Plugins should never have to create their own instance of
|
||||
this class.
|
||||
"""Plugins should not have to create their own instance of this class.
|
||||
|
||||
kek_datum is typically a barbican.model.models.EncryptedDatum instance.
|
||||
"""
|
||||
self.kek_label = kek_datum.kek_label
|
||||
self.plugin_name = kek_datum.plugin_name
|
||||
@ -153,7 +153,9 @@ class KEKMetaDTO(object):
|
||||
|
||||
|
||||
class GenerateDTO(object):
|
||||
"""Data Transfer Object used to pass all the necessary data for the plugin
|
||||
"""Secret Generation DTO
|
||||
|
||||
Data Transfer Object used to pass all the necessary data for the plugin
|
||||
to generate a secret on behalf of the user.
|
||||
|
||||
.. attribute:: generation_type
|
||||
@ -195,7 +197,9 @@ class ResponseDTO(object):
|
||||
|
||||
|
||||
class DecryptDTO(object):
|
||||
"""Data Transfer Object used to pass all the necessary data for the plugin
|
||||
"""Secret Decryption DTO
|
||||
|
||||
Data Transfer Object used to pass all the necessary data for the plugin
|
||||
to perform decryption of a secret.
|
||||
|
||||
Currently, this DTO only contains the data produced by the plugin during
|
||||
@ -216,7 +220,9 @@ class DecryptDTO(object):
|
||||
|
||||
|
||||
class EncryptDTO(object):
|
||||
"""Data Transfer Object used to pass all the necessary data for the plugin
|
||||
"""Secret Encryption DTO
|
||||
|
||||
Data Transfer Object used to pass all the necessary data for the plugin
|
||||
to perform encryption of a secret.
|
||||
|
||||
Currently, this DTO only contains the raw bytes to be encrypted by the
|
||||
@ -233,9 +239,10 @@ class EncryptDTO(object):
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class CryptoPluginBase(object):
|
||||
"""Base class for all Crypto plugins. Implementations of this abstract
|
||||
base class will be used by Barbican to perform cryptographic operations on
|
||||
secrets.
|
||||
"""Base class for all Crypto plugins.
|
||||
|
||||
Implementations of this abstract base class will be used by Barbican to
|
||||
perform cryptographic operations on secrets.
|
||||
|
||||
Barbican requests operations by invoking the methods on an instance of the
|
||||
implementing class. Barbican's plugin manager handles the life-cycle of
|
||||
@ -243,10 +250,12 @@ class CryptoPluginBase(object):
|
||||
persist the data that is assigned to these DTOs by the plugin.
|
||||
"""
|
||||
|
||||
#TODO(atiwari): fix 1331815
|
||||
# TODO(atiwari): fix 1331815
|
||||
@abc.abstractmethod
|
||||
def encrypt(self, encrypt_dto, kek_meta_dto, keystone_id):
|
||||
"""This method will be called by Barbican when requesting an encryption
|
||||
"""Encryption handler function
|
||||
|
||||
This method will be called by Barbican when requesting an encryption
|
||||
operation on a secret on behalf of a project (tenant).
|
||||
|
||||
:param encrypt_dto: :class:`EncryptDTO` instance containing the raw
|
||||
@ -300,7 +309,9 @@ class CryptoPluginBase(object):
|
||||
|
||||
@abc.abstractmethod
|
||||
def bind_kek_metadata(self, kek_meta_dto):
|
||||
"""Bind a key encryption key (KEK) metadata to the sub-system
|
||||
"""Key Encryption Key Metadata binding function
|
||||
|
||||
Bind a key encryption key (KEK) metadata to the sub-system
|
||||
handling encryption/decryption, updating information about the
|
||||
key encryption key (KEK) metadata in the supplied 'kek_metadata'
|
||||
data-transfer-object instance, and then returning this instance.
|
||||
@ -357,7 +368,7 @@ class CryptoPluginBase(object):
|
||||
"""
|
||||
raise NotImplementedError # pragma: no cover
|
||||
|
||||
#TODO(atiwari): fix 1331815
|
||||
# TODO(atiwari): fix 1331815
|
||||
@abc.abstractmethod
|
||||
def supports(self, type_enum, algorithm=None, bit_length=None,
|
||||
mode=None):
|
||||
|
@ -24,7 +24,9 @@ CONF = cfg.CONF
|
||||
class _CryptoPluginManager(named.NamedExtensionManager):
|
||||
def __init__(self, conf=CONF, invoke_on_load=True,
|
||||
invoke_args=(), invoke_kwargs={}):
|
||||
"""Each time this class is initialized it will load a new instance
|
||||
"""Crypto Plugin Manager
|
||||
|
||||
Each time this class is initialized it will load a new instance
|
||||
of each enabled crypto plugin. This is undesirable, so rather than
|
||||
initializing a new instance of this class use the PLUGIN_MANAGER
|
||||
at the module level.
|
||||
|
@ -21,10 +21,9 @@ import base64
|
||||
from oslo.config import cfg
|
||||
|
||||
from barbican.common import exception
|
||||
from barbican.plugin.crypto import crypto as plugin
|
||||
|
||||
from barbican.openstack.common import gettextutils as u
|
||||
from barbican.openstack.common import jsonutils as json
|
||||
from barbican.plugin.crypto import crypto as plugin
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
@ -51,6 +50,7 @@ class P11CryptoPluginException(exception.BarbicanException):
|
||||
|
||||
class P11CryptoPlugin(plugin.CryptoPluginBase):
|
||||
"""PKCS11 supporting implementation of the crypto plugin.
|
||||
|
||||
Generates a key per tenant and encrypts using AES-256-GCM.
|
||||
This implementation currently relies on an unreleased fork of PyKCS11.
|
||||
"""
|
||||
|
@ -10,16 +10,13 @@
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
|
||||
from Crypto.PublicKey import DSA
|
||||
from Crypto.PublicKey import RSA
|
||||
from Crypto.Util import asn1
|
||||
from cryptography import fernet
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
import six
|
||||
|
||||
from barbican.openstack.common import gettextutils as u
|
||||
@ -94,7 +91,8 @@ class SimpleCryptoPlugin(c.CryptoPluginBase):
|
||||
keystone_id)
|
||||
|
||||
def generate_asymmetric(self, generate_dto, kek_meta_dto, keystone_id):
|
||||
"""Generate asymmetric keys based on below rule
|
||||
"""Generate asymmetric keys based on below rules:
|
||||
|
||||
- RSA, with passphrase (supported)
|
||||
- RSA, without passphrase (supported)
|
||||
- DSA, without passphrase (supported)
|
||||
@ -108,8 +106,8 @@ class SimpleCryptoPlugin(c.CryptoPluginBase):
|
||||
DSA keys and DER formated keys, later we need to pick better
|
||||
crypto lib.
|
||||
"""
|
||||
if generate_dto.algorithm is None\
|
||||
or generate_dto.algorithm.lower() == 'rsa':
|
||||
if(generate_dto.algorithm is None or generate_dto
|
||||
.algorithm.lower() == 'rsa'):
|
||||
private_key = RSA.generate(
|
||||
generate_dto.bit_length, None, None, 65537)
|
||||
elif generate_dto.algorithm.lower() == 'dsa':
|
||||
@ -139,8 +137,8 @@ class SimpleCryptoPlugin(c.CryptoPluginBase):
|
||||
passphrase_dto = None
|
||||
if generate_dto.passphrase:
|
||||
if isinstance(generate_dto.passphrase, six.text_type):
|
||||
generate_dto.passphrase = \
|
||||
generate_dto.passphrase.encode('utf-8')
|
||||
generate_dto.passphrase = generate_dto.passphrase.encode(
|
||||
'utf-8')
|
||||
|
||||
passphrase_dto = self.encrypt(c.EncryptDTO(generate_dto.
|
||||
passphrase),
|
||||
@ -179,14 +177,16 @@ class SimpleCryptoPlugin(c.CryptoPluginBase):
|
||||
pub_seq = asn1.DerSequence()
|
||||
pub_seq[:] = [0, public_key.p, public_key.q,
|
||||
public_key.g, public_key.y]
|
||||
public_key = "-----BEGIN DSA PUBLIC KEY-----\n%s"\
|
||||
"-----END DSA PUBLIC KEY-----" % pub_seq.encode().encode("base64")
|
||||
public_key = ("-----BEGIN DSA PUBLIC KEY-----\n{0}"
|
||||
"-----END DSA PUBLIC KEY-----"
|
||||
.format(pub_seq.encode().encode("base64")))
|
||||
|
||||
prv_seq = asn1.DerSequence()
|
||||
prv_seq[:] = [0, private_key.p, private_key.q,
|
||||
private_key.g, private_key.y, private_key.x]
|
||||
private_key = "-----BEGIN DSA PRIVATE KEY-----\n%s"\
|
||||
"-----END DSA PRIVATE KEY-----" % prv_seq.encode().encode("base64")
|
||||
private_key = ("-----BEGIN DSA PRIVATE KEY-----\n{0}"
|
||||
"-----END DSA PRIVATE KEY-----"
|
||||
.format(prv_seq.encode().encode("base64")))
|
||||
|
||||
return public_key, private_key
|
||||
|
||||
@ -195,11 +195,12 @@ class SimpleCryptoPlugin(c.CryptoPluginBase):
|
||||
if algorithm is None or bit_length is None:
|
||||
return False
|
||||
|
||||
if algorithm.lower() in c.PluginSupportTypes.SYMMETRIC_ALGORITHMS \
|
||||
and bit_length in c.PluginSupportTypes.SYMMETRIC_KEY_LENGTHS:
|
||||
if (algorithm.lower() in
|
||||
c.PluginSupportTypes.SYMMETRIC_ALGORITHMS and bit_length in
|
||||
c.PluginSupportTypes.SYMMETRIC_KEY_LENGTHS):
|
||||
return True
|
||||
elif algorithm.lower() in c.PluginSupportTypes.ASYMMETRIC_ALGORITHMS \
|
||||
and bit_length in c.PluginSupportTypes.ASYMMETRIC_KEY_LENGTHS:
|
||||
elif (algorithm.lower() in c.PluginSupportTypes.ASYMMETRIC_ALGORITHMS
|
||||
and bit_length in c.PluginSupportTypes.ASYMMETRIC_KEY_LENGTHS):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
@ -105,7 +105,7 @@ class DogtagKRAPlugin(sstore.SecretStoreBase):
|
||||
crypto, create_nss_db = setup_nss_db(conf)
|
||||
connection = create_connection(conf, 'kra')
|
||||
|
||||
#create kraclient
|
||||
# create kraclient
|
||||
kraclient = pki.kra.KRAClient(connection, crypto)
|
||||
self.keyclient = kraclient.keys
|
||||
self.systemcert_client = kraclient.system_certs
|
||||
@ -270,6 +270,7 @@ class DogtagKRAPlugin(sstore.SecretStoreBase):
|
||||
@staticmethod
|
||||
def _map_algorithm(algorithm):
|
||||
"""Map Barbican algorithms to Dogtag plugin algorithms.
|
||||
|
||||
Note that only algorithms supported by Dogtag will be mapped.
|
||||
"""
|
||||
if algorithm == sstore.KeyAlgorithm.AES:
|
||||
@ -288,7 +289,7 @@ class DogtagKRAPlugin(sstore.SecretStoreBase):
|
||||
# asymmetric keys not yet supported
|
||||
return None
|
||||
elif algorithm == sstore.KeyAlgorithm.RSA:
|
||||
#asymmetric keys not yet supported
|
||||
# asymmetric keys not yet supported
|
||||
return None
|
||||
else:
|
||||
return None
|
||||
@ -346,6 +347,7 @@ class DogtagCAPlugin(cm.CertificatePluginBase):
|
||||
|
||||
def check_certificate_status(self, order_id, order_meta, plugin_meta):
|
||||
"""Check the status of a certificate request.
|
||||
|
||||
:param order_id: ID of the order associated with this request
|
||||
:param order_meta: order_metadata associated with this order
|
||||
:param plugin_meta: data populated by previous calls for this order,
|
||||
@ -431,7 +433,7 @@ class DogtagCAPlugin(cm.CertificatePluginBase):
|
||||
raise cm.CertificateGeneralException(
|
||||
"No request returned in enrollment_results")
|
||||
|
||||
#store the request_id in the plugin metadata
|
||||
# store the request_id in the plugin metadata
|
||||
plugin_meta[self.REQUEST_ID] = request.request_id
|
||||
|
||||
cert = enrollment_result.cert
|
||||
|
@ -14,9 +14,9 @@
|
||||
# limitations under the License.
|
||||
|
||||
import abc
|
||||
import six
|
||||
|
||||
from oslo.config import cfg
|
||||
import six
|
||||
from stevedore import named
|
||||
|
||||
from barbican.common import exception
|
||||
@ -56,9 +56,7 @@ class SecretStorePluginNotFound(exception.BarbicanException):
|
||||
|
||||
|
||||
class SecretStoreSupportedPluginNotFound(exception.BarbicanException):
|
||||
"""Raised when no plugins are found that support the requested
|
||||
operation.
|
||||
"""
|
||||
"""Raised if no plugins are found that support the requested operation."""
|
||||
message = "Secret store plugin not found for requested operation."
|
||||
|
||||
|
||||
@ -153,8 +151,9 @@ class SecretStorePluginsNotConfigured(exception.BarbicanException):
|
||||
|
||||
class SecretType(object):
|
||||
|
||||
"""Constant to define the symmetric key type. Used by getSecret to retrieve
|
||||
a symmetric key.
|
||||
"""Constant to define the symmetric key type.
|
||||
|
||||
Used by getSecret to retrieve a symmetric key.
|
||||
"""
|
||||
SYMMETRIC = "symmetric"
|
||||
"""Constant to define the public key type. Used by getSecret to retrieve a
|
||||
@ -225,13 +224,14 @@ class KeySpec(object):
|
||||
|
||||
|
||||
class SecretDTO(object):
|
||||
"""This object is a secret data transfer object (DTO). This object
|
||||
encapsulates a key and attributes about the key. The attributes include a
|
||||
KeySpec that contains the algorithm and bit length. The attributes also
|
||||
include information on the encoding of the key.
|
||||
"""This object is a secret data transfer object (DTO).
|
||||
|
||||
This object encapsulates a key and attributes about the key. The attributes
|
||||
include a KeySpec that contains the algorithm and bit length. The
|
||||
attributes also include information on the encoding of the key.
|
||||
"""
|
||||
|
||||
#TODO(john-wood-w) Remove 'content_type' once secret normalization work is
|
||||
# TODO(john-wood-w) Remove 'content_type' once secret normalization work is
|
||||
# completed.
|
||||
def __init__(self, type, secret, key_spec, content_type,
|
||||
transport_key=None):
|
||||
@ -257,9 +257,9 @@ class SecretDTO(object):
|
||||
|
||||
|
||||
class AsymmetricKeyMetadataDTO(object):
|
||||
"""This DTO encapsulates metadata(s) for asymmetric key
|
||||
components. These components are private_key_meta,
|
||||
public_key_meta and passphrase_meta.
|
||||
"""This DTO encapsulates metadata(s) for asymmetric key components.
|
||||
|
||||
These components are private_key_meta, public_key_meta and passphrase_meta.
|
||||
"""
|
||||
|
||||
def __init__(self, private_key_meta=None,
|
||||
@ -276,7 +276,7 @@ class AsymmetricKeyMetadataDTO(object):
|
||||
self.passphrase_meta = passphrase_meta
|
||||
|
||||
|
||||
#TODO(john-wood-w) Remove this class once repository factory work is
|
||||
# TODO(john-wood-w) Remove this class once repository factory work is
|
||||
# completed.
|
||||
class SecretStoreContext(object):
|
||||
"""Context for secret store plugins.
|
||||
@ -294,9 +294,9 @@ class SecretStoreContext(object):
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class SecretStoreBase(object):
|
||||
|
||||
#TODO(john-wood-w) Remove 'context' once repository factory and secret
|
||||
# TODO(john-wood-w) Remove 'context' once repository factory and secret
|
||||
# normalization work is completed.
|
||||
#TODO(john-wood-w) Combine generate_symmetric_key() and
|
||||
# TODO(john-wood-w) Combine generate_symmetric_key() and
|
||||
# generate_asymmetric_key() into one method: generate_key(), that will
|
||||
# return a dict with this structure:
|
||||
# { SecretType.xxxxx: {secret-meta dict}
|
||||
@ -467,6 +467,7 @@ class SecretStorePluginManager(named.NamedExtensionManager):
|
||||
def get_plugin_store(self, key_spec, plugin_name=None,
|
||||
transport_key_needed=False):
|
||||
"""Gets a secret store plugin.
|
||||
|
||||
:param: plugin_name: set to plugin_name to get specific plugin
|
||||
:param: key_spec: KeySpec of key that will be stored
|
||||
:param: transport_key_needed: set to True if a transport
|
||||
@ -487,8 +488,8 @@ class SecretStorePluginManager(named.NamedExtensionManager):
|
||||
|
||||
else:
|
||||
for ext in self.extensions:
|
||||
if ext.obj.get_transport_key() is not None and\
|
||||
ext.obj.store_secret_supports(key_spec):
|
||||
if (ext.obj.get_transport_key() is not None and
|
||||
ext.obj.store_secret_supports(key_spec)):
|
||||
return ext.obj
|
||||
|
||||
raise SecretStoreSupportedPluginNotFound()
|
||||
|
@ -22,8 +22,9 @@ def get_transport_key_model(key_spec, repos, transport_key_needed):
|
||||
if transport_key_needed:
|
||||
# get_plugin_store() will throw an exception if no suitable
|
||||
# plugin with transport key is found
|
||||
store_plugin = secret_store.SecretStorePluginManager(). \
|
||||
get_plugin_store(key_spec=key_spec, transport_key_needed=True)
|
||||
plugin_manager = secret_store.SecretStorePluginManager()
|
||||
store_plugin = plugin_manager.get_plugin_store(
|
||||
key_spec=key_spec, transport_key_needed=True)
|
||||
plugin_name = utils.generate_fullname_for(store_plugin)
|
||||
|
||||
key_repo = repos.transport_key_repo
|
||||
@ -94,18 +95,19 @@ def store_secret(unencrypted_raw, content_type_raw, content_encoding,
|
||||
repos, transport_key_id)
|
||||
|
||||
# Locate a suitable plugin to store the secret.
|
||||
store_plugin = secret_store.SecretStorePluginManager().\
|
||||
get_plugin_store(key_spec=key_spec, plugin_name=plugin_name)
|
||||
plugin_manager = secret_store.SecretStorePluginManager()
|
||||
store_plugin = plugin_manager.get_plugin_store(
|
||||
key_spec=key_spec, plugin_name=plugin_name)
|
||||
|
||||
# Normalize inputs prior to storage.
|
||||
#TODO(john-wood-w) Normalize all secrets to base64, so we don't have to
|
||||
# TODO(john-wood-w) Normalize all secrets to base64, so we don't have to
|
||||
# pass in 'content' type to the store_secret() call below.
|
||||
unencrypted, content_type = tr.normalize_before_encryption(
|
||||
unencrypted_raw, content_type_raw, content_encoding,
|
||||
enforce_text_only=True)
|
||||
|
||||
# Store the secret securely.
|
||||
#TODO(john-wood-w) Remove the SecretStoreContext once repository factory
|
||||
# TODO(john-wood-w) Remove the SecretStoreContext once repository factory
|
||||
# and unit test patch work is completed.
|
||||
context = secret_store.SecretStoreContext(secret_model=secret_model,
|
||||
tenant_model=tenant_model,
|
||||
@ -140,11 +142,12 @@ def get_secret(requesting_content_type, secret_model, tenant_model,
|
||||
secret_metadata['transport_key'] = transport_key
|
||||
|
||||
# Locate a suitable plugin to store the secret.
|
||||
retrieve_plugin = secret_store.SecretStorePluginManager()\
|
||||
.get_plugin_retrieve_delete(secret_metadata.get('plugin_name'))
|
||||
plugin_manager = secret_store.SecretStorePluginManager()
|
||||
retrieve_plugin = plugin_manager.get_plugin_retrieve_delete(
|
||||
secret_metadata.get('plugin_name'))
|
||||
|
||||
# Retrieve the secret.
|
||||
#TODO(john-wood-w) Remove the SecretStoreContext once repository factory
|
||||
# TODO(john-wood-w) Remove the SecretStoreContext once repository factory
|
||||
# and unit test patch work is completed.
|
||||
context = secret_store.SecretStoreContext(secret_model=secret_model,
|
||||
tenant_model=tenant_model)
|
||||
@ -165,8 +168,9 @@ def get_transport_key_id_for_retrieval(secret_model):
|
||||
secret_metadata = dict((k, v.value) for (k, v) in
|
||||
secret_model.secret_store_metadata.items())
|
||||
|
||||
retrieve_plugin = secret_store.SecretStorePluginManager()\
|
||||
.get_plugin_retrieve_delete(secret_metadata.get('plugin_name'))
|
||||
plugin_manager = secret_store.SecretStorePluginManager()
|
||||
retrieve_plugin = plugin_manager.get_plugin_retrieve_delete(
|
||||
secret_metadata.get('plugin_name'))
|
||||
|
||||
transport_key_id = retrieve_plugin.get_transport_key()
|
||||
return transport_key_id
|
||||
@ -180,24 +184,24 @@ def generate_secret(spec, content_type,
|
||||
key_spec = secret_store.KeySpec(alg=spec.get('algorithm'),
|
||||
bit_length=spec.get('bit_length'),
|
||||
mode=spec.get('mode'))
|
||||
generate_plugin = secret_store.SecretStorePluginManager()\
|
||||
.get_plugin_generate(key_spec)
|
||||
|
||||
plugin_manager = secret_store.SecretStorePluginManager()
|
||||
generate_plugin = plugin_manager.get_plugin_generate(key_spec)
|
||||
|
||||
# Create secret model to eventually save metadata to.
|
||||
secret_model = models.Secret(spec)
|
||||
|
||||
# Generate the secret.
|
||||
#TODO(john-wood-w) Remove the SecretStoreContext once repository factory
|
||||
# TODO(john-wood-w) Remove the SecretStoreContext once repository factory
|
||||
# and unit test patch work is completed.
|
||||
context = secret_store.SecretStoreContext(content_type=content_type,
|
||||
secret_model=secret_model,
|
||||
tenant_model=tenant_model,
|
||||
repos=repos)
|
||||
|
||||
#TODO(john-wood-w) Replace with single 'generate_key()' call once
|
||||
# TODO(john-wood-w) Replace with single 'generate_key()' call once
|
||||
# asymmetric and symmetric generation is combined.
|
||||
secret_metadata = generate_plugin.\
|
||||
generate_symmetric_key(key_spec, context)
|
||||
secret_metadata = generate_plugin.generate_symmetric_key(key_spec, context)
|
||||
|
||||
# Save secret and metadata.
|
||||
_save_secret(secret_model, tenant_model, repos)
|
||||
@ -209,36 +213,35 @@ def generate_secret(spec, content_type,
|
||||
|
||||
def generate_asymmetric_secret(spec, content_type,
|
||||
tenant_model, repos):
|
||||
"""Generate an asymmetric secret and store
|
||||
into a secure backend.
|
||||
"""
|
||||
"""Generate an asymmetric secret and store into a secure backend."""
|
||||
# Locate a suitable plugin to store the secret.
|
||||
key_spec = secret_store.KeySpec(alg=spec.get('algorithm'),
|
||||
bit_length=spec.get('bit_length'),
|
||||
passphrase=spec.get('passphrase'))
|
||||
|
||||
generate_plugin = secret_store.SecretStorePluginManager()\
|
||||
.get_plugin_generate(key_spec)
|
||||
plugin_manager = secret_store.SecretStorePluginManager()
|
||||
generate_plugin = plugin_manager.get_plugin_generate(key_spec)
|
||||
|
||||
# Create secret models to eventually save metadata to.
|
||||
private_secret_model = models.Secret(spec)
|
||||
public_secret_model = models.Secret(spec)
|
||||
passphrase_secret_model = models.Secret(spec)\
|
||||
if spec.get('passphrase') else None
|
||||
passphrase_secret_model = (models.Secret(spec)
|
||||
if spec.get('passphrase') else None)
|
||||
|
||||
# Generate the secret.
|
||||
# TODO(john-wood-w) Remove the SecretStoreContext once repository factory
|
||||
# and unit test patch work is completed.
|
||||
context = secret_store.\
|
||||
SecretStoreContext(content_type=content_type,
|
||||
private_secret_model=private_secret_model,
|
||||
public_secret_model=public_secret_model,
|
||||
passphrase_secret_model=passphrase_secret_model,
|
||||
tenant_model=tenant_model,
|
||||
repos=repos)
|
||||
context = secret_store.SecretStoreContext(
|
||||
content_type=content_type,
|
||||
private_secret_model=private_secret_model,
|
||||
public_secret_model=public_secret_model,
|
||||
passphrase_secret_model=passphrase_secret_model,
|
||||
tenant_model=tenant_model,
|
||||
repos=repos)
|
||||
|
||||
asymmetric_meta_dto = generate_plugin.\
|
||||
generate_asymmetric_key(key_spec, context)
|
||||
asymmetric_meta_dto = generate_plugin.generate_asymmetric_key(
|
||||
key_spec, context
|
||||
)
|
||||
|
||||
# Save secret and metadata.
|
||||
_save_secret(private_secret_model, tenant_model, repos)
|
||||
@ -278,8 +281,9 @@ def delete_secret(secret_model, project_id, repos):
|
||||
secret_model.secret_store_metadata.items())
|
||||
|
||||
# Locate a suitable plugin to delete the secret from.
|
||||
delete_plugin = secret_store.SecretStorePluginManager()\
|
||||
.get_plugin_retrieve_delete(secret_metadata.get('plugin_name'))
|
||||
plugin_manager = secret_store.SecretStorePluginManager()
|
||||
delete_plugin = plugin_manager.get_plugin_retrieve_delete(
|
||||
secret_metadata.get('plugin_name'))
|
||||
|
||||
# Delete the secret from plugin storage.
|
||||
delete_plugin.delete_secret(secret_metadata)
|
||||
@ -296,8 +300,7 @@ def _save_secret_metadata(secret_model, secret_metadata,
|
||||
if not secret_metadata:
|
||||
secret_metadata = dict()
|
||||
|
||||
secret_metadata['plugin_name'] = utils\
|
||||
.generate_fullname_for(store_plugin)
|
||||
secret_metadata['plugin_name'] = utils.generate_fullname_for(store_plugin)
|
||||
|
||||
secret_metadata['content_type'] = content_type
|
||||
|
||||
|
@ -89,8 +89,7 @@ class SimpleCertificatePlugin(cert.CertificatePluginBase):
|
||||
return cert.ResultDTO(cert.CertificateStatus.WAITING_FOR_CA)
|
||||
|
||||
def supports(self, certificate_spec):
|
||||
"""Returns a boolean indicating if the plugin supports the
|
||||
certificate type.
|
||||
"""Indicates whether the plugin supports the certificate type.
|
||||
|
||||
:param certificate_spec: Contains details on the certificate to
|
||||
generate the certificate order
|
||||
|
@ -65,7 +65,7 @@ class StoreCryptoAdapterPlugin(sstore.SecretStoreBase):
|
||||
encrypt_dto, kek_meta_dto, context.tenant_model.keystone_id
|
||||
)
|
||||
# Convert binary data into a text-based format.
|
||||
#TODO(jwood) Figure out by storing binary (BYTEA) data in Postgres
|
||||
# TODO(jwood) Figure out by storing binary (BYTEA) data in Postgres
|
||||
# isn't working.
|
||||
self._store_secret_and_datum(context,
|
||||
context.secret_model,
|
||||
@ -76,11 +76,11 @@ class StoreCryptoAdapterPlugin(sstore.SecretStoreBase):
|
||||
|
||||
def get_secret(self, secret_metadata, context):
|
||||
"""Retrieve a secret."""
|
||||
if not context.secret_model \
|
||||
or not context.secret_model.encrypted_data:
|
||||
if (not context.secret_model or
|
||||
not context.secret_model.encrypted_data):
|
||||
raise sstore.SecretNotFoundException()
|
||||
|
||||
#TODO(john-wood-w) Need to revisit 1 to many datum relationship.
|
||||
# TODO(john-wood-w) Need to revisit 1 to many datum relationship.
|
||||
datum_model = context.secret_model.encrypted_data[0]
|
||||
|
||||
# Find HSM-style 'crypto' plugin.
|
||||
@ -91,7 +91,7 @@ class StoreCryptoAdapterPlugin(sstore.SecretStoreBase):
|
||||
kek_meta_dto = crypto.KEKMetaDTO(datum_model.kek_meta_tenant)
|
||||
|
||||
# Convert from text-based storage format to binary.
|
||||
#TODO(jwood) Figure out by storing binary (BYTEA) data in
|
||||
# TODO(jwood) Figure out by storing binary (BYTEA) data in
|
||||
# Postgres isn't working.
|
||||
encrypted = base64.b64decode(datum_model.cypher_text)
|
||||
decrypt_dto = crypto.DecryptDTO(encrypted)
|
||||
@ -137,9 +137,8 @@ class StoreCryptoAdapterPlugin(sstore.SecretStoreBase):
|
||||
key_spec.bit_length,
|
||||
key_spec.mode, None)
|
||||
# Create the encrypted meta.
|
||||
response_dto = generating_plugin.\
|
||||
generate_symmetric(generate_dto, kek_meta_dto,
|
||||
context.tenant_model.keystone_id)
|
||||
response_dto = generating_plugin.generate_symmetric(
|
||||
generate_dto, kek_meta_dto, context.tenant_model.keystone_id)
|
||||
|
||||
# Convert binary data into a text-based format.
|
||||
# TODO(jwood) Figure out by storing binary (BYTEA) data in Postgres
|
||||
@ -164,11 +163,8 @@ class StoreCryptoAdapterPlugin(sstore.SecretStoreBase):
|
||||
if crypto.PluginSupportTypes.ASYMMETRIC_KEY_GENERATION != plugin_type:
|
||||
raise sstore.SecretAlgorithmNotSupportedException(key_spec.alg)
|
||||
|
||||
generating_plugin = manager.PLUGIN_MANAGER\
|
||||
.get_plugin_store_generate(plugin_type,
|
||||
key_spec.alg,
|
||||
key_spec.bit_length,
|
||||
None)
|
||||
generating_plugin = manager.PLUGIN_MANAGER.get_plugin_store_generate(
|
||||
plugin_type, key_spec.alg, key_spec.bit_length, None)
|
||||
|
||||
# Find or create a key encryption key metadata.
|
||||
kek_datum_model, kek_meta_dto = self._find_or_create_kek_objects(
|
||||
@ -179,9 +175,11 @@ class StoreCryptoAdapterPlugin(sstore.SecretStoreBase):
|
||||
None, key_spec.passphrase)
|
||||
|
||||
# Create the encrypted meta.
|
||||
private_key_dto, public_key_dto, passwd_dto = generating_plugin.\
|
||||
generate_asymmetric(generate_dto, kek_meta_dto,
|
||||
context.tenant_model.keystone_id)
|
||||
private_key_dto, public_key_dto, passwd_dto = (
|
||||
generating_plugin.generate_asymmetric(
|
||||
generate_dto, kek_meta_dto, context.tenant_model.keystone_id
|
||||
)
|
||||
)
|
||||
|
||||
self._store_secret_and_datum(context,
|
||||
context.private_secret_model,
|
||||
@ -281,10 +279,11 @@ class StoreCryptoAdapterPlugin(sstore.SecretStoreBase):
|
||||
kek_datum.mode = kek_meta_dto.mode
|
||||
kek_datum.plugin_meta = kek_meta_dto.plugin_meta
|
||||
|
||||
#TODO(john-wood-w) Move this to the more generic secret_store.py?
|
||||
# TODO(john-wood-w) Move this to the more generic secret_store.py?
|
||||
def _determine_generation_type(self, algorithm):
|
||||
"""Determines the type (symmetric and asymmetric for now)
|
||||
based on algorithm
|
||||
"""Determines the type based on the given algorithm.
|
||||
|
||||
For now this is either symmetric or asymmetric.
|
||||
"""
|
||||
symmetric_algs = crypto.PluginSupportTypes.SYMMETRIC_ALGORITHMS
|
||||
asymmetric_algs = crypto.PluginSupportTypes.ASYMMETRIC_ALGORITHMS
|
||||
|
@ -307,7 +307,7 @@ class BeginTypeOrder(BaseTask):
|
||||
|
||||
|
||||
class UpdateOrder(BaseTask):
|
||||
"""Handles updating an order"""
|
||||
"""Handles updating an order."""
|
||||
def get_name(self):
|
||||
return u._('Update Order')
|
||||
|
||||
|
@ -18,7 +18,6 @@ This test module focuses on typical-flow business logic tests with the API
|
||||
resource classes. For RBAC tests of these classes, see the
|
||||
'resources_policy_test.py' module.
|
||||
"""
|
||||
|
||||
import base64
|
||||
import logging
|
||||
import mimetypes
|
||||
@ -1996,6 +1995,7 @@ class WhenCreatingContainersUsingContainersResource(FunctionalTest):
|
||||
self.container_req
|
||||
)
|
||||
self.assertEqual(resp.status_int, 201)
|
||||
self.assertNotIn(self.tenant_keystone_id, resp.headers['Location'])
|
||||
|
||||
args, kwargs = self.container_repo.create_from.call_args
|
||||
container = args[0]
|
||||
@ -2179,6 +2179,7 @@ class WhenCreatingConsumersUsingConsumersResource(FunctionalTest):
|
||||
self.consumer_ref
|
||||
)
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertNotIn(self.tenant_keystone_id, resp.headers['Location'])
|
||||
|
||||
args, kwargs = self.consumer_repo.create_from.call_args
|
||||
consumer = args[0]
|
||||
|
Loading…
x
Reference in New Issue
Block a user