baseui.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. # ===========================================================================
  2. # This file is part of Pwman3.
  3. #
  4. # Pwman3 is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License, version 2
  6. # as published by the Free Software Foundation;
  7. #
  8. # Pwman3 is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with Pwman3; if not, write to the Free Software
  15. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. # ============================================================================
  17. # Copyright (C) 2013, 2014 Oz Nahum Tiram <nahumoz@gmail.com>
  18. # ============================================================================
  19. from __future__ import print_function
  20. from pwman.util.crypto_engine import CryptoEngine
  21. import sys
  22. import os
  23. from pwman.ui import tools
  24. from colorama import Fore
  25. from pwman.data.nodes import Node
  26. import getpass
  27. import ast
  28. import csv
  29. if sys.version_info.major > 2:
  30. raw_input = input
  31. from .base import HelpUI
  32. class BaseCommands(HelpUI):
  33. def do_copy(self, args):
  34. """copy item to clipboard"""
  35. pass
  36. def do_exit(self, args):
  37. """close the text console"""
  38. self._db.close()
  39. return True
  40. def do_cls(self, args): # pragma: no cover
  41. """clear the screen"""
  42. os.system("clear")
  43. def do_edit(self, args):
  44. """edit a node"""
  45. pass
  46. def do_export(self, args):
  47. """export the database to a given format"""
  48. try:
  49. args = ast.literal_eval(args)
  50. except Exception:
  51. args = {}
  52. filename = args.get('filename', 'pwman-export.csv')
  53. delim = args.get('delimiter', ';')
  54. nodeids = self._db.listnodes()
  55. nodes = self._db.getnodes(nodeids)
  56. with open(filename, 'w') as csvfile:
  57. writer = csv.writer(csvfile, delimiter=delim)
  58. writer.writerow(['Username', 'URL', 'Password', 'Notes',
  59. 'Tags'])
  60. for n in nodes:
  61. tags = n.tags
  62. tags = filter(None, tags)
  63. tags = ','.join(t.strip() for t in tags)
  64. writer.writerow([n.username, n.url, n.password, n.notes,
  65. tags])
  66. print("Successfuly exported database to {}".format(
  67. os.path.join(os.getcwd(), filename)))
  68. def do_forget(self, args):
  69. """
  70. drop saved key forcing the user to re-enter the master
  71. password
  72. """
  73. enc = CryptoEngine.get()
  74. enc.forget()
  75. def do_passwd(self, args):
  76. """change the master password of the database"""
  77. pass
  78. def do_tags(self, args):
  79. """
  80. print all existing tags
  81. """
  82. ce = CryptoEngine.get()
  83. print("Tags:")
  84. tags = self._db.listtags()
  85. for t in tags:
  86. print(ce.decrypt(t).decode())
  87. def _get_tags(self, default=None, reader=raw_input):
  88. """
  89. Read tags from user input.
  90. Tags are simply returned as a list
  91. """
  92. # TODO: add method to read tags from db, so they
  93. # could be used for tab completer
  94. print("Tags: ", end="")
  95. sys.stdout.flush()
  96. taglist = sys.stdin.readline()
  97. tagstrings = taglist.split()
  98. tags = [tn for tn in tagstrings]
  99. return tags
  100. def _prep_term(self):
  101. self.do_cls('')
  102. if sys.platform != 'win32':
  103. rows, cols = tools.gettermsize()
  104. else:
  105. rows, cols = 18, 80 # fix this !
  106. cols -= 8
  107. return rows, cols
  108. def _format_line(self, tag_pad, nid="ID", user="USER", url="URL",
  109. tags="TAGS"):
  110. return ("{ID:<3} {USER:<{us}}{URL:<{ur}}{Tags:<{tg}}"
  111. "".format(ID=nid, USER=user,
  112. URL=url, Tags=tags, us=12,
  113. ur=20, tg=tag_pad - 32))
  114. def _print_node_line(self, node, rows, cols):
  115. tagstring = ','.join([t.decode() for t in node.tags])
  116. fmt = self._format_line(cols - 32, node._id, node.username.decode(),
  117. node.url.decode(),
  118. tagstring)
  119. formatted_entry = tools.typeset(fmt, Fore.YELLOW, False)
  120. print(formatted_entry)
  121. def _get_node_ids(self, args):
  122. filter = None
  123. if args:
  124. filter = args.split()[0]
  125. ce = CryptoEngine.get()
  126. filter = ce.encrypt(filter)
  127. nodeids = self._db.listnodes(filter=filter)
  128. return nodeids
  129. def do_list(self, args):
  130. """list all existing nodes in database"""
  131. rows, cols = self._prep_term()
  132. nodeids = self._get_node_ids(args)
  133. nodes = self._db.getnodes(nodeids)
  134. _nodes_inst = []
  135. # user, pass, url, notes
  136. for node in nodes:
  137. _nodes_inst.append(Node.from_encrypted_entries(
  138. node[1],
  139. node[2],
  140. node[3],
  141. node[4],
  142. node[5:]))
  143. head = self._format_line(cols-32)
  144. print(tools.typeset(head, Fore.YELLOW, False))
  145. for idx, node in enumerate(_nodes_inst):
  146. node._id = idx + 1
  147. self._print_node_line(node, rows, cols)
  148. def _get_input(self, prompt):
  149. print(prompt, end="")
  150. sys.stdout.flush()
  151. return sys.stdin.readline()
  152. def _get_secret(self):
  153. # TODO: enable old functionallity, with password generator.
  154. if sys.stdin.isatty():
  155. p = getpass.getpass()
  156. else:
  157. p = sys.stdin.readline().rstrip()
  158. return p
  159. def do_new(self, args):
  160. node = {}
  161. node['username'] = self._get_input("Username: ")
  162. node['password'] = self._get_secret()
  163. node['url'] = self._get_input("Url: ")
  164. node['notes'] = self._get_input("Notes: ")
  165. node['tags'] = self._get_tags()
  166. node = Node(clear_text=True, **node)
  167. self._db.add_node(node)
  168. return node