baseui.py 5.3 KB

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