Beispiel #1
0
 def get_organization(self):
     if self.organization_url_kwarg in self.kwargs:
         queryset = Organization.objects.filter(
             slug=self.kwargs.get(self.organization_url_kwarg))
         if queryset.exists():
             return queryset.get()
     return get_broker()
Beispiel #2
0
 def get(self, request, *args, **kwargs):
     provider = get_broker()
     if fail_direct(request, organization=provider):
         return super(ProviderRedirectView, self).get(
             request, *args, **kwargs)
     kwargs.update({self.slug_url_kwarg: provider})
     return RedirectView.get(self, request, *args, **kwargs)
Beispiel #3
0
def _read_agreement_file(slug, context=None):
    import markdown

    if not context:
        context = {"organization": get_broker()}
    source, _ = loader.find_template("saas/agreements/legal_%s.md" % slug)
    return markdown.markdown(source.render(Context(context)))
Beispiel #4
0
def parse_line(line, account_first=False, create_organizations=False):
    """
    Parse an (organization, account, amount) triplet.
    """
    if account_first:
        look = re.match(r'\s+(?P<account>(\w+:)+)(?P<organization>\w+)'\
r'(\s+(?P<amount>.+))?', line)
    else:
        look = re.match(r'\s+(?P<organization>\w+)(?P<account>(:(\w+))+)'\
r'(\s+(?P<amount>.+))?', line)
    if look:
        organization_slug = look.group('organization')
        account = look.group('account')
        if account.startswith(':'):
            account = account[1:]
        if account.endswith(':'):
            account = account[:-1]
        amount = look.group('amount')
        if amount and amount.startswith('$'):
            locale.setlocale(locale.LC_ALL, 'en_US')
            amount = long(locale.atof(amount[1:]) * 100)
        try:
            if create_organizations:
                organization, _ = Organization.objects.get_or_create(
                    slug=organization_slug)
            else:
                organization = Organization.objects.get(slug=organization_slug)
            if account_first:
                organization = get_broker()
            return (organization, account, amount)
        except Organization.DoesNotExist:
            print "Cannot find Organization '%s'" % organization_slug
    return (None, None, None)
Beispiel #5
0
def _read_agreement_file(slug, context=None):
    import markdown
    if not context:
        context = {'organization': get_broker()}
    # We use context and not context=context in the following statement
    # such that the code is compatible with Django 1.7 and Django 1.8
    return markdown.markdown(
        render_to_string('saas/agreements/legal_%s.md' % slug, context))
Beispiel #6
0
def is_current_provider(organization):
    # We do a string compare here because both ``Organization`` might come
    # from a different db. That is if the organization parameter is not
    # a unicode string itself.
    slug = ''
    if isinstance(organization, basestring):
        slug = organization
    elif organization:
        slug = organization.slug
    return slug == get_broker().slug
Beispiel #7
0
def user_reset_password_notice(sender, user, request, back_url,
                               expiration_days, **kwargs):
    """
    A user has reset her password.
    """
    LOGGER.debug("[signal] user_reset_password_notice(user=%s, back_url=%s,"\
        " expiration_days=%s)", user, back_url, expiration_days)
    if SEND_EMAIL:
        app = get_current_app()
        site = get_current_site()
        _send_notification_email(site, [user.email],
                                 'notification/password_reset.eml',
                                 context={
                                     'request': request,
                                     'broker': get_broker(),
                                     'app': app,
                                     'back_url': back_url,
                                     'expiration_days': expiration_days,
                                     'user': get_user_context(user)
                                 })
Beispiel #8
0
def card_updated_notice(sender, organization, user, old_card, new_card,
                        **kwargs):
    recipients, bcc = _notified_recipients(organization)
    app = get_current_app()
    LOGGER.debug("[signal] card_updated_notice(organization=%s, user=%s,"\
        "old_card=%s, new_card=%s)", organization, user, old_card, new_card)
    if SEND_EMAIL:
        get_email_backend(connection=app.get_connection()).send(
            from_email=app.get_from_email(),
            recipients=recipients,
            bcc=bcc,
            template='notification/card_updated.eml',
            context={
                'broker': get_broker(),
                'app': app,
                'organization': organization,
                'user': get_user_context(user),
                'old_card': old_card,
                'new_card': new_card
            })
Beispiel #9
0
def card_updated_notice(sender, organization, user,
                        old_card, new_card, **kwargs):
    recipients, bcc = _notified_recipients(organization, 'card_updated')
    LOGGER.debug("[signal] card_updated_notice(organization=%s, user=%s,"\
        "old_card=%s, new_card=%s)", organization, user, old_card, new_card)
    if SEND_EMAIL and recipients:
        broker = get_broker()
        broker_recipients, broker_bcc = _notified_recipients(broker,
            'card_updated')
        app = get_current_app()
        site = get_current_site()
        if broker.email and broker.email != site.get_from_email():
            reply_to = broker.email
        _send_notification_email(site, recipients,
            'notification/card_updated.eml',
            reply_to=reply_to, bcc=bcc + broker_recipients + broker_bcc,
            context={
                'broker': broker, 'app': app,
                'organization': organization, 'user': get_user_context(user),
                'old_card': old_card, 'new_card': new_card})
