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]))
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()
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)
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)
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)
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)
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 )
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)
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]))
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)
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]))
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]))
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]))
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]))
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]))
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)
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)
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]))
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)
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
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)
def post(self, request, *args, **kwargs): meta = get_meta(request) track_clicked_deploy_on_hubspot.delay(request.couch_user, request.COOKIES, meta) return HttpResponse()
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)
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)
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)
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)
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
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()
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
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
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)
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
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
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)