def get(params, uid): try: prompt_for_credentials(params) api.sync_down(params) if uid: api.get_record(params, uid).display() except Exception as e: raise click.ClickException(e)
def build_hash_dict(params, tokenize_gen): """Return a dict of hashes to record uid's with a parameterized tokenizing generator.""" preexisting_record_hash = {} for preexisting_r_uid in params.record_cache: preexisting_rec = api.get_record(params, preexisting_r_uid) preexisting_record_hash[build_record_hash(preexisting_rec, tokenize_gen)] = preexisting_r_uid return preexisting_record_hash
def create_or_update_record(params, criteria): # Scan vault for shared folder sfs = api.search_shared_folders(params, criteria) if len(sfs) == 0: print(f'Shared folder {criteria} not found') return shared_folder = sfs[0] record_title = 'Test Record' record_uid = None if shared_folder.records: records = [api.get_record(params, x['record_uid']) for x in shared_folder.records] record_uid = next((x.record_uid for x in records if x.title.casefold() == record_title.casefold()), None) shared_folder_uid = shared_folder.shared_folder_uid if record_uid: command = RecordEditCommand() command.execute(params, record=record_uid, generate=True) print(f'Updated record {record_uid} in shared folder uid={shared_folder_uid}') else: command = RecordAddCommand() # Inputs - hard coded for demo purposes record_uid = command.execute( params, title='Test Record', login='******', folder=shared_folder_uid, generate=True, # force=True disables asking for missing fields force=True) print(f'Added record {record_uid} to shared folder uid={shared_folder_uid}')
def test_upload_attachment_command(self): params = get_synced_params() cmd = recordv2.RecordUploadAttachmentCommand() record_uid = next( iter([ x['record_uid'] for x in params.record_cache.values() if len(x['extra_unencrypted']) > 10 ])) rec = api.get_record(params, record_uid) with self.assertRaises(CommandError): cmd.execute(params, record=rec.title) def request_upload(rq): self.assertEqual(rq['command'], 'request_upload') return { 'file_uploads': [{ 'max_size': 1000000, 'url': 'https://keepersecurity.com/uploads/', 'success_status_code': 201, 'file_id': 'ABCDEF%.2d' % x, 'file_parameter': 'file', 'parameters': { 'a': 'b' } } for x in range((rq.get('file_count') or 0) + (rq.get('thumbnail_count') or 0))] } def request_http_post(url, **kwargs): attachment = mock.Mock() attachment.status_code = 201 return attachment with mock.patch('requests.post', side_effect=request_http_post), \ mock.patch('builtins.open', mock.mock_open(read_data=b'data')) as m_open, \ mock.patch('os.path.isfile', return_value=True), \ mock.patch('os.path.getsize') as mock_getsize: m_open.return_value.tell = lambda: 4 mock_getsize.return_value = 1000000000 with self.assertRaises(CommandError): KeeperApiHelper.communicate_expect([request_upload]) cmd.execute(params, file=['file.data'], record=record_uid) self.assertTrue(KeeperApiHelper.is_expect_empty()) KeeperApiHelper.communicate_expect( [request_upload, 'record_update']) m_open.return_value.tell = lambda: 4 mock_getsize.return_value = 1000 cmd.execute(params, file=['file.data'], record=record_uid) self.assertTrue(KeeperApiHelper.is_expect_empty())
def test_delete_attachment_command(self): params = get_synced_params() cmd = recordv2.RecordDeleteAttachmentCommand() record_uid = next( iter([ x['record_uid'] for x in params.record_cache.values() if len(x['extra_unencrypted']) > 10 ])) rec = api.get_record(params, record_uid) KeeperApiHelper.communicate_expect(['record_update']) cmd.execute(params, name=[rec.attachments[0]['id']], record=rec.title) self.assertTrue(KeeperApiHelper.is_expect_empty())
def test_remove_command_from_root(self): params = get_synced_params() cmd = recordv2.RecordRemoveCommand() record_uid = next(iter(params.subfolder_record_cache[''])) rec = api.get_record(params, record_uid) def pre_delete_command(rq): self.assertEqual(rq['command'], 'pre_delete') return { 'pre_delete_response': { 'would_delete': { 'deletion_summary': ['delete all'] }, 'pre_delete_token': 'token' } } with mock.patch('keepercommander.commands.recordv2.user_choice' ) as choice_mock: choice_mock.return_value = KeyboardInterrupt() KeeperApiHelper.communicate_expect([pre_delete_command, 'delete']) cmd.execute(params, force=True, record=rec.record_uid) self.assertTrue(KeeperApiHelper.is_expect_empty()) KeeperApiHelper.communicate_expect([pre_delete_command, 'delete']) cmd.execute(params, force=True, record=rec.title) self.assertTrue(KeeperApiHelper.is_expect_empty()) with mock.patch('builtins.print'): choice_mock.return_value = 'y' KeeperApiHelper.communicate_expect( [pre_delete_command, 'delete']) cmd.execute(params, record=rec.record_uid) self.assertTrue(KeeperApiHelper.is_expect_empty()) KeeperApiHelper.communicate_expect( [pre_delete_command, 'delete']) cmd.execute(params, record=rec.title) self.assertTrue(KeeperApiHelper.is_expect_empty()) choice_mock.return_value = 'n' KeeperApiHelper.communicate_expect([pre_delete_command]) cmd.execute(params, record=rec.record_uid) self.assertTrue(KeeperApiHelper.is_expect_empty()) KeeperApiHelper.communicate_expect([pre_delete_command]) cmd.execute(params, record=rec.title) self.assertTrue(KeeperApiHelper.is_expect_empty())
def export(params, format, filename): api.sync_down(params) records = [api.get_record(params, record_uid) for record_uid in params.record_cache] records.sort(key=lambda x: ((x.folder if x.folder else ' ') + x.title).lower(), reverse=False) if format == 'json': with open(filename, mode="w", encoding="utf8") as f: json.dump([record.to_dictionary() for record in records], f, indent=2, ensure_ascii=False) else: with open(filename, mode="wt", encoding="utf8") as f: for record in records: f.write(record.to_tab_delimited() + '\n') print('{0} records exported to {1}'.format(len(records), filename))
def export(params, format, filename): api.sync_down(params) records = [api.get_record(params, record_uid) for record_uid in params.record_cache if params.meta_data_cache[record_uid]['owner']] records.sort(key=lambda x: ((x.folder if x.folder else ' ') + x.title).lower(), reverse=False) if format == 'json': with open(filename, 'w') as f: json.dump([record.to_dictionary() for record in records], f, indent=2) else: with open(filename, 'wt') as f: for record in records: f.write(record.to_tab_delimited() + '\n') print('{0} records exported to {1}'.format(len(records), filename))
def export(params, format, filename): api.sync_down(params) records = [api.get_record(params, record_uid) for record_uid in params.record_cache if params.meta_data_cache[record_uid]['owner']] records.sort(key=lambda x: ((x.folder if x.folder else ' ') + x.title).lower(), reverse=False) if format == 'json': with open(filename, 'w') as f: json.dump([record.to_dictionary() for record in records], f, indent=2) else: with open(filename, 'wt') as f: for record in records: f.write(record.to_tab_delimited() + '\n') print(('{0} records exported to {1}'.format(len(records), filename)))
password = sys.argv[2] except IndexError: try: password = os.environ['password'] except KeyError: from getpass import getpass password = getpass('Password:'******'user': user, 'password': password} params = params.KeeperParams() # config=config) params.user = user params.password = password session_token = api.login(params) # extractor = URLExtract() with open(f"{__file__}.output", mode='a') as o_f: for record_uid in params.record_cache: rec = api.get_record(params, record_uid) try: base_url = extract_base(rec.login_url) except (MatchError, IndexError): logger.debug( f"Login URL ({rec.login_url}) error at record uid: {record_uid}" ) # base_url = ('', '') else: # title = rec.title home_url = '://'.join(base_url) # urls_in_title = extractor.find_urls(rec.title) for url_in_title in urls_in_title: # if not title: # if title is empty # print("No title at record_uid:%s" % record_uid) # res.encoding = res.apparent_encoding() # req = request.Request(home_url) # with request.urlopen(req) as res:
except KeyError: user = input("User:"******"Exitting because of over repeat limit {repeat}") break rec = api.get_record(params, uid) if rec.login_url == sn_url: rec.login_url = '' # set string empty api.update_record(params, rec) logger.info(f"sn_url is erased at {uid} : {rec.title}") exit(0) # to suppress warning of 'Exit without exit code'
params.password = params.config['password'] if 'device_id' in params.config: device_id = base64.urlsafe_b64decode( params.config['device_id'] + '==') params.rest_context.device_id = device_id my_params = KeeperParams() read_config_file(my_params) while not my_params.user: my_params.user = getpass.getpass(prompt='User(Email): ', stream=None) while not my_params.password: my_params.password = getpass.getpass(prompt='Master Password: '******'Record UID: ', stream=None) api.sync_down(my_params) # See record.py for available fields # or call display.formatted_records(record) to show all record details record = api.get_record(my_params, record_uid) if record: print('Record Password: '******'No record found with that UID')
def test_vault_commands(self): params = TestConnectedCommands.params # type: KeeperParams with mock.patch( 'builtins.input', side_effect=KeyboardInterrupt()), mock.patch('builtins.print'): cli.do_command( params, 'add --login="******" --pass=password --url="https://keepersecurity.com/" --custom="{\\"cmdr:plugin\\":\\"noop\\"}" "Record 1"' ) cli.do_command(params, 'sync-down') record_uid = next(iter(params.record_cache.keys())) rec = api.get_record(params, record_uid) self.assertEqual(rec.get('cmdr:plugin'), 'noop') old_password = rec.password cli.do_command(params, 'r -- {0}'.format(rec.record_uid)) cli.do_command(params, 'sync-down') rec = api.get_record(params, record_uid) self.assertNotEqual(old_password, rec.password) cli.do_command(params, 'ls -l') cli.do_command(params, 'mkdir --user-folder "User Folder 1"') cli.do_command(params, 'mkdir --shared-folder --all "Shared Folder 1"') cli.do_command(params, 'sync-down') cli.do_command(params, 'cd "User Folder 1"') cli.do_command(params, 'mkdir --user-folder "User Folder 2"') cli.do_command(params, 'cd /') cli.do_command(params, 'ln "Record 1" "Shared Folder 1"') cli.do_command(params, 'mv "Record 1" "User Folder 1"') params.revision = 0 cli.do_command(params, 'sync-down') self.assertEqual(len(params.record_cache), 1) self.assertEqual(len(params.shared_folder_cache), 1) cli.do_command(params, 'cd "Shared Folder 1"') cli.do_command( params, 'append-notes --notes="Additional info" "Record 1"') cli.do_command(params, 'sync-down') cli.do_command(params, 'cd "../User Folder 1"') cli.do_command(params, 'rmdir --force "User Folder 2"') cli.do_command(params, 'sync-down') cli.do_command(params, 'cd /') cli.do_command(params, 'search record') cli.do_command(params, 'search folder') with tempfile.NamedTemporaryFile() as f: f.write(b'data') f.flush() cli.do_command(params, 'cd "User Folder 1"') cli.do_command( params, 'upload-attachment --file="{0}" "Record 1"'.format(f.name)) cli.do_command(params, 'sync-down') with mock.patch('builtins.open', mock.mock_open()) as m_open, mock.patch( 'os.path.abspath', return_value='file/path'): cli.do_command(params, 'download-attachment -- {0}'.format(record_uid)) m_open.assert_called() m_open.return_value.write.assert_called() rec = api.get_record(params, record_uid) self.assertEqual(len(rec.attachments), 1) cli.do_command( params, 'delete-attachment --name={0} -- {1}'.format( rec.attachments[0]['id'], record_uid)) cli.do_command(params, 'sync-down') rec = api.get_record(params, record_uid) self.assertEqual(len(rec.attachments), 0) json_text = '' with mock.patch('builtins.open', mock.mock_open()) as m_open, mock.patch( 'os.path.abspath', return_value='file/path'): def file_write(text): nonlocal json_text json_text += text m_open.return_value.write = file_write cli.do_command(params, 'export --format=json file') self.assertTrue(len(json_text) > 0) exported = json.loads(json_text) self.assertEqual(len(params.record_cache), len(exported['records'])) self.assertEqual(len(params.shared_folder_cache), len(exported['shared_folders'])) TestConnectedCommands.wipe_out_data() with mock.patch('builtins.open', mock.mock_open()) as m_open, mock.patch( 'os.path.isfile', return_value=True): def file_read(): nonlocal json_text return json_text m_open.return_value.read = file_read cli.do_command(params, 'import --format=json file') self.assertEqual(len(params.record_cache), len(exported['records'])) self.assertEqual(len(params.shared_folder_cache), len(exported['shared_folders']))
def export(params, file_format, filename, **export_args): api.sync_down(params) exporter = exporter_for_format(file_format)() # type: BaseExporter if export_args: if 'max_size' in export_args: exporter.max_size = int(export_args['max_size']) to_export = [] if exporter.has_shared_folders(): shfolders = [ api.get_shared_folder(params, sf_uid) for sf_uid in params.shared_folder_cache ] shfolders.sort(key=lambda x: x.name.lower(), reverse=False) for f in shfolders: fol = ImportSharedFolder() fol.uid = f.shared_folder_uid fol.path = get_folder_path(params, f.shared_folder_uid) fol.manage_users = f.default_manage_users fol.manage_records = f.default_manage_records fol.can_edit = f.default_can_edit fol.can_share = f.default_can_share fol.permissions = [] if f.teams: for team in f.teams: perm = ImportPermission() perm.uid = team['team_uid'] perm.name = team['name'] perm.manage_users = team['manage_users'] perm.manage_records = team['manage_records'] fol.permissions.append(perm) if f.users: for user in f.users: perm = ImportPermission() perm.name = user['username'] perm.manage_users = user['manage_users'] perm.manage_records = user['manage_records'] fol.permissions.append(perm) to_export.append(fol) sf_count = len(to_export) records = [ api.get_record(params, record_uid) for record_uid in params.record_cache ] records.sort(key=lambda x: x.title.lower(), reverse=False) for r in records: rec = ImportRecord() rec.uid = r.record_uid rec.title = r.title.strip('\x00') if r.title else '' rec.login = r.login.strip('\x00') if r.login else '' rec.password = r.password.strip('\x00') if r.password else '' rec.login_url = r.login_url.strip('\x00') if r.login_url else '' rec.notes = r.notes.strip('\x00') if r.notes else '' for cf in r.custom_fields: name = cf.get('name') value = cf.get('value') if name and value: rec.custom_fields[name] = value if r.totp: rec.custom_fields[TWO_FACTOR_CODE] = r.totp for folder_uid in find_folders(params, r.record_uid): if folder_uid in params.folder_cache: folder = get_import_folder(params, folder_uid, r.record_uid) if rec.folders is None: rec.folders = [] rec.folders.append(folder) if exporter.has_attachments() and r.attachments: rec.attachments = [] names = set() for a in r.attachments: orig_name = a.get('title') or a.get('name') or 'attachment' name = orig_name counter = 0 while name in names: counter += 1 name = "{0}-{1}".format(orig_name, counter) names.add(name) atta = KeeperAttachment(params, rec.uid) atta.file_id = a['id'] atta.name = name atta.size = a['size'] atta.key = base64.urlsafe_b64decode(a['key'] + '==') atta.mime = a.get('type') or '' rec.attachments.append(atta) to_export.append(rec) rec_count = len(to_export) - sf_count if len(to_export) > 0: exporter.execute(filename, to_export) params.queue_audit_event('exported_records', file_format=file_format) logging.info('%d records exported', rec_count)
def prepare_record_add(params, records): record_hash = {} for r_uid in params.record_cache: rec = api.get_record(params, r_uid) h = hashlib.sha256() for token in tokenize_record(rec): h.update(token.encode()) record_hash[h.hexdigest()] = r_uid record_adds = [] for rec in records: h = hashlib.sha256() for token in tokenize_import_record(rec): h.update(token.encode()) r_hash = h.hexdigest() if r_hash in record_hash: rec.uid = record_hash[r_hash] else: rec.uid = api.generate_record_uid() record_hash[r_hash] = rec.uid record_key = os.urandom(32) rec_req = folder_pb2.RecordRequest() rec_req.recordUid = base64.urlsafe_b64decode(rec.uid + '==') rec_req.recordType = 0 rec_req.encryptedRecordKey = base64.urlsafe_b64decode( api.encrypt_aes(record_key, params.data_key) + '==') rec_req.howLongAgo = 0 rec_req.folderType = 1 folder_uid = None if rec.folders: folder_uid = rec.folders[0].uid if folder_uid: if folder_uid in params.folder_cache: folder = params.folder_cache[folder_uid] if folder.type in { BaseFolderNode.SharedFolderType, BaseFolderNode.SharedFolderFolderType }: rec_req.folderUid = base64.urlsafe_b64decode( folder.uid + '==') rec_req.folderType = 2 if folder.type == BaseFolderNode.SharedFolderType else 3 sh_uid = folder.uid if folder.type == BaseFolderNode.SharedFolderType else folder.shared_folder_uid sf = params.shared_folder_cache[sh_uid] rec_req.encryptedRecordFolderKey = base64.urlsafe_b64decode( api.encrypt_aes( record_key, sf['shared_folder_key_unencrypted']) + '==') else: rec_req.folderType = 1 if folder.type != BaseFolderNode.RootFolderType: rec_req.folderUid = base64.urlsafe_b64decode( folder.uid + '==') custom_fields = [] totp = None if rec.custom_fields: for cf in rec.custom_fields: if cf == TWO_FACTOR_CODE: totp = rec.custom_fields[cf] else: custom_fields.append({ 'name': cf, 'value': rec.custom_fields[cf] }) data = { 'title': rec.title or '', 'secret1': rec.login or '', 'secret2': rec.password or '', 'link': rec.login_url or '', 'notes': rec.notes or '', 'custom': custom_fields } rec_req.recordData = base64.urlsafe_b64decode( api.encrypt_aes(json.dumps(data).encode('utf-8'), record_key) + '==') if totp: extra = { 'fields': [{ 'id': api.generate_record_uid(), 'field_type': 'totp', 'field_title': 'Two-Factor Code', 'type': 0, 'data': totp }] } rec_req.extra = base64.urlsafe_b64decode( api.encrypt_aes( json.dumps(extra).encode('utf-8'), record_key) + '==') record_adds.append(rec_req) return record_adds
def test_commands(self): params = TestConnectedCommands.params # type: KeeperParams with mock.patch( 'builtins.input', side_effect=KeyboardInterrupt()), mock.patch('builtins.print'): record_uid = cli.do_command( params, 'add --legacy --login="******" --pass=password --url="https://keepersecurity.com/" --custom="{\\"cmdr:plugin\\":\\"noop\\"}" --title="Record 1"' ) cli.do_command(params, 'sync-down') rec = api.get_record(params, record_uid) self.assertEqual(rec.get('cmdr:plugin'), 'noop') old_password = rec.password cli.do_command(params, 'rotate -- {0}'.format(rec.record_uid)) cli.do_command(params, 'sync-down') rec = api.get_record(params, record_uid) self.assertNotEqual(old_password, rec.password) cli.do_command(params, 'ls -l') cli.do_command(params, 'mkdir --user-folder "User Folder 1"') cli.do_command(params, 'mkdir --shared-folder --all "Shared Folder 1"') cli.do_command(params, 'sync-down') cli.do_command(params, 'cd "User Folder 1"') cli.do_command(params, 'mkdir --user-folder "User Folder 2"') cli.do_command(params, 'cd /') cli.do_command(params, 'ln "Record 1" "Shared Folder 1"') cli.do_command(params, 'mv "Record 1" "User Folder 1"') params.revision = 0 cli.do_command(params, 'sync-down') self.assertEqual(len(params.record_cache), 1) self.assertEqual(len(params.shared_folder_cache), 1) cli.do_command(params, 'cd "Shared Folder 1"') cli.do_command( params, 'append-notes --notes="Additional info" "Record 1"') cli.do_command(params, 'sync-down') cli.do_command(params, 'cd "../User Folder 1"') cli.do_command(params, 'rmdir --force "User Folder 2"') cli.do_command(params, 'sync-down') cli.do_command(params, 'cd /') cli.do_command(params, 'search record') cli.do_command(params, 'search folder') with tempfile.NamedTemporaryFile(delete=False) as f: try: f.write(b'data') f.flush() cli.do_command(params, 'cd "User Folder 1"') cli.do_command( params, 'upload-attachment --file="{0}" "Record 1"'.format( f.name)) f.close() finally: os.remove(f.name) cli.do_command(params, 'sync-down') rec = api.get_record(params, record_uid) self.assertEqual(len(rec.attachments), 1) cli.do_command( params, 'delete-attachment --name={0} -- {1}'.format( rec.attachments[0]['id'], record_uid)) cli.do_command(params, 'sync-down') rec = api.get_record(params, record_uid) self.assertEqual(len(rec.attachments), 0) script_path = os.path.dirname(__file__) cwd = os.getcwd() if script_path.startswith(cwd): script_path = script_path[len(cwd):] if script_path.startswith(os.sep): script_path = script_path[1:] file = 'keepass.kdbx' if script_path: file = os.path.join(script_path, file) if os.path.isfile(file): os.remove(file) with mock.patch('getpass.getpass', return_value='password'), mock.patch( 'keepercommander.commands.base.user_choice', return_value='y'): cli.do_command(params, 'export --format=keepass "{0}"'.format(file)) TestConnectedCommands.wipe_out_data() cli.do_command(params, 'sync-down') with mock.patch('getpass.getpass', return_value='password'), mock.patch( 'builtins.input', return_value=''): cli.do_command(params, 'import --format=keepass "{0}"'.format(file)) cli.do_command(params, 'sync-down') json_text = '' with mock.patch('builtins.open', mock.mock_open()) as m_open, mock.patch( 'os.path.abspath', return_value='file/path'): def file_write(text): nonlocal json_text json_text += text m_open.return_value.write = file_write cli.do_command(params, 'export --format=json file') self.assertTrue(len(json_text) > 0) exported = json.loads(json_text) self.assertEqual(len(params.record_cache), len(exported['records'])) self.assertEqual(len(params.shared_folder_cache), len(exported['shared_folders'])) TestConnectedCommands.wipe_out_data() with mock.patch('builtins.open', mock.mock_open()) as m_open, mock.patch( 'os.path.isfile', return_value=True): def file_read(): nonlocal json_text return json_text m_open.return_value.read = file_read cli.do_command(params, 'import --format=json file') self.assertEqual(len(params.record_cache), len(exported['records'])) self.assertEqual(len(params.shared_folder_cache), len(exported['shared_folders']))
def prepare_record_add(params, records): record_hash = {} for r_uid in params.record_cache: rec = api.get_record(params, r_uid) h = hashlib.md5() hs = '{0}|{1}|{2}'.format(rec.title or '', rec.login or '', rec.password or '') h.update(hs.encode()) record_hash[h.hexdigest()] = r_uid record_adds = [] for rec in records: h = hashlib.md5() hs = '{0}|{1}|{2}'.format(rec.title or '', rec.login or '', rec.password or '') h.update(hs.encode()) rec_hash = h.hexdigest() record_uid = record_hash.get(rec_hash) if record_uid is None: record_key = os.urandom(32) record_uid = api.generate_record_uid() req = { 'command': 'record_add', 'record_uid': record_uid, 'record_type': 'password', 'record_key': api.encrypt_aes(record_key, params.data_key), 'how_long_ago': 0, 'folder_type': 'user_folder' } folder_uid = None if rec.folders: if len(rec.folders) > 0: folder_uid = rec.folders[0].uid if folder_uid: if folder_uid in params.folder_cache: folder = params.folder_cache[folder_uid] if folder.type in { BaseFolderNode.SharedFolderType, BaseFolderNode.SharedFolderFolderType }: req['folder_uid'] = folder.uid req['folder_type'] = 'shared_folder' if folder.type == BaseFolderNode.SharedFolderType else 'shared_folder_folder' sh_uid = folder.uid if folder.type == BaseFolderNode.SharedFolderType else folder.shared_folder_uid sf = params.shared_folder_cache[sh_uid] req['folder_key'] = api.encrypt_aes( record_key, sf['shared_folder_key_unencrypted']) if 'key_type' not in sf: if 'teams' in sf: for team in sf['teams']: req['team_uid'] = team['team_uid'] if team['manage_records']: break else: req['folder_type'] = 'user_folder' if folder.type != BaseFolderNode.RootFolderType: req['folder_uid'] = folder.uid custom_fields = [] if rec.custom_fields: for cf in rec.custom_fields: custom_fields.append({ 'name': cf, 'value': rec.custom_fields[cf] }) data = { 'title': rec.title or '', 'secret1': rec.login or '', 'secret2': rec.password or '', 'link': rec.login_url or '', 'notes': rec.notes or '', 'custom': custom_fields } req['data'] = api.encrypt_aes( json.dumps(data).encode('utf-8'), record_key) record_adds.append(req) rec.uid = record_uid return record_adds
def do_command(params): if (params.command == 'q'): return False elif (params.command == 'l'): if (len(params.record_cache) == 0): print('No records') else: results = api.search_records(params, '') display.formatted_records(results) elif (params.command == 'lsf'): if (len(params.shared_folder_cache) == 0): print('No shared folders') else: results = api.search_shared_folders(params, '') display.formatted_shared_folders(results) elif (params.command[:2] == 'g '): if (api.is_shared_folder(params, params.command[2:])): sf = api.get_shared_folder(params, params.command[2:]) if sf: sf.display() else: r = api.get_record(params, params.command[2:]) if r: r.display() elif (params.command[:2] == 'r '): api.rotate_password(params, params.command[2:]) elif (params.command[:2] == 'd '): api.delete_record(params, params.command[2:]) elif (params.command == 'c'): print(chr(27) + "[2J") elif (params.command[:2] == 's '): results = api.search_records(params, params.command[2:]) display.formatted_records(results) elif (params.command[:2] == 'b '): results = api.search_records(params, params.command[2:]) for r in results: api.rotate_password(params, r.record_uid) elif (params.command[:3] == 'an '): api.append_notes(params, params.command[3:]) elif (params.command == 'd'): api.sync_down(params) elif (params.command == 'a'): api.add_record(params) elif (params.command == 'h'): display.formatted_history(stack) elif (params.command == 'debug'): if params.debug: params.debug = False print('Debug OFF') else: params.debug = True print('Debug ON') elif params.command == '': pass else: print('\n\nCommands:\n') print(' d ... download & decrypt data') print(' l ... list folders and titles') print(' lsf ... list shared folders') print(' s <regex> ... search with regular expression') print(' g <uid> ... get record or shared folder details for uid') print(' r <uid> ... rotate password for uid') print( ' b <regex> ... rotate password for matches of regular expression' ) print(' a ... add a new record interactively') print(' an <uid> ... append some notes to the specified record') print(' c ... clear the screen') print(' h ... show command history') print(' q ... quit') print('') if params.command: if params.command != 'h': stack.append(params.command) stack.reverse() return True
def do_command(params): if (params.command == 'q'): return False elif (params.command == 'l'): if (len(params.record_cache) == 0): print('No records') else: results = api.search_records(params, '') display.formatted_records(results) elif (params.command[:2] == 'g '): r = api.get_record(params, params.command[2:]) if r: r.display() elif (params.command[:2] == 'r '): api.rotate_password(params, params.command[2:]) elif (params.command == 'c'): print(chr(27) + "[2J") elif (params.command[:2] == 's '): results = api.search_records(params, params.command[2:]) display.formatted_records(results) elif (params.command[:2] == 'b '): results = api.search_records(params, params.command[2:]) for r in results: api.rotate_password(params, r.record_uid) elif (params.command == 'd'): api.sync_down(params) elif (params.command == 'a'): api.add_record(params) elif (params.command == 'h'): display.formatted_history(stack) elif (params.command == 'debug'): if params.debug: params.debug = False print('Debug OFF') else: params.debug = True print('Debug ON') elif params.command == '': pass else: print('\n\nCommands:\n') print(' d ... download & decrypt data') print(' l ... list folders and titles') print(' s <regex> ... search with regular expression') print(' g <uid> ... get record details for uid') print(' r <uid> ... rotate password for uid') print(' b <regex> ... rotate password for matches of regular expression') print(' a ... add a new record interactively') print(' c ... clear the screen') print(' h ... show command history') print(' q ... quit') print('') if params.command: if params.command != 'h': stack.append(params.command) stack.reverse() return True
def do_command(params): if (params.command == 'q'): return False elif (params.command == 'l'): if (len(params.record_cache) == 0): print('No records') else: results = api.search_records(params, '') display.formatted_records(results) elif (params.command == 'lsf'): if (len(params.shared_folder_cache) == 0): print('No shared folders') else: results = api.search_shared_folders(params, '') display.formatted_shared_folders(results) elif (params.command == 'lt'): if (len(params.team_cache) == 0): print('No teams') else: results = api.search_teams(params, '') display.formatted_teams(results) elif (params.command[:2] == 'g '): if (api.is_shared_folder(params, params.command[2:])): sf = api.get_shared_folder(params, params.command[2:]) if sf: sf.display() elif (api.is_team(params, params.command[2:])): team = api.get_team(params, params.command[2:]) if team: team.display() else: r = api.get_record(params, params.command[2:]) if r: r.display() elif (params.command[:2] == 'r '): api.rotate_password(params, params.command[2:]) elif (params.command[:2] == 'd '): api.delete_record(params, params.command[2:]) elif (params.command == 'c'): print(chr(27) + "[2J") elif (params.command[:2] == 's '): results = api.search_records(params, params.command[2:]) display.formatted_records(results) elif (params.command[:2] == 'b '): results = api.search_records(params, params.command[2:]) for r in results: api.rotate_password(params, r.record_uid) elif (params.command[:3] == 'an '): api.append_notes(params, params.command[3:]) elif (params.command == 'd'): api.sync_down(params) elif (params.command == 'a'): record = Record() while not record.title: record.title = input("... Title (req'd): ") record.folder = input("... Folder: ") record.login = input("... Login: "******"... Password: "******"... Login URL: ") record.notes = input("... Notes: ") while True: custom_dict = {} custom_dict['name'] = input("... Custom Field Name : ") if not custom_dict['name']: break custom_dict['value'] = input("... Custom Field Value : ") custom_dict['type'] = 'text' record.custom_fields.append(custom_dict) api.add_record(params, record) elif (params.command == 'h'): display.formatted_history(stack) elif (params.command == 'debug'): if params.debug: params.debug = False print('Debug OFF') else: params.debug = True print('Debug ON') elif params.command == '': pass else: print('\n\nShell Commands:\n') print(' d ... download & decrypt data') print(' l ... list folders and record titles') print(' lsf ... list shared folders') print(' lt ... list teams') print(' s <regex> ... search with regular expression') print(' g <uid> ... get record or shared folder details for uid') print(' r <uid> ... rotate password for uid') print( ' b <regex> ... rotate password for matches of regular expression' ) print(' a ... add a new record interactively') print(' an <uid> ... append some notes to the specified record') print(' c ... clear the screen') print(' h ... show command history') print(' q ... quit') print('') if params.command: if params.command != 'h': stack.append(params.command) stack.reverse() return True