def get_product_jwt(product, contribution): """Prepare a JWT for paid products to pass into navigator.pay()""" issued_at = calendar.timegm(time.gmtime()) token_data = { 'iss': settings.APP_PURCHASE_KEY, 'typ': settings.APP_PURCHASE_TYP, 'aud': settings.APP_PURCHASE_AUD, 'iat': issued_at, 'exp': issued_at + 3600, # expires in 1 hour 'request': { 'id': product.external_id(), 'name': unicode(product.name()), 'icons': product.icons(), 'description': strip_tags(product.description()), 'pricePoint': product.price().name, 'productData': urlencode(product.product_data(contribution)), 'chargebackURL': absolutify(reverse('webpay.chargeback')), 'postbackURL': absolutify(reverse('webpay.postback')), } } token = sign_webpay_jwt(token_data) log.debug('Preparing webpay JWT for self.product {0}: {1}'.format( product.id(), token)) return { 'webpayJWT': token, 'contribStatusURL': reverse( 'webpay-status', kwargs={'uuid': contribution.uuid} ) }
def create_test_receipt(root, status): time_ = calendar.timegm(time.gmtime()) detail = absolutify(reverse('receipt.test.details')) receipt = { 'detail': absolutify(detail), 'exp': time_ + (60 * 60 * 24), 'iat': time_, 'iss': settings.SITE_URL, 'nbf': time_, 'product': { 'storedata': urlencode({'id': 0}), 'url': root, }, 'reissue': detail, 'typ': 'test-receipt', 'user': { 'type': 'directed-identifier', 'value': 'none' }, 'verify': absolutify(reverse('receipt.test.verify', kwargs={'status': status})) } if settings.SIGNING_SERVER_ACTIVE: return sign(receipt) else: return jwt.encode(receipt, get_key(), u'RS512')
def create_test_receipt(root, status, storedata=None): if not storedata: storedata = {'id': 0} time_ = calendar.timegm(time.gmtime()) detail = absolutify(reverse('receipt.test.details')) receipt = { 'detail': absolutify(detail), 'exp': time_ + (60 * 60 * 24), 'iat': time_, 'iss': settings.SITE_URL, 'nbf': time_, 'product': { 'storedata': urlencode(storedata), 'url': root, }, 'reissue': detail, 'typ': 'test-receipt', 'user': { 'type': 'directed-identifier', 'value': 'none' }, 'verify': absolutify(reverse('receipt.test.verify', kwargs={'status': status})) } return sign(receipt)
def prepare_pay(request, addon): """Prepare a BlueVia JWT to pass into navigator.pay()""" amount, currency, uuid_, contrib_for = start_purchase(request, addon) log.debug('Storing contrib for uuid: %s' % uuid_) Contribution.objects.create(addon_id=addon.id, amount=amount, source=request.REQUEST.get('src', ''), source_locale=request.LANG, uuid=str(uuid_), type=amo.CONTRIB_PENDING, paykey=None, user=request.amo_user, price_tier=addon.premium.price, client_data=ClientData.get_or_create(request)) prices = [{'currency': cur, 'amount': str(tier.price)} for cur, tier in addon.premium.price.currencies()] data = {'amount': str(amount), 'prices': prices, 'currency': currency, 'app_name': unicode(addon.name), 'app_description': unicode(addon.description), 'postback_url': absolutify(reverse('bluevia.postback')), 'chargeback_url': absolutify(reverse('bluevia.chargeback')), 'seller': addon.pk, 'product_data': urlencode({'contrib_uuid': uuid_, 'addon_id': addon.pk}), 'typ': 'tu.com/payments/inapp/v1', 'aud': 'tu.com', 'memo': contrib_for} return {'blueviaJWT': prepare_bluevia_pay(data), 'contribStatusURL': reverse('bluevia.pay_status', args=[addon.app_slug, uuid_])}
def prepare_pay(request, addon): """Prepare a BlueVia JWT to pass into navigator.pay()""" amount, currency, uuid_, contrib_for = start_purchase(request, addon) log.debug('Storing contrib for uuid: %s' % uuid_) Contribution.objects.create(addon_id=addon.id, amount=amount, source=request.REQUEST.get('src', ''), source_locale=request.LANG, uuid=str(uuid_), type=amo.CONTRIB_PENDING, paykey=None, user=request.amo_user, price_tier=addon.premium.price, client_data=ClientData.get_or_create(request)) acct = addon.app_payment_account.payment_account seller_uuid = acct.solitude_seller.uuid data = {'amount': str(amount), 'price_point': addon.premium.price.pk, 'id': addon.pk, 'app_name': unicode(addon.name), 'app_description': unicode(addon.summary), 'postback_url': absolutify(reverse('webpay.postback')), 'chargeback_url': absolutify(reverse('webpay.chargeback')), 'seller': addon.pk, 'product_data': urlencode({'contrib_uuid': uuid_, 'seller_uuid': seller_uuid, 'addon_id': addon.pk}), 'typ': 'tu.com/payments/inapp/v1', 'aud': 'tu.com', 'memo': contrib_for} jwt_ = prepare_webpay_pay(data) log.debug('Preparing webpay JWT for addon %s: %s' % (addon, jwt_)) return {'webpayJWT': jwt_, 'contribStatusURL': reverse('webpay.pay_status', args=[addon.app_slug, uuid_])}
def create_test_receipt(root, status): time_ = calendar.timegm(time.gmtime()) detail = absolutify(reverse('receipt.test.details')) receipt = { 'detail': absolutify(detail), 'exp': time_ + (60 * 60 * 24), 'iat': time_, 'iss': settings.SITE_URL, 'nbf': time_, 'product': { 'storedata': urlencode({'id': 0}), 'url': root, 'type': 'test' }, 'reissue': detail, 'typ': 'purchase-receipt', 'user': { 'type': 'directed-identifier', 'value': 'none' }, 'verify': absolutify(reverse('receipt.test.verify', kwargs={'status': status})) } if settings.SIGNING_SERVER_ACTIVE: return sign(receipt) else: return jwt.encode(receipt, get_key(), u'RS512')
def test_addon_license(self): """Test for license information in response.""" addon = Addon.objects.get(id=3615) license = addon.current_version.license license.name = 'My License' license.url = 'someurl' license.save() api_url = '/en-US/firefox/api/%.1f/addon/3615' % api.CURRENT_VERSION response = self.client.get(api_url) doc = pq(response.content) eq_(doc('license').length, 1) eq_(doc('license name').length, 1) eq_(doc('license url').length, 1) eq_(doc('license name').text(), unicode(license.name)) eq_(doc('license url').text(), helpers.absolutify(license.url)) license.url = '' license.save() addon.save() response = self.client.get(api_url) doc = pq(response.content) license_url = addon.current_version.license_url() eq_(doc('license url').text(), helpers.absolutify(license_url)) license.delete() response = self.client.get(api_url) doc = pq(response.content) eq_(doc('license').length, 0)
def setUp(self): self.data = {'return_url': absolutify(reverse('home')), 'cancel_url': absolutify(reverse('home')), 'amount': 10, 'email': '*****@*****.**', 'uuid': time.time(), 'ip': '127.0.0.1'}
def create_receipt(webapp, user, uuid, flavour=None, contrib=None): """ Creates a receipt for use in payments. :params app: the app record. :params user: the UserProfile record. :params uuid: a uuid placed in the user field for this purchase. :params flavour: None, developer, inapp, or reviewer - the flavour of receipt. :param: contrib: the Contribution object for the purchase. """ # Unflavo(u)red receipts are for plain ol' vanilla app purchases. assert flavour in (None, 'developer', 'inapp', 'reviewer'), ( 'Invalid flavour: %s' % flavour) time_ = calendar.timegm(time.gmtime()) typ = 'purchase-receipt' storedata = {'id': int(webapp.pk)} # Generate different receipts for reviewers or developers. expiry = time_ + settings.WEBAPPS_RECEIPT_EXPIRY_SECONDS verify = static_url('WEBAPPS_RECEIPT_URL') if flavour == 'inapp': if not contrib: raise ValueError( 'a contribution object is required for in-app receipts') if not contrib.inapp_product: raise ValueError( 'contribution {c} does not link to an in-app product' .format(c=contrib)) storedata['contrib'] = int(contrib.pk) elif flavour in ('developer', 'reviewer'): if not (acl.action_allowed_user(user, 'Apps', 'Review') or webapp.has_author(user)): raise ValueError('User %s is not a reviewer or developer' % user.pk) # Developer and reviewer receipts should expire after 24 hours. expiry = time_ + (60 * 60 * 24) typ = flavour + '-receipt' verify = absolutify(reverse('receipt.verify', args=[webapp.guid])) product = {'storedata': urlencode(storedata), # Packaged and hosted apps should have an origin. If there # isn't one, fallback to the SITE_URL. 'url': webapp.origin or settings.SITE_URL} reissue = absolutify(reverse('receipt.reissue')) receipt = dict(exp=expiry, iat=time_, iss=settings.SITE_URL, nbf=time_, product=product, # TODO: This is temporary until detail pages get added. # TODO: bug 1020997, bug 1020999 detail=absolutify(reissue), # Currently this is a 404. reissue=absolutify(reissue), typ=typ, user={'type': 'directed-identifier', 'value': uuid}, verify=verify) return sign(receipt)
def prepare_pay(request, addon): """Prepare a BlueVia JWT to pass into navigator.pay()""" amount, currency, uuid_, contrib_for = start_purchase(request, addon) log.debug('Storing contrib for uuid: %s' % uuid_) Contribution.objects.create(addon_id=addon.id, amount=amount, source=request.REQUEST.get('src', ''), source_locale=request.LANG, uuid=str(uuid_), type=amo.CONTRIB_PENDING, paykey=None, user=request.amo_user, price_tier=addon.premium.price, client_data=ClientData.get_or_create(request)) data = {'amount': str(amount), 'currency': currency, 'app_name': unicode(addon.name), 'app_description': unicode(addon.description), 'postback_url': absolutify(reverse('bluevia.postback')), 'chargeback_url': absolutify(reverse('bluevia.chargeback')), 'seller': addon.pk, 'product_data': urlencode({'contrib_uuid': uuid_, 'addon_id': addon.pk}), 'typ': 'tu.com/payments/inapp/v1', 'aud': 'tu.com', 'memo': contrib_for} if waffle.flag_is_active(request, 'solitude-payments'): bluevia_jwt = client.prepare_bluevia_pay(data) else: bluevia_jwt = prepare_bluevia_pay(data) return {'blueviaJWT': bluevia_jwt, 'contribStatusURL': reverse('bluevia.pay_status', args=[addon.app_slug, uuid_])}
def test_suggestions(self): app1 = Webapp.objects.get(pk=337141) app1.save() app2 = app_factory(name=u"Second âpp", description=u"Second dèsc" * 25, created=self.days_ago(3)) self.refresh('webapp') response = self.client.get(self.url) parsed = json.loads(response.content) eq_(parsed[0], '') self.assertSetEqual( parsed[1], [unicode(app1.name), unicode(app2.name)]) self.assertSetEqual( parsed[2], [unicode(app1.description), unicode(truncate(app2.description))]) self.assertSetEqual(parsed[3], [ absolutify(app1.get_detail_url()), absolutify(app2.get_detail_url()) ]) self.assertSetEqual(parsed[4], [app1.get_icon_url(64), app2.get_icon_url(64)]) # Cleanup to remove these from the index. unindex_webapps([app1.id, app2.id]) app1.delete() app2.delete()
def create_test_receipt(root, status): time_ = calendar.timegm(time.gmtime()) detail = absolutify(reverse('receipt.test.details')) receipt = { 'detail': absolutify(detail), 'exp': time_ + (60 * 60 * 24), 'iat': time_, 'iss': settings.SITE_URL, 'nbf': time_, 'product': { 'storedata': urlencode({'id': 0}), 'url': root, }, 'reissue': detail, 'typ': 'test-receipt', 'user': { 'type': 'directed-identifier', 'value': 'none' }, 'verify': absolutify(reverse('receipt.test.verify', kwargs={'status': status})) } return sign(receipt)
def get_context_data(self): # We need to display the name in some language that is relevant to the # recipient(s) instead of using the reviewer's. addon.default_locale # should work. if self.addon.name.locale != self.addon.default_locale: lang = to_language(self.addon.default_locale) with translation.override(lang): app = Webapp.objects.get(id=self.addon.id) else: app = self.addon return { 'name': app.name, 'reviewer': self.request.user.get_profile().name, 'detail_url': absolutify(app.get_url_path(add_prefix=False)), 'review_url': absolutify( reverse('reviewers.apps.review', args=[app.app_slug], add_prefix=False)), 'status_url': absolutify(app.get_dev_url('versions')), 'comments': self.data['comments'], 'MKT_SUPPORT_EMAIL': settings.MKT_SUPPORT_EMAIL, 'SITE_URL': settings.SITE_URL }
def send_purchase_receipt(contrib_id, **kw): """ Sends an email to the purchaser of the app. """ contrib = Contribution.objects.get(pk=contrib_id) with contrib.user.activate_lang(): addon = contrib.addon version = addon.current_version or addon.latest_version # L10n: {0} is the app name. subject = _('Receipt for {0}').format(contrib.addon.name) data = { 'app_name': addon.name, 'developer_name': version.developer_name if version else '', 'price': contrib.get_amount_locale(get_locale_from_lang( contrib.source_locale)), 'date': datetime(contrib.created.date()), 'purchaser_email': contrib.user.email, #'purchaser_phone': '', # TODO: See bug 894614. #'purchaser_last_four': '', 'transaction_id': contrib.uuid, 'purchases_url': absolutify('/purchases'), 'support_url': addon.support_url, 'terms_of_service_url': absolutify('/terms-of-use'), } log.info('Sending email about purchase: %s' % contrib_id) text_template = 'purchase/receipt.ltxt' html_template = 'purchase/receipt.html' send_html_mail_jinja(subject, html_template, text_template, data, recipient_list=[contrib.user.email])
def get_paykey(data): """ Gets a paykey from Paypal. Need to pass in the following in data: pattern: the reverse pattern to resolve email: who the money is going to (required) amount: the amount of money (required) ip: ip address of end user (required) uuid: contribution_uuid (required) memo: any nice message (optional) qs: anything you want to append to the complete or cancel (optional) currency: valid paypal currency, defaults to USD (optional) """ if data["pattern"]: complete = reverse(data["pattern"], args=[data["slug"], "complete"]) cancel = reverse(data["pattern"], args=[data["slug"], "cancel"]) else: # If there's no pattern given, just fake some urls. complete = cancel = settings.SITE_URL + "/paypal/dummy/" qs = {"uuid": data["uuid"]} if "qs" in data: qs.update(data["qs"]) uuid_qs = urllib.urlencode(qs) paypal_data = { "actionType": "PAY", "currencyCode": data.get("currency", "USD"), "cancelUrl": absolutify("%s?%s" % (cancel, uuid_qs)), "returnUrl": absolutify("%s?%s" % (complete, uuid_qs)), "trackingId": data["uuid"], "ipnNotificationUrl": absolutify(reverse("amo.paypal")), } receivers = (data.get("chains", ()), data["email"], data["amount"], data["uuid"]) if data.get("preapproval"): # The paypal_key might be empty if they have removed it. key = data["preapproval"].paypal_key if key: paypal_log.info("Using preapproval: %s" % data["preapproval"].pk) paypal_data["preapprovalKey"] = key paypal_data.update(add_receivers(*receivers, preapproval="preapprovalKey" in paypal_data)) if data.get("memo"): paypal_data["memo"] = data["memo"] try: with statsd.timer("paypal.paykey.retrieval"): response = _call(settings.PAYPAL_PAY_URL + "Pay", paypal_data, ip=data["ip"]) except PreApprovalError, e: # Let's retry just once without preapproval. paypal_log.error("Failed using preapproval, reason: %s" % e) # Now it's not a pre-approval, make sure we get the # DIGITALGOODS setting back in there. del paypal_data["preapprovalKey"] paypal_data.update(add_receivers(*receivers)) # If this fails, we won't try again, just fail. with statsd.timer("paypal.paykey.retrieval"): response = _call(settings.PAYPAL_PAY_URL + "Pay", paypal_data, ip=data["ip"])
def send_notification(self, version): user_log.info('Sending addon update notice to %s for %s' % (self.user.email, self.addon.pk)) context = Context({ 'name': self.addon.name, 'url': absolutify( reverse('addons.detail', args=[self.addon.pk], add_prefix=False)), 'number': version.version, 'review': absolutify( reverse('editors.review', args=[self.addon.pk], add_prefix=False)), 'SITE_URL': settings.SITE_URL, }) # Not being localised because we don't know the editors locale. subject = 'Mozilla Add-ons: %s Updated' % self.addon.name template = loader.get_template('editors/emails/notify_update.ltxt') send_mail(subject, template.render(Context(context)), recipient_list=[self.user.email], from_email=settings.EDITORS_EMAIL, use_blacklist=False)
def get_preapproval_key(data): """ Get a preapproval key from PayPal. If this passes, you get a key that you can use in a redirect to PayPal. """ paypal_data = { 'currencyCode': 'USD', 'startingDate': data['startDate'].strftime('%Y-%m-%d'), 'endingDate': data['endDate'].strftime('%Y-%m-%d'), 'maxTotalAmountOfAllPayments': str(data.get('maxAmount', '2000')), 'returnUrl': absolutify(reverse(data['pattern'], args=['complete'])), 'cancelUrl': absolutify(reverse(data['pattern'], args=['cancel'])), } if settings.PAYPAL_LIMIT_PREAPPROVAL: paypal_data.update({ 'maxAmountPerPayment': 15, 'maxNumberOfPaymentsPerPeriod': 15, 'paymentPeriod': 'DAILY', }) with statsd.timer('paypal.preapproval.token'): response = _call(settings.PAYPAL_PAY_URL + 'Preapproval', paypal_data, ip=data.get('ip')) return response
def create_receipt(installed_pk): installed = Installed.objects.get(pk=installed_pk) addon_pk = installed.addon.pk verify = '%s%s' % (settings.WEBAPPS_RECEIPT_URL, addon_pk) detail = reverse('account.purchases.receipt', args=[addon_pk]) reissue = installed.addon.get_purchase_url('reissue') time_ = calendar.timegm(time.gmtime()) receipt = dict(typ='purchase-receipt', product={'url': installed.addon.origin, 'storedata': urlencode({'id': int(addon_pk)})}, user={'type': 'directed-identifier', 'value': installed.uuid}, iss=settings.SITE_URL, nbf=time_, iat=time_, exp=(time_ + settings.WEBAPPS_RECEIPT_EXPIRY_SECONDS), detail=absolutify(detail), verify=absolutify(verify), reissue=absolutify(reissue)) if settings.SIGNING_SERVER_ACTIVE: # The shiny new code. return sign(receipt) else: # Our old bad code. return jwt.encode(receipt, get_key(), u'RS512')
def prepare_pay(request, addon): """Prepare a BlueVia JWT to pass into navigator.pay()""" amount, currency, uuid_, contrib_for = start_purchase(request, addon) log.debug('Storing contrib for uuid: %s' % uuid_) Contribution.objects.create(addon_id=addon.id, amount=amount, source=request.REQUEST.get('src', ''), source_locale=request.LANG, uuid=str(uuid_), type=amo.CONTRIB_PENDING, paykey=None, user=request.amo_user, price_tier=addon.premium.price, client_data=ClientData.get_or_create(request)) prices = [{'currency': cur, 'country': 'XX', # This is unused but required! 'amount': str(tier.price)} for cur, tier in addon.premium.price.currencies()] data = {'amount': str(amount), 'prices': prices, 'currency': currency, 'app_name': unicode(addon.name), 'app_description': unicode(addon.description), 'postback_url': absolutify(reverse('webpay.postback')), 'chargeback_url': absolutify(reverse('webpay.chargeback')), 'seller': addon.pk, 'product_data': urlencode({'contrib_uuid': uuid_, 'addon_id': addon.pk}), 'typ': 'tu.com/payments/inapp/v1', 'aud': 'tu.com', 'memo': contrib_for} return {'webpayJWT': prepare_webpay_pay(data), 'contribStatusURL': reverse('webpay.pay_status', args=[addon.app_slug, uuid_])}
def test_prepare_pay(self): from mkt.purchase.webpay import make_ext_id data = self.post(self.prepare_pay) cn = Contribution.objects.get() eq_(cn.type, amo.CONTRIB_PENDING) eq_(cn.user, self.user) eq_(cn.price_tier, self.price) data = jwt.decode(data["webpayJWT"].encode("ascii"), verify=False) eq_(data["typ"], settings.APP_PURCHASE_TYP) eq_(data["aud"], settings.APP_PURCHASE_AUD) req = data["request"] eq_(req["pricePoint"], self.price.name) eq_(req["id"], make_ext_id(self.addon.pk)) eq_(req["name"], unicode(self.addon.name)) eq_(req["description"], unicode(self.addon.description)) eq_(req["postbackURL"], absolutify(reverse("webpay.postback"))) eq_(req["chargebackURL"], absolutify(reverse("webpay.chargeback"))) eq_(req["icons"]["512"], absolutify(self.addon.get_icon_url(512))) pd = urlparse.parse_qs(req["productData"]) eq_(pd["contrib_uuid"][0], cn.uuid) eq_(pd["seller_uuid"][0], self.seller.uuid) eq_(pd["addon_id"][0], str(self.addon.pk)) eq_(pd["application_size"][0], "388096")
def send_purchase_receipt(contrib_id, **kw): """ Sends an email to the purchaser of the app. """ contrib = Contribution.objects.get(pk=contrib_id) with contrib.user.activate_lang(): # L10n: {0} is the app name. subject = _('Receipt for {0}') % contrib.addon.name data = { 'app_name': contrib.addon.name, 'authors': ', '.join([ author.display_name for author in contrib.addon.authors.all() ]), 'date': datetime(contrib.created.date()), 'purchases': absolutify(reverse('account.purchases')), 'support_url': contrib.addon.support_url, 'terms_of_service_url': absolutify(reverse('site.terms')), 'transaction_id': contrib.uuid } log.info('Sending email about purchase: %s' % contrib_id) send_mail_jinja(subject, 'purchase/receipt.txt', data, recipient_list=[contrib.user.email])
def send_purchase_receipt(contrib_id, **kw): """ Sends an email to the purchaser of the app. """ contrib = Contribution.objects.get(pk=contrib_id) with contrib.user.activate_lang(): addon = contrib.addon version = addon.current_version or addon.latest_version # L10n: {0} is the app name. subject = _('Receipt for {0}').format(contrib.addon.name) data = { 'app_name': addon.name, 'developer_name': version.developer_name if version else '', 'price': contrib.get_amount_locale(get_locale_from_lang( contrib.source_locale)), 'date': jingo.helpers.datetime(contrib.created.date()), 'purchaser_email': contrib.user.email, #'purchaser_phone': '', # TODO: See bug 894614. #'purchaser_last_four': '', 'transaction_id': contrib.uuid, 'purchases_url': absolutify('/purchases'), 'support_url': addon.support_url, 'terms_of_service_url': absolutify('/terms-of-use'), } log.info('Sending email about purchase: %s' % contrib_id) text_template = 'purchase/receipt.ltxt' html_template = 'purchase/receipt.html' send_html_mail_jinja(subject, html_template, text_template, data, recipient_list=[contrib.user.email])
def _prepare_pay(request, addon): """Prepare a JWT to pass into navigator.pay()""" if addon.is_premium() and addon.has_purchased(request.amo_user): log.info('Already purchased: %d' % addon.pk) raise AlreadyPurchased amount, currency, uuid_, contrib_for = start_purchase(request, addon) log.debug('Storing contrib for uuid: %s' % uuid_) Contribution.objects.create(addon_id=addon.id, amount=amount, source=request.REQUEST.get('src', ''), source_locale=request.LANG, uuid=str(uuid_), type=amo.CONTRIB_PENDING, paykey=None, user=request.amo_user, price_tier=addon.premium.price, client_data=ClientData.get_or_create(request)) # Until atob() supports encoded HTML we are stripping all tags. # See bug 831524 app_description = bleach.clean(unicode(addon.description), strip=True, tags=[]) acct = addon.app_payment_account.payment_account seller_uuid = acct.solitude_seller.uuid application_size = addon.current_version.all_files[0].size issued_at = calendar.timegm(time.gmtime()) icons = {} for size in amo.ADDON_ICON_SIZES: icons[str(size)] = absolutify(addon.get_icon_url(size)) req = { 'iss': settings.APP_PURCHASE_KEY, 'typ': settings.APP_PURCHASE_TYP, 'aud': settings.APP_PURCHASE_AUD, 'iat': issued_at, 'exp': issued_at + 3600, # expires in 1 hour 'request': { 'name': unicode(addon.name), 'description': app_description, 'pricePoint': addon.premium.price.name, 'id': make_ext_id(addon.pk), 'postbackURL': absolutify(reverse('webpay.postback')), 'chargebackURL': absolutify(reverse('webpay.chargeback')), 'productData': urlencode({'contrib_uuid': uuid_, 'seller_uuid': seller_uuid, 'addon_id': addon.pk, 'application_size': application_size}), 'icons': icons, } } jwt_ = sign_webpay_jwt(req) log.debug('Preparing webpay JWT for addon %s: %s' % (addon, jwt_)) app_pay_cef.log(request, 'Preparing JWT', 'preparing_jwt', 'Preparing JWT for: %s' % (addon.pk), severity=3) if request.API: url = reverse('webpay-status', kwargs={'uuid': uuid_}) else: url = reverse('webpay.pay_status', args=[addon.app_slug, uuid_]) return {'webpayJWT': jwt_, 'contribStatusURL': url}
def get_product_jwt(product, user=None, region=None, source=None, lang=None, client_data=None): """Prepare a JWT for paid products to pass into navigator.pay()""" # TODO: Contribution should be created outside of the JWT producer contribution = Contribution.objects.create( addon_id=product.addon().pk, amount=product.amount(region), client_data=client_data, paykey=None, price_tier=product.price(), source=source, source_locale=lang, type=amo.CONTRIB_PENDING, user=user, uuid=str(uuid.uuid4()), ) log.debug('Storing contrib for uuid: {0}'.format(contribution.uuid)) user_id = user.pk if user else None log.debug('Starting purchase of app: {0} by user: {1}'.format( product.id(), user_id)) issued_at = calendar.timegm(time.gmtime()) token_data = { 'iss': settings.APP_PURCHASE_KEY, 'typ': settings.APP_PURCHASE_TYP, 'aud': settings.APP_PURCHASE_AUD, 'iat': issued_at, 'exp': issued_at + 3600, # expires in 1 hour 'request': { 'id': product.external_id(), 'name': unicode(product.name()), 'icons': product.icons(), 'description': strip_tags(product.description()), 'pricePoint': product.price().name, 'productData': urlencode(product.product_data(contribution)), 'chargebackURL': absolutify(reverse('webpay.chargeback')), 'postbackURL': absolutify(reverse('webpay.postback')), } } token = sign_webpay_jwt(token_data) log.debug('Preparing webpay JWT for self.product {0}: {1}'.format( product.id(), token)) return { 'webpayJWT': token, 'contribStatusURL': reverse('webpay-status', kwargs={'uuid': contribution.uuid}) }
def get_paykey(data): """ Gets a paykey from Paypal. Need to pass in the following in data: pattern: the reverse pattern to resolve email: who the money is going to (required) amount: the amount of money (required) ip: ip address of end user (required) uuid: contribution_uuid (required) memo: any nice message (optional) qs: anything you want to append to the complete or cancel (optional) currency: valid paypal currency, defaults to USD (optional) """ complete = reverse(data['pattern'], args=[data['slug'], 'complete']) cancel = reverse(data['pattern'], args=[data['slug'], 'cancel']) qs = {'uuid': data['uuid']} if 'qs' in data: qs.update(data['qs']) uuid_qs = urllib.urlencode(qs) paypal_data = { 'actionType': 'PAY', 'currencyCode': data.get('currency', 'USD'), 'cancelUrl': absolutify('%s?%s' % (cancel, uuid_qs)), 'returnUrl': absolutify('%s?%s' % (complete, uuid_qs)), 'trackingId': data['uuid'], 'ipnNotificationUrl': absolutify(reverse('amo.paypal'))} receivers = (data.get('chains', ()), data['email'], data['amount'], data['uuid']) if data.get('preapproval'): # The paypal_key might be empty if they have removed it. key = data['preapproval'].paypal_key if key: paypal_log.info('Using preapproval: %s' % data['preapproval'].pk) paypal_data['preapprovalKey'] = key paypal_data.update(add_receivers(*receivers, preapproval='preapprovalKey' in paypal_data)) if data.get('memo'): paypal_data['memo'] = data['memo'] try: with statsd.timer('paypal.paykey.retrieval'): response = _call(settings.PAYPAL_PAY_URL + 'Pay', paypal_data, ip=data['ip']) except PreApprovalError, e: # Let's retry just once without preapproval. paypal_log.error('Failed using preapproval, reason: %s' % e) # Now it's not a pre-approval, make sure we get the # DIGITALGOODS setting back in there. del paypal_data['preapprovalKey'] paypal_data.update(add_receivers(*receivers)) # If this fails, we won't try again, just fail. with statsd.timer('paypal.paykey.retrieval'): response = _call(settings.PAYPAL_PAY_URL + 'Pay', paypal_data, ip=data['ip'])
def test_preapproval_patterns(self, _call): _call.return_value = good_preapproval_string data = self.get_data() paypal.get_preapproval_key(data) eq_(_call.call_args[0][1]['cancelUrl'], absolutify(reverse(data['pattern'], args=['cancel']))) eq_(_call.call_args[0][1]['returnUrl'], absolutify(reverse(data['pattern'], args=['complete'])))
def test_suggestions(self): response = self.client.get(self.url, data={"lang": "en-US"}) parsed = json.loads(response.content) eq_(parsed[0], "") self.assertSetEqual(parsed[1], [unicode(self.app1.name), unicode(self.app2.name)]) self.assertSetEqual(parsed[2], [unicode(self.app1.description), unicode(truncate(self.app2.description))]) self.assertSetEqual(parsed[3], [absolutify(self.app1.get_detail_url()), absolutify(self.app2.get_detail_url())]) self.assertSetEqual(parsed[4], [self.app1.get_icon_url(64), self.app2.get_icon_url(64)])
def notify_compatibility(users, job, data, **kw): log.info('[%s@%s] Sending notification mail for job %s.' % (len(users), notify_compatibility.rate_limit, job.pk)) set_user(get_task_user()) dry_run = data['preview_only'] app_id = job.target_version.application.pk stats = collections.defaultdict(int) stats['processed'] = 0 stats['is_dry_run'] = int(dry_run) for user in users: stats['processed'] += 1 for a in chain(user.passing_addons, user.failing_addons): results = job.result_set.filter(file__version__addon=a) a.links = ' '.join(absolutify(reverse('devhub.bulk_compat_result', args=[a.slug, r.pk])) for r in results) a.compat_link = absolutify(reverse('devhub.versions.edit', args=[a.pk, a.current_version.pk])) context = Context({ 'APPLICATION': str(job.application), 'VERSION': job.target_version.version, 'PASSING_ADDONS': user.passing_addons, 'FAILING_ADDONS': user.failing_addons, }) log.info(u'Emailing %s%s for %d addons about ' 'bulk validation job %s' % (user.email, ' [PREVIEW]' if dry_run else '', len(user.passing_addons) + len(user.failing_addons), job.pk)) args = (Template(data['subject']).render(context), Template(data['text']).render(context)) kwargs = dict(from_email=settings.DEFAULT_FROM_EMAIL, recipient_list=[user.email]) if dry_run: job.preview_notify_mail(*args, **kwargs) else: stats['author_emailed'] += 1 send_mail(*args, **kwargs) amo.log(amo.LOG.BULK_VALIDATION_USER_EMAILED, user, details={'passing': [a.id for a in user.passing_addons], 'failing': [a.id for a in user.failing_addons], 'target': job.target_version.version, 'application': app_id}) log.info('[%s@%s] bulk email stats for job %s: {%s}' % (len(users), notify_compatibility.rate_limit, job.pk, ', '.join('%s: %s' % (k, stats[k]) for k in sorted(stats.keys()))))
def get_product_jwt(product, user=None, region=None, source=None, lang=None, client_data=None): """Prepare a JWT for paid products to pass into navigator.pay()""" # TODO: Contribution should be created outside of the JWT producer contribution = Contribution.objects.create( addon_id=product.addon().pk, amount=product.amount(region), client_data=client_data, paykey=None, price_tier=product.price(), source=source, source_locale=lang, type=amo.CONTRIB_PENDING, user=user, uuid=str(uuid.uuid4()), ) log.debug('Storing contrib for uuid: {0}'.format(contribution.uuid)) user_id = user.pk if user else None log.debug('Starting purchase of app: {0} by user: {1}'.format( product.id(), user_id)) issued_at = calendar.timegm(time.gmtime()) token_data = { 'iss': settings.APP_PURCHASE_KEY, 'typ': settings.APP_PURCHASE_TYP, 'aud': settings.APP_PURCHASE_AUD, 'iat': issued_at, 'exp': issued_at + 3600, # expires in 1 hour 'request': { 'id': product.external_id(), 'name': unicode(product.name()), 'icons': product.icons(), 'description': strip_tags(product.description()), 'pricePoint': product.price().name, 'productData': urlencode(product.product_data(contribution)), 'chargebackURL': absolutify(reverse('webpay.chargeback')), 'postbackURL': absolutify(reverse('webpay.postback')), } } token = sign_webpay_jwt(token_data) log.debug('Preparing webpay JWT for self.product {0}: {1}'.format( product.id(), token)) return { 'webpayJWT': token, 'contribStatusURL': reverse( 'webpay-status', kwargs={ 'uuid': contribution.uuid } ) }
def setUp(self): self.data = { 'return_url': absolutify(reverse('home')), 'cancel_url': absolutify(reverse('home')), 'amount': 10, 'email': '*****@*****.**', 'uuid': time.time(), 'ip': '127.0.0.1' }
def get_context_data(self): return { "name": self.addon.name, "number": self.version.version, "reviewer": (self.request.user.display_name), "addon_url": absolutify(self.addon.get_url_path(add_prefix=False)), "review_url": absolutify(reverse("editors.review", args=[self.addon.pk], add_prefix=False)), "comments": self.data["comments"], "SITE_URL": settings.SITE_URL, }
def get_context_data(self): return { "name": self.addon.name, "reviewer": self.request.user.get_profile().name, "detail_url": absolutify(self.addon.get_url_path(add_prefix=False)), "review_url": absolutify(reverse("reviewers.apps.review", args=[self.addon.app_slug], add_prefix=False)), "status_url": absolutify(self.addon.get_dev_url("versions")), "comments": self.data["comments"], "MKT_SUPPORT_EMAIL": settings.MKT_SUPPORT_EMAIL, "SITE_URL": settings.SITE_URL, }
def get_context_data(self): return {'name': self.addon.name, 'number': self.version.version, 'reviewer': (self.request.user.display_name), 'addon_url': absolutify( self.addon.get_url_path(add_prefix=False)), 'review_url': absolutify(reverse('editors.review', args=[self.addon.pk], add_prefix=False)), 'comments': self.data['comments'], 'SITE_URL': settings.SITE_URL}
def create_receipt(webapp, user, uuid, flavour=None): """ Creates a receipt for use in payments. :params app: the app record. :params user: the UserProfile record. :params uuid: a uuid placed in the user field for this purchase. :params flavour: None, developer or reviewer, the flavour of receipt. """ assert flavour in [None, 'developer', 'reviewer'], ('Invalid flavour: %s' % flavour) time_ = calendar.timegm(time.gmtime()) typ = 'purchase-receipt' product = { 'storedata': urlencode({'id': int(webapp.pk)}), # Packaged and hosted apps should have an origin. If there # isn't one, fallback to the SITE_URL. 'url': webapp.origin or settings.SITE_URL } # Generate different receipts for reviewers or developers. expiry = time_ + settings.WEBAPPS_RECEIPT_EXPIRY_SECONDS if flavour: if not (acl.action_allowed_user(user, 'Apps', 'Review') or webapp.has_author(user)): raise ValueError('User %s is not a reviewer or developer' % user.pk) # Developer and reviewer receipts should expire after 24 hours. expiry = time_ + (60 * 60 * 24) typ = flavour + '-receipt' verify = absolutify(reverse('receipt.verify', args=[webapp.guid])) else: verify = settings.WEBAPPS_RECEIPT_URL reissue = absolutify(reverse('receipt.reissue')) receipt = dict( exp=expiry, iat=time_, iss=settings.SITE_URL, nbf=time_, product=product, # TODO: This is temporary until detail pages get added. detail=absolutify(reissue), # Currently this is a 404. reissue=absolutify(reissue), typ=typ, user={ 'type': 'directed-identifier', 'value': uuid }, verify=verify) return sign(receipt)
def get_context_data(self): return {'name': self.addon.name, 'reviewer': self.request.user.get_profile().name, 'detail_url': absolutify( self.addon.get_url_path(add_prefix=False)), 'review_url': absolutify(reverse('reviewers.apps.review', args=[self.addon.app_slug], add_prefix=False)), 'status_url': absolutify(self.addon.get_dev_url('versions')), 'comments': self.data['comments'], 'MKT_SUPPORT_EMAIL': settings.MKT_SUPPORT_EMAIL, 'SITE_URL': settings.SITE_URL}
def create_receipt(installed, flavour=None): assert flavour in [None, 'developer', 'reviewer'], ('Invalid flavour: %s' % flavour) webapp = installed.addon time_ = calendar.timegm(time.gmtime()) typ = 'purchase-receipt' product = { 'storedata': urlencode({'id': int(webapp.pk)}), # Packaged and hosted apps should have an origin. If there # isn't one, fallback to the SITE_URL. 'url': webapp.origin or settings.SITE_URL } # Generate different receipts for reviewers or developers. expiry = time_ + settings.WEBAPPS_RECEIPT_EXPIRY_SECONDS if flavour: if not (acl.action_allowed_user(installed.user, 'Apps', 'Review') or webapp.has_author(installed.user)): raise ValueError('User %s is not a reviewer or developer' % installed.user.pk) # Developer and reviewer receipts should expire after 24 hours. expiry = time_ + (60 * 60 * 24) typ = flavour + '-receipt' verify = absolutify(reverse('receipt.verify', args=[webapp.guid])) else: verify = settings.WEBAPPS_RECEIPT_URL reissue = absolutify(reverse('receipt.reissue')) receipt = dict( exp=expiry, iat=time_, iss=settings.SITE_URL, nbf=time_, product=product, # TODO: This is temporary until detail pages get added. detail=absolutify(reissue), # Currently this is a 404. reissue=absolutify(reissue), # Currently this is a 404. typ=typ, user={ 'type': 'directed-identifier', 'value': installed.uuid }, verify=verify) if settings.SIGNING_SERVER_ACTIVE: # The shiny new code. return sign(receipt) else: # Our old bad code. return jwt.encode(receipt, get_key(), u'RS512')
def preapproval(request, complete=None, cancel=None): if waffle.switch_is_active('currencies'): failure = currency(request, do_redirect=False) if failure: return failure today = datetime.today() data = { 'startDate': today, 'endDate': today + timedelta(days=365), } store = { 'expiry': data['endDate'], 'solitude-key': None, 'complete': complete, 'cancel': cancel, } if waffle.flag_is_active(request, 'solitude-payments'): client.create_buyer_if_missing(request.amo_user) try: result = client.post_preapproval( data={ 'start': data['startDate'].date(), 'end': data['endDate'].date(), 'uuid': request.amo_user, 'return_url': absolutify(reverse('account.payment', args=['complete'])), 'cancel_url': absolutify(reverse('account.payment', args=['cancel'])), }) except client.Error: paypal_log.error(u'preapproval', exc_info=True) raise store.update({'key': result['key'], 'solitude-key': result['pk']}) url = result['paypal_url'] else: # TODO(solitude): remove this. data.update({'pattern': 'account.payment'}) try: result = paypal.get_preapproval_key(data) except paypal.PaypalError, e: paypal_log.error(u'Preapproval key: %s' % e, exc_info=True) raise store.update({'key': result['preapprovalKey']}) url = paypal.get_preapproval_url(result['preapprovalKey'])
def get_context(addon, version, job, results): result_links = (absolutify(reverse('devhub.validation_result', args=[addon.slug, r.pk])) for r in results) return Context({ 'ADDON_NAME': addon.name, 'ADDON_VERSION': version.version, 'APPLICATION': str(job.application), 'COMPAT_LINK': absolutify(reverse('devhub.versions.edit', args=[addon.pk, version.pk])), 'RESULT_LINKS': ' '.join(result_links), 'VERSION': job.target_version.version, })
def good_data(da): da = json.loads(da) # TODO(Kumar) fix this when we have default currencies (bug 777747) eq_(da['currency'], 'USD') eq_(da['amount'], str(self.price.price)) eq_(da['app_name'], unicode(self.addon.name)) eq_(da['app_description'], unicode(self.addon.description)) eq_(da['postback_url'], absolutify(reverse('bluevia.postback'))) eq_(da['chargeback_url'], absolutify(reverse('bluevia.chargeback'))) assert 'contrib_uuid' in da return True
def get_context_data(self): if self.addon.is_listed: url = self.addon.get_url_path(add_prefix=False) else: url = self.addon.get_dev_url('versions') return {'name': self.addon.name, 'number': self.version.version, 'reviewer': self.user.display_name, 'addon_url': absolutify(url), 'review_url': absolutify(reverse('editors.review', args=[self.addon.pk], add_prefix=False)), 'comments': self.data.get('comments'), 'SITE_URL': settings.SITE_URL}
def get_context_data(self): if self.addon.is_listed: url = self.addon.get_url_path(add_prefix=False) else: url = self.addon.get_dev_url("versions") return { "name": self.addon.name, "number": self.version.version, "reviewer": self.user.display_name, "addon_url": absolutify(url), "review_url": absolutify(reverse("editors.review", args=[self.addon.pk], add_prefix=False)), "comments": self.data.get("comments"), "SITE_URL": settings.SITE_URL, }
def get_context(addon, version, job, results, fileob=None): result_links = (absolutify(reverse('devhub.bulk_compat_result', args=[addon.slug, r.pk])) for r in results) addon_name = addon.name if fileob and fileob.platform != amo.PLATFORM_ALL.id: addon_name = u'%s (%s)' % (addon_name, fileob.get_platform_display()) return Context({ 'ADDON_NAME': addon_name, 'ADDON_VERSION': version.version, 'APPLICATION': str(job.application), 'COMPAT_LINK': absolutify(reverse('devhub.versions.edit', args=[addon.pk, version.pk])), 'RESULT_LINKS': ' '.join(result_links), 'VERSION': job.target_version.version})
def get_context(addon, version, job, results, fileob=None): result_links = (absolutify(reverse("devhub.bulk_compat_result", args=[addon.slug, r.pk])) for r in results) addon_name = addon.name if fileob and fileob.platform.id != amo.PLATFORM_ALL.id: addon_name = u"%s (%s)" % (addon_name, fileob.platform) return Context( { "ADDON_NAME": addon_name, "ADDON_VERSION": version.version, "APPLICATION": str(job.application), "COMPAT_LINK": absolutify(reverse("devhub.versions.edit", args=[addon.pk, version.pk])), "RESULT_LINKS": " ".join(result_links), "VERSION": job.target_version.version, } )
def create_receipt(installed_pk): installed = Installed.objects.get(pk=installed_pk) verify = "%s%s" % (settings.WEBAPPS_RECEIPT_URL, 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.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_paykey(data): """ Gets a paykey from Paypal. Need to pass in the following in data: pattern: the reverse pattern to resolve email: who the money is going to (required) amount: the amount of money (required) ip: ip address of end user (required) uuid: contribution_uuid (required) memo: any nice message (optional) qs: anything you want to append to the complete or cancel (optional) currency: valid paypal currency, defaults to USD (optional) """ if data['pattern']: complete = reverse(data['pattern'], args=[data['slug'], 'complete']) cancel = reverse(data['pattern'], args=[data['slug'], 'cancel']) else: # If there's no pattern given, just fake some urls. complete = cancel = settings.SITE_URL + '/paypal/dummy/' qs = {'uuid': data['uuid']} if 'qs' in data: qs.update(data['qs']) uuid_qs = urllib.urlencode(qs) paypal_data = { 'actionType': 'PAY', 'currencyCode': data.get('currency', 'USD'), 'cancelUrl': absolutify('%s?%s' % (cancel, uuid_qs)), 'returnUrl': absolutify('%s?%s' % (complete, uuid_qs)), 'trackingId': data['uuid'], 'ipnNotificationUrl': absolutify(reverse('amo.paypal')), 'receiverList.receiver(0).email': data['email'], 'receiverList.receiver(0).amount': data['amount'], 'receiverList.receiver(0).invoiceID': 'mozilla-%s' % data['uuid'], 'receiverList.receiver(0).primary': 'TRUE', 'receiverList.receiver(0).paymentType': 'DIGITALGOODS', 'requestEnvelope.errorLanguage': 'US' } if data.get('memo'): paypal_data['memo'] = data['memo'] with statsd.timer('paypal.paykey.retrieval'): response = _call(settings.PAYPAL_PAY_URL + 'Pay', paypal_data, ip=data['ip']) return response['payKey'], response['paymentExecStatus']
def create_receipt(installed_pk, flavour=None): assert flavour in [None, 'developer', 'reviewer'], ('Invalid flavour: %s' % flavour) installed = Installed.objects.get(pk=installed_pk) webapp = installed.addon origin = (settings.SITE_URL if webapp.is_packaged else webapp.origin) time_ = calendar.timegm(time.gmtime()) product = {'url': origin, 'storedata': urlencode({'id': int(webapp.pk)})} # Generate different receipts for reviewers or developers. expiry = time_ + settings.WEBAPPS_RECEIPT_EXPIRY_SECONDS if flavour: if not (acl.action_allowed_user(installed.user, 'Apps', 'Review') or webapp.has_author(installed.user)): raise ValueError('User %s is not a reviewer or developer' % installed.user.pk) if flavour == 'reviewer': expiry = time_ + (60 * 60 * 24) product['type'] = flavour verify = absolutify(reverse('receipt.verify', args=[webapp.app_slug])) else: verify = settings.WEBAPPS_RECEIPT_URL detail = reverse('account.purchases.receipt', args=[webapp.pk]) reissue = webapp.get_purchase_url('reissue') receipt = dict(detail=absolutify(detail), exp=expiry, iat=time_, iss=settings.SITE_URL, nbf=time_, product=product, reissue=absolutify(reissue), typ='purchase-receipt', user={ 'type': 'directed-identifier', 'value': installed.uuid }, verify=verify) if settings.SIGNING_SERVER_ACTIVE: # The shiny new code. return sign(receipt) else: # Our old bad code. return jwt.encode(receipt, get_key(), u'RS512')
def good_data(da): da = json.loads(da) # TODO(Kumar) fix this when we have default currencies (bug 777747) eq_(da['currency'], 'USD') eq_(da['typ'], 'tu.com/payments/inapp/v1') eq_(da['aud'], 'tu.com') eq_(da['amount'], str(self.price.price)) eq_(da['app_name'], unicode(self.addon.name)) eq_(da['app_description'], unicode(self.addon.description)) eq_(da['postback_url'], absolutify(reverse('bluevia.postback'))) eq_(da['chargeback_url'], absolutify(reverse('bluevia.chargeback'))) pd = urlparse.parse_qs(da['product_data']) assert 'contrib_uuid' in pd, 'Unexpected: %s' % pd eq_(pd['addon_id'][0], str(self.addon.pk)) return True
def refund_permission_url(addon, dest='payments'): """ Send permissions request to PayPal for refund privileges on this addon's paypal account. Returns URL on PayPal site to visit. """ # This is set in settings_test so we don't start calling PayPal # by accident. Explicitly set this in your tests. if not settings.PAYPAL_PERMISSIONS_URL: return '' paypal_log.debug('Getting refund permission URL for addon: %s' % addon.pk) with statsd.timer('paypal.permissions.url'): url = urlparams(reverse('devhub.addons.acquire_refund_permission', args=[addon.slug]), dest=dest) try: r = _call(settings.PAYPAL_PERMISSIONS_URL + 'RequestPermissions', { 'scope': 'REFUND', 'callback': absolutify(url) }) except PaypalError, e: paypal_log.debug('Error on refund permission URL addon: %s, %s' % (addon.pk, e)) if 'malformed' in str(e): # PayPal is very picky about where they redirect users to. # If you try and create a PayPal permissions URL on a # zamboni that has a non-standard port number or a # non-standard TLD, it will blow up with an error. We need # to be able to at least visit these pages and alter them # in dev, so this will give you a broken token that doesn't # work, but at least the page will function. r = {'token': 'wont-work-paypal-doesnt-like-your-domain'} else: raise
def link(self, category): """Link for the feed as a whole""" if self.category: base = url('browse.search-tools.rss', self.category.slug) else: base = url('browse.search-tools.rss') return absolutify(base + '?sort=' + self.sort)
def _mini_manifest(addon, version_id, token=None): if not addon.is_packaged: raise http.Http404 version = get_object_or_404(addon.versions, pk=version_id) file_ = version.all_files[0] manifest = addon.get_manifest_json(file_) package_path = absolutify( reverse('reviewers.signed', args=[addon.app_slug, version.id])) if token: # Generate a fresh token. token = Token(data={'app_id': addon.id}) token.save() package_path = urlparams(package_path, token=token.token) data = { 'name': manifest['name'], 'version': version.version, 'size': file_.size, 'release_notes': version.releasenotes, 'package_path': package_path, } for key in ['developer', 'icons', 'locales']: if key in manifest: data[key] = manifest[key] return json.dumps(data, cls=JSONEncoder)
def _mini_manifest(addon, version_id): if not addon.is_packaged: raise http.Http404 version = get_object_or_404(addon.versions, pk=version_id) file_ = version.all_files[0] manifest = addon.get_manifest_json(file_) data = { 'name': addon.name, 'version': version.version, 'size': file_.size, 'release_notes': version.releasenotes, 'package_path': absolutify( reverse('reviewers.signed', args=[addon.app_slug, version.id])) } if 'icons' in manifest: data['icons'] = manifest['icons'] if 'locales' in manifest: data['locales'] = manifest['locales'] return json.dumps(data, cls=JSONEncoder)
def test_verify(self): url = absolutify( reverse('receipt.test.verify', kwargs={'status': 'expired'})) receipt = create_test_receipt('http://foo', 'expired') req = RawRequestFactory().post(url, receipt) res = devhub_verify(req, 'expired') eq_(json.loads(res.content)['status'], 'expired')