Skip to content

Commit d4905f4

Browse files
committed
Merge branch 'develop'
2 parents 728f90c + e35b32f commit d4905f4

File tree

1 file changed

+28
-25
lines changed
  • random_password_generator

1 file changed

+28
-25
lines changed

random_password_generator/rpg.py

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import random
44
import secrets
55
import string
6+
from typing import Optional
67

78
import click
89
import requests
@@ -18,6 +19,9 @@
1819
128+ bits\t= Very Strong; often overkill"""
1920

2021
_available_charsets = {"l", "u", "d", "p"}
22+
_max_pass_length = 50
23+
_min_pass_length = 12
24+
_max_pass_number = 50
2125

2226

2327
@click.command(context_settings={'help_option_names': ['-h', '--help']})
@@ -44,15 +48,15 @@ def rpg(pass_length: int, number: int, output: click.File, exclude_charsets: str
4448
:return: None
4549
"""
4650
# Check pass_length validity
47-
msg.Prints.verbose("Checking <pass-length> ({}) validity".format(pass_length), verbose)
48-
if pass_length > 90 or pass_length < 12:
51+
msg.Prints.verbose(f"Checking <pass-length> ({pass_length}) validity", verbose)
52+
if pass_length > _max_pass_length or pass_length < _min_pass_length:
4953
raise click.BadArgumentUsage(
50-
msg.Echoes.error("Invalid value for \"<pass-length>\": {} is not in the valid range of 12 to 90.")
51-
.format(pass_length))
54+
msg.Echoes.error(
55+
f"Invalid value for \"<pass-length>\": {pass_length} is not in the valid range of 12 to 90."))
5256

5357
# Check number validity
54-
msg.Prints.verbose("Checking <pass-number> ({}) validity".format(number), verbose)
55-
if number > 50:
58+
msg.Prints.verbose(f"Checking <pass-number> ({number}) validity", verbose)
59+
if number > _max_pass_number:
5660
raise click.BadOptionUsage("number", msg.Echoes.error(
5761
"Invalid value for \"<pass-number>\": the maximum value accepted is 50."))
5862

@@ -66,7 +70,7 @@ def rpg(pass_length: int, number: int, output: click.File, exclude_charsets: str
6670
raise click.BadOptionUsage("--exclude-charsets",
6771
msg.Echoes.error("RPG needs at least one charsets type to generate password."))
6872
else:
69-
if not len(chars) == 4:
73+
if not len(chars) == len(string.ascii_lowercase + string.ascii_uppercase + string.digits + string.punctuation):
7074
# User chose to not use any charsets, print warning message
7175
msg.Prints.warning("You are going to generate passwords without one or more of default charsets!")
7276
msg.Prints.warning(
@@ -99,20 +103,20 @@ def rpg(pass_length: int, number: int, output: click.File, exclude_charsets: str
99103

100104
for pw in pw_list:
101105
if output:
102-
output.write("{}\n".format(pw))
106+
output.write(f"{pw}\n")
103107
else:
104108
msg.Prints.info(pw)
105109

106110
# Calculate entropy and print it
107111
entropy = _get_entropy(pass_length, chars)
108112
if output:
109-
output.write("\nEntropy: {}".format(entropy))
113+
output.write(f"\nEntropy: {entropy}")
110114
else:
111-
msg.Prints.emphasis("\nThe entropy of generated password is: {}".format(entropy))
115+
msg.Prints.emphasis(f"\nThe entropy of generated password is: {entropy}")
112116

113117
# Print summary table, only if --verbose or --output
114118
if output:
115-
output.write("\n{}".format(_password_entropy_table))
119+
output.write(f"\n{_password_entropy_table}")
116120
else:
117121
msg.Prints.verbose(_password_entropy_table, verbose)
118122

@@ -124,7 +128,7 @@ def _get_char_list(charsets_to_exclude: str = None) -> list:
124128
:param str charsets_to_exclude: charsets to exclude
125129
:return list: available charsets list
126130
"""
127-
chars = []
131+
chars = ""
128132

129133
charsets = {}
130134
if charsets_to_exclude is not None:
@@ -134,21 +138,21 @@ def _get_char_list(charsets_to_exclude: str = None) -> list:
134138
# If charsets is empty, take all charsets
135139
if not bool(charsets):
136140
if charsets_to_exclude is not None:
137-
return chars
141+
return list(chars)
138142
else:
139143
charsets = _available_charsets
140144

141145
for cset in charsets:
142146
if cset == "l":
143-
chars.append(string.ascii_lowercase)
147+
chars += string.ascii_lowercase
144148
elif cset == "u":
145-
chars.append(string.ascii_uppercase)
149+
chars += string.ascii_uppercase
146150
elif cset == "d":
147-
chars.append(string.digits)
151+
chars += string.digits
148152
elif cset == "p":
149-
chars.append(string.punctuation)
153+
chars += string.punctuation
150154

151-
return chars
155+
return list(chars)
152156

153157

154158
def _sanitize_excluded_charsets(charsets_to_sanitize: str) -> set:
@@ -163,7 +167,7 @@ def _sanitize_excluded_charsets(charsets_to_sanitize: str) -> set:
163167
return set_to_sanitize & _available_charsets
164168

165169

166-
def _generate_random_password(length: int, charsets: list, no_safe: bool = False):
170+
def _generate_random_password(length: int, charsets: list, no_safe: bool = False) -> Optional[str]:
167171
"""
168172
Generate random password.
169173
@@ -173,27 +177,26 @@ def _generate_random_password(length: int, charsets: list, no_safe: bool = False
173177
:return: str random password | None
174178
"""
175179
pw = []
176-
chars = len(charsets)
177180

178181
# Shuffle chars to change every password generation
179182
random.shuffle(charsets)
180183

181184
for i in range(length):
182185
# Append random char into generated password
183-
pw.append(secrets.choice(charsets[i % chars]))
186+
pw.append(secrets.choice(charsets))
184187

185188
random.shuffle(pw)
186-
pw = "".join(pw)
189+
pw_str = "".join(pw)
187190

188191
# Check if generated password is in a password leak
189192
if not no_safe:
190-
leaks = _is_leaked_password(pw)
193+
leaks = _is_leaked_password(pw_str)
191194
if leaks == 1:
192-
_generate_random_password(length, charsets)
195+
return _generate_random_password(length, charsets)
193196
elif leaks == 9:
194197
return None
195198

196-
return pw
199+
return pw_str
197200

198201

199202
def _is_leaked_password(pw: str) -> int:

0 commit comments

Comments
 (0)