Skip to content

Adjustments #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion README.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Thin Python binding for onetimesecret.com API.
Thin Python 3.7 binding for onetimesecret.com API.
Unicode-safe.
Description of API itself you can find here: https://onetimesecret.com/docs/api

Expand Down
74 changes: 26 additions & 48 deletions onetimesecret.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-

__author__ = 'Step'
import urllib2
import json
from urllib import urlencode

from urllib.request import urlopen, build_opener, HTTPBasicAuthHandler, install_opener
from urllib.parse import urlencode
from urllib.error import URLError, HTTPError
from functools import wraps
import os


def server_check(func):
"""
Expand All @@ -21,6 +20,7 @@ def checked_func(self, *args, **kwargs):
raise Exception("Server is not ready")
return checked_func


def create_opener(url, username, password):
"""
Creates opener for the OTS site with given credentials.
Expand All @@ -31,14 +31,12 @@ def create_opener(url, username, password):
@type username: string
@type password: string
"""
auth_handler = urllib2.HTTPBasicAuthHandler()
auth_handler.add_password(realm='OTS',
uri=url,
user=username,
passwd=password)
opener = urllib2.build_opener(auth_handler)
auth_handler = HTTPBasicAuthHandler()
auth_handler.add_password(realm="OTS", uri=url, user=username, passwd=password)
opener = build_opener(auth_handler)
return opener


class OneTimeSecret(object):
def __init__(self, username, api_key, api_ver=None, url=None):
"""
Expand All @@ -64,7 +62,6 @@ def __init__(self, username, api_key, api_ver=None, url=None):
self.opener = create_opener("https://%s/*" % url, username, api_key)
self.secret_link_url = "https://onetimesecret.com/secret/"

@server_check
def share(self, secret, passphrase=None, recipient=None, ttl=None):
"""
Shares given secret and returns Python dictionary, containing server response.
Expand Down Expand Up @@ -92,16 +89,15 @@ def share(self, secret, passphrase=None, recipient=None, ttl=None):
if ttl is None:
ttl = 3600 * 24

data = {"secret":secret.encode("utf-8"),
"ttl":ttl}

data = {"secret": secret.encode("utf-8"), "ttl": ttl}

if passphrase:
data.update({"passphrase":passphrase.encode("utf-8")})
data.update({"passphrase": passphrase.encode("utf-8")})
if recipient:
data.update({"recipient":recipient.encode("utf-8")})
data.update({"recipient": recipient.encode("utf-8")})

url = self.url % "share"
raw = urllib2.urlopen(url, urlencode(data)).read()
raw = urlopen(url, urlencode(data).encode("utf-8")).read()
res = json.loads(raw)
return res

Expand All @@ -110,15 +106,12 @@ def generate(self, passphrase=None, recipient=None, ttl=None):
"""
Generates random secret. Inputs and return are similar to share()'s, except "secret", which is not
in use here.

@param passphrase: password, if you wish to keep your secret totally confidential
@param recipient: recipient's e-mail, if you wish to send him an invitation to see your secret
@param ttl: TTL of your secret, in seconds. Set to one day by default

@type passphrase: string
@type recipient: string
@type ttl: int

@rtype res: dict
"""
if ttl is None:
Expand All @@ -130,7 +123,7 @@ def generate(self, passphrase=None, recipient=None, ttl=None):
data.update({"recipient":recipient.encode("utf-8")})

url = self.url % "generate"
raw = urllib2.urlopen(url, urlencode(data)).read()
raw = urlopen(url, urlencode(data)).read()
res = json.loads(raw)
return res

Expand All @@ -140,17 +133,13 @@ def retrieve_secret(self, secret_key, passphrase=None):
Retrieves secret by given secret_key and passphrase (if necessary) and returns
Python dictionary, containing server response. Raises exception if finds some
problems with passphrase.

Usefull fields:
[*] res["value"] : secret you were looking for
Other field's meaning you can obtain from https://onetimesecret.com/docs/api/secrets

@param secret_key: key of the secret you wish to get
@param passphrase: you can specify passphrase if necessary

@type secret_key: string
@type passphrase: string

@rtype res: dict
"""
try:
Expand All @@ -159,10 +148,10 @@ def retrieve_secret(self, secret_key, passphrase=None):
data.update({"passphrase":passphrase.encode("utf-8")})

url = self.url % "secret/%s" % secret_key
raw = urllib2.urlopen(url, urlencode(data)).read()
raw = urlopen(url, urlencode(data).encode("utf-8")).read()
res = json.loads(raw)
return res
except urllib2.HTTPError:
except HTTPError:
raise Exception("Check key and passphrase")

