|
|
@ -32,32 +32,28 @@ class PassUi(wx.Frame):
|
|
|
|
|
|
|
|
|
|
|
|
def add_buttons(self):
|
|
|
|
def add_buttons(self):
|
|
|
|
self.sizer.Clear(delete_windows=True)
|
|
|
|
self.sizer.Clear(delete_windows=True)
|
|
|
|
self.add_push_pull()
|
|
|
|
self.add_tools()
|
|
|
|
if self.curdir != self.topdir:
|
|
|
|
if self.curdir != self.topdir:
|
|
|
|
index = -1
|
|
|
|
btn = self.make_back_button()
|
|
|
|
cpath = os.path.abspath(os.path.join(self.curdir, os.pardir))
|
|
|
|
|
|
|
|
label = '../'
|
|
|
|
|
|
|
|
btn = wx.Button(self.pnl, id=index, label=label)
|
|
|
|
|
|
|
|
self.sizer.Add(btn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.sizer.Add(btn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.Bind(wx.EVT_BUTTON,
|
|
|
|
self.Bind(wx.EVT_BUTTON,
|
|
|
|
lambda event, path=cpath: self.path_button_clicked(
|
|
|
|
lambda event: self.path_button_clicked(event), btn)
|
|
|
|
event, path),
|
|
|
|
|
|
|
|
btn)
|
|
|
|
|
|
|
|
index = 0
|
|
|
|
index = 0
|
|
|
|
for cpath in self.cur_paths:
|
|
|
|
for cpath in self.cur_paths:
|
|
|
|
if cpath != self.curdir:
|
|
|
|
if cpath != self.curdir:
|
|
|
|
label = os.path.basename(os.path.normpath(cpath))
|
|
|
|
label = os.path.basename(os.path.normpath(cpath))
|
|
|
|
btn = wx.Button(self.pnl, id=index, label=label)
|
|
|
|
btn = wx.Button(self.pnl, label=label)
|
|
|
|
self.sizer.Add(btn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.sizer.Add(btn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.Bind(wx.EVT_BUTTON,
|
|
|
|
self.Bind(wx.EVT_BUTTON,
|
|
|
|
lambda event, path=cpath: self.path_button_clicked(
|
|
|
|
lambda event, path=cpath: self.path_button_clicked(
|
|
|
|
event, path),
|
|
|
|
event, path),
|
|
|
|
btn)
|
|
|
|
btn)
|
|
|
|
index = index + 1
|
|
|
|
index = index + 1
|
|
|
|
|
|
|
|
index = 0
|
|
|
|
for password in self.cur_passwords:
|
|
|
|
for password in self.cur_passwords:
|
|
|
|
label = os.path.splitext(
|
|
|
|
label = os.path.splitext(
|
|
|
|
os.path.basename(os.path.normpath(password)))[0]
|
|
|
|
os.path.basename(os.path.normpath(password)))[0]
|
|
|
|
btn = wx.Button(self.pnl, id=index, label=label)
|
|
|
|
btn = wx.Button(self.pnl, label=label)
|
|
|
|
self.sizer.Add(btn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.sizer.Add(btn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.Bind(wx.EVT_BUTTON,
|
|
|
|
self.Bind(wx.EVT_BUTTON,
|
|
|
|
lambda event, index=index: self.password_button_clicked(
|
|
|
|
lambda event, index=index: self.password_button_clicked(
|
|
|
@ -75,11 +71,24 @@ class PassUi(wx.Frame):
|
|
|
|
self.sizer.Add(pullbtn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.sizer.Add(pullbtn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.Bind(wx.EVT_BUTTON, lambda event: pass_pull(event), pullbtn)
|
|
|
|
self.Bind(wx.EVT_BUTTON, lambda event: pass_pull(event), pullbtn)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def add_tools(self, index=None):
|
|
|
|
|
|
|
|
btn = wx.Button(self.pnl, label="Show tools")
|
|
|
|
|
|
|
|
font = btn.GetFont().MakeBold()
|
|
|
|
|
|
|
|
btn.SetFont(font)
|
|
|
|
|
|
|
|
self.sizer.Add(btn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
|
|
|
|
self.Bind(wx.EVT_BUTTON,
|
|
|
|
|
|
|
|
lambda event, index=index: self.show_tools(event, index),
|
|
|
|
|
|
|
|
btn)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def back_button_clicked(self, event, index=None):
|
|
|
|
|
|
|
|
if index:
|
|
|
|
|
|
|
|
self.show_password_dialog(index)
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
self.add_buttons()
|
|
|
|
|
|
|
|
|
|
|
|
def get_pass_path_from_index(self, index, pathtype="path"):
|
|
|
|
def get_pass_path_from_index(self, index, pathtype="path"):
|
|
|
|
result = ""
|
|
|
|
result = ""
|
|
|
|
if pathtype == "password":
|
|
|
|
if pathtype == "password":
|
|
|
|
index = index - len(self.cur_paths)
|
|
|
|
|
|
|
|
result = self.cur_passwords[index]
|
|
|
|
result = self.cur_passwords[index]
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
result = self.cur_paths[index]
|
|
|
|
result = self.cur_paths[index]
|
|
|
@ -104,10 +113,23 @@ class PassUi(wx.Frame):
|
|
|
|
dirs = sorted(dirs)
|
|
|
|
dirs = sorted(dirs)
|
|
|
|
return dirs
|
|
|
|
return dirs
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def make_back_button(self, index=None):
|
|
|
|
|
|
|
|
print(index)
|
|
|
|
|
|
|
|
if index != None:
|
|
|
|
|
|
|
|
label = self.get_pass_path_from_index(index, "password")
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
label = self.curdir.replace(self.topdir, '')
|
|
|
|
|
|
|
|
btn = wx.Button(self.pnl, label=label)
|
|
|
|
|
|
|
|
font = btn.GetFont().MakeItalic().MakeBold()
|
|
|
|
|
|
|
|
btn.SetFont(font)
|
|
|
|
|
|
|
|
return btn
|
|
|
|
|
|
|
|
|
|
|
|
def password_button_clicked(self, event, index):
|
|
|
|
def password_button_clicked(self, event, index):
|
|
|
|
self.show_password_dialog(index)
|
|
|
|
self.show_password_dialog(index)
|
|
|
|
|
|
|
|
|
|
|
|
def path_button_clicked(self, event, path):
|
|
|
|
def path_button_clicked(self, event, path=None):
|
|
|
|
|
|
|
|
if path == None:
|
|
|
|
|
|
|
|
path = os.path.abspath(os.path.join(self.curdir, os.pardir))
|
|
|
|
self.curdir = path
|
|
|
|
self.curdir = path
|
|
|
|
self.cur_paths = self.get_pass_paths()
|
|
|
|
self.cur_paths = self.get_pass_paths()
|
|
|
|
self.cur_passwords = self.get_pass_passwords()
|
|
|
|
self.cur_passwords = self.get_pass_passwords()
|
|
|
@ -115,50 +137,52 @@ class PassUi(wx.Frame):
|
|
|
|
|
|
|
|
|
|
|
|
def show_password_dialog(self, index):
|
|
|
|
def show_password_dialog(self, index):
|
|
|
|
self.sizer.Clear(delete_windows=True)
|
|
|
|
self.sizer.Clear(delete_windows=True)
|
|
|
|
self.add_push_pull()
|
|
|
|
self.add_tools(index)
|
|
|
|
|
|
|
|
|
|
|
|
cpath = os.path.abspath(os.path.join(self.curdir, os.pardir))
|
|
|
|
passpath = self.get_pass_path_from_index(index, "password")
|
|
|
|
label = '../'
|
|
|
|
cpath = self.topdir + os.path.dirname(passpath)
|
|
|
|
btn = wx.Button(self.pnl, id=index, label=label)
|
|
|
|
password = get_password_from_path(passpath)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
btn = self.make_back_button(index)
|
|
|
|
self.sizer.Add(btn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.sizer.Add(btn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.Bind(
|
|
|
|
self.Bind(
|
|
|
|
wx.EVT_BUTTON,
|
|
|
|
wx.EVT_BUTTON,
|
|
|
|
lambda event, path=cpath: self.path_button_clicked(event, path),
|
|
|
|
lambda event, path=cpath: self.path_button_clicked(event, path),
|
|
|
|
btn)
|
|
|
|
btn)
|
|
|
|
|
|
|
|
|
|
|
|
passpath = self.get_pass_path_from_index(index, "password")
|
|
|
|
sbtn = wx.Button(self.pnl, label="Show/edit password")
|
|
|
|
password = get_password_from_path(passpath)
|
|
|
|
cbtn = wx.Button(self.pnl, label="Copy password")
|
|
|
|
sbtn = wx.Button(self.pnl, id=index + 1, label = "Show/edit password")
|
|
|
|
|
|
|
|
cbtn = wx.Button(self.pnl, id=index + 2, label = "Copy password")
|
|
|
|
|
|
|
|
self.sizer.Add(sbtn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.sizer.Add(sbtn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.sizer.Add(cbtn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.sizer.Add(cbtn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.Bind(wx.EVT_BUTTON,
|
|
|
|
self.Bind(wx.EVT_BUTTON,
|
|
|
|
lambda event, text=password: copy_to_clipboard(event, text),
|
|
|
|
lambda event, text=password: copy_to_clipboard(event, text),
|
|
|
|
cbtn)
|
|
|
|
cbtn)
|
|
|
|
self.Bind(wx.EVT_BUTTON,
|
|
|
|
self.Bind(
|
|
|
|
lambda event, index = index: self.show_password(event, index),
|
|
|
|
wx.EVT_BUTTON,
|
|
|
|
|
|
|
|
lambda event, mindex=index: self.show_password(event, mindex),
|
|
|
|
sbtn)
|
|
|
|
sbtn)
|
|
|
|
self.pnl.SetupScrolling()
|
|
|
|
self.pnl.SetupScrolling()
|
|
|
|
self.sizer.Layout()
|
|
|
|
self.sizer.Layout()
|
|
|
|
|
|
|
|
|
|
|
|
def show_password(self, event, index):
|
|
|
|
def show_password(self, event, index):
|
|
|
|
self.sizer.Clear(delete_windows=True)
|
|
|
|
self.sizer.Clear(delete_windows=True)
|
|
|
|
self.add_push_pull()
|
|
|
|
self.add_tools(index)
|
|
|
|
|
|
|
|
passpath = self.get_pass_path_from_index(index, "password")
|
|
|
|
|
|
|
|
cpath = self.topdir + os.path.dirname(passpath)
|
|
|
|
|
|
|
|
password = get_password_from_path(passpath)
|
|
|
|
|
|
|
|
|
|
|
|
cpath = os.path.abspath(os.path.join(self.curdir, os.pardir))
|
|
|
|
btn = self.make_back_button(index)
|
|
|
|
label = '../'
|
|
|
|
|
|
|
|
btn = wx.Button(self.pnl, id=index, label=label)
|
|
|
|
|
|
|
|
self.sizer.Add(btn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.sizer.Add(btn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.Bind(
|
|
|
|
self.Bind(
|
|
|
|
wx.EVT_BUTTON,
|
|
|
|
wx.EVT_BUTTON,
|
|
|
|
lambda event, path=cpath: self.path_button_clicked(event, path),
|
|
|
|
lambda event, path=cpath: self.path_button_clicked(event, path),
|
|
|
|
btn)
|
|
|
|
btn)
|
|
|
|
|
|
|
|
|
|
|
|
passpath = self.get_pass_path_from_index(index, "password")
|
|
|
|
text = wx.TextCtrl(self.pnl,
|
|
|
|
password = get_password_from_path(passpath)
|
|
|
|
value=password,
|
|
|
|
text = wx.TextCtrl(self.pnl, value = password)
|
|
|
|
style=wx.TE_MULTILINE | wx.TE_DONTWRAP)
|
|
|
|
cbtn = wx.Button(self.pnl, id=index + 2, label = "Copy password")
|
|
|
|
cbtn = wx.Button(self.pnl, label="Copy password")
|
|
|
|
sbtn = wx.Button(self.pnl, id=index + 3, label = "Save password")
|
|
|
|
sbtn = wx.Button(self.pnl, label="Save password")
|
|
|
|
self.sizer.Add(text, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.sizer.Add(text, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.sizer.Add(cbtn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.sizer.Add(cbtn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.sizer.Add(sbtn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
self.sizer.Add(sbtn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
@ -166,39 +190,59 @@ class PassUi(wx.Frame):
|
|
|
|
lambda event, text=password: copy_to_clipboard(event, text),
|
|
|
|
lambda event, text=password: copy_to_clipboard(event, text),
|
|
|
|
cbtn)
|
|
|
|
cbtn)
|
|
|
|
self.Bind(wx.EVT_BUTTON,
|
|
|
|
self.Bind(wx.EVT_BUTTON,
|
|
|
|
lambda event, path=passpath, text = text: save_to_pass(event, path, text),
|
|
|
|
lambda event, path=passpath, text=text: save_to_pass(
|
|
|
|
|
|
|
|
event, path, text),
|
|
|
|
sbtn)
|
|
|
|
sbtn)
|
|
|
|
self.pnl.SetupScrolling()
|
|
|
|
self.pnl.SetupScrolling()
|
|
|
|
self.sizer.Layout()
|
|
|
|
self.sizer.Layout()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def show_tools(self, event, index=None):
|
|
|
|
|
|
|
|
self.sizer.Clear(delete_windows=True)
|
|
|
|
|
|
|
|
btn = wx.Button(self.pnl, label="Go back")
|
|
|
|
|
|
|
|
font = btn.GetFont().MakeBold()
|
|
|
|
|
|
|
|
btn.SetFont(font)
|
|
|
|
|
|
|
|
self.sizer.Add(btn, 0, wx.EXPAND) # pylint: disable=no-member
|
|
|
|
|
|
|
|
self.Bind(
|
|
|
|
|
|
|
|
wx.EVT_BUTTON,
|
|
|
|
|
|
|
|
lambda event, index=index: self.back_button_clicked(event, index),
|
|
|
|
|
|
|
|
btn)
|
|
|
|
|
|
|
|
self.add_push_pull()
|
|
|
|
|
|
|
|
self.pnl.SetupScrolling()
|
|
|
|
|
|
|
|
self.sizer.Layout()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def copy_to_clipboard(event, text):
|
|
|
|
def copy_to_clipboard(event, text):
|
|
|
|
command1 = '/bin/echo ' + text
|
|
|
|
password = text.split('\n')[0]
|
|
|
|
command2 = '/usr/bin/wl-copy'
|
|
|
|
command1 = ['/bin/echo', password]
|
|
|
|
return run_command(command1, command2)
|
|
|
|
command2 = ['/usr/bin/wl-copy']
|
|
|
|
|
|
|
|
result = run_command(command1, command2)
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_password_from_path(passpath):
|
|
|
|
def get_password_from_path(passpath):
|
|
|
|
result = run_command("/usr/bin/pass show " + passpath)
|
|
|
|
result = run_command(['/usr/bin/pass', 'show', passpath])
|
|
|
|
temp = result[0].decode()
|
|
|
|
print(passpath)
|
|
|
|
password = temp.split('\n')[0]
|
|
|
|
password = result[0].decode()
|
|
|
|
return password
|
|
|
|
return password
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def pass_pull(event):
|
|
|
|
def pass_pull(event):
|
|
|
|
result = run_command('/usr/bin/pass git pull')
|
|
|
|
result = run_command(['/usr/bin/pass', 'git', 'pull'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def pass_push(event):
|
|
|
|
def pass_push(event):
|
|
|
|
result = run_command('/usr/bin/pass git push')
|
|
|
|
result = run_command(['/usr/bin/pass', 'git', 'push'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def run_command(command1, command2=None):
|
|
|
|
def run_command(command1, command2=None):
|
|
|
|
"""Run a command on system and capture result"""
|
|
|
|
"""Run a command on system and capture result"""
|
|
|
|
process1 = subprocess.Popen(command1.split(),
|
|
|
|
process1 = subprocess.Popen(command1,
|
|
|
|
shell=False,
|
|
|
|
shell=False,
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stderr=subprocess.PIPE)
|
|
|
|
stderr=subprocess.PIPE)
|
|
|
|
# If there is a second command it is taken to be a pipline
|
|
|
|
# If there is a second command it is taken to be a pipline
|
|
|
|
if command2:
|
|
|
|
if command2:
|
|
|
|
process2 = subprocess.Popen(command2.split(),
|
|
|
|
process2 = subprocess.Popen(command2,
|
|
|
|
shell=False,
|
|
|
|
shell=False,
|
|
|
|
stdin=process1.stdout,
|
|
|
|
stdin=process1.stdout,
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
@ -206,12 +250,18 @@ def run_command(command1, command2=None):
|
|
|
|
process1.stdout.close()
|
|
|
|
process1.stdout.close()
|
|
|
|
return process1.communicate()
|
|
|
|
return process1.communicate()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def save_to_pass(event, path, text):
|
|
|
|
def save_to_pass(event, path, text):
|
|
|
|
password = text.GetLineText(0)
|
|
|
|
password = str()
|
|
|
|
command1 = '/bin/echo ' + password
|
|
|
|
for lineno in range(text.GetNumberOfLines()):
|
|
|
|
command2 = '/usr/bin/pass insert -m ' + path
|
|
|
|
password += text.GetLineText(lineno)
|
|
|
|
|
|
|
|
password += '\n'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
command1 = ['/bin/echo', password.rstrip("\n")]
|
|
|
|
|
|
|
|
command2 = ['/usr/bin/pass', 'insert', '-m', path]
|
|
|
|
result = run_command(command1, command2)
|
|
|
|
result = run_command(command1, command2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
if __name__ == '__main__':
|
|
|
|
# When this module is run (not imported) then create the app, the
|
|
|
|
# When this module is run (not imported) then create the app, the
|
|
|
|
# frame, show it, and start the event loop.
|
|
|
|
# frame, show it, and start the event loop.
|
|
|
|