keystone.common package

Subpackages

Submodules

keystone.common.authorization module

keystone.common.authorization.AUTH_CONTEXT_ENV = 'KEYSTONE_AUTH_CONTEXT'

Environment variable used to convey the Keystone auth context.

Auth context is essentially the user credential used for policy enforcement. It is a dictionary with the following attributes:

  • user_id: user ID of the principal

  • project_id (optional): project ID of the scoped project if auth is

    project-scoped

  • domain_id (optional): domain ID of the scoped domain if auth is

    domain-scoped

  • roles (optional): list of role names for the given scope

  • group_ids: list of group IDs for which the API user has membership

keystone.common.authorization.flatten(d, parent_key='')[source]

Flatten a nested dictionary

Converts a dictionary with nested values to a single level flat dictionary, with dotted notation for each key.

keystone.common.authorization.is_v3_token(token)[source]
keystone.common.authorization.token_to_auth_context(token)[source]
keystone.common.authorization.v2_token_to_auth_context(token)[source]
keystone.common.authorization.v3_token_to_auth_context(token)[source]

keystone.common.base64utils module

Python provides the base64 module as a core module but this is mostly limited to encoding and decoding base64 and it’s variants. It is often useful to be able to perform other operations on base64 text. This module is meant to be used in conjunction with the core base64 module.

Standarized base64 is defined in RFC-4648 “The Base16, Base32, and Base64 Data Encodings”.

This module provides the following base64 utility functionality:

  • tests if text is valid base64

  • filter formatting from base64

  • convert base64 between different alphabets

  • Handle padding issues
    • test if base64 is padded
    • removes padding
    • restores padding
  • wraps base64 text into formatted blocks
    • via iterator
    • return formatted string
exception keystone.common.base64utils.InvalidBase64Error[source]

Bases: exceptions.ValueError

keystone.common.base64utils.base64_assure_padding(text, pad='=')[source]

Assure the input text ends with padding.

Base64 text is normally expected to be a multple of 4 characters. Each 4 character base64 sequence produces 3 octets of binary data. If the binary data is not a multiple of 3 the base64 text is padded at the end with a pad character such that is is always a multple of 4. Padding is ignored and does not alter the binary data nor it’s length.

In some circumstances is is desirable to omit the padding character due to transport encoding conflicts. Base64 text can still be correctly decoded if the length of the base64 text (consisting only of characters in the desired base64 alphabet) is known, padding is not absolutely necessary.

Some base64 decoders demand correct padding or one may wish to format RFC compliant base64, this function performs this action.

Input is assumed to consist only of members of a base64 alphabet (i.e no whitepace). Iteration yields a sequence of lines. The line does NOT terminate with a line ending.

Use the filter_formatting() function to assure the input text contains only the members of the alphabet.

If the text ends with the pad it is assumed to already be padded. Otherwise the binary length is computed from the input text length and correct number of pad characters are appended.

Parameters:
  • text (string) – text containing ONLY characters in a base64 alphabet
  • pad (string) – pad character (must be single character) (default: ‘=’)
Returns:

string – input base64 text with padding

Raises:

ValueError

keystone.common.base64utils.base64_is_padded(text, pad='=')[source]

Test if the text is base64 padded.

The input text must be in a base64 alphabet. The pad must be a single character. If the text has been percent-encoded (e.g. pad is the string ‘%3D’) you must convert the text back to a base64 alphabet (e.g. if percent-encoded use the function base64url_percent_decode()).

Parameters:
  • text (string) – text containing ONLY characters in a base64 alphabet
  • pad (string) – pad character (must be single character) (default: ‘=’)
Returns:

bool – True if padded, False otherwise

Raises:

ValueError, InvalidBase64Error

keystone.common.base64utils.base64_strip_padding(text, pad='=')[source]

Remove padding from input base64 text.

Parameters:
  • text (string) – text containing ONLY characters in a base64 alphabet
  • pad (string) – pad character (must be single character) (default: ‘=’)
Returns:

string – base64 text without padding

Raises:

ValueError

keystone.common.base64utils.base64_to_base64url(text)[source]

Convert base64 text to base64url text.

base64url text is designed to be safe for use in filenames and URL’s. It is defined in RFC-4648 Section 5.

base64url differs from base64 in the last two alphabet characters at index 62 and 63, these are sometimes referred as the altchars. The ‘+’ character at index 62 is replaced by ‘-‘ (hyphen) and the ‘/’ character at index 63 is replaced by ‘_’ (underscore).

This function only translates the altchars, non-alphabet characters are not filtered out.

WARNING:

base64url continues to use the '=' pad character which is NOT URL
safe. RFC-4648 suggests two alternate methods to deal with this:

percent-encode
    percent-encode the pad character (e.g. '=' becomes
    '%3D'). This makes the base64url text fully safe. But
    percent-enconding has the downside of requiring
    percent-decoding prior to feeding the base64url text into a
    base64url decoder since most base64url decoders do not
    recognize %3D as a pad character and most decoders require
    correct padding.

no-padding
    padding is not strictly necessary to decode base64 or
    base64url text, the pad can be computed from the input text
    length. However many decoders demand padding and will consider
    non-padded text to be malformed. If one wants to omit the
    trailing pad character(s) for use in URL's it can be added back
    using the base64_assure_padding() function.

This function makes no decisions about which padding methodolgy to
use. One can either call base64_strip_padding() to remove any pad
characters (restoring later with base64_assure_padding()) or call
base64url_percent_encode() to percent-encode the pad characters.
Parameters:text (string) – input base64 text
Returns:string – base64url text
keystone.common.base64utils.base64_wrap(text, width=64)[source]

Fold text into lines of text with max line length.

