-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcabinet_wrapper.py
256 lines (200 loc) · 6.91 KB
/
cabinet_wrapper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
from sys import exit
from getpass import getpass
from utils import get_configs
from cabinet import Cabinet
class CabinetWrapper:
"""
A wrapper to easely use the cabinet library.
TODO: In the future we should try moving this all to the library.
"""
def __init__(self, vault_name=None, account_id=None, password=None):
"""
Initialize the cabinet instance using the given vault/account or from
the configuration file if you don't specify them.
This will prompt for the account password to open the vault.
:param vault_name: The name of the vault
:type: str
:param account_id:
:type: str
"""
join = os.path.join
self.base_path = join(os.path.expanduser('~'), '.config', 'cabinet')
self.config_file = join(self.base_path, 'cli.ini')
self.secrets_path = join(self.base_path, 'secrets')
self.vault_path = join(self.base_path, 'vaults')
self._ready = self._load_credentials(vault_name, account_id, password)
def _load_credentials(self, vault_name=None, account_id=None, password=None):
"""
It loads the vault name and account id from the configuration, then
it overrides the configuration with the cli options (if entered).
Finally, it prompts for the account password and opens the vault.
Params:
:param vault_name: The name of the vault
:type: str
:param account_id:
:type: str
TODO: Move the print and die to utils
"""
config = get_configs(self.config_file)
if vault_name:
self.vault_name = vault_name
elif config.get('vault_name'):
self.vault_name = config.get('vault_name')
else:
print('Vault not specified')
exit()
if account_id:
self.account_id = account_id
elif config.get('account_id'):
self.account_id = config.get('account_id')
else:
print('Account not specified')
exit()
is_open = False
for i in range(3):
try:
if password is None:
self.password = getpass()
else:
self.password = password
is_open = self.open_vault(self.account_id, self.password,
self.vault_name)
break
except Exception as e:
msg = "There was an error opening the vault."
if i < 2:
msg += " Wrong password? Try again or Ctrl+C to quit."
else:
msg += " Exit."
print(msg)
return is_open
def open_vault(self, account_id, password, vault_name):
"""
Open the vault identified by the vault_name.
Params:
:param account_id:
:type: str
:param password:
:type: str
:param vault_name: The name of the vault
:type: str
TODO: Implement account_id/password/vault validation and opening
"""
self.cab = Cabinet(account_id, password, self.secrets_path)
self.cab.open(vault_name, self.vault_path)
# TODO: Add open check. For this, the vault should verify keys
return True
def get_by_tags(self, tags):
"""
Get all the items from the vault without the 'content' (i.e: only name
and tags) that matches all the given tags.
:returns: The list of items
:type: list of dicts.
"""
return self.cab.get_by_tags(tags)
def get_tags(self):
"""
Get all the tags from the vault.
"""
tags = self.cab.get_tags()
print("Tags:", ','.join(tags))
def get_all(self):
"""
Get all the items from the vault without the 'content' (i.e: only name
and tags).
:returns: The list of items
:type: list of dicts.
"""
return self.cab.get_all()
def get_item(self, name, print_all):
"""
Get an item from the vault.
:param name: The name of the item to recover.
:type: str
:param print_all: Print all the information related to the item.
:type: bool
:returns: The item with the specified name.
:type: dict
"""
if self._ready:
item = self.cab.get(name)
if not item:
print('Item with name "{0}" not found!'.format(name))
return
if print_all:
print("Name: {0}\nTags: {1}\nContent: {2}"
.format(name, item['tags'], item['content']))
else:
print(item['content'])
def get_item_content(self, name):
"""
Get the content of an item from the vault.
:param name: The name of the item to recover.
:type: str
:returns: The item's content.
:type: str
"""
if self._ready:
item = self.cab.get(name)
if not item:
print('Item with name "{0}" not found!'.format(name))
return
return item['content']
def get_item_tags(self, name):
"""
Get the tags of an item from the vault.
:param name: The name of the item to recover.
:type: str
:returns: The item's tags.
:type: list
"""
if self._ready:
item = self.cab.get(name)
if not item:
print('Item with name "{0}" not found!'.format(name))
return
return item['tags']
def add_item(self, name, tags, content):
"""
Add an item to the vault.
:param item: The item's name
:type: str
:param tags: The item's tags
:type: list
:param content: The item's contents
:type: any
"""
if self._ready:
item = {
'name': name,
'tags': tags,
'content': content
}
self.cab.add(item)
def update(self, name, tags, content):
if self._ready:
self.cab.update(name, content, tags)
def rename(self, name, new_name):
if self._ready:
self.cab.rename(name, new_name)
def remove(self, name):
if self._ready:
self.cab.remove(name)
def search(self, tags, show_tags):
"""
Search for items with the given tags.
:param tags: the tags to search for
:type tags: list
:param show_tags: whether we should show the tags or not
:type show_tags: bool
"""
if not self._ready:
return
item_list = self.get_by_tags(tags)
for item in item_list:
line = "{0} \ttags: {1}"
tags = ", ".join(item['tags'])
print(line.format(item['name'], tags))