Skip to content

Commit 7a70392

Browse files
committed
Added support to create manual ident URLs
1 parent d3f4b46 commit 7a70392

4 files changed

Lines changed: 75 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
* Added explicit support for the `muid` argument to `get_add_url()`,
66
`get_buy_url()` and `get_subscribe_url()`.
77

8+
* Added function to create manual ident URLs. A user can visit these URLs to
9+
regain access to previous purchased or bought content.
10+
11+
* Added [PyJWT](https://pyjwt.readthedocs.io/en/latest/) >= 1.4.2 to the
12+
installation requirements as it's required for the added manual ident URLs
13+
feature.
14+
815
## 5.2.0
916

1017
* Added constants outlining expiration and duration time bases for purchases

laterpay/__init__.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414
import string
1515
import time
1616

17+
import jwt
1718
import requests
1819

1920
import six
2021
from six.moves.urllib.parse import quote_plus
2122

22-
from . import constants, signing, utils
23+
from . import compat, constants, signing, utils
2324

2425

2526
_logger = logging.getLogger(__name__)
@@ -396,3 +397,20 @@ def get_access_data(self, article_ids, lptoken=None):
396397
response.raise_for_status()
397398

398399
return response.json()
400+
401+
def get_manual_ident_url(self, article_url, article_ids):
402+
"""
403+
Return a URL to allow users to claim previous purchase content.
404+
"""
405+
token = self._get_manual_ident_token(article_url, article_ids)
406+
return '%s/ident/%s/%s/' % (self.web_root, self.cp_key, token)
407+
408+
def _get_manual_ident_token(self, article_url, article_ids):
409+
"""
410+
Return the token data for ``get_manual_ident_url()``.
411+
"""
412+
data = {
413+
'back': compat.stringify(article_url),
414+
'ids': [compat.stringify(article_id) for article_id in article_ids],
415+
}
416+
return jwt.encode(data, self.shared_secret).decode()

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
packages=_packages,
3030

3131
install_requires=[
32+
'PyJWT>=1.4.2',
3233
'requests',
3334
'six',
3435
],

tests/test_client.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import json
44
import unittest
55

6+
import jwt
67
import mock
78
import responses
89

@@ -509,6 +510,53 @@ def test_get_controls_balance_url_all_set(self, time_mock):
509510
'ts': ['12345678'],
510511
})
511512

513+
def test_get_manual_ident_url(self):
514+
article_url = u'http://example.com/news?id=10&emoji=😄'
515+
article_ids = ['aid≠1', b'aid\xe2\x89\xa02']
516+
517+
url = self.lp.get_manual_ident_url(article_url, article_ids)
518+
519+
url_info = urlparse(url)
520+
521+
self.assertEqual(url_info.scheme, 'https')
522+
self.assertEqual(url_info.netloc, 'web.laterpay.net')
523+
self.assertEqual(url_info.hostname, 'web.laterpay.net')
524+
self.assertEqual(url_info.params, '')
525+
self.assertEqual(url_info.query, '')
526+
self.assertEqual(url_info.fragment, '')
527+
self.assertIsNone(url_info.username)
528+
self.assertIsNone(url_info.password)
529+
self.assertIsNone(url_info.port)
530+
531+
path_segments = url_info.path.split('/')
532+
533+
self.assertEqual(len(path_segments), 5)
534+
self.assertEqual(path_segments[0], '')
535+
self.assertEqual(path_segments[1], 'ident')
536+
self.assertEqual(path_segments[2], self.lp.cp_key)
537+
self.assertEqual(path_segments[4], '')
538+
539+
token = path_segments[3]
540+
541+
data = jwt.decode(token, self.lp.shared_secret)
542+
543+
self.assertEqual(data, {
544+
'back': u'http://example.com/news?id=10&emoji=\U0001f604',
545+
'ids': [u'aid\u22601', u'aid\u22602'],
546+
})
547+
548+
def test_get_manual_ident_token(self):
549+
article_url = u'http://example.com/news?id=10&emoji=😄'
550+
article_ids = ['aid≠1', b'aid\xe2\x89\xa02']
551+
552+
token = self.lp._get_manual_ident_token(article_url, article_ids)
553+
data = jwt.decode(token, self.lp.shared_secret)
554+
555+
self.assertEqual(data, {
556+
'back': u'http://example.com/news?id=10&emoji=\U0001f604',
557+
'ids': [u'aid\u22601', u'aid\u22602'],
558+
})
559+
512560

513561
if __name__ == '__main__':
514562
unittest.main()

0 commit comments

Comments
 (0)