Skip to content

Commit

Permalink
add in a receipt (bug 679871)
Browse files Browse the repository at this point in the history
  • Loading branch information
Andy McKay committed Sep 8, 2011
1 parent 58c1810 commit 3ea7504
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 2 deletions.
41 changes: 41 additions & 0 deletions apps/market/models.py
@@ -1,16 +1,21 @@
# -*- coding: utf-8 -*-
import time

from django.conf import settings
from django.db import models
from django.dispatch import receiver

from translations.fields import TranslatedField

import amo
import amo.models
from amo.urlresolvers import reverse
from stats.models import Contribution
from users.models import UserProfile

import commonware.log
from jinja2.filters import do_dictsort
import jwt


log = commonware.log.getLogger('z.market')
Expand Down Expand Up @@ -54,13 +59,49 @@ def __unicode__(self):
class AddonPurchase(amo.models.ModelBase):
addon = models.ForeignKey('addons.Addon')
user = models.ForeignKey(UserProfile)
receipt = models.TextField(default='')

class Meta:
db_table = 'addon_purchase'

def __unicode__(self):
return u'%s: %s' % (self.addon, self.user)

def create_receipt(self):
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='', # Not implemented yet
# Slugs can be edited, so lets us the pk.
verify=reverse('api.market.verify',
args=[self.addon.pk]))
self.receipt = jwt.encode(receipt, get_key())


def get_key():
"""Return a key for using with encode."""
return jwt.rsa_load(settings.WEBAPPS_RECEIPT_KEY)


@receiver(models.signals.post_save, sender=AddonPurchase,
dispatch_uid='create_receipt')
def create_receipt(sender, instance, **kw):
"""
When the AddonPurchase gets created, see if we need to create a receipt.
"""
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()


@receiver(models.signals.post_save, sender=Contribution,
dispatch_uid='create_addon_purchase')
Expand Down
16 changes: 16 additions & 0 deletions apps/market/tests/sample.key
@@ -0,0 +1,16 @@
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAM1lIRXaaLVgzlvW
F2S6OMFJsfG+coZLx9qzmNb2gK6qjyGa71HeaLvFmQFv60dPjpuaGPs2uhL88hcN
JAChGiD8LxNpVW0EEw+RRH6/CBlDGuKjkSaPz8zzpEhSZq/yGb0F4zaau1HINnwo
rYPyRXWyRUzfpEB/7mx8/FUD24knAgMBAAECgYAaInsSP8dBBP9c+iHh5DwihBEL
VJNX+T6F2oJhH96B2xv5R7CZ9zXWZq8wWqBSY5IexH3XQUBt+BeJzVc+aUFcpKLM
D1O3OZ8NwC9HGIY0sLeX+uawYdFAPJfF8BZ8x3LMxWA8jdJM+4/P3C3jh2EvyzLT
HQ1rXBPrLkH45xJQSQJBAPPfSiObRvbeJvkgE0z5SqdbQjTGxeAX5qt1e2LtTwdU
gAxpYnYPz9CFCcIpa0j9UejlGninXasQvhpdwytBLk0CQQDXm/2kKh9BuWzemIu/
QcLSgc7VrGgZnGQ27fp3bXDSOV3Bev9VywLQ5VDBJcRSkMTC0V/+iHZbMl9EpwHN
8ZdDAkBJHtAZ8PrMFjvVQnrG/5AUsdYeAONfl4sAKc9/D+w8JGfoUMjG4WLMALe2
UbjrP5kJnXfcaUI6gmCdgzN7iqWZAkAvJbpKOrfJDH4lEuCEOyIaHC6ZhPDioNM9
O77ofLMOFWNOGtJY9WKxQWPuSI7sqyGLpHNEWpzfBl3UylxXp3u3AkEAzCzGUMfM
0qw/TFlVLzCHhrkP13SrJohdD693w9nuhYM2u27R32qJlF1OvN9NxEV7ZoOSGJxi
CGTjWcXUGgYQgQ==
-----END PRIVATE KEY-----
51 changes: 49 additions & 2 deletions apps/market/tests/test_models.py
@@ -1,14 +1,21 @@
import json
import os

from django.conf import settings

import mock
from nose.tools import eq_

from addons.models import Addon
import amo
import amo.tests
from amo.urlresolvers import reverse
from addons.models import Addon
from market.models import Price
from market.models import AddonPurchase, Price, get_key
from stats.models import Contribution
from users.models import UserProfile
from webapps.models import Webapp

key = os.path.join(os.path.dirname(__file__), 'sample.key')


class TestPrice(amo.tests.TestCase):
Expand All @@ -25,6 +32,46 @@ def test_currency(self):
eq_(self.tier_one.pricecurrency_set.count(), 2)


class TestReceipt(amo.tests.TestCase):
fixtures = ['base/users.json']

def setUp(self):
self.webapp = Webapp.objects.create(type=amo.ADDON_EXTENSION)
self.user = UserProfile.objects.get(pk=999)
self.other_user = UserProfile.objects.exclude(pk=999)[0]

def test_no_receipt(self):
ap = AddonPurchase.objects.create(user=self.user, addon=self.webapp)
eq_(ap.receipt, '')

@mock.patch.object(settings, 'WEBAPPS_RECEIPT_KEY', 'rubbish')
def test_get_key(self):
self.assertRaises(IOError, get_key)

@mock.patch.object(settings, 'WEBAPPS_RECEIPT_KEY', key)
def create_receipt(self, user, webapp):
self.webapp.update(type=amo.ADDON_WEBAPP,
manifest_url='http://somesite.com/')
return AddonPurchase.objects.create(user=user, addon=webapp)

def test_receipt(self):
ap = self.create_receipt(self.user, self.webapp)
assert ap.receipt.startswith('eyJhbGciOiAiSFMyNTY'), ap.receipt

def test_receipt_different(self):
ap = self.create_receipt(self.user, self.webapp)
ap_other = self.create_receipt(self.other_user, self.webapp)
assert ap.receipt != ap_other.receipt

def test_addon(self):
# An overall test of what's going on.
self.create_receipt(self.user, self.webapp)
self.webapp.update(premium_type=amo.ADDON_PREMIUM)
assert self.webapp.has_purchased(self.user)
assert not self.webapp.has_purchased(self.other_user)
assert self.webapp.addonpurchase_set.all()[0].receipt


class TestAddonPurchase(amo.tests.TestCase):
fixtures = ['base/addon_3615', 'base/users']

Expand Down
1 change: 1 addition & 0 deletions migrations/246-add-receipt.sql
@@ -0,0 +1 @@
ALTER TABLE addon_purchase ADD COLUMN `receipt` longtext NOT NULL;

0 comments on commit 3ea7504

Please sign in to comment.