Beispiel #10
0
def pass_direct(request, charge=None, organization=None, strength=NORMAL):
    """
    Returns True if the request authenticated ``User`` is a direct contributor
    (or manager) for the ``Organization`` associated to the request.

    Managers can issue all types of requests (GET, POST, etc.) while
    contributors are restricted to GET requests.

    .. image:: perms-contrib.*
    """
    if charge:
        if not isinstance(charge, Charge):
            charge = get_object_or_404(Charge, processor_key=charge)
        organization = charge.customer
    elif organization:
        if not isinstance(organization, Organization):
            organization = get_object_or_404(Organization, slug=organization)
    else:
        organization = get_broker()
    return organization and _has_valid_access(request, [organization], strength)
Beispiel #11
0
def weekly_sales_report_notice(sender, provider, dates, data, **kwargs):
    recipients, bcc = _notified_recipients(
        provider, "weekly_sales_report_created")
    if SEND_EMAIL and recipients:
        prev_week, notused = dates #pylint:disable=unused-variable
        last_sunday = prev_week[-1]
        date = last_sunday.strftime("%A %b %d, %Y")

        app = get_current_app()
        site = get_current_site()
        # XXX using the provider in templates is incorrect. "Any questions
        # or comments..." should show DjaoDjin support email address.
        _send_notification_email(site, recipients,
            'notification/weekly_sales_report_created.eml',
            bcc=bcc,
            context={'broker': get_broker(), 'provider': provider,
                # Without ``app`` we don't set the color correctly in
                # in notification/base.html, thus ending with an error
                # in premailer.
                'app': app, 'table': data, 'date': date})
Beispiel #12
0
def pass_provider_only(request,
                       charge=None, organization=None, strength=NORMAL):
    """
    Returns True if the request authenticated ``User``
    is a contributor (or manager) for a provider to the ``Organization``
    associated to the request.

    When *strength* is NORMAL, managers can issue all types of requests
    (GET, POST, etc.) while contributors are restricted to GET requests.

    .. image:: perms-contrib-provider-only.*
    """
    if charge:
        charge = get_object_or_404(Charge, processor_key=charge)
        organization = charge.customer
    elif organization:
        organization = get_object_or_404(Organization, slug=organization)
    if organization:
        return _has_valid_access(request,
            list(Organization.objects.providers_to(organization)), strength)
    return  _has_valid_access(request, [get_broker()])
Beispiel #13
0
def user_reset_password_notice(sender, user, request, back_url,
                               expiration_days, **kwargs):
    """
    A user has reset her password.
    """
    app = get_current_app()
    LOGGER.debug("[signal] user_reset_password_notice(user=%s, back_url=%s,"\
        " expiration_days=%s)", user, back_url, expiration_days)
    if SEND_EMAIL:
        get_email_backend(connection=app.get_connection()).send(
            from_email=app.get_from_email(),
            recipients=[user.email],
            template='notification/password_reset.eml',
            context={
                'request': request,
                'broker': get_broker(),
                'app': app,
                'back_url': back_url,
                'expiration_days': expiration_days,
                'user': get_user_context(user)
            })
Beispiel #14
0
def role_grant_accepted_notice(sender, role, grant_key, request=None, **kwargs):
    LOGGER.debug("[signal] role_grant_accepted_notice("\
        " role=%s, grant_key=%s)", role, grant_key)
    originated_by = request.user if request else None
    user_context = get_user_context(originated_by)
    recipients, bcc = _notified_recipients(
        role.organization, "role_grant_accepted_notice",
        originated_by=originated_by)
    if SEND_EMAIL and recipients:
        site = get_current_site()
        app = get_current_app()
        _send_notification_email(site, recipients,
            'notification/role_grant_accepted.eml',
            reply_to=user_context['email'], bcc=bcc,
            context={
                'broker': get_broker(), 'app': app,
                'back_url': site.as_absolute_uri(reverse('saas_role_detail',
                    args=(role.organization, role.role_description))),
                'organization': role.organization,
                'role': role.role_description.title,
                'user': user_context})
Beispiel #15
0
def subscribe_req_accepted_notice(sender, subscription, request_key,
                                       request=None, **kwargs):
    subscriber = subscription.organization
    recipients, bcc = _notified_recipients(subscriber,
        "subscribe_req_accepted_notice")
    LOGGER.debug("[signal] subscribe_req_accepted_notice("\
        " subscription=%s, request_key=%s)", subscription, request_key)
    if SEND_EMAIL and recipients:
        site = get_current_site()
        app = get_current_app()
        user_context = get_user_context(request.user if request else None)
        _send_notification_email(site, recipients,
            'notification/subscription_request_accepted.eml',
            reply_to=user_context['email'], bcc=bcc,
            context={
                'broker': get_broker(), 'app': app,
                'back_url': site.as_absolute_uri(reverse('organization_app',
                    args=(subscriber,))),
                'organization': subscriber,
                'plan': subscription.plan,
                'user': user_context})
