Coverage for plugins/attributes/ldapPasswordHash/ldapPasswordHash.py: 39%
28 statements
« prev ^ index » next coverage.py v7.10.1, created at 2025-07-28 07:24 +0000
« prev ^ index » next coverage.py v7.10.1, created at 2025-07-28 07:24 +0000
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
4# Hermes : Change Data Capture (CDC) tool from any source(s) to any target
5# Copyright (C) 2023, 2024 INSA Strasbourg
6#
7# This file is part of Hermes.
8#
9# Hermes is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# Hermes is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with Hermes. If not, see <https://www.gnu.org/licenses/>.
23from jinja2 import Undefined
26from helpers.ldaphash import LDAPHash
27from lib.plugins import AbstractAttributePlugin
29HERMES_PLUGIN_CLASSNAME: str | None = "LdapPasswordHashPlugin"
30"""The plugin class name defined in this module file"""
33class InvalidLdapPasswordHashType(Exception):
34 """Raised when an unknown hash type has been requested"""
37class LdapPasswordHashPlugin(AbstractAttributePlugin):
38 """Plugin to generate LDAP password hashes"""
40 def __init__(self, settings: dict[str, any]) -> None:
41 """Instantiate new plugin and store a copy of its settings dict in
42 self._settings"""
43 super().__init__(settings)
44 self._defaulthashtypes: list[str] = self._settings["default_hash_types"]
46 def filter(
47 self, password: str | None | Undefined, hashtypes: None | str | list[str] = None
48 ) -> list[str] | None:
49 """Call the plugin with specified value, and returns the result."""
51 if password is None:
52 return Undefined(hint="No password specified")
54 if isinstance(password, Undefined):
55 return password
57 if type(password) is not str:
58 raise TypeError(
59 f"Invalid type for password: {type(password)=}."
60 " Password must be a string"
61 )
63 if hashtypes is None:
64 # No type(s) explicitly specified, use default values specified in config
65 _hashtypes: list[str] = self._defaulthashtypes
66 else:
67 # Use specified type(s), and ensure to store values in a set to filter
68 # duplicates
69 if type(hashtypes) is str:
70 _hashtypes = [hashtypes]
71 elif type(hashtypes) is list:
72 _hashtypes = hashtypes
73 else:
74 raise TypeError(
75 f"Invalid type for hashtypes: {type(hashtypes)=}."
76 " Hashtype must be a string or a list of string"
77 )
79 unknownHashTypes = set(_hashtypes) - set(LDAPHash.getAvailableHashtypes())
80 if unknownHashTypes:
81 raise InvalidLdapPasswordHashType(
82 f"Invalid LDAP password hash type specified: {unknownHashTypes}"
83 )
85 return [LDAPHash.hash(password, hashtype) for hashtype in _hashtypes]