Source code for swh.model.fields.hashes
# Copyright (C) 2015 The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU General Public License version 3, or any later version
# See top-level LICENSE file for more information
import string
from ..exceptions import ValidationError
[docs]
def validate_hash(value, hash_type):
"""Validate that the given value represents a hash of the given hash_type.
Args:
value: the value to check
hash_type: the type of hash the value is representing
Returns:
True if the hash validates
Raises:
ValueError if the hash does not validate
"""
hash_lengths = {
"sha1": 20,
"sha1_git": 20,
"sha256": 32,
}
hex_digits = set(string.hexdigits)
if hash_type not in hash_lengths:
raise ValidationError(
"Unexpected hash type %(hash_type)s, expected one of" " %(hash_types)s",
params={
"hash_type": hash_type,
"hash_types": ", ".join(sorted(hash_lengths)),
},
code="unexpected-hash-type",
)
if isinstance(value, str):
errors = []
extra_chars = set(value) - hex_digits
if extra_chars:
errors.append(
ValidationError(
"Unexpected characters `%(unexpected_chars)s' for hash "
"type %(hash_type)s",
params={
"unexpected_chars": ", ".join(sorted(extra_chars)),
"hash_type": hash_type,
},
code="unexpected-hash-contents",
)
)
length = len(value)
expected_length = 2 * hash_lengths[hash_type]
if length != expected_length:
errors.append(
ValidationError(
"Unexpected length %(length)d for hash type "
"%(hash_type)s, expected %(expected_length)d",
params={
"length": length,
"expected_length": expected_length,
"hash_type": hash_type,
},
code="unexpected-hash-length",
)
)
if errors:
raise ValidationError(errors)
return True
if isinstance(value, bytes):
length = len(value)
expected_length = hash_lengths[hash_type]
if length != expected_length:
raise ValidationError(
"Unexpected length %(length)d for hash type "
"%(hash_type)s, expected %(expected_length)d",
params={
"length": length,
"expected_length": expected_length,
"hash_type": hash_type,
},
code="unexpected-hash-length",
)
return True
raise ValidationError(
"Unexpected type %(type)s for hash, expected str or bytes",
params={
"type": value.__class__.__name__,
},
code="unexpected-hash-value-type",
)
[docs]
def validate_sha1(sha1):
"""Validate that sha1 is a valid sha1 hash"""
return validate_hash(sha1, "sha1")
[docs]
def validate_sha1_git(sha1_git):
"""Validate that sha1_git is a valid sha1_git hash"""
return validate_hash(sha1_git, "sha1_git")
[docs]
def validate_sha256(sha256):
"""Validate that sha256 is a valid sha256 hash"""
return validate_hash(sha256, "sha256")