Input is assumed to consist only of members of a base64 alphabet (i.e no whitepace). Fold the text into lines whose line length is width chars long, terminate each line with line ending (default is ‘n’). Return the wrapped text as a single string.

Use the filter_formatting() function to assure the input text contains only the members of the alphabet.

Parameters:
  • text (string) – text containing ONLY characters in a base64 alphabet
  • width (int) – number of characters in each wrapped line (default: 64)
Returns:

string – wrapped text.

keystone.common.base64utils.base64_wrap_iter(text, width=64)[source]

Fold text into lines of text with max line length.

Input is assumed to consist only of members of a base64 alphabet (i.e no whitepace). Iteration yields a sequence of lines. The line does NOT terminate with a line ending.

Use the filter_formatting() function to assure the input text contains only the members of the alphabet.

Parameters:
  • text (string) – text containing ONLY characters in a base64 alphabet
  • width (int) – number of characters in each wrapped line (default: 64)
Returns:

generator – sequence of lines of base64 text.

keystone.common.base64utils.base64url_percent_decode(text)[source]

Percent-decode base64url padding.

The input text should only contain base64url alphabet characters and the percent-encoded pad character. Any other percent-encoded characters will be subject to percent-decoding.

Parameters:text (string) – base64url alphabet text
Returns:string – percent-decoded base64url text
keystone.common.base64utils.base64url_percent_encode(text)[source]

Percent-encode base64url padding.

The input text should only contain base64url alphabet characters. Any non-base64url alphabet characters will also be subject to percent-encoding.

Parameters:text (string) – text containing ONLY characters in the base64url alphabet
Returns:string – percent-encoded base64url text
Raises:InvalidBase64Error
keystone.common.base64utils.base64url_to_base64(text)[source]

Convert base64url text to base64 text.

See base64_to_base64url() for a description of base64url text and it’s issues.

This function does NOT handle percent-encoded pad characters, they will be left intact. If the input base64url text is percent-encoded you should call

Parameters:text (string) – text in base64url alphabet
Returns:string – text in base64 alphabet
keystone.common.base64utils.filter_formatting(text)[source]

Return base64 text without any formatting, just the base64.

Base64 text is often formatted with whitespace, line endings, etc. This function strips out any formatting, the result will contain only base64 characters.

Note, this function does not filter out all non-base64 alphabet characters, it only removes characters used for formatting.

Parameters:text (string) – input text to filter
Returns:string – filtered text without formatting
keystone.common.base64utils.is_valid_base64(text)[source]

Test if input text can be base64 decoded.

Parameters:text (string) – input base64 text
Returns:bool – True if text can be decoded as base64, False otherwise
keystone.common.base64utils.is_valid_base64url(text)[source]

Test if input text can be base64url decoded.

Parameters:text (string) – input base64 text
Returns:bool – True if text can be decoded as base64url, False otherwise

keystone.common.config module

keystone.common.config.configure(conf=None)[source]
keystone.common.config.list_opts()[source]

Return a list of oslo.config options available in Keystone.

The returned list includes all oslo.config options which are registered as the “FILE_OPTIONS” in keystone.common.config. This list will not include the options from the oslo-incubator library or any options registered dynamically at run time.

Each object in the list is a two element tuple. The first element of each tuple is the name of the group under which the list of options in the second element will be registered. A group name of None corresponds to the [DEFAULT] group in config files.

This function is also discoverable via the ‘oslo.config.opts’ entry point under the ‘keystone.config.opts’ namespace.

The purpose of this is to allow tools like the Oslo sample config file generator to discover the options exposed to users by this library.

Returns:a list of (group_name, opts) tuples
keystone.common.config.setup_authentication(conf=None)[source]

keystone.common.controller module

class keystone.common.controller.V2Controller(*args, **kwargs)[source]

Bases: keystone.common.wsgi.Application

Base controller class for Identity API v2.

static filter_domain_id(ref)[source]

Remove domain_id since v2 calls are not domain-aware.

static normalize_username_in_request(ref)[source]

Adds name in incoming user refs to match the v2 spec.

Internally we use name to represent a user’s name. The v2 spec requires the use of username instead.

static normalize_username_in_response(ref)[source]

Adds username to outgoing user refs to match the v2 spec.

Internally we use name to represent a user’s name. The v2 spec requires the use of username instead.

static v3_to_v2_user(ref)[source]

Convert a user_ref from v3 to v2 compatible.

  • v2.0 users are not domain aware, and should have domain_id removed
  • v2.0 users expect the use of tenantId instead of default_project_id
  • v2.0 users have a username attribute

This method should only be applied to user_refs being returned from the v2.0 controller(s).

If ref is a list type, we will iterate through each element and do the conversion.

class keystone.common.controller.V3Controller(*args, **kwargs)[source]

Bases: keystone.common.wsgi.Application

Base controller class for Identity API v3.

Child classes should set the collection_name and member_name class attributes, representing the collection of entities they are exposing to the API. This is required for supporting self-referential links, pagination, etc.

Class parameters:

  • _mutable_parameters - set of parameters that can be changed by users.

    Usually used by cls.check_immutable_params()

  • _public_parameters - set of parameters that are exposed to the user.

    Usually used by cls.filter_params()

classmethod base_url(context, path=None)[source]
classmethod build_driver_hints(context, supported_filters)[source]

Build list hints based on the context query string.

Parameters:
  • context – contains the query_string from which any list hints can be extracted
  • supported_filters – list of filters supported, so ignore any keys in query_dict that are not in this list.
classmethod check_immutable_params(ref)[source]

Raise exception when disallowed parameter is in ref.

Check whether the ref dictionary representing a request has only mutable parameters included. If not, raise an exception. This method checks only root-level keys from a ref dictionary.

