예제 #1
0
def save(path=None,
         *,
         myst: Mystic,
         timer: ResettableTimer,
         source_path=None,
         **kwargs):
    """
    Will save the mystic to a file. Accepts a path for the file. If the path is not provided, the mystic's source path will be used, if available. Will also reset the auto-close timer. If tk is installed, if the path is "?", then a dialog box will open for the file's path.
    """
    if path == '?':
        if not tk:
            raise ImportError(
                'tkinter module not imported, this functionality is unavailable'
            )
        initialdir = None
        if source_path:
            initialdir = os.path.dirname(source_path)
        path = tk_filedialog.asksaveasfilename(
            initialdir=initialdir,
            filetypes=(("mystic files", "*.scm"), ("all files", "*.*")))
        if not path:
            return 'save cancelled'
    if path is None:
        path = source_path
        if path is None:
            return 'A path must be entered for newly created files'
    with open(path, 'wb') as dst:
        myst.to_stream(dst)
    timer.reset()
    return f'saved to {path}, timer reset.'
예제 #2
0
def del_password(*, myst: Mystic, **kwargs):
    """
    Delete a password from the mystic. Takes no arguments. Yuo will be prompted to enter the password to delete. You cannot delete the only password, add a password beforehand.
    """
    if not myst.mutable:
        return 'the myst is in read-only mode, use the enable_write command to enable editing'
    myst.del_password()
    return 'password deleted'
예제 #3
0
def add_password(*, myst: Mystic, **kwargs):
    """
    Add a password to the mystic. Takes no arguments. You will be prompted to enter the new password. If a password already exists, you will be prompted to enter it too.
    """
    if not myst.mutable:
        return 'the myst is in read-only mode, use the enable_write command to enable editing'
    myst.add_password()
    return 'new password added'
예제 #4
0
파일: routes.py 프로젝트: bentheiii/mystic
def process_input(raw_source, password, pre_load_filter, check_weak=True):
    stream = BytesIO(raw_source)
    try:
        mystic = Mystic.from_stream(stream)
    except (ValueError, EOFError) as e:
        raise DumpError from e
    mystic.password_callback = lambda x: password
    try:
        try:
            mystic.mutable = True
        except Exception:
            pass

        if pre_load_filter:
            d = ((k, str(v)) for (k, v) in mystic.items()
                 if fuzzy_in(pre_load_filter, k))
        else:
            d = ((k, str(v)) for (k, v) in mystic.items())
        d = list(d)
    except BadKey:
        raise DumpError('a bad password was entered')

    if check_weak:
        p_str = pass_strength(password)

        if p_str is not None:
            add_warning(
                f'your password has been rated as {p_str}, consider changing it!'
            )

    return render_template('dump.html', results=d)
예제 #5
0
def enable_write(*, myst: Mystic, **kwargs):
    """
    Set the mystic to write mode.
    """
    if myst.mutable:
        return 'already in write mode'
    myst.mutable = True
    return 'myst in write mode'
예제 #6
0
def dump(pattern='', separator=': ', *, myst: Mystic, **kwargs):
    """
    Display all the entries in the myst. Accepts an optional pattern and an optional separator. Only keys matching the pattern will be returned, and the separator will be between every key and value.
    """
    p = re.compile(pattern)
    ret = []
    for k, v in myst.items():
        if p.search(k):
            ret.append(f'{k}{separator}{v}')
    return '\n'.join(ret)
예제 #7
0
 def load_gen_no_mutable(self, buffer):
     buffer.seek(0)
     loaded = Mystic.from_stream(buffer)
     loaded.password_callback = self.pass_callback
     self.assertEqual(loaded['one'], '1')
     self.assertEqual(loaded['two'], '2')
     self.assertEqual(loaded['three'], 'שלוש')
     self.assertIsNone(loaded.cached_dict)
     self.assertFalse(loaded.changed())
     return buffer
예제 #8
0
 def dump_clip(pattern='', separator=': ', *, myst: Mystic, **kwargs):
     """
     Get all the entries in the myst and copy thm to clipboard. Accepts an optional pattern and an optional separator. Only keys matching the pattern will be returned, and the separator will be between every key and value.  This command will only be present if pyperclip is installed.
     """
     p = re.compile(pattern)
     ret = []
     for k, v in myst.items():
         if p.search(k):
             ret.append(f'{k}{separator}{v}')
     pyperclip.copy('\n'.join(ret))
     return 'dump copied to clipboard'
예제 #9
0
def quit(*, myst: Mystic, **kwargs):
    """
    Exit the mysticCLI. Will prompt if any unsaved changes are recorded.
    """
    if myst.changed():
        response = input(
            'unsaved changes are recorded, press enter to continue, enter anything to cancel\n'
        ).lower()
        if response:
            return ''
    return False
예제 #10
0
def main(args=None):
    kwargs = {}
    if tk:
        tk_root = tk.Tk()
        tk_root.withdraw()
        kwargs['tk_root'] = tk_root
        del tk_root

    args = parser.parse_args(args)

    while args.source == ':':
        args.source = input('input file or method. * is for new file.'
                            f'{" ? for a pop-up dialog" if tk else ""}'
                            '\n')

    if args.source == '?':
        if not tk:
            raise ImportError('the tkinter module could not be imported, this functionality is not available')
        args.source = tk_filedialog.askopenfilename(filetypes=(("mystic files", "*.scm"), ("all files", "*.*")))
        if not args.source:
            exit()

    if args.source.startswith('*'):
        form = args.source[1:]
        if form == '':
            form = 'scm'
        myst = Mystic.new_from_format(form)
    else:
        kwargs['source_path'] = args.source
        with open(args.source, mode='br') as source:
            myst = Mystic.from_stream(source)

    if args.timeout < 0:
        timer = GreyHole()
    else:
        timer = ResettableTimer(args.timeout * 60, lambda: os._exit(0))

    kwargs['commands'] = Command

    if args.nsecure:
        myst.password_callback = input
    else:
        myst.password_callback = partial(getpass, stream=sys.stdout)

    kwargs['getpass'] = myst.password_callback

    if (not myst.mutable) and args.write:
        try:
            myst.mutable = True
        except Exception as e:
            if args.write is ...:
                warnings.warn('opening in read-only mode, reason: ' + str(e))
            else:
                raise

    timer.start()

    print(
        f'Welcome to the mystic CLI console version {__version__}'
        '\nNEVER enter your master password as a function argument!'
        '\nTo see all the available functions, enter help')
    try:
        while True:
            line = input()
            if not handle_line(line, throw=args.throw, myst=myst, timer=timer, **kwargs):
                break
    finally:
        timer.cancel()