baseui.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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. if sys.version_info.major > 2:
  28. raw_input = input
  29. from .base import HelpUI
  30. class BaseCommands(HelpUI):
  31. def do_copy(self, args):
  32. """copy item to clipboard"""
  33. pass
  34. def do_exit(self, args):
  35. """close the text console"""
  36. self._db.close()
  37. return True
  38. def do_export(self, args):
  39. """export the database to a given format"""
  40. pass
  41. def do_forget(self, args):
  42. """drop saved key forcing the user to re-enter the master
  43. password"""
  44. pass
  45. def do_cls(self, args): # pragma: no cover
  46. """clear the screen"""
  47. os.system("clear")
  48. def do_edit(self, args):
  49. """edit a node"""
  50. pass
  51. def do_clear(self, args):
  52. """remove db filter"""
  53. pass
  54. def do_passwd(self, args):
  55. """change the master password of the database"""
  56. pass
  57. def do_tags(self, args):
  58. """
  59. print all existing tags
  60. """
  61. ce = CryptoEngine.get()
  62. print("Tags:")
  63. tags = self._db.listtags()
  64. for t in tags:
  65. print(ce.decrypt(t).decode())
  66. def _get_tags(self, default=None, reader=raw_input):
  67. """
  68. Read tags from user input.
  69. Tags are simply returned as a list
  70. """
  71. # TODO: add method to read tags from db, so they
  72. # could be used for tab completer
  73. print("Tags: ", end="")
  74. sys.stdout.flush()
  75. taglist = sys.stdin.readline()
  76. tagstrings = taglist.split()
  77. tags = [tn for tn in tagstrings]
  78. return tags
  79. def _prep_term(self):
  80. self.do_cls('')
  81. if sys.platform != 'win32':
  82. rows, cols = tools.gettermsize()
  83. else:
  84. rows, cols = 18, 80 # fix this !
  85. cols -= 8
  86. return rows, cols
  87. def _format_line(self, tag_pad, nid="ID", user="USER", url="URL",
  88. tags="TAGS"):
  89. return ("{ID:<3} {USER:<{us}}{URL:<{ur}}{Tags:<{tg}}"
  90. "".format(ID=nid, USER=user,
  91. URL=url, Tags=tags, us=12,
  92. ur=20, tg=tag_pad - 32))
  93. def _print_node_line(self, node, rows, cols):
  94. tagstring = ','.join([t.decode() for t in node.tags])
  95. fmt = self._format_line(cols - 32, node._id, node.username.decode(),
  96. node.url.decode(),
  97. tagstring)
  98. formatted_entry = tools.typeset(fmt, Fore.YELLOW, False)
  99. print(formatted_entry)
  100. def _get_node_ids(self, args):
  101. filter = None
  102. if args:
  103. filter = args.split()[0]
  104. ce = CryptoEngine.get()
  105. filter = ce.encrypt(filter)
  106. nodeids = self._db.listnodes(filter=filter)
  107. return nodeids
  108. def do_list(self, args):
  109. """list all existing nodes in database"""
  110. rows, cols = self._prep_term()
  111. nodeids = self._get_node_ids(args)
  112. nodes = self._db.getnodes(nodeids)
  113. _nodes_inst = []
  114. # user, pass, url, notes
  115. for node in nodes:
  116. _nodes_inst.append(Node.from_encrypted_entries(
  117. node[1],
  118. node[2],
  119. node[3],
  120. node[4],
  121. node[5:]))
  122. head = self._format_line(cols-32)
  123. print(tools.typeset(head, Fore.YELLOW, False))
  124. for idx, node in enumerate(_nodes_inst):
  125. node._id = idx + 1
  126. self._print_node_line(node, rows, cols)
  127. def _get_input(self, prompt):
  128. print(prompt, end="")
  129. sys.stdout.flush()
  130. return sys.stdin.readline()
  131. def _get_secret(self):
  132. # TODO: enable old functionallity, with password generator.
  133. if sys.stdin.isatty():
  134. p = getpass.getpass()
  135. else:
  136. p = sys.stdin.readline().rstrip()
  137. return p
  138. def do_new(self, args):
  139. node = {}
  140. node['username'] = self._get_input("Username: ")
  141. node['password'] = self._get_secret()
  142. node['url'] = self._get_input("Url: ")
  143. node['notes'] = self._get_input("Notes: ")
  144. node['tags'] = self._get_tags()
  145. node = Node(clear_text=True, **node)
  146. self._db.add_node(node)
  147. return node