Parameters:ref – a dictionary representing deserialized request to be stored
Raises:keystone.exception.ImmutableAttributeError
check_protection(context, prep_info, target_attr=None)[source]

Provide call protection for complex target attributes.

As well as including the standard parameters from the original API call (which is passed in prep_info), this call will add in any additional entities or attributes (passed in target_attr), so that they can be referenced by policy rules.

classmethod check_required_params(ref)[source]

Raise exception when required parameter is not in ref.

Check whether the ref dictionary representing a request has the required parameters to fulfill the request. If not, raise an exception. This method checks only root-level keys from a ref dictionary.

Parameters:ref – a dictionary representing deserialized request to be stored
Raises:keystone.exception.ValidationError
collection_name = 'entities'
classmethod filter_by_attributes(refs, hints)[source]

Filters a list of references by filter values.

static filter_domain_id(ref)[source]

Override v2 filter to let domain_id out for v3 calls.

classmethod filter_params(ref)[source]

Remove unspecified parameters from the dictionary.

This function removes unspecified parameters from the dictionary. See check_immutable_parameters for corresponding function that raises exceptions. This method checks only root-level keys from a ref dictionary.

Parameters:ref – a dictionary representing deserialized response to be serialized
get_member_from_driver = None
classmethod limit(refs, hints)[source]

Limits a list of entities.

The underlying driver layer may have already truncated the collection for us, but in case it was unable to handle truncation we check here.

Parameters:
  • refs – the list of members of the collection
  • hints – hints, containing, among other things, the limit requested
Returns:

boolean indicating whether the list was truncated, as well as the list of (truncated if necessary) entities.

member_name = 'entity'
classmethod wrap_collection(context, refs, hints=None)[source]

Wrap a collection, checking for filtering and pagination.

Returns the wrapped collection, which includes: - Executing any filtering not already carried out - Truncate to a set limit if necessary - Adds ‘self’ links in every member - Adds ‘next’, ‘self’ and ‘prev’ links for the whole collection.

Parameters:
  • context – the current context, containing the original url path and query string
  • refs – the list of members of the collection
  • hints – list hints, containing any relevant filters and limit. Any filters already satisfied by managers will have been removed
classmethod wrap_member(context, ref)[source]
keystone.common.controller.filterprotected(*filters)[source]

Wraps filtered API calls with role based access controls (RBAC).

keystone.common.controller.protected(callback=None)[source]

Wraps API calls with role based access controls (RBAC).

This handles both the protection of the API parameters as well as any target entities for single-entity API calls.

More complex API calls (for example that deal with several different entities) should pass in a callback function, that will be subsequently called to check protection for these multiple entities. This callback function should gather the appropriate entities needed and then call check_proetction() in the V3Controller class.

keystone.common.controller.v2_deprecated(f)[source]

No-op decorator in preparation for deprecating Identity API v2.

This is a placeholder for the pending deprecation of v2. The implementation of this decorator can be replaced with:

from keystone.openstack.common import versionutils


v2_deprecated = versionutils.deprecated(
    what='v2 API',
    as_of=versionutils.deprecated.JUNO,
    in_favor_of='v3 API')

keystone.common.dependency module

This module provides support for dependency injection.

Providers are registered via the ‘provider’ decorator, and dependencies on them are registered with ‘requires’ or ‘optional’. Providers are available to their consumers via an attribute. See the documentation for the individual functions for more detail.

See also:

exception keystone.common.dependency.UnresolvableDependencyException(name)[source]

Bases: exceptions.Exception

An UnresolvableDependencyException is raised when a required dependency is not resolvable; see ‘resolve_future_dependencies’.

keystone.common.dependency.optional(*dependencies)[source]

‘optional’ is the same as ‘requires’, except that the dependencies are optional - if no provider is available, the attributes will be set to None.

keystone.common.dependency.provider(name)[source]

‘provider’ is a class decorator used to register providers.

When ‘provider’ is used to decorate a class, members of that class will register themselves as providers for the named dependency. As an example, In the code fragment:

@dependency.provider('foo_api')
class Foo:
    def __init__(self):
        ...

    ...

foo = Foo()

The object ‘foo’ will be registered as a provider for ‘foo_api’. No more than one such instance should be created; additional instances will replace the previous ones, possibly resulting in different instances being used by different consumers.

keystone.common.dependency.requires(*dependencies)[source]

‘requires’ is a class decorator used to inject providers into consumers.

The required providers will be made available to instances of the decorated class via an attribute with the same name as the provider. For example, in the code fragment:

@dependency.requires('foo_api', 'bar_api')
class FooBarClient:
    def __init__(self):
        ...

    ...

client = FooBarClient()

The object ‘client’ will have attributes named ‘foo_api’ and ‘bar_api’, which are instances of the named providers.

Objects must not rely on the existence of these attributes until after ‘resolve_future_dependencies’ has been called; they may not exist beforehand.

Dependencies registered via ‘required’ must have providers - if not, an exception will be raised when ‘resolve_future_dependencies’ is called.

keystone.common.dependency.reset()[source]

Reset the registry of providers.

This is useful for unit testing to ensure that tests don’t use providers from previous tests.

keystone.common.dependency.resolve_future_dependencies(provider_name=None)[source]

‘resolve_future_dependencies’ forces injection of all dependencies.

Before this function is called, circular dependencies may not have been injected. This function should be called only once, after all global providers are registered. If an object needs to be created after this call, it must not have circular dependencies.

If any required dependencies are unresolvable, this function will raise an UnresolvableDependencyException.

Outside of this module, this function should be called with no arguments; the optional argument is used internally, and should be treated as an implementation detail.

keystone.common.driver_hints module

