apehex's picture
Use the GPM package + draft the UI
0ce396c
import functools
import gradio
import gpm.pipeline
# META #########################################################################
STYLE = '''.white-text span { color: white; }'''
TITLE = '''Generative Password Manager'''
INTRO = '''This is a POC, do **not** use it to manage your secrets.\nStateless password manager: you don't need to save passwords, they can all be derived from a single master key.\nAlways use the same format for a given target / ID: for example the password generated for "Github" and "github.com" are different.'''
# ENUMS ########################################################################
# password level
CHARS = 0
WORDS = 1
# password alphabet
DIGITS = 1
LOWERS = 2
UPPERS = 4
SPACES = 8
SYMBOLS = 16
# INTRO ########################################################################
def create_intro_block(intro: str) -> dict:
__intro = gradio.Markdown(intro, line_breaks=True)
return {'intro_block': __intro}
# MASTER #######################################################################
def create_master_block() -> dict:
__key = gradio.Textbox(label='Key', type='text', value='', placeholder='Your master key.', lines=1, max_lines=1, scale=1, show_copy_button=True, interactive=True)
return {
'key_block': __key,}
# VOCABULARY ###################################################################
def create_vocabulary_block() -> dict:
__level = gradio.Radio(label='Level', type='value', value=CHARS, choices=[('Character', CHARS), ('Word', WORDS)], interactive=True)
__vocabulary = gradio.CheckboxGroup(label='Vocabulary', type='value', value=[DIGITS, LOWERS, UPPERS], choices=[('Digits', DIGITS), ('Lowercase', LOWERS), ('Uppercase', UPPERS), ('Spaces', SPACES), ('Symbols', SYMBOLS)], interactive=True)
return {
'level_block': __level,
'vocabulary_block': __vocabulary,}
# SAMPLING #####################################################################
def create_sampling_block() -> dict:
__length = gradio.Slider(label='Length', value=8, minimum=1, maximum=32, step=1, scale=1, interactive=True)
__nonce = gradio.Number(label='Nonce', value=1, minimum=0, maximum=2 ** 32, step=1, scale=1, interactive=True)
return {
'length_block': __length,
'nonce_block': __nonce,}
# INPUTS #######################################################################
def create_inputs_block() -> dict:
__target = gradio.Textbox(label='Target', type='text', value='', placeholder='The login target (URL, IP, name, etc), like "Hugging Face" or "https://github.com".', lines=1, max_lines=1, scale=1, show_copy_button=True, interactive=True)
__identifier = gradio.Textbox(label='Identifier', type='text', value='', placeholder='The login ID (username, email, etc), like "John Doe" or "john.doe@example.com".', lines=1, max_lines=1, scale=1, show_copy_button=True, interactive=True)
return {
'target_block': __target,
'identifier_block': __identifier,}
# OUTPUTS ######################################################################
def create_outputs_block() -> dict:
__password = gradio.Textbox(label='Password', type='text', value='', placeholder='The generated password.', lines=1, max_lines=1, scale=1, show_copy_button=True, interactive=False)
return {
'password_block': __password,}
# ACTIONS ######################################################################
def create_actions_block() -> dict:
__process = gradio.Button('Generate', variant='primary', size='lg', scale=1, interactive=True)
return {'process_block': __process,}
# STATE ########################################################################
def create_state() -> dict:
return {}
# LAYOUT #######################################################################
def create_layout(intro: str=INTRO) -> dict:
__fields = {}
__fields.update(create_intro_block(intro=intro))
with gradio.Tabs():
with gradio.Tab('Manager') as __main_tab:
__fields.update({'main_tab': __main_tab})
with gradio.Row(equal_height=True):
__fields.update(create_inputs_block())
with gradio.Row(equal_height=True):
__fields.update(create_outputs_block())
with gradio.Row(equal_height=True):
__fields.update(create_actions_block())
with gradio.Tab('Settings') as __settings_tab:
__fields.update({'settings_tab': __settings_tab})
with gradio.Column(scale=1):
with gradio.Row(equal_height=True):
__fields.update(create_master_block())
with gradio.Row(equal_height=True):
__fields.update(create_vocabulary_block())
with gradio.Row(equal_height=True):
__fields.update(create_sampling_block())
return __fields
# EVENTS #######################################################################
def generate_password(
master_key: str,
login_target: str,
login_id: str,
password_length: int,
password_nonce: int,
password_level: int,
password_alphabet: list,
) -> str:
return gpm.pipeline.process(
master_key=master_key,
login_target=login_target,
login_id=login_id,
password_length=password_length,
password_nonce=password_nonce,
include_lowers=(LOWERS in password_alphabet),
include_uppers=(UPPERS in password_alphabet),
include_digits=(DIGITS in password_alphabet),
include_symbols=(SYMBOLS in password_alphabet),
include_spaces=(SPACES in password_alphabet),
include_words=(password_level == WORDS),
input_vocabulary=[chr(__i) for __i in range(128)],
model_context_dim=8,
model_embedding_dim=128)
# APP ##########################################################################
def create_app(title: str=TITLE, intro: str=INTRO, style: str=STYLE) -> gradio.Blocks:
__fields = {}
with gradio.Blocks(theme=gradio.themes.Soft(), title=title, css=style) as __app:
# __tokenizer = psaiops.score.similarity.lib.get_tokenizer(name=model, device='cpu')
# create the UI
__fields.update(create_layout(intro=intro))
# init the state
__fields.update(create_state())
# wire the input fields
__fields['process_block'].click(
fn=generate_password,
inputs=[__fields[__k] for __k in ['key_block', 'target_block', 'identifier_block', 'length_block', 'nonce_block', 'level_block', 'vocabulary_block']],
outputs=__fields['password_block'],
queue=False,
show_progress='full')
# gradio application
return __app
# MAIN #########################################################################
if __name__ == '__main__':
__app = create_app()
__app.launch()