diff --git a/src/main.py b/src/main.py index 50b7f0f..ef2d31e 100755 --- a/src/main.py +++ b/src/main.py @@ -3,13 +3,14 @@ A mobile first interface for the standard unix password manager written in python """ import os +import tempfile from typing import Union import wx import wx.lib.scrolledpanel as scrolled import gnupg -from pass_handler import Pass, copy_to_clipboard, get_password_from_path, pass_pull, pass_push +from pass_handler import Pass, copy_to_clipboard, get_password_from_path, pass_pull, pass_push, run_command class PassUi(wx.Frame): @@ -42,6 +43,7 @@ class PassUi(wx.Frame): :param kw: """ super().__init__(*args, **kw) + self.file_str: str = str() self.pass_handler: Pass = Pass() self.gpg_handler: gnupg.GPG = gnupg.GPG() self.gpg_key: str = str() @@ -98,12 +100,16 @@ class PassUi(wx.Frame): self.sizer.Add(choice, 0, wx.EXPAND) # pylint: disable=no-member select_label: str = "Select New GPG Key" gpg_btn: wx.Button = wx.Button(self.pnl, label=select_label) - init_btn: wx.Button = wx.Button(self.pnl, label="Init Local Password Store") self.sizer.Add(gpg_btn, 0, wx.EXPAND) # pylint: disable=no-member - self.sizer.Add(init_btn, 0, wx.EXPAND) # pylint: disable=no-member self.Bind(wx.EVT_BUTTON, lambda event: self.gpg_button_clicked(), gpg_btn) if self.gpg_key: + init_btn: wx.Button = wx.Button(self.pnl, label="Init Local Password Store") + git_btn: wx.Button = wx.Button(self.pnl, label="Init Git Password Store") + self.sizer.Add(init_btn, 0, wx.EXPAND) # pylint: disable=no-member + self.sizer.Add(git_btn, 0, wx.EXPAND) # pylint: disable=no-member + self.Bind(wx.EVT_BUTTON, + lambda event: self.git_button_clicked(), git_btn) self.Bind(wx.EVT_BUTTON, lambda event: self.init_button_clicked(), init_btn) @@ -170,6 +176,14 @@ class PassUi(wx.Frame): btn.SetFont(font) return btn + def git_button_clicked(self): + """git_button_clicked. + + """ + git_repo: str = self.show_git_picker() + # self.pass_handler.pass_init(self.gpg_key, git_repo) + # self.add_buttons() + def gpg_button_clicked(self): """gpg_button_clicked. @@ -181,11 +195,11 @@ class PassUi(wx.Frame): uid_list.append(uid) self.show_choice(uid_list, "Select GNUPG Key") - def init_button_clicked(self): + def init_button_clicked(self, repo: Union[str, None] = None): """init_button_clicked. """ - self.pass_handler.pass_init(self.gpg_key) + self.pass_handler.pass_init(self.gpg_key, repo) self.add_buttons() def password_button_clicked(self, index: int): @@ -381,6 +395,50 @@ class PassUi(wx.Frame): n_btn) self.add_push_pull() + @redraw + def show_git_picker(self): + widget_list: list[Union[wx.StaticText, wx.TextCtrl, wx.Button]] = list() + widget_list.append(wx.StaticText(self.pnl, label='Username:')) + widget_list.append(wx.TextCtrl(self.pnl)) + widget_list.append(wx.StaticText(self.pnl, label='Password:')) + widget_list.append(wx.TextCtrl(self.pnl, style=wx.TE_PASSWORD)) + widget_list.append(wx.StaticText(self.pnl, label='Protocol:')) + widget_list.append(wx.Choice(self.pnl, choices=['https', 'git', 'git+ssh'])) + widget_list[5].SetSelection(0) + widget_list.append(wx.StaticText(self.pnl, label='Hostname:')) + widget_list.append(wx.TextCtrl(self.pnl, value='example.org')) + widget_list.append(wx.StaticText(self.pnl, label='Port:')) + widget_list.append(wx.TextCtrl(self.pnl, value='443')) + widget_list.append(wx.StaticText(self.pnl, label='Path to repo:')) + widget_list.append(wx.TextCtrl(self.pnl, value='/')) + widget_list.append(wx.Button(self.pnl, label="Submit")) + + for widget in widget_list: + self.sizer.Add(widget, 0, wx.EXPAND) # pylint: disable=no-member + self.Bind(wx.EVT_BUTTON, lambda event, m_widgets=widget_list: self.git_submit_btn_clicked(m_widgets), + widget_list[12]) + + def git_submit_btn_clicked(self, widget_list) -> str: + default_ports = {'git': 9418, 'git+ssh': 22, 'https': 443} + user: str = widget_list[1].GetLineText(0) + password: str = widget_list[3].GetLineText(0) + protocol: str = widget_list[5].GetString(widget_list[5].GetSelection()) + host: str = widget_list[7].GetLineText(0) + port: str = widget_list[9].GetLineText(0) + path: str = widget_list[11].GetLineText(0) + if not port: + port = default_ports[protocol] + self.file_str = 'protocol={}\nhost={}:{}{}\nusername=\npassword={}\n'.format(protocol, host, port, path, user, + password) + timeout_in_sec = 24 * 60 * 60 + temp_tuple = tempfile.mkstemp(text=self.file_str) + run_command(['/usr/bin/git', 'credential-store', '--file', temp_tuple[1]]) + run_command( + ['/usr/bin/git', 'config', 'credential.helper', 'cache --timeout={}'.format(timeout_in_sec)]) + os.unlink(temp_tuple[1]) + self.init_button_clicked('{}://{}:{}{}'.format(protocol, host, port, path)) + + if __name__ == '__main__': # When this module is run (not imported) then create the app, the # frame, show it, and start the event loop. diff --git a/src/pass_handler/__init__.py b/src/pass_handler/__init__.py index e1b40ef..05980ee 100644 --- a/src/pass_handler/__init__.py +++ b/src/pass_handler/__init__.py @@ -67,11 +67,14 @@ class Pass: self.move_up() return True - def pass_init(self, gpg_key): + def pass_init(self, gpg_key: str, git_repo: Union[None, str] = None): """pass_init. """ - run_command(['/usr/bin/pass', 'init', gpg_key]) + if git_repo: + run_command(['/usr/bin/git', 'clone', git_repo, self.top_dir]) + else: + run_command(['/usr/bin/pass', 'init', gpg_key]) self.set_paths_on_init() def save_to_pass(self, password, path, full_path):