class keystone.common.driver_hints.Hints[source]

Bases: list

Encapsulate driver hints for listing entities.

Hints are modifiers that affect the return of entities from a list_<entities> operation. They are typically passed to a driver to give direction as to what filtering, pagination or list limiting actions are being requested.

It is optional for a driver to action some or all of the list hints, but any filters that it does satisfy must be marked as such by calling removing the filter from the list.

A Hint object is a list of dicts, initially of type ‘filter’ or ‘limit’, although other types may be added in the future. The list can be enumerated directly, or by using the filters() method which will guarantee to only return filters.

add_filter(name, value, comparator='equals', case_sensitive=False)[source]
filters()[source]

Iterate over all unsatisfied filters.

Each filter term consists of:

  • name: the name of the attribute being matched

  • value: the value against which it is being matched

  • comparator: the operation, which can be one of equals,

    startswith or endswith

  • case_sensitive: whether any comparison should take account of

    case

  • type: will always be ‘filter’

get_exact_filter_by_name(name)[source]

Return a filter key and value if exact filter exists for name.

get_limit()[source]

Get the limit to which the list should be truncated.

set_limit(limit, truncated=False)[source]

Set a limit to indicate the list should be truncated.

keystone.common.extension module

keystone.common.extension.register_admin_extension(url_prefix, extension_data)[source]

Register extension with collection of admin extensions.

Extensions register the information here that will show up in the /extensions page as a way to indicate that the extension is active.

url_prefix: unique key for the extension that will appear in the
urls generated by the extension.
extension_data is a dictionary. The expected fields are:
‘name’: short, human readable name of the extension ‘namespace’: xml namespace ‘alias’: identifier for the extension ‘updated’: date the extension was last updated ‘description’: text description of the extension ‘links’: hyperlinks to documents describing the extension
keystone.common.extension.register_public_extension(url_prefix, extension_data)[source]

Same as register_admin_extension but for public extensions.

keystone.common.manager module

class keystone.common.manager.Manager(driver_name)[source]

Bases: object

Base class for intermediary request layer.

The Manager layer exists to support additional logic that applies to all or some of the methods exposed by a service that are not specific to the HTTP interface.

It also provides a stable entry point to dynamic backends.

An example of a probable use case is logging all the calls.

keystone.common.manager.response_truncated(f)[source]

Truncate the list returned by the wrapped function.

This is designed to wrap Manager list_{entity} methods to ensure that any list limits that are defined are passed to the driver layer. If a hints list is provided, the wrapper will insert the relevant limit into the hints so that the underlying driver call can try and honor it. If the driver does truncate the response, it will update the ‘truncated’ attribute in the ‘limit’ entry in the hints list, which enables the caller of this function to know if truncation has taken place. If, however, the driver layer is unable to perform truncation, the ‘limit’ entry is simply left in the hints list for the caller to handle.

A _get_list_limit() method is required to be present in the object class hierarchy, which returns the limit for this backend to which we will truncate.

If a hints list is not provided in the arguments of the wrapped call then any limits set in the config file are ignored. This allows internal use of such wrapped methods where the entire data set is needed as input for the calculations of some other API (e.g. get role assignments for a given project).

keystone.common.models module

Base model for keystone internal services

Unless marked otherwise, all fields are strings.

class keystone.common.models.Domain[source]

Bases: keystone.common.models.Model

Domain object.

Required keys:
id name

Optional keys:

description enabled (bool, default True)
optional_keys = ('description', 'enabled')
required_keys = ('id', 'name')
class keystone.common.models.Endpoint[source]

Bases: keystone.common.models.Model

Endpoint object

Required keys:
id region service_id
Optional keys:
internalurl publicurl adminurl
optional_keys = ('internalurl', 'publicurl', 'adminurl')
required_keys = ('id', 'region', 'service_id')
class keystone.common.models.Group[source]

Bases: keystone.common.models.Model

Group object.

Required keys:
id name domain_id

Optional keys:

description
optional_keys = ('description',)
required_keys = ('id', 'name', 'domain_id')
class keystone.common.models.Model[source]

Bases: dict

Base model class.

known_keys[source]
class keystone.common.models.Project[source]

Bases: keystone.common.models.Model

Project object.

Required keys:
id name domain_id
Optional Keys:
description enabled (bool, default True)
optional_keys = ('description', 'enabled')
required_keys = ('id', 'name', 'domain_id')
class keystone.common.models.Role[source]

Bases: keystone.common.models.Model

Role object.

Required keys:
id name
optional_keys = ()
required_keys = ('id', 'name')
class keystone.common.models.Service[source]

Bases: keystone.common.models.Model

Service object.

Required keys:
id type name

Optional keys:

optional_keys = ()
required_keys = ('id', 'type', 'name')
class keystone.common.models.Token[source]

Bases: keystone.common.models.Model

Token object.

Required keys:
id expires (datetime)
Optional keys:
user tenant metadata trust_id
optional_keys = ('extra',)
required_keys = ('id', 'expires')
class keystone.common.models.Trust[source]

Bases: keystone.common.models.Model

Trust object.

Required keys:
id trustor_user_id trustee_user_id project_id
optional_keys = ('expires_at',)
required_keys = ('id', 'trustor_user_id', 'trustee_user_id', 'project_id')
class keystone.common.models.User[source]

Bases: keystone.common.models.Model

User object.

Required keys:
id name domain_id
Optional keys:
password description email enabled (bool, default True) default_project_id
optional_keys = ('password', 'description', 'email', 'enabled', 'default_project_id')
required_keys = ('id', 'name', 'domain_id')

keystone.common.openssl module

class keystone.common.openssl.BaseCertificateConfigure(conf_obj, keystone_user, keystone_group, **kwargs)[source]

