예제 #1
0
    def test_add_password_regenerate_password(self, pmui_empty, monkeypatch,
                                              capsys, choice, num_of_tries):
        # generate some random info = (username, app, email, url)
        info = tuple(crypto_stuff.generate_password() for _ in range(4))
        monkeypatch.setattr(pm_ui.PM_UI, 'get_unique_info_from_user',
                            lambda *args: info)

        count = [0]

        monkeypatch.setattr(pm_ui, 'how_to_generate_pw', lambda: choice)
        # pw = crypto_stuff.generate_password()
        monkeypatch.setattr(pm_ui, 'generate_pw',
                            lambda *args: crypto_stuff.generate_password())

        monkeypatch.setattr(pm_ui, 'reveal_password',
                            lambda *args: print(f'Try {count[0]}'))

        def time_to_stop(*args):
            count[0] += 1
            if count[0] >= num_of_tries:
                return True
            return False

        monkeypatch.setattr(pm_ui.PM_UI, 'save_password_to_db_or_not',
                            time_to_stop)

        pmui_empty.add_password()

        printed = capsys.readouterr()[0]

        assert 'Password has been generated.' in printed

        for i in range(num_of_tries):
            assert f'Try {i}' in printed
예제 #2
0
def generate_pw(type_num: int) -> str:
    # add the cancel password option just to be sure
    if type_num == 0:
        return ''
    # generate using all characters
    if type_num == 1:
        return generate_password()
    # generate using letters and numbers
    if type_num == 2:
        return generate_password(choice=1)
    # user makes the password (or saves an existing one to database)
    if type_num == 3:
        while True:
            pw = getpass.getpass('Type the password you want: ')
            pw2 = getpass.getpass('Type the password again: ')
            if pw == pw2:
                if pw:
                    return pw
                ans = yes_or_no_question('you did not type any password. Do you want to try again?')
                if ans == 'n':
                    return ''
            else:
                ans = yes_or_no_question('Passwords were not the same. Do you want to try again?')
                if ans == 'n':
                    return ''
예제 #3
0
    def test_add_password(self, pmui_empty, monkeypatch, capsys):
        # generate some random info = (username, app, email, url)
        info = tuple(crypto_stuff.generate_password() for _ in range(4))
        monkeypatch.setattr(pm_ui.PM_UI, 'get_unique_info_from_user',
                            lambda *args: info)

        # generate a password to go with the info
        monkeypatch.setattr(pm_ui, 'how_to_generate_pw', lambda: 3)
        pw = crypto_stuff.generate_password()
        monkeypatch.setattr(pm_ui, 'generate_pw', lambda *args: pw)

        monkeypatch.setattr(pm_ui, 'yes_or_no_question', lambda *args: 'y')

        pmui_empty.add_password() is None

        # text indicating success was printed on the screen
        printed = capsys.readouterr()[0]
        success_text = f'Password for user {info[0]} to app {info[2]} has been saved to the database.'

        assert success_text in printed

        # the password and related info was saved to db
        pw_info = pmui_empty.pm.find_password(info[2])
        # it is extremely unlikely that the previous app would show up here
        assert len(pw_info) == 1
        assert pw_info[0][1] == info[0]
        assert pw_info[0][3] == pw
        assert pw_info[0][4] == info[2]
예제 #4
0
def test_generate_password():
    pwd = cs.generate_password()
    assert len(pwd) == 20
    # only letters and numbers
    chars = "abcdefghijklmnopqrstuvwxyz"
    chars += chars.upper() + "0123456789"
    pwd = cs.generate_password(20, True)
    assert len(pwd) == 20
    for char in pwd:
        assert char in chars
예제 #5
0
    def test_find_app_and_username(self, pmui_empty, monkeypatch, capsys):
        # random header line
        first_line = crypto_stuff.generate_password()
        # 'input' random app name
        name_of_the_app = crypto_stuff.generate_password()
        monkeypatch.setattr('builtins.input', lambda *args: name_of_the_app)

        # there is nothing so this should find nothing
        assert pmui_empty.find_app_and_username(first_line) is None
        printed = capsys.readouterr()[0]
        assert first_line in printed
        assert f'No passwords related to {name_of_the_app} found' in printed
예제 #6
0
def test_password_manager_clean_start(monkeypatch, capsys, paths, password, default_paths, inputs):
    inputs.insert(1, password)
    inputs.insert(1, password)
    # random app_name should be noticeable
    app_name = crypto_stuff.generate_password(10, True)
    inputs.insert(4, app_name)

    monkeypatch.setattr(file_locations, 'paths', paths)
    # clearing screen might be bad for debugging
    monkeypatch.setattr(pm, 'clear_screen', lambda: None)
    if os.name == 'nt':
        monkeypatch.setattr(msvcrt, 'kbhit', lambda *args: True)
        monkeypatch.setattr(msvcrt, 'getch', lambda *args: b'\r')
    else:
        monkeypatch.setattr(select, 'select', lambda *args: (False, None, None))

    count = [-1]

    def give_input(prompt=None):
        count[0] += 1
        return inputs[count[0]]

    monkeypatch.setattr('builtins.input', give_input)
    monkeypatch.setattr(getpass, 'getpass', give_input)

    pm.password_manager()

    assert app_name in capsys.readouterr()[0]
