def can_use_restore_as(request): if not hasattr(request, "couch_user"): return False return ( request.couch_user.can_edit_commcare_users() and has_privilege(request, privileges.DATA_CLEANUP) and has_privilege(request, privileges.CLOUDCARE) )
def permissions_check(self, report, request, domain=None, is_navigation_check=False): if is_navigation_check: from corehq.apps.case_importer.base import ImportCases from corehq.apps.data_interfaces.interfaces import BulkFormManagementInterface report_name = report.split('.')[-1] if report_name == ImportCases.__name__: if not has_privilege(request, privileges.BULK_CASE_MANAGEMENT): return False if report_name == BulkFormManagementInterface.__name__: if not has_privilege(request, privileges.DATA_CLEANUP): return False return request.couch_user.can_edit_data(domain)
def can_edit_locations_not_users(request): if not has_privilege(request, privileges.LOCATIONS): return False user = request.couch_user return not can_edit_users(request) and ( user.can_edit_locations() or user_can_edit_location_types(user, request.domain) )
def permissions_check(self, report, request, domain=None, is_navigation_check=False): if is_navigation_check: from corehq.apps.importer.base import ImportCases if report.split('.')[-1] in [ImportCases.__name__]: if not has_privilege(request, privileges.BULK_CASE_MANAGEMENT): return False return request.couch_user.can_edit_data(domain)
def page_context(self): context = { 'are_groups': bool(len(self.all_groups)), 'groups_url': reverse('all_groups', args=[self.domain]), 'group_form': self.group_form, 'reset_password_form': self.reset_password_form, 'is_currently_logged_in_user': self.is_currently_logged_in_user, 'data_fields_form': self.custom_data.form, 'can_use_inbound_sms': domain_has_privilege(self.domain, privileges.INBOUND_SMS), 'needs_to_downgrade_locations': ( users_have_locations(self.domain) and not has_privilege(self.request, privileges.LOCATIONS) ), 'demo_restore_date': naturaltime(demo_restore_date_created(self.editable_user)), 'hide_password_feedback': settings.ENABLE_DRACONIAN_SECURITY_FEATURES } if self.commtrack_form.errors: messages.error(self.request, _( "There were some errors while saving user's locations. Please check the 'Locations' tab" )) if self.domain_object.commtrack_enabled or self.domain_object.uses_locations: context.update({ 'commtrack_enabled': self.domain_object.commtrack_enabled, 'uses_locations': self.domain_object.uses_locations, 'commtrack': { 'update_form': self.commtrack_form, }, }) return context
def permissions_check(self, report, request, domain=None, is_navigation_check=False): if is_navigation_check: from corehq.apps.reports.standard.export import DeidExportReport if report.split('.')[-1] in [DeidExportReport.__name__]: if not has_privilege(request, privileges.DEIDENTIFIED_DATA): return False return super(DataInterfaceDispatcher, self).permissions_check(report, request, domain)
def has_report_builder_access(request): builder_enabled = toggle_enabled(request, toggles.REPORT_BUILDER) legacy_builder_priv = has_privilege(request, privileges.REPORT_BUILDER) beta_group_enabled = toggle_enabled(request, toggles.REPORT_BUILDER_BETA_GROUP) has_add_on_priv = has_report_builder_add_on_privilege(request) return (builder_enabled and legacy_builder_priv) or beta_group_enabled or has_add_on_priv
def main_context(self): context = super(BaseGroupsView, self).main_context context.update({ 'all_groups': self.all_groups, 'needs_to_downgrade_locations': ( users_have_locations(self.domain) and not has_privilege(self.request, privileges.LOCATIONS) ), }) return context
def permissions_check(self, report, request, domain=None, is_navigation_check=False): if is_navigation_check and not has_privilege(request, privileges.CUSTOM_REPORTS): return False if isinstance(request.couch_user, AnonymousCouchUser) and self.prefix == 'custom_project_report': reports = self.get_reports(domain) for section in reports: for report_class in section[1]: report_class_name = report_class.__module__ + '.' + report_class.__name__ if report_class_name == report and report_class.is_public: return True return super(CustomProjectReportDispatcher, self).permissions_check(report, request, domain)
def _get_account_or_404(request, domain): account = BillingAccount.get_account_by_domain(domain) if account is None: raise Http404() if not account.has_enterprise_admin(request.couch_user.username): if not has_privilege(request, privileges.ACCOUNTING_ADMIN): raise Http404() return account
def can_add_extra_mobile_workers(request): from corehq.apps.users.models import CommCareUser from corehq.apps.accounting.models import Subscription num_web_users = CommCareUser.total_by_domain(request.domain) user_limit = request.plan.user_limit if user_limit == -1 or num_web_users < user_limit: return True if not has_privilege(request, privileges.ALLOW_EXCESS_USERS): current_subscription = Subscription.get_active_subscription_by_domain(request.domain) if current_subscription is None or current_subscription.account.date_confirmed_extra_charges is None: return False return True
def page_context(self): owner_id = self.export_instance.owner_id return { 'export_instance': self.export_instance, 'export_home_url': self.export_home_url, 'allow_deid': has_privilege(self.request, privileges.DEIDENTIFIED_DATA), 'has_excel_dashboard_access': domain_has_privilege(self.domain, EXCEL_DASHBOARD), 'has_daily_saved_export_access': domain_has_privilege(self.domain, DAILY_SAVED_EXPORT), 'can_edit': self.export_instance.can_edit(self.request.couch_user), 'has_other_owner': owner_id and owner_id != self.request.couch_user.user_id, 'owner_name': WebUser.get_by_user_id(owner_id).username if owner_id else None, }
def allowed_report_builder_reports(request): """ Return the number of report builder reports allowed """ builder_enabled = toggle_enabled(request, toggles.REPORT_BUILDER) legacy_builder_priv = has_privilege(request, privileges.REPORT_BUILDER) beta_group_enabled = toggle_enabled(request, toggles.REPORT_BUILDER_BETA_GROUP) if toggle_enabled(request, toggles.UNLIMITED_REPORT_BUILDER_REPORTS): return float("inf") if has_privilege(request, privileges.REPORT_BUILDER_30): return 30 if has_privilege(request, privileges.REPORT_BUILDER_15): return 15 if ( has_privilege(request, privileges.REPORT_BUILDER_TRIAL) or has_privilege(request, privileges.REPORT_BUILDER_5) or beta_group_enabled or (builder_enabled and legacy_builder_priv) ): return 5
def can_add_extra_mobile_workers(request): from corehq.apps.users.models import CommCareUser from corehq.apps.accounting.models import BillingAccount num_web_users = CommCareUser.total_by_domain(request.domain) user_limit = request.plan.user_limit if user_limit == -1 or num_web_users < user_limit: return True if not has_privilege(request, privileges.ALLOW_EXCESS_USERS): account = BillingAccount.get_account_by_domain(request.domain) if account is None or account.date_confirmed_extra_charges is None: return False return True
def can_use_restore_as(request): if not hasattr(request, 'couch_user'): return False if request.couch_user.is_superuser: return True if toggles.LOGIN_AS_ALWAYS_OFF.enabled(request.domain): return False return ( request.couch_user.can_edit_commcare_users() and has_privilege(request, privileges.LOGIN_AS) )
def domain_billing_context(request): is_domain_billing_admin = False restrict_domain_creation = settings.RESTRICT_DOMAIN_CREATION if getattr(request, 'couch_user', None) and getattr(request, 'domain', None): account = BillingAccount.get_account_by_domain(request.domain) if account: if has_privilege(request, privileges.ACCOUNTING_ADMIN): is_domain_billing_admin = True elif account.has_enterprise_admin(request.couch_user.username): is_domain_billing_admin = True if not is_domain_billing_admin: restrict_domain_creation = restrict_domain_creation or account.restrict_domain_creation return { 'IS_DOMAIN_BILLING_ADMIN': is_domain_billing_admin, 'restrict_domain_creation': restrict_domain_creation, }
def get_releases_context(request, domain, app_id): app = get_app(domain, app_id) can_send_sms = domain_has_privilege(domain, privileges.OUTBOUND_SMS) build_profile_access = domain_has_privilege(domain, privileges.BUILD_PROFILES) prompt_settings_form = PromptUpdateSettingsForm.from_app(app, request_user=request.couch_user) context = { 'release_manager': True, 'can_send_sms': can_send_sms, 'can_view_cloudcare': has_privilege(request, privileges.CLOUDCARE), 'has_mobile_workers': get_doc_count_in_domain_by_class(domain, CommCareUser) > 0, 'latest_released_version': get_latest_released_app_version(domain, app_id), 'sms_contacts': ( get_sms_autocomplete_context(request, domain)['sms_contacts'] if can_send_sms else [] ), 'build_profile_access': build_profile_access, 'application_profile_url': reverse(LanguageProfilesView.urlname, args=[domain, app_id]), 'lastest_j2me_enabled_build': CommCareBuildConfig.latest_j2me_enabled_config().label, 'fetchLimit': request.GET.get('limit', DEFAULT_FETCH_LIMIT), 'latest_build_id': get_latest_build_id(domain, app_id), 'prompt_settings_url': reverse(PromptSettingsUpdateView.urlname, args=[domain, app_id]), 'prompt_settings_form': prompt_settings_form, 'full_name': request.couch_user.full_name, 'can_manage_releases': can_manage_releases(request.couch_user, request.domain, app_id) } if not app.is_remote_app(): context.update({ 'enable_update_prompts': app.enable_update_prompts, }) if len(app.modules) == 0: context.update({'intro_only': True}) # Multimedia is not supported for remote applications at this time. try: multimedia_state = app.check_media_state() context.update({ 'multimedia_state': multimedia_state, }) except ReportConfigurationNotFoundError: pass return context
def get_restore_params(request): """ Given a request, get the relevant restore parameters out with sensible defaults """ # not a view just a view util try: openrosa_headers = getattr(request, 'openrosa_headers', {}) openrosa_version = openrosa_headers[OPENROSA_VERSION_HEADER] except KeyError: openrosa_version = request.GET.get('openrosa_version', OPENROSA_DEFAULT_VERSION) return { 'since': request.GET.get('since'), 'version': request.GET.get('version', "1.0"), 'state': request.GET.get('state'), 'items': request.GET.get('items') == 'true', 'as_user': request.GET.get('as'), 'has_data_cleanup_privelege': has_privilege(request, privileges.DATA_CLEANUP), 'overwrite_cache': request.GET.get('overwrite_cache') == 'true', 'openrosa_version': openrosa_version, }
def page_context(self): context = { 'are_groups': bool(len(self.all_groups)), 'groups_url': reverse('all_groups', args=[self.domain]), 'group_form': self.group_form, 'reset_password_form': self.reset_password_form, 'is_currently_logged_in_user': self.is_currently_logged_in_user, 'data_fields_form': self.custom_data.form, 'can_use_inbound_sms': domain_has_privilege(self.domain, privileges.INBOUND_SMS), 'needs_to_downgrade_locations': ( users_have_locations(self.domain) and not has_privilege(self.request, privileges.LOCATIONS) ), } if self.domain_object.commtrack_enabled or self.domain_object.uses_locations: context.update({ 'commtrack_enabled': self.domain_object.commtrack_enabled, 'uses_locations': self.domain_object.uses_locations, 'commtrack': { 'update_form': self.update_commtrack_form, }, }) return context
def _can_access_sms(request): return has_privilege(request, privileges.OUTBOUND_SMS)
def can_bulk_edit_users(self): return has_privilege(self.request, privileges.BULK_USER_MANAGEMENT) and not self.request.is_view_only
def can_bulk_edit_users(self): if not user_can_edit_any_location(self.request.couch_user, self.request.project): return False return has_privilege(self.request, privileges.BULK_USER_MANAGEMENT)
def has_report_builder_add_on_privilege(request): return any( has_privilege(request, p) for p in privileges.REPORT_BUILDER_ADD_ON_PRIVS)
def patched(request, slug, **assignment): if slug == privilege_name: return True return has_privilege(request, slug, **assignment)
def can_use_survey_reminders(request): return has_privilege(request, privileges.INBOUND_SMS)
def can_view_deid(self): return has_privilege(self.request, privileges.DEIDENTIFIED_DATA)
def can_view_data(request): return ((request.couch_user.can_edit_data() or request.couch_user.can_access_any_exports()) and has_privilege(request, privileges.PROJECT_ACCESS))
def can_edit_roles(self): return (has_privilege(self.request, privileges.ROLE_BASED_ACCESS) and self.couch_user.is_domain_admin)
def can_edit_roles(self): return has_privilege(self.request, privileges.ROLE_BASED_ACCESS) \ and self.couch_user.is_domain_admin
def _ensure_case_sharing_privilege(request, group): if not has_privilege(request, CASE_SHARING_GROUPS): if group.case_sharing: group.reporting = True group.case_sharing = False
def render_form(form, domain, options): """ Uses options since Django 1.3 doesn't seem to support templatetag kwargs. Change to kwargs when we're on a version of Django that does. """ timezone = get_timezone_for_request() case_id = options.get('case_id') side_pane = options.get('side_pane', False) user = options.get('user', None) request = options.get('request', None) support_enabled = toggle_enabled(request, toggles.SUPPORT) _get_tables_as_columns = partial(get_tables_as_columns, timezone=timezone) # Form Data tab form_data, question_list_not_found = get_readable_data_for_submission(form) # Case Changes tab case_blocks = extract_case_blocks(form) for i, block in enumerate(list(case_blocks)): if case_id and block.get(const.CASE_ATTR_ID) == case_id: case_blocks.pop(i) case_blocks.insert(0, block) cases = [] for b in case_blocks: this_case_id = b.get(const.CASE_ATTR_ID) try: this_case = CaseAccessors(domain).get_case( this_case_id) if this_case_id else None valid_case = True except ResourceNotFound: this_case = None valid_case = False if this_case and this_case.case_id: url = reverse('case_details', args=[domain, this_case.case_id]) else: url = "#" definition = get_default_definition( sorted_case_update_keys(b.keys()), assume_phonetimes=( not form.metadata or (form.metadata.deviceID != CLOUDCARE_DEVICE_ID)), ) cases.append({ "is_current_case": case_id and this_case_id == case_id, "name": case_inline_display(this_case), "table": _get_tables_as_columns(b, definition), "url": url, "valid_case": valid_case }) # Form Metadata tab meta = _top_level_tags(form).get('meta', None) or {} meta['received_on'] = json_format_datetime(form.received_on) if support_enabled: meta['last_sync_token'] = form.last_sync_token definition = get_default_definition(sorted_form_metadata_keys(meta.keys())) form_meta_data = _get_tables_as_columns(meta, definition) if getattr(form, 'auth_context', None): auth_context = AuthContext(form.auth_context) auth_context_user_id = auth_context.user_id auth_user_info = get_doc_info_by_id(domain, auth_context_user_id) else: auth_user_info = get_doc_info_by_id(domain, None) auth_context = AuthContext( user_id=None, authenticated=False, domain=domain, ) meta_userID = meta.get('userID') meta_username = meta.get('username') if meta_userID == 'demo_user': user_info = DocInfo( domain=domain, display='demo_user', ) elif meta_username == 'admin': user_info = DocInfo( domain=domain, display='admin', ) else: user_info = get_doc_info_by_id(domain, meta_userID) user_can_edit = (request and user and request.domain and (user.can_edit_data() or user.is_commcare_user())) show_edit_options = (user_can_edit and can_edit_form_location(domain, user, form)) show_edit_submission = (user_can_edit and has_privilege(request, privileges.DATA_CLEANUP) and not form.is_deprecated) show_resave = (user_can_edit and support_enabled) def _get_edit_info(instance): info = { 'was_edited': False, 'is_edit': False, } if instance.is_deprecated: info.update({ 'was_edited': True, 'latest_version': instance.orig_id, }) if getattr(instance, 'edited_on', None) and getattr( instance, 'deprecated_form_id', None): info.update({ 'is_edit': True, 'edited_on': instance.edited_on, 'previous_version': instance.deprecated_form_id }) return info return render_to_string( "reports/form/partials/single_form.html", { "context_case_id": case_id, "instance": form, "is_archived": form.is_archived, "edit_info": _get_edit_info(form), "domain": domain, 'question_list_not_found': question_list_not_found, "form_data": form_data, "cases": cases, "form_table_options": { # todo: wells if display config has more than one column "put_loners_in_wells": False }, "form_meta_data": form_meta_data, "auth_context": auth_context, "auth_user_info": auth_user_info, "user_info": user_info, "side_pane": side_pane, "show_edit_options": show_edit_options, "show_edit_submission": show_edit_submission, "show_resave": show_resave, }, RequestContext(request))
def has_report_builder_trial(request): return has_privilege(request, privileges.REPORT_BUILDER_TRIAL)
def get_app_view_context(request, app): """ This provides the context to render commcare settings on Edit Application Settings page This is where additional app or domain specific context can be added to any individual commcare-setting defined in commcare-app-settings.yaml or commcare-profile-settings.yaml """ context = {} settings_layout = copy.deepcopy( get_commcare_settings_layout(app.get_doc_type())) for section in settings_layout: new_settings = [] for setting in section['settings']: toggle_name = setting.get('toggle') if toggle_name and not toggle_enabled(request, toggle_name): continue privilege_name = setting.get('privilege') if privilege_name and not has_privilege(request, privilege_name): continue disable_if_true = setting.get('disable_if_true') if disable_if_true and getattr(app, setting['id']): continue if app.get_doc_type() == 'LinkedApplication': if setting['id'] in app.SUPPORTED_SETTINGS: if setting['id'] not in app.linked_app_attrs: setting['is_inherited'] = True new_settings.append(setting) section['settings'] = new_settings app_view_options = { 'permissions': { 'cloudcare': has_privilege(request, privileges.CLOUDCARE), }, 'sections': settings_layout, 'urls': { 'save': reverse("edit_commcare_settings", args=(app.domain, app.id)), }, 'user': { 'is_previewer': request.couch_user.is_previewer(), }, 'values': get_settings_values(app), 'warning': _("This is not an allowed value for this field"), } if (app.get_doc_type() == 'Application' and toggles.CUSTOM_PROPERTIES.enabled(request.domain) and 'custom_properties' in getattr(app, 'profile', {})): custom_properties_array = [{ 'key': p[0], 'value': p[1] } for p in app.profile.get('custom_properties').items()] app_view_options.update({'customProperties': custom_properties_array}) context.update({ 'app_view_options': app_view_options, }) build_config = CommCareBuildConfig.fetch() options = build_config.get_menu() if not request.user.is_superuser and not toggles.IS_CONTRACTOR.enabled( request.user.username): options = [option for option in options if not option.superuser_only] options_map = defaultdict(lambda: {"values": [], "value_names": []}) for option in options: builds = options_map[option.build.major_release()] builds["values"].append(option.build.to_string()) builds["value_names"].append(option.get_label()) if "default" not in builds: app_ver = MAJOR_RELEASE_TO_VERSION[option.build.major_release()] builds["default"] = build_config.get_default(app_ver).to_string() def _get_setting(setting_type, setting_id): # get setting dict from settings_layout if not settings_layout: return None matched = [ x for x in [ setting for section in settings_layout for setting in section['settings'] ] if x['type'] == setting_type and x['id'] == setting_id ] if matched: return matched[0] else: return None build_spec_setting = _get_setting('hq', 'build_spec') if build_spec_setting: build_spec_setting['options_map'] = options_map build_spec_setting['default_app_version'] = app.application_version practice_user_setting = _get_setting('hq', 'practice_mobile_worker_id') if practice_user_setting and has_privilege( request, privileges.PRACTICE_MOBILE_WORKERS): try: practice_users = get_practice_mode_mobile_workers(request.domain) except ESError: notify_exception(request, 'Error getting practice mode mobile workers') practice_users = [] practice_user_setting['values'] = [''] + [ u['_id'] for u in practice_users ] practice_user_setting['value_names'] = [_('Not set')] + [ u['username'] for u in practice_users ] context.update({ 'bulk_ui_translation_upload': { 'action': reverse('upload_bulk_ui_translations', args=(app.domain, app.get_id)), 'download_url': reverse('download_bulk_ui_translations', args=(app.domain, app.get_id)), 'adjective': _("U\u200BI translation"), 'plural_noun': _("U\u200BI translations"), }, 'bulk_app_translation_upload': { 'action': reverse('upload_bulk_app_translations', args=(app.domain, app.get_id)), 'download_url': reverse('download_bulk_app_translations', args=(app.domain, app.get_id)), 'adjective': _("app translation"), 'plural_noun': _("app translations"), 'can_select_language': toggles.BULK_UPDATE_MULTIMEDIA_PATHS.enabled_for_request(request), 'can_validate_app_translations': toggles.VALIDATE_APP_TRANSLATIONS.enabled_for_request(request), }, }) context.update({ 'bulk_ui_translation_form': get_bulk_upload_form( context, context_key="bulk_ui_translation_upload", ), 'bulk_app_translation_form': get_bulk_upload_form( context, context_key="bulk_app_translation_upload", form_class=AppTranslationsBulkUploadForm, ), }) context.update({ 'smart_lang_display_enabled': getattr(app, 'smart_lang_display', False) }) # Not used in APP_MANAGER_V2 context['is_app_view'] = True if app.get_doc_type() == 'LinkedApplication': context['upstream_url'] = _get_upstream_url(app, request.couch_user) try: context['master_version'] = app.get_master_version() except RemoteRequestError: pass return context
def can_bulk_edit_users(self): return has_privilege(self.request, privileges.BULK_USER_MANAGEMENT)
def can_use_custom_logo(self): return has_privilege(self.request, privileges.CUSTOM_BRANDING)
def view_generic(request, domain, app_id=None, module_id=None, form_id=None, copy_app_form=None, release_manager=False, module_unique_id=None, form_unique_id=None): """ This is the main view for the app. All other views redirect to here. """ if form_id and not module_id and module_unique_id is None: return bail(request, domain, app_id) app = module = form = None try: if app_id: app = get_app(domain, app_id) if module_id: try: module = app.get_module(module_id) except ModuleNotFoundException: raise Http404() if not module.unique_id: module.get_or_create_unique_id() app.save() elif module_unique_id: try: module = app.get_module_by_unique_id(module_unique_id) except ModuleNotFoundException: raise Http404() module_id = module.id if form_id and module is not None: try: form = module.get_form(form_id) except IndexError: raise Http404() elif form_unique_id: try: form = app.get_form(form_unique_id) except FormNotFoundException: raise Http404() form_id = form.id if form is not None and module is None: # this is the case where only the form_unique_id is given module = form.get_module() module_id = module.id except (ModuleNotFoundException, FormNotFoundException): return bail(request, domain, app_id) # Application states that should no longer exist if app: if app.application_version == APP_V1: _assert = soft_assert() _assert(False, 'App version 1.0', { 'domain': domain, 'app_id': app_id }) return render(request, "app_manager/no_longer_supported.html", { 'domain': domain, 'app': app, }) if not app.vellum_case_management and not app.is_remote_app(): # Soft assert but then continue rendering; template will contain a user-facing warning _assert = soft_assert(['jschweers' + '@' + 'dimagi.com']) _assert(False, 'vellum_case_management=False', { 'domain': domain, 'app_id': app_id }) if (form is not None and "usercase_preload" in getattr(form, "actions", {}) and form.actions.usercase_preload.preload): _assert = soft_assert(['dmiller' + '@' + 'dimagi.com']) _assert( False, 'User property easy refs + old-style config = bad', { 'domain': domain, 'app_id': app_id, 'module_id': module_id, 'module_unique_id': module_unique_id, 'form_id': form_id, 'form_unique_id': form_unique_id, }) context = get_apps_base_context(request, domain, app) if app and app.copy_of: # redirect to "main" app rather than specific build return HttpResponseRedirect( reverse("view_app", args=[domain, app.copy_of])) # grandfather in people who set commcare sense earlier if app and 'use_commcare_sense' in app: if app['use_commcare_sense']: if 'features' not in app.profile: app.profile['features'] = {} app.profile['features']['sense'] = 'true' del app['use_commcare_sense'] app.save() context.update({ 'module': module, 'form': form, }) lang = context['lang'] if app and not module and hasattr(app, 'translations'): context.update({"translations": app.translations.get(lang, {})}) if app and not app.is_remote_app(): context.update({ 'add_ons': add_ons.get_dict(request, app, module, form), 'add_ons_layout': add_ons.get_layout(request), }) if form: template, form_context = get_form_view_context_and_template( request, domain, form, context['langs']) context.update(form_context) elif module: template = get_module_template(request.user, module) # make sure all modules have unique ids app.ensure_module_unique_ids(should_save=True) module_context = get_module_view_context(app, module, lang) context.update(module_context) elif app: context.update(get_app_view_context(request, app)) template = 'app_manager/app_view_settings.html' if release_manager: template = 'app_manager/app_view_release_manager.html' if release_manager: context.update(get_releases_context(request, domain, app_id)) context.update({ 'is_app_settings_page': not release_manager, }) else: from corehq.apps.dashboard.views import DomainDashboardView return HttpResponseRedirect( reverse(DomainDashboardView.urlname, args=[domain])) # update multimedia context for forms and modules. menu_host = form or module if menu_host: default_file_name = 'module%s' % module_id if form: default_file_name = '%s_form%s' % (default_file_name, form_id) specific_media = [{ 'menu_refs': app.get_menu_media(module, module_id, form=form, form_index=form_id, to_language=lang), 'default_file_name': '{name}_{lang}'.format(name=default_file_name, lang=lang), }] if not form and module and not isinstance( module, ReportModule) and module.uses_media(): def _make_name(suffix): return "{default_name}_{suffix}_{lang}".format( default_name=default_file_name, suffix=suffix, lang=lang, ) specific_media.append({ 'menu_refs': app.get_case_list_form_media(module, module_id, to_language=lang), 'default_file_name': _make_name('case_list_form'), 'qualifier': 'case_list_form_', }) specific_media.append({ 'menu_refs': app.get_case_list_menu_item_media(module, module_id, to_language=lang), 'default_file_name': _make_name('case_list_menu_item'), 'qualifier': 'case_list-menu_item_', }) if (toggles.CASE_LIST_LOOKUP.enabled(request.user.username) or toggles.CASE_LIST_LOOKUP.enabled(app.domain)): specific_media.append({ 'menu_refs': app.get_case_list_lookup_image(module, module_id), 'default_file_name': '{}_case_list_lookup'.format(default_file_name), 'qualifier': 'case-list-lookupcase', }) if hasattr(module, 'product_details'): specific_media.append({ 'menu_refs': app.get_case_list_lookup_image(module, module_id, type='product'), 'default_file_name': '{}_product_list_lookup'.format(default_file_name), 'qualifier': 'case-list-lookupproduct', }) uploaders = { 'icon': MultimediaImageUploadController( "hqimage", reverse(ProcessImageFileUploadView.name, args=[app.domain, app.get_id])), 'audio': MultimediaAudioUploadController( "hqaudio", reverse(ProcessAudioFileUploadView.name, args=[app.domain, app.get_id])), } context.update({ 'multimedia': { "object_map": app.get_object_map(), 'upload_managers': uploaders, 'upload_managers_js': {type: u.js_options for type, u in six.iteritems(uploaders)}, } }) context['module_icon'] = None if toggles.CUSTOM_ICON_BADGES.enabled(domain): context[ 'module_icon'] = module.custom_icon if module.custom_icon else CustomIcon( ) try: context['multimedia']['references'] = app.get_references() except ReportConfigurationNotFoundError: pass context['nav_menu_media_specifics'] = specific_media error = request.GET.get('error', '') context.update({ 'error': error, 'app': app, }) # Pass form for Copy Application to template domain_names = [d.name for d in Domain.active_for_user(request.couch_user)] domain_names.sort() if app and copy_app_form is None: toggle_enabled = toggles.EXPORT_ZIPPED_APPS.enabled( request.user.username) copy_app_form = CopyApplicationForm( domain, app, export_zipped_apps_enabled=toggle_enabled) context.update({ 'domain_names': domain_names, }) linked_domains_enabled = toggles.LINKED_DOMAINS.enabled(domain) context.update({ 'copy_app_form': copy_app_form, 'linked_domains_enabled': linked_domains_enabled, }) context['latest_commcare_version'] = get_commcare_versions( request.user)[-1] context['current_app_version_url'] = reverse('current_app_version', args=[domain, app_id]) if app and app.doc_type == 'Application' and has_privilege( request, privileges.COMMCARE_LOGO_UPLOADER): uploader_slugs = list(ANDROID_LOGO_PROPERTY_MAPPING.keys()) from corehq.apps.hqmedia.controller import MultimediaLogoUploadController from corehq.apps.hqmedia.views import ProcessLogoFileUploadView uploaders = [ MultimediaLogoUploadController( slug, reverse( ProcessLogoFileUploadView.name, args=[domain, app_id, slug], )) for slug in uploader_slugs ] context.update({ "sessionid": request.COOKIES.get('sessionid'), "uploaders": uploaders, "uploaders_js": [u.js_options for u in uploaders], "refs": { slug: ApplicationMediaReference( app.logo_refs.get(slug, {}).get("path", slug), media_class=CommCareImage, module_id=app.logo_refs.get(slug, {}).get("m_id"), ).as_dict() for slug in uploader_slugs }, "media_info": { slug: app.logo_refs.get(slug) for slug in uploader_slugs if app.logo_refs.get(slug) }, }) context.update({ 'show_live_preview': app and should_show_preview_app(request, app, request.couch_user.username), 'can_preview_form': request.couch_user.has_permission(domain, 'edit_data') }) confirm = request.session.pop('CONFIRM', False) context.update({'confirm': confirm}) response = render(request, template, context) response.set_cookie('lang', encode_if_unicode(lang)) return response
def edit_app_attr(request, domain, app_id, attr): """ Called to edit any (supported) app attribute, given by attr """ app = get_app(domain, app_id) lang = request.COOKIES.get("lang", (app.langs or ["en"])[0]) try: hq_settings = json.loads(request.body)["hq"] except ValueError: hq_settings = request.POST attributes = [ "all", "recipients", "name", "use_commcare_sense", "text_input", "platform", "build_spec", "use_custom_suite", "custom_suite", "admin_password", "comment", "use_j2me_endpoint", # Application only "cloudcare_enabled", "case_sharing", "translation_strategy", "auto_gps_capture", # RemoteApp only "profile_url", "manage_urls", ] if attr not in attributes: return HttpResponseBadRequest() def should_edit(attribute): return attribute == attr or ("all" == attr and attribute in hq_settings) resp = {"update": {}} # For either type of app easy_attrs = ( ("build_spec", BuildSpec.from_string), ("case_sharing", None), ("cloudcare_enabled", None), ("commtrack_requisition_mode", lambda m: None if m == "disabled" else m), ("manage_urls", None), ("name", None), ("platform", None), ("recipients", None), ("text_input", None), ("use_custom_suite", None), ("secure_submissions", None), ("translation_strategy", None), ("auto_gps_capture", None), ("use_grid_menus", None), ("grid_form_menus", None), ("comment", None), ("custom_base_url", None), ("use_j2me_endpoint", None), ) for attribute, transformation in easy_attrs: if should_edit(attribute): value = hq_settings[attribute] if transformation: value = transformation(value) setattr(app, attribute, value) if should_edit("name"): clear_app_cache(request, domain) name = hq_settings["name"] resp["update"].update( { ".variable-app_name": name, '[data-id="{id}"]'.format(id=app_id): ApplicationsTab.make_app_title(name, app.doc_type), } ) if should_edit("build_spec"): resp["update"]["commcare-version"] = app.commcare_minor_release if should_edit("admin_password"): admin_password = hq_settings.get("admin_password") if admin_password: app.set_admin_password(admin_password) # For Normal Apps if should_edit("cloudcare_enabled"): if app.get_doc_type() not in ("Application",): raise Exception("App type %s does not support cloudcare" % app.get_doc_type()) if not has_privilege(request, privileges.CLOUDCARE): app.cloudcare_enabled = False def require_remote_app(): if app.get_doc_type() not in ("RemoteApp",): raise Exception("App type %s does not support profile url" % app.get_doc_type()) # For RemoteApps if should_edit("profile_url"): require_remote_app() app["profile_url"] = hq_settings["profile_url"] if should_edit("manage_urls"): require_remote_app() app.save(resp) # this is a put_attachment, so it has to go after everything is saved if should_edit("custom_suite"): app.set_custom_suite(hq_settings["custom_suite"]) return HttpResponse(json.dumps(resp))
def can_view_reports(request): return (user_can_view_reports(request.project, request.couch_user) and has_privilege(request, privileges.PROJECT_ACCESS))
def _can_access_reminders(request): return has_privilege(request, privileges.REMINDERS_FRAMEWORK)
def view_generic(request, domain, app_id=None, module_id=None, form_id=None, copy_app_form=None): """ This is the main view for the app. All other views redirect to here. """ if form_id and not module_id: return bail(request, domain, app_id) app = module = form = None try: if app_id: app = get_app(domain, app_id) if module_id: try: module = app.get_module(module_id) except ModuleNotFoundException: raise Http404() if not module.unique_id: module.get_or_create_unique_id() app.save() if form_id: try: form = module.get_form(form_id) except IndexError: raise Http404() except ModuleNotFoundException: return bail(request, domain, app_id) if app and app.application_version == '1.0': _assert = soft_assert(to=['droberts' + '@' + 'dimagi.com']) _assert(False, 'App version 1.0', {'domain': domain, 'app_id': app_id}) return render(request, 'app_manager/no_longer_supported.html', { 'domain': domain, 'app': app, }) context = get_apps_base_context(request, domain, app) if app and app.copy_of: # don't fail hard. return HttpResponseRedirect( reverse("corehq.apps.app_manager.views.view_app", args=[domain, app.copy_of])) # grandfather in people who set commcare sense earlier if app and 'use_commcare_sense' in app: if app['use_commcare_sense']: if 'features' not in app.profile: app.profile['features'] = {} app.profile['features']['sense'] = 'true' del app['use_commcare_sense'] app.save() context.update({ 'module': module, 'form': form, }) lang = context['lang'] if app and not module and hasattr(app, 'translations'): context.update({"translations": app.translations.get(lang, {})}) if form: template, form_context = get_form_view_context_and_template( request, domain, form, context['langs']) context.update({ 'case_properties': get_all_case_properties(app), 'usercase_properties': get_usercase_properties(app), }) context.update(form_context) elif module: template = get_module_template(module) # make sure all modules have unique ids app.ensure_module_unique_ids(should_save=True) module_context = get_module_view_context(app, module, lang) context.update(module_context) elif app: template = "app_manager/app_view.html" context.update(get_app_view_context(request, app)) else: from corehq.apps.dashboard.views import NewUserDashboardView template = NewUserDashboardView.template_name context.update({'templates': NewUserDashboardView.templates(domain)}) # update multimedia context for forms and modules. menu_host = form or module if menu_host: default_file_name = 'module%s' % module_id if form_id: default_file_name = '%s_form%s' % (default_file_name, form_id) specific_media = { 'menu': { 'menu_refs': app.get_menu_media(module, module_id, form=form, form_index=form_id, to_language=lang), 'default_file_name': '{name}_{lang}'.format(name=default_file_name, lang=lang), } } if module and module.uses_media(): def _make_name(suffix): return "{default_name}_{suffix}_{lang}".format( default_name=default_file_name, suffix=suffix, lang=lang, ) specific_media['case_list_form'] = { 'menu_refs': app.get_case_list_form_media(module, module_id, to_language=lang), 'default_file_name': _make_name('case_list_form'), } specific_media['case_list_menu_item'] = { 'menu_refs': app.get_case_list_menu_item_media(module, module_id, to_language=lang), 'default_file_name': _make_name('case_list_menu_item'), } specific_media['case_list_lookup'] = { 'menu_refs': app.get_case_list_lookup_image(module, module_id), 'default_file_name': '{}_case_list_lookup'.format(default_file_name), } if hasattr(module, 'product_details'): specific_media['product_list_lookup'] = { 'menu_refs': app.get_case_list_lookup_image(module, module_id, type='product'), 'default_file_name': '{}_product_list_lookup'.format(default_file_name), } context.update({ 'multimedia': { "object_map": app.get_object_map(), 'upload_managers': { 'icon': MultimediaImageUploadController( "hqimage", reverse(ProcessImageFileUploadView.name, args=[app.domain, app.get_id])), 'audio': MultimediaAudioUploadController( "hqaudio", reverse(ProcessAudioFileUploadView.name, args=[app.domain, app.get_id])), }, } }) try: context['multimedia']['references'] = app.get_references() except ReportConfigurationNotFoundError: pass context['multimedia'].update(specific_media) error = request.GET.get('error', '') context.update({ 'error': error, 'app': app, }) # Pass form for Copy Application to template domain_names = [d.name for d in Domain.active_for_user(request.couch_user)] domain_names.sort() if copy_app_form is None: toggle_enabled = toggles.EXPORT_ZIPPED_APPS.enabled( request.user.username) copy_app_form = CopyApplicationForm( app_id, export_zipped_apps_enabled=toggle_enabled) context.update({ 'copy_app_form': copy_app_form, 'domain_names': domain_names, }) context['latest_commcare_version'] = get_commcare_versions( request.user)[-1] if app and app.doc_type == 'Application' and has_privilege( request, privileges.COMMCARE_LOGO_UPLOADER): uploader_slugs = ANDROID_LOGO_PROPERTY_MAPPING.keys() from corehq.apps.hqmedia.controller import MultimediaLogoUploadController from corehq.apps.hqmedia.views import ProcessLogoFileUploadView context.update({ "sessionid": request.COOKIES.get('sessionid'), 'uploaders': [ MultimediaLogoUploadController( slug, reverse( ProcessLogoFileUploadView.name, args=[domain, app_id, slug], )) for slug in uploader_slugs ], "refs": { slug: ApplicationMediaReference( app.logo_refs.get(slug, {}).get("path", slug), media_class=CommCareImage, module_id=app.logo_refs.get(slug, {}).get("m_id"), ).as_dict() for slug in uploader_slugs }, "media_info": { slug: app.logo_refs.get(slug) for slug in uploader_slugs if app.logo_refs.get(slug) }, }) response = render(request, template, context) response.set_cookie('lang', encode_if_unicode(lang)) return response
def can_view_apps(request): return request.couch_user.can_view_apps() and has_privilege( request, privileges.PROJECT_ACCESS)
def get_app_view_context(request, app): is_cloudcare_allowed = has_privilege(request, privileges.CLOUDCARE) context = {} settings_layout = copy.deepcopy(get_commcare_settings_layout(request.domain)[app.get_doc_type()]) for section in settings_layout: new_settings = [] for setting in section["settings"]: toggle_name = setting.get("toggle") if toggle_name and not toggle_enabled(request, toggle_name): continue privilege_name = setting.get("privilege") if privilege_name and not has_privilege(request, privilege_name): continue disable_if_true = setting.get("disable_if_true") if disable_if_true and getattr(app, setting["id"]): continue new_settings.append(setting) section["settings"] = new_settings if toggles.CUSTOM_PROPERTIES.enabled(request.domain) and "custom_properties" in app.profile: custom_properties_array = map( lambda p: {"key": p[0], "value": p[1]}, app.profile.get("custom_properties").items() ) context.update({"custom_properties": custom_properties_array}) context.update( { "settings_layout": settings_layout, "settings_values": get_settings_values(app), "is_cloudcare_allowed": is_cloudcare_allowed, } ) build_config = CommCareBuildConfig.fetch() options = build_config.get_menu() if not request.user.is_superuser: options = [option for option in options if not option.superuser_only] options_map = defaultdict(lambda: {"values": [], "value_names": []}) for option in options: builds = options_map[option.build.major_release()] builds["values"].append(option.build.to_string()) builds["value_names"].append(option.get_label()) if "default" not in builds: app_ver = MAJOR_RELEASE_TO_VERSION[option.build.major_release()] builds["default"] = build_config.get_default(app_ver).to_string() (build_spec_setting,) = filter( lambda x: x["type"] == "hq" and x["id"] == "build_spec", [setting for section in context["settings_layout"] for setting in section["settings"]], ) build_spec_setting["options_map"] = options_map build_spec_setting["default_app_version"] = app.application_version context.update( { "bulk_ui_translation_upload": { "action": reverse("upload_bulk_ui_translations", args=(app.domain, app.get_id)), "download_url": reverse("download_bulk_ui_translations", args=(app.domain, app.get_id)), "adjective": _(u"U\u200BI translation"), "plural_noun": _(u"U\u200BI translations"), }, "bulk_app_translation_upload": { "action": reverse("upload_bulk_app_translations", args=(app.domain, app.get_id)), "download_url": reverse("download_bulk_app_translations", args=(app.domain, app.get_id)), "adjective": _("app translation"), "plural_noun": _("app translations"), }, } ) context.update( { "bulk_ui_translation_form": get_bulk_upload_form(context, context_key="bulk_ui_translation_upload"), "bulk_app_translation_form": get_bulk_upload_form(context, context_key="bulk_app_translation_upload"), } ) context["is_app_view"] = True try: context["fetchLimit"] = int(request.GET.get("limit", DEFAULT_FETCH_LIMIT)) except ValueError: context["fetchLimit"] = DEFAULT_FETCH_LIMIT return context
def permissions_check(self, report, request, domain=None, is_navigation_check=False): if is_navigation_check and not has_privilege(request, privileges.CUSTOM_REPORTS): return False return super(CustomProjectReportDispatcher, self).permissions_check(report, request, domain)
def get(self, request, *args, **kwargs): if request.couch_user.is_domain_admin(self.domain) and has_privilege(request, privileges.PROJECT_ACCESS): return HttpResponseRedirect(reverse(EditBasicProjectInfoView.urlname, args=[self.domain])) return HttpResponseRedirect(reverse(EditMyProjectSettingsView.urlname, args=[self.domain]))
def edit_app_attr(request, domain, app_id, attr): """ Called to edit any (supported) app attribute, given by attr """ app = get_app(domain, app_id) try: hq_settings = json.loads(request.body)['hq'] except ValueError: hq_settings = request.POST attributes = [ 'all', 'recipients', 'name', 'text_input', 'platform', 'build_spec', 'use_custom_suite', 'custom_suite', 'admin_password', 'comment', 'use_j2me_endpoint', # Application only 'cloudcare_enabled', 'case_sharing', 'translation_strategy', 'auto_gps_capture', # RemoteApp only 'profile_url', 'manage_urls', 'mobile_ucr_restore_version', ] if attr not in attributes: return HttpResponseBadRequest() def should_edit(attribute): return attribute == attr or ('all' == attr and attribute in hq_settings) def parse_sync_interval(interval): try: return int(interval) except ValueError: pass resp = {"update": {}} # For either type of app easy_attrs = ( ('build_spec', BuildSpec.from_string), ('practice_mobile_worker_id', None), ('case_sharing', None), ('cloudcare_enabled', None), ('manage_urls', None), ('name', None), ('platform', None), ('recipients', None), ('text_input', None), ('use_custom_suite', None), ('secure_submissions', None), ('translation_strategy', None), ('auto_gps_capture', None), ('use_grid_menus', None), ('grid_form_menus', None), ('target_commcare_flavor', None), ('comment', None), ('custom_base_url', None), ('use_j2me_endpoint', None), ('mobile_ucr_restore_version', None), ('location_fixture_restore', None), ) for attribute, transformation in easy_attrs: if should_edit(attribute): value = hq_settings[attribute] if transformation: value = transformation(value) setattr(app, attribute, value) if app.get_doc_type( ) == 'LinkedApplication' and attribute in app.SUPPORTED_SETTINGS: app.linked_app_attrs.update({ attribute: value, }) if should_edit("name"): clear_app_cache(request, domain) name = hq_settings['name'] resp['update'].update({ '.variable-app_name': name, '[data-id="{id}"]'.format(id=app_id): ApplicationsTab.make_app_title(name, app.doc_type), }) if should_edit("build_spec"): resp['update']['commcare-version'] = app.commcare_minor_release if should_edit("practice_mobile_worker_id"): user_id = hq_settings['practice_mobile_worker_id'] if not app.enable_practice_users: app.practice_mobile_worker_id = None elif user_id: get_and_assert_practice_user_in_domain(user_id, request.domain) if should_edit("admin_password"): admin_password = hq_settings.get('admin_password') if admin_password: app.set_admin_password(admin_password) # For Normal Apps if should_edit("cloudcare_enabled"): if app.get_doc_type() not in ("Application", ): raise Exception("App type %s does not support cloudcare" % app.get_doc_type()) if not has_privilege(request, privileges.CLOUDCARE): app.cloudcare_enabled = False def require_remote_app(): if app.get_doc_type() not in ("RemoteApp", ): raise Exception("App type %s does not support profile url" % app.get_doc_type()) # For RemoteApps if should_edit("profile_url"): require_remote_app() app['profile_url'] = hq_settings['profile_url'] if should_edit("manage_urls"): require_remote_app() app.save(resp) # this is a put_attachment, so it has to go after everything is saved if should_edit("custom_suite"): app.set_custom_suite(hq_settings['custom_suite']) return HttpResponse(json.dumps(resp))
def render_form(form, domain, options): """ Uses options since Django 1.3 doesn't seem to support templatetag kwargs. Change to kwargs when we're on a version of Django that does. """ # don't actually use the passed in timezone since we assume form submissions already come # in in local time. # todo: we should revisit this when we properly handle timezones in form processing. timezone = pytz.utc case_id = options.get('case_id') side_pane = options.get('side_pane', False) user = options.get('user', None) _get_tables_as_columns = partial(get_tables_as_columns, timezone=timezone) # Form Data tab form_data, question_list_not_found = get_readable_data_for_submission(form) # Case Changes tab case_blocks = extract_case_blocks(form) for i, block in enumerate(list(case_blocks)): if case_id and block.get(const.CASE_ATTR_ID) == case_id: case_blocks.pop(i) case_blocks.insert(0, block) cases = [] for b in case_blocks: this_case_id = b.get(const.CASE_ATTR_ID) try: this_case = CommCareCase.get(this_case_id) if this_case_id else None valid_case = True except ResourceNotFound: this_case = None valid_case = False if this_case and this_case._id: url = reverse('case_details', args=[domain, this_case._id]) else: url = "#" definition = get_definition(sorted_case_update_keys(b.keys())) cases.append({ "is_current_case": case_id and this_case_id == case_id, "name": case_inline_display(this_case), "table": _get_tables_as_columns(b, definition), "url": url, "valid_case": valid_case }) # Form Metadata tab meta = form.top_level_tags().get('meta', None) or {} definition = get_definition(sorted_form_metadata_keys(meta.keys())) form_meta_data = _get_tables_as_columns(meta, definition) if 'auth_context' in form: auth_context = AuthContext(form.auth_context) auth_context_user_id = auth_context.user_id auth_user_info = get_doc_info_by_id(domain, auth_context_user_id) else: auth_user_info = get_doc_info_by_id(domain, None) auth_context = AuthContext( user_id=None, authenticated=False, domain=domain, ) meta_userID = meta.get('userID') meta_username = meta.get('username') if meta_userID == 'demo_user': user_info = DocInfo( domain=domain, display='demo_user', ) elif meta_username == 'admin': user_info = DocInfo( domain=domain, display='admin', ) else: user_info = get_doc_info_by_id(domain, meta_userID) request = options.get('request', None) user_can_edit = ( request and user and request.domain and (user.can_edit_data() or user.is_commcare_user()) ) show_edit_submission = ( user_can_edit and has_privilege(request, privileges.CLOUDCARE) and toggle_enabled(request, toggles.EDIT_SUBMISSIONS) ) # stuffing this in the same flag as case rebuild show_resave = ( user_can_edit and toggle_enabled(request, toggles.CASE_REBUILD) ) return render_to_string("reports/form/partials/single_form.html", { "context_case_id": case_id, "instance": form, "is_archived": form.doc_type == "XFormArchived", "domain": domain, 'question_list_not_found': question_list_not_found, "form_data": form_data, "cases": cases, "form_table_options": { # todo: wells if display config has more than one column "put_loners_in_wells": False }, "form_meta_data": form_meta_data, "auth_context": auth_context, "auth_user_info": auth_user_info, "user_info": user_info, "side_pane": side_pane, "user": user, "show_edit_submission": show_edit_submission, "show_resave": show_resave, })
def render_form(form, domain, options): """ Uses options since Django 1.3 doesn't seem to support templatetag kwargs. Change to kwargs when we're on a version of Django that does. """ timezone = get_timezone_for_request() case_id = options.get('case_id') side_pane = options.get('side_pane', False) user = options.get('user', None) request = options.get('request', None) support_enabled = toggle_enabled(request, toggles.SUPPORT) _get_tables_as_columns = partial(get_tables_as_columns, timezone=timezone) # Form Data tab form_data, question_list_not_found = get_readable_data_for_submission(form) # Case Changes tab case_blocks = extract_case_blocks(form) for i, block in enumerate(list(case_blocks)): if case_id and block.get(const.CASE_ATTR_ID) == case_id: case_blocks.pop(i) case_blocks.insert(0, block) cases = [] for b in case_blocks: this_case_id = b.get(const.CASE_ATTR_ID) try: this_case = CaseAccessors(domain).get_case(this_case_id) if this_case_id else None valid_case = True except ResourceNotFound: this_case = None valid_case = False if this_case and this_case.case_id: url = reverse('case_details', args=[domain, this_case.case_id]) else: url = "#" definition = get_default_definition( sorted_case_update_keys(b.keys()), assume_phonetimes=(not form.metadata or (form.metadata.deviceID != CLOUDCARE_DEVICE_ID)), ) cases.append({ "is_current_case": case_id and this_case_id == case_id, "name": case_inline_display(this_case), "table": _get_tables_as_columns(b, definition), "url": url, "valid_case": valid_case }) # Form Metadata tab meta = _top_level_tags(form).get('meta', None) or {} meta['received_on'] = json_format_datetime(form.received_on) if support_enabled: meta['last_sync_token'] = form.last_sync_token definition = get_default_definition(sorted_form_metadata_keys(meta.keys())) form_meta_data = _get_tables_as_columns(meta, definition) if getattr(form, 'auth_context', None): auth_context = AuthContext(form.auth_context) auth_context_user_id = auth_context.user_id auth_user_info = get_doc_info_by_id(domain, auth_context_user_id) else: auth_user_info = get_doc_info_by_id(domain, None) auth_context = AuthContext( user_id=None, authenticated=False, domain=domain, ) meta_userID = meta.get('userID') meta_username = meta.get('username') if meta_userID == 'demo_user': user_info = DocInfo( domain=domain, display='demo_user', ) elif meta_username == 'admin': user_info = DocInfo( domain=domain, display='admin', ) else: user_info = get_doc_info_by_id(domain, meta_userID) user_can_edit = ( request and user and request.domain and (user.can_edit_data() or user.is_commcare_user()) ) show_edit_options = ( user_can_edit and can_edit_form_location(domain, user, form) ) show_edit_submission = ( user_can_edit and has_privilege(request, privileges.DATA_CLEANUP) and not form.is_deprecated ) show_resave = ( user_can_edit and support_enabled ) def _get_edit_info(instance): info = { 'was_edited': False, 'is_edit': False, } if instance.is_deprecated: info.update({ 'was_edited': True, 'latest_version': instance.orig_id, }) if getattr(instance, 'edited_on', None) and getattr(instance, 'deprecated_form_id', None): info.update({ 'is_edit': True, 'edited_on': instance.edited_on, 'previous_version': instance.deprecated_form_id }) return info return render_to_string("reports/form/partials/single_form.html", { "context_case_id": case_id, "instance": form, "is_archived": form.is_archived, "edit_info": _get_edit_info(form), "domain": domain, 'question_list_not_found': question_list_not_found, "form_data": form_data, "cases": cases, "form_table_options": { # todo: wells if display config has more than one column "put_loners_in_wells": False }, "form_meta_data": form_meta_data, "auth_context": auth_context, "auth_user_info": auth_user_info, "user_info": user_info, "side_pane": side_pane, "show_edit_options": show_edit_options, "show_edit_submission": show_edit_submission, "show_resave": show_resave, }, RequestContext(request))