Bases: object

Create a certificate signing environment.

This is based on a config section and reasonable OpenSSL defaults.

build_ca_cert()[source]
build_private_key()[source]
build_signing_cert()[source]
build_ssl_config_file()[source]
exec_command(command)[source]
run()[source]
sslconfig = '\n# OpenSSL configuration file.\n#\n\n# Establish working directory.\n\ndir = %(conf_dir)s\n\n[ ca ]\ndefault_ca = CA_default\n\n[ CA_default ]\nnew_certs_dir = $dir\nserial = $dir/serial\ndatabase = $dir/index.txt\ndefault_days = 365\ndefault_md = %(default_md)s\npreserve = no\nemail_in_dn = no\nnameopt = default_ca\ncertopt = default_ca\npolicy = policy_anything\nx509_extensions = usr_cert\nunique_subject = no\n\n[ policy_anything ]\ncountryName = optional\nstateOrProvinceName = optional\norganizationName = optional\norganizationalUnitName = optional\ncommonName = supplied\nemailAddress = optional\n\n[ req ]\ndefault_bits = 2048 # Size of keys\ndefault_keyfile = key.pem # name of generated keys\nstring_mask = utf8only # permitted characters\ndistinguished_name = req_distinguished_name\nreq_extensions = v3_req\nx509_extensions = v3_ca\n\n[ req_distinguished_name ]\ncountryName = Country Name (2 letter code)\ncountryName_min = 2\ncountryName_max = 2\nstateOrProvinceName = State or Province Name (full name)\nlocalityName = Locality Name (city, district)\n0.organizationName = Organization Name (company)\norganizationalUnitName = Organizational Unit Name (department, division)\ncommonName = Common Name (hostname, IP, or your name)\ncommonName_max = 64\nemailAddress = Email Address\nemailAddress_max = 64\n\n[ v3_ca ]\nbasicConstraints = CA:TRUE\nsubjectKeyIdentifier = hash\nauthorityKeyIdentifier = keyid:always,issuer\n\n[ v3_req ]\nbasicConstraints = CA:FALSE\nkeyUsage = nonRepudiation, digitalSignature, keyEncipherment\n\n[ usr_cert ]\nbasicConstraints = CA:FALSE\nsubjectKeyIdentifier = hash\nauthorityKeyIdentifier = keyid:always\n'
class keystone.common.openssl.ConfigurePKI(keystone_user, keystone_group)[source]

Bases: keystone.common.openssl.BaseCertificateConfigure

Generate files for PKI signing using OpenSSL.

Signed tokens require a private key and signing certificate which itself must be signed by a CA. This class generates them with workable defaults if each of the files are not present

class keystone.common.openssl.ConfigureSSL(keystone_user, keystone_group)[source]

Bases: keystone.common.openssl.BaseCertificateConfigure

Generate files for HTTPS using OpenSSL.

Creates a public/private key and certificates. If a CA is not given one will be generated using provided arguments.

keystone.common.openssl.file_exists(file_path)[source]

keystone.common.pemutils module

PEM formatted data is used frequently in conjunction with X509 PKI as a data exchange mechanism for binary data. The acronym PEM stands for Privacy Enhanced Mail as defined in RFC-1421. Contrary to expectation the PEM format in common use has little to do with RFC-1421. Instead what we know as PEM format grew out of the need for a data exchange mechanism largely by the influence of OpenSSL. Other X509 implementations have adopted it.

Unfortunately PEM format has never been officially standarized. It’s basic format is as follows:

1) A header consisting of 5 hyphens followed by the word BEGIN and a single space. Then an upper case string describing the contents of the PEM block, this is followed by 5 hyphens and a newline.

2) Binary data (typically in DER ASN.1 format) encoded in base64. The base64 text is line wrapped so that each line of base64 is 64 characters long and terminated with a newline. The last line of base64 text may be less than 64 characters. The content and format of the binary data is entirely dependent upon the type of data announced in the header and footer.

3) A footer in the exact same as the header except the word BEGIN is replaced by END. The content name in both the header and footer should exactly match.

The above is called a PEM block. It is permissible for multiple PEM blocks to appear in a single file or block of text. This is often used when specifying multiple X509 certificates.

An example PEM block for a certificate is:

—–BEGIN CERTIFICATE—– MIIC0TCCAjqgAwIBAgIJANsHKV73HYOwMA0GCSqGSIb3DQEBBQUAMIGeMQowCAYD VQQFEwE1MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVN1bm55 dmFsZTESMBAGA1UEChMJT3BlblN0YWNrMREwDwYDVQQLEwhLZXlzdG9uZTElMCMG CSqGSIb3DQEJARYWa2V5c3RvbmVAb3BlbnN0YWNrLm9yZzEUMBIGA1UEAxMLU2Vs ZiBTaWduZWQwIBcNMTIxMTA1MTgxODI0WhgPMjA3MTA0MzAxODE4MjRaMIGeMQow CAYDVQQFEwE1MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVN1 bm55dmFsZTESMBAGA1UEChMJT3BlblN0YWNrMREwDwYDVQQLEwhLZXlzdG9uZTEl MCMGCSqGSIb3DQEJARYWa2V5c3RvbmVAb3BlbnN0YWNrLm9yZzEUMBIGA1UEAxML U2VsZiBTaWduZWQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALzI17ExCaqd r7xY2Q5CBZ1bW1lsrXxS8eNJRdQtskDuQVAluY03/OGZd8HQYiiY/ci2tYy7BNIC bh5GaO95eqTDykJR3liOYE/tHbY6puQlj2ZivmhlSd2d5d7lF0/H28RQsLu9VktM uw6q9DpDm35jfrr8LgSeA3MdVqcS/4OhAgMBAAGjEzARMA8GA1UdEwEB/wQFMAMB Af8wDQYJKoZIhvcNAQEFBQADgYEAjSQND7i1dNZtLKpWgX+JqMr3BdVlM15mFeVr C26ZspZjZVY5okdozO9gU3xcwRe4Cg30sKFOe6EBQKpkTZucFOXwBtD3h6dWJrdD c+m/CL/rs0GatDavbaIT2vv405SQUQooCdVh72LYel+4/a6xmRd7fQx3iEXN9QYj vmHJUcA= —–END CERTIFICATE—–

