Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
2 additions
and
0 deletions.
There are no files selected for viewing
1 change: 1 addition & 0 deletions
1
Dynamic Folder/Pleasant Password Server/Pleasant Password (Python).rdfe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"Name":"Dynamic Folder Export","Objects":[{"Type":"DynamicFolder","Name":"Pleasant Password","Notes":"<h2><strong>Dynamic Folder sample for Pleasant Password Server</strong></h2>\n\n<p>This Dynamic Folder sample for Pleasant Password Server supports Dynamic Credentials and Multi-Factor-Authentication (MFA).</p>\n\n<h3><strong>Setup</strong></h3>\n\n<ul>\n\t<li>Enter your "Server URL" in the "Custom Properties" section.</li>\n\t<li>Enter or assign your Pleasant Password Server credentials.</li>\n</ul>\n","CustomProperties":[{"Name":"Server URL","Type":"URL","Value":"TODO"}],"ScriptInterpreter":"python","DynamicCredentialScriptInterpreter":"python","DynamicCredentialScript":"import json\nimport requests\nimport urllib3\nfrom Tkinter import *\n\nclass TakeInput(object):\n def __init__(self, request_message):\n self.root = Tk()\n\n self.root.title('')\n self.string = ''\n\n self.frame = Frame(self.root)\n self.frame.pack()\n\n self.acceptInput(request_message)\n\n def acceptInput(self, request_message):\n r = self.frame\n\n k = Label(r, text=request_message)\n k.pack(side='left')\n self.e = Entry(r, text='Name')\n self.e.pack(side='left')\n self.e.focus_set()\n b = Button(r, text='OK', command=self.gettext)\n b.pack(side='right')\n\n def gettext(self):\n self.string = self.e.get()\n self.root.destroy()\n\n def getString(self):\n return self.string\n\n def waitForInput(self):\n self.root.lift()\n self.root.attributes('-topmost', True)\n self.root.after_idle(self.root.attributes, '-topmost', False)\n\n self.root.mainloop()\n\n\ndef show_prompt(request_message):\n msg_box = TakeInput(request_message)\n\n # loop until the user makes a decision and the window is destroyed\n\n msg_box.waitForInput()\n\n return msg_box.getString()\n\n\ndef call_token_endpoint(url, body, otp_headers):\n token_json = requests.post(url + \"/OAuth2/Token\", data=body, verify=False, headers=otp_headers)\n\n return token_json\n\n\ndef get_dynamic_credential(url, username, password, credential_id):\n urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)\n\n token_params = {\n \"grant_type\": \"password\",\n \"username\": username,\n \"password\": password\n }\n\n token_json = call_token_endpoint(url, token_params, None)\n\n if not token_json.ok:\n if \"X-Pleasant-OTP\" in token_json.headers and token_json.headers[\"X-Pleasant-OTP\"] == \"required\":\n otp_provider = token_json.headers[\"X-Pleasant-OTP-Provider\"]\n\n otp_token = show_prompt(\"Enter your OTP for MFA (\" + otp_provider + \"):\")\n\n if not otp_token:\n print >> sys.stderr, \"No token for MFA provided\"\n return \"\"\n\n otp_headers = {\n \"X-Pleasant-OTP-Provider\": otp_provider,\n \"X-Pleasant-OTP\": otp_token\n }\n\n token_json = call_token_endpoint(url, token_params, otp_headers)\n else:\n print >> sys.stderr, \"An unknown error occurred\"\n return \"\"\n\n token = json.loads(token_json.content)[\"access_token\"]\n\n headers = {\n \"Accept\": \"application/json\",\n \"Authorization\": token\n }\n\n credential_password_json = requests.get(url + \"/api/v4/rest/credential/\" + credential_id + \"/password\", headers=headers, verify=False)\n credential_password = json.loads(credential_password_json.content)\n\n credential = {\n \"Password\": credential_password\n }\n\n credential_json = json.dumps(credential)\n\n return credential_json\n \n\nprint(get_dynamic_credential(\"$CustomProperty.ServerURL$\", \"$EffectiveUsername$\", \"$EffectivePassword$\", \"$DynamicCredential.EffectiveID$\"))","Script":"import json\nimport requests\nimport urllib3\nfrom Tkinter import *\n\nclass TakeInput(object):\n def __init__(self, request_message):\n self.root = Tk()\n\n self.root.title('')\n self.string = ''\n\n self.frame = Frame(self.root)\n self.frame.pack()\n\n self.acceptInput(request_message)\n\n def acceptInput(self, request_message):\n r = self.frame\n\n k = Label(r, text=request_message)\n k.pack(side='left')\n self.e = Entry(r, text='Name')\n self.e.pack(side='left')\n self.e.focus_set()\n b = Button(r, text='OK', command=self.gettext)\n b.pack(side='right')\n\n def gettext(self):\n self.string = self.e.get()\n self.root.destroy()\n\n def getString(self):\n return self.string\n\n def waitForInput(self):\n self.root.lift()\n self.root.attributes('-topmost', True)\n self.root.after_idle(self.root.attributes, '-topmost', False)\n\n self.root.mainloop()\n\n\ndef show_prompt(request_message):\n msg_box = TakeInput(request_message)\n\n # loop until the user makes a decision and the window is destroyed\n\n msg_box.waitForInput()\n\n return msg_box.getString()\n\n\ndef convert_notes_to_html(notes):\n if notes is None:\n return \"\"\n else:\n return notes.replace(\"\\r\\n\", \"<br />\").replace(\"\\r\", \"<br />\").replace(\"\\n\", \"<br />\")\n\n\ndef create_credential(url, headers, credential):\n credential_id = credential[\"Id\"]\n credential_name = credential[\"Name\"]\n credential_url = credential[\"Url\"]\n credential_username = credential[\"Username\"]\n credential_notes = convert_notes_to_html(credential[\"Notes\"])\n credential_custom_properties = credential[\"CustomUserFields\"]\n credential_color = \"\"\n\n credential_custom_app_fields = credential.get(\"CustomApplicationFields\", None)\n\n if credential_custom_app_fields is not None:\n credential_color = credential_custom_app_fields.get(\"ForegroundColor\", \"\")\n\n credential_description = \"\"\n\n for tag in credential[\"Tags\"]:\n tag_name = tag[\"Name\"]\n credential_description += tag_name + \", \"\n\n if credential_description.endswith(\", \"):\n credential_description = credential_description[:len(credential_description) - 2]\n\n credential = {\n \"Type\": \"DynamicCredential\",\n \"ID\": credential_id,\n \"Name\": credential_name,\n \"Color\": credential_color,\n \"URL\": credential_url,\n \"Username\": credential_username,\n \"Notes\": credential_notes,\n \"Description\": credential_description,\n \"CustomProperties\": credential_custom_properties\n }\n\n return credential\n\n\ndef create_credential_group(url, headers, credential_group):\n folder_id = credential_group[\"Id\"]\n folder_name = credential_group[\"Name\"]\n folder_notes = convert_notes_to_html(credential_group[\"Notes\"])\n\n folder_objects = []\n\n for sub_credential_group in credential_group[\"Children\"]:\n folder_object = create_credential_group(url, headers, sub_credential_group)\n folder_objects.append(folder_object)\n\n for credential in credential_group[\"Credentials\"]:\n credential_object = create_credential(url, headers, credential)\n folder_objects.append(credential_object)\n\n folder = {\n \"Type\": \"Folder\",\n \"ID\": folder_id,\n \"Name\": folder_name,\n \"Notes\": folder_notes,\n \"Objects\": folder_objects\n }\n\n # No need to create the root folder\n if credential_group[\"ParentId\"] == \"00000000-0000-0000-0000-000000000000\" and folder_name == \"Root\":\n return folder_objects\n\n return folder\n\n\ndef call_token_endpoint(url, body, otp_headers):\n token_json = requests.post(url + \"/OAuth2/Token\", data=body, verify=False, headers=otp_headers)\n\n return token_json\n\n\ndef get_entries(url, username, password):\n urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)\n\n token_params = {\n \"grant_type\": \"password\",\n \"username\": username,\n \"password\": password\n }\n\n token_json = call_token_endpoint(url, token_params, None)\n\n if not token_json.ok:\n if \"X-Pleasant-OTP\" in token_json.headers and token_json.headers[\"X-Pleasant-OTP\"] == \"required\":\n otp_provider = token_json.headers[\"X-Pleasant-OTP-Provider\"]\n\n otp_token = show_prompt(\"Enter your OTP for MFA (\" + otp_provider + \"):\")\n\n if not otp_token:\n print >> sys.stderr, \"No token for MFA provided\"\n return \"\"\n\n otp_headers = {\n \"X-Pleasant-OTP-Provider\": otp_provider,\n \"X-Pleasant-OTP\": otp_token\n }\n\n token_json = call_token_endpoint(url, token_params, otp_headers)\n else:\n print >> sys.stderr, \"An unknown error occurred\"\n return \"\"\n\n token = json.loads(token_json.content)[\"access_token\"]\n\n headers = {\n \"Accept\": \"application/json\",\n \"Authorization\": token\n }\n\n credential_groups_json = requests.get(url + \"/api/v4/rest/credentialgroup\", headers=headers, verify=False)\n credential_groups = json.loads(credential_groups_json.content)\n\n store_objects = []\n\n if credential_groups is not list:\n credential_groups = [credential_groups]\n\n for credentialGroup in credential_groups:\n folder = create_credential_group(url, headers, credentialGroup)\n store_objects.extend(folder)\n\n store = {\n \"Objects\": store_objects\n }\n\n store_json = json.dumps(store)\n\n return store_json\n \n\nprint(get_entries(\"$CustomProperty.ServerURL$\", \"$EffectiveUsername$\", \"$EffectivePassword$\"))"}]} |
1 change: 1 addition & 0 deletions
1
Dynamic Folder/Thycotic Secret Server/Thycotic Secret Server (PowerShell).rdfe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"Name":"Dynamic Folder Export","Objects":[{"Type":"DynamicFolder","Name":"Thycotic Secret Server","Description":"Dynamic Folder Sample for Secret Server","Notes":"<h2><strong>Dynamic Folder sample for Secret Server</strong></h2>\n\n<p>This Dynamic Folder sample for Thycotic Secret Server supports Dynamic Credentials and Multi-Factor-Authentication (MFA).</p>\n\n<h3><strong>Setup</strong></h3>\n\n<ul>\n\t<li>Enter your "Server URL" in the "Custom Properties" section.</li>\n\t<li>Enter or assign your Secret Server credentials.</li>\n\t<li>If MFA is required by your server/user, enable it by setting "<span style=\"font-family:courier new,courier,monospace;\">-requiresMFA</span>" to "<span style=\"font-family:courier new,courier,monospace;\">$true</span>" instead of "<span style=\"font-family:courier new,courier,monospace;\">$false</span>" in the last line of both scripts.</li>\n</ul>\n","CustomProperties":[{"Name":"Server URL","Type":"URL","Value":"TODO"}],"ScriptInterpreter":"powershell","DynamicCredentialScriptInterpreter":"powershell","DynamicCredentialScript":"$ErrorActionPreference = \"Stop\"\n\nfunction Is-MacOS() {\n [String]$os = $PSVersionTable.OS\n\n return $os.StartsWith(\"darwin\", [System.StringComparison]::CurrentCultureIgnoreCase)\n}\n\nfunction Run-Native([String] $command, [Array] $commandArgs) {\n $env:commandlineargumentstring=($commandArgs | %{'\"'+ ($_ -replace '(\\\\*)\"','$1$1\\\"' -replace '(\\\\*)$','$1$1') + '\"'}) -join ' ';\n return & $command --% %commandlineargumentstring%\n}\n\nfunction Show-Prompt-Mac([String] $prompt, [String] $defaultValue) {\n $command = \"/usr/bin/osascript\"\n $script = \"set resp to text returned of (display dialog \"\"$prompt\"\" default answer \"\"$defaultValue\"\" buttons {\"\"Cancel\"\", \"\"OK\"\"} default button \"\"OK\"\")\"\n $commandArgs = @( \"-e\", $script )\n\n $ret = Run-Native -command $command -commandArgs @( \"-e\", $script )\n\n return $ret\n}\n\nfunction Show-Prompt-Windows([String] $prompt, [String] $defaultValue) {\n [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null\n $ret = [Microsoft.VisualBasic.Interaction]::InputBox($prompt, \"\", $defaultValue)\n\n return $ret\n}\n\nfunction Show-Prompt([String] $prompt, [String] $defaultValue) {\n if (Is-MacOS) {\n return Show-Prompt-Mac -prompt $prompt -defaultValue $defaultValue\n } else {\n return Show-Prompt-Windows -prompt $prompt -defaultValue $defaultValue\n }\n}\n\nfunction Convert-Notes-To-HTML ($notes) {\n $notes -Replace \"\\r\\n\", \"<br />\" -Replace \"\\r\", \"<br />\" -Replace \"\\n\", \"<br />\"\n}\n\n$SLUGS_USERNAME = ( \"username\", \"licensed-to\" );\n$SLUGS_DOMAIN = ( \"domain\" );\n$SLUGS_PASSWORD = ( \"password\", \"pin-code\", \"combination\", \"license-key\", \"pin\" );\n$SLUGS_PASSPHRASE = ( \"private-key-passphrase\", \"passphrase\" );\n\nfunction Create-Credential ($restricted) {\n $restrictedItems = $restricted.items\n\n $credentialUsername = \"\"\n $credentialPassword = \"\"\n $credentialPassphrase = \"\"\n \n ForEach ($restrictedItem in $restrictedItems) {\n $restrictedItemValue = $restrictedItem.itemValue\n\n if (!$restrictedItemValue) {\n continue\n }\n\n $slug = $restrictedItem.slug\n \n if ($SLUGS_USERNAME.Contains($slug)) {\n $credentialUsername = $restrictedItemValue\n } elseif ($SLUGS_DOMAIN.Contains($slug)) {\n $credentialDomain = $restrictedItemValue\n } elseif ($SLUGS_PASSWORD.Contains($slug)) {\n $credentialPassword = $restrictedItemValue\n } elseif ($SLUGS_PASSPHRASE.Contains($slug)) {\n $credentialPassphrase = $restrictedItemValue\n }\n }\n\n if ($credentialDomain -and $credentialUsername) {\n $credentialUsername = \"$credentialDomain\\$credentialUsername\"\n }\n \n $credential = New-Object pscustomobject -Property @{\n \"Username\" = $credentialUsername;\n \"Password\" = $credentialPassword;\n \"Passphrase\" = $credentialPassphrase;\n }\n\n return $credential\n}\n\nfunction Get-Credential($url, $username, $password, $requiresMFA, $secretID) {\n $api = \"$url/api/v1\"\n $tokenRoute = \"$url/oauth2/token\";\n\n $tokenParams = @{\n grant_type = \"password\";\n username = $username;\n password = $password;\n }\n\n $headers = $null\n\n If ($requiresMFA) {\n $headers = @{\n \"OTP\" = Show-Prompt -prompt \"Enter your OTP for MFA:\"\n }\n }\n\n $tokenJSON = Invoke-WebRequest -SkipCertificateCheck -Uri $tokenRoute -Method POST -Body $tokenParams -Headers $headers\n $token = (ConvertFrom-Json $tokenJSON.Content).access_token\n\n $headers = @{\n \"Authorization\" = \"Bearer $token\"\n }\n\n $restrictedJSON = Invoke-WebRequest -SkipCertificateCheck -Uri \"$api/secrets/$secretID/restricted\" -Headers $headers -Method POST\n $restricted = (ConvertFrom-Json $restrictedJSON.Content)\n\n $credential = Create-Credential -restricted $restricted\n\n $credentialJSON = (ConvertTo-Json -InputObject $credential -Depth 100)\n \n $credentialJSON\n}\n\nGet-Credential -url \"$CustomProperty.ServerURL$\" -username \"$EffectiveUsername$\" -password \"$EffectivePassword$\" -secretID \"$DynamicCredential.EffectiveID$\" -requiresMFA $false","Script":"$ErrorActionPreference = \"Stop\"\n\nfunction Is-MacOS() {\n [String]$os = $PSVersionTable.OS\n\n return $os.StartsWith(\"darwin\", [System.StringComparison]::CurrentCultureIgnoreCase)\n}\n\nfunction Run-Native([String] $command, [Array] $commandArgs) {\n $env:commandlineargumentstring=($commandArgs | %{'\"'+ ($_ -replace '(\\\\*)\"','$1$1\\\"' -replace '(\\\\*)$','$1$1') + '\"'}) -join ' ';\n return & $command --% %commandlineargumentstring%\n}\n\nfunction Show-Prompt-Mac([String] $prompt, [String] $defaultValue) {\n $command = \"/usr/bin/osascript\"\n $script = \"set resp to text returned of (display dialog \"\"$prompt\"\" default answer \"\"$defaultValue\"\" buttons {\"\"Cancel\"\", \"\"OK\"\"} default button \"\"OK\"\")\"\n $commandArgs = @( \"-e\", $script )\n\n $ret = Run-Native -command $command -commandArgs @( \"-e\", $script )\n\n return $ret\n}\n\nfunction Show-Prompt-Windows([String] $prompt, [String] $defaultValue) {\n [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null\n $ret = [Microsoft.VisualBasic.Interaction]::InputBox($prompt, \"\", $defaultValue)\n\n return $ret\n}\n\nfunction Show-Prompt([String] $prompt, [String] $defaultValue) {\n if (Is-MacOS) {\n return Show-Prompt-Mac -prompt $prompt -defaultValue $defaultValue\n } else {\n return Show-Prompt-Windows -prompt $prompt -defaultValue $defaultValue\n }\n}\n\nfunction Convert-Notes-To-HTML ($notes) {\n $notes -Replace \"\\r\\n\", \"<br />\" -Replace \"\\r\", \"<br />\" -Replace \"\\n\", \"<br />\"\n}\n\nfunction Create-Credential ($apiURL, $secret, $folderDict) {\n $credentialID = $secret.id\n $credentialName = $secret.name\n\n $folderPath = \"\"\n \n if ($secret.folderId -and $folderDict.ContainsKey($secret.folderId)) {\n $folderPath = $folderDict[$secret.folderId]\n }\n \n $credential = New-Object pscustomobject -Property @{\n \"Type\" = \"DynamicCredential\";\n \"ID\" = $credentialID;\n \"Name\" = $credentialName;\n \"Path\" = $folderPath;\n }\n\n return $credential\n}\n\nfunction Get-Entries($url, $username, $password, $requiresMFA) {\n $api = \"$url/api/v1\"\n $tokenRoute = \"$url/oauth2/token\";\n\n $tokenParams = @{\n grant_type = \"password\";\n username = $username;\n password = $password;\n }\n\n $headers = $null\n\n If ($requiresMFA) {\n $headers = @{\n \"OTP\" = Show-Prompt -prompt \"Enter your OTP for MFA:\"\n }\n }\n\n $tokenJSON = Invoke-WebRequest -SkipCertificateCheck -Uri $tokenRoute -Method POST -Body $tokenParams -Headers $headers\n $token = (ConvertFrom-Json $tokenJSON.Content).access_token\n\n $headers = @{\n \"Authorization\" = \"Bearer $token\"\n }\n\n $foldersRequestBody = @{\n \"paging.take\" = 1000;\n }\n\n $foldersJSON = Invoke-WebRequest -SkipCertificateCheck -Uri \"$api/folders\" -Headers $headers -Body $foldersRequestBody\n $folders = (ConvertFrom-Json $foldersJSON.Content)\n\n $folderDict = @{}\n\n ForEach ($folder in $folders.records) {\n $folderDict.Add($folder.id, $folder.folderPath)\n }\n\n $secretsRequestBody = @{\n \"paging.take\" = 1000;\n }\n\n $secretsJSON = Invoke-WebRequest -SkipCertificateCheck -Uri \"$api/secrets\" -Headers $headers -Body $secretsRequestBody\n $secrets = (ConvertFrom-Json $secretsJSON.Content)\n\n $storeObjects = @()\n\n ForEach ($secret in $secrets.records) {\n $credential = Create-Credential -apiURL $api -secret $secret -folderDict $folderDict\n \n $storeObjects += $credential\n }\n\n $store = New-Object pscustomobject -Property @{\n \"Objects\" = $storeObjects;\n }\n\n $storeJSON = (ConvertTo-Json -InputObject $store -Depth 100)\n \n $storeJSON\n}\n\nGet-Entries -url \"$CustomProperty.ServerURL$\" -username \"$EffectiveUsername$\" -password \"$EffectivePassword$\" -requiresMFA $false"}]} |