예제 #7
0
def generate_dummy_string(
        type_of_string: str,
        fernet_obj: Optional[Fernet] = None,
        password_hasher: Optional[cs.argon2.PasswordHasher] = None):
    if type_of_string == 'normal':
        if fernet_obj is None:
            fernet_obj = Fernet(Fernet.generate_key())
        return cs.encrypt_text(cs.generate_password(), fernet_obj)
    elif type_of_string == 'key':
        if fernet_obj is None:
            fernet_obj = Fernet(Fernet.generate_key())
        return fernet_obj.encrypt(Fernet.generate_key())
    elif type_of_string == 'hash':
        if password_hasher is None:
            password_hasher = cs.PasswordHasher()
        return password_hasher.hash(cs.generate_password())
    else:
        raise Exception('Invalid type of dummy data')
예제 #8
0
 def give_input(*args):
     if args:
         return app
     count[0] += 1
     if count[0] < 3:
         return crypto_stuff.generate_password()
     if count[0] < 5:
         return 1729
     return '1'
예제 #9
0
    def test_add_password_no_password(self, pmui_empty, monkeypatch, capsys):
        # generate some random info = (username, app, email, url)
        info = tuple(crypto_stuff.generate_password() for _ in range(4))
        monkeypatch.setattr(pm_ui.PM_UI, 'get_unique_info_from_user',
                            lambda *args: info)

        monkeypatch.setattr(pm_ui, 'how_to_generate_pw', lambda: 3)
        monkeypatch.setattr(pm_ui, 'generate_pw', lambda *args: '')

        pmui_empty.add_password()

        printed = capsys.readouterr()[0]

        assert 'Adding password canceled.' in printed
예제 #10
0
    def test_change_password(self, pmui_w_stuff, monkeypatch, capsys,
                             some_info, index):
        info_line = some_info[index]
        monkeypatch.setattr('builtins.input', lambda *args: info_line[2])

        monkeypatch.setattr(pm_ui, 'how_to_generate_pw', lambda *args: 3)
        pw = crypto_stuff.generate_password()
        monkeypatch.setattr(pm_ui, 'generate_pw', lambda *args: pw)

        monkeypatch.setattr(pm_ui, 'yes_or_no_question', lambda *args: 'y')

        assert pmui_w_stuff.change_password() is None

        db_search = pmui_w_stuff.pm.find_password(info_line[2])[0]

        assert db_search[1:] == (*info_line[:2], pw, *info_line[2:])
예제 #11
0
    def test_find_password_for_app(self, pmui_empty, monkeypatch, capsys):
        # 'input' random app name
        name_of_the_app = crypto_stuff.generate_password()
        monkeypatch.setattr('builtins.input', lambda *args: name_of_the_app)

        # if obtain_password is called, something has gone wrong
        def error_message(*args):
            print('ERROR')

        monkeypatch.setattr(pm_ui, 'obtain_password', error_message)

        assert pmui_empty.find_password_for_app() is None
        printed = capsys.readouterr()[0]

        assert 'Email' not in printed
        assert 'Username' not in printed
        assert 'ERROR' not in printed
예제 #12
0
    def test_save_password_to_db_or_not(self, pmui_empty, monkeypatch, capsys,
                                        ans, is_done, text):
        info = tuple(crypto_stuff.generate_password() for _ in range(5))
        count = [-1]

        def answer(*args):
            count[0] += 1
            return ans[count[0]]

        monkeypatch.setattr(pm_ui, 'yes_or_no_question', answer)

        assert pmui_empty.save_password_to_db_or_not(info) == is_done

        if text:
            printed = capsys.readouterr()[0]
            assert text in printed

        if ans[:2] == ('y', 'y'):
            pw_info = pmui_empty.pm.find_password(info[3])
            assert len(pw_info) == 1
            # username, password and app name should be the same
            assert pw_info[0][1] == info[0]
            assert pw_info[0][3:5] == info[2:4]
예제 #13
0
    def test_change_password_in_db(self, pmui_w_stuff, monkeypatch, capsys,
                                   type_choice):

        monkeypatch.setattr(pm_ui, 'how_to_generate_pw',
                            lambda *args: type_choice)
        pw = crypto_stuff.generate_password()
        monkeypatch.setattr(pm_ui, 'generate_pw', lambda *args: pw)

        monkeypatch.setattr(pm_ui, 'reveal_password',
                            lambda *args: print('revelation happening'))

        # monkeypatch.setattr(pm_ui, 'yes_or_no_question', lambda *args: 'y')
        monkeypatch.setattr(pm_ui.PM_UI, 'change_password_in_db_or_not',
                            lambda *args: True)

        assert pmui_w_stuff.change_password_in_db(
            (0, '1', '2', '3', '4', '5')) is None

        printed = capsys.readouterr()[0]

        if type_choice in (1, 2):
            assert 'revelation happening' in printed
        else:
            assert 'revelation happening' not in printed
예제 #14
0
def password():
    return crypto_stuff.generate_password(32, True)