1import random 2import string 3import re 4 5from moto.core import ACCOUNT_ID 6 7 8def random_password( 9 password_length, 10 exclude_characters, 11 exclude_numbers, 12 exclude_punctuation, 13 exclude_uppercase, 14 exclude_lowercase, 15 include_space, 16 require_each_included_type, 17): 18 19 password = "" 20 required_characters = "" 21 22 if not exclude_lowercase and not exclude_uppercase: 23 password += string.ascii_letters 24 required_characters += random.choice( 25 _exclude_characters(string.ascii_lowercase, exclude_characters) 26 ) 27 required_characters += random.choice( 28 _exclude_characters(string.ascii_uppercase, exclude_characters) 29 ) 30 elif not exclude_lowercase: 31 password += string.ascii_lowercase 32 required_characters += random.choice( 33 _exclude_characters(string.ascii_lowercase, exclude_characters) 34 ) 35 elif not exclude_uppercase: 36 password += string.ascii_uppercase 37 required_characters += random.choice( 38 _exclude_characters(string.ascii_uppercase, exclude_characters) 39 ) 40 if not exclude_numbers: 41 password += string.digits 42 required_characters += random.choice( 43 _exclude_characters(string.digits, exclude_characters) 44 ) 45 if not exclude_punctuation: 46 password += string.punctuation 47 required_characters += random.choice( 48 _exclude_characters(string.punctuation, exclude_characters) 49 ) 50 if include_space: 51 password += " " 52 required_characters += " " 53 if exclude_characters: 54 password = _exclude_characters(password, exclude_characters) 55 56 password = "".join(str(random.choice(password)) for x in range(password_length)) 57 58 if require_each_included_type: 59 password = _add_password_require_each_included_type( 60 password, required_characters 61 ) 62 63 return password 64 65 66def secret_arn(region, secret_id): 67 id_string = "".join(random.choice(string.ascii_letters) for _ in range(5)) 68 return "arn:aws:secretsmanager:{0}:{1}:secret:{2}-{3}".format( 69 region, ACCOUNT_ID, secret_id, id_string 70 ) 71 72 73def get_secret_name_from_arn(secret_id): 74 # can fetch by both arn and by name 75 # but we are storing via name 76 # so we need to change the arn to name 77 # if it starts with arn then the secret id is arn 78 if secret_id.startswith("arn:aws:secretsmanager:"): 79 # split the arn by colon 80 # then get the last value which is the name appended with a random string 81 # then remove the random string 82 secret_id = "-".join(secret_id.split(":")[-1].split("-")[:-1]) 83 return secret_id 84 85 86def _exclude_characters(password, exclude_characters): 87 for c in exclude_characters: 88 if c in string.punctuation: 89 # Escape punctuation regex usage 90 c = r"\{0}".format(c) 91 password = re.sub(c, "", str(password)) 92 return password 93 94 95def _add_password_require_each_included_type(password, required_characters): 96 password_with_required_char = password[: -len(required_characters)] 97 password_with_required_char += required_characters 98 99 return password_with_required_char 100