@server_check
Expand All @@ -173,39 +162,32 @@ def retrieve_meta(self, meta_key):
[*] res["secret_key"] : key of the secret associated with this meta
[*] res["received"] : time (in POSIX format, UTC), the secret
associated with this meta was received. False if secret wasn't open.

@param meta_key : metadata_key of the secret, you want to lookup

@type meta_key : string

@rtype res: dict
"""
data = {"METADATA_KEY":meta_key}

url = self.url % "private/%s" % meta_key
raw = urllib2.urlopen(url, urlencode(data)).read()
raw = urlopen(url, urlencode(data).encode("utf-8")).read()
res = json.loads(raw)
if not res.has_key(u"received"):
if not ("received" in res):
res.update({u"received":False})
return res

@server_check
def share_file(self, file_path, passphrase=None, recipient=None, ttl=None):
"""
Shares given file_path and returns Python dictionary, containing server response.

@param file_path: The file you want to share
@param passphrase: password, if you wish to keep your secret totally confidential
@param recipient: recipient's e-mail, if you wish to send him an invitation to see your secret
@param ttl: TTL of your secret, in seconds. Set to one day by default

@type secret: string
@type passphrase: string
@type recipient: string
@type ttl: int

@rtype res: dict

"""
if os.path.exists(os.path.dirname(file_path)):
secret = open(file_path, 'r').read()
Expand All @@ -217,33 +199,29 @@ def share_file(self, file_path, passphrase=None, recipient=None, ttl=None):
def secret_link(self, meta_key):
"""
Retrieves secret link.

URL: https://onetimesecret.com/secret/*secret_key*
URL: https://onetimesecret.com/secret/*secret_key*
@param meta_key: metadata_key of the secret, you want to lookup

@type meta_key: string

@rtype res: dict
"""

data = {"METADATA_KEY":meta_key}
url = self.url % "private/%s" % meta_key
raw = urllib2.urlopen(url, urlencode(data)).read()
raw = urlopen(url, urlencode(data).encode("utf-8")).read()
res = json.loads(raw)

return self.secret_link_url + res['secret_key']

def status(self):
"""
Checks server's ability to process our request. Also, sets necessary credentials for urllib2.
Checks server's ability to process our request. Also, sets necessary credentials for urllib.
Returns True if all is OK, else False.

@rtype: bool
"""
try:
urllib2.install_opener(self.opener)
install_opener(self.opener)
url = self.url % "status"
raw = urllib2.urlopen(url).read()
raw = urlopen(url).read()
return json.loads(raw)[u"status"] == u"nominal"
except (urllib2.URLError, ValueError, KeyError):
except (URLError, ValueError, KeyError):
return False
33 changes: 5 additions & 28 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,10 @@
from onetimesecret import OneTimeSecret

o = OneTimeSecret("YOUR_EMAIL", "YOUR_OTS_APIKEY")
secret = o.share(u"Привет, Хабр")
# {u'updated': 1340611352,
# u'created': 1340611352,
# u'recipient': [],
# u'metadata_key': u'653lzljgwgj74ys6hvrpta2wmhaamrg', ### Ключ метаданных (просмотренно/нет, когда, запаролено ли и т.д.).
# Доступ к метаданным по ссылке вида https://onetimesecret.com/private/META_KEY
# u'metadata_ttl': 86400,
# u'secret_ttl': 86400,
# u'state': u'new',
# u'passphrase_required': False,
# u'ttl': 86400,
# u'secret_key': u'3ery270erhtk1gjsti90d70z5h8aqgd', ### Ключ секрета, доступ к самому
# по ссылке вида https://onetimesecret.com/secret/SECRET_KEY
#
# u'custid': u'anon'}
secret = o.share(u"Test")

print o.retrieve_secret(secret[u"secret_key"])
# {u'secret_key': u'dtr7ixukiolpx1i4i87kahmhyoy2q65',
# u'value': u'Привет, Хабр'}

print o.retrieve_meta(secret["metadata_key"])
# {u'received': 1340731164,
# u'updated': 1340731164,
# u'created': 1340731159,
# u'recipient': [],
# u'metadata_key': u'qvu20axsugif3fo4zjas5ujvp1q9k75',
# u'metadata_ttl': 86398,
# u'state': u'received', ### Сообщение было прочитано
# u'ttl': 86400,
# u'custid': u'anon'}
print(o.retrieve_secret(secret[u"secret_key"]))


print(o.retrieve_meta(secret["metadata_key"]))