Beispiel #16
0
def order_executed_notice(sender, invoiced_items, user, **kwargs):
    invoiced_items = list(invoiced_items)
    organization = (invoiced_items[0].dest_organization
                    if invoiced_items else None)
    recipients, bcc = _notified_recipients(organization, 'order_executed')
    LOGGER.debug("[signal] order_executed_notice(invoiced_items=%s, user=%s)",
                 [invoiced_item.pk for invoiced_item in invoiced_items], user)
    if SEND_EMAIL and recipients:
        broker = get_broker()
        broker_recipients, broker_bcc = _notified_recipients(
            broker, 'order_executed')
        app = get_current_app()
        site = get_current_site()
        context = {
            'broker': broker,
            'app': app,
            'provider': broker,
            'organization': organization,
            'invoiced_items': invoiced_items,
            'created_by': user
        }
        if user:
            context.update({
                'urls': {
                    'order': {
                        'created_by': reverse('users_profile', args=(user, ))
                    }
                }
            })
        kwargs = {}
        if broker.email and broker.email != site.get_from_email():
            kwargs = {'reply_to': broker.email}
        get_email_backend(connection=site.get_email_connection()).send(
            from_email=site.get_from_email(),
            recipients=recipients,
            bcc=bcc + broker_recipients + broker_bcc,
            template='notification/order_executed.eml',
            context=context,
            **kwargs)
Beispiel #17
0
def subscribe_req_accepted_notice(sender,
                                  subscription,
                                  request_key,
                                  request=None,
                                  **kwargs):
    user_context = get_user_context(request.user if request else None)
    subscriber = subscription.organization
    if subscriber.email:
        site = get_current_site()
        app = get_current_app()
        LOGGER.debug("[signal] subscribe_req_accepted_notice("\
            " subscription=%s, request_key=%s)", subscription, request_key)
        if SEND_EMAIL:
            get_email_backend(connection=app.get_connection()).send(
                from_email=app.get_from_email(),
                recipients=[subscriber.email],
                reply_to=user_context['email'],
                template='notification/subscription_request_accepted.eml',
                context={
                    'broker':
                    get_broker(),
                    'app':
                    app,
                    'back_url':
                    site.as_absolute_uri(
                        reverse('organization_app', args=(subscriber, ))),
                    'organization':
                    subscriber,
                    'plan':
                    subscription.plan,
                    'user':
                    user_context
                })
    else:
        LOGGER.warning(
            "%s will not be notified that its subscription to %s"\
            " was accepted because e-mail address is invalid.", subscriber,
            subscription.plan)
Beispiel #18
0
def renewal_charge_failed_notice(sender, invoiced_items, total_price,
                                 final_notice, **kwargs):
    invoiced_items = list(invoiced_items)
    organization = (invoiced_items[0].dest_organization
                    if invoiced_items else None)
    recipients, bcc = _notified_recipients(organization,
                                           'renewal_charge_failed')
    LOGGER.debug("[signal] renewal_charge_failed_notice(invoiced_items=%s,"\
        " total_price=%s, final_notice=%s)",
        [invoiced_item.pk for invoiced_item in invoiced_items],
        total_price, final_notice)
    if SEND_EMAIL and recipients:
        broker = get_broker()
        broker_recipients, broker_bcc = _notified_recipients(
            broker, 'renewal_charge_failed')
        app = get_current_app()
        site = get_current_site()
        context = {
            'broker': broker,
            'app': app,
            'provider': broker,
            'organization': organization,
            'invoiced_items': invoiced_items,
            'total_price': total_price,
            'max_renewal_attempts': saas_settings.MAX_RENEWAL_ATTEMPTS,
            'final_notice': final_notice,
            'back_url': reverse('saas_organization_cart',
                                args=(organization, ))
        }
        reply_to = None
        if broker.email and broker.email != site.get_from_email():
            reply_to = broker.email
        _send_notification_email(site,
                                 recipients,
                                 'notification/renewal_charge_failed.eml',
                                 reply_to=reply_to,
                                 bcc=bcc + broker_recipients + broker_bcc,
                                 context=context)
Beispiel #19
0
def processor_setup_error_notice(sender, provider, error_message, **kwargs):
    recipients, notused = _notified_recipients(
        provider, 'processor_setup_error')
    if SEND_EMAIL and recipients:
        broker = get_broker()
        site = get_current_site()
        app = get_current_app()
        broker_recipients, broker_bcc = _notified_recipients(
        broker, 'processor_setup_error')
        reply_to = None
        if broker.email and broker.email != site.get_from_email():
            reply_to = broker.email
        _send_notification_email(site, recipients,
            'notification/processor_setup_error.eml',
            reply_to=reply_to, bcc=broker_recipients + broker_bcc,
            context={
                'broker': broker, 'app': app,
                'organization': provider,
                'message': error_message,
                'urls':{
                    'update_bank': site.as_absolute_uri(reverse(
                            'saas_update_bank', args=(provider,))),
                }})
Beispiel #20
0
def order_executed_notice(sender, invoiced_items, user, **kwargs):
    from saas.models import Transaction
    invoiced_items = Transaction.objects.filter(id__in=invoiced_items)
    broker = get_broker()
    recipients, bcc = _notified_recipients(
        invoiced_items.first().dest_organization)
    broker_recipients, broker_bcc = _notified_recipients(broker)
    app = get_current_app()
    LOGGER.debug("[signal] order_executed_notice(invoiced_items=%s, user=%s)",
                 invoiced_items, user)
    if SEND_EMAIL:
        get_email_backend(connection=app.get_connection()).send(
            from_email=app.get_from_email(),
            recipients=recipients,
            bcc=bcc + broker_recipients + broker_bcc,
            reply_to=broker_recipients[0],
            template='notification/order_executed.eml',
            context={
                'broker': broker,
                'app': app,
                'provider': broker,
                'invoiced_items': invoiced_items
            })
Beispiel #21
0
 def get_initial(self):
     """
     Populates place order forms with the organization address
     whenever possible.
     """
     self.customer = self.get_organization()
     kwargs = super(CardFormMixin, self).get_initial()
     provider = get_broker()
     if self.customer.country:
         country = self.customer.country
     else:
         country = provider.country
     if self.customer.region:
         region = self.customer.region
     else:
         region = provider.region
     kwargs.update({'card_name': self.customer.full_name,
                    'card_city': self.customer.locality,
                    'card_address_line1': self.customer.street_address,
                    'country': country,
                    'region': region,
                    'card_address_zip': self.customer.postal_code})
     return kwargs
Beispiel #22
0
def subscribe_grant_accepted_notice(sender,
                                    subscription,
                                    grant_key,
                                    request=None,
                                    **kwargs):
    provider = subscription.plan.organization
    originated_by = request.user if request else None
    recipients, bcc = _notified_recipients(provider,
                                           "subscribe_grant_accepted_notice",
                                           originated_by=originated_by)
    LOGGER.debug("[signal] subscribe_grant_accepted_notice("\
        " subscription=%s, grant_key=%s)", subscription, grant_key)
    if SEND_EMAIL and recipients:
        site = get_current_site()
        app = get_current_app()
        user_context = get_user_context(originated_by)
        get_email_backend(connection=site.get_email_connection()).send(
            from_email=site.get_from_email(),
            recipients=recipients,
            bcc=bcc,
            reply_to=user_context['email'],
            template='notification/subscription_grant_accepted.eml',
            context={
                'broker':
                get_broker(),
                'app':
                app,
                'back_url':
                site.as_absolute_uri(
                    reverse('organization_app', args=(provider, ))),
                'organization':
                subscription.organization,
                'plan':
                subscription.plan,
                'user':
                user_context
            })
Beispiel #23
0
def user_relation_requested_notice(sender,
                                   organization,
                                   user,
                                   reason=None,
                                   **kwargs):
    if user.email != organization.email:
        if user.email:
            site = get_current_site()
            app = get_current_app()
            LOGGER.debug("[signal] user_relation_requested_notice("\
                "organization=%s, user=%s, reason=%s)",
                organization, user, reason)
            if SEND_EMAIL:
                get_email_backend(connection=app.get_connection()).send(
                    from_email=app.get_from_email(),
                    recipients=[organization.email],
                    reply_to=user.email,
                    template='notification/user_relation_requested.eml',
                    context={
                        'broker':
                        get_broker(),
                        'app':
                        app,
                        'back_url':
                        site.as_absolute_uri(
                            reverse('saas_role_list', args=(organization, ))),
                        'organization':
                        organization,
                        'reason':
                        reason if reason is not None else "",
                        'user':
                        get_user_context(user)
                    })
        else:
            LOGGER.warning(
                "%s will not be notified of role request to %s"\
                "because e-mail address is invalid.", user, organization)
Beispiel #24
0
def user_registered_notice(sender, user, **kwargs):
    """
    A new user has registered (frictionless or completely)
    """
    LOGGER.debug("[signal] user_registered_notice(user=%s)", user)
    if not SEND_EMAIL:
        return
    broker = get_broker()
    app = get_current_app()
    site = get_current_site()
    recipients, bcc = _notified_recipients(broker, "user_registered_notice")
    if hasattr(app, 'welcome_email') and app.welcome_email:
        back_url = site.as_absolute_uri()
        reply_to = None
        if broker.email and broker.email != site.get_from_email():
            reply_to = broker.email
        _send_notification_email(site, [user.email],
                                 'notification/user_welcome.eml',
                                 reply_to=reply_to,
                                 bcc=recipients + bcc,
                                 context={
                                     'broker': broker,
                                     'app': app,
                                     'user': get_user_context(user),
                                     'back_url': back_url
                                 })
    if recipients:
        _send_notification_email(site,
                                 recipients,
                                 'notification/user_registered.eml',
                                 bcc=bcc,
                                 context={
                                     'broker': broker,
                                     'app': app,
                                     'user': get_user_context(user)
                                 })
    def handle(self, *args, **options):
        #pylint: disable=too-many-locals,too-many-statements
        from saas.metrics.base import month_periods  # avoid import loop

        RazorpayBackend.bypass_api = True

        now = datetime.datetime.utcnow().replace(tzinfo=utc)
        from_date = now
        from_date = datetime.datetime(year=from_date.year,
                                      month=from_date.month,
                                      day=1)
        if args:
            from_date = datetime.datetime.strptime(args[0], '%Y-%m-%d')
        # Create a set of 3 plans
        broker = get_broker()
        plan, _ = Plan.objects.get_or_create(slug='basic',
                                             defaults={
                                                 'title': "Basic",
                                                 'description': "Basic Plan",
                                                 'period_amount': 24900,
                                                 'broker_fee_percent': 0,
                                                 'period_type': 4,
                                                 'organization': broker,
                                                 'is_active': True
                                             })
        advance_discount = AdvanceDiscount.objects.get_or_create(
            plan=plan,
            discount_type=AdvanceDiscount.PERCENTAGE,
            amount=1000,
            length=12)
        Plan.objects.get_or_create(slug='medium',
                                   defaults={
                                       'title': "Medium",
                                       'description': "Medium Plan",
                                       'period_amount': 24900,
                                       'broker_fee_percent': 0,
                                       'period_type': 4,
                                       'organization': broker,
                                       'is_active': True
                                   })
        plan, _ = Plan.objects.get_or_create(slug='premium',
                                             defaults={
                                                 'title': "Premium",
                                                 'description': "Premium Plan",
                                                 'period_amount': 18900,
                                                 'broker_fee_percent': 0,
                                                 'period_type': 4,
                                                 'organization': broker,
                                                 'is_active': True
                                             })
        advance_discount = AdvanceDiscount.objects.get_or_create(
            plan=plan,
            discount_type=AdvanceDiscount.PERCENTAGE,
            amount=81,
            length=12)
        # Create Income transactions that represents a growing bussiness.
        provider = Organization.objects.get(slug=options['provider'])
        processor = Organization.objects.get(pk=PROCESSOR_ID)
        for end_period in month_periods(from_date=from_date):
            nb_new_customers = random.randint(0, 9)
            for _ in range(nb_new_customers):
                queryset = Plan.objects.filter(organization=provider,
                                               period_amount__gt=0)
                plan = queryset[random.randint(0, queryset.count() - 1)]
                created = False
                trials = 0
                while not created:
                    try:
                        first_name = self.FIRST_NAMES[random.randint(
                            0,
                            len(self.FIRST_NAMES) - 1)]
                        last_name = self.LAST_NAMES[random.randint(
                            0,
                            len(self.LAST_NAMES) - 1)]
                        full_name = '%s %s' % (first_name, last_name)
                        slug = slugify('demo%d' % random.randint(1, 1000))
                        customer, created = Organization.objects.get_or_create(
                            slug=slug, full_name=full_name)
                    #pylint: disable=catching-non-exception
                    except IntegrityError:
                        trials = trials + 1
                        if trials > 10:
                            raise RuntimeError(
                                'impossible to create a new customer after 10 trials.'
                            )
                Organization.objects.filter(pk=customer.id).update(
                    created_at=end_period)
                subscription = Subscription.objects.create(
                    organization=customer,
                    plan=plan,
                    ends_at=now + datetime.timedelta(days=31))
                Subscription.objects.filter(pk=subscription.id).update(
                    created_at=end_period)
            # Insert some churn in %
            churn_rate = 2
            all_subscriptions = Subscription.objects.filter(
                plan__organization=provider)
            nb_churn_customers = (all_subscriptions.count() * churn_rate //
                                  100)
            subscriptions = random.sample(
                list(all_subscriptions),
                all_subscriptions.count() - nb_churn_customers)
            for subscription in subscriptions:
                nb_periods = random.randint(1, 6)
                amount = nb_periods * subscription.plan.period_amount
                ends_at = subscription.plan.end_of_period(
                    subscription.ends_at, nb_periods)
                transaction_item = Transaction.objects.new_subscription_order(
                    subscription,
                    amount=amount,
                    descr=humanize.describe_buy_periods(
                        subscription.plan, ends_at, nb_periods),
                    created_at=end_period)
                if transaction_item.dest_amount < 50:
                    continue
                transaction_item.orig_amount = transaction_item.dest_amount
                transaction_item.orig_unit = transaction_item.dest_unit
                transaction_item.save()
                charge = Charge.objects.create(
                    created_at=transaction_item.created_at,
                    amount=transaction_item.dest_amount,
                    customer=subscription.organization,
                    description='Charge for %d periods' % nb_periods,
                    last4=1241,
                    exp_date=datetime_or_now(),
                    processor=processor,
                    processor_key=str(transaction_item.pk),
                    # XXX We can't do that yet because of
                    # ``PROCESSOR_BACKEND.charge_distribution(self)``
                    #                    unit=transaction_item.dest_unit,
                    state=Charge.CREATED)
                charge.created_at = transaction_item.created_at
                charge.save()
                ChargeItem.objects.create(invoiced=transaction_item,
                                          charge=charge)
                charge.payment_successful()
            churned = all_subscriptions.exclude(
                pk__in=[subscription.pk for subscription in subscriptions])
            for subscription in churned:
                subscription.ends_at = end_period
                subscription.save()
            self.stdout.write(
                "%d new and %d churned customers at %s" %
                (nb_new_customers, nb_churn_customers, end_period))
Beispiel #26
0
 def get_provider():
     return get_broker()
Beispiel #27
0
 def get_template_names(self):
     if not fail_direct(self.request, organization=get_broker()):
         return ['app_proxy_help.html']
     return super(DjaoAppPageView, self).get_template_names()
Beispiel #28
0
    def get_context_data(self, **kwargs):
        context = super(NotificationListView, self).get_context_data(**kwargs)
        broker = get_broker()
        context.update({
            'notifications': {
                'card_updated': {
                    'title': _("Card updated"),
                    'descr': _("This notification is sent when a credit card"\
" on file is updated.")
                },
                'charge_receipt': {
                    'title': _("Charge receipt"),
                    'descr': _("This notification is sent when a charge is"\
" created on a credit card. It is also sent when the charge is refunded.")
                },
                'claim_code_generated': {
                    'title': _("Claim code"),
                    'descr': _("")
                },
                'expires_soon': {
                    'title': _("Expires soon"),
                    'descr': _("This notification is sent when a subscription"\
" is about to expire.")
                },
                'order_executed': {
                    'title': _("Order confirmation"),
                    'descr': _("This notification is sent when an order has"\
" been confirmed but a charge has been successfuly processed yet.")
                },
                'organization_updated': {
                    'title': _("Profile updated"),
                    'descr': _("This notification is sent when a profile"\
" is updated.")
                },
                'password_reset': {
                    'title': _("Password reset"),
                    'descr': _("This notification is sent to a user that has"\
" requested to reset their password through a \"forgot password?\" link.")
                },
                'user_activated': {
                    'title': _("User activated"),
                    'descr': _("This notification is sent to profile managers"\
" of a domain when a user has activated his/her account.")
                },
                'user_contact': {
                    'title': _("User contact"),
                    'descr': _("")
                },
                'user_registered': {
                    'title': _("User registered"),
                    'descr': _("This notification is sent to profile managers"\
" of a domain when a user has registered.")
                },
                'user_relation_requested': {
                    'title': _("User relation requested"),
                    'descr': _("This notification is sent to profile managers"\
" of an organization when a user has requested a role on that organization.")
                },
                'verification': {
                    'title': _("Verification"),
                    'descr': _("This notification is sent to verify an e-mail"\
" address of a user.")
                },
                'sales_report': {
                    'title': _("Weekly sales report"),
                    'descr': _("This notification is sent to profile managers."\
" It contains the weekly sales results.")
                },
            },
            'role_descriptions': broker.get_role_descriptions()
        })
        self.update_context_urls(
            context, {'send_test_email': reverse('api_notification_base')})
        return context
Beispiel #29
0
 def get_site(obj):  #pylint:disable=unused-argument
     broker = get_broker()
     return {'printable_name': broker.printable_name, 'email': broker.email}
Beispiel #30
0
def get_test_email_context():
    broker = get_broker()
    site = get_current_site()
    return {
        # specific to charge_receipt
        'charge': {
            'price': Price(2999, 'usd'),
            'processor_key': "{{charge.processor_key}}",
            'last4': "{{charge.last4}}",
            'exp_date': "{{charge.exp_date}}",
            'created_by': {},
        },
        'email_by': {
            'username': "******",
            'email': "{{charge.email_by.email}}",
            'first_name': "{{charge.email_by.first_name}}",
            'printable_name': "{{charge.email_by.printable_name}}"
        },
        # specific to organization_updated
        'changes': {},
        # specific to claim_code_generated
        'subscriber': {},
        # specific to card_updated
        'old_card': {
            'last4': "{{old_card.last4}}",
            'exp_date': "{{old_card.exp_date}}"
        },
        'new_card': {
            'last4': "{{new_card.last4}}",
            'exp_date': "{{new_card.exp_date}}"
        },
        # specific to weekly_report
        'table': {},
        'date': '',
        # app_created/app_updated
        'instance': {
            'printable_name': "{{instance.printable_name}}"
        },
        # common across all notifications
        'urls': {
            'cart': site.as_absolute_uri(reverse('saas_cart')),
            'user': {
                'profile': None
            },
            'organization': {
                'profile': None
            }
        },
        'user': {
            'username': "******",
            'email': "{{user.email}}",
            'first_name': "{{user.first_name}}",
            'printable_name': "{{user.printable_name}}"
        },
        'organization': {
            'printable_name': "{{organization.printable_name}}"
        },
        'site': site,
        'app': get_current_app(),
        'provider': broker,
        'broker': broker
    }
Beispiel #31
0
def subscribe_grant_created_notice(sender,
                                   subscription,
                                   reason=None,
                                   invite=False,
                                   request=None,
                                   **kwargs):
    #pylint:disable=too-many-locals
    if subscription.grant_key:
        user_context = get_user_context(request.user if request else None)
        organization = subscription.organization
        back_url_base = reverse('subscription_grant_accept',
                                args=(
                                    organization,
                                    subscription.grant_key,
                                ))
        LOGGER.debug("[signal] subscribe_grant_created_notice("\
            " subscription=%s, reason=%s, invite=%s)",
            subscription, reason, invite)
        # We don't use `_notified_recipients` because
        #    1. We need the actual User object to update/create a Contact
        #    2. We should not send to the organization e-mail address
        #       because the e-mail there might not be linked to a manager.
        managers = organization.with_role(saas_settings.MANAGER)
        emails = kwargs.get('emails', None)
        if emails:
            managers = managers.filter(email__in=emails)
        if not managers:
            LOGGER.warning(
                "%s will not be notified of a subscription grant to %s"\
                " because there are no managers to send e-mails to.",
                organization, subscription.plan)
        for manager in managers:
            # The following line could as well be `if invite:`
            if has_invalid_password(manager):
                # The User is already in the system but the account
                # has never been activated.
                #pylint:disable=unused-variable
                contact, notused = Contact.objects.update_or_create_token(
                    manager)
                back_url = "%s?next=%s" % (reverse(
                    'registration_activate',
                    args=(contact.verification_key, )), back_url_base)
            else:
                back_url = back_url_base
            LOGGER.debug("[signal] would send subscribe_grant_created_notice"\
                " for subscription '%s' to '%s'", subscription, manager.email)
            if SEND_EMAIL:
                site = get_current_site()
                app = get_current_app()
                _send_notification_email(
                    site, [manager.email],
                    'notification/subscription_grant_created.eml',
                    reply_to=user_context['email'],
                    context={
                        'broker': get_broker(),
                        'app': app,
                        'back_url': site.as_absolute_uri(back_url),
                        'organization': organization,
                        'plan': subscription.plan,
                        'reason': reason if reason is not None else "",
                        'invite': invite,
                        'user': user_context
                    })
Beispiel #32
0
def on_user_post_save(sender, instance, created, raw, **kwargs):
    #pylint:disable=unused-argument
    if created and instance.is_superuser:
        get_broker().add_manager(instance)
Beispiel #33
0
def is_direct(request, organization=None):
    if organization is None:
        organization = get_broker()
    return pass_direct(request, organization=organization)
Beispiel #34
0
def inject_edition_tools(response,
                         request,
                         context=None,
                         body_top_template_name=None,
                         body_bottom_template_name=None):
    """
    If the ``request.user`` has editable permissions, this method
    injects the edition tools into the html *content* and return
    a BeautifulSoup object of the resulting content + tools.

    If the response is editable according to the proxy rules, this
    method returns a BeautifulSoup object of the content such that
    ``PageMixin`` inserts the edited page elements.
    """
    #pylint:disable=too-many-locals,too-many-nested-blocks,too-many-statements
    content_type = response.get('content-type', '')
    if not content_type.startswith('text/html'):
        return None

    if not is_authenticated(request):
        return None

    if context is None:
        context = {}

    # ``app.account`` is guarenteed to be in the same database as ``app``.
    # ``site.account`` is always in the *default* database, which is not
    # the expected database ``Organization`` are typically queried from.
    app = get_current_app()
    provider = app.account
    soup = None
    if app.show_edit_tools and get_role_model().objects.valid_for(
            organization=provider, user=request.user):
        edit_urls = {
            'api_medias':
            reverse('uploaded_media_elements', kwargs={'path': ''}),
            'api_sitecss':
            reverse('edit_sitecss'),
            'api_less_overrides':
            reverse('pages_api_less_overrides'),
            'api_sources':
            reverse('pages_api_sources'),
            'api_page_element_base':
            reverse('api_page_element', kwargs={'path': ''}),
            'api_plans':
            reverse('saas_api_plans', args=(provider, )),
            'plan_update_base':
            reverse('saas_plan_base', args=(provider, ))
        }
        try:
            # The following statement will raise an Exception
            # when we are dealing with a ``FileSystemStorage``.
            _ = get_storage_class().bucket_name
            edit_urls.update(
                {'media_upload': reverse('api_credentials_organization')})
        except AttributeError:
            LOGGER.debug("doesn't look like we have a S3Storage.")
        # XXX sites which are hosted on a same domain shouldn't disable
        # all edit functionality, just the edition of base templates.
        site = get_current_site()
        enable_code_editor = is_domain_site(site)
        if enable_code_editor:
            dj_urls = djaoapp_urls(request,
                                   account=provider,
                                   base=site.as_base())
            body_bottom_template_name = "pages/_body_bottom_edit_tools.html"
        else:
            dj_urls = djaoapp_urls(request, account=provider)
            body_bottom_template_name = "pages/_body_bottom.html"

        context.update({
            'ENABLE_CODE_EDITOR': enable_code_editor,
            'FEATURE_DEBUG': settings.FEATURES_DEBUG,
            'urls': {
                'djaodjin': dj_urls,
                'edit': edit_urls
            }
        })
        context.update(csrf(request))
        soup = pages_inject_edition_tools(
            response,
            request,
            context=context,
            body_top_template_name=body_top_template_name,
            body_bottom_template_name=body_bottom_template_name)

    # Insert the authenticated user information and roles on organization.
    if not soup:
        soup = BeautifulSoup(response.content, 'html5lib')
    if soup and soup.body:
        # Implementation Note: we have to use ``.body.next`` here
        # because html5lib "fixes" our HTML by adding missing
        # html/body tags. Furthermore if we use
        #``soup.body.insert(1, BeautifulSoup(body_top, 'html.parser'))``
        # instead, later on ``soup.find_all(class_=...)`` returns
        # an empty set though ``soup.prettify()`` outputs the full
        # expected HTML text.
        auth_user = soup.body.find(class_='header-menubar')
        user_menu_template = '_menubar.html'
        if auth_user and user_menu_template:
            serializer_class = import_string(rules_settings.SESSION_SERIALIZER)
            serializer = serializer_class(request)
            path_parts = reversed(request.path.split('/'))
            top_accessibles = []
            has_broker_role = False
            active_organization = None
            for role, organizations in six.iteritems(serializer.data['roles']):
                for organization in organizations:
                    if organization['slug'] == request.user.username:
                        # Personal Organization
                        continue
                    db_obj = get_organization_model().objects.get(
                        slug=organization['slug'])  # XXX Remove query.
                    if db_obj.is_provider:
                        settings_location = reverse(
                            'saas_dashboard', args=(organization['slug'], ))
                    else:
                        settings_location = reverse(
                            'saas_organization_profile',
                            args=(organization['slug'], ))
                    app_location = reverse('organization_app',
                                           args=(organization['slug'], ))
                    if organization['slug'] in path_parts:
                        active_organization = TopAccessibleOrganization(
                            organization['slug'],
                            organization['printable_name'], settings_location,
                            role, app_location)
                    if is_broker(organization['slug']):
                        has_broker_role = True
                    top_accessibles += [
                        TopAccessibleOrganization(
                            organization['slug'],
                            organization['printable_name'], settings_location,
                            role, app_location)
                    ]
            if not active_organization and has_broker_role:
                active_organization = get_broker()
            context.update({'active_organization': active_organization})
            context.update({'top_accessibles': top_accessibles})
            template = loader.get_template(user_menu_template)
            user_menu = render_template(template, context, request).strip()
            auth_user.clear()
            els = BeautifulSoup(user_menu, 'html5lib').body.ul.children
            for elem in els:
                auth_user.append(BeautifulSoup(str(elem), 'html5lib'))

    return soup
Beispiel #35
0
    def get_notifications(user=None):
        broker = get_broker()
        notifications = {
            'card_updated': {
                'title': _("Card updated"),
                'descr': _("This notification is sent when a credit card"\
" on file is updated.")
            },
            'charge_receipt': {
                'title': _("Charge receipt"),
                'descr': _("This notification is sent when a charge is"\
" created on a credit card. It is also sent when the charge is refunded.")
            },
            'claim_code_generated': {
                'title': _("Claim code"),
                'descr': _("This notification is sent to the user invited"\
" through a groupBuy.")
            },
            'expires_soon': {
                'title': _("Expires soon"),
                'descr': _("This notification is sent when a subscription"\
" is about to expire.")
            },
            'order_executed': {
                'title': _("Order confirmation"),
                'descr': _("This notification is sent when an order has"\
" been confirmed but a charge has not been successfully processed yet.")
            },
            'organization_updated': {
                'title': _("Profile updated"),
                'descr': _("This notification is sent when a profile"\
" is updated.")
            },
            'password_reset': {
                'title': _("Password reset"),
                'descr': _("This notification is sent to a user that has"\
" requested to reset their password through a \"forgot password?\" link.")
            },
            'user_activated': {
                'title': _("User activated"),
                'descr': _("This notification is sent to profile managers"\
" of a domain when a user has activated his/her account.")
                },
            'user_contact': {
                'title': _("User contact"),
                'descr': _("This notification is sent to profile managers"\
" of a domain when a user submits an inquiry on the contact-us page.")
            },
            'user_registered': {
                'title': _("User registered"),
                'descr': _("This notification is sent to profile managers"\
" of a domain when a user has registered.")
            },
            'user_welcome': {
                'title': _("Welcome e-mail"),
                'descr': _("This notification is sent to a user after they"\
" register an account with the site."),
            },
            'role_request_created': {
                'title': _("Role requested"),
                'descr': _("This notification is sent to profile managers"\
" of an organization when a user has requested a role on that organization.")
                },
            'verification': {
                'title': _("Verification"),
                'descr': _("This notification is sent to verify an e-mail"\
" address of a user.")
            },
            'sales_report': {
                'title': _("Weekly sales report"),
                'descr': _("This notification is sent to profile managers."\
" It contains the weekly sales results.")
            },
        }
        for role_descr in broker.get_role_descriptions():
            notifications.update({
                "%s_role_grant_created" % role_descr.slug: {
                    'title': _("%(role_title)s Added") % {
                        'role_title': role_descr.title
                    },
                    'descr': ""
                }
            })

        # user with profile manager of broker (or theme editor)
        if not user or broker.with_role(
                saas_settings.MANAGER).filter(pk=user.pk).exists():
            return notifications

        # regular subscriber
        return {
            key: notifications[key]
            for key in [
                'charge_receipt', 'card_updated', 'order_executed',
                'organization_updated', 'expires_soon'
            ]
        }