Skip to content

Commit

Permalink
KSM-492 Added clone option (#565)
Browse files Browse the repository at this point in the history
  • Loading branch information
idimov-keeper authored Apr 12, 2024
1 parent a31bf92 commit 6725b7c
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class AliasedGroup(HelpColorsGroup):
"add",
"editor",
"field",
"clone",
"record",
"file",
"cache",
Expand Down Expand Up @@ -887,6 +888,32 @@ def secret_add_field_command(ctx, storage_folder_uid, record_type, title, passwo
print("", file=sys.stderr)


def validate_non_empty(ctx, param, value):
"""Validate that parameter's value is not an empty string"""
if isinstance(value, str) and value != "":
return value
raise click.BadParameter("Empty strings are not allowed")


@click.command(
name='clone',
cls=HelpColorsCommand,
help_options_color='blue'
)
@click.pass_context
@click.option('--uid', '-u', required=True, type=str, callback=validate_non_empty, help="Record UID to clone")
@click.option('--title', '-t', type=str, help="New record title")
def secret_add_clone_command(ctx, uid, title):
"""Add new record by duplicating existing record"""

ctx.obj["secret"].add_record_from_clone(
uid=uid,
title=title
)
print("", file=sys.stderr)


secret_add_command.add_command(secret_add_clone_command)
secret_add_command.add_command(secret_add_field_command)
secret_add_command.add_command(secret_add_file_command)
secret_add_command.add_command(secret_add_editor_command)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from keeper_secrets_manager_core.core import SecretsManager, CreateOptions, KeeperFolder
from keeper_secrets_manager_core.utils import get_totp_code, generate_password as sdk_generate_password
from keeper_secrets_manager_helper.record import Record
from keeper_secrets_manager_helper.v3.record import Record as RecordV3
from keeper_secrets_manager_helper.field_type import FieldType
from keeper_secrets_manager_helper.exception import FileSyntaxException
from .table import Table, ColumnAlign
Expand Down Expand Up @@ -746,6 +747,43 @@ def add_record_from_field_args(self, version, folder_uid, password_generate_flag
print("The following is the new record UID ...", file=sys.stderr)
return self.cli.output(record_uid)

def add_record_from_clone(self, uid: str, title: str):

record_uid = '' # new record UID
self._check_if_can_add_records()

try:
recs = self.cli.client.get_secrets([uid]) or []
if recs:
rec = recs[0]
if rec.folder_uid:
folder_options = CreateOptions(rec.folder_uid, rec.inner_folder_uid)
record_data = {
"version": "v3",
"kind": "KeeperRecord",
"data": [{
"recordType": rec.type,
"title": title if title else rec.title,
"notes": rec.dict.get("notes", ""),
"fields": rec.dict.get("fields", []),
"customFields": rec.dict.get("custom", [])
}]
}
records = RecordV3.create_from_data(record_data)
record = records[0]
record_create_obj = record.get_record_create_obj()
record_uid = self.cli.client.create_secret_with_options(folder_options, record_create_obj)
else:
print(f"Unable to find the parent shared folder for record {uid} - individually shared records cannot be cloned.", file=sys.stderr)
else:
print(f"Record UID not found {uid}", file=sys.stderr)
except Exception as err:
raise KsmCliException(f"{err}")

if record_uid:
print("The following is the new record UID ...", file=sys.stderr)
return self.cli.output(record_uid)

def build_folder_options(self, folder_uid: str, folders: List[KeeperFolder] = []) -> Tuple[CreateOptions, List[KeeperFolder]]:
""" Build and return folder create options and folders list """

Expand Down

0 comments on commit 6725b7c

Please sign in to comment.