diff --git a/Dynamic Folder/1Password/1Password (Python).rdfe b/Dynamic Folder/1Password/1Password (Python).rdfe deleted file mode 100644 index d5da20b..0000000 --- a/Dynamic Folder/1Password/1Password (Python).rdfe +++ /dev/null @@ -1,77 +0,0 @@ -{ - "Name": "Dynamic Folder Export", - "Objects": [ - { - "Type": "DynamicFolder", - "Name": "1Password (Python)", - "Description": "This Dynamic Folder sample allows you to import dynamic credentials from 1Password.", - "Notes": "\n\n\n

1Password Dynamic Folder sample

\n\n

Version: 2.0.5
\nAuthor: Royal Apps

\n\n

This Dynamic Folder sample allows you to import credentials from 1Password. The 1Password command-line tool is required and the path where it is installed must be configured in the "Custom Properties" section. Also, your 1Password login details must be provided in the "Login" section of the custom properties.

\n\n

Items are imported as Dynamic Credentials. This means that the username and password fields will remain empty after reloading the dynamic folder and only be requested when a connection is established that uses one of the credentials of this dynamic folder. While you can instruct the script to import regular credentials (by setting the "Dynamic Credentials" setting in the "Custom Properties" section to "No", it's not(!) recommended to do so as it has many downsides. For instance, it will take much longer to retrieve all items because a web request to 1Password's web service will need to be made for each individual item. 1Password also enforces API rate limits, so if you have a lot of items, you might not be able to retrieve all of them before hitting the rate limit.

\n\n

By default, items of all vaults are imported. If you only want to retrieve items of a specific vault, you can configure the vault's name in the "Filter" section of the "Custom Properties".

\n\n

Requirements

\n\n\n\n

 

\n\n

Setup

\n\n\n", - "CustomProperties": [ - { - "Name": "Command Line Tool Configuration", - "Type": "Header", - "Value": "" - }, - { - "Name": "OP Path (Windows)", - "Type": "Text", - "Value": "C:\\Program Files\\op.exe" - }, - { - "Name": "OP Path (macOS)", - "Type": "Text", - "Value": "/usr/local/bin/op" - }, - { - "Name": "Login", - "Type": "Header", - "Value": "" - }, - { - "Name": "Sign In Address", - "Type": "URL", - "Value": "my.1password.com" - }, - { - "Name": "Email Address", - "Type": "Email", - "Value": "TODO" - }, - { - "Name": "Secret Key", - "Type": "Protected", - "Value": "TODO" - }, - { - "Name": "Master Password", - "Type": "Protected", - "Value": "TODO" - }, - { - "Name": "Filter", - "Type": "Header", - "Value": "" - }, - { - "Name": "Vault", - "Type": "Text", - "Value": "" - }, - { - "Name": "Configuration", - "Type": "Header", - "Value": "" - }, - { - "Name": "Dynamic Credentials", - "Type": "YesNo", - "Value": "True" - } - ], - "Script": "from __future__ import print_function\r\nfrom functools import partial\r\nfrom sys import platform as _platform\r\nfrom subprocess import Popen, PIPE\r\n\r\nimport tempfile\r\nimport sys\r\nimport json\r\nimport subprocess\r\nimport os\r\nimport base64\r\n\r\nop_path_windows = r\"$CustomProperty.OPPathWindows$\"\r\nop_path_macOS = r\"$CustomProperty.OPPathmacOS$\"\r\nsign_in_address = r\"$CustomProperty.SignInAddress$\"\r\nemail_address = r\"$CustomProperty.EmailAddress$\"\r\nsecret_key = r\"$CustomProperty.SecretKey$\"\r\nmaster_password = r\"$CustomProperty.MasterPassword$\"\r\nfilter_vault = r\"$CustomProperty.Vault$\"\r\ncreate_dynamic_credentials = r\"$CustomProperty.DynamicCredentials$\".lower() != \"no\"\r\n# item_id = r\"$DynamicCredential.EffectiveID$\"\r\n\r\nclass RoyalUtils:\r\n\t@staticmethod\r\n\tdef is_macOS():\r\n\t\tplat = _platform.lower()\r\n\r\n\t\treturn plat.startswith(\"darwin\")\r\n\r\n\t@staticmethod\r\n\tdef get_last_line(the_string: str):\r\n\t\tstripped_str = the_string.strip()\r\n\r\n\t\tif \"\\n\" in stripped_str:\r\n\t\t\tlines = stripped_str.splitlines()\r\n\t\t\tstripped_str = lines[len(lines) - 1]\r\n\r\n\t\treturn stripped_str\r\n\r\n\t@staticmethod\r\n\tdef random_uuid():\r\n\t\tuuid = base64.b32encode(os.urandom(16)).decode().lower().rstrip(\"=\")\r\n\r\n\t\treturn uuid\r\n\r\n\t@staticmethod\r\n\tdef exit_with_error(message, exception=None):\r\n\t\tprintError = partial(print, file=sys.stderr) # python2 compatibility\r\n\r\n\t\texception_message = str(exception) if exception else \"N/A\"\r\n\r\n\t\tfull_message = message + exception_message\r\n\r\n\t\tprintError(full_message)\r\n\t\tsys.exit(1)\r\n\r\n\t@staticmethod\r\n\tdef to_json(obj, pretty=False):\r\n\t\treturn json.dumps(obj, indent=4) if pretty else json.dumps(obj)\r\n\r\n\t@staticmethod\r\n\tdef decode_to_utf8_string(potential_bytes):\r\n\t\tif isinstance(potential_bytes, str):\r\n\t\t\treturn potential_bytes\r\n\t\telse:\r\n\t\t\treturn potential_bytes.decode(\"utf-8\")\r\n\r\nif RoyalUtils.is_macOS():\r\n\timport pexpect\r\nelse:\r\n\timport wexpect\r\n\r\nclass RoyalInputPrompt:\r\n\t@staticmethod\r\n\tdef show(title: str, message: str, defaultValue: str):\r\n\t\tif RoyalUtils.is_macOS(): # macOS\r\n\t\t\treturn RoyalInputPrompt._show_macOS(title, message, defaultValue)\r\n\t\telse: # Windows\r\n\t\t\treturn RoyalInputPrompt._show_windows(title, message, defaultValue)\r\n\r\n\t@staticmethod\r\n\tdef _escape_string_quotes_js(target_string: str):\r\n\t\tescaped_string = target_string.replace('\"', '\\\\\"')\r\n\r\n\t\treturn escaped_string\r\n\r\n\t@staticmethod\r\n\tdef _escape_string_quotes_vbs(target_string: str):\r\n\t\tescaped_string = target_string.replace('\"', '\\\"\\\"')\r\n\r\n\t\treturn escaped_string\r\n\r\n\t@staticmethod\r\n\tdef _show_macOS(title: str, message: str, defaultValue: str):\r\n\t\tscript = f\"\"\"\r\n\t\tfunction showInputPrompt(title, message, defaultValue) {{\r\n\t\t\tlet app = Application.currentApplication();\r\n\t\t\tapp.includeStandardAdditions = true;\r\n\t\t\t\r\n\t\t\tvar value = \"\";\r\n\t\t\t\r\n\t\t\ttry {{\r\n\t\t\t\tlet response = app.displayDialog(message, {{\r\n\t\t\t\t\twithTitle: title,\r\n\t\t\t\t\tdefaultAnswer: defaultValue,\r\n\t\t\t\t\twithIcon: \"note\",\r\n\t\t\t\t\tbuttons: [ \"Cancel\", \"OK\" ],\r\n\t\t\t\t\tdefaultButton: \"OK\",\r\n\t\t\t\t\tcancelButton: \"Cancel\"\r\n\t\t\t\t}});\r\n\t\t\t\t\r\n\t\t\t\tif (response.buttonReturned == \"OK\") {{\r\n\t\t\t\t\tvalue = response.textReturned;\r\n\t\t\t\t}}\r\n\t\t\t}} catch {{ }}\r\n\t\t\t\r\n\t\t\treturn value;\r\n\t\t}}\r\n\r\n\t\tfunction run(argv) {{\r\n\t\t\tlet value = showInputPrompt(\"{RoyalInputPrompt._escape_string_quotes_js(title)}\", \"{RoyalInputPrompt._escape_string_quotes_js(message)}\", \"{RoyalInputPrompt._escape_string_quotes_js(defaultValue)}\");\r\n\t\t\t\r\n\t\t\treturn value;\r\n\t\t}}\"\"\"\r\n\r\n\t\tencoding = \"utf-8\"\r\n\r\n\t\tcmd = [ \"osascript\", \"-l\", \"JavaScript\", \"-\" ]\r\n\r\n\t\tproc = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)\r\n\t\tstdout, _ = proc.communicate(script.encode(encoding))\r\n\r\n\t\treturn_value = RoyalUtils.decode_to_utf8_string(stdout)\r\n\r\n\t\treturn return_value\r\n\r\n\t@staticmethod\r\n\tdef _show_windows(title: str, message: str, defaultValue: str):\r\n\t\treturn_value = \"\"\r\n\r\n\t\tscript = f\"\"\"\r\n\t\tWScript.Echo InputBox(\"{RoyalInputPrompt._escape_string_quotes_vbs(message)}\", \"{RoyalInputPrompt._escape_string_quotes_vbs(title)}\", \"{RoyalInputPrompt._escape_string_quotes_vbs(defaultValue)}\")\r\n\t\t\"\"\"\r\n\r\n\t\tencoding = \"utf-8\"\r\n\r\n\t\ttemp_file = tempfile.NamedTemporaryFile(suffix=\".vbs\", mode=\"w\", encoding=encoding, delete=False)\r\n\t\ttemp_file_path = temp_file.name\r\n\r\n\t\ttemp_file.write(script)\r\n\t\ttemp_file.flush()\r\n\r\n\t\ttemp_file.close()\r\n\r\n\t\ttry:\r\n\t\t\tcmd = [ \"cscript.exe\", \"/Nologo\", temp_file_path ]\r\n\r\n\t\t\tproc = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)\r\n\t\t\tstdout, _ = proc.communicate()\r\n\r\n\t\t\treturn_value = RoyalUtils.decode_to_utf8_string(stdout)\r\n\t\texcept:\r\n\t\t\tpass\r\n\t\tfinally:\r\n\t\t\tif os.path.exists(temp_file_path):\r\n\t\t\t\tos.remove(temp_file_path)\r\n\r\n\t\treturn return_value\r\n\r\nclass OnePassword:\r\n\tconfig_path = \"\"\r\n\tconfig_file_path = \"\"\r\n\r\n\top_path = \"\"\r\n\tsession_token = \"\"\r\n\taccount_shorthand = \"\"\r\n\r\n\top_cli_version = \"\"\r\n\tis_op_cli_v2 = False\r\n\r\n\tunknown_error_string = \"An unknown error occurred.\"\r\n\r\n\tdef __init__(self, op_path):\r\n\t\tself.config_path = os.path.expanduser(\"~/.config/op\")\r\n\t\tself.config_file_path = os.path.join(self.config_path, \"config\")\r\n\r\n\t\tself.op_path = op_path\r\n\r\n\t\top_cli_version = \"1\"\r\n\r\n\t\ttry:\r\n\t\t\top_cli_version = self.get_cli_version()\r\n\t\texcept:\r\n\t\t\tpass\r\n\r\n\t\tif not op_cli_version:\r\n\t\t\top_cli_version = \"1\"\r\n\r\n\t\tself.op_cli_version = op_cli_version\r\n\t\tself.is_op_cli_v2 = op_cli_version.startswith(\"2\")\r\n\t\r\n\tdef get_cli_version(self):\r\n\t\tcmd_get_version = [ self.op_path, \"--version\" ]\r\n\t\top = subprocess.Popen(cmd_get_version, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\r\n\r\n\t\t(output, err) = op.communicate()\r\n\t\texit_code = op.wait()\r\n\r\n\t\tsuccess = exit_code == 0\r\n\r\n\t\top_cli_version = \"\"\r\n\r\n\t\tif success:\r\n\t\t\top_cli_version = RoyalUtils.decode_to_utf8_string(output)\r\n\t\t\top_cli_version = RoyalUtils.get_last_line(op_cli_version)\r\n\t\telse:\r\n\t\t\tif not err:\r\n\t\t\t\terr = self.unknown_error_string\r\n\t\t\telse:\r\n\t\t\t\terr = RoyalUtils.decode_to_utf8_string(err)\r\n\r\n\t\t\traise Exception(err)\r\n\t\t\r\n\t\treturn op_cli_version\r\n\t\r\n\tdef get_device_id(self):\r\n\t\tdevice_id = os.environ.get(\"OP_DEVICE\")\r\n\r\n\t\treturn device_id\r\n\t\r\n\tdef set_device_id(self, device_id):\r\n\t\tos.environ[\"OP_DEVICE\"] = device_id\r\n\r\n\t\tif not os.path.exists(self.config_file_path):\r\n\t\t\tconfig_json = RoyalUtils.to_json({ \"device\": device_id }, True)\r\n\r\n\t\t\ttry:\r\n\t\t\t\tfile = open(self.config_file_path, \"w\")\r\n\r\n\t\t\t\tfile.write(config_json)\r\n\t\t\t\tfile.close()\r\n\r\n\t\t\t\tif RoyalUtils.is_macOS:\r\n\t\t\t\t\tos.chmod(self.config_file_path, 0o600)\r\n\t\t\t\t\r\n\t\t\t\treturn True\r\n\t\t\texcept:\r\n\t\t\t\treturn False\r\n\t\t\r\n\t\treturn True\r\n\t\r\n\tdef get_account_shorthand(self, sign_in_address, email_address):\r\n\t\tshorthand = sign_in_address.replace(\".\", \"_\") + \"__\" + email_address.replace(\".\", \"_\").replace(\"@\", \"_\").replace(\"+\", \"_\")\r\n\r\n\t\treturn shorthand\r\n\r\n\tdef sign_out(self):\r\n\t\tcmd_signout = [ ]\r\n\r\n\t\tif self.account_shorthand:\r\n\t\t\tcmd_signout = [\r\n\t\t\t\tself.op_path,\r\n\t\t\t\t\"signout\",\r\n\t\t\t\t\"--account\", self.account_shorthand\r\n\t\t\t]\r\n\t\telse:\r\n\t\t\tcmd_signout = [\r\n\t\t\t\tself.op_path,\r\n\t\t\t\t\"signout\"\r\n\t\t\t]\r\n\r\n\t\top = subprocess.Popen(cmd_signout, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\r\n\t\t\r\n\t\t(output, err) = op.communicate()\r\n\t\texit_code = op.wait()\r\n\r\n\t\tsuccess = exit_code == 0\r\n\r\n\t\tif success:\r\n\t\t\tself.session_token = \"\"\r\n\t\t\tself.account_shorthand = \"\"\r\n\t\telse:\r\n\t\t\tif not err:\r\n\t\t\t\terr = self.unknown_error_string\r\n\t\t\telse:\r\n\t\t\t\terr = RoyalUtils.decode_to_utf8_string(err)\r\n\r\n\t\t\traise Exception(err)\r\n\t\r\n\tdef sign_in(self, sign_in_address, email_address, secret_key, master_password, second_try=False, add_account=False):\r\n\t\tshorthand = self.get_account_shorthand(sign_in_address, email_address)\r\n\r\n\t\ttimeout = 10\r\n\r\n\t\tcmd = self.op_path\r\n\r\n\t\targs = [ ]\r\n\r\n\t\tif self.is_op_cli_v2:\r\n\t\t\tif add_account:\r\n\t\t\t\targs = [\r\n\t\t\t\t\t\"account\", \"add\",\r\n\t\t\t\t\t\"--signin\",\r\n\t\t\t\t\t\"--address\", sign_in_address,\r\n\t\t\t\t\t\"--email\", email_address,\r\n\t\t\t\t\t\"--secret-key\", secret_key,\r\n\t\t\t\t\t\"--shorthand\", shorthand,\r\n\t\t\t\t\t\"--raw\"\r\n\t\t\t\t]\r\n\t\t\telse:\r\n\t\t\t\targs = [\r\n\t\t\t\t\t\"signin\",\r\n\t\t\t\t\t\"--account\", shorthand,\r\n\t\t\t\t\t\"--raw\"\r\n\t\t\t\t]\r\n\t\telse:\r\n\t\t\tadd_account = True\r\n\t\t\targs = [\r\n\t\t\t\t\"signin\",\r\n\t\t\t\tsign_in_address,\r\n\t\t\t\temail_address,\r\n\t\t\t\tsecret_key,\r\n\t\t\t\t\"--shorthand\", shorthand,\r\n\t\t\t\t\"--raw\"\r\n\t\t\t]\r\n\r\n\t\teof = None\r\n\t\tproc = None\r\n\r\n\t\tif RoyalUtils.is_macOS():\r\n\t\t\teof = pexpect.EOF\r\n\t\t\tproc = pexpect.spawn(cmd, args)\r\n\t\telse:\r\n\t\t\teof = wexpect.EOF\r\n\t\t\tproc = wexpect.spawn(cmd, args)\r\n\r\n\t\texp_str_password = f\"Enter the password for.*:\"\r\n\t\texp_str_error = \"\\[ERROR\\].*\"\r\n\t\texp_str_biometric_unlock_enabled = \"Biometric unlock integration with the 1Password app is enabled*\"\r\n\t\texp_str_add_account = \"Do you want to add an account manually now?\"\r\n\r\n\t\terr = None\r\n\r\n\t\ttry:\r\n\t\t\texp_pw_prompt = proc.expect([ exp_str_password, exp_str_error, exp_str_biometric_unlock_enabled, exp_str_add_account ], timeout=timeout)\r\n\r\n\t\t\tif exp_pw_prompt == 0: # Password Prompt\r\n\t\t\t\tproc.sendline(master_password)\r\n\r\n\t\t\t\texp_str_mfa = \"Enter your.*authentication code.*:\"\r\n\r\n\t\t\t\texp_mfa = proc.expect([ exp_str_mfa, exp_str_error, eof ], timeout=timeout)\r\n\r\n\t\t\t\tif exp_mfa == 0: # MFA Prompt\r\n\t\t\t\t\tmfa_code = RoyalInputPrompt.show(\"1Password Multi-Factor-Authentication\", f\"Enter multi-factor authentication code for {email_address}:\", \"\")\r\n\t\t\t\t\tmfa_code = mfa_code.replace(\"\\n\", \"\").replace(\"\\r\", \"\")\r\n\r\n\t\t\t\t\tif not mfa_code:\r\n\t\t\t\t\t\traise Exception(\"No multi-factor code provided\")\r\n\t\t\t\t\t\r\n\t\t\t\t\tproc.sendline(mfa_code)\r\n\t\t\t\t\texp_mfa_sent = proc.expect([ exp_str_error, eof ], timeout=timeout)\r\n\r\n\t\t\t\t\tif exp_mfa_sent == 0: # Error\r\n\t\t\t\t\t\terr = RoyalUtils.get_last_line(RoyalUtils.decode_to_utf8_string(proc.match.string))\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\traise Exception(err)\r\n\t\t\t\telif exp_mfa == 1: # Error\r\n\t\t\t\t\terr = RoyalUtils.get_last_line(RoyalUtils.decode_to_utf8_string(proc.match.string))\r\n\t\t\t\t\t\r\n\t\t\t\t\traise Exception(err)\r\n\r\n\t\t\t\toutput = proc.before\r\n\r\n\t\t\t\tif output:\r\n\t\t\t\t\toutput = RoyalUtils.decode_to_utf8_string(output)\r\n\t\t\t\t\r\n\t\t\t\tproc.close()\r\n\t\t\t\texit_code = proc.wait()\r\n\t\t\t\t\r\n\t\t\t\tsuccess = exit_code == 0\r\n\r\n\t\t\t\tif success:\r\n\t\t\t\t\tself.session_token = RoyalUtils.get_last_line(output)\r\n\t\t\t\t\tself.account_shorthand = shorthand\r\n\t\t\t\telse:\r\n\t\t\t\t\tif not err:\r\n\t\t\t\t\t\terr = self.unknown_error_string\r\n\r\n\t\t\t\t\traise Exception(err)\r\n\t\t\telif exp_pw_prompt == 1: # Error\r\n\t\t\t\terr = RoyalUtils.get_last_line(RoyalUtils.decode_to_utf8_string(proc.match.string))\r\n\r\n\t\t\t\tif not second_try:\r\n\t\t\t\t\tif \"No saved device ID\" in err:\r\n\t\t\t\t\t\texport_start_str = \"export OP_DEVICE=\"\r\n\t\t\t\t\t\tdevice_id = \"\"\r\n\r\n\t\t\t\t\t\tif export_start_str in err:\r\n\t\t\t\t\t\t\tstart_index = err.index(export_start_str) + len(export_start_str)\r\n\t\t\t\t\t\t\tdevice_id = err[start_index:]\r\n\t\t\t\t\t\t\tend_index = device_id.index(\"`\")\r\n\t\t\t\t\t\t\tdevice_id = device_id[:end_index]\r\n\r\n\t\t\t\t\t\tif not device_id or len(device_id) != 26:\r\n\t\t\t\t\t\t\tdevice_id = RoyalUtils.random_uuid()\r\n\r\n\t\t\t\t\t\tself.set_device_id(device_id)\r\n\r\n\t\t\t\t\t\tself.sign_in(sign_in_address, email_address, secret_key, master_password, second_try=True, add_account=add_account)\r\n\r\n\t\t\t\t\t\treturn\r\n\r\n\t\t\t\tif not add_account:\r\n\t\t\t\t\t# Try resolving the error by re-adding the account\r\n\t\t\t\t\treturn self.sign_in(sign_in_address, email_address, secret_key, master_password, second_try, add_account=True)\r\n\r\n\t\t\t\tif not err:\r\n\t\t\t\t\terr = self.unknown_error_string\r\n\r\n\t\t\t\traise Exception(err)\r\n\t\t\telif exp_pw_prompt == 2: # Biometric unlock enabled\r\n\t\t\t\terr = \"Biometric unlock integration with the 1Password app is enabled. This feature is not supported by the 1Password Dynamic Folder Script. Please disable biometric unlock in the 1Password app.\"\r\n\t\t\t\t\r\n\t\t\t\traise Exception(err)\r\n\t\t\telif exp_pw_prompt == 3: # Account doesn't exist yet\r\n\t\t\t\treturn self.sign_in(sign_in_address, email_address, secret_key, master_password, second_try, add_account=True)\r\n\t\texcept Exception as ex:\r\n\t\t\terr = str(ex)\r\n\r\n\t\t\tif not err:\r\n\t\t\t\terr = self.unknown_error_string\r\n\r\n\t\t\traise Exception(err)\r\n\r\n\tdef get_vaults(self):\r\n\t\tcmd_list_vaults = [ ]\r\n\r\n\t\tif self.is_op_cli_v2:\r\n\t\t\tcmd_list_vaults = [\r\n\t\t\t\tself.op_path,\r\n\t\t\t\t\"vault\", \"list\",\r\n\t\t\t\t\"--format=json\",\r\n\t\t\t\t\"--account\", self.account_shorthand,\r\n\t\t\t\t\"--session\", self.session_token\r\n\t\t\t]\r\n\t\telse:\r\n\t\t\tcmd_list_vaults = [\r\n\t\t\t\tself.op_path,\r\n\t\t\t\t\"list\", \"vaults\",\r\n\t\t\t\t\"--account\", self.account_shorthand,\r\n\t\t\t\t\"--session\", self.session_token\r\n\t\t\t]\r\n\t\t\r\n\t\top = subprocess.Popen(cmd_list_vaults, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\r\n\r\n\t\t(output, err) = op.communicate()\r\n\t\texit_code = op.wait()\r\n\r\n\t\tsuccess = exit_code == 0\r\n\r\n\t\tif success:\r\n\t\t\toutput = RoyalUtils.decode_to_utf8_string(output)\r\n\r\n\t\t\tvaults_str = \"\"\r\n\r\n\t\t\tif self.is_op_cli_v2:\r\n\t\t\t\tvaults_str = output\r\n\t\t\telse:\r\n\t\t\t\tvaults_str = RoyalUtils.get_last_line(output)\r\n\t\t\t\r\n\t\t\tvaults = json.loads(vaults_str)\r\n\r\n\t\t\treturn vaults\r\n\t\t\r\n\t\tif not err:\r\n\t\t\terr = self.unknown_error_string\r\n\t\telse:\r\n\t\t\terr = RoyalUtils.decode_to_utf8_string(err)\r\n\t\t\r\n\t\traise Exception(err)\r\n\r\n\tdef get_items(self, vault):\r\n\t\tcmd_list_items = [ ]\r\n\r\n\t\tif self.is_op_cli_v2:\r\n\t\t\tcmd_list_items = [\r\n\t\t\t\tself.op_path,\r\n\t\t\t\t\"item\", \"list\",\r\n\t\t\t\t\"--format=json\",\r\n\t\t\t\t\"--account\", self.account_shorthand,\r\n\t\t\t\t\"--session\", self.session_token\r\n\t\t\t]\r\n\t\telse:\r\n\t\t\tcmd_list_items = [\r\n\t\t\t\tself.op_path,\r\n\t\t\t\t\"list\", \"items\",\r\n\t\t\t\t\"--account\", self.account_shorthand,\r\n\t\t\t\t\"--session\", self.session_token\r\n\t\t\t]\r\n\t\t\r\n\t\tif not vault:\r\n\t\t\tvault = \"\"\r\n\t\t\r\n\t\tvault = vault.strip()\r\n\t\t\r\n\t\tif vault:\r\n\t\t\tcmd_list_items.append(\"--vault\")\r\n\t\t\tcmd_list_items.append(vault)\r\n\r\n\t\top = subprocess.Popen(cmd_list_items, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\r\n\r\n\t\t(output, err) = op.communicate()\r\n\t\texit_code = op.wait()\r\n\r\n\t\tsuccess = exit_code == 0\r\n\r\n\t\tif success:\r\n\t\t\toutput = RoyalUtils.decode_to_utf8_string(output)\r\n\r\n\t\t\titems_str = \"\"\r\n\r\n\t\t\tif self.is_op_cli_v2:\r\n\t\t\t\titems_str = output\r\n\t\t\telse:\r\n\t\t\t\titems_str = RoyalUtils.get_last_line(output)\r\n\r\n\t\t\titems = json.loads(items_str)\r\n\t\t\r\n\t\t\treturn items\r\n\t\telse:\r\n\t\t\tif not err:\r\n\t\t\t\terr = self.unknown_error_string\r\n\t\t\telse:\r\n\t\t\t\terr = RoyalUtils.decode_to_utf8_string(err)\r\n\t\t\r\n\t\t\traise Exception(err)\r\n\r\n\tdef get_item_details(self, item_id):\r\n\t\tcmd_get_item = [ ]\r\n\r\n\t\tif self.is_op_cli_v2:\r\n\t\t\tcmd_get_item = [\r\n\t\t\t\tself.op_path,\r\n\t\t\t\t\"item\", \"get\", item_id,\r\n\t\t\t\t# \"--fields\", \"label=password,label=privatekey\",\r\n\t\t\t\t\"--format=JSON\",\r\n\t\t\t\t\"--account\", self.account_shorthand,\r\n\t\t\t\t\"--session\", self.session_token\r\n\t\t\t]\r\n\t\telse:\r\n\t\t\tcmd_get_item = [\r\n\t\t\t\tself.op_path,\r\n\t\t\t\t\"get\", \"item\", item_id,\r\n\t\t\t\t\"--fields\", \"username,password\",\r\n\t\t\t\t\"--format\", \"JSON\",\r\n\t\t\t\t\"--account\", self.account_shorthand,\r\n\t\t\t\t\"--session\", self.session_token\r\n\t\t\t]\r\n\r\n\t\top = subprocess.Popen(cmd_get_item, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\r\n\r\n\t\t(output, err) = op.communicate()\r\n\t\texit_code = op.wait()\r\n\r\n\t\tsuccess = exit_code == 0\r\n\r\n\t\tif success:\r\n\t\t\toutput = RoyalUtils.decode_to_utf8_string(output)\r\n\r\n\t\t\titem_str = \"\"\r\n\r\n\t\t\tif self.is_op_cli_v2:\r\n\t\t\t\titem_str = output\r\n\t\t\telse:\r\n\t\t\t\titem_str = RoyalUtils.get_last_line(output)\r\n\t\t\t\r\n\t\t\titem = json.loads(item_str)\r\n\t\t\r\n\t\t\treturn item\r\n\t\telse:\r\n\t\t\tif not err:\r\n\t\t\t\terr = self.unknown_error_string\r\n\t\t\telse:\r\n\t\t\t\terr = RoyalUtils.decode_to_utf8_string(err)\r\n\t\t\t\r\n\t\t\traise Exception(err)\r\n\r\nclass Converter:\r\n\t@staticmethod\r\n\tdef get_vault_name(vaults, vault_id, is_op_cli_v2):\r\n\t\tfor vault in vaults:\r\n\t\t\tif is_op_cli_v2:\r\n\t\t\t\tif vault.get(\"id\", \"\") == vault_id:\r\n\t\t\t\t\treturn vault.get(\"name\", \"\")\r\n\t\t\telse:\r\n\t\t\t\tif vault.get(\"uuid\", \"\") == vault_id:\r\n\t\t\t\t\treturn vault.get(\"name\", \"\")\r\n\t\t\r\n\t\treturn \"\"\r\n\r\n\t@staticmethod\r\n\tdef convert_items(vaults, items, is_op_cli_v2):\r\n\t\tobjects = []\r\n\r\n\t\tfor item in items:\r\n\t\t\toverview = None\r\n\r\n\t\t\tif is_op_cli_v2:\r\n\t\t\t\toverview = item\r\n\t\t\telse:\r\n\t\t\t\toverview = item.get(\"overview\", None)\r\n\r\n\t\t\tif overview == None:\r\n\t\t\t\tcontinue\r\n\r\n\t\t\tid = \"\"\r\n\r\n\t\t\tif is_op_cli_v2:\r\n\t\t\t\tid = item.get(\"id\", \"\")\r\n\t\t\telse:\r\n\t\t\t\tid = item.get(\"uuid\", \"\")\r\n\t\t\t\r\n\t\t\ttitle = overview.get(\"title\", \"N/A\")\r\n\t\t\turl = overview.get(\"url\", \"\")\r\n\r\n\t\t\tvault_id = \"\"\r\n\r\n\t\t\tif is_op_cli_v2:\r\n\t\t\t\titem_vault = item.get(\"vault\", None)\r\n\r\n\t\t\t\tif item_vault:\r\n\t\t\t\t\tvault_id = item_vault.get(\"id\", \"\")\r\n\t\t\telse:\r\n\t\t\t\tvault_id = item.get(\"vaultUuid\", \"\")\r\n\r\n\t\t\tvault_name = Converter.get_vault_name(vaults, vault_id, is_op_cli_v2)\r\n\r\n\t\t\titem_details = item.get(\"__item_details\", None)\r\n\t\t\tconverted_item_details = None\r\n\r\n\t\t\tif item_details is not None:\r\n\t\t\t\tconverted_item_details = Converter.convert_item(item_details, is_op_cli_v2)\r\n\r\n\t\t\tcred_type = \"DynamicCredential\" if converted_item_details is None else \"Credential\"\r\n\r\n\t\t\tcred = {\r\n\t\t\t\t\"Type\": cred_type,\r\n\t\t\t\t\"ID\": id,\r\n\t\t\t\t\"Name\": title,\r\n\t\t\t\t\"Path\": vault_name\r\n\t\t\t}\r\n\r\n\t\t\tif url != \"\":\r\n\t\t\t\tcred[\"URL\"] = url\r\n\t\t\t\r\n\t\t\tif converted_item_details is not None:\r\n\t\t\t\tfor key in converted_item_details:\r\n\t\t\t\t\tcred[key] = converted_item_details[key]\r\n\r\n\t\t\tobjects.append(cred)\r\n\r\n\t\tobjects = sorted(objects, key = lambda i: (i[\"Path\"], i[\"Name\"]))\r\n\r\n\t\tstore = {\r\n\t\t\t\"Objects\": objects\r\n\t\t}\r\n\r\n\t\treturn store\r\n\t\r\n\t@staticmethod\r\n\tdef convert_item(item_details, is_op_cli_v2):\r\n\t\tusername = None\r\n\t\tpassword = None\r\n\t\tprivate_key = None\r\n\r\n\t\tif is_op_cli_v2:\r\n\t\t\tfields = item_details.get(\"fields\")\r\n\r\n\t\t\tif not fields:\r\n\t\t\t\tfields = item_details\r\n\r\n\t\t\tfor field in fields:\r\n\t\t\t\tfield_id = field.get(\"id\", None)\r\n\t\t\t\tfield_label = field.get(\"label\", None)\r\n\t\t\t\tfield_value = field.get(\"value\", None)\r\n\r\n\t\t\t\tif field_id == \"username\" or field_label == \"username\":\r\n\t\t\t\t\tusername = field_value\r\n\t\t\t\telif field_id == \"password\" or field_label == \"password\":\r\n\t\t\t\t\tpassword = field_value\r\n\t\t\t\telif field_id == \"private_key\" or field_label == \"private key\":\r\n\t\t\t\t\tprivate_key = field_value\r\n\t\telse:\r\n\t\t\tusername = item_details.get(\"username\", None)\r\n\t\t\tpassword = item_details.get(\"password\", None)\r\n\r\n\t\tcred = { }\r\n\r\n\t\tif username is not None:\r\n\t\t\tcred[\"Username\"] = username\r\n\r\n\t\tif password is not None:\r\n\t\t\tcred[\"Password\"] = password\r\n\r\n\t\tif private_key is not None:\r\n\t\t\tcred[\"KeyFileContent\"] = private_key\r\n\r\n\t\treturn cred\r\n\r\nclass Coordinator:\r\n\top_path = \"\"\r\n\tsign_in_address = \"\"\r\n\temail_address = \"\"\r\n\tsecret_key = \"\"\r\n\tmaster_password = \"\"\r\n\tcreate_dynamic_credentials = True\r\n\r\n\terror_message_sign_in = \"Error while signing in: \"\r\n\terror_message_sign_out = \"Error while signing out: \"\r\n\terror_message_get_vaults = \"Error while getting vaults: \"\r\n\terror_message_get_items = \"Error while getting items: \"\r\n\terror_message_get_item_details = \"Error while getting item details: \"\r\n\r\n\tdef __init__(self, op_path_windows, op_path_macOS, sign_in_address, email_address, secret_key, master_password, create_dynamic_credentials):\r\n\t\tself.op_path = op_path_macOS if RoyalUtils.is_macOS() else op_path_windows\r\n\t\tself.sign_in_address = sign_in_address\r\n\t\tself.email_address = email_address\r\n\t\tself.secret_key = secret_key\r\n\t\tself.master_password = master_password\r\n\t\tself.create_dynamic_credentials = create_dynamic_credentials\r\n\t\t\r\n\tdef get_items(self, vault):\r\n\t\top = OnePassword(self.op_path)\r\n\r\n\t\ttry:\r\n\t\t\top.sign_out()\r\n\t\texcept Exception:\r\n\t\t\tpass\r\n\r\n\t\ttry:\r\n\t\t\top.sign_in(self.sign_in_address, self.email_address, self.secret_key, self.master_password)\r\n\t\texcept Exception as e:\r\n\t\t\tRoyalUtils.exit_with_error(self.error_message_sign_in, e)\r\n\r\n\t\tvaults = None\r\n\r\n\t\ttry:\r\n\t\t\tvaults = op.get_vaults()\r\n\t\texcept Exception as e:\r\n\t\t\tRoyalUtils.exit_with_error(self.error_message_get_vaults, e)\r\n\t\t\r\n\t\titems = None\r\n\r\n\t\ttry:\r\n\t\t\titems = op.get_items(vault)\r\n\t\texcept Exception as e:\r\n\t\t\tRoyalUtils.exit_with_error(self.error_message_get_items, e)\r\n\t\t\r\n\t\titems_details = [ ]\r\n\r\n\t\tif not self.create_dynamic_credentials:\r\n\t\t\tfor item in items:\r\n\t\t\t\tid = \"\"\r\n\r\n\t\t\t\tif op.is_op_cli_v2:\r\n\t\t\t\t\tid = item.get(\"id\", \"\")\r\n\t\t\t\telse:\r\n\t\t\t\t\tid = item.get(\"uuid\", \"\")\r\n\t\t\t\t\r\n\t\t\t\titem_details = op.get_item_details(id)\r\n\r\n\t\t\t\titem[\"__item_details\"] = item_details\r\n\r\n\t\ttry:\r\n\t\t\top.sign_out()\r\n\t\texcept Exception as e:\r\n\t\t\tRoyalUtils.exit_with_error(self.error_message_sign_out, e)\r\n\r\n\t\tstore = Converter.convert_items(vaults, items, op.is_op_cli_v2)\r\n\t\tstore_json = RoyalUtils.to_json(store, True)\r\n\r\n\t\tprint(store_json)\r\n\t\r\n\tdef get_item_details(self, item_id):\r\n\t\top = OnePassword(self.op_path)\r\n\r\n\t\ttry:\r\n\t\t\top.sign_out()\r\n\t\texcept Exception:\r\n\t\t\tpass\r\n\r\n\t\ttry:\r\n\t\t\top.sign_in(self.sign_in_address, self.email_address, self.secret_key, self.master_password)\r\n\t\texcept Exception as e:\r\n\t\t\tRoyalUtils.exit_with_error(self.error_message_sign_in, e)\r\n\r\n\t\titem_details = None\r\n\r\n\t\ttry:\r\n\t\t\titem_details = op.get_item_details(item_id)\r\n\t\texcept Exception as e:\r\n\t\t\tRoyalUtils.exit_with_error(self.error_message_get_item_details, e)\r\n\r\n\t\ttry:\r\n\t\t\top.sign_out()\r\n\t\texcept Exception as e:\r\n\t\t\tRoyalUtils.exit_with_error(self.error_message_sign_out, e)\r\n\r\n\t\tstore = Converter.convert_item(item_details, op.is_op_cli_v2)\r\n\t\tstore_json = RoyalUtils.to_json(store, True)\r\n\r\n\t\tprint(store_json)\r\n\r\ncoordinator = Coordinator(op_path_windows, op_path_macOS, sign_in_address, email_address, secret_key, master_password, create_dynamic_credentials)\r\ncoordinator.get_items(filter_vault)\r\n# coordinator.get_item_details(item_id)", - "ScriptInterpreter": "python", - "DynamicCredentialScriptInterpreter": "python", - "DynamicCredentialScript": "from __future__ import print_function\r\nfrom functools import partial\r\nfrom sys import platform as _platform\r\nfrom subprocess import Popen, PIPE\r\n\r\nimport tempfile\r\nimport sys\r\nimport json\r\nimport subprocess\r\nimport os\r\nimport base64\r\n\r\nop_path_windows = r\"$CustomProperty.OPPathWindows$\"\r\nop_path_macOS = r\"$CustomProperty.OPPathmacOS$\"\r\nsign_in_address = r\"$CustomProperty.SignInAddress$\"\r\nemail_address = r\"$CustomProperty.EmailAddress$\"\r\nsecret_key = r\"$CustomProperty.SecretKey$\"\r\nmaster_password = r\"$CustomProperty.MasterPassword$\"\r\nfilter_vault = r\"$CustomProperty.Vault$\"\r\ncreate_dynamic_credentials = r\"$CustomProperty.DynamicCredentials$\".lower() != \"no\"\r\nitem_id = r\"$DynamicCredential.EffectiveID$\"\r\n\r\nclass RoyalUtils:\r\n\t@staticmethod\r\n\tdef is_macOS():\r\n\t\tplat = _platform.lower()\r\n\r\n\t\treturn plat.startswith(\"darwin\")\r\n\r\n\t@staticmethod\r\n\tdef get_last_line(the_string: str):\r\n\t\tstripped_str = the_string.strip()\r\n\r\n\t\tif \"\\n\" in stripped_str:\r\n\t\t\tlines = stripped_str.splitlines()\r\n\t\t\tstripped_str = lines[len(lines) - 1]\r\n\r\n\t\treturn stripped_str\r\n\r\n\t@staticmethod\r\n\tdef random_uuid():\r\n\t\tuuid = base64.b32encode(os.urandom(16)).decode().lower().rstrip(\"=\")\r\n\r\n\t\treturn uuid\r\n\r\n\t@staticmethod\r\n\tdef exit_with_error(message, exception=None):\r\n\t\tprintError = partial(print, file=sys.stderr) # python2 compatibility\r\n\r\n\t\texception_message = str(exception) if exception else \"N/A\"\r\n\r\n\t\tfull_message = message + exception_message\r\n\r\n\t\tprintError(full_message)\r\n\t\tsys.exit(1)\r\n\r\n\t@staticmethod\r\n\tdef to_json(obj, pretty=False):\r\n\t\treturn json.dumps(obj, indent=4) if pretty else json.dumps(obj)\r\n\r\n\t@staticmethod\r\n\tdef decode_to_utf8_string(potential_bytes):\r\n\t\tif isinstance(potential_bytes, str):\r\n\t\t\treturn potential_bytes\r\n\t\telse:\r\n\t\t\treturn potential_bytes.decode(\"utf-8\")\r\n\r\nif RoyalUtils.is_macOS():\r\n\timport pexpect\r\nelse:\r\n\timport wexpect\r\n\r\nclass RoyalInputPrompt:\r\n\t@staticmethod\r\n\tdef show(title: str, message: str, defaultValue: str):\r\n\t\tif RoyalUtils.is_macOS(): # macOS\r\n\t\t\treturn RoyalInputPrompt._show_macOS(title, message, defaultValue)\r\n\t\telse: # Windows\r\n\t\t\treturn RoyalInputPrompt._show_windows(title, message, defaultValue)\r\n\r\n\t@staticmethod\r\n\tdef _escape_string_quotes_js(target_string: str):\r\n\t\tescaped_string = target_string.replace('\"', '\\\\\"')\r\n\r\n\t\treturn escaped_string\r\n\r\n\t@staticmethod\r\n\tdef _escape_string_quotes_vbs(target_string: str):\r\n\t\tescaped_string = target_string.replace('\"', '\\\"\\\"')\r\n\r\n\t\treturn escaped_string\r\n\r\n\t@staticmethod\r\n\tdef _show_macOS(title: str, message: str, defaultValue: str):\r\n\t\tscript = f\"\"\"\r\n\t\tfunction showInputPrompt(title, message, defaultValue) {{\r\n\t\t\tlet app = Application.currentApplication();\r\n\t\t\tapp.includeStandardAdditions = true;\r\n\t\t\t\r\n\t\t\tvar value = \"\";\r\n\t\t\t\r\n\t\t\ttry {{\r\n\t\t\t\tlet response = app.displayDialog(message, {{\r\n\t\t\t\t\twithTitle: title,\r\n\t\t\t\t\tdefaultAnswer: defaultValue,\r\n\t\t\t\t\twithIcon: \"note\",\r\n\t\t\t\t\tbuttons: [ \"Cancel\", \"OK\" ],\r\n\t\t\t\t\tdefaultButton: \"OK\",\r\n\t\t\t\t\tcancelButton: \"Cancel\"\r\n\t\t\t\t}});\r\n\t\t\t\t\r\n\t\t\t\tif (response.buttonReturned == \"OK\") {{\r\n\t\t\t\t\tvalue = response.textReturned;\r\n\t\t\t\t}}\r\n\t\t\t}} catch {{ }}\r\n\t\t\t\r\n\t\t\treturn value;\r\n\t\t}}\r\n\r\n\t\tfunction run(argv) {{\r\n\t\t\tlet value = showInputPrompt(\"{RoyalInputPrompt._escape_string_quotes_js(title)}\", \"{RoyalInputPrompt._escape_string_quotes_js(message)}\", \"{RoyalInputPrompt._escape_string_quotes_js(defaultValue)}\");\r\n\t\t\t\r\n\t\t\treturn value;\r\n\t\t}}\"\"\"\r\n\r\n\t\tencoding = \"utf-8\"\r\n\r\n\t\tcmd = [ \"osascript\", \"-l\", \"JavaScript\", \"-\" ]\r\n\r\n\t\tproc = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)\r\n\t\tstdout, _ = proc.communicate(script.encode(encoding))\r\n\r\n\t\treturn_value = RoyalUtils.decode_to_utf8_string(stdout)\r\n\r\n\t\treturn return_value\r\n\r\n\t@staticmethod\r\n\tdef _show_windows(title: str, message: str, defaultValue: str):\r\n\t\treturn_value = \"\"\r\n\r\n\t\tscript = f\"\"\"\r\n\t\tWScript.Echo InputBox(\"{RoyalInputPrompt._escape_string_quotes_vbs(message)}\", \"{RoyalInputPrompt._escape_string_quotes_vbs(title)}\", \"{RoyalInputPrompt._escape_string_quotes_vbs(defaultValue)}\")\r\n\t\t\"\"\"\r\n\r\n\t\tencoding = \"utf-8\"\r\n\r\n\t\ttemp_file = tempfile.NamedTemporaryFile(suffix=\".vbs\", mode=\"w\", encoding=encoding, delete=False)\r\n\t\ttemp_file_path = temp_file.name\r\n\r\n\t\ttemp_file.write(script)\r\n\t\ttemp_file.flush()\r\n\r\n\t\ttemp_file.close()\r\n\r\n\t\ttry:\r\n\t\t\tcmd = [ \"cscript.exe\", \"/Nologo\", temp_file_path ]\r\n\r\n\t\t\tproc = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)\r\n\t\t\tstdout, _ = proc.communicate()\r\n\r\n\t\t\treturn_value = RoyalUtils.decode_to_utf8_string(stdout)\r\n\t\texcept:\r\n\t\t\tpass\r\n\t\tfinally:\r\n\t\t\tif os.path.exists(temp_file_path):\r\n\t\t\t\tos.remove(temp_file_path)\r\n\r\n\t\treturn return_value\r\n\r\nclass OnePassword:\r\n\tconfig_path = \"\"\r\n\tconfig_file_path = \"\"\r\n\r\n\top_path = \"\"\r\n\tsession_token = \"\"\r\n\taccount_shorthand = \"\"\r\n\r\n\top_cli_version = \"\"\r\n\tis_op_cli_v2 = False\r\n\r\n\tunknown_error_string = \"An unknown error occurred.\"\r\n\r\n\tdef __init__(self, op_path):\r\n\t\tself.config_path = os.path.expanduser(\"~/.config/op\")\r\n\t\tself.config_file_path = os.path.join(self.config_path, \"config\")\r\n\r\n\t\tself.op_path = op_path\r\n\r\n\t\top_cli_version = \"1\"\r\n\r\n\t\ttry:\r\n\t\t\top_cli_version = self.get_cli_version()\r\n\t\texcept:\r\n\t\t\tpass\r\n\r\n\t\tif not op_cli_version:\r\n\t\t\top_cli_version = \"1\"\r\n\r\n\t\tself.op_cli_version = op_cli_version\r\n\t\tself.is_op_cli_v2 = op_cli_version.startswith(\"2\")\r\n\t\r\n\tdef get_cli_version(self):\r\n\t\tcmd_get_version = [ self.op_path, \"--version\" ]\r\n\t\top = subprocess.Popen(cmd_get_version, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\r\n\r\n\t\t(output, err) = op.communicate()\r\n\t\texit_code = op.wait()\r\n\r\n\t\tsuccess = exit_code == 0\r\n\r\n\t\top_cli_version = \"\"\r\n\r\n\t\tif success:\r\n\t\t\top_cli_version = RoyalUtils.decode_to_utf8_string(output)\r\n\t\t\top_cli_version = RoyalUtils.get_last_line(op_cli_version)\r\n\t\telse:\r\n\t\t\tif not err:\r\n\t\t\t\terr = self.unknown_error_string\r\n\t\t\telse:\r\n\t\t\t\terr = RoyalUtils.decode_to_utf8_string(err)\r\n\r\n\t\t\traise Exception(err)\r\n\t\t\r\n\t\treturn op_cli_version\r\n\t\r\n\tdef get_device_id(self):\r\n\t\tdevice_id = os.environ.get(\"OP_DEVICE\")\r\n\r\n\t\treturn device_id\r\n\t\r\n\tdef set_device_id(self, device_id):\r\n\t\tos.environ[\"OP_DEVICE\"] = device_id\r\n\r\n\t\tif not os.path.exists(self.config_file_path):\r\n\t\t\tconfig_json = RoyalUtils.to_json({ \"device\": device_id }, True)\r\n\r\n\t\t\ttry:\r\n\t\t\t\tfile = open(self.config_file_path, \"w\")\r\n\r\n\t\t\t\tfile.write(config_json)\r\n\t\t\t\tfile.close()\r\n\r\n\t\t\t\tif RoyalUtils.is_macOS:\r\n\t\t\t\t\tos.chmod(self.config_file_path, 0o600)\r\n\t\t\t\t\r\n\t\t\t\treturn True\r\n\t\t\texcept:\r\n\t\t\t\treturn False\r\n\t\t\r\n\t\treturn True\r\n\t\r\n\tdef get_account_shorthand(self, sign_in_address, email_address):\r\n\t\tshorthand = sign_in_address.replace(\".\", \"_\") + \"__\" + email_address.replace(\".\", \"_\").replace(\"@\", \"_\").replace(\"+\", \"_\")\r\n\r\n\t\treturn shorthand\r\n\r\n\tdef sign_out(self):\r\n\t\tcmd_signout = [ ]\r\n\r\n\t\tif self.account_shorthand:\r\n\t\t\tcmd_signout = [\r\n\t\t\t\tself.op_path,\r\n\t\t\t\t\"signout\",\r\n\t\t\t\t\"--account\", self.account_shorthand\r\n\t\t\t]\r\n\t\telse:\r\n\t\t\tcmd_signout = [\r\n\t\t\t\tself.op_path,\r\n\t\t\t\t\"signout\"\r\n\t\t\t]\r\n\r\n\t\top = subprocess.Popen(cmd_signout, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\r\n\t\t\r\n\t\t(output, err) = op.communicate()\r\n\t\texit_code = op.wait()\r\n\r\n\t\tsuccess = exit_code == 0\r\n\r\n\t\tif success:\r\n\t\t\tself.session_token = \"\"\r\n\t\t\tself.account_shorthand = \"\"\r\n\t\telse:\r\n\t\t\tif not err:\r\n\t\t\t\terr = self.unknown_error_string\r\n\t\t\telse:\r\n\t\t\t\terr = RoyalUtils.decode_to_utf8_string(err)\r\n\r\n\t\t\traise Exception(err)\r\n\t\r\n\tdef sign_in(self, sign_in_address, email_address, secret_key, master_password, second_try=False, add_account=False):\r\n\t\tshorthand = self.get_account_shorthand(sign_in_address, email_address)\r\n\r\n\t\ttimeout = 10\r\n\r\n\t\tcmd = self.op_path\r\n\r\n\t\targs = [ ]\r\n\r\n\t\tif self.is_op_cli_v2:\r\n\t\t\tif add_account:\r\n\t\t\t\targs = [\r\n\t\t\t\t\t\"account\", \"add\",\r\n\t\t\t\t\t\"--signin\",\r\n\t\t\t\t\t\"--address\", sign_in_address,\r\n\t\t\t\t\t\"--email\", email_address,\r\n\t\t\t\t\t\"--secret-key\", secret_key,\r\n\t\t\t\t\t\"--shorthand\", shorthand,\r\n\t\t\t\t\t\"--raw\"\r\n\t\t\t\t]\r\n\t\t\telse:\r\n\t\t\t\targs = [\r\n\t\t\t\t\t\"signin\",\r\n\t\t\t\t\t\"--account\", shorthand,\r\n\t\t\t\t\t\"--raw\"\r\n\t\t\t\t]\r\n\t\telse:\r\n\t\t\tadd_account = True\r\n\t\t\targs = [\r\n\t\t\t\t\"signin\",\r\n\t\t\t\tsign_in_address,\r\n\t\t\t\temail_address,\r\n\t\t\t\tsecret_key,\r\n\t\t\t\t\"--shorthand\", shorthand,\r\n\t\t\t\t\"--raw\"\r\n\t\t\t]\r\n\r\n\t\teof = None\r\n\t\tproc = None\r\n\r\n\t\tif RoyalUtils.is_macOS():\r\n\t\t\teof = pexpect.EOF\r\n\t\t\tproc = pexpect.spawn(cmd, args)\r\n\t\telse:\r\n\t\t\teof = wexpect.EOF\r\n\t\t\tproc = wexpect.spawn(cmd, args)\r\n\r\n\t\texp_str_password = f\"Enter the password for.*:\"\r\n\t\texp_str_error = \"\\[ERROR\\].*\"\r\n\t\texp_str_biometric_unlock_enabled = \"Biometric unlock integration with the 1Password app is enabled*\"\r\n\t\texp_str_add_account = \"Do you want to add an account manually now?\"\r\n\r\n\t\terr = None\r\n\r\n\t\ttry:\r\n\t\t\texp_pw_prompt = proc.expect([ exp_str_password, exp_str_error, exp_str_biometric_unlock_enabled, exp_str_add_account ], timeout=timeout)\r\n\r\n\t\t\tif exp_pw_prompt == 0: # Password Prompt\r\n\t\t\t\tproc.sendline(master_password)\r\n\r\n\t\t\t\texp_str_mfa = \"Enter your.*authentication code.*:\"\r\n\r\n\t\t\t\texp_mfa = proc.expect([ exp_str_mfa, exp_str_error, eof ], timeout=timeout)\r\n\r\n\t\t\t\tif exp_mfa == 0: # MFA Prompt\r\n\t\t\t\t\tmfa_code = RoyalInputPrompt.show(\"1Password Multi-Factor-Authentication\", f\"Enter multi-factor authentication code for {email_address}:\", \"\")\r\n\t\t\t\t\tmfa_code = mfa_code.replace(\"\\n\", \"\").replace(\"\\r\", \"\")\r\n\r\n\t\t\t\t\tif not mfa_code:\r\n\t\t\t\t\t\traise Exception(\"No multi-factor code provided\")\r\n\t\t\t\t\t\r\n\t\t\t\t\tproc.sendline(mfa_code)\r\n\t\t\t\t\texp_mfa_sent = proc.expect([ exp_str_error, eof ], timeout=timeout)\r\n\r\n\t\t\t\t\tif exp_mfa_sent == 0: # Error\r\n\t\t\t\t\t\terr = RoyalUtils.get_last_line(RoyalUtils.decode_to_utf8_string(proc.match.string))\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\traise Exception(err)\r\n\t\t\t\telif exp_mfa == 1: # Error\r\n\t\t\t\t\terr = RoyalUtils.get_last_line(RoyalUtils.decode_to_utf8_string(proc.match.string))\r\n\t\t\t\t\t\r\n\t\t\t\t\traise Exception(err)\r\n\r\n\t\t\t\toutput = proc.before\r\n\r\n\t\t\t\tif output:\r\n\t\t\t\t\toutput = RoyalUtils.decode_to_utf8_string(output)\r\n\t\t\t\t\r\n\t\t\t\tproc.close()\r\n\t\t\t\texit_code = proc.wait()\r\n\t\t\t\t\r\n\t\t\t\tsuccess = exit_code == 0\r\n\r\n\t\t\t\tif success:\r\n\t\t\t\t\tself.session_token = RoyalUtils.get_last_line(output)\r\n\t\t\t\t\tself.account_shorthand = shorthand\r\n\t\t\t\telse:\r\n\t\t\t\t\tif not err:\r\n\t\t\t\t\t\terr = self.unknown_error_string\r\n\r\n\t\t\t\t\traise Exception(err)\r\n\t\t\telif exp_pw_prompt == 1: # Error\r\n\t\t\t\terr = RoyalUtils.get_last_line(RoyalUtils.decode_to_utf8_string(proc.match.string))\r\n\r\n\t\t\t\tif not second_try:\r\n\t\t\t\t\tif \"No saved device ID\" in err:\r\n\t\t\t\t\t\texport_start_str = \"export OP_DEVICE=\"\r\n\t\t\t\t\t\tdevice_id = \"\"\r\n\r\n\t\t\t\t\t\tif export_start_str in err:\r\n\t\t\t\t\t\t\tstart_index = err.index(export_start_str) + len(export_start_str)\r\n\t\t\t\t\t\t\tdevice_id = err[start_index:]\r\n\t\t\t\t\t\t\tend_index = device_id.index(\"`\")\r\n\t\t\t\t\t\t\tdevice_id = device_id[:end_index]\r\n\r\n\t\t\t\t\t\tif not device_id or len(device_id) != 26:\r\n\t\t\t\t\t\t\tdevice_id = RoyalUtils.random_uuid()\r\n\r\n\t\t\t\t\t\tself.set_device_id(device_id)\r\n\r\n\t\t\t\t\t\tself.sign_in(sign_in_address, email_address, secret_key, master_password, second_try=True, add_account=add_account)\r\n\r\n\t\t\t\t\t\treturn\r\n\r\n\t\t\t\tif not add_account:\r\n\t\t\t\t\t# Try resolving the error by re-adding the account\r\n\t\t\t\t\treturn self.sign_in(sign_in_address, email_address, secret_key, master_password, second_try, add_account=True)\r\n\r\n\t\t\t\tif not err:\r\n\t\t\t\t\terr = self.unknown_error_string\r\n\r\n\t\t\t\traise Exception(err)\r\n\t\t\telif exp_pw_prompt == 2: # Biometric unlock enabled\r\n\t\t\t\terr = \"Biometric unlock integration with the 1Password app is enabled. This feature is not supported by the 1Password Dynamic Folder Script. Please disable biometric unlock in the 1Password app.\"\r\n\t\t\t\t\r\n\t\t\t\traise Exception(err)\r\n\t\t\telif exp_pw_prompt == 3: # Account doesn't exist yet\r\n\t\t\t\treturn self.sign_in(sign_in_address, email_address, secret_key, master_password, second_try, add_account=True)\r\n\t\texcept Exception as ex:\r\n\t\t\terr = str(ex)\r\n\r\n\t\t\tif not err:\r\n\t\t\t\terr = self.unknown_error_string\r\n\r\n\t\t\traise Exception(err)\r\n\r\n\tdef get_vaults(self):\r\n\t\tcmd_list_vaults = [ ]\r\n\r\n\t\tif self.is_op_cli_v2:\r\n\t\t\tcmd_list_vaults = [\r\n\t\t\t\tself.op_path,\r\n\t\t\t\t\"vault\", \"list\",\r\n\t\t\t\t\"--format=json\",\r\n\t\t\t\t\"--account\", self.account_shorthand,\r\n\t\t\t\t\"--session\", self.session_token\r\n\t\t\t]\r\n\t\telse:\r\n\t\t\tcmd_list_vaults = [\r\n\t\t\t\tself.op_path,\r\n\t\t\t\t\"list\", \"vaults\",\r\n\t\t\t\t\"--account\", self.account_shorthand,\r\n\t\t\t\t\"--session\", self.session_token\r\n\t\t\t]\r\n\t\t\r\n\t\top = subprocess.Popen(cmd_list_vaults, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\r\n\r\n\t\t(output, err) = op.communicate()\r\n\t\texit_code = op.wait()\r\n\r\n\t\tsuccess = exit_code == 0\r\n\r\n\t\tif success:\r\n\t\t\toutput = RoyalUtils.decode_to_utf8_string(output)\r\n\r\n\t\t\tvaults_str = \"\"\r\n\r\n\t\t\tif self.is_op_cli_v2:\r\n\t\t\t\tvaults_str = output\r\n\t\t\telse:\r\n\t\t\t\tvaults_str = RoyalUtils.get_last_line(output)\r\n\t\t\t\r\n\t\t\tvaults = json.loads(vaults_str)\r\n\r\n\t\t\treturn vaults\r\n\t\t\r\n\t\tif not err:\r\n\t\t\terr = self.unknown_error_string\r\n\t\telse:\r\n\t\t\terr = RoyalUtils.decode_to_utf8_string(err)\r\n\t\t\r\n\t\traise Exception(err)\r\n\r\n\tdef get_items(self, vault):\r\n\t\tcmd_list_items = [ ]\r\n\r\n\t\tif self.is_op_cli_v2:\r\n\t\t\tcmd_list_items = [\r\n\t\t\t\tself.op_path,\r\n\t\t\t\t\"item\", \"list\",\r\n\t\t\t\t\"--format=json\",\r\n\t\t\t\t\"--account\", self.account_shorthand,\r\n\t\t\t\t\"--session\", self.session_token\r\n\t\t\t]\r\n\t\telse:\r\n\t\t\tcmd_list_items = [\r\n\t\t\t\tself.op_path,\r\n\t\t\t\t\"list\", \"items\",\r\n\t\t\t\t\"--account\", self.account_shorthand,\r\n\t\t\t\t\"--session\", self.session_token\r\n\t\t\t]\r\n\t\t\r\n\t\tif not vault:\r\n\t\t\tvault = \"\"\r\n\t\t\r\n\t\tvault = vault.strip()\r\n\t\t\r\n\t\tif vault:\r\n\t\t\tcmd_list_items.append(\"--vault\")\r\n\t\t\tcmd_list_items.append(vault)\r\n\r\n\t\top = subprocess.Popen(cmd_list_items, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\r\n\r\n\t\t(output, err) = op.communicate()\r\n\t\texit_code = op.wait()\r\n\r\n\t\tsuccess = exit_code == 0\r\n\r\n\t\tif success:\r\n\t\t\toutput = RoyalUtils.decode_to_utf8_string(output)\r\n\r\n\t\t\titems_str = \"\"\r\n\r\n\t\t\tif self.is_op_cli_v2:\r\n\t\t\t\titems_str = output\r\n\t\t\telse:\r\n\t\t\t\titems_str = RoyalUtils.get_last_line(output)\r\n\r\n\t\t\titems = json.loads(items_str)\r\n\t\t\r\n\t\t\treturn items\r\n\t\telse:\r\n\t\t\tif not err:\r\n\t\t\t\terr = self.unknown_error_string\r\n\t\t\telse:\r\n\t\t\t\terr = RoyalUtils.decode_to_utf8_string(err)\r\n\t\t\r\n\t\t\traise Exception(err)\r\n\r\n\tdef get_item_details(self, item_id):\r\n\t\tcmd_get_item = [ ]\r\n\r\n\t\tif self.is_op_cli_v2:\r\n\t\t\tcmd_get_item = [\r\n\t\t\t\tself.op_path,\r\n\t\t\t\t\"item\", \"get\", item_id,\r\n\t\t\t\t# \"--fields\", \"label=password,label=privatekey\",\r\n\t\t\t\t\"--format=JSON\",\r\n\t\t\t\t\"--account\", self.account_shorthand,\r\n\t\t\t\t\"--session\", self.session_token\r\n\t\t\t]\r\n\t\telse:\r\n\t\t\tcmd_get_item = [\r\n\t\t\t\tself.op_path,\r\n\t\t\t\t\"get\", \"item\", item_id,\r\n\t\t\t\t\"--fields\", \"username,password\",\r\n\t\t\t\t\"--format\", \"JSON\",\r\n\t\t\t\t\"--account\", self.account_shorthand,\r\n\t\t\t\t\"--session\", self.session_token\r\n\t\t\t]\r\n\r\n\t\top = subprocess.Popen(cmd_get_item, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\r\n\r\n\t\t(output, err) = op.communicate()\r\n\t\texit_code = op.wait()\r\n\r\n\t\tsuccess = exit_code == 0\r\n\r\n\t\tif success:\r\n\t\t\toutput = RoyalUtils.decode_to_utf8_string(output)\r\n\r\n\t\t\titem_str = \"\"\r\n\r\n\t\t\tif self.is_op_cli_v2:\r\n\t\t\t\titem_str = output\r\n\t\t\telse:\r\n\t\t\t\titem_str = RoyalUtils.get_last_line(output)\r\n\t\t\t\r\n\t\t\titem = json.loads(item_str)\r\n\t\t\r\n\t\t\treturn item\r\n\t\telse:\r\n\t\t\tif not err:\r\n\t\t\t\terr = self.unknown_error_string\r\n\t\t\telse:\r\n\t\t\t\terr = RoyalUtils.decode_to_utf8_string(err)\r\n\t\t\t\r\n\t\t\traise Exception(err)\r\n\r\nclass Converter:\r\n\t@staticmethod\r\n\tdef get_vault_name(vaults, vault_id, is_op_cli_v2):\r\n\t\tfor vault in vaults:\r\n\t\t\tif is_op_cli_v2:\r\n\t\t\t\tif vault.get(\"id\", \"\") == vault_id:\r\n\t\t\t\t\treturn vault.get(\"name\", \"\")\r\n\t\t\telse:\r\n\t\t\t\tif vault.get(\"uuid\", \"\") == vault_id:\r\n\t\t\t\t\treturn vault.get(\"name\", \"\")\r\n\t\t\r\n\t\treturn \"\"\r\n\r\n\t@staticmethod\r\n\tdef convert_items(vaults, items, is_op_cli_v2):\r\n\t\tobjects = []\r\n\r\n\t\tfor item in items:\r\n\t\t\toverview = None\r\n\r\n\t\t\tif is_op_cli_v2:\r\n\t\t\t\toverview = item\r\n\t\t\telse:\r\n\t\t\t\toverview = item.get(\"overview\", None)\r\n\r\n\t\t\tif overview == None:\r\n\t\t\t\tcontinue\r\n\r\n\t\t\tid = \"\"\r\n\r\n\t\t\tif is_op_cli_v2:\r\n\t\t\t\tid = item.get(\"id\", \"\")\r\n\t\t\telse:\r\n\t\t\t\tid = item.get(\"uuid\", \"\")\r\n\t\t\t\r\n\t\t\ttitle = overview.get(\"title\", \"N/A\")\r\n\t\t\turl = overview.get(\"url\", \"\")\r\n\r\n\t\t\tvault_id = \"\"\r\n\r\n\t\t\tif is_op_cli_v2:\r\n\t\t\t\titem_vault = item.get(\"vault\", None)\r\n\r\n\t\t\t\tif item_vault:\r\n\t\t\t\t\tvault_id = item_vault.get(\"id\", \"\")\r\n\t\t\telse:\r\n\t\t\t\tvault_id = item.get(\"vaultUuid\", \"\")\r\n\r\n\t\t\tvault_name = Converter.get_vault_name(vaults, vault_id, is_op_cli_v2)\r\n\r\n\t\t\titem_details = item.get(\"__item_details\", None)\r\n\t\t\tconverted_item_details = None\r\n\r\n\t\t\tif item_details is not None:\r\n\t\t\t\tconverted_item_details = Converter.convert_item(item_details, is_op_cli_v2)\r\n\r\n\t\t\tcred_type = \"DynamicCredential\" if converted_item_details is None else \"Credential\"\r\n\r\n\t\t\tcred = {\r\n\t\t\t\t\"Type\": cred_type,\r\n\t\t\t\t\"ID\": id,\r\n\t\t\t\t\"Name\": title,\r\n\t\t\t\t\"Path\": vault_name\r\n\t\t\t}\r\n\r\n\t\t\tif url != \"\":\r\n\t\t\t\tcred[\"URL\"] = url\r\n\t\t\t\r\n\t\t\tif converted_item_details is not None:\r\n\t\t\t\tfor key in converted_item_details:\r\n\t\t\t\t\tcred[key] = converted_item_details[key]\r\n\r\n\t\t\tobjects.append(cred)\r\n\r\n\t\tobjects = sorted(objects, key = lambda i: (i[\"Path\"], i[\"Name\"]))\r\n\r\n\t\tstore = {\r\n\t\t\t\"Objects\": objects\r\n\t\t}\r\n\r\n\t\treturn store\r\n\t\r\n\t@staticmethod\r\n\tdef convert_item(item_details, is_op_cli_v2):\r\n\t\tusername = None\r\n\t\tpassword = None\r\n\t\tprivate_key = None\r\n\r\n\t\tif is_op_cli_v2:\r\n\t\t\tfields = item_details.get(\"fields\")\r\n\r\n\t\t\tif not fields:\r\n\t\t\t\tfields = item_details\r\n\r\n\t\t\tfor field in fields:\r\n\t\t\t\tfield_id = field.get(\"id\", None)\r\n\t\t\t\tfield_label = field.get(\"label\", None)\r\n\t\t\t\tfield_value = field.get(\"value\", None)\r\n\r\n\t\t\t\tif field_id == \"username\" or field_label == \"username\":\r\n\t\t\t\t\tusername = field_value\r\n\t\t\t\telif field_id == \"password\" or field_label == \"password\":\r\n\t\t\t\t\tpassword = field_value\r\n\t\t\t\telif field_id == \"private_key\" or field_label == \"private key\":\r\n\t\t\t\t\tprivate_key = field_value\r\n\t\telse:\r\n\t\t\tusername = item_details.get(\"username\", None)\r\n\t\t\tpassword = item_details.get(\"password\", None)\r\n\r\n\t\tcred = { }\r\n\r\n\t\tif username is not None:\r\n\t\t\tcred[\"Username\"] = username\r\n\r\n\t\tif password is not None:\r\n\t\t\tcred[\"Password\"] = password\r\n\r\n\t\tif private_key is not None:\r\n\t\t\tcred[\"KeyFileContent\"] = private_key\r\n\r\n\t\treturn cred\r\n\r\nclass Coordinator:\r\n\top_path = \"\"\r\n\tsign_in_address = \"\"\r\n\temail_address = \"\"\r\n\tsecret_key = \"\"\r\n\tmaster_password = \"\"\r\n\tcreate_dynamic_credentials = True\r\n\r\n\terror_message_sign_in = \"Error while signing in: \"\r\n\terror_message_sign_out = \"Error while signing out: \"\r\n\terror_message_get_vaults = \"Error while getting vaults: \"\r\n\terror_message_get_items = \"Error while getting items: \"\r\n\terror_message_get_item_details = \"Error while getting item details: \"\r\n\r\n\tdef __init__(self, op_path_windows, op_path_macOS, sign_in_address, email_address, secret_key, master_password, create_dynamic_credentials):\r\n\t\tself.op_path = op_path_macOS if RoyalUtils.is_macOS() else op_path_windows\r\n\t\tself.sign_in_address = sign_in_address\r\n\t\tself.email_address = email_address\r\n\t\tself.secret_key = secret_key\r\n\t\tself.master_password = master_password\r\n\t\tself.create_dynamic_credentials = create_dynamic_credentials\r\n\t\t\r\n\tdef get_items(self, vault):\r\n\t\top = OnePassword(self.op_path)\r\n\r\n\t\ttry:\r\n\t\t\top.sign_out()\r\n\t\texcept Exception:\r\n\t\t\tpass\r\n\r\n\t\ttry:\r\n\t\t\top.sign_in(self.sign_in_address, self.email_address, self.secret_key, self.master_password)\r\n\t\texcept Exception as e:\r\n\t\t\tRoyalUtils.exit_with_error(self.error_message_sign_in, e)\r\n\r\n\t\tvaults = None\r\n\r\n\t\ttry:\r\n\t\t\tvaults = op.get_vaults()\r\n\t\texcept Exception as e:\r\n\t\t\tRoyalUtils.exit_with_error(self.error_message_get_vaults, e)\r\n\t\t\r\n\t\titems = None\r\n\r\n\t\ttry:\r\n\t\t\titems = op.get_items(vault)\r\n\t\texcept Exception as e:\r\n\t\t\tRoyalUtils.exit_with_error(self.error_message_get_items, e)\r\n\t\t\r\n\t\titems_details = [ ]\r\n\r\n\t\tif not self.create_dynamic_credentials:\r\n\t\t\tfor item in items:\r\n\t\t\t\tid = \"\"\r\n\r\n\t\t\t\tif op.is_op_cli_v2:\r\n\t\t\t\t\tid = item.get(\"id\", \"\")\r\n\t\t\t\telse:\r\n\t\t\t\t\tid = item.get(\"uuid\", \"\")\r\n\t\t\t\t\r\n\t\t\t\titem_details = op.get_item_details(id)\r\n\r\n\t\t\t\titem[\"__item_details\"] = item_details\r\n\r\n\t\ttry:\r\n\t\t\top.sign_out()\r\n\t\texcept Exception as e:\r\n\t\t\tRoyalUtils.exit_with_error(self.error_message_sign_out, e)\r\n\r\n\t\tstore = Converter.convert_items(vaults, items, op.is_op_cli_v2)\r\n\t\tstore_json = RoyalUtils.to_json(store, True)\r\n\r\n\t\tprint(store_json)\r\n\t\r\n\tdef get_item_details(self, item_id):\r\n\t\top = OnePassword(self.op_path)\r\n\r\n\t\ttry:\r\n\t\t\top.sign_out()\r\n\t\texcept Exception:\r\n\t\t\tpass\r\n\r\n\t\ttry:\r\n\t\t\top.sign_in(self.sign_in_address, self.email_address, self.secret_key, self.master_password)\r\n\t\texcept Exception as e:\r\n\t\t\tRoyalUtils.exit_with_error(self.error_message_sign_in, e)\r\n\r\n\t\titem_details = None\r\n\r\n\t\ttry:\r\n\t\t\titem_details = op.get_item_details(item_id)\r\n\t\texcept Exception as e:\r\n\t\t\tRoyalUtils.exit_with_error(self.error_message_get_item_details, e)\r\n\r\n\t\ttry:\r\n\t\t\top.sign_out()\r\n\t\texcept Exception as e:\r\n\t\t\tRoyalUtils.exit_with_error(self.error_message_sign_out, e)\r\n\r\n\t\tstore = Converter.convert_item(item_details, op.is_op_cli_v2)\r\n\t\tstore_json = RoyalUtils.to_json(store, True)\r\n\r\n\t\tprint(store_json)\r\n\r\ncoordinator = Coordinator(op_path_windows, op_path_macOS, sign_in_address, email_address, secret_key, master_password, create_dynamic_credentials)\r\n# coordinator.get_items(filter_vault)\r\ncoordinator.get_item_details(item_id)" - } - ] -} diff --git a/Dynamic Folder/1Password/1Password v8 (Python).rdfx b/Dynamic Folder/1Password/1Password v8 (Python).rdfx new file mode 100644 index 0000000..a337fa2 --- /dev/null +++ b/Dynamic Folder/1Password/1Password v8 (Python).rdfx @@ -0,0 +1,573 @@ + + Dynamic Folder Export + + + DynamicFolder + 1Password v8+ (Python) + This Dynamic Folder sample allows you to import dynamic credentials from 1Password v8+ + + + +

1Password v8+ Dynamic Folder sample

+ +

This Dynamic Folder sample allows you to import credentials from 1Password. It requires both the 1Password app (version 8 or above) and the 1Password CLI tool (version 2.19 or above). The 1Password CLI tool must be installed, and the path where it is installed must be configured in the "Custom Properties" section. You also need to turn on the 1Password CLI/desktop integration in the 1Password app (Settings -> Developer -> enable "Integrate with 1Password CLI").

+ +

Items are imported as Dynamic Credentials. This means that the username and password fields will remain empty after reloading the dynamic folder and only be requested when a connection is established that uses one of the credentials of this dynamic folder.

+ +

By default, the last signed in account in 1Password is used (this is defined by the 1Password CLI tool). If you require fetching from a specific account, you can specify this in the "Account" custom property.

+ +

By default, items of all vaults are imported. If you only want to retrieve items of a specific vault (or a list of specific vaults, comma-separated), you can configure the "Vaults" custom property.

+ +

Requirements

+ +
    +
  • Royal TS v7 or higher / Royal TSX v6 or higher
  • +
  • 1Password CLI tool (Version 2+)
  • +
  • Python 3 (Python 2 is not supported)
  • +
  • Python Module: sys
  • +
  • Python Module: json
  • +
  • Python Module: subprocess
  • +
+ +

 

+ +

Setup

+ +
    +
  • Specify the full, absolute path to the 1Password command-line tool in the "OP Path" variable in the "Custom Properties" section.
  • +
  • Optionally specify the 1Password account ID (found via op account list) in the "Account" variable in the "Custom Properties" section.
  • +
  • Optionally specify the vault ID or ID's (via op vault list) you want to filter on in the "Vaults" variable in the "Custom Properties" section.
  • +
+]]>
+ + + 1Password CLI path + Header + + + + OP Path (Windows) + Text + C:\Program Files\1Password CLI\op.exe + + + OP Path (macOS) + Text + /usr/local/bin/op + + + Filters + Header + + + + Account + Text + + + + Vaults + Text + + + + python + + python + +
+
+
\ No newline at end of file