def api(request): roles = request.amo_user.groups.filter(name="Admins").exists() f = APIConsumerForm() if roles: messages.error(request, _("Users with the admin role cannot use the API.")) elif request.method == "POST": if "delete" in request.POST: try: consumer = Access.objects.get(pk=request.POST.get("consumer")) consumer.delete() except Access.DoesNotExist: messages.error(request, _("No such API key.")) else: key = "mkt:%s:%s:%s" % ( request.amo_user.pk, request.amo_user.email, Access.objects.filter(user=request.user).count(), ) access = Access.objects.create(key=key, user=request.user, secret=generate()) f = APIConsumerForm(request.POST, instance=access) if f.is_valid(): f.save() messages.success(request, _("New API key generated.")) else: access.delete() consumers = list(Access.objects.filter(user=request.user)) return jingo.render( request, "developers/api.html", {"consumers": consumers, "profile": profile, "roles": roles, "form": f} )
def hera(request): form = FlushForm(initial={"flushprefix": site_settings.SITE_URL}) boxes = [] configured = False # Default to not showing the form. for i in site_settings.HERA: hera = get_hera(i) r = {"location": urlparse(i["LOCATION"])[1], "stats": False} if hera: r["stats"] = hera.getGlobalCacheInfo() configured = True boxes.append(r) if not configured: messages.error(request, "Hera is not (or mis-)configured.") form = None if request.method == "POST" and hera: form = FlushForm(request.POST) if form.is_valid(): expressions = request.POST["flushlist"].splitlines() for url in expressions: num = flush_urls([url], request.POST["flushprefix"], True) msg = "Flushed %d objects from front end cache for: %s" % (len(num), url) log.info("[Hera] (user:%s) %s" % (request.user, msg)) messages.success(request, msg) return jingo.render(request, "zadmin/hera.html", {"form": form, "boxes": boxes})
def in_app_config(request, addon_id, addon, webapp=True): inapp = addon.premium_type in amo.ADDON_INAPPS if not inapp: messages.error(request, _('Your app is not configured for in-app payments.')) return redirect(reverse('mkt.developers.apps.payments', args=[addon.app_slug])) try: account = addon.app_payment_account except ObjectDoesNotExist: messages.error(request, _('No payment account for this app.')) return redirect(reverse('mkt.developers.apps.payments', args=[addon.app_slug])) seller_config = get_seller_product(account) owner = acl.check_addon_ownership(request, addon) if request.method == 'POST': # Reset the in-app secret for the app. (client.api.generic .product(seller_config['resource_pk']) .patch(data={'secret': generate_key(48)})) messages.success(request, _('Changes successfully saved.')) return redirect(reverse('mkt.developers.apps.in_app_config', args=[addon.app_slug])) return jingo.render(request, 'developers/payments/in-app-config.html', {'addon': addon, 'owner': owner, 'seller_config': seller_config})
def hera(request): form = FlushForm(initial={'flushprefix': settings.SITE_URL}) boxes = [] configured = False # Default to not showing the form. for i in settings.HERA: hera = get_hera(i) r = {'location': urlparse(i['LOCATION'])[1], 'stats': False} if hera: r['stats'] = hera.getGlobalCacheInfo() configured = True boxes.append(r) if not configured: messages.error(request, "Hera is not (or mis-)configured.") form = None if request.method == 'POST' and hera: form = FlushForm(request.POST) if form.is_valid(): expressions = request.POST['flushlist'].splitlines() for url in expressions: num = flush_urls([url], request.POST['flushprefix'], True) msg = ("Flushed %d objects from front end cache for: %s" % (len(num), url)) log.info("[Hera] (user:%s) %s" % (request.user, msg)) messages.success(request, msg) return jingo.render(request, 'zadmin/hera.html', {'form': form, 'boxes': boxes})
def paypal_setup(request, addon_id, addon, webapp): if addon.premium_type == amo.ADDON_FREE: messages.error(request, "Your app does not use payments.") return redirect(addon.get_dev_url("payments")) paypal_form = PaypalSetupForm(request.POST or None) currency_form = CurrencyForm( request.POST or None, initial={"currencies": addon.premium.currencies if addon.premium else {}} ) context = {"addon": addon, "paypal_form": paypal_form, "currency_form": currency_form} if request.POST.get("form") == "paypal" and paypal_form.is_valid(): existing = paypal_form.cleaned_data["business_account"] if existing != "yes": # Go create an account. # TODO: this will either become the API or something some better # URL for the future. return redirect(settings.PAYPAL_CGI_URL) else: # Go setup your details on paypal. addon.update(paypal_id=paypal_form.cleaned_data["email"]) if addon.premium and addon.premium.paypal_permissions_token: addon.premium.update(paypal_permissions_token="") return redirect(addon.get_dev_url("paypal_setup_bounce")) if waffle.switch_is_active("currencies") and request.POST.get("form") == "currency" and currency_form.is_valid(): currencies = currency_form.cleaned_data["currencies"] addon.premium.update(currencies=currencies) messages.success(request, _("Currencies updated.")) return redirect(addon.get_dev_url("paypal_setup")) return jingo.render(request, "developers/payments/paypal-setup.html", context)
def api(request): roles = request.amo_user.groups.filter(name='Admins').exists() f = APIConsumerForm() if roles: messages.error(request, _('Users with the admin role cannot use the API.')) elif request.method == 'POST': if 'delete' in request.POST: try: consumer = Access.objects.get(pk=request.POST.get('consumer')) consumer.delete() except Access.DoesNotExist: messages.error(request, _('No such API key.')) else: key = 'mkt:%s:%s:%s' % ( request.amo_user.pk, request.amo_user.email, Access.objects.filter(user=request.user).count()) access = Access.objects.create(key=key, user=request.user, secret=generate()) f = APIConsumerForm(request.POST, instance=access) if f.is_valid(): f.save() messages.success(request, _('New API key generated.')) else: access.delete() consumers = list(Access.objects.filter(user=request.user)) return jingo.render(request, 'developers/api.html', {'consumers': consumers, 'roles': roles, 'form': f})
def in_app_config(request, addon_id, addon, webapp=True): if addon.premium_type not in amo.ADDON_INAPPS: messages.error(request, 'Your app does not use payments.') return redirect(addon.get_dev_url('payments')) try: inapp_config = InappConfig.objects.get(addon=addon, status=amo.INAPP_STATUS_ACTIVE) except models.ObjectDoesNotExist: inapp_config = None inapp_form = InappConfigForm(request.POST or None, instance=inapp_config) if request.method == 'POST' and inapp_form.is_valid(): new_inapp = inapp_form.save(commit=False) new_inapp.addon = addon new_inapp.status = amo.INAPP_STATUS_ACTIVE if not new_inapp.public_key: new_inapp.public_key = InappConfig.generate_public_key() new_inapp.save() if not new_inapp.has_private_key(): new_inapp.set_private_key(InappConfig.generate_private_key()) messages.success(request, _('Changes successfully saved.')) return redirect(addon.get_dev_url('in_app_config')) return jingo.render(request, 'developers/payments/in-app-config.html', dict(addon=addon, inapp_form=inapp_form, inapp_config=inapp_config))
def issue_refund(request, addon_id, addon, webapp=False): txn_id = request.REQUEST.get("transaction_id") if not txn_id: raise http.Http404 form_enabled = True contribution = get_object_or_404( Contribution, transaction_id=txn_id, type__in=[amo.CONTRIB_PURCHASE, amo.CONTRIB_INAPP] ) if hasattr(contribution, "refund") and contribution.refund.status not in (amo.REFUND_PENDING, amo.REFUND_FAILED): # If it's not pending, we've already taken action. messages.error(request, _("Refund already processed.")) form_enabled = False elif request.method == "POST": if "issue" in request.POST: if waffle.flag_is_active(request, "solitude-payments"): try: response = client.post_refund(data={"uuid": contribution.transaction_id}) except client.Error, e: contribution.record_failed_refund(e) paypal_log.error("Refund failed for: %s" % txn_id, exc_info=True) messages.error(request, _("There was an error with " "the refund.")) return redirect(addon.get_dev_url("refunds")) results = response["response"] else: # TODO(solitude): remove this. try: results = paypal.refund(contribution.paykey) except PaypalError, e: contribution.record_failed_refund(e) paypal_log.error("Refund failed for: %s" % txn_id, exc_info=True) messages.error(request, _("There was an error with " "the refund.")) return redirect(addon.get_dev_url("refunds")) for res in results: if res["refundStatus"] == "ALREADY_REVERSED_OR_REFUNDED": paypal_log.debug( "Refund attempt for already-refunded paykey: %s, %s" % (contribution.paykey, res["receiver.email"]) ) messages.error(request, _("Refund was previously issued; " "no action taken.")) return redirect(addon.get_dev_url("refunds")) elif res["refundStatus"] == "NO_API_ACCESS_TO_RECEIVER": paypal_log.debug( "Refund attempt for product %s with no " "refund token: %s, %s" % (contribution.addon.pk, contribution.paykey, res["receiver.email"]) ) messages.error( request, _("A refund can't be issued at this time. We've " "notified an admin; please try again later."), ) return redirect(addon.get_dev_url("refunds")) contribution.mail_approved() amo.log(amo.LOG.REFUND_GRANTED, addon, contribution.user) refund = contribution.enqueue_refund(amo.REFUND_APPROVED) paypal_log.info("Refund %r issued for contribution %r" % (refund.pk, contribution.pk)) messages.success(request, _("Refund issued."))
def in_app_config(request, addon_id, addon, webapp=True): inapp = addon.premium_type in amo.ADDON_INAPPS if not inapp: messages.error(request, _("Your app is not configured for in-app payments.")) return redirect(reverse("mkt.developers.apps.payments", args=[addon.app_slug])) try: account = addon.app_payment_account except ObjectDoesNotExist: messages.error(request, _("No payment account for this app.")) return redirect(reverse("mkt.developers.apps.payments", args=[addon.app_slug])) seller_config = get_seller_product(account) owner = acl.check_addon_ownership(request, addon) if request.method == "POST": # Reset the in-app secret for the app. (client.api.generic.product(seller_config["resource_pk"]).patch(data={"secret": generate_key(48)})) messages.success(request, _("Changes successfully saved.")) return redirect(reverse("mkt.developers.apps.in_app_config", args=[addon.app_slug])) return jingo.render( request, "developers/payments/in-app-config.html", {"addon": addon, "owner": owner, "seller_config": seller_config}, )
def landing(request): """Developer Hub landing page.""" _refresh_mdn(request) videos = [ {"name": "airbnb", "path": "FirefoxMarketplace-airbnb-BR-RC-SD1%20640"}, {"name": "evernote", "path": "FirefoxMarketplace-Evernote_BR-RC-SD1%20640"}, {"name": "uken", "path": "FirefoxMarketplace-uken-BR-RC-SD1%20640"}, {"name": "soundcloud", "path": "FirefoxMarketplace-Soundcloud-BR-RC-SD1%20640"}, {"name": "box", "path": "FirefoxMarketplace_box-BR-RC-SD1%20640"}, ] form = DevNewsletterForm(request.POST or None) if request.method == "POST" and form.is_valid(): data = form.cleaned_data try: basket.subscribe(data["email"], "app-dev", source_url=settings.SITE_URL) messages.success(request, _("Thank you for subscribing!")) return redirect("ecosystem.landing") except basket.BasketException: messages.error(request, _("We apologize, but an error " "occurred in our system. Please try again later.")) return jingo.render(request, "ecosystem/landing.html", {"videos": videos, "newsletter_form": form})
def edit(request): webapp = settings.APP_PREVIEW # Don't use request.amo_user since it has too much caching. amouser = UserProfile.objects.get(pk=request.user.id) if request.method == "POST": # ModelForm alters the instance you pass in. We need to keep a copy # around in case we need to use it below (to email the user) original_email = amouser.email form = forms.UserEditForm(request.POST, request.FILES, request=request, instance=amouser, webapp=webapp) if form.is_valid(): messages.success(request, _("Profile Updated")) if amouser.email != original_email: # Temporarily block email changes. if settings.APP_PREVIEW: messages.error(request, "Error", "You cannot change your email on the " "developer preview site.") return jingo.render(request, "users/edit.html", {"form": form, "amouser": amouser}) l = {"user": amouser, "mail1": original_email, "mail2": amouser.email} log.info(u"User (%(user)s) has requested email change from" "(%(mail1)s) to (%(mail2)s)" % l) messages.info( request, _("Email Confirmation Sent"), _( u"An email has been sent to {0} to confirm your new " "email address. For the change to take effect, you " "need to click on the link provided in this email. " "Until then, you can keep logging in with your " "current email address." ).format(amouser.email), ) domain = settings.DOMAIN token, hash = EmailResetCode.create(amouser.id, amouser.email) url = "%s%s" % (settings.SITE_URL, reverse("users.emailchange", args=[amouser.id, token, hash])) t = loader.get_template("users/email/emailchange.ltxt") c = {"domain": domain, "url": url} send_mail( _("Please confirm your email address " "change at %s" % domain), t.render(Context(c)), None, [amouser.email], use_blacklist=False, real_email=True, ) # Reset the original email back. We aren't changing their # address until they confirm the new one amouser.email = original_email form.save() return redirect("users.edit") else: messages.error( request, _("Errors Found"), _("There were errors in the changes " "you made. Please correct them and " "resubmit."), ) else: form = forms.UserEditForm(instance=amouser, webapp=webapp) return jingo.render(request, "users/edit.html", {"form": form, "amouser": amouser, "webapp": webapp})
def preload_submit(request, addon_id, addon, webapp): if request.method == 'POST': form = PreloadTestPlanForm(request.POST, request.FILES) if form.is_valid(): # Save test plan file. test_plan = request.FILES['test_plan'] # Figure the type to save it as (cleaned as pdf/xls from the form). if test_plan.content_type == 'application/pdf': filename = 'test_plan_%s.pdf' else: filename = 'test_plan_%s.xls' # Timestamp. filename = filename % str(time.time()).split('.')[0] save_test_plan(request.FILES['test_plan'], filename, addon) # Log test plan. PreloadTestPlan.objects.filter(addon=addon).update( status=amo.STATUS_DISABLED ) PreloadTestPlan.objects.create(addon=addon, filename=filename) messages.success( request, _('Application for preload successfully submitted.')) return redirect(addon.get_dev_url('versions')) else: messages.error(request, _('There was an error with the form.')) else: form = PreloadTestPlanForm() return jingo.render(request, 'developers/apps/preload/submit.html', { 'addon': addon, 'form': form })
def edit(request): webapp = settings.APP_PREVIEW # Don't use request.amo_user since it has too much caching. amouser = UserProfile.objects.get(pk=request.user.id) if request.method == 'POST': # ModelForm alters the instance you pass in. We need to keep a copy # around in case we need to use it below (to email the user) original_email = amouser.email form = forms.UserEditForm(request.POST, request.FILES, request=request, instance=amouser, webapp=webapp) if form.is_valid(): messages.success(request, _('Profile Updated')) if amouser.email != original_email: # Temporarily block email changes. if settings.APP_PREVIEW: messages.error(request, 'Error', 'You cannot change your email on the ' 'developer preview site.') return jingo.render(request, 'users/edit.html', {'form': form, 'amouser': amouser}) l = {'user': amouser, 'mail1': original_email, 'mail2': amouser.email} log.info(u"User (%(user)s) has requested email change from" "(%(mail1)s) to (%(mail2)s)" % l) messages.info(request, _('Email Confirmation Sent'), _(u'An email has been sent to {0} to confirm your new ' 'email address. For the change to take effect, you ' 'need to click on the link provided in this email. ' 'Until then, you can keep logging in with your ' 'current email address.').format(amouser.email)) domain = settings.DOMAIN token, hash = EmailResetCode.create(amouser.id, amouser.email) url = "%s%s" % (settings.SITE_URL, reverse('users.emailchange', args=[amouser.id, token, hash])) t = loader.get_template('users/email/emailchange.ltxt') c = {'domain': domain, 'url': url} send_mail(_('Please confirm your email address ' 'change at %s' % domain), t.render(Context(c)), None, [amouser.email], use_blacklist=False, real_email=True) # Reset the original email back. We aren't changing their # address until they confirm the new one amouser.email = original_email form.save() return redirect('users.edit') else: messages.error(request, _('Errors Found'), _('There were errors in the changes ' 'you made. Please correct them and ' 'resubmit.')) else: form = forms.UserEditForm(instance=amouser, webapp=webapp) return jingo.render(request, 'users/edit.html', {'form': form, 'amouser': amouser, 'webapp': webapp})
def payments(request, addon_id, addon): charity = None if addon.charity_id == amo.FOUNDATION_ORG else addon.charity charity_form = forms.CharityForm(request.POST or None, instance=charity, prefix='charity') contrib_form = forms.ContribForm(request.POST or None, instance=addon, initial=forms.ContribForm.initial(addon)) profile_form = forms.ProfileForm(request.POST or None, instance=addon, required=True) if request.method == 'POST': if contrib_form.is_valid(): addon = contrib_form.save(commit=False) addon.wants_contributions = True valid = _save_charity(addon, contrib_form, charity_form) if not addon.has_full_profile(): valid &= profile_form.is_valid() if valid: profile_form.save() if valid: addon.save() messages.success(request, _('Changes successfully saved.')) amo.log(amo.LOG.EDIT_CONTRIBUTIONS, addon) return redirect('devhub.addons.payments', addon.slug) errors = charity_form.errors or contrib_form.errors or profile_form.errors if errors: messages.error(request, _('There were errors in your submission.')) return jingo.render(request, 'devhub/addons/payments.html', dict(addon=addon, charity_form=charity_form, errors=errors, contrib_form=contrib_form, profile_form=profile_form))
def paypal_setup(request, addon_id, addon, webapp): if addon.premium_type == amo.ADDON_FREE: messages.error(request, 'Your app does not use payments.') return redirect(addon.get_dev_url('payments')) paypal_form = PaypalSetupForm(request.POST or None) currency_form = CurrencyForm(request.POST or None, initial={'currencies': addon.premium.currencies if addon.premium else {}}) context = {'addon': addon, 'paypal_form': paypal_form, 'currency_form': currency_form} if request.POST.get('form') == 'paypal' and paypal_form.is_valid(): existing = paypal_form.cleaned_data['business_account'] if existing != 'yes': # Go create an account. # TODO: this will either become the API or something some better # URL for the future. return redirect(settings.PAYPAL_CGI_URL) else: # Go setup your details on paypal. addon.update(paypal_id=paypal_form.cleaned_data['email']) if addon.premium and addon.premium.paypal_permissions_token: addon.premium.update(paypal_permissions_token='') return redirect(addon.get_dev_url('paypal_setup_bounce')) if request.POST.get('form') == 'currency' and currency_form.is_valid(): currencies = currency_form.cleaned_data['currencies'] addon.premium.update(currencies=currencies) messages.success(request, _('Currencies updated.')) return redirect(addon.get_dev_url('paypal_setup')) return jingo.render(request, 'developers/payments/paypal-setup.html', context)
def api(request): try: access = Access.objects.get(user=request.user) except Access.DoesNotExist: access = None roles = request.amo_user.groups.all() if roles: messages.error(request, _('Users with roles cannot use the API.')) elif not request.amo_user.read_dev_agreement: messages.error(request, _('You must accept the terms of service.')) elif request.method == 'POST': if 'delete' in request.POST: if access: access.delete() messages.success(request, _('API key deleted.')) else: if not access: key = 'mkt:%s:%s' % (request.amo_user.pk, request.amo_user.email) access = Access.objects.create(key=key, user=request.user, secret=generate()) else: access.update(secret=generate()) messages.success(request, _('New API key generated.')) return redirect(reverse('mkt.developers.apps.api')) return jingo.render(request, 'developers/api.html', {'consumer': access, 'profile': profile, 'roles': roles})
def inner(request, addon_id, addon, *args, **kwargs): inapp = addon.premium_type in amo.ADDON_INAPPS if not inapp: messages.error(request, _("Your app is not configured for in-app payments.")) return redirect(reverse("mkt.developers.apps.payments", args=[addon.app_slug])) else: return render_view(request, addon_id, addon, *args, **kwargs)
def preload_submit(request, addon_id, addon): if request.method == "POST": form = PreloadTestPlanForm(request.POST, request.FILES) if form.is_valid(): # Save test plan file. test_plan = request.FILES["test_plan"] # Figure the type to save it as (cleaned as pdf/xls from the form). filetype = mimetypes.guess_type(test_plan.name)[0] if "pdf" in filetype: filename = "test_plan_%s.pdf" else: filename = "test_plan_%s.xls" # Timestamp. filename = filename % str(time.time()).split(".")[0] save_test_plan(request.FILES["test_plan"], filename, addon) # Log test plan. PreloadTestPlan.objects.filter(addon=addon).update(status=amo.STATUS_DISABLED) PreloadTestPlan.objects.create(addon=addon, filename=filename) messages.success(request, _("Application for preload successfully submitted.")) return redirect(addon.get_dev_url("versions")) else: messages.error(request, _("There was an error with the form.")) else: form = PreloadTestPlanForm() return render(request, "developers/apps/preload/submit.html", {"addon": addon, "form": form})
def payments(request, addon_id, addon): charity = None if addon.charity_id == amo.FOUNDATION_ORG else addon.charity charity_form = forms.CharityForm(request.POST or None, instance=charity, prefix='charity') contrib_form = forms.ContribForm(request.POST or None, instance=addon, initial=forms.ContribForm.initial(addon)) if request.method == 'POST': if contrib_form.is_valid(): addon, valid = contrib_form.save(commit=False), True addon.wants_contributions = True recipient = contrib_form.cleaned_data['recipient'] if recipient == 'dev': addon.charity = None elif recipient == 'moz': addon.charity_id = amo.FOUNDATION_ORG elif recipient == 'org': valid = charity_form.is_valid() if valid: addon.charity = charity_form.save() if valid: addon.save() messages.success(request, _('Changes successfully saved.')) return redirect('devhub.addons.payments', addon_id) if charity_form.errors or contrib_form.errors: messages.error(request, _('There were errors in your submission.')) return jingo.render(request, 'devhub/addons/payments.html', dict(addon=addon, charity_form=charity_form, contrib_form=contrib_form))
def in_app_keys(request): """ Allows developers to get a simulation-only key for in-app payments. This key cannot be used for real payments. """ keys = UserInappKey.objects.no_cache().filter( solitude_seller__user=request.amo_user ) # TODO(Kumar) support multiple test keys. For now there's only one. key = None key_public_id = None if keys.exists(): key = keys.get() # Attempt to retrieve the public id from solitude try: key_public_id = key.public_id() except HttpClientError, e: messages.error(request, _('A server error occurred ' 'when retrieving the application key.')) log.exception('Solitude connection error: {0}'.format(e.message))
def langpacks(request): if request.method == 'POST': try: tasks.fetch_langpacks.delay(request.POST['path']) except ValueError, e: messages.error(request, "Invalid language pack sub-path provided.") return redirect('zadmin.langpacks')
def inner(request, addon_id, addon, *args, **kwargs): inapp = addon.premium_type in amo.ADDON_INAPPS if not inapp: messages.error( request, _('Your app is not configured for in-app payments.')) return redirect( reverse('mkt.developers.apps.payments', args=[addon.app_slug])) else: return render_view(request, addon_id, addon, *args, **kwargs)
def app_review(request, addon): resp = None try: resp = _review(request, addon) except SigningError, exc: transaction.rollback() messages.error(request, "Signing Error: %s" % exc.message) transaction.commit() return redirect(reverse("reviewers.apps.review", args=[addon.app_slug]))
def register(request): if waffle.switch_is_active('fxa-auth'): return login(request) if request.user.is_authenticated(): messages.info(request, _('You are already logged in to an account.')) form = None elif request.method == 'POST': form = forms.UserRegisterForm(request.POST) mkt_user = UserProfile.objects.filter(email=form.data['email'], password='') if form.is_valid(): try: u = form.save(commit=False) u.set_password(form.cleaned_data['password']) u.generate_confirmationcode() u.lang = request.LANG u.save() log.info(u'Registered new account for user (%s)', u) log_cef('New Account', 5, request, username=u.username, signature='AUTHNOTICE', msg='User created a new account') u.email_confirmation_code() msg = _('Congratulations! Your user account was ' 'successfully created.') messages.success(request, msg) msg = _(u'An email has been sent to your address {0} to ' 'confirm your account. Before you can log in, you ' 'have to activate your account by clicking on the ' 'link provided in this email.').format(u.email) messages.info(request, _('Confirmation Email Sent'), msg) except IntegrityError, e: # I was unable to reproduce this, but I suspect it happens # when they POST twice quickly and the slaves don't have the # new info yet (total guess). Anyway, I'm assuming the # first one worked properly, so this is still a success # case to the end user so we just log it... log.error('Failed to register new user (%s): %s' % (u, e)) return http.HttpResponseRedirect(reverse('users.login')) elif mkt_user.exists(): f = PasswordResetForm() f.users_cache = [mkt_user[0]] f.save(use_https=request.is_secure(), email_template_name='users/email/pwreset.ltxt', request=request) return render(request, 'users/newpw_sent.html', {}) else: messages.error(request, _('There are errors in this form'), _('Please correct them and resubmit.'))
def _login(request, template=None, data=None, dont_redirect=False): data = data or {} data['webapp'] = True # In case we need it later. See below. get_copy = request.GET.copy() if 'to' in request.GET: request = _clean_next_url(request) if request.user.is_authenticated(): return http.HttpResponseRedirect( request.GET.get('to', settings.LOGIN_REDIRECT_URL)) user = None login_status = None r = auth_login(request, template_name=template, redirect_field_name='to', extra_context=data) if isinstance(r, http.HttpResponseRedirect): # Django's auth.views.login has security checks to prevent someone from # redirecting to another domain. Since we want to allow this in # certain cases, we have to make a new response object here to replace # the above. if 'domain' in request.GET: request.GET = get_copy request = _clean_next_url(request) r = http.HttpResponseRedirect(request.GET['to']) # Succsesful log in according to django. Now we do our checks. I do # the checks here instead of the form's clean() because I want to use # the messages framework and it's not available in the request there. if user.deleted: logout(request) log.warning(u'Attempt to log in with deleted account (%s)' % user) messages.error(request, _('Wrong email address or password!')) user.log_login_attempt(False) log_cef('Authentication Failure', 5, request, username=request.user, signature='AUTHFAIL', msg='Account is deactivated') return render(request, template, data) login_status = True if dont_redirect: # We're recalling the middleware to re-initialize amo_user ACLMiddleware().process_request(request) r = render(request, template, data) if login_status is not None: user.log_login_attempt(login_status) log_cef('Authentication Failure', 5, request, username=request.POST['username'], signature='AUTHFAIL', msg='The password was incorrect') return r
def acquire_refund_permission(request, addon_id, addon, webapp=False): """This is the callback from Paypal.""" # Set up our redirects. if request.GET.get('dest', '') == 'submission': on_good = reverse('submit.app.payments.confirm', args=[addon.app_slug]) on_error = reverse('submit.app.payments.paypal', args=[addon.app_slug]) show_good_msgs = False else: # The management pages are the default. on_good = addon.get_dev_url('paypal_setup_confirm') on_error = addon.get_dev_url('paypal_setup_bounce') show_good_msgs = True if 'request_token' not in request.GET: paypal_log.debug('User did not approve permissions for' ' addon: %s' % addon_id) messages.error( request, 'You will need to accept the permissions ' 'to continue.') return redirect(on_error) paypal_log.debug('User approved permissions for addon: %s' % addon_id) token = paypal.get_permissions_token(request.GET['request_token'], request.GET['verification_code']) paypal_log.debug('Getting personal data for token: %s' % addon_id) data = paypal.get_personal_data(token) email = data.get('email') # If the email from paypal is different, something has gone wrong. if email != addon.paypal_id: paypal_log.debug('Addon paypal_id and personal data differ: ' '%s vs %s' % (email, addon.paypal_id)) messages.warning( request, _('The email returned by Paypal, ' 'did not match the PayPal email you ' 'entered. Please login using %s.') % email) return redirect(on_error) # Set the permissions token that we have just successfully used # in get_personal_data. addonpremium, created = (AddonPremium.objects.safer_get_or_create( addon=addon)) addonpremium.update(paypal_permissions_token=token) # Finally update the data returned from PayPal for this addon. paypal_log.debug('Updating personal data for: %s' % addon_id) apd, created = AddonPaymentData.objects.safer_get_or_create(addon=addon) apd.update(**data) amo.log(amo.LOG.EDIT_PROPERTIES, addon) if show_good_msgs: messages.success(request, 'Please confirm the data we ' 'received from PayPal.') return redirect(on_good)
def login(request): logout(request) if 'to' in request.GET: request = _clean_next_url(request) r = auth.views.login(request, template_name='users/login.html', redirect_field_name='to', authentication_form=forms.AuthenticationForm) if isinstance(r, http.HttpResponseRedirect): # Succsesful log in according to django. Now we do our checks. I do # the checks here instead of the form's clean() because I want to use # the messages framework and it's not available in the request there user = request.user.get_profile() if user.deleted: logout(request) log.warning(u'Attempt to log in with deleted account (%s)' % user) messages.error(request, _('Wrong email address or password!')) return jingo.render(request, 'users/login.html', {'form': forms.AuthenticationForm()}) if user.confirmationcode: logout(request) log.info(u'Attempt to log in with unconfirmed account (%s)' % user) msg1 = _(('A link to activate your user account was sent by email ' 'to your address {0}. You have to click it before you ' 'can log in.').format(user.email)) url = "%s%s" % (settings.SITE_URL, reverse('users.confirm.resend', args=[user.id])) msg2 = _(('If you did not receive the confirmation email, make ' 'sure your email service did not mark it as "junk ' 'mail" or "spam". If you need to, you can have us ' '<a href="%s">resend the confirmation message</a> ' 'to your email address mentioned above.') % url) messages.error(request, _('Activation Email Sent'), msg1) messages.info(request, _('Having Trouble?'), msg2, title_safe=True) return jingo.render(request, 'users/login.html', {'form': forms.AuthenticationForm()}) rememberme = request.POST.get('rememberme', None) if rememberme: request.session.set_expiry(settings.SESSION_COOKIE_AGE) log.debug((u'User (%s) logged in successfully with ' '"remember me" set') % user) else: user.log_login_attempt(request, True) elif 'username' in request.POST: # Hitting POST directly because cleaned_data doesn't exist user = UserProfile.objects.filter(email=request.POST['username']) if user: user.get().log_login_attempt(request, False) return r
def delete(request, addon_id, addon): form = forms.DeleteForm(request) if form.is_valid(): addon.delete('Removed via devhub') messages.success(request, _('Add-on deleted.')) return redirect('devhub.addons') else: messages.error(request, _('Password was incorrect. Add-on was not deleted.')) return redirect('devhub.versions', addon.slug)
def notify(request, job): job = get_object_or_404(ValidationJob, pk=job) notify_form = NotifyForm(request.POST, text='validation') if not notify_form.is_valid(): messages.error(request, notify_form) else: tasks.notify_compatibility.delay(job, notify_form.cleaned_data) return redirect(reverse('zadmin.validation'))
def app_review(request, addon): resp = None try: resp = _review(request, addon) except SigningError, exc: transaction.rollback() messages.error(request, 'Signing Error: %s' % exc) transaction.commit() return redirect(reverse('reviewers.apps.review', args=[addon.app_slug]))
def register(request): if request.user.is_authenticated(): messages.info(request, _('You are already logged in to an account.')) form = None elif request.method == 'POST': form = forms.UserRegisterForm(request.POST) mkt_user = UserProfile.objects.filter(email=form.data['email'], password='') if form.is_valid(): try: u = form.save(commit=False) u.set_password(form.cleaned_data['password']) u.generate_confirmationcode() u.lang = request.LANG u.save() log.info(u'Registered new account for user (%s)', u) log_cef('New Account', 5, request, username=u.username, signature='AUTHNOTICE', msg='User created a new account') u.email_confirmation_code() msg = _('Congratulations! Your user account was ' 'successfully created.') messages.success(request, msg) msg = _(u'An email has been sent to your address {0} to ' 'confirm your account. Before you can log in, you ' 'have to activate your account by clicking on the ' 'link provided in this email.').format(u.email) messages.info(request, _('Confirmation Email Sent'), msg) except IntegrityError, e: # I was unable to reproduce this, but I suspect it happens # when they POST twice quickly and the slaves don't have the # new info yet (total guess). Anyway, I'm assuming the # first one worked properly, so this is still a success # case to the end user so we just log it... log.error('Failed to register new user (%s): %s' % (u, e)) return http.HttpResponseRedirect(reverse('users.login')) elif mkt_user.exists(): f = PasswordResetForm() f.users_cache = [mkt_user[0]] f.save(use_https=request.is_secure(), email_template_name='users/email/pwreset.ltxt', request=request) return render(request, 'users/newpw_sent.html', {}) else: messages.error(request, _('There are errors in this form'), _('Please correct them and resubmit.'))
def edit(request): # Don't use request.user since it has too much caching. amouser = UserProfile.objects.get(pk=request.user.id) if request.method == 'POST': # ModelForm alters the instance you pass in. We need to keep a copy # around in case we need to use it below (to email the user) original_email = amouser.email form = forms.UserEditForm(request.POST, request.FILES, request=request, instance=amouser) if form.is_valid(): messages.success(request, _('Profile Updated')) if amouser.email != original_email: l = {'user': amouser, 'mail1': original_email, 'mail2': amouser.email} log.info(u"User (%(user)s) has requested email change from " u"(%(mail1)s) to (%(mail2)s)" % l) messages.info( request, _('Email Confirmation Sent'), _(u'An email has been sent to {0} to confirm your new ' u'email address. For the change to take effect, you ' u'need to click on the link provided in this email. ' u'Until then, you can keep logging in with your ' u'current email address.').format(amouser.email)) token, hash_ = EmailResetCode.create(amouser.id, amouser.email) url = '%s%s' % (settings.SITE_URL, reverse('users.emailchange', args=[amouser.id, token, hash_])) t = loader.get_template('users/email/emailchange.ltxt') c = {'domain': settings.DOMAIN, 'url': url} send_mail( _('Please confirm your email address ' 'change at %s' % settings.DOMAIN), t.render(Context(c)), None, [amouser.email], use_blacklist=False, real_email=True) # Reset the original email back. We aren't changing their # address until they confirm the new one amouser.email = original_email form.save() return redirect('users.edit') else: messages.error( request, _('Errors Found'), _('There were errors in the changes you made. Please correct ' 'them and resubmit.')) else: form = forms.UserEditForm(instance=amouser, request=request) return render(request, 'users/edit.html', {'form': form, 'amouser': amouser})
def jetpack(request): upgrader = files.utils.JetpackUpgrader() minver, maxver = upgrader.jetpack_versions() form = JetpackUpgradeForm(request.POST) if request.method == "POST": if form.is_valid(): if "minver" in request.POST: data = form.cleaned_data upgrader.jetpack_versions(data["minver"], data["maxver"]) elif "upgrade" in request.POST: if upgrader.version(maxver): start_upgrade(minver, maxver) elif "cancel" in request.POST: upgrader.cancel() return redirect("zadmin.jetpack") else: messages.error(request, form.errors.as_text()) jetpacks = files.utils.find_jetpacks(minver, maxver, from_builder_only=True) upgrading = upgrader.version() # Current Jetpack version upgrading to. repack_status = upgrader.files() # The files being repacked. show = request.GET.get("show", upgrading or minver) subset = filter(lambda f: not f.needs_upgrade and f.jetpack_version == show, jetpacks) need_upgrade = filter(lambda f: f.needs_upgrade, jetpacks) repacked = [] if upgrading: # Group the repacked files by status for this Jetpack upgrade. grouped_files = sorted_groupby(repack_status.values(), key=lambda f: f["status"]) for group, rows in grouped_files: rows = sorted(list(rows), key=lambda f: f["file"]) for idx, row in enumerate(rows): rows[idx]["file"] = File.objects.get(id=row["file"]) repacked.append((group, rows)) groups = sorted_groupby(jetpacks, "jetpack_version") by_version = dict((version, len(list(files))) for version, files in groups) return jingo.render( request, "zadmin/jetpack.html", dict( form=form, upgrader=upgrader, by_version=by_version, upgrading=upgrading, need_upgrade=need_upgrade, subset=subset, show=show, repacked=repacked, repack_status=repack_status, ), )
def jetpack(request): upgrader = files.utils.JetpackUpgrader() minver, maxver = upgrader.jetpack_versions() form = JetpackUpgradeForm(request.POST) if request.method == 'POST': if form.is_valid(): if 'minver' in request.POST: data = form.cleaned_data upgrader.jetpack_versions(data['minver'], data['maxver']) elif 'upgrade' in request.POST: if upgrader.version(maxver): start_upgrade(minver, maxver) elif 'cancel' in request.POST: upgrader.cancel() return redirect('zadmin.jetpack') else: messages.error(request, form.errors.as_text()) jetpacks = files.utils.find_jetpacks(minver, maxver, from_builder_only=True) upgrading = upgrader.version() # Current Jetpack version upgrading to. repack_status = upgrader.files() # The files being repacked. show = request.GET.get('show', upgrading or minver) subset = filter( lambda f: not f.needs_upgrade and f.jetpack_version == show, jetpacks) need_upgrade = filter(lambda f: f.needs_upgrade, jetpacks) repacked = [] if upgrading: # Group the repacked files by status for this Jetpack upgrade. grouped_files = sorted_groupby(repack_status.values(), key=lambda f: f['status']) for group, rows in grouped_files: rows = sorted(list(rows), key=lambda f: f['file']) for idx, row in enumerate(rows): rows[idx]['file'] = File.objects.get(id=row['file']) repacked.append((group, rows)) groups = sorted_groupby(jetpacks, 'jetpack_version') by_version = dict((version, len(list(files))) for version, files in groups) return jingo.render( request, 'zadmin/jetpack.html', dict(form=form, upgrader=upgrader, by_version=by_version, upgrading=upgrading, need_upgrade=need_upgrade, subset=subset, show=show, repacked=repacked, repack_status=repack_status))
def app_review(request, addon): version = addon.latest_version resp = None try: resp = _review(request, addon, version) except SigningError, exc: transaction.rollback() messages.error(request, 'Signing Error: %s' % exc) transaction.commit() return redirect( reverse('reviewers.apps.review', args=[addon.app_slug]))
def acquire_refund_permission(request, addon_id, addon, webapp=False): """This is the callback from Paypal.""" # Set up our redirects. if request.GET.get('dest', '') == 'submission': on_good = reverse('submit.app.payments.confirm', args=[addon.app_slug]) on_error = reverse('submit.app.payments.paypal', args=[addon.app_slug]) show_good_msgs = False else: # The management pages are the default. on_good = addon.get_dev_url('paypal_setup_confirm') on_error = addon.get_dev_url('paypal_setup_bounce') show_good_msgs = True if 'request_token' not in request.GET: paypal_log.debug('User did not approve permissions for' ' addon: %s' % addon_id) messages.error(request, 'You will need to accept the permissions ' 'to continue.') return redirect(on_error) paypal_log.debug('User approved permissions for addon: %s' % addon_id) token = paypal.get_permissions_token(request.GET['request_token'], request.GET['verification_code']) paypal_log.debug('Getting personal data for token: %s' % addon_id) data = paypal.get_personal_data(token) email = data.get('email') # If the email from paypal is different, something has gone wrong. if email != addon.paypal_id: paypal_log.debug('Addon paypal_id and personal data differ: ' '%s vs %s' % (email, addon.paypal_id)) messages.warning(request, _('The email returned by Paypal, ' 'did not match the PayPal email you ' 'entered. Please login using %s.') % email) return redirect(on_error) # Set the permissions token that we have just successfully used # in get_personal_data. addonpremium, created = (AddonPremium.objects .safer_get_or_create(addon=addon)) addonpremium.update(paypal_permissions_token=token) # Finally update the data returned from PayPal for this addon. paypal_log.debug('Updating personal data for: %s' % addon_id) apd, created = AddonPaymentData.objects.safer_get_or_create(addon=addon) apd.update(**data) amo.log(amo.LOG.EDIT_PROPERTIES, addon) if show_good_msgs: messages.success(request, 'Please confirm the data we ' 'received from PayPal.') return redirect(on_good)
def inner(request, addon_id, addon, *args, **kwargs): setup_url = reverse('mkt.developers.apps.payments', args=[addon.app_slug]) if addon.premium_type not in amo.ADDON_INAPPS: messages.error( request, _('Your app is not configured for in-app payments.')) return redirect(setup_url) if not addon.has_payment_account(): messages.error(request, _('No payment account for this app.')) return redirect(setup_url) # App is set up for payments; render the view. return render_view(request, addon_id, addon, *args, **kwargs)
def paypal_setup_bounce(request, addon_id, addon, webapp): if not addon.paypal_id: messages.error(request, 'We need a PayPal email before continuing.') return redirect(addon.get_dev_url('paypal_setup')) paypal_url = paypal.get_permission_url(addon, 'management', [ 'REFUND', 'ACCESS_BASIC_PERSONAL_DATA', 'ACCESS_ADVANCED_PERSONAL_DATA' ]) return jingo.render(request, 'developers/payments/paypal-details-request.html', { 'paypal_url': paypal_url, 'addon': addon })
def notify(request, job): job = get_object_or_404(ValidationJob, pk=job) notify_form = NotifyForm(request.POST, text='validation') if not notify_form.is_valid(): messages.error(request, notify_form) else: for chunk in chunked(updated_versions(job), 100): tasks.update_maxversions.delay(chunk, job.pk, notify_form.cleaned_data) updated_authors = completed_version_authors(job) for chunk in chunked(updated_authors, 100): # There are times when you want to punch django's ORM in # the face. This may be one of those times. # TODO: Offload most of this work to the task? users_addons = list( UserProfile.objects.filter( pk__in=chunk).filter(**_completed_versions( job, 'addons__versions')).values_list( 'pk', 'addons__pk').distinct()) users = list( UserProfile.objects.filter(pk__in=set( u for u, a in users_addons))) # Annotate fails in tests when using cached results addons = (Addon.objects.no_cache().filter( **{ 'pk__in': set(a for u, a in users_addons), 'versions__files__' 'validation_results__validation_job': job }).annotate( errors=Sum('versions__files__validation_results__errors'))) addons = dict((a.id, a) for a in addons) users_addons = dict( (u, [addons[a] for u, a in row]) for u, row in sorted_groupby(users_addons, lambda k: k[0])) for u in users: addons = users_addons[u.pk] u.passing_addons = [a for a in addons if a.errors == 0] u.failing_addons = [a for a in addons if a.errors > 0] tasks.notify_compatibility.delay(users, job, notify_form.cleaned_data) return redirect(reverse('zadmin.validation'))
def notify_failure(request, job): job = get_object_or_404(ValidationJob, pk=job) notify_form = NotifyForm(request.POST, text='failure') if not notify_form.is_valid(): messages.error(request, notify_form) else: file_pks = job.result_failing().values_list('file_id', flat=True) for chunk in chunked(file_pks, 100): tasks.notify_failed.delay(chunk, job.pk, notify_form.cleaned_data) messages.success(request, _('Notifying authors task started.')) return redirect(reverse('zadmin.validation'))
def confirm(request, user, token): if not user.confirmationcode: return redirect('users.login') if user.confirmationcode != token: log.info(u"Account confirmation failed for user (%s)", user) messages.error(request, _('Invalid confirmation code!')) return redirect('users.login') user.confirmationcode = '' user.save() messages.success(request, _('Successfully verified!')) log.info(u"Account confirmed for user (%s)", user) return redirect('users.login')
def refund_reason(request, contribution, wizard): addon = contribution.addon if not 'request' in wizard.get_progress(): return redirect('users.support', contribution.pk, 'request') if contribution.transaction_id is None: messages.error( request, _('A refund cannot be applied for yet. Please try again' ' later. If this error persists contact ' '[email protected].')) paypal_log.info('Refund requested for contribution with no ' 'transaction_id: %r' % (contribution.pk, )) return redirect('users.purchases') if contribution.is_instant_refund(): paypal.refund(contribution.paykey) # TODO: Consider requiring a refund reason for instant refunds. refund = contribution.enqueue_refund(amo.REFUND_APPROVED_INSTANT) paypal_log.info('Refund %r issued for contribution %r' % (refund.pk, contribution.pk)) # Note: we have to wait for PayPal to issue an IPN before it's # completely refunded. messages.success(request, _('Refund is being processed.')) return redirect('users.purchases') form = forms.ContactForm(request.POST or None) if request.method == 'POST' and form.is_valid(): reason = form.cleaned_data['text'] template = jingo.render_to_string( request, wizard.tpl('emails/refund-request.txt'), context={ 'addon': addon, 'form': form, 'user': request.amo_user, 'contribution': contribution, 'refund_url': contribution.get_absolute_refund_url(), 'refund_reason': reason }) log.info('Refund request sent by user: %s for addon: %s' % (request.amo_user.pk, addon.pk)) # L10n: %s is the addon name. send_mail(_(u'New Refund Request for %s' % addon.name), template, settings.NOBODY_EMAIL, [smart_str(addon.support_email)]) # Add this refund request to the queue. contribution.enqueue_refund(amo.REFUND_PENDING, reason) return redirect( reverse('users.support', args=[contribution.pk, 'refund-sent'])) return wizard.render(request, wizard.tpl('refund.html'), {'form': form})
def notify_success(request, job): job = get_object_or_404(ValidationJob, pk=job) notify_form = NotifyForm(request.POST, text='success') if not notify_form.is_valid(): messages.error(request, notify_form.errors) else: versions = completed_versions_dirty(job) for chunk in chunked(versions, 100): tasks.notify_success.delay(chunk, job.pk, notify_form.cleaned_data) messages.success(request, _('Updating max version task and ' 'notifying authors started.')) return redirect(reverse('zadmin.validation'))
def confirm(request, user_id, token): user = get_object_or_404(UserProfile, id=user_id) if not user.confirmationcode: return http.HttpResponseRedirect(reverse('users.login')) if user.confirmationcode != token: log.info(u"Account confirmation failed for user (%s)", user) messages.error(request, _('Invalid confirmation code!')) return http.HttpResponseRedirect(reverse('users.login')) user.confirmationcode = '' user.save() messages.success(request, _('Successfully verified!')) log.info(u"Account confirmed for user (%s)", user) return http.HttpResponseRedirect(reverse('users.login'))
def landing(request): """Developer Hub landing page.""" videos = [ { 'name': 'airbnb', 'path': 'FirefoxMarketplace-airbnb-BR-RC-SD1%20640' }, { 'name': 'evernote', 'path': 'FirefoxMarketplace-Evernote_BR-RC-SD1%20640' }, { 'name': 'uken', 'path': 'FirefoxMarketplace-uken-BR-RC-SD1%20640' }, { 'name': 'soundcloud', 'path': 'FirefoxMarketplace-Soundcloud-BR-RC-SD1%20640' }, { 'name': 'box', 'path': 'FirefoxMarketplace_box-BR-RC-SD1%20640' } ] form = DevNewsletterForm(request.LANG, request.POST or None) if request.method == 'POST' and form.is_valid(): data = form.cleaned_data try: basket.subscribe(data['email'], 'app-dev', format=data['email_format'], source_url=settings.SITE_URL) messages.success(request, _('Thank you for subscribing!')) return redirect('ecosystem.landing') except basket.BasketException as e: log.error( 'Basket exception in ecosystem newsletter: %s' % e) messages.error( request, _('We apologize, but an error occurred in our ' 'system. Please try again later.')) return jingo.render(request, 'ecosystem/landing.html', {'videos': videos, 'newsletter_form': form})
def register(request): if request.user.is_authenticated(): messages.info(request, _("You are already logged in to an account.")) form = None elif request.method == 'POST': form = forms.UserRegisterForm(request.POST) if form.is_valid(): try: u = form.save(commit=False) u.set_password(form.cleaned_data['password']) u.generate_confirmationcode() u.save() u.create_django_user() log.info(u"Registered new account for user (%s)", u) u.email_confirmation_code() msg = _('Congratulations! Your user account was successfully ' 'created.') messages.success(request, msg) msg = _(('An email has been sent to your address {0} to ' 'confirm your account. Before you can log in, you ' 'have to activate your account by clicking on the ' 'link provided in this email.').format(u.email)) messages.info(request, _('Confirmation Email Sent'), msg) except IntegrityError, e: # I was unable to reproduce this, but I suspect it happens # when they POST twice quickly and the slaves don't have the # new info yet (total guess). Anyway, I'm assuming the # first one worked properly, so this is still a success # case to tne end user so we just log it... log.error("Failed to register new user (%s): %s" % (u, e)) amo.utils.clear_messages(request) return http.HttpResponseRedirect(reverse('users.login') + '?m=3') # TODO POSTREMORA Replace the above two lines # when remora goes away with this: #return http.HttpResponseRedirect(reverse('users.login')) else: messages.error(request, _('There are errors in this form'), _('Please correct them and resubmit.'))
def confirm(request, user_id, token): user = get_object_or_404(UserProfile, id=user_id) if not user.confirmationcode: return redirect('users.login') if user.confirmationcode != token: log.info(u"Account confirmation failed for user (%s)", user) if waffle.switch_is_active('zamboni-login'): messages.error(request, _('Invalid confirmation code!')) return redirect('users.login') user.confirmationcode = '' user.save() if waffle.switch_is_active('zamboni-login'): messages.success(request, _('Successfully verified!')) log.info(u"Account confirmed for user (%s)", user) return redirect('users.login')
def t_shirt(request): if not waffle.switch_is_active('t-shirt-orders'): raise http.Http404() user = request.user eligible = tshirt_eligible(user) if request.method == 'POST': if not eligible: messages.error(request, _("We're sorry, but you are not eligible to " "request a t-shirt at this time.")) return redirect('users.t-shirt') if not user.t_shirt_requested: user.update(t_shirt_requested=datetime.now()) return render(request, 'users/t-shirt.html', {'eligible': eligible, 'user': user})
def langpacks(request): if request.method == 'POST': try: tasks.fetch_langpacks.delay(request.POST['path']) except ValueError: messages.error(request, 'Invalid language pack sub-path provided.') return redirect('zadmin.langpacks') addons = (Addon.objects.no_cache() .filter(addonuser__user__email=settings.LANGPACK_OWNER_EMAIL, type=amo.ADDON_LPAPP) .order_by('name')) data = {'addons': addons, 'base_url': settings.LANGPACK_DOWNLOAD_BASE, 'default_path': settings.LANGPACK_PATH_DEFAULT % ( 'firefox', amo.FIREFOX.latest_version)} return jingo.render(request, 'zadmin/langpack_update.html', data)
def paypal_setup(request, addon_id, addon, webapp): if addon.premium_type == amo.ADDON_FREE: messages.error(request, 'Your app does not use payments.') return redirect(addon.get_dev_url('payments')) paypal_form = PaypalSetupForm(request.POST or None) currency_form = CurrencyForm( request.POST or None, initial={ 'currencies': addon.premium.currencies if addon.premium else {} }) context = { 'addon': addon, 'paypal_form': paypal_form, 'currency_form': currency_form } if request.POST.get('form') == 'paypal' and paypal_form.is_valid(): existing = paypal_form.cleaned_data['business_account'] if existing != 'yes': # Go create an account. # TODO: this will either become the API or something some better # URL for the future. return redirect(settings.PAYPAL_CGI_URL) else: # Go setup your details on paypal. addon.update(paypal_id=paypal_form.cleaned_data['email']) if addon.premium and addon.premium.paypal_permissions_token: addon.premium.update(paypal_permissions_token='') return redirect(addon.get_dev_url('paypal_setup_bounce')) if (waffle.switch_is_active('currencies') and request.POST.get('form') == 'currency' and currency_form.is_valid()): currencies = currency_form.cleaned_data['currencies'] addon.premium.update(currencies=currencies) messages.success(request, _('Currencies updated.')) return redirect(addon.get_dev_url('paypal_setup')) return jingo.render(request, 'developers/payments/paypal-setup.html', context)
def register(request): if request.user.is_authenticated(): messages.info(request, _("You are already logged in to an account.")) form = None elif request.method == 'POST': form = forms.UserRegisterForm(request.POST) if form.is_valid(): u = form.save(commit=False) u.set_password(form.cleaned_data['password']) u.generate_confirmationcode() u.save() u.create_django_user() log.info(u"Registered new account for user (%s)", u) u.email_confirmation_code() messages.success( request, _('Congratulations! Your user account ' 'was successfully created.')) msg = _(('An email has been sent to your address {0} to confirm ' 'your account. Before you can log in, you have to ' 'activate your account by clicking on the link provided ' ' in this email.').format(u.email)) messages.info(request, _('Confirmation Email Sent'), msg) amo.utils.clear_messages(request) return http.HttpResponseRedirect(reverse('users.login') + '?m=3') # TODO POSTREMORA Replace the above with this line # when remora goes away #return http.HttpResponseRedirect(reverse('users.login')) else: messages.error(request, _('There are errors in this form'), _('Please correct them and resubmit.')) else: form = forms.UserRegisterForm() return jingo.render(request, 'users/register.html', { 'form': form, })
def in_app_keys(request): keys = UserInappKey.objects.no_cache().filter( solitude_seller__user=request.amo_user ) # TODO(Kumar) support multiple test keys. For now there's only one. key = None key_public_id = None if keys.exists(): key = keys.get() # Attempt to retrieve the public id from solitude try: key_public_id = key.public_id() except HttpClientError, e: messages.error(request, _('A server error occurred ' 'when retrieving the application key.')) log.exception('Solitude connection error: {0}'.format(e.message))
def delete(request, addon_id, addon, webapp=False): # Database deletes only allowed for free or incomplete addons. if not addon.can_be_deleted(): msg = _('Paid apps cannot be deleted. Disable this app instead.') messages.error(request, msg) return redirect(addon.get_dev_url('versions')) # TODO: This short circuits the delete form which checks the password. When # BrowserID adds re-auth support, update the form to check with BrowserID # and remove the short circuit. form = forms.DeleteForm(request) if True or form.is_valid(): addon.delete('Removed via devhub') messages.success(request, _('App deleted.')) # Preserve query-string parameters if we were directed from Dashboard. return redirect( request.GET.get('to') or reverse('mkt.developers.apps')) else: msg = _('Password was incorrect. App was not deleted.') messages.error(request, msg) return redirect(addon.get_dev_url('versions'))
def marketplace_confirm(request, addon_id, addon, webapp=False): if request.method == 'POST': if (addon.premium and addon.premium.is_complete() and addon.premium.has_permissions_token()): if addon.status == amo.STATUS_UNREVIEWED: addon.status = amo.STATUS_NOMINATED addon.premium_type = amo.ADDON_PREMIUM addon.save() amo.log(amo.LOG.MAKE_PREMIUM, addon) return redirect(addon.get_dev_url('payments')) messages.error(request, 'Some required details are missing.') return redirect(addon.get_dev_url('market.1')) return jingo.render( request, 'developers/payments/second-confirm.html', { 'addon': addon, 'webapp': webapp, 'upsell': addon.upsold, 'premium': addon.premium })
def delete(request, addon_id, addon, webapp=False): # Database deletes only allowed for free or incomplete addons. if not addon.can_be_deleted(): msg = _('Paid apps cannot be deleted. Disable this app instead.') messages.error(request, msg) return redirect(addon.get_dev_url('versions')) # TODO: Force the user to re-auth with BrowserID (this DeleteForm doesn't # ask the user for his password) form = forms.DeleteForm(request) if form.is_valid(): reason = form.cleaned_data.get('reason', '') addon.delete(msg='Removed via devhub', reason=reason) messages.success(request, _('App deleted.')) # Preserve query-string parameters if we were directed from Dashboard. return redirect( request.GET.get('to') or reverse('mkt.developers.apps')) else: msg = _('Password was incorrect. App was not deleted.') messages.error(request, msg) return redirect(addon.get_dev_url('versions'))
def api(request): try: access = Access.objects.get(user=request.user) except Access.DoesNotExist: access = None roles = request.amo_user.groups.filter(name='Admins').exists() if roles: messages.error(request, _('Users with the admin role cannot use the API.')) elif not request.amo_user.read_dev_agreement: messages.error(request, _('You must accept the terms of service.')) elif request.method == 'POST': if 'delete' in request.POST: if access: access.delete() messages.success(request, _('API key deleted.')) else: if not access: key = 'mkt:%s:%s' % (request.amo_user.pk, request.amo_user.email) access = Access.objects.create(key=key, user=request.user, secret=generate()) else: access.update(secret=generate()) messages.success(request, _('New API key generated.')) return redirect(reverse('mkt.developers.apps.api')) return jingo.render(request, 'developers/api.html', { 'consumer': access, 'profile': profile, 'roles': roles })