Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
master_password.py157 linesDownload Raw Back to utils
1import config2from flask import current_app, session, current_app3from flask_login import current_user4from pgadmin.model import db, User, Server5from pgadmin.utils.crypto import encrypt, decrypt6 7 8MASTERPASS_CHECK_TEXT = 'ideas are bulletproof'9 10 11def set_crypt_key(_key, _new_login=True):12    """13    Set the crypt key14    :param _key: The key15    :param _new_login: Is fresh login or password change16    """17    current_app.keyManager.set(_key, _new_login)18 19 20def get_crypt_key():21    """22    Returns the crypt key23    :return: the key24    """25    enc_key = current_app.keyManager.get()26 27    # if desktop mode and master pass disabled then use the password hash28    if not config.MASTER_PASSWORD_REQUIRED \29            and not config.SERVER_MODE:30        return True, current_user.password31    # if desktop mode and master pass enabled32    elif config.MASTER_PASSWORD_REQUIRED and \33        config.MASTER_PASSWORD_HOOK is None\34            and enc_key is None:35        return False, None36    elif not config.MASTER_PASSWORD_REQUIRED and config.SERVER_MODE and \37            'pass_enc_key' in session:38        return True, session['pass_enc_key']39    elif config.MASTER_PASSWORD_REQUIRED and config.SERVER_MODE and \40            config.MASTER_PASSWORD_HOOK and current_user.password is None:41        cmd = config.MASTER_PASSWORD_HOOK42        command = cmd.replace('%u', current_user.username) \43            if '%u' in cmd else cmd44        return get_master_password_from_master_hook(command)45    else:46        return True, enc_key47 48 49def validate_master_password(password):50    """51    Validate the password/key against the stored encrypted text52    :param password: password/key53    :return: Valid or not54    """55    # master pass is incorrect if decryption fails56    try:57        decrypted_text = decrypt(current_user.masterpass_check, password)58 59        if isinstance(decrypted_text, bytes):60            decrypted_text = decrypted_text.decode()61 62        if MASTERPASS_CHECK_TEXT != decrypted_text:63            return False64        else:65            return True66    except Exception:67        False68 69 70def set_masterpass_check_text(password, clear=False):71    """72    Set the encrypted text which will be used later to validate entered key73    :param password: password/key74    :param clear: remove the encrypted text75    """76    try:77        masterpass_check = None78        if not clear:79            masterpass_check = encrypt(MASTERPASS_CHECK_TEXT, password)80 81        # set the encrypted sample text with the new82        # master pass83        db.session.query(User) \84            .filter(User.id == current_user.id) \85            .update({User.masterpass_check: masterpass_check})86        db.session.commit()87 88    except Exception:89        db.session.rollback()90        raise91 92 93def cleanup_master_password():94    """95    Remove the master password and saved passwords from DB which are96    encrypted using master password. Also remove the encrypted text97    """98 99    # also remove the master password check string as it will help if master100    # password entered/enabled again101    set_masterpass_check_text('', clear=True)102 103    from pgadmin.browser.server_groups.servers.utils \104        import remove_saved_passwords105    remove_saved_passwords(current_user.id)106 107    current_app.keyManager.hard_reset()108 109    from pgadmin.utils.driver import get_driver110    driver = get_driver(config.PG_DEFAULT_DRIVER)111 112    for server in Server.query.filter_by(user_id=current_user.id).all():113        manager = driver.connection_manager(server.id)114        manager.update(server)115 116 117def process_masterpass_disabled():118    """119    On master password disable, remove the connection data from session as it120    may have saved password which will cause trouble121    :param session: Flask session122    :param conn_data: connection manager copy from session if any123    """124    if not config.SERVER_MODE and not config.MASTER_PASSWORD_REQUIRED \125            and current_user.masterpass_check is not None:126        cleanup_master_password()127        return True128 129    return False130 131 132def get_master_password_from_master_hook(command):133    """134    This method executes specified command & returns output.135    :param command: Shell command with absolute path136    :return: Output of command.137    """138    import subprocess139    try:140        p = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)141        out, err = p.communicate()142        if p.returncode == 0:143            output = out.decode() if hasattr(out, 'decode') else out144            output = output.strip()145            return True, output146        else:147            error = "Command '{0}' failed, exit-code={1} error = {2}".format(148                command, p.returncode, str(err))149            current_app.logger.error(error)150            return False, None151    except Exception as e:152        current_app.logger.exception(153            'Failed to retrieve master password from the master password hook'154            ' utility.Error: {0}'.format(e)155        )156        return False, None157 
codekingpro/portable-devtools · Team Ai