def do_modify_secret(): stores_path, store_name, store_key, use_keyring = \ obtain_commons(positionals, options) secret_id = int( get_positional_or_prompt(positionals, 1, "ID of the secret to modify: ")) secret_data = options.get(Options.SECRET_DATA) store = Store(stores_path, store_name, store_key) open_store(store, update_keyring=use_keyring) # Secret data if secret_data is None: secret_mod = {} secret = store.secret(secret_id) if not secret: abort("Error: invalid secret ID; index out of bound") logging.debug(f"Will modify secret {secret}") print("Which field to modify?") choice = len(store.fields) max_length = 0 for f in store.fields: max_length = max(len(f.name), max_length) while choice >= len(store.fields): for i, f in enumerate(store.fields): s = str(i) + ") " + f.name.ljust(max_length) if f.name in secret: s += " (" + (secret[f.name] if not f.hidden else "*" * len(secret[f.name])) + ")" print(s) choice = int(input(": ")) changed_field = store.fields[choice] newval = prompt( "New value of '" + changed_field.name + "': ", secure=changed_field.hidden, double_check=True, double_check_prompt_text="New value of '" + changed_field.name + "' again: ", double_check_failed_message= "Double check failed, please insert the field again", until_valid=changed_field.mandatory) secret_mod[changed_field.name] = newval else: secret_mod = keyval_list_to_dict(secret_data.split(",")) if not store.modify_secret(secret_id, secret_mod): return False return store.save()
def do_destroy_store(): stores_path = obtain_stores_path(options) store_name = obtain_store_name(positionals) store = Store(stores_path, store_name) if not store.destroy(): return False # Remind to delete the keyring keyring_del_key(store_name) return True
def do_show_store(): stores_path, store_name, store_key, use_keyring = \ obtain_commons(positionals, options) fields = options.get(Options.STORE_FIELDS) if fields: fields = fields.split(",") store = Store(stores_path, store_name, store_key) open_store(store, update_keyring=use_keyring) return store.show(table=not options.get(Options.NO_TABLE), when=options.get(Options.WHEN), fields=fields, sort_by=options.get(Options.SORT) or options.get(Options.RSORT), reverse=options.get(Options.RSORT) is not None)
def do_remove_secret(): stores_path, store_name, store_key, use_keyring = \ obtain_commons(positionals, options) raw_secrets_ids = get_positional_or_prompt( positionals, 1, "ID of the secret(s) to remove: ", count=None) # Convert to list if is a string (took with input()) if isinstance(raw_secrets_ids, str): raw_secrets_ids = raw_secrets_ids.split(" ") secret_ids = [int(sid) for sid in raw_secrets_ids] store = Store(stores_path, store_name, store_key) open_store(store, update_keyring=use_keyring) if not store.remove_secrets(*secret_ids): return False return store.save()
def do_clear_store(): stores_path, store_name, store_key, use_keyring = \ obtain_commons(positionals, options) store = Store(stores_path, store_name, store_key) store.open() store.clear_secrets() return store.save()
def do_add_secret(): stores_path, store_name, store_key, use_keyring = \ obtain_commons(positionals, options) secret_data = options.get(Options.SECRET_DATA) store = Store(stores_path, store_name, store_key) open_store(store, update_keyring=use_keyring) if secret_data: secret = keyval_list_to_dict(secret_data.split(",")) secret_fields = [k.lower() for k in secret.keys()] # If there are already some fields, ask only the mandatory # (since this is probably non interactive mode and we won't # block the execution) missing_fields = [ f for f in store.fields if f.mandatory and f.name.lower() not in secret_fields ] else: secret = {} # Ask every field missing_fields = [f for f in store.fields] logging.debug( f"Missing fields to ask: {[f.name for f in missing_fields]}") for f in missing_fields: secret[f.name] = prompt( f.name + ": ", secure=f.hidden, double_check=True, double_check_prompt_text=f.name + " again: ", double_check_failed_message= "Double check failed, please insert the field again", until_valid=f.mandatory) if not store.add_secrets(secret): return False return store.save()
def do_create_store(): stores_path, store_name, store_key, use_keyring = \ obtain_commons(positionals, options, ensure_existence=False, allow_keyring=False) # Store fields raw_store_fields = options.get(Options.STORE_FIELDS) if raw_store_fields is None: raw_store_fields = [] i = 1 print( "\n" "Insert store fields with format <name>[+<attr_1><attr_2>...].\n" "Available attributes are:\n" "+ m (mandatory)\n" "+ h (hidden)\n" "(Leave empty for terminate the fields insertion)\n") while True: f = input(f"{i} ° field: ") if not f: break raw_store_fields.append(f) i += 1 store_fields = [] for raw_field in raw_store_fields: field_parts = raw_field.split("+") fieldname = field_parts[0] fieldattributes = field_parts[1] if len(field_parts) > 1 else [] store_fields.append( StoreField(fieldname, hidden=SecretAttributes.HIDDEN in fieldattributes, mandatory=SecretAttributes.MANDATORY in fieldattributes)) store = Store(stores_path, store_name, store_key) store.add_fields(*store_fields) return store.save()
def do_grep_secret(): stores_path, store_name, store_key, use_keyring = \ obtain_commons(positionals, options) grep_pattern = get_positional_or_prompt(positionals, 1, "Search pattern: ") fields = options.get(Options.STORE_FIELDS) if fields: fields = fields.split(",") store = Store(stores_path, store_name, store_key) open_store(store, update_keyring=use_keyring) return store.grep(grep_pattern, fields=fields, colors=not options.get(Options.NO_COLOR), table=not options.get(Options.NO_TABLE), when=options.get(Options.WHEN), sort_by=options.get(Options.SORT) or options.get(Options.RSORT), reverse=options.get(Options.RSORT) is not None)
def do_change_store_key(): stores_path, store_name, store_key, use_keyring = \ obtain_commons(positionals, options) new_store_key = get_positional_or_prompt(positionals, 1, "New store key: ", secure=True, double_check=True) store = Store(stores_path, store_name, store_key) store.open() new_store = Store(stores_path, store_name, new_store_key) new_store.clone_content(store) if not new_store.save(): return False # Remind to delete the keyring keyring_del_key(store_name) return True