import sqlite3
from keepersdk.vault import (
sqlite_storage,
vault_online,
shares_management,
share_management_utils,
)
def build_shared_folder_info(vault, shared_folder_uid: str) -> dict:
sh_fol = vault.vault_data.load_shared_folder(shared_folder_uid)
if not sh_fol:
raise ValueError(f'Shared folder not found: {shared_folder_uid}')
sf_entity = vault.vault_data.storage.shared_folders.get_entity(shared_folder_uid)
sf_key = vault.vault_data.get_shared_folder_key(shared_folder_uid=shared_folder_uid)
if not sf_key:
raise ValueError(f'Could not resolve shared folder key: {shared_folder_uid}')
return {
'shared_folder_uid': shared_folder_uid,
'users': sh_fol.user_permissions,
'teams': [],
'records': [{'record_uid': r.record_uid} for r in sh_fol.record_permissions],
'shared_folder_key_unencrypted': sf_key,
'default_manage_users': sh_fol.default_manage_users,
'default_manage_records': sh_fol.default_manage_records,
'revision': sf_entity.revision if sf_entity else 0,
}
def share_folder(
keeper_auth_context,
*,
shared_folder_uid: str,
users: list[str] | None = None,
teams: list[str] | None = None,
record_uids: list[str] | None = None,
action: str = 'grant', # -a grant|remove
manage_records: str | None = 'on', # -p on|off
manage_users: str | None = 'off', # -o on|off
can_edit: str | None = 'on', # -d on|off
can_share: str | None = 'off', # -s on|off
default_account: bool = False, # -e '*'
default_record: bool = False, # -r '*'
expire_at: str | None = None, # --expire-at
expire_in: str | None = '7d', # --expire-in
rotate_on_expiration: bool = False, # -roe
):
"""
keepercliのshare-folderコマンドに相当するSDK処理です。
CLIの例:
share-folder -e user@example.com -p on -o off -d on -s off \
--expire-in 7d -roe -a grant IQ_folderUid
"""
conn = sqlite3.Connection('file::memory:', uri=True)
vault_storage = sqlite_storage.SqliteVaultStorage(
lambda: conn,
vault_owner=bytes(keeper_auth_context.auth_context.username, 'utf-8'),
)
vault = vault_online.VaultOnline(keeper_auth_context, vault_storage)
vault.sync_down()
try:
share_expiration = None
if action == shares_management.ShareAction.GRANT.value:
share_expiration = share_management_utils.get_share_expiration(
expire_at=expire_at,
expire_in=expire_in,
)
if rotate_on_expiration:
share_management_utils.validate_rotate_on_expiration(
share_expiration, rotate_on_expiration
)
if action != shares_management.ShareAction.GRANT.value:
raise share_management_utils.ShareValidationError(
'--rotate-on-expiration is only valid with --action grant'
)
share_management_utils.validate_folder_shares_rotate_on_expiration(
vault, [shared_folder_uid], rotate_on_expiration
)
sf_info = build_shared_folder_info(vault, shared_folder_uid)
request = shares_management.FolderShares.prepare_request(
vault=vault,
kwargs={
'action': action,
'manage_records': manage_records,
'manage_users': manage_users,
'can_edit': can_edit,
'can_share': can_share,
},
curr_sf=sf_info,
users=users or [],
teams=teams or [],
rec_uids=record_uids or [],
default_record=default_record,
default_account=default_account,
share_expiration=share_expiration,
rotate_on_expiration=rotate_on_expiration,
)
success, failed = shares_management.FolderShares.send_requests(vault, [[request]])
print('Success:', success)
print('Failed:', failed)
vault.sync_down()
return success, failed
except share_management_utils.ShareValidationError as err:
print(f'Validation error: {err}')
raise
finally:
vault.close()
keeper_auth_context.close()
# --- 使用例 ---
# 基本的な許可
# share_folder(auth, shared_folder_uid='IQ_...', users=['user@example.com'])
# ROE付きで許可
# share_folder(
# auth,
# shared_folder_uid='IQ_...',
# users=['contractor@example.com'],
# expire_in='7d',
# rotate_on_expiration=True,
# )
# チーム + 特定レコードへの許可
# share_folder(
# auth,
# shared_folder_uid='IQ_...',
# teams=['IQ_teamUid'],
# record_uids=['IQ_recordUid1', 'IQ_recordUid2'],
# manage_records='on',
# can_edit='on',
# can_share='off',
# )
# ユーザーを削除
# share_folder(
# auth,
# shared_folder_uid='IQ_...',
# users=['user@example.com'],
# action='remove',
# )
# 既定のフォルダ権限を設定 (-e '*' -r '*')
# share_folder(
# auth,
# shared_folder_uid='IQ_...',
# default_account=True,
# default_record=True,
# manage_records='on',
# manage_users='off',
# can_edit='on',
# can_share='off',
# )