PEM format is safe for transmission in 7-bit ASCII systems (i.e. standard email). Since 7-bit ASCII is a proper subset of UTF-8 and Latin-1 it is not affected by transcoding between those charsets. Nor is PEM format affected by the choice of line endings. This makes PEM format particularity attractive for transport and storage of binary data.

This module provides a number of utilities supporting the generation and consumption of PEM formatted data including:

  • parse text and find all PEM blocks contained in the text. Information on the location of the block in the text, the type of PEM block, and it’s base64 and binary data contents.
  • parse text assumed to contain PEM data and return the binary data.
  • test if a block of text is a PEM block
  • convert base64 text into a formatted PEM block
  • convert binary data into a formatted PEM block
  • access to the valid PEM types and their headers
class keystone.common.pemutils.PEMParseResult(pem_type=None, pem_header=None, pem_start=None, pem_end=None, base64_start=None, base64_end=None, binary_data=None)[source]

Bases: object

Information returned when a PEM block is found in text.

PEMParseResult contains information about a PEM block discovered while parsing text. The following properties are defined:

pem_type
A short hand name for the type of the PEM data, e.g. cert, csr, crl, cms, key. Valid pem_types are listed in pem_types. When the pem_type is set the pem_header is updated to match it.
pem_header

The text following ‘—–BEGIN ‘ in the PEM header. Common examples are:

—–BEGIN CERTIFICATE—– —–BEGIN CMS—–

Thus the pem_header would be CERTIFICATE and CMS respectively. When the pem_header is set the pem_type is updated to match it.

pem_start, pem_end
The beginning and ending positions of the PEM block including the PEM header and footer.
base64_start, base64_end
The beginning and ending positions of the base64 data contained inside the PEM header and footer. Includes trailing new line
binary_data
The decoded base64 data. None if not decoded.
pem_header[source]
pem_type[source]
keystone.common.pemutils.base64_to_pem(base64_text, pem_type='cert')[source]

Format string of base64 text into PEM format

Input is assumed to consist only of members of the base64 alphabet (i.e no whitepace). Use one of the filter functions from base64utils to assure the input is clean (i.e. strip_whitespace()).

Parameters:
  • base64_text (string) – text containing ONLY base64 alphabet characters to be inserted into PEM output.
  • pem_type (string) – Produce a PEM block for this type. Valid types are: csr, cert, crl, cms, key. (default: ‘cert’)
Returns:

string – PEM formatted text

keystone.common.pemutils.binary_to_pem(binary_data, pem_type='cert')[source]

Format binary data into PEM format

Example:

# get the certificate binary data in DER format der_data = certificate.der # convert the DER binary data into a PEM pem = binary_to_pem(der_data, ‘cert’)
Parameters:
  • binary_data (buffer) – binary data to encapsulate into PEM
  • pem_type (string) – Produce a PEM block for this type. Valid types are: csr, cert, crl, cms, key. (default: ‘cert’)
Returns:

string – PEM formatted text

keystone.common.pemutils.get_pem_data(text, pem_type='cert')[source]

Scan text for PEM data, return binary contents

The input text is scanned for a PEM block which matches the pem_type. If found the binary data contained in the PEM block is returned. If no PEM block is found or it does not match the specified pem type None is returned.

Parameters:
  • text (string) – The text to search for the PEM block
  • pem_type (string) – Only return data for this pem_type. Valid types are: csr, cert, crl, cms, key. (default: ‘cert’)
Returns:

binary data or None if not found.

keystone.common.pemutils.is_pem(text, pem_type='cert')[source]

Does this text contain a PEM block.

Check for the existence of a PEM formatted block in the text, if one is found verify it’s contents can be base64 decoded, if so return True. Return False otherwise.

Parameters:
  • text (string) – The text to search for PEM blocks
  • pem_type (string) – Only return data for this pem_type. Valid types are: csr, cert, crl, cms, key. (default: ‘cert’)
Returns:

bool – True if text contains PEM matching the pem_type, False otherwise.

keystone.common.pemutils.parse_pem(text, pem_type=None, max_items=None)[source]

Scan text for PEM data, return list of PEM items

The input text is scanned for PEM blocks, for each one found a PEMParseResult is contructed and added to the return list.

pem_type operates as a filter on the type of PEM desired. If pem_type is specified only those PEM blocks which match will be included. The pem_type is a logical name, not the actual text in the pem header (e.g. ‘cert’). If the pem_type is None all PEM blocks are returned.

If max_items is specified the result is limited to that number of items.

The return value is a list of PEMParseResult objects. The PEMParseResult provides complete information about the PEM block including the decoded binary data for the PEM block. The list is ordered in the same order as found in the text.

Examples:

# Get all certs
certs = parse_pem(text, 'cert')

# Get the first cert
try:
    binary_cert = parse_pem(text, 'cert', 1)[0].binary_data
except IndexError:
    raise ValueError('no cert found')
Parameters:
  • text (string) – The text to search for PEM blocks
  • pem_type (string or None) – Only return data for this pem_type. Valid types are: csr, cert, crl, cms, key. If pem_type is None no filtering is performed. (default: None)
  • max_items (int or None) – Limit the number of blocks returned. (default: None)
