Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/test.ansible.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ name: Test-Ansible
on:
pull_request:
branches: [ master ]
paths:
- 'integration/keeper_secrets_manager_ansible/**'
- 'sdk/python/core/**'
- '.github/workflows/test.ansible.yml'

jobs:
test-ansible:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
import random
from enum import Enum
import traceback
import pickle
import io
import base64
import socket

Expand All @@ -37,6 +35,7 @@
from keeper_secrets_manager_core.core import KSMCache, CreateOptions
from keeper_secrets_manager_core.storage import FileKeyValueStorage, InMemoryKeyValueStorage
from keeper_secrets_manager_core.utils import generate_password as sdk_generate_password, strtobool
from keeper_secrets_manager_core.dto.dtos import Record as _Record, KeeperFile as _KeeperFile

# If keeper_secrets_manager_core is installed, then these will be installed. They are deps.
from cryptography.fernet import Fernet
Expand Down Expand Up @@ -306,16 +305,95 @@ def get_encryption_key(self):

return base64.urlsafe_b64encode(kdf.derive(cache_secret.encode()))

def encrypt(self, data):
@staticmethod
def _file_to_dict(keeper_file):
"""Serialize a KeeperFile instance to a JSON-safe dictionary."""
d = {
"name": keeper_file.name,
"title": keeper_file.title,
"type": keeper_file.type,
"last_modified": keeper_file.last_modified,
"size": keeper_file.size,
"f": keeper_file.f,
"file_key": keeper_file.file_key,
"meta_dict": keeper_file.meta_dict,
}
d["record_key_bytes"] = base64.b64encode(keeper_file.record_key_bytes).decode("ascii") \
if keeper_file.record_key_bytes is not None else None
d["file_data"] = base64.b64encode(keeper_file.file_data).decode("ascii") \
if keeper_file.file_data is not None else None
return d

@staticmethod
def _file_from_dict(d):
"""Reconstruct a KeeperFile instance from a JSON-deserialized dictionary."""
f = object.__new__(_KeeperFile)
f.name = d["name"]
f.title = d["title"]
f.type = d["type"]
f.last_modified = d["last_modified"]
f.size = d["size"]
f.f = d["f"]
f.file_key = d["file_key"]
f.meta_dict = d["meta_dict"]
f.record_key_bytes = base64.b64decode(d["record_key_bytes"]) \
if d["record_key_bytes"] is not None else None
f.file_data = base64.b64decode(d["file_data"]) \
if d["file_data"] is not None else None
return f

@staticmethod
def _record_to_dict(record):
"""Serialize a Record instance to a JSON-safe dictionary."""
d = {
"uid": record.uid,
"title": record.title,
"type": record.type,
"raw_json": record.raw_json,
"dict": record.dict,
"password": record.password,
"revision": record.revision,
"is_editable": record.is_editable,
"folder_uid": record.folder_uid,
"inner_folder_uid": record.inner_folder_uid,
"links": record.links,
"files": [KeeperAnsible._file_to_dict(f) for f in record.files],
}
d["record_key_bytes"] = base64.b64encode(record.record_key_bytes).decode("ascii") \
if record.record_key_bytes is not None else None
return d

@staticmethod
def _record_from_dict(d):
"""Reconstruct a Record instance from a JSON-deserialized dictionary."""
r = object.__new__(_Record)
r.uid = d["uid"]
r.title = d["title"]
r.type = d["type"]
r.raw_json = d["raw_json"]
r.dict = d["dict"]
r.password = d["password"]
r.revision = d["revision"]
r.is_editable = d["is_editable"]
r.folder_uid = d["folder_uid"]
r.inner_folder_uid = d["inner_folder_uid"]
r.links = d["links"]
r.record_key_bytes = base64.b64decode(d["record_key_bytes"]) \
if d["record_key_bytes"] is not None else None
r.files = [KeeperAnsible._file_from_dict(fd) for fd in d["files"]]
return r

def encrypt(self, data):
secret_key = self.get_encryption_key()
record_fh = io.BytesIO()
pickle.dump(data, record_fh)
return Fernet(secret_key).encrypt(record_fh.getvalue())
serializable = [KeeperAnsible._record_to_dict(r) for r in data]
json_bytes = json.dumps(serializable).encode("utf-8")
return Fernet(secret_key).encrypt(json_bytes)

def decrypt(self, ciphertext):
secret_key = self.get_encryption_key()
return pickle.loads(Fernet(secret_key).decrypt(ciphertext))
json_bytes = Fernet(secret_key).decrypt(ciphertext)
record_dicts = json.loads(json_bytes)
return [KeeperAnsible._record_from_dict(d) for d in record_dicts]

@staticmethod
def convert_records_into_dict(records):
Expand Down
2 changes: 1 addition & 1 deletion integration/keeper_secrets_manager_ansible/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

setup(
name="keeper-secrets-manager-ansible",
version='1.4.0',
version='1.5.0',
description="Keeper Secrets Manager plugins for Ansible.",
long_description=long_description,
long_description_content_type="text/markdown",
Expand Down
Loading