class CertificateNestedOutputSchema(LemurOutputSchema): __envelope__ = False id = fields.Integer() name = fields.String() owner = fields.Email() creator = fields.Nested(UserNestedOutputSchema) description = fields.String() status = fields.String() bits = fields.Integer() body = fields.String() chain = fields.String() active = fields.Boolean() rotation = fields.Boolean() notify = fields.Boolean() rotation_policy = fields.Nested(RotationPolicyNestedOutputSchema) # Note aliasing is the first step in deprecating these fields. cn = fields.String() # deprecated common_name = fields.String(attribute='cn') not_after = fields.DateTime() # deprecated validity_end = ArrowDateTime(attribute='not_after') not_before = fields.DateTime() # deprecated validity_start = ArrowDateTime(attribute='not_before') issuer = fields.Nested(AuthorityNestedOutputSchema)
class CertificateOutputSchema(LemurOutputSchema): id = fields.Integer() external_id = fields.String() bits = fields.Integer() body = fields.String() chain = fields.String() csr = fields.String() deleted = fields.Boolean(default=False) description = fields.String() issuer = fields.String() name = fields.String() dns_provider_id = fields.Integer(required=False, allow_none=True) date_created = ArrowDateTime() resolved = fields.Boolean(required=False, allow_none=True) resolved_cert_id = fields.Integer(required=False, allow_none=True) rotation = fields.Boolean() # Note aliasing is the first step in deprecating these fields. notify = fields.Boolean() active = fields.Boolean(attribute="notify") has_private_key = fields.Boolean() cn = fields.String() common_name = fields.String(attribute="cn") distinguished_name = fields.String() not_after = fields.DateTime() validity_end = ArrowDateTime(attribute="not_after") not_before = fields.DateTime() validity_start = ArrowDateTime(attribute="not_before") owner = fields.Email() san = fields.Boolean() serial = fields.String() serial_hex = Hex(attribute="serial") signing_algorithm = fields.String() key_type = fields.String(allow_none=True) status = fields.String() user = fields.Nested(UserNestedOutputSchema) extensions = fields.Nested(ExtensionSchema) # associated objects domains = fields.Nested(DomainNestedOutputSchema, many=True) destinations = fields.Nested(DestinationNestedOutputSchema, many=True) notifications = fields.Nested(NotificationNestedOutputSchema, many=True) replaces = fields.Nested(CertificateNestedOutputSchema, many=True) authority = fields.Nested(AuthorityNestedOutputSchema) dns_provider = fields.Nested(DnsProvidersNestedOutputSchema) roles = fields.Nested(RoleNestedOutputSchema, many=True) endpoints = fields.Nested(EndpointNestedOutputSchema, many=True, missing=[]) replaced_by = fields.Nested(CertificateNestedOutputSchema, many=True, attribute="replaced") rotation_policy = fields.Nested(RotationPolicyNestedOutputSchema)
class AuthorityInputSchema(LemurInputSchema): name = fields.String(required=True) owner = fields.Email(required=True) description = fields.String() common_name = fields.String(required=True, validate=validators.sensitive_domain) validity_start = ArrowDateTime() validity_end = ArrowDateTime() validity_years = fields.Integer() # certificate body fields organizational_unit = fields.String(missing=lambda: current_app.config.get( 'LEMUR_DEFAULT_ORGANIZATIONAL_UNIT')) organization = fields.String( missing=lambda: current_app.config.get('LEMUR_DEFAULT_ORGANIZATION')) location = fields.String( missing=lambda: current_app.config.get('LEMUR_DEFAULT_LOCATION')) country = fields.String( missing=lambda: current_app.config.get('LEMUR_DEFAULT_COUNTRY')) state = fields.String( missing=lambda: current_app.config.get('LEMUR_DEFAULT_STATE')) plugin = fields.Nested(PluginInputSchema) # signing related options type = fields.String(validate=validate.OneOf(['root', 'subca']), missing='root') parent = fields.Nested(AssociatedAuthoritySchema) signing_algorithm = fields.String(validate=validate.OneOf( ['sha256WithRSA', 'sha1WithRSA']), missing='sha256WithRSA') key_type = fields.String(validate=validate.OneOf(['RSA2048', 'RSA4096']), missing='RSA2048') key_name = fields.String() sensitivity = fields.String(validate=validate.OneOf(['medium', 'high']), missing='medium') serial_number = fields.Integer() first_serial = fields.Integer(missing=1) extensions = fields.Nested(ExtensionSchema) roles = fields.Nested(AssociatedRoleSchema(many=True)) @validates_schema def validate_dates(self, data): validators.dates(data) @validates_schema def validate_subca(self, data): if data['type'] == 'subca': if not data.get('parent'): raise ValidationError( "If generating a subca, parent 'authority' must be specified." ) @pre_load def ensure_dates(self, data): return missing.convert_validity_years(data)
class CertificateInputSchema(CertificateCreationSchema): name = fields.String() common_name = fields.String(required=True, validate=validators.sensitive_domain) authority = fields.Nested(AssociatedAuthoritySchema, required=True) validity_start = ArrowDateTime() validity_end = ArrowDateTime() validity_years = fields.Integer() destinations = fields.Nested(AssociatedDestinationSchema, missing=[], many=True) notifications = fields.Nested(AssociatedNotificationSchema, missing=[], many=True) replaces = fields.Nested(AssociatedCertificateSchema, missing=[], many=True) replacements = fields.Nested(AssociatedCertificateSchema, missing=[], many=True) # deprecated roles = fields.Nested(AssociatedRoleSchema, missing=[], many=True) csr = fields.String(validate=validators.csr) key_type = fields.String(validate=validate.OneOf(['RSA2048', 'RSA4096']), missing='RSA2048') notify = fields.Boolean(default=True) rotation = fields.Boolean() rotation_policy = fields.Nested(AssociatedRotationPolicySchema, missing={'name': 'default'}, default={'name': 'default'}) # certificate body fields organizational_unit = fields.String(missing=lambda: current_app.config.get( 'LEMUR_DEFAULT_ORGANIZATIONAL_UNIT')) organization = fields.String( missing=lambda: current_app.config.get('LEMUR_DEFAULT_ORGANIZATION')) location = fields.String( missing=lambda: current_app.config.get('LEMUR_DEFAULT_LOCATION')) country = fields.String( missing=lambda: current_app.config.get('LEMUR_DEFAULT_COUNTRY')) state = fields.String( missing=lambda: current_app.config.get('LEMUR_DEFAULT_STATE')) extensions = fields.Nested(ExtensionSchema) @validates_schema def validate_dates(self, data): validators.dates(data) @pre_load def load_data(self, data): if data.get('replacements'): data['replaces'] = data[ 'replacements'] # TODO remove when field is deprecated return missing.convert_validity_years(data)
class CertificateOutputSchema(LemurOutputSchema): id = fields.Integer() external_id = fields.String() bits = fields.Integer() body = fields.String() chain = fields.String() deleted = fields.Boolean(default=False) description = fields.String() issuer = fields.String() name = fields.String() rotation = fields.Boolean() # Note aliasing is the first step in deprecating these fields. notify = fields.Boolean() active = fields.Boolean(attribute='notify') cn = fields.String() common_name = fields.String(attribute='cn') not_after = fields.DateTime() validity_end = ArrowDateTime(attribute='not_after') not_before = fields.DateTime() validity_start = ArrowDateTime(attribute='not_before') owner = fields.Email() san = fields.Boolean() serial = fields.String() serial_hex = Hex(attribute='serial') signing_algorithm = fields.String() status = fields.String() user = fields.Nested(UserNestedOutputSchema) extensions = fields.Nested(ExtensionSchema) # associated objects domains = fields.Nested(DomainNestedOutputSchema, many=True) destinations = fields.Nested(DestinationNestedOutputSchema, many=True) notifications = fields.Nested(NotificationNestedOutputSchema, many=True) replaces = fields.Nested(CertificateNestedOutputSchema, many=True) authority = fields.Nested(AuthorityNestedOutputSchema) roles = fields.Nested(RoleNestedOutputSchema, many=True) endpoints = fields.Nested(EndpointNestedOutputSchema, many=True, missing=[]) replaced_by = fields.Nested(CertificateNestedOutputSchema, many=True, attribute='replaced') rotation_policy = fields.Nested(RotationPolicyNestedOutputSchema)
class CertificateInputSchema(CertificateCreationSchema): name = fields.String() common_name = fields.String(required=True, validate=validators.common_name) authority = fields.Nested(AssociatedAuthoritySchema, required=True) validity_start = ArrowDateTime(allow_none=True) validity_end = ArrowDateTime(allow_none=True) validity_years = fields.Integer(allow_none=True) destinations = fields.Nested(AssociatedDestinationSchema, missing=[], many=True) notifications = fields.Nested(AssociatedNotificationSchema, missing=[], many=True) replaces = fields.Nested(AssociatedCertificateSchema, missing=[], many=True) replacements = fields.Nested(AssociatedCertificateSchema, missing=[], many=True) # deprecated roles = fields.Nested(AssociatedRoleSchema, missing=[], many=True) dns_provider = fields.Nested(AssociatedDnsProviderSchema, missing=None, allow_none=True, required=False) csr = fields.String(validate=validators.csr) key_type = fields.String( validate=validate.OneOf(CERTIFICATE_KEY_TYPES), missing='RSA2048') notify = fields.Boolean(default=True) rotation = fields.Boolean() rotation_policy = fields.Nested(AssociatedRotationPolicySchema, missing={'name': 'default'}, allow_none=True, default={'name': 'default'}) # certificate body fields organizational_unit = fields.String(missing=lambda: current_app.config.get('LEMUR_DEFAULT_ORGANIZATIONAL_UNIT')) organization = fields.String(missing=lambda: current_app.config.get('LEMUR_DEFAULT_ORGANIZATION')) location = fields.String(missing=lambda: current_app.config.get('LEMUR_DEFAULT_LOCATION')) country = fields.String(missing=lambda: current_app.config.get('LEMUR_DEFAULT_COUNTRY')) state = fields.String(missing=lambda: current_app.config.get('LEMUR_DEFAULT_STATE')) extensions = fields.Nested(ExtensionSchema) @validates_schema def validate_authority(self, data): if not data['authority'].active: raise ValidationError("The authority is inactive.", ['authority']) @validates_schema def validate_dates(self, data): validators.dates(data) @pre_load def load_data(self, data): if data.get('replacements'): data['replaces'] = data['replacements'] # TODO remove when field is deprecated return missing.convert_validity_years(data)
class DnsProvidersNestedOutputSchema(LemurOutputSchema): __envelope__ = False id = fields.Integer() name = fields.String() provider_type = fields.String() description = fields.String() api_endpoint = fields.String() date_created = ArrowDateTime()
class CertificateNotificationOutputSchema(LemurOutputSchema): description = fields.String() issuer = fields.String() name = fields.String() owner = fields.Email() user = fields.Nested(UserNestedOutputSchema) validity_end = ArrowDateTime(attribute='not_after') replaced_by = fields.Nested(CertificateNestedOutputSchema, many=True, attribute='replaced') endpoints = fields.Nested(EndpointNestedOutputSchema, many=True, missing=[])
class CertificateInputSchema(CertificateCreationSchema): name = fields.String() common_name = fields.String(required=True, validate=validators.common_name) authority = fields.Nested(AssociatedAuthoritySchema, required=True) validity_start = ArrowDateTime(allow_none=True) validity_end = ArrowDateTime(allow_none=True) validity_years = fields.Integer(allow_none=True) destinations = fields.Nested(AssociatedDestinationSchema, missing=[], many=True) notifications = fields.Nested(AssociatedNotificationSchema, missing=[], many=True) replaces = fields.Nested(AssociatedCertificateSchema, missing=[], many=True) replacements = fields.Nested(AssociatedCertificateSchema, missing=[], many=True) # deprecated roles = fields.Nested(AssociatedRoleSchema, missing=[], many=True) dns_provider = fields.Nested(AssociatedDnsProviderSchema, missing=None, allow_none=True, required=False) csr = fields.String(allow_none=True, validate=validators.csr) key_type = fields.String(validate=validate.OneOf(CERTIFICATE_KEY_TYPES), missing="RSA2048") notify = fields.Boolean(default=True) rotation = fields.Boolean() rotation_policy = fields.Nested( AssociatedRotationPolicySchema, missing={"name": "default"}, allow_none=True, default={"name": "default"}, ) # certificate body fields organizational_unit = fields.String(missing=lambda: current_app.config.get( "LEMUR_DEFAULT_ORGANIZATIONAL_UNIT")) organization = fields.String( missing=lambda: current_app.config.get("LEMUR_DEFAULT_ORGANIZATION")) location = fields.String() country = fields.String( missing=lambda: current_app.config.get("LEMUR_DEFAULT_COUNTRY")) state = fields.String( missing=lambda: current_app.config.get("LEMUR_DEFAULT_STATE")) extensions = fields.Nested(ExtensionSchema) @validates_schema def validate_authority(self, data): if 'authority' not in data: raise ValidationError("Missing Authority.") if isinstance(data["authority"], str): raise ValidationError("Authority not found.") if not data["authority"].active: raise ValidationError("The authority is inactive.", ["authority"]) @validates_schema def validate_dates(self, data): validators.dates(data) @pre_load def load_data(self, data): if data.get("replacements"): data["replaces"] = data[ "replacements"] # TODO remove when field is deprecated if data.get("csr"): csr_sans = cert_utils.get_sans_from_csr(data["csr"]) if not data.get("extensions"): data["extensions"] = {"subAltNames": {"names": []}} elif not data["extensions"].get("subAltNames"): data["extensions"]["subAltNames"] = {"names": []} elif not data["extensions"]["subAltNames"].get("names"): data["extensions"]["subAltNames"]["names"] = [] data["extensions"]["subAltNames"]["names"] = csr_sans common_name = cert_utils.get_cn_from_csr(data["csr"]) if common_name: data["common_name"] = common_name key_type = cert_utils.get_key_type_from_csr(data["csr"]) if key_type: data["key_type"] = key_type # This code will be exercised for certificate import (without CSR) if data.get("key_type") is None: if data.get("body"): data["key_type"] = utils.get_key_type_from_certificate( data["body"]) else: data["key_type"] = "RSA2048" # default value return missing.convert_validity_years(data)
class CertificateOutputSchema(LemurOutputSchema): id = fields.Integer() external_id = fields.String() bits = fields.Integer() body = fields.String() chain = fields.String() csr = fields.String() deleted = fields.Boolean(default=False) description = fields.String() issuer = fields.String() name = fields.String() dns_provider_id = fields.Integer(required=False, allow_none=True) date_created = ArrowDateTime() resolved = fields.Boolean(required=False, allow_none=True) resolved_cert_id = fields.Integer(required=False, allow_none=True) rotation = fields.Boolean() # Note aliasing is the first step in deprecating these fields. notify = fields.Boolean() active = fields.Boolean(attribute="notify") has_private_key = fields.Boolean() cn = fields.String() common_name = fields.String(attribute="cn") distinguished_name = fields.String() not_after = fields.DateTime() validity_end = ArrowDateTime(attribute="not_after") not_before = fields.DateTime() validity_start = ArrowDateTime(attribute="not_before") owner = fields.Email() san = fields.Boolean() serial = fields.String() serial_hex = Hex(attribute="serial") signing_algorithm = fields.String() key_type = fields.String(allow_none=True) status = fields.String() user = fields.Nested(UserNestedOutputSchema) extensions = fields.Nested(ExtensionSchema) # associated objects domains = fields.Nested(DomainNestedOutputSchema, many=True) destinations = fields.Nested(DestinationNestedOutputSchema, many=True) notifications = fields.Nested(NotificationNestedOutputSchema, many=True) replaces = fields.Nested(CertificateNestedOutputSchema, many=True) authority = fields.Nested(AuthorityNestedOutputSchema) dns_provider = fields.Nested(DnsProvidersNestedOutputSchema) roles = fields.Nested(RoleNestedOutputSchema, many=True) endpoints = fields.Nested(EndpointNestedOutputSchema, many=True, missing=[]) replaced_by = fields.Nested(CertificateNestedOutputSchema, many=True, attribute="replaced") rotation_policy = fields.Nested(RotationPolicyNestedOutputSchema) country = fields.String() location = fields.String() state = fields.String() organization = fields.String() organizational_unit = fields.String() @post_dump def handle_subject_details(self, data): # Remove subject details if authority is CA/Browser Forum compliant. The code will use default set of values in that case. # If CA/Browser Forum compliance of an authority is unknown (None), it is safe to fallback to default values. Thus below # condition checks for 'not False' ==> 'True or None' if data.get("authority"): is_cab_compliant = data.get("authority").get("isCabCompliant") if is_cab_compliant is not False: data.pop("country", None) data.pop("state", None) data.pop("location", None) data.pop("organization", None) data.pop("organizational_unit", None)
class AuthorityInputSchema(LemurInputSchema): name = fields.String(required=True) owner = fields.Email(required=True) description = fields.String() common_name = fields.String(required=True, validate=validators.common_name) validity_start = ArrowDateTime() validity_end = ArrowDateTime() validity_years = fields.Integer() # certificate body fields organizational_unit = fields.String(missing=lambda: current_app.config.get( "LEMUR_DEFAULT_ORGANIZATIONAL_UNIT")) organization = fields.String( missing=lambda: current_app.config.get("LEMUR_DEFAULT_ORGANIZATION")) location = fields.String( missing=lambda: current_app.config.get("LEMUR_DEFAULT_LOCATION")) country = fields.String( missing=lambda: current_app.config.get("LEMUR_DEFAULT_COUNTRY")) state = fields.String( missing=lambda: current_app.config.get("LEMUR_DEFAULT_STATE")) # Creating a String field instead of Email to allow empty value email = fields.String() plugin = fields.Nested(PluginInputSchema) # signing related options type = fields.String(validate=validate.OneOf(["root", "subca"]), missing="root") parent = fields.Nested(AssociatedAuthoritySchema) signing_algorithm = fields.String( validate=validate.OneOf([ "sha256WithRSA", "sha1WithRSA", "sha256WithECDSA", "SHA384withECDSA", "SHA512withECDSA" ]), missing="sha256WithRSA", ) key_type = fields.String(validate=validate.OneOf(CERTIFICATE_KEY_TYPES), missing="RSA2048") key_name = fields.String() sensitivity = fields.String(validate=validate.OneOf(["medium", "high"]), missing="medium") serial_number = fields.Integer() first_serial = fields.Integer(missing=1) extensions = fields.Nested(ExtensionSchema) roles = fields.Nested(AssociatedRoleSchema(many=True)) @validates_schema def validate_dates(self, data): validators.dates(data) @validates_schema def validate_subca(self, data): if data["type"] == "subca": if not data.get("parent"): raise ValidationError( "If generating a subca, parent 'authority' must be specified." ) @pre_load def ensure_dates(self, data): return missing.convert_validity_years(data)