Returns:

List of PEMParseResult, one for each PEM block found

Raises:

ValueError, InvalidBase64Error

Search for a block of PEM formatted data

Search for a PEM block in a text string. The search begins at start. If a PEM block is found a PEMParseResult object is returned, otherwise if no PEM block is found None is returned.

If the pem_type is not the same in both the header and footer a ValueError is raised.

The start and end positions are suitable for use as slices into the text. To search for multiple PEM blocks pass pem_end as the start position for the next iteration. Terminate the iteration when None is returned. Example:

start = 0
while True:
    block = pem_search(text, start)
    if block is None:
        break
    base64_data = text[block.base64_start : block.base64_end]
    start = block.pem_end
Parameters:
  • text (string) – the text to search for PEM blocks
  • start (int) – the position in text to start searching from (default: 0)
Returns:

PEMParseResult or None if not found

Raises:

ValueError

keystone.common.router module

class keystone.common.router.Router(controller, collection_key, key)[source]

Bases: keystone.common.wsgi.ComposableRouter

add_routes(mapper)[source]

keystone.common.serializer module

Dict <–> XML de/serializer.

The identity API prefers attributes over elements, so we serialize that way by convention, with a few hardcoded exceptions.

class keystone.common.serializer.XmlDeserializer[source]

Bases: object

walk_element(element, namespace=False)[source]

Populates a dictionary by walking an etree element.

class keystone.common.serializer.XmlSerializer[source]

Bases: object

populate_element(element, value)[source]

Populates an etree with the given value.

keystone.common.serializer.from_xml(xml)[source]

Deserialize XML to a dictionary.

keystone.common.serializer.to_xml(d, xmlns=None)[source]

Serialize a dictionary to XML.

keystone.common.systemd module

Helper module for systemd start-up completion notification. Used for “onready” configuration parameter in keystone.conf

keystone.common.systemd.notify()[source]

keystone.common.utils module

class keystone.common.utils.LimitingReader(data, limit)[source]

Bases: object

Reader to limit the size of an incoming request.

read(i=None)[source]
class keystone.common.utils.SmarterEncoder(skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, encoding='utf-8', default=None)[source]

Bases: json.encoder.JSONEncoder

Help for JSON encoding dict-like objects.

default(obj)[source]
class keystone.common.utils.WhiteListedFormatter(whitelist, data)[source]

Bases: object

keystone.common.utils.attr_as_boolean(val_attr)[source]

Returns the boolean value, decoded from a string.

We test explicitly for a value meaning False, which can be one of several formats as specified in oslo strutils.FALSE_STRINGS. All other string values (including an empty string) are treated as meaning True.

keystone.common.utils.auth_str_equal(provided, known)[source]

Constant-time string comparison.

Params provided:
 the first string
Params known:the second string
Returns:True if the strings are equal.

This function takes two strings and compares them. It is intended to be used when doing a comparison for authentication purposes to help guard against timing attacks. When using the function for this purpose, always provide the user-provided password as the first argument. The time this function will take is always a factor of the length of this string.

keystone.common.utils.check_password(password, hashed)[source]

Check that a plaintext password matches hashed.

hashpw returns the salt value concatenated with the actual hash value. It extracts the actual salt if this value is then passed as the salt.

keystone.common.utils.convert_ec2_to_v3_credential(ec2credential)[source]
keystone.common.utils.convert_v3_to_ec2_credential(credential)[source]
keystone.common.utils.get_blob_from_credential(credential)[source]
keystone.common.utils.get_unix_group(group=None)[source]

Get the gid and group name.

This is a convenience utility which accepts a variety of input which might represent a unix group. If successful it returns the gid and name. Valid input is:

string
A string is first considered to be a group name and a lookup is attempted under that name. If no name is found then an attempt is made to convert the string to an integer and perform a lookup as a gid.
int
An integer is interpretted as a gid.
None
None is interpreted to mean use the current process’s effective group.

If the input is a valid type but no group is found a KeyError is raised. If the input is not a valid type a TypeError is raised.

Parameters:group (object) – string, int or None specifying the group to lookup.
Returns:tuple of (gid, name)
keystone.common.utils.get_unix_user(user=None)[source]

Get the uid and user name.

This is a convenience utility which accepts a variety of input which might represent a unix user. If successful it returns the uid and name. Valid input is:

string
A string is first considered to be a user name and a lookup is attempted under that name. If no name is found then an attempt is made to convert the string to an integer and perform a lookup as a uid.
int
An integer is interpretted as a uid.
None
None is interpreted to mean use the current process’s effective user.

If the input is a valid type but no user is found a KeyError is raised. If the input is not a valid type a TypeError is raised.

Parameters:user (object) – string, int or None specifying the user to lookup.
Returns:tuple of (uid, name)
keystone.common.utils.hash_access_key(access)[source]
keystone.common.utils.hash_ldap_user_password(user)[source]

Hash a user dict’s password without modifying the passed-in dict.

keystone.common.utils.hash_password(password)[source]

Hash a password. Hard.

keystone.common.utils.hash_user_password(user)[source]

Hash a user dict’s password without modifying the passed-in dict.

keystone.common.utils.ldap_check_password(password, hashed)[source]
keystone.common.utils.ldap_hash_password(password)[source]

Hash a password. Hard.

keystone.common.utils.make_dirs(path, mode=None, user=None, group=None, log=None)[source]

Assure directory exists, set ownership and permissions.

Assure the directory exists and optionally set it’s ownership and permissions.

Each of the mode, user and group are optional, if None then that aspect is not modified.

Owner and group may be specified either with a symbolic name or numeric id.

