add in decoding receipts and just cache the receipts instead (bug 699486)

This commit is contained in:
Andy McKay 2011-11-14 11:12:57 -08:00
Родитель 9a34fed161
Коммит 7a3483ad01
3 изменённых файлов: 36 добавлений и 35 удалений

Просмотреть файл

@ -5,8 +5,6 @@ import urlparse
from django.conf import settings
from django.db import models
from django.dispatch import receiver
from django.utils.http import urlencode
import commonware.log
@ -15,6 +13,7 @@ from amo.decorators import skip_cache
from amo.helpers import absolutify
import amo.models
from amo.urlresolvers import reverse
from amo.utils import memoize
from addons import query
from addons.models import (Addon, clear_name_table, delete_search_index,
update_name_table, update_search_index)
@ -135,29 +134,33 @@ class Installed(amo.models.ModelBase):
"""Track WebApp installations."""
addon = models.ForeignKey('addons.Addon', related_name='installed')
user = models.ForeignKey('users.UserProfile')
receipt = models.TextField(default='')
class Meta:
db_table = 'users_install'
unique_together = ('addon', 'user')
def create_receipt(self):
verify = reverse('api.market.verify', args=[self.addon.pk])
detail = reverse('users.purchases.receipt', args=[self.addon.pk])
hsh = self.addon.get_watermark_hash(self.user)
url = urlencode({amo.WATERMARK_KEY: self.user.email,
amo.WATERMARK_KEY_HASH: hsh})
verify = '%s?%s' % (verify, url)
receipt = dict(typ='purchase-receipt',
product=self.addon.origin,
user={'type': 'email',
'value': self.user.email},
iss=settings.SITE_URL,
nbf=time.time(),
iat=time.time(),
detail=absolutify(detail),
verify=absolutify(verify))
self.receipt = jwt.encode(receipt, get_key())
@property
def receipt(self):
if self.addon.is_webapp():
return create_receipt(self.pk)
return ''
@memoize(prefix='create-receipt', time=60 * 10)
def create_receipt(installed_pk):
installed = Installed.objects.get(pk=installed_pk)
verify = reverse('api.market.verify', args=[installed.addon.pk])
detail = reverse('users.purchases.receipt', args=[installed.addon.pk])
receipt = dict(typ='purchase-receipt',
product=installed.addon.origin,
user={'type': 'email',
'value': installed.user.email},
iss=settings.SITE_URL,
nbf=time.mktime(installed.created.timetuple()),
iat=time.time(),
detail=absolutify(detail),
verify=absolutify(verify))
return jwt.encode(receipt, get_key(), u'RS512')
def get_key():
@ -165,17 +168,9 @@ def get_key():
return jwt.rsa_load(settings.WEBAPPS_RECEIPT_KEY)
@receiver(models.signals.post_save, sender=Installed,
dispatch_uid='create_receipt')
def create_receipt(sender, instance, **kw):
def decode_receipt(receipt):
"""
When something gets installed, see if we need to create a receipt.
Cracks the receipt using the private key. This will probably change
to using the cert at some point, especially when we get the HSM.
"""
if (kw.get('raw') or instance.addon.type != amo.ADDON_WEBAPP
or instance.receipt):
return
log.debug('Creating receipt for: addon %s, user %s'
% (instance.addon.pk, instance.user.pk))
instance.create_receipt()
instance.save()
return jwt.decode(receipt, get_key())

Просмотреть файл

@ -13,7 +13,7 @@ from addons.models import Addon, BlacklistedSlug
from devhub.tests.test_views import BaseWebAppTest
from users.models import UserProfile
from versions.models import Version
from webapps.models import Installed, Webapp, get_key
from webapps.models import Installed, Webapp, get_key, decode_receipt
key = os.path.join(os.path.dirname(__file__), 'sample.key')
@ -85,7 +85,7 @@ class TestWebappManager(test_utils.TestCase):
def test_unreviewed(self):
for status in amo.UNREVIEWED_STATUSES:
w = Webapp.objects.create(status=status)
Webapp.objects.create(status=status)
self.reviewed_eq()
Webapp.objects.all().delete()
@ -187,7 +187,7 @@ class TestReceipt(amo.tests.TestCase):
def test_receipt(self):
ins = self.create_install(self.user, self.webapp)
assert ins.receipt.startswith('eyJhbGciOiAiSFMyNTY'), ins.receipt
assert ins.receipt.startswith('eyJhbGciOiAiUlM1MTIiLCA'), ins.receipt
def test_get_receipt(self):
ins = self.create_install(self.user, self.webapp)
@ -210,3 +210,8 @@ class TestReceipt(amo.tests.TestCase):
self.webapp.update(premium_type=amo.ADDON_FREE)
self.create_install(self.user, self.webapp)
assert self.webapp.get_receipt(self.user)
def test_crack_receipt(self):
receipt = self.create_install(self.user, self.webapp).receipt
result = decode_receipt(receipt)
eq_(result['typ'], u'purchase-receipt')

Просмотреть файл

@ -0,0 +1 @@
ALTER TABLE users_install DROP COLUMN receipt;