Skip to content

Commit 6692053

Browse files
committed
Fixed #104 -- Passed only one of lptoken and muid to /access
1 parent 397afe0 commit 6692053

3 files changed

Lines changed: 109 additions & 10 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
## 5.3.1 (under development)
44

5+
* Only passed one of `lptoken` and `muid` to `/access` calls. Passing both is
6+
not supported.
7+
58
## 5.3.0
69

710
* Added explicit support for the `muid` argument to `get_add_url()`,

laterpay/__init__.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -360,16 +360,34 @@ def get_access_params(self, article_ids, lptoken=None, muid=None):
360360
params = {
361361
'cp': self.cp_key,
362362
'ts': str(int(time.time())),
363-
'lptoken': str(lptoken or self.lptoken),
364363
'article_id': article_ids,
365364
}
366365

367-
if muid:
368-
# TODO: The behavior when lptoken and muid are given is not yet
369-
# defined. Thus we'll allow both at the same time for now. It might
370-
# be that in the end only one is allowed or one is prefered over
371-
# the other.
366+
"""
367+
l = lptoken
368+
s = self.lptoken
369+
m = muid
370+
x = error
371+
372+
| L | not L | L | not L
373+
-------+-------+-------+-------+-------
374+
l | x | x | l | l
375+
-------+-------+-------+-------+-------
376+
not l | m | m | s | x
377+
-------+-------+-------+-------+-------
378+
| m | m | not m | not m
379+
"""
380+
if lptoken is None and muid is not None:
372381
params['muid'] = muid
382+
elif lptoken is not None and muid is None:
383+
params['lptoken'] = lptoken
384+
elif lptoken is None and muid is None and self.lptoken is not None:
385+
params['lptoken'] = self.lptoken
386+
else:
387+
raise AssertionError(
388+
'Either lptoken, self.lptoken or muid has to be passed. '
389+
'Passing neither or both lptoken and muid is not allowed.',
390+
)
373391

374392
params['hmac'] = signing.sign(
375393
secret=self.shared_secret,

tests/test_client.py

Lines changed: 82 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,6 @@ def test_get_access_data_success(self, time_time_mock, sign_mock):
326326
data = client.get_access_data(
327327
['article-1', 'article-2'],
328328
lptoken='fake-lptoken',
329-
muid='some-user',
330329
)
331330

332331
self.assertEqual(data, {
@@ -349,7 +348,7 @@ def test_get_access_data_success(self, time_time_mock, sign_mock):
349348
self.assertEqual(qd['cp'], ['fake-cp-key'])
350349
self.assertEqual(qd['article_id'], ['article-1', 'article-2'])
351350
self.assertEqual(qd['hmac'], ['fake-signature'])
352-
self.assertEqual(qd['muid'], ['some-user'])
351+
self.assertNotIn('muid', 'qd')
353352

354353
sign_mock.assert_called_once_with(
355354
secret='fake-shared-secret',
@@ -358,6 +357,70 @@ def test_get_access_data_success(self, time_time_mock, sign_mock):
358357
'article_id': ['article-1', 'article-2'],
359358
'ts': '123',
360359
'lptoken': 'fake-lptoken',
360+
},
361+
url='http://example.net/access',
362+
method='GET',
363+
)
364+
365+
@mock.patch('laterpay.signing.sign')
366+
@mock.patch('time.time')
367+
@responses.activate
368+
def test_get_access_data_success_muid(self, time_time_mock, sign_mock):
369+
time_time_mock.return_value = 123
370+
sign_mock.return_value = 'fake-signature'
371+
responses.add(
372+
responses.GET,
373+
'http://example.net/access',
374+
body=json.dumps({
375+
"status": "ok",
376+
"articles": {
377+
"article-1": {"access": True},
378+
"article-2": {"access": False},
379+
},
380+
}),
381+
status=200,
382+
content_type='application/json',
383+
)
384+
385+
client = LaterPayClient(
386+
'fake-cp-key',
387+
'fake-shared-secret',
388+
api_root='http://example.net',
389+
)
390+
391+
data = client.get_access_data(
392+
['article-1', 'article-2'],
393+
muid='some-user',
394+
)
395+
396+
self.assertEqual(data, {
397+
"status": "ok",
398+
"articles": {
399+
"article-1": {"access": True},
400+
"article-2": {"access": False},
401+
},
402+
})
403+
self.assertEqual(len(responses.calls), 1)
404+
405+
call = responses.calls[0]
406+
407+
self.assertEqual(call.request.headers['X-LP-APIVersion'], '2')
408+
409+
qd = parse_qs(urlparse(call.request.url).query)
410+
411+
self.assertEqual(qd['ts'], ['123'])
412+
self.assertEqual(qd['cp'], ['fake-cp-key'])
413+
self.assertEqual(qd['article_id'], ['article-1', 'article-2'])
414+
self.assertEqual(qd['hmac'], ['fake-signature'])
415+
self.assertEqual(qd['muid'], ['some-user'])
416+
self.assertNotIn('lptoken', 'qd')
417+
418+
sign_mock.assert_called_once_with(
419+
secret='fake-shared-secret',
420+
params={
421+
'cp': 'fake-cp-key',
422+
'article_id': ['article-1', 'article-2'],
423+
'ts': '123',
361424
'muid': 'some-user',
362425
},
363426
url='http://example.net/access',
@@ -379,16 +442,31 @@ def test_get_access_params(self, time_time_mock, sign_mock):
379442
'hmac': 'fake-signature',
380443
})
381444

382-
params = self.lp.get_access_params('article-1', lptoken='fake-lptoken', muid='some-user')
445+
params = self.lp.get_access_params('article-1', muid='some-user')
383446
self.assertEqual(params, {
384447
'cp': '1',
385448
'ts': '123',
386-
'lptoken': 'fake-lptoken',
387449
'article_id': ['article-1'],
388450
'hmac': 'fake-signature',
389451
'muid': 'some-user',
390452
})
391453

454+
lpclient = LaterPayClient('1', 'some-secret', lptoken='instance-lptoken')
455+
params = lpclient.get_access_params('article-1')
456+
self.assertEqual(params, {
457+
'cp': '1',
458+
'ts': '123',
459+
'lptoken': 'instance-lptoken',
460+
'article_id': ['article-1'],
461+
'hmac': 'fake-signature',
462+
})
463+
464+
with self.assertRaises(AssertionError):
465+
self.lp.get_access_params('article-1', lptoken='fake-lptoken', muid='some-user')
466+
467+
with self.assertRaises(AssertionError):
468+
self.lp.get_access_params('article-1')
469+
392470
@mock.patch('time.time')
393471
def test_get_gettoken_redirect(self, time_mock):
394472
time_mock.return_value = 12345678

0 commit comments

Comments
 (0)