Parameters:
  • path (string) – Pathname of directory whose existence is assured.
  • mode (object) – ownership permissions flags (int) i.e. chmod, if None do not set.
  • user (object) – set user, name (string) or uid (integer), if None do not set.
  • group (object) – set group, name (string) or gid (integer) if None do not set.
  • log (logger) – logging.logger object, used to emit log messages, if None no logging is performed.
keystone.common.utils.read_cached_file(filename, cache_info, reload_func=None)[source]

Read from a file if it has been modified.

Parameters:
  • cache_info – dictionary to hold opaque cache.
  • reload_func – optional function to be called with data when file is reloaded due to a modification.
Returns:

data from file.

keystone.common.utils.set_permissions(path, mode=None, user=None, group=None, log=None)[source]

Set the ownership and permissions on the pathname.

Each of the mode, user and group are optional, if None then that aspect is not modified.

Owner and group may be specified either with a symbolic name or numeric id.

Parameters:
  • path (string) – Pathname of directory whose existence is assured.
  • mode (object) – ownership permissions flags (int) i.e. chmod, if None do not set.
  • user (object) – set user, name (string) or uid (integer), if None do not set.
  • group (object) – set group, name (string) or gid (integer) if None do not set.
  • log (logger) – logging.logger object, used to emit log messages, if None no logging is performed.
keystone.common.utils.setup_remote_pydev_debug()[source]
keystone.common.utils.trunc_password(password)[source]

Truncate passwords to the max_length.

keystone.common.utils.unixtime(dt_obj)[source]

Format datetime object as unix timestamp

Parameters:dt_obj – datetime.datetime object
Returns:float

keystone.common.wsgi module

Utility methods for working with WSGI servers.

class keystone.common.wsgi.Application(*args, **kwargs)[source]

Bases: keystone.common.wsgi.BaseApplication

assert_admin(context)[source]
classmethod base_url(context, endpoint_type)[source]
class keystone.common.wsgi.BaseApplication[source]

Bases: object

Base WSGI application wrapper. Subclasses need to implement __call__.

classmethod factory(global_config, **local_config)[source]

Used for paste app factories in paste.deploy config files.

Any local configuration (that is, values under the [app:APPNAME] section of the paste config) will be passed into the __init__ method as kwargs.

A hypothetical configuration would look like:

[app:wadl] latest_version = 1.3 paste.app_factory = keystone.fancy_api:Wadl.factory

which would result in a call to the Wadl class as

import keystone.fancy_api keystone.fancy_api.Wadl(latest_version=‘1.3’)

You could of course re-implement the factory method in subclasses, but using the kwarg passing it shouldn’t be necessary.

class keystone.common.wsgi.ComposableRouter(mapper=None)[source]

Bases: keystone.common.wsgi.Router

Router that supports use by ComposingRouter.

add_routes(mapper)[source]

Add routes to given mapper.

class keystone.common.wsgi.ComposingRouter(mapper=None, routers=None)[source]

Bases: keystone.common.wsgi.Router

class keystone.common.wsgi.Debug(application)[source]

Bases: keystone.common.wsgi.Middleware

Helper class for debugging a WSGI application.

Can be inserted into any WSGI application chain to get information about the request and response.

static print_generator(app_iter)[source]

Iterator that prints the contents of a wrapper string.

class keystone.common.wsgi.ExtensionRouter(application, mapper=None)[source]

Bases: keystone.common.wsgi.Router

A router that allows extensions to supplement or overwrite routes.

Expects to be subclassed.

add_routes(mapper)[source]
classmethod factory(global_config, **local_config)[source]

Used for paste app factories in paste.deploy config files.

Any local configuration (that is, values under the [filter:APPNAME] section of the paste config) will be passed into the __init__ method as kwargs.

A hypothetical configuration would look like:

[filter:analytics] redis_host = 127.0.0.1 paste.filter_factory = keystone.analytics:Analytics.factory

which would result in a call to the Analytics class as

import keystone.analytics keystone.analytics.Analytics(app, redis_host=‘127.0.0.1’)

You could of course re-implement the factory method in subclasses, but using the kwarg passing it shouldn’t be necessary.

class keystone.common.wsgi.Middleware(application)[source]

Bases: keystone.common.wsgi.Application

Base WSGI middleware.

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.

classmethod factory(global_config, **local_config)[source]

Used for paste app factories in paste.deploy config files.

Any local configuration (that is, values under the [filter:APPNAME] section of the paste config) will be passed into the __init__ method as kwargs.

A hypothetical configuration would look like:

[filter:analytics] redis_host = 127.0.0.1 paste.filter_factory = keystone.analytics:Analytics.factory

which would result in a call to the Analytics class as

import keystone.analytics keystone.analytics.Analytics(app, redis_host=‘127.0.0.1’)

You could of course re-implement the factory method in subclasses, but using the kwarg passing it shouldn’t be necessary.

process_request(request)[source]

Called on each request.

If this returns None, the next application down the stack will be executed. If it returns a response then that response will be returned and execution will stop here.

process_response(request, response)[source]

Do whatever you’d like to the response, based on the request.

class keystone.common.wsgi.Router(mapper)[source]

Bases: object

WSGI middleware that maps incoming requests to WSGI apps.

keystone.common.wsgi.best_match_language(req)[source]

Determines the best available locale from the Accept-Language HTTP header passed in the request.

keystone.common.wsgi.render_exception(error, context=None, request=None, user_locale=None)[source]

Forms a WSGI response based on the current error.

keystone.common.wsgi.render_response(body=None, status=None, headers=None, method=None)[source]

Forms a WSGI response.

keystone.common.wsgi.validate_token_bind(context, token_ref)[source]

Module contents