Created
September 4, 2020 15:44
-
-
Save bitnot/fa61cfde50cab3d2f807a01fc161a647 to your computer and use it in GitHub Desktop.
Export passwords from "Pleasant Password Server" web API.
This file contains hidden or 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
import requests, json | |
# Look for TODO's | |
YOUR_TREE_ID='<TODO: put your tree UUID from /WebClient/Main/GetTree request>' | |
YOUR_PPS_HOST='TODO.put.your.host.com' | |
BASE_URL = 'https://' + YOUR_PPS_HOST | |
GET_PASS='/WebClient/Main/CopyPasswordPopup?credentialId={}' | |
GET_GROUP='/WebClient/CredentialListGrid/Select?CredentialGroupId={}' | |
GET_TREE='/WebClient/Main/GetTree?id={}' | |
DEFAULT_DATA='sort=Name-asc&page=1&pageSize=100&group=&filter=' | |
csv_header=','.join('url,type,username,password,hostname,extra,name,grouping'.split(',')) | |
def default_headers(): | |
cookie = get_cookies() | |
return { | |
'Cookie': cookie | |
,'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' | |
,'Accept': '*/*' | |
,'Host': YOUR_PPS_HOST | |
,'Origin': 'https://' + YOUR_PPS_HOST | |
,'Referer': f'https://{YOUR_PPS_HOST}/WebClient/Main' | |
,'X-Requested-With': 'XMLHttpRequest' | |
} | |
def get_cookies(): | |
# TODO: put the value of the "Cookie" header in "cookie.txt" | |
with open('cookie.txt', 'r') as cf: | |
return cf.readline() | |
def get_groups(tree_id, headers, data): | |
tree_url = BASE_URL + GET_TREE.format(tree_id) | |
return requests.get(tree_url, headers=headers, data=data).json() | |
def get_credentials(group_id, headers, data): | |
group_url = BASE_URL + GET_GROUP.format(group_id) | |
return requests.post(group_url, headers=headers, data=data).json() | |
def get_password(credential_id, headers, data): | |
password_url = BASE_URL + GET_PASS.format(credential_id) | |
return requests.get(password_url, headers=headers, data=data).json() | |
def to_csv(credential): | |
url = credential['Url'] | |
type_ = '' | |
username = credential['Username'] | |
password = credential['Password'] | |
hostname = '' | |
extra = f"Notes: {credential['Notes']}; Tags: {credential['Tags']}" # TODO: Add missing data here | |
name = credential['Name'] | |
grouping = credential['Path'] | |
return ','.join([ f'"{part}"' for part in | |
[url, type_, username, password, hostname, extra, name, grouping]]) | |
if __name__ == "__main__": | |
headers = default_headers() | |
groups = get_groups(YOUR_TREE_ID, headers, DEFAULT_DATA) | |
for group in groups: | |
group_name = group['name'] | |
credentials = get_credentials(group['id'], headers, DEFAULT_DATA) | |
print(csv_header) | |
for credential in credentials['Data']: | |
credential_id = credential['Id'] | |
password = get_password(credential_id, headers, DEFAULT_DATA)['response'] | |
credential['Password'] = password | |
print(to_csv(credential)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment