Exemplo n.º 1
0
def default_new_app(request, domain):
    """New Blank Application according to defaults. So that we can link here
    instead of creating a form and posting to the above link, which was getting
    annoying for the Dashboard.
    """
    meta = get_meta(request)
    track_app_from_template_on_hubspot.delay(request.couch_user,
                                             request.COOKIES, meta)
    if tours.NEW_APP.is_enabled(request.user):
        identify.delay(request.couch_user.username,
                       {'First Template App Chosen': 'blank'})
    lang = 'en'
    app = Application.new_app(domain, _("Untitled Application"), lang=lang)

    if not toggles.APP_MANAGER_V2.enabled(domain):
        # APP MANAGER V2 is completely blank on new app
        module = Module.new_module(_("Untitled Module"), lang)
        app.add_module(module)
        form = app.new_form(0, "Untitled Form", lang)

    if request.project.secure_submissions:
        app.secure_submissions = True
    clear_app_cache(request, domain)
    app.save()
    if toggles.APP_MANAGER_V2.enabled(request.domain):
        return HttpResponseRedirect(reverse('view_app', args=[domain,
                                                              app._id]))
    return HttpResponseRedirect(
        reverse('view_form', args=[domain, app._id, 0, 0]))
Exemplo n.º 2
0
 def post(self, request, *args, **kwargs):
     meta = get_meta(request)
     if hasattr(request, 'couch_user'):
         track_clicked_deploy_on_hubspot.delay(
             request.couch_user.get_id, request.COOKIES.get(HUBSPOT_COOKIE),
             meta)
     return HttpResponse()
Exemplo n.º 3
0
 def post(self, request, *args, **kwargs):
     if self.prefilled_email:
         meta = get_meta(request)
         track_clicked_signup_on_hubspot.delay(
             self.prefilled_email, request.COOKIES.get(HUBSPOT_COOKIE),
             meta)
     return super(UserRegistrationView, self).get(request, *args, **kwargs)
Exemplo n.º 4
0
def register_user(request):
    prefilled_email = request.GET.get('e', '')
    context = get_domain_context()

    if request.user.is_authenticated():
        # Redirect to a page which lets user choose whether or not to create a new account
        domains_for_user = Domain.active_for_user(request.user)
        if len(domains_for_user) == 0:
            return redirect("registration_domain")
        else:
            return redirect("homepage")
    else:
        if request.method == 'POST':
            form = NewWebUserRegistrationForm(request.POST)
            if form.is_valid():
                activate_new_user(form, ip=get_ip(request))
                new_user = authenticate(username=form.cleaned_data['email'],
                                        password=form.cleaned_data['password'])

                track_workflow(new_user.email, "Requested new account")

                login(request, new_user)

                requested_domain = form.cleaned_data['hr_name']
                if form.cleaned_data['create_domain']:
                    try:
                        requested_domain = request_new_domain(
                            request, form, is_new_user=True)
                    except NameUnavailableException:
                        context.update({
                            'current_page': {'page_name': _('Oops!')},
                            'error_msg': _('Project name already taken - please try another'),
                            'show_homepage_link': 1
                        })
                        return render(request, 'error.html', context)

                context.update({
                    'requested_domain': requested_domain,
                    'track_domain_registration': True,
                    'current_page': {'page_name': _('Confirmation Email Sent')},
                })
                return render(request, 'registration/confirmation_sent.html', context)
            context.update({'create_domain': form.cleaned_data['create_domain']})
        else:
            form = NewWebUserRegistrationForm(
                initial={'email': prefilled_email, 'create_domain': True})
            context.update({'create_domain': True})
            meta = get_meta(request)
            track_clicked_signup_on_hubspot(prefilled_email, request.COOKIES, meta)

        context.update({
            'form': form,
            'current_page': {'page_name': _('Create an Account')},
            'hide_password_feedback': settings.ENABLE_DRACONIAN_SECURITY_FEATURES,
            'is_register_user': True,
        })
        return render(request, 'registration/create_new_user.html', context)
Exemplo n.º 5
0
def track_user_login(sender, request, user, **kwargs):
    couch_user = CouchUser.from_django_user(user)
    if couch_user and couch_user.is_web_user():
        if not request or HUBSPOT_COOKIE not in request.COOKIES:
            # API calls, form submissions etc.
            return

        meta = get_meta(request)
        track_user_sign_in_on_hubspot.delay(couch_user, request.COOKIES, meta, request.path)
Exemplo n.º 6
0
def track_user_login(sender, request, user, **kwargs):
    couch_user = CouchUser.from_django_user(user)
    if couch_user and couch_user.is_web_user():
        if not request or HUBSPOT_COOKIE not in request.COOKIES:
            # API calls, form submissions etc.
            return

        meta = get_meta(request)
        track_user_sign_in_on_hubspot.delay(couch_user, request.COOKIES, meta,
                                            request.path)
Exemplo n.º 7
0
def send_hubspot_form(form_id, request, user=None):
    """
    pulls out relevant info from request object before sending to celery since
    requests cannot be pickled
    """
    if user is None:
        user = getattr(request, 'couch_user', None)
    if request and user and user.is_web_user():
        meta = get_meta(request)
        send_hubspot_form_task.delay(form_id, user, request.COOKIES.get(HUBSPOT_COOKIE), meta)
Exemplo n.º 8
0
def send_hubspot_form(form_id, request, user=None, extra_fields=None):
    """
    pulls out relevant info from request object before sending to celery since
    requests cannot be pickled
    """
    if user is None:
        user = getattr(request, 'couch_user', None)
    if request and user and user.is_web_user():
        meta = get_meta(request)
        send_hubspot_form_task_v2.delay(
            form_id, user.user_id, request.COOKIES.get(HUBSPOT_COOKIE),
            meta, extra_fields=extra_fields
        )
Exemplo n.º 9
0
def track_user_login(sender, request, user, **kwargs):
    couch_user = CouchUser.from_django_user(user)
    if couch_user and couch_user.is_web_user():
        if not request or HUBSPOT_COOKIE not in request.COOKIES:
            # API calls, form submissions etc.

            user_confirming = request.path.startswith(reverse(ProcessRegistrationView.urlname))
            if user_confirming:
                _no_cookie_soft_assert(False, 'User confirmed account but had no cookie')
            else:
                return

        meta = get_meta(request)
        track_user_sign_in_on_hubspot.delay(couch_user, request.COOKIES, meta, request.path)
Exemplo n.º 10
0
def app_from_template(request, domain, slug):
    meta = get_meta(request)
    track_app_from_template_on_hubspot.delay(request.couch_user, request.COOKIES, meta)
    if tours.NEW_APP.is_enabled(request.user):
        identify.delay(request.couch_user.username, {"First Template App Chosen": "%s" % slug})
    clear_app_cache(request, domain)
    template = load_app_template(slug)
    app = import_app_util(template, domain, {"created_from_template": "%s" % slug})
    module_id = 0
    form_id = 0
    try:
        app.get_module(module_id).get_form(form_id)
    except (ModuleNotFoundException, FormNotFoundException):
        return HttpResponseRedirect(reverse("view_app", args=[domain, app._id]))
    return HttpResponseRedirect(reverse("view_form", args=[domain, app._id, module_id, form_id]))
Exemplo n.º 11
0
def track_user_login(sender, request, user, **kwargs):
    if settings.ANALYTICS_IDS.get('HUBSPOT_API_ID'):
        couch_user = CouchUser.from_django_user(user)
        if couch_user and couch_user.is_web_user():
            if not request or HUBSPOT_COOKIE not in request.COOKIES:
                # API calls, form submissions etc.

                user_confirming = request.path.startswith(reverse(ProcessRegistrationView.urlname))
                if user_confirming:
                    _no_cookie_soft_assert(False, 'User confirmed account but had no cookie')
                else:
                    return

            meta = get_meta(request)
            track_user_sign_in_on_hubspot_v2.delay(couch_user, request.COOKIES.get(HUBSPOT_COOKIE), meta, request.path)
Exemplo n.º 12
0
def app_from_template(request, domain, slug):
    meta = get_meta(request)
    track_app_from_template_on_hubspot.delay(request.couch_user, request.COOKIES, meta)
    clear_app_cache(request, domain)
    template = load_app_template(slug)
    app = import_app_util(template, domain, {
        'created_from_template': '%s' % slug,
    })
    module_id = 0
    form_id = 0
    try:
        app.get_module(module_id).get_form(form_id)
    except (ModuleNotFoundException, FormNotFoundException):
        return HttpResponseRedirect(reverse('view_app', args=[domain, app._id]))
    return HttpResponseRedirect(reverse('view_form_legacy', args=[domain, app._id, module_id, form_id]))
Exemplo n.º 13
0
def app_from_template(request, domain, slug):
    meta = get_meta(request)
    track_app_from_template_on_hubspot.delay(request.couch_user, request.COOKIES, meta)
    clear_app_cache(request, domain)
    template = load_app_template(slug)
    app = import_app_util(template, domain, {
        'created_from_template': '%s' % slug,
    })
    module_id = 0
    form_id = 0
    try:
        app.get_module(module_id).get_form(form_id)
    except (ModuleNotFoundException, FormNotFoundException):
        return HttpResponseRedirect(reverse('view_app', args=[domain, app._id]))
    return HttpResponseRedirect(reverse('form_source', args=[domain, app._id, module_id, form_id]))
Exemplo n.º 14
0
def default_new_app(request, domain):
    """New Blank Application according to defaults. So that we can link here
    instead of creating a form and posting to the above link, which was getting
    annoying for the Dashboard.
    """
    meta = get_meta(request)
    track_app_from_template_on_hubspot.delay(request.couch_user, request.COOKIES, meta)

    lang = 'en'
    app = Application.new_app(domain, _("Untitled Application"), lang=lang)
    add_ons.init_app(request, app)

    if request.project.secure_submissions:
        app.secure_submissions = True
    clear_app_cache(request, domain)
    app.save()
    return HttpResponseRedirect(reverse('view_app', args=[domain, app._id]))
Exemplo n.º 15
0
def app_from_template(request, domain, slug):
    meta = get_meta(request)
    track_app_from_template_on_hubspot.delay(request.couch_user, request.COOKIES, meta)
    if tours.NEW_APP.is_enabled(request.user):
        identify.delay(request.couch_user.username, {'First Template App Chosen': '%s' % slug})
    clear_app_cache(request, domain)
    template = load_app_template(slug)
    app = import_app_util(template, domain, {
        'created_from_template': '%s' % slug,
    })
    module_id = 0
    form_id = 0
    try:
        app.get_module(module_id).get_form(form_id)
    except (ModuleNotFoundException, FormNotFoundException):
        return HttpResponseRedirect(reverse('view_app', args=[domain, app._id]))
    return HttpResponseRedirect(reverse('view_form', args=[domain, app._id, module_id, form_id]))
Exemplo n.º 16
0
def default_new_app(request, domain):
    """New Blank Application according to defaults. So that we can link here
    instead of creating a form and posting to the above link, which was getting
    annoying for the Dashboard.
    """
    meta = get_meta(request)
    track_app_from_template_on_hubspot.delay(request.couch_user, request.COOKIES, meta)
    lang = 'en'
    app = Application.new_app(
        domain, _("Untitled Application"), lang=lang,
        application_version=APP_V2
    )
    module = Module.new_module(_("Untitled Module"), lang)
    app.add_module(module)
    form = app.new_form(0, "Untitled Form", lang)
    if request.project.secure_submissions:
        app.secure_submissions = True
    clear_app_cache(request, domain)
    app.save()
    return HttpResponseRedirect(reverse('form_source', args=[domain, app._id, 0, 0]))
Exemplo n.º 17
0
    def post(self, request, *args, **kwargs):
        if self.invite_web_user_form.is_valid():
            # If user exists and has already requested access, just add them to the project
            # Otherwise, send an invitation
            create_invitation = True
            data = self.invite_web_user_form.cleaned_data
            domain_request = DomainRequest.by_email(self.domain, data["email"])
            if domain_request is not None:
                domain_request.is_approved = True
                domain_request.save()
                user = CouchUser.get_by_username(domain_request.email)
                if user is not None:
                    domain_request.send_approval_email()
                    create_invitation = False
                    user.add_as_web_user(self.domain,
                                         role=data["role"],
                                         location_id=data.get(
                                             "supply_point", None),
                                         program_id=data.get("program", None))
                messages.success(request, "%s added." % data["email"])
            else:
                track_workflow(request.couch_user.get_email(),
                               "Sent a project invitation",
                               {"Sent a project invitation": "yes"})
                meta = get_meta(request)
                track_sent_invite_on_hubspot.delay(request.couch_user,
                                                   request.COOKIES, meta)
                messages.success(request,
                                 "Invitation sent to %s" % data["email"])

            if create_invitation:
                data["invited_by"] = request.couch_user.user_id
                data["invited_on"] = datetime.utcnow()
                data["domain"] = self.domain
                invite = Invitation(**data)
                invite.save()
                invite.send_activation_email()
            return HttpResponseRedirect(
                reverse(ListWebUsersView.urlname, args=[self.domain]))
        return self.get(request, *args, **kwargs)
Exemplo n.º 18
0
    def post(self, request, *args, **kwargs):
        if self.invite_web_user_form.is_valid():
            # If user exists and has already requested access, just add them to the project
            # Otherwise, send an invitation
            create_invitation = True
            data = self.invite_web_user_form.cleaned_data
            domain_request = DomainRequest.by_email(self.domain, data["email"])
            if domain_request is not None:
                domain_request.is_approved = True
                domain_request.save()
                user = CouchUser.get_by_username(domain_request.email)
                if user is not None:
                    domain_request.send_approval_email()
                    create_invitation = False
                    user.add_as_web_user(self.domain, role=data["role"],
                                         location_id=data.get("supply_point", None),
                                         program_id=data.get("program", None))
                messages.success(request, "%s added." % data["email"])
            else:
                track_workflow(request.couch_user.get_email(),
                               "Sent a project invitation",
                               {"Sent a project invitation": "yes"})
                meta = get_meta(request)
                track_sent_invite_on_hubspot.delay(request.couch_user, request.COOKIES, meta)
                messages.success(request, "Invitation sent to %s" % data["email"])

            if create_invitation:
                data["invited_by"] = request.couch_user.user_id
                data["invited_on"] = datetime.utcnow()
                data["domain"] = self.domain
                invite = Invitation(**data)
                invite.save()
                invite.send_activation_email()
            return HttpResponseRedirect(reverse(
                ListWebUsersView.urlname,
                args=[self.domain]
            ))
        return self.get(request, *args, **kwargs)
Exemplo n.º 19
0
def default_new_app(request, domain):
    """New Blank Application according to defaults. So that we can link here
    instead of creating a form and posting to the above link, which was getting
    annoying for the Dashboard.
    """
    meta = get_meta(request)
    track_app_from_template_on_hubspot.delay(request.couch_user, request.COOKIES, meta)
    if tours.NEW_APP.is_enabled(request.user):
        identify.delay(request.couch_user.username, {"First Template App Chosen": "blank"})
    lang = "en"
    app = Application.new_app(domain, _("Untitled Application"), lang=lang)

    if not toggles.APP_MANAGER_V2.enabled(domain):
        # APP MANAGER V2 is completely blank on new app
        module = Module.new_module(_("Untitled Module"), lang)
        app.add_module(module)
        form = app.new_form(0, "Untitled Form", lang)

    if request.project.secure_submissions:
        app.secure_submissions = True
    clear_app_cache(request, domain)
    app.save()
    return HttpResponseRedirect(reverse("view_form", args=[domain, app._id, 0, 0]))
Exemplo n.º 20
0
 def post(self, request, *args, **kwargs):
     if self.prefilled_email:
         meta = get_meta(request)
         track_clicked_signup_on_hubspot_v2.delay(
             self.prefilled_email, request.COOKIES.get(HUBSPOT_COOKIE), meta)
     return super(UserRegistrationView, self).get(request, *args, **kwargs)
Exemplo n.º 21
0
def form_designer(request, domain, app_id, module_id=None, form_id=None):
    def _form_uses_case(module, form):
        return module and module.case_type and form.requires_case()

    def _form_is_basic(form):
        return form.doc_type == 'Form'

    def _form_too_large(app, form):
        # form less than 0.1MB, anything larger starts to have
        # performance issues with fullstory
        return app.blobs['{}.xml'.format(
            form.unique_id)]['content_length'] > 102400

    meta = get_meta(request)
    track_entered_form_builder_on_hubspot.delay(request.couch_user,
                                                request.COOKIES, meta)

    app = get_app(domain, app_id)
    module = None

    try:
        module = app.get_module(module_id)
    except ModuleNotFoundException:
        return bail(request, domain, app_id, not_found="module")
    try:
        form = module.get_form(form_id)
    except IndexError:
        return bail(request, domain, app_id, not_found="form")

    if form.no_vellum:
        messages.warning(
            request,
            _("You tried to edit this form in the Form Builder. "
              "However, your administrator has locked this form against editing "
              "in the form builder, so we have redirected you to "
              "the form's front page instead."))
        return back_to_main(request,
                            domain,
                            app_id=app_id,
                            unique_form_id=form.unique_id)

    include_fullstory = False
    vellum_plugins = ["modeliteration", "itemset", "atwho"]
    if (toggles.COMMTRACK.enabled(domain)):
        vellum_plugins.append("commtrack")
    if toggles.VELLUM_SAVE_TO_CASE.enabled(domain):
        vellum_plugins.append("saveToCase")
    if (_form_uses_case(module, form) and _form_is_basic(form)):
        vellum_plugins.append("databrowser")

    vellum_features = toggles.toggles_dict(username=request.user.username,
                                           domain=domain)
    vellum_features.update(feature_previews.previews_dict(domain))
    include_fullstory = not _form_too_large(app, form)
    vellum_features.update({
        'group_in_field_list':
        app.enable_group_in_field_list,
        'image_resize':
        app.enable_image_resize,
        'markdown_in_groups':
        app.enable_markdown_in_groups,
        'lookup_tables':
        domain_has_privilege(domain, privileges.LOOKUP_TABLES),
        'templated_intents':
        domain_has_privilege(domain, privileges.TEMPLATED_INTENTS),
        'custom_intents':
        domain_has_privilege(domain, privileges.CUSTOM_INTENTS),
        'rich_text':
        True,
    })

    has_schedule = (getattr(module, 'has_schedule', False)
                    and getattr(form, 'schedule', False)
                    and form.schedule.enabled)
    scheduler_data_nodes = []
    if has_schedule:
        scheduler_data_nodes = [
            SCHEDULE_CURRENT_VISIT_NUMBER,
            SCHEDULE_NEXT_DUE,
            SCHEDULE_UNSCHEDULED_VISIT,
            SCHEDULE_GLOBAL_NEXT_VISIT_DATE,
        ]
        scheduler_data_nodes.extend([
            u"next_{}".format(f.schedule_form_id)
            for f in form.get_phase().get_forms()
            if getattr(f, 'schedule', False) and f.schedule.enabled
        ])

    if tours.VELLUM_CASE_MANAGEMENT.is_enabled(
            request.user) and form.requires_case():
        request.guided_tour = tours.VELLUM_CASE_MANAGEMENT.get_tour_data()

    context = get_apps_base_context(request, domain, app)
    context.update(locals())
    context.update({
        'vellum_debug':
        settings.VELLUM_DEBUG,
        'nav_form':
        form,
        'formdesigner':
        True,
        'include_fullstory':
        include_fullstory,
        'notifications_enabled':
        request.user.is_superuser,
        'notify_facility':
        get_facility_for_form(domain, app_id, form.unique_id),
    })
    notify_form_opened(domain, request.couch_user, app_id, form.unique_id)

    domain_obj = Domain.get_by_name(domain)
    context.update({
        'show_live_preview':
        should_show_preview_app(
            request,
            app,
            request.couch_user.username,
        ),
        'can_preview_form':
        request.couch_user.has_permission(domain, 'edit_data'),
    })

    core = {
        'dataSourcesEndpoint':
        reverse('get_form_data_schema',
                kwargs={
                    'domain': domain,
                    'form_unique_id': form.get_unique_id()
                }),
        'dataSource': [
            # DEPRECATED. Use dataSourcesEndpoint
            {
                'key': 'fixture',
                'name': 'Fixtures',
                'endpoint': reverse('fixture_metadata',
                                    kwargs={'domain': domain}),
            },
        ],
        'form':
        form.source,
        'formId':
        form.get_unique_id(),
        'formName':
        trans(form.name, app.langs),
        'saveType':
        'patch',
        'saveUrl':
        reverse('edit_form_attr',
                args=[domain, app.id,
                      form.get_unique_id(), 'xform']),
        'patchUrl':
        reverse('patch_xform', args=[domain, app.id,
                                     form.get_unique_id()]),
        'allowedDataNodeReferences': [
            "meta/deviceID",
            "meta/instanceID",
            "meta/username",
            "meta/userID",
            "meta/timeStart",
            "meta/timeEnd",
            "meta/location",
        ] + scheduler_data_nodes,
        'activityUrl':
        reverse('ping'),
        'sessionid':
        request.COOKIES.get('sessionid'),
        'externalLinks': {
            'changeSubscription':
            reverse("domain_subscription_view", kwargs={'domain': domain}),
        },
        'invalidCaseProperties': ['name'],
    }

    if toggles.APP_MANAGER_V2.enabled(request.user.username):
        if form.get_action_type() == 'open':
            core.update({
                'defaultHelpTextTemplateId': '#fd-hq-helptext-registration',
                'formIconClass': 'fcc fcc-app-createform',
            })
        elif form.get_action_type() == 'close':
            core.update({
                'defaultHelpTextTemplateId': '#fd-hq-helptext-close',
                'formIconClass': 'fcc fcc-app-completeform',
            })
        elif form.get_action_type() == 'update':
            core.update({
                'defaultHelpTextTemplateId': '#fd-hq-helptext-followup',
                'formIconClass': 'fcc fcc-app-updateform',
            })
        else:
            core.update({
                'defaultHelpTextTemplateId': '#fd-hq-helptext-survey',
                'formIconClass': 'fa fa-file-o',
            })

    vellum_options = {
        'core': core,
        'plugins': vellum_plugins,
        'features': vellum_features,
        'intents': {
            'templates': next(app_callout_templates),
        },
        'javaRosa': {
            'langs': app.langs,
            'displayLanguage': context['lang'],
        },
        'uploader': {
            'uploadUrls': {
                'image': reverse("hqmedia_uploader_image",
                                 args=[domain, app.id]),
                'audio': reverse("hqmedia_uploader_audio",
                                 args=[domain, app.id]),
                'video': reverse("hqmedia_uploader_video",
                                 args=[domain, app.id]),
                'text': reverse("hqmedia_uploader_text", args=[domain,
                                                               app.id]),
            },
            'objectMap': app.get_object_map(),
            'sessionid': request.COOKIES.get('sessionid'),
        },
    }
    context.update({
        'vellum_options': vellum_options,
        'CKEDITOR_BASEPATH': "app_manager/js/vellum/lib/ckeditor/",
    })

    if not settings.VELLUM_DEBUG:
        context.update({'requirejs_url': "app_manager/js/vellum/src"})
    elif settings.VELLUM_DEBUG == "dev-min":
        context.update({'requirejs_url': "formdesigner/_build/src"})
    else:
        context.update({'requirejs_url': "formdesigner/src"})
    context.update({
        'requirejs_args':
        'version={}{}'.format(
            cachebuster("app_manager/js/vellum/src/main-components.js"),
            cachebuster("app_manager/js/vellum/src/local-deps.js")),
    })

    template = get_app_manager_template(
        request.user,
        'app_manager/v1/form_designer.html',
        'app_manager/v2/form_designer.html',
    )

    response = render(request, template, context)
    return response
Exemplo n.º 22
0
def form_designer(request, domain, app_id, module_id=None, form_id=None,
                  is_user_registration=False):
    meta = get_meta(request)
    track_entered_form_builder_on_hubspot.delay(request.couch_user, request.COOKIES, meta)

    app = get_app(domain, app_id)
    module = None

    if is_user_registration:
        form = app.get_user_registration()
    else:
        try:
            module = app.get_module(module_id)
        except ModuleNotFoundException:
            return bail(request, domain, app_id, not_found="module")
        try:
            form = module.get_form(form_id)
        except IndexError:
            return bail(request, domain, app_id, not_found="form")

    if form.no_vellum:
        messages.warning(request, _(
            "You tried to edit this form in the Form Builder. "
            "However, your administrator has locked this form against editing "
            "in the form builder, so we have redirected you to "
            "the form's front page instead."
        ))
        return back_to_main(request, domain, app_id=app_id,
                            unique_form_id=form.unique_id)

    vellum_plugins = ["modeliteration", "itemset"]
    if toggles.VELLUM_TRANSACTION_QUESTION_TYPES.enabled(domain):
        vellum_plugins.append("commtrack")
    if toggles.VELLUM_SAVE_TO_CASE.enabled(domain):
        vellum_plugins.append("saveToCase")
    if toggles.VELLUM_EXPERIMENTAL_UI.enabled(domain):
        vellum_plugins.append("databrowser")

    vellum_features = toggles.toggles_dict(username=request.user.username,
                                           domain=domain)
    vellum_features.update({
        'group_in_field_list': app.enable_group_in_field_list,
        'image_resize': app.enable_image_resize,
        'markdown_in_groups': app.enable_markdown_in_groups,
        'lookup_tables': domain_has_privilege(domain, privileges.LOOKUP_TABLES),
        'templated_intents': domain_has_privilege(domain, privileges.TEMPLATED_INTENTS),
        'custom_intents': domain_has_privilege(domain, privileges.CUSTOM_INTENTS),
    })

    has_schedule = (
        getattr(module, 'has_schedule', False) and
        getattr(form, 'schedule', False) and form.schedule.enabled
    )
    scheduler_data_nodes = []
    if has_schedule:
        scheduler_data_nodes = [
            SCHEDULE_CURRENT_VISIT_NUMBER,
            SCHEDULE_NEXT_DUE,
            SCHEDULE_UNSCHEDULED_VISIT,
            SCHEDULE_GLOBAL_NEXT_VISIT_DATE,
        ]
        scheduler_data_nodes.extend([
            u"next_{}".format(f.schedule_form_id)
            for f in form.get_phase().get_forms()
            if getattr(f, 'schedule', False) and f.schedule.enabled
        ])


    context = get_apps_base_context(request, domain, app)
    context.update(locals())
    context.update({
        'vellum_debug': settings.VELLUM_DEBUG,
        'nav_form': form if not is_user_registration else '',
        'formdesigner': True,
        'multimedia_object_map': app.get_object_map(),
        'sessionid': request.COOKIES.get('sessionid'),
        'features': vellum_features,
        'plugins': vellum_plugins,
        'app_callout_templates': next(app_callout_templates),
        'scheduler_data_nodes': scheduler_data_nodes,
    })
    return render(request, 'app_manager/form_designer.html', context)
Exemplo n.º 23
0
 def post(self, request, *args, **kwargs):
     meta = get_meta(request)
     track_clicked_deploy_on_hubspot.delay(request.couch_user,
                                           request.COOKIES, meta)
     return HttpResponse()
Exemplo n.º 24
0
    def __call__(self, request, invitation_id, **kwargs):
        logging.info(
            "Don't use this view in more apps until it gets cleaned up.")
        # add the correct parameters to this instance
        self.request = request
        self.inv_id = invitation_id
        if 'domain' in kwargs:
            self.domain = kwargs['domain']

        if request.GET.get('switch') == 'true':
            logout(request)
            return redirect_to_login(request.path)
        if request.GET.get('create') == 'true':
            logout(request)
            return HttpResponseRedirect(request.path)

        try:
            invitation = Invitation.get(invitation_id)
        except ResourceNotFound:
            messages.error(
                request,
                _("Sorry, it looks like your invitation has expired. "
                  "Please check the invitation link you received and try again, or request a "
                  "project administrator to send you the invitation again."))
            return HttpResponseRedirect(reverse("login"))
        if invitation.is_accepted:
            messages.error(
                request,
                _("Sorry, that invitation has already been used up. "
                  "If you feel this is a mistake please ask the inviter for "
                  "another invitation."))
            return HttpResponseRedirect(reverse("login"))

        self.validate_invitation(invitation)

        if invitation.is_expired:
            return HttpResponseRedirect(reverse("no_permissions"))

        # Add zero-width space to username for better line breaking
        username = self.request.user.username.replace("@", "​@")
        context = {
            'create_domain': False,
            'formatted_username': username,
            'domain': self.domain,
            'invite_to': self.domain,
            'invite_type': _('Project'),
            'hide_password_feedback':
            settings.ENABLE_DRACONIAN_SECURITY_FEATURES,
        }
        if request.user.is_authenticated:
            context['current_page'] = {'page_name': _('Project Invitation')}
        else:
            context['current_page'] = {
                'page_name': _('Project Invitation, Account Required')
            }
        if request.user.is_authenticated():
            is_invited_user = request.couch_user.username.lower(
            ) == invitation.email.lower()
            if self.is_invited(invitation, request.couch_user
                               ) and not request.couch_user.is_superuser:
                if is_invited_user:
                    # if this invite was actually for this user, just mark it accepted
                    messages.info(
                        request,
                        _("You are already a member of {entity}.").format(
                            entity=self.inviting_entity))
                    invitation.is_accepted = True
                    invitation.save()
                else:
                    messages.error(
                        request,
                        _("It looks like you are trying to accept an invitation for "
                          "{invited} but you are already a member of {entity} with the "
                          "account {current}. Please sign out to accept this invitation "
                          "as another user.").format(
                              entity=self.inviting_entity,
                              invited=invitation.email,
                              current=request.couch_user.username,
                          ))
                return HttpResponseRedirect(self.redirect_to_on_success)

            if not is_invited_user:
                messages.error(
                    request,
                    _("The invited user {invited} and your user {current} do not match!"
                      ).format(invited=invitation.email,
                               current=request.couch_user.username))

            if request.method == "POST":
                couch_user = CouchUser.from_django_user(request.user)
                self._invite(invitation, couch_user)
                track_workflow(
                    request.couch_user.get_email(),
                    "Current user accepted a project invitation",
                    {"Current user accepted a project invitation": "yes"})
                meta = get_meta(request)
                track_existing_user_accepted_invite_on_hubspot.delay(
                    request.couch_user, request.COOKIES, meta)
                return HttpResponseRedirect(self.redirect_to_on_success)
            else:
                mobile_user = CouchUser.from_django_user(
                    request.user).is_commcare_user()
                context.update({
                    'mobile_user':
                    mobile_user,
                    "invited_user":
                    invitation.email
                    if request.couch_user.username != invitation.email else "",
                })
                return render(request, self.template, context)
        else:
            if request.method == "POST":
                form = WebUserInvitationForm(request.POST)
                if form.is_valid():
                    # create the new user
                    user = activate_new_user(form, domain=invitation.domain)
                    user.save()
                    messages.success(
                        request,
                        _("User account for %s created!") %
                        form.cleaned_data["email"])
                    self._invite(invitation, user)
                    authenticated = authenticate(
                        username=form.cleaned_data["email"],
                        password=form.cleaned_data["password"])
                    if authenticated is not None and authenticated.is_active:
                        login(request, authenticated)
                    track_workflow(
                        request.POST['email'],
                        "New User Accepted a project invitation",
                        {"New User Accepted a project invitation": "yes"})
                    meta = get_meta(request)
                    track_new_user_accepted_invite_on_hubspot.delay(
                        user, request.COOKIES, meta)
                    return HttpResponseRedirect(
                        reverse("domain_homepage", args=[invitation.domain]))
            else:
                if CouchUser.get_by_username(invitation.email):
                    return HttpResponseRedirect(
                        reverse("login") + '?next=' +
                        reverse('domain_accept_invitation',
                                args=[invitation.domain, invitation.get_id]))
                form = WebUserInvitationForm(
                    initial={
                        'email': invitation.email,
                        'hr_name': invitation.domain,
                        'create_domain': False,
                    })

        context.update({"form": form})
        return render(request, self.template, context)
Exemplo n.º 25
0
def _get_form_designer_view(request, domain, app, module, form):
    if form.no_vellum:
        messages.warning(
            request,
            _("You tried to edit this form in the Form Builder. "
              "However, your administrator has locked this form against editing "
              "in the form builder, so we have redirected you to "
              "the form's front page instead."))
        return back_to_main(request,
                            domain,
                            app_id=app.id,
                            form_unique_id=form.unique_id)

    track_entered_form_builder_on_hubspot.delay(request.couch_user,
                                                request.COOKIES,
                                                get_meta(request))

    def _form_too_large(_app, _form):
        # form less than 0.1MB, anything larger starts to have
        # performance issues with fullstory
        return _app.blobs['{}.xml'.format(
            _form.unique_id)]['content_length'] > 102400

    context = get_apps_base_context(request, domain, app)
    context.update(locals())

    vellum_options = _get_base_vellum_options(request, domain, app,
                                              context['lang'])
    vellum_options['core'] = _get_vellum_core_context(request, domain, app,
                                                      module, form)
    vellum_options['plugins'] = _get_vellum_plugins(domain, form, module)
    vellum_options['features'] = _get_vellum_features(request, domain, app)
    context['vellum_options'] = vellum_options

    context.update({
        'vellum_debug':
        settings.VELLUM_DEBUG,
        'nav_form':
        form,
        'formdesigner':
        True,
        'include_fullstory':
        not _form_too_large(app, form),
        'CKEDITOR_BASEPATH':
        "app_manager/js/vellum/lib/ckeditor/",
        'show_live_preview':
        should_show_preview_app(
            request,
            app,
            request.couch_user.username,
        ),
    })
    context.update(_get_requirejs_context())
    context['current_app_version_url'] = reverse('current_app_version',
                                                 args=[domain, app.id])

    if request.user.is_superuser:
        context.update({
            'notification_options':
            _get_notification_options(request, domain, app, form)
        })

    notify_form_opened(domain, request.couch_user, app.id, form.unique_id)

    return render(request, "app_manager/form_designer.html", context)
Exemplo n.º 26
0
    def get(self, request, domain, urlPath):
        try:
            preview = string_to_boolean(request.GET.get("preview", "false"))
        except ValueError:
            # this is typically only set at all if it's intended to be true so this
            # is a reasonable default for "something went wrong"
            preview = True

        app_access = ApplicationAccess.get_by_domain(domain)
        accessor = CaseAccessors(domain)

        if not preview:
            apps = get_cloudcare_apps(domain)
            if request.project.use_cloudcare_releases:

                if (toggles.CLOUDCARE_LATEST_BUILD.enabled(domain)
                        or toggles.CLOUDCARE_LATEST_BUILD.enabled(
                            request.couch_user.username)):
                    get_cloudcare_app = get_latest_build_doc
                else:
                    get_cloudcare_app = get_latest_released_app_doc

                apps = map(
                    lambda app: get_cloudcare_app(domain, app['_id']),
                    apps,
                )
                apps = filter(None, apps)
                apps = map(wrap_app, apps)

                # convert to json
                apps = [get_app_json(app) for app in apps]
            else:
                # legacy functionality - use the latest build regardless of stars
                apps = [
                    get_latest_build_doc(domain, app['_id']) for app in apps
                ]
                apps = [
                    get_app_json(ApplicationBase.wrap(app)) for app in apps
                    if app
                ]

        else:
            # big TODO: write a new apps view for Formplayer, can likely cut most out now
            if toggles.USE_FORMPLAYER_FRONTEND.enabled(domain):
                apps = get_cloudcare_apps(domain)
            else:
                apps = get_brief_apps_in_domain(domain)
            apps = [
                get_app_json(app) for app in apps if app and
                (isinstance(app, RemoteApp) or app.application_version == V2)
            ]
            meta = get_meta(request)
            track_clicked_preview_on_hubspot(request.couch_user,
                                             request.COOKIES, meta)

        # trim out empty apps
        apps = filter(lambda app: app, apps)
        apps = filter(
            lambda app: app_access.user_can_access_app(request.couch_user, app
                                                       ), apps)

        def _default_lang():
            if apps:
                # unfortunately we have to go back to the DB to find this
                return Application.get(apps[0]["_id"]).default_language
            else:
                return "en"

        # default language to user's preference, followed by
        # first app's default, followed by english
        language = request.couch_user.language or _default_lang()

        def _url_context():
            # given a url path, returns potentially the app, parent, and case, if
            # they're selected. the front end optimizes with these to avoid excess
            # server calls

            # there's an annoying dependency between this logic and backbone's
            # url routing that seems hard to solve well. this needs to be synced
            # with apps.js if anything changes

            # for apps anything with "view/app/" works

            # for cases it will be:
            # "view/:app/:module/:form/case/:case/"

            # if there are parent cases, it will be:
            # "view/:app/:module/:form/parent/:parent/case/:case/

            # could use regex here but this is actually simpler with the potential
            # absence of a trailing slash
            split = urlPath.split('/')
            app_id = split[1] if len(split) >= 2 else None

            if len(split) >= 5 and split[4] == "parent":
                parent_id = split[5]
                case_id = split[7] if len(split) >= 7 else None
            else:
                parent_id = None
                case_id = split[5] if len(split) >= 6 else None

            app = None
            if app_id:
                if app_id in [a['_id'] for a in apps]:
                    app = look_up_app_json(domain, app_id)
                else:
                    messages.info(
                        request,
                        _("That app is no longer valid. Try using the "
                          "navigation links to select an app."))
            if app is None and len(apps) == 1:
                app = look_up_app_json(domain, apps[0]['_id'])

            def _get_case(domain, case_id):
                case = accessor.get_case(case_id)
                assert case.domain == domain, "case %s not in %s" % (case_id,
                                                                     domain)
                return case.to_api_json()

            case = _get_case(domain, case_id) if case_id else None
            if parent_id is None and case is not None:
                parent_id = case.get('indices',
                                     {}).get('parent',
                                             {}).get('case_id', None)
Exemplo n.º 27
0
    def get(self, request, domain, urlPath):
        try:
            preview = string_to_boolean(request.GET.get("preview", "false"))
        except ValueError:
            # this is typically only set at all if it's intended to be true so this
            # is a reasonable default for "something went wrong"
            preview = True

        app_access = ApplicationAccess.get_by_domain(domain)
        accessor = CaseAccessors(domain)

        if not preview:
            apps = get_cloudcare_apps(domain)
            if request.project.use_cloudcare_releases:

                if (toggles.CLOUDCARE_LATEST_BUILD.enabled(domain) or
                        toggles.CLOUDCARE_LATEST_BUILD.enabled(request.couch_user.username)):
                    get_cloudcare_app = get_latest_build_doc
                else:
                    get_cloudcare_app = get_latest_released_app_doc

                apps = map(
                    lambda app: get_cloudcare_app(domain, app['_id']),
                    apps,
                )
                apps = filter(None, apps)
                apps = map(wrap_app, apps)

                # convert to json
                apps = [get_app_json(app) for app in apps]
            else:
                # legacy functionality - use the latest build regardless of stars
                apps = [get_latest_build_doc(domain, app['_id']) for app in apps]
                apps = [get_app_json(ApplicationBase.wrap(app)) for app in apps if app]

        else:
            # big TODO: write a new apps view for Formplayer, can likely cut most out now
            if toggles.USE_FORMPLAYER_FRONTEND.enabled(domain):
                apps = get_cloudcare_apps(domain)
            else:
                apps = get_brief_apps_in_domain(domain)
            apps = [get_app_json(app) for app in apps if app and (
                isinstance(app, RemoteApp) or app.application_version == V2)]
            meta = get_meta(request)
            track_clicked_preview_on_hubspot(request.couch_user, request.COOKIES, meta)

        # trim out empty apps
        apps = filter(lambda app: app, apps)
        apps = filter(lambda app: app_access.user_can_access_app(request.couch_user, app), apps)

        def _default_lang():
            if apps:
                # unfortunately we have to go back to the DB to find this
                return Application.get(apps[0]["_id"]).default_language
            else:
                return "en"

        # default language to user's preference, followed by
        # first app's default, followed by english
        language = request.couch_user.language or _default_lang()

        def _url_context():
            # given a url path, returns potentially the app, parent, and case, if
            # they're selected. the front end optimizes with these to avoid excess
            # server calls

            # there's an annoying dependency between this logic and backbone's
            # url routing that seems hard to solve well. this needs to be synced
            # with apps.js if anything changes

            # for apps anything with "view/app/" works

            # for cases it will be:
            # "view/:app/:module/:form/case/:case/"

            # if there are parent cases, it will be:
            # "view/:app/:module/:form/parent/:parent/case/:case/

            # could use regex here but this is actually simpler with the potential
            # absence of a trailing slash
            split = urlPath.split('/')
            app_id = split[1] if len(split) >= 2 else None

            if len(split) >= 5 and split[4] == "parent":
                parent_id = split[5]
                case_id = split[7] if len(split) >= 7 else None
            else:
                parent_id = None
                case_id = split[5] if len(split) >= 6 else None

            app = None
            if app_id:
                if app_id in [a['_id'] for a in apps]:
                    app = look_up_app_json(domain, app_id)
                else:
                    messages.info(request, _("That app is no longer valid. Try using the "
                                             "navigation links to select an app."))
            if app is None and len(apps) == 1:
                app = look_up_app_json(domain, apps[0]['_id'])

            def _get_case(domain, case_id):
                case = accessor.get_case(case_id)
                assert case.domain == domain, "case %s not in %s" % (case_id, domain)
                return case.to_api_json()

            case = _get_case(domain, case_id) if case_id else None
            if parent_id is None and case is not None:
                parent_id = case.get('indices', {}).get('parent', {}).get('case_id', None)
            parent = _get_case(domain, parent_id) if parent_id else None

            return {
                "app": app,
                "case": case,
                "parent": parent
            }

        context = {
            "domain": domain,
            "language": language,
            "apps": apps,
            "apps_raw": apps,
            "preview": preview,
            "maps_api_key": settings.GMAPS_API_KEY,
            "sessions_enabled": request.couch_user.is_commcare_user(),
            "use_cloudcare_releases": request.project.use_cloudcare_releases,
            "username": request.user.username,
            "formplayer_url": settings.FORMPLAYER_URL,
            'use_sqlite_backend': use_sqlite_backend(domain),
        }
        context.update(_url_context())
        if toggles.USE_FORMPLAYER_FRONTEND.enabled(domain):
            return render(request, "cloudcare/formplayer_home.html", context)
        else:
            return render(request, "cloudcare/cloudcare_home.html", context)
Exemplo n.º 28
0
def form_designer(request, domain, app_id, module_id=None, form_id=None):

    def _form_uses_case(module, form):
        return module and module.case_type and form.requires_case()

    def _form_is_basic(form):
        return form.doc_type == 'Form'

    def _form_too_large(app, form):
        # form less than 0.1MB, anything larger starts to have
        # performance issues with fullstory
        return app.blobs['{}.xml'.format(form.unique_id)]['content_length'] > 102400

    meta = get_meta(request)
    track_entered_form_builder_on_hubspot.delay(request.couch_user, request.COOKIES, meta)

    app = get_app(domain, app_id)
    module = None

    try:
        module = app.get_module(module_id)
    except ModuleNotFoundException:
        return bail(request, domain, app_id, not_found="module")
    try:
        form = module.get_form(form_id)
    except IndexError:
        return bail(request, domain, app_id, not_found="form")

    if form.no_vellum:
        messages.warning(request, _(
            "You tried to edit this form in the Form Builder. "
            "However, your administrator has locked this form against editing "
            "in the form builder, so we have redirected you to "
            "the form's front page instead."
        ))
        return back_to_main(request, domain, app_id=app_id,
                            unique_form_id=form.unique_id)

    include_fullstory = False
    vellum_plugins = ["modeliteration", "itemset", "atwho"]
    if (toggles.COMMTRACK.enabled(domain)):
        vellum_plugins.append("commtrack")
    if toggles.VELLUM_SAVE_TO_CASE.enabled(domain):
        vellum_plugins.append("saveToCase")
    if (_form_uses_case(module, form) and _form_is_basic(form)):
        vellum_plugins.append("databrowser")

    vellum_features = toggles.toggles_dict(username=request.user.username,
                                           domain=domain)
    vellum_features.update(feature_previews.previews_dict(domain))
    include_fullstory = not _form_too_large(app, form)
    vellum_features.update({
        'group_in_field_list': app.enable_group_in_field_list,
        'image_resize': app.enable_image_resize,
        'markdown_in_groups': app.enable_markdown_in_groups,
        'lookup_tables': domain_has_privilege(domain, privileges.LOOKUP_TABLES),
        'templated_intents': domain_has_privilege(domain, privileges.TEMPLATED_INTENTS),
        'custom_intents': domain_has_privilege(domain, privileges.CUSTOM_INTENTS),
        'rich_text': True,
    })

    has_schedule = (
        getattr(module, 'has_schedule', False) and
        getattr(form, 'schedule', False) and form.schedule.enabled
    )
    scheduler_data_nodes = []
    if has_schedule:
        scheduler_data_nodes = [
            SCHEDULE_CURRENT_VISIT_NUMBER,
            SCHEDULE_NEXT_DUE,
            SCHEDULE_UNSCHEDULED_VISIT,
            SCHEDULE_GLOBAL_NEXT_VISIT_DATE,
        ]
        scheduler_data_nodes.extend([
            u"next_{}".format(f.schedule_form_id)
            for f in form.get_phase().get_forms()
            if getattr(f, 'schedule', False) and f.schedule.enabled
        ])

    if tours.VELLUM_CASE_MANAGEMENT.is_enabled(request.user) and form.requires_case():
        request.guided_tour = tours.VELLUM_CASE_MANAGEMENT.get_tour_data()

    context = get_apps_base_context(request, domain, app)
    context.update(locals())
    context.update({
        'vellum_debug': settings.VELLUM_DEBUG,
        'nav_form': form,
        'formdesigner': True,
        'multimedia_object_map': app.get_object_map(),
        'sessionid': request.COOKIES.get('sessionid'),
        'features': vellum_features,
        'plugins': vellum_plugins,
        'app_callout_templates': next(app_callout_templates),
        'scheduler_data_nodes': scheduler_data_nodes,
        'include_fullstory': include_fullstory,
        'notifications_enabled': request.user.is_superuser,
        'notify_facility': get_facility_for_form(domain, app_id, form.unique_id),
    })
    notify_form_opened(domain, request.couch_user, app_id, form.unique_id)

    live_preview_ab = ab_tests.ABTest(ab_tests.LIVE_PREVIEW, request)
    domain_obj = Domain.get_by_name(domain)
    context.update({
        'live_preview_ab': live_preview_ab.context,
        'is_onboarding_domain': domain_obj.is_onboarding_domain,
        'show_live_preview': (
            toggles.PREVIEW_APP.enabled(domain)
            or toggles.PREVIEW_APP.enabled(request.couch_user.username)
            or (domain_obj.is_onboarding_domain
                and live_preview_ab.version == ab_tests.LIVE_PREVIEW_ENABLED)
        )
    })

    response = render(request, 'app_manager/v1/form_designer.html', context)
    live_preview_ab.update_response(response)
    return response
Exemplo n.º 29
0
 def post(self, request, *args, **kwargs):
     meta = get_meta(request)
     track_clicked_deploy_on_hubspot_v2.delay(request.couch_user, request.COOKIES.get(HUBSPOT_COOKIE), meta)
     return HttpResponse()
Exemplo n.º 30
0
def request_new_domain(request, form, is_new_user=True):
    now = datetime.utcnow()
    current_user = CouchUser.from_django_user(request.user)

    dom_req = RegistrationRequest()
    if is_new_user:
        dom_req.request_time = now
        dom_req.request_ip = get_ip(request)
        dom_req.activation_guid = uuid.uuid1().hex

    project_name = form.cleaned_data.get('hr_name') or form.cleaned_data.get(
        'project_name')
    name = name_to_url(project_name, "project")
    with CriticalSection(['request_domain_name_{}'.format(name)]):
        name = Domain.generate_name(name)
        new_domain = Domain(name=name,
                            hr_name=project_name,
                            is_active=False,
                            date_created=datetime.utcnow(),
                            creating_user=current_user.username,
                            secure_submissions=True,
                            use_sql_backend=True,
                            first_domain_for_user=is_new_user)

        if form.cleaned_data.get('domain_timezone'):
            new_domain.default_timezone = form.cleaned_data['domain_timezone']

        if not is_new_user:
            new_domain.is_active = True

        # ensure no duplicate domain documents get created on cloudant
        new_domain.save(**get_safe_write_kwargs())

    if not new_domain.name:
        new_domain.name = new_domain._id
        new_domain.save()  # we need to get the name from the _id

    if is_new_user:
        # Only new-user domains are eligible for Advanced trial
        # domains with no subscription are equivalent to be on free Community plan
        create_30_day_advanced_trial(new_domain, current_user.username)
    else:
        ensure_explicit_community_subscription(new_domain.name, date.today())

    UserRole.init_domain_with_presets(new_domain.name)

    # add user's email as contact email for billing account for the domain
    account = BillingAccount.get_account_by_domain(new_domain.name)
    billing_contact, _ = BillingContactInfo.objects.get_or_create(
        account=account)
    billing_contact.email_list = [current_user.email]
    billing_contact.save()

    dom_req.domain = new_domain.name

    if request.user.is_authenticated():
        if not current_user:
            current_user = WebUser()
            current_user.sync_from_django_user(request.user)
            current_user.save()
        current_user.add_domain_membership(new_domain.name, is_admin=True)
        current_user.save()
        dom_req.requesting_user_username = request.user.username
        dom_req.new_user_username = request.user.username

    if is_new_user:
        dom_req.save()
        send_domain_registration_email(request.user.email, dom_req.domain,
                                       dom_req.activation_guid,
                                       request.user.get_full_name())
    send_new_request_update_email(request.user,
                                  get_ip(request),
                                  new_domain.name,
                                  is_new_user=is_new_user)

    meta = get_meta(request)
    track_created_new_project_space_on_hubspot.delay(current_user,
                                                     request.COOKIES, meta)
    return new_domain.name
Exemplo n.º 31
0
def request_new_domain(request, form, is_new_user=True):
    now = datetime.utcnow()
    current_user = CouchUser.from_django_user(request.user)

    dom_req = RegistrationRequest()
    if is_new_user:
        dom_req.request_time = now
        dom_req.request_ip = get_ip(request)
        dom_req.activation_guid = uuid.uuid1().hex

    name = name_to_url(form.cleaned_data['hr_name'], "project")
    with CriticalSection(['request_domain_name_{}'.format(name)]):
        name = Domain.generate_name(name)
        new_domain = Domain(
            name=name,
            hr_name=form.cleaned_data['hr_name'],
            is_active=False,
            date_created=datetime.utcnow(),
            creating_user=current_user.username,
            secure_submissions=True,
        )

        if form.cleaned_data.get('domain_timezone'):
            new_domain.default_timezone = form.cleaned_data['domain_timezone']

        if not is_new_user:
            new_domain.is_active = True

        force_sql_backed = getattr(settings, 'NEW_DOMAINS_USE_SQL_BACKEND', False)
        if force_sql_backed or current_user.is_superuser and form.cleaned_data.get('use_new_backend') == ['yes']:
            enable_toggles_for_scale_beta(new_domain.name)

        # ensure no duplicate domain documents get created on cloudant
        new_domain.save(**get_safe_write_kwargs())

    if not new_domain.name:
        new_domain.name = new_domain._id
        new_domain.save()  # we need to get the name from the _id

    if is_new_user:
        # Only new-user domains are eligible for Advanced trial
        # domains with no subscription are equivalent to be on free Community plan
        create_30_day_advanced_trial(new_domain)

    UserRole.init_domain_with_presets(new_domain.name)

    dom_req.domain = new_domain.name

    if request.user.is_authenticated():
        if not current_user:
            current_user = WebUser()
            current_user.sync_from_django_user(request.user)
            current_user.save()
        current_user.add_domain_membership(new_domain.name, is_admin=True)
        current_user.save()
        dom_req.requesting_user_username = request.user.username
        dom_req.new_user_username = request.user.username

    if is_new_user:
        dom_req.save()
        send_domain_registration_email(request.user.email,
                                       dom_req.domain,
                                       dom_req.activation_guid,
                                       request.user.get_full_name())
    send_new_request_update_email(request.user, get_ip(request), new_domain.name, is_new_user=is_new_user)

    meta = get_meta(request)
    track_created_new_project_space_on_hubspot.delay(current_user, request.COOKIES, meta)
    return new_domain.name
Exemplo n.º 32
0
    def __call__(self, request, invitation_id, **kwargs):
        logging.info("Don't use this view in more apps until it gets cleaned up.")
        # add the correct parameters to this instance
        self.request = request
        self.inv_id = invitation_id
        if 'domain' in kwargs:
            self.domain = kwargs['domain']

        if request.GET.get('switch') == 'true':
            logout(request)
            return redirect_to_login(request.path)
        if request.GET.get('create') == 'true':
            logout(request)
            return HttpResponseRedirect(request.path)

        try:
            invitation = Invitation.get(invitation_id)
        except ResourceNotFound:
            messages.error(request, _("Sorry, it looks like your invitation has expired. "
                                      "Please check the invitation link you received and try again, or request a "
                                      "project administrator to send you the invitation again."))
            return HttpResponseRedirect(reverse("login"))
        if invitation.is_accepted:
            messages.error(request, _("Sorry, that invitation has already been used up. "
                                      "If you feel this is a mistake please ask the inviter for "
                                      "another invitation."))
            return HttpResponseRedirect(reverse("login"))

        self.validate_invitation(invitation)

        if invitation.is_expired:
            return HttpResponseRedirect(reverse("no_permissions"))

        # Add zero-width space to username for better line breaking
        username = self.request.user.username.replace("@", "​@")
        context = {
            'create_domain': False,
            'formatted_username': username,
            'domain': self.domain,
            'invite_to': self.domain,
            'invite_type': _('Project'),
            'hide_password_feedback': settings.ENABLE_DRACONIAN_SECURITY_FEATURES,
        }
        if request.user.is_authenticated:
            context['current_page'] = {'page_name': _('Project Invitation')}
        else:
            context['current_page'] = {'page_name': _('Project Invitation, Account Required')}
        if request.user.is_authenticated():
            is_invited_user = request.couch_user.username.lower() == invitation.email.lower()
            if self.is_invited(invitation, request.couch_user) and not request.couch_user.is_superuser:
                if is_invited_user:
                    # if this invite was actually for this user, just mark it accepted
                    messages.info(request, _("You are already a member of {entity}.").format(
                        entity=self.inviting_entity))
                    invitation.is_accepted = True
                    invitation.save()
                else:
                    messages.error(request, _("It looks like you are trying to accept an invitation for "
                                             "{invited} but you are already a member of {entity} with the "
                                             "account {current}. Please sign out to accept this invitation "
                                             "as another user.").format(
                                                 entity=self.inviting_entity,
                                                 invited=invitation.email,
                                                 current=request.couch_user.username,
                                             ))
                return HttpResponseRedirect(self.redirect_to_on_success)

            if not is_invited_user:
                messages.error(request, _("The invited user {invited} and your user {current} do not match!").format(
                    invited=invitation.email, current=request.couch_user.username))

            if request.method == "POST":
                couch_user = CouchUser.from_django_user(request.user)
                self._invite(invitation, couch_user)
                track_workflow(request.couch_user.get_email(),
                               "Current user accepted a project invitation",
                               {"Current user accepted a project invitation": "yes"})
                meta = get_meta(request)
                track_existing_user_accepted_invite_on_hubspot.delay(request.couch_user, request.COOKIES, meta)
                return HttpResponseRedirect(self.redirect_to_on_success)
            else:
                mobile_user = CouchUser.from_django_user(request.user).is_commcare_user()
                context.update({
                    'mobile_user': mobile_user,
                    "invited_user": invitation.email if request.couch_user.username != invitation.email else "",
                })
                return render(request, self.template, context)
        else:
            if request.method == "POST":
                form = WebUserInvitationForm(request.POST)
                if form.is_valid():
                    # create the new user
                    user = activate_new_user(form, domain=invitation.domain)
                    user.save()
                    messages.success(request, _("User account for %s created!") % form.cleaned_data["email"])
                    self._invite(invitation, user)
                    authenticated = authenticate(username=form.cleaned_data["email"],
                                                 password=form.cleaned_data["password"])
                    if authenticated is not None and authenticated.is_active:
                        login(request, authenticated)
                    track_workflow(request.POST['email'],
                                   "New User Accepted a project invitation",
                                   {"New User Accepted a project invitation": "yes"})
                    meta = get_meta(request)
                    track_new_user_accepted_invite_on_hubspot.delay(user, request.COOKIES, meta)
                    return HttpResponseRedirect(reverse("domain_homepage", args=[invitation.domain]))
            else:
                if CouchUser.get_by_username(invitation.email):
                    return HttpResponseRedirect(reverse("login") + '?next=' +
                        reverse('domain_accept_invitation', args=[invitation.domain, invitation.get_id]))
                form = WebUserInvitationForm(initial={
                    'email': invitation.email,
                    'hr_name': invitation.domain,
                    'create_domain': False,
                })

        context.update({"form": form})
        return render(request, self.template, context)
Exemplo n.º 33
0
def request_new_domain(request, form, is_new_user=True):
    now = datetime.utcnow()
    current_user = CouchUser.from_django_user(request.user)

    dom_req = RegistrationRequest()
    if is_new_user:
        dom_req.request_time = now
        dom_req.request_ip = get_ip(request)
        dom_req.activation_guid = uuid.uuid1().hex

    project_name = form.cleaned_data.get('hr_name') or form.cleaned_data.get('project_name')
    name = name_to_url(project_name, "project")
    with CriticalSection(['request_domain_name_{}'.format(name)]):
        name = Domain.generate_name(name)
        new_domain = Domain(
            name=name,
            hr_name=project_name,
            is_active=False,
            date_created=datetime.utcnow(),
            creating_user=current_user.username,
            secure_submissions=True,
            use_sql_backend=True,
            first_domain_for_user=is_new_user
        )

        if form.cleaned_data.get('domain_timezone'):
            new_domain.default_timezone = form.cleaned_data['domain_timezone']

        if not is_new_user:
            new_domain.is_active = True

        # ensure no duplicate domain documents get created on cloudant
        new_domain.save(**get_safe_write_kwargs())

    if not new_domain.name:
        new_domain.name = new_domain._id
        new_domain.save()  # we need to get the name from the _id

    if is_new_user:
        # Only new-user domains are eligible for Advanced trial
        # domains with no subscription are equivalent to be on free Community plan
        create_30_day_advanced_trial(new_domain, current_user.username)
    else:
        ensure_explicit_community_subscription(new_domain.name, date.today())

    UserRole.init_domain_with_presets(new_domain.name)

    dom_req.domain = new_domain.name

    if request.user.is_authenticated():
        if not current_user:
            current_user = WebUser()
            current_user.sync_from_django_user(request.user)
            current_user.save()
        current_user.add_domain_membership(new_domain.name, is_admin=True)
        current_user.save()
        dom_req.requesting_user_username = request.user.username
        dom_req.new_user_username = request.user.username

    if is_new_user:
        dom_req.save()
        send_domain_registration_email(request.user.email,
                                       dom_req.domain,
                                       dom_req.activation_guid,
                                       request.user.get_full_name())
    send_new_request_update_email(request.user, get_ip(request), new_domain.name, is_new_user=is_new_user)

    set_toggle(toggles.USE_FORMPLAYER_FRONTEND.slug, new_domain.name, True, namespace=toggles.NAMESPACE_DOMAIN)
    meta = get_meta(request)
    track_created_new_project_space_on_hubspot.delay(current_user, request.COOKIES, meta)
    return new_domain.name
Exemplo n.º 34
0
def form_designer(request, domain, app_id, module_id=None, form_id=None):
    def _form_uses_case(module, form):
        return module and module.case_type and form.requires_case()

    def _form_is_basic(form):
        return form.doc_type == 'Form'

    def _form_too_large(app, form):
        # form less than 0.1MB, anything larger starts to have
        # performance issues with fullstory
        return app.blobs['{}.xml'.format(
            form.unique_id)]['content_length'] > 102400

    meta = get_meta(request)
    track_entered_form_builder_on_hubspot.delay(request.couch_user,
                                                request.COOKIES, meta)

    app = get_app(domain, app_id)
    module = None

    try:
        module = app.get_module(module_id)
    except ModuleNotFoundException:
        return bail(request, domain, app_id, not_found="module")
    try:
        form = module.get_form(form_id)
    except IndexError:
        return bail(request, domain, app_id, not_found="form")

    if form.no_vellum:
        messages.warning(
            request,
            _("You tried to edit this form in the Form Builder. "
              "However, your administrator has locked this form against editing "
              "in the form builder, so we have redirected you to "
              "the form's front page instead."))
        return back_to_main(request,
                            domain,
                            app_id=app_id,
                            unique_form_id=form.unique_id)

    include_fullstory = False
    vellum_plugins = ["modeliteration", "itemset", "atwho"]
    if (toggles.COMMTRACK.enabled(domain)):
        vellum_plugins.append("commtrack")
    if toggles.VELLUM_SAVE_TO_CASE.enabled(domain):
        vellum_plugins.append("saveToCase")
    if (_form_uses_case(module, form) and _form_is_basic(form)):
        vellum_plugins.append("databrowser")

    vellum_features = toggles.toggles_dict(username=request.user.username,
                                           domain=domain)
    vellum_features.update(feature_previews.previews_dict(domain))
    include_fullstory = not _form_too_large(app, form)
    vellum_features.update({
        'group_in_field_list':
        app.enable_group_in_field_list,
        'image_resize':
        app.enable_image_resize,
        'markdown_in_groups':
        app.enable_markdown_in_groups,
        'lookup_tables':
        domain_has_privilege(domain, privileges.LOOKUP_TABLES),
        'templated_intents':
        domain_has_privilege(domain, privileges.TEMPLATED_INTENTS),
        'custom_intents':
        domain_has_privilege(domain, privileges.CUSTOM_INTENTS),
        'rich_text':
        True,
    })

    has_schedule = (getattr(module, 'has_schedule', False)
                    and getattr(form, 'schedule', False)
                    and form.schedule.enabled)
    scheduler_data_nodes = []
    if has_schedule:
        scheduler_data_nodes = [
            SCHEDULE_CURRENT_VISIT_NUMBER,
            SCHEDULE_NEXT_DUE,
            SCHEDULE_UNSCHEDULED_VISIT,
            SCHEDULE_GLOBAL_NEXT_VISIT_DATE,
        ]
        scheduler_data_nodes.extend([
            u"next_{}".format(f.schedule_form_id)
            for f in form.get_phase().get_forms()
            if getattr(f, 'schedule', False) and f.schedule.enabled
        ])

    if tours.VELLUM_CASE_MANAGEMENT.is_enabled(
            request.user) and form.requires_case():
        request.guided_tour = tours.VELLUM_CASE_MANAGEMENT.get_tour_data()

    vellum_base = 'corehq/apps/app_manager/static/app_manager/js/'
    vellum_dir = 'vellum'
    if isdir(join(vellum_base, 'vellum_beta')):
        vellum_dir = 'vellum_beta'

    context = get_apps_base_context(request, domain, app)
    context.update(locals())
    context.update({
        'vellum_debug':
        settings.VELLUM_DEBUG,
        'nav_form':
        form,
        'vellum_style_path':
        'app_manager/js/{}/style.css'.format(vellum_dir),
        'vellum_ckeditor_path':
        'app_manager/js/{}/lib/ckeditor/'.format(vellum_dir),
        'vellum_js_path':
        'app_manager/js/{}/src'.format(vellum_dir),
        'vellum_main_components_path':
        'app_manager/js/{}/src/main-components.js'.format(vellum_dir),
        'vellum_local_deps_path':
        'app_manager/js/{}/src/local-deps.js'.format(vellum_dir),
        'formdesigner':
        True,
        'multimedia_object_map':
        app.get_object_map(),
        'sessionid':
        request.COOKIES.get('sessionid'),
        'features':
        vellum_features,
        'plugins':
        vellum_plugins,
        'app_callout_templates':
        next(app_callout_templates),
        'scheduler_data_nodes':
        scheduler_data_nodes,
        'include_fullstory':
        include_fullstory,
        'notifications_enabled':
        request.user.is_superuser,
        'notify_facility':
        get_facility_for_form(domain, app_id, form.unique_id),
    })
    notify_form_opened(domain, request.couch_user, app_id, form.unique_id)

    domain_obj = Domain.get_by_name(domain)
    context.update({
        'show_live_preview':
        should_show_preview_app(
            request,
            app,
            request.couch_user.username,
        ),
        'can_preview_form':
        request.couch_user.has_permission(domain, 'edit_data')
    })

    template = get_app_manager_template(
        domain,
        'app_manager/v1/form_designer.html',
        'app_manager/v2/form_designer.html',
    )

    response = render(request, template, context)
    return response
Exemplo n.º 35
0
    def __call__(self, request, invitation_id, **kwargs):
        logging.warning("Don't use this view in more apps until it gets cleaned up.")
        # add the correct parameters to this instance
        self.request = request
        self.inv_id = invitation_id
        if "domain" in kwargs:
            self.domain = kwargs["domain"]

        if request.GET.get("switch") == "true":
            logout(request)
            return redirect_to_login(request.path)
        if request.GET.get("create") == "true":
            logout(request)
            return HttpResponseRedirect(request.path)

        try:
            invitation = Invitation.get(invitation_id)
        except ResourceNotFound:
            messages.error(
                request,
                _(
                    "Sorry, it looks like your invitation has expired. "
                    "Please check the invitation link you received and try again, or request a "
                    "project administrator to send you the invitation again."
                ),
            )
            return HttpResponseRedirect(reverse("login"))
        if invitation.is_accepted:
            messages.error(
                request,
                _(
                    "Sorry, that invitation has already been used up. "
                    "If you feel this is a mistake please ask the inviter for "
                    "another invitation."
                ),
            )
            return HttpResponseRedirect(reverse("login"))

        self.validate_invitation(invitation)

        if invitation.is_expired:
            return HttpResponseRedirect(reverse("no_permissions"))

        context = self.added_context()
        if request.user.is_authenticated():
            is_invited_user = request.couch_user.username.lower() == invitation.email.lower()
            if self.is_invited(invitation, request.couch_user) and not request.couch_user.is_superuser:
                if is_invited_user:
                    # if this invite was actually for this user, just mark it accepted
                    messages.info(
                        request, _("You are already a member of {entity}.").format(entity=self.inviting_entity)
                    )
                    invitation.is_accepted = True
                    invitation.save()
                else:
                    messages.error(
                        request,
                        _(
                            "It looks like you are trying to accept an invitation for "
                            "{invited} but you are already a member of {entity} with the "
                            "account {current}. Please sign out to accept this invitation "
                            "as another user."
                        ).format(
                            entity=self.inviting_entity, invited=invitation.email, current=request.couch_user.username
                        ),
                    )
                return HttpResponseRedirect(self.redirect_to_on_success)

            if not is_invited_user:
                messages.error(
                    request,
                    _("The invited user {invited} and your user {current} do not match!").format(
                        invited=invitation.email, current=request.couch_user.username
                    ),
                )

            if request.method == "POST":
                couch_user = CouchUser.from_django_user(request.user)
                self._invite(invitation, couch_user)
                track_workflow(
                    request.couch_user.get_email(),
                    "Current user accepted a project invitation",
                    {"Current user accepted a project invitation": "yes"},
                )
                meta = get_meta(request)
                track_existing_user_accepted_invite_on_hubspot.delay(request.couch_user, request.COOKIES, meta)
                return HttpResponseRedirect(self.redirect_to_on_success)
            else:
                mobile_user = CouchUser.from_django_user(request.user).is_commcare_user()
                context.update(
                    {
                        "mobile_user": mobile_user,
                        "invited_user": invitation.email if request.couch_user.username != invitation.email else "",
                    }
                )
                return render(request, self.template, context)
        else:
            if request.method == "POST":
                form = NewWebUserRegistrationForm(request.POST)
                if form.is_valid():
                    # create the new user
                    user = activate_new_user(form)
                    user.save()
                    messages.success(request, _("User account for %s created!") % form.cleaned_data["email"])
                    self._invite(invitation, user)
                    authenticated = authenticate(
                        username=form.cleaned_data["email"], password=form.cleaned_data["password"]
                    )
                    if authenticated is not None and authenticated.is_active:
                        login(request, authenticated)
                    track_workflow(
                        request.POST["email"],
                        "New User Accepted a project invitation",
                        {"New User Accepted a project invitation": "yes"},
                    )
                    meta = get_meta(request)
                    track_new_user_accepted_invite_on_hubspot.delay(user, request.COOKIES, meta)
                    return HttpResponseRedirect(reverse("domain_homepage", args=[invitation.domain]))
            else:
                if CouchUser.get_by_username(invitation.email):
                    return HttpResponseRedirect(
                        reverse("login")
                        + "?next="
                        + reverse("domain_accept_invitation", args=[invitation.domain, invitation.get_id])
                    )
                domain = Domain.get_by_name(invitation.domain)
                form = NewWebUserRegistrationForm(
                    initial={
                        "email": invitation.email,
                        "hr_name": domain.display_name() if domain else invitation.domain,
                        "create_domain": False,
                    }
                )

        context.update({"form": form})
        return render(request, self.template, context)