class FormplayerMain(View): preview = False urlname = 'formplayer_main' @use_datatables @use_legacy_jquery @use_jquery_ui @method_decorator(require_cloudcare_access) @method_decorator( requires_privilege_for_commcare_user(privileges.CLOUDCARE)) def dispatch(self, request, *args, **kwargs): return super(FormplayerMain, self).dispatch(request, *args, **kwargs) def fetch_app(self, domain, app_id): username = self.request.couch_user.username if (toggles.CLOUDCARE_LATEST_BUILD.enabled(domain) or toggles.CLOUDCARE_LATEST_BUILD.enabled(username)): return get_latest_build_doc(domain, app_id) else: return get_latest_released_app_doc(domain, app_id) def get(self, request, domain): app_access = ApplicationAccess.get_by_domain(domain) app_ids = get_app_ids_in_domain(domain) apps = map( lambda app_id: self.fetch_app(domain, app_id), app_ids, ) apps = filter(None, apps) apps = filter(lambda app: app.get('cloudcare_enabled') or self.preview, apps) apps = filter( lambda app: app_access.user_can_access_app(request.couch_user, app ), apps) apps = sorted(apps, key=lambda app: app['name']) def _default_lang(): try: return apps[0]['langs'][0] except Exception: 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() context = { "domain": domain, "language": language, "apps": apps, "maps_api_key": settings.GMAPS_API_KEY, "username": request.user.username, "formplayer_url": settings.FORMPLAYER_URL, "single_app_mode": False, "home_url": reverse(self.urlname, args=[domain]), "environment": WEB_APPS_ENVIRONMENT, } return render(request, "cloudcare/formplayer_home.html", context)
class FormplayerPreviewSingleApp(View): urlname = 'formplayer_single_app' @use_datatables @use_jquery_ui @method_decorator(require_cloudcare_access) @method_decorator( requires_privilege_for_commcare_user(privileges.CLOUDCARE)) def dispatch(self, request, *args, **kwargs): return super(FormplayerPreviewSingleApp, self).dispatch(request, *args, **kwargs) def get(self, request, domain, app_id, **kwargs): app_access = get_application_access_for_domain(domain) app = get_current_app(domain, app_id) if not app_access.user_can_access_app(request.couch_user, app): raise Http404() role = request.couch_user.get_role(domain) if role and not role.permissions.view_web_app(app.origin_id): raise Http404() def _default_lang(): try: return app['langs'][0] except Exception: 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() domain_obj = Domain.get_by_name(domain) context = { "domain": domain, "default_geocoder_location": domain_obj.default_geocoder_location, "language": language, "apps": [_format_app_doc(app)], "mapbox_access_token": settings.MAPBOX_ACCESS_TOKEN, "username": request.user.username, "formplayer_url": get_formplayer_url(for_js=True), "single_app_mode": True, "home_url": reverse(self.urlname, args=[domain, app_id]), "environment": WEB_APPS_ENVIRONMENT, "integrations": integration_contexts(domain), "has_geocoder_privs": has_geocoder_privs(domain), } return render(request, "cloudcare/formplayer_home.html", context)
class FormplayerPreviewSingleApp(View): urlname = 'formplayer_single_app' @use_datatables @use_legacy_jquery @use_jquery_ui @method_decorator(require_cloudcare_access) @method_decorator( requires_privilege_for_commcare_user(privileges.CLOUDCARE)) def dispatch(self, request, *args, **kwargs): return super(FormplayerPreviewSingleApp, self).dispatch(request, *args, **kwargs) def get(self, request, domain, app_id, **kwargs): app_access = ApplicationAccess.get_by_domain(domain) app = get_current_app(domain, app_id) if not app_access.user_can_access_app(request.couch_user, app): raise Http404() role = request.couch_user.get_role(domain) if role and not role.permissions.view_web_app(app): raise Http404() def _default_lang(): try: return app['langs'][0] except Exception: 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() context = { "domain": domain, "language": language, "apps": [app], "maps_api_key": settings.GMAPS_API_KEY, "username": request.user.username, "formplayer_url": settings.FORMPLAYER_URL, "single_app_mode": True, "home_url": reverse(self.urlname, args=[domain, app_id]), "environment": WEB_APPS_ENVIRONMENT, 'use_live_query': toggles.FORMPLAYER_USE_LIVEQUERY.enabled(domain), } return render(request, "cloudcare/formplayer_home.html", context)
class FormplayerMain(View): preview = False urlname = 'formplayer_main' @use_datatables @use_legacy_jquery @use_jquery_ui @method_decorator(require_cloudcare_access) @method_decorator( requires_privilege_for_commcare_user(privileges.CLOUDCARE)) def dispatch(self, request, *args, **kwargs): return super(FormplayerMain, self).dispatch(request, *args, **kwargs) def fetch_app(self, domain, app_id): username = self.request.couch_user.username if (toggles.CLOUDCARE_LATEST_BUILD.enabled(domain) or toggles.CLOUDCARE_LATEST_BUILD.enabled(username)): return get_latest_build_doc(domain, app_id) else: return get_latest_released_app_doc(domain, app_id) def get_web_apps_available_to_user(self, domain, user): app_access = ApplicationAccess.get_by_domain(domain) app_ids = get_app_ids_in_domain(domain) apps = list( map( lambda app_id: self.fetch_app(domain, app_id), app_ids, )) apps = filter(None, apps) apps = filter(lambda app: app.get('cloudcare_enabled') or self.preview, apps) apps = filter(lambda app: app_access.user_can_access_app(user, app), apps) role = user.get_role(domain) if role: apps = [app for app in apps if role.permissions.view_web_app(app)] apps = sorted(apps, key=lambda app: app['name']) return apps @staticmethod def get_restore_as_user(request, domain): """ returns (user, set_cookie), where set_cookie is a function to be called on the eventual response """ if not hasattr(request, 'couch_user'): raise Http404() def set_cookie(response): # set_coookie is a noop by default return response cookie_name = six.moves.urllib.parse.quote('restoreAs:{}:{}'.format( domain, request.couch_user.username)) username = request.COOKIES.get(cookie_name) if username: user = CouchUser.get_by_username(format_username(username, domain)) if user: return user, set_cookie else: def set_cookie( response): # overwrite the default noop set_cookie response.delete_cookie(cookie_name) return response return request.couch_user, set_cookie def get(self, request, domain): option = request.GET.get('option') if option == 'apps': return self.get_option_apps(request, domain) else: return self.get_main(request, domain) def get_option_apps(self, request, domain): restore_as, set_cookie = self.get_restore_as_user(request, domain) apps = self.get_web_apps_available_to_user(domain, restore_as) return JsonResponse(apps, safe=False) def get_main(self, request, domain): restore_as, set_cookie = self.get_restore_as_user(request, domain) apps = self.get_web_apps_available_to_user(domain, restore_as) def _default_lang(): try: return apps[0]['langs'][0] except Exception: 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() context = { "domain": domain, "language": language, "apps": apps, "domain_is_on_trial": domain_is_on_trial(domain), "maps_api_key": settings.GMAPS_API_KEY, "username": request.couch_user.username, "formplayer_url": settings.FORMPLAYER_URL, "single_app_mode": False, "home_url": reverse(self.urlname, args=[domain]), "environment": WEB_APPS_ENVIRONMENT, 'use_live_query': toggles.FORMPLAYER_USE_LIVEQUERY.enabled(domain), } return set_cookie( render(request, "cloudcare/formplayer_home.html", context))
class LoginAsUsers(View): http_method_names = ['get'] urlname = 'login_as_users' @method_decorator(login_and_domain_required) @method_decorator(require_can_edit_commcare_users) @method_decorator( requires_privilege_for_commcare_user(privileges.CLOUDCARE)) def dispatch(self, *args, **kwargs): return super(LoginAsUsers, self).dispatch(*args, **kwargs) def get(self, request, domain, **kwargs): self.domain = domain self.couch_user = request.couch_user try: limit = int(request.GET.get('limit', 10)) except ValueError: limit = 10 # front end pages start at one try: page = int(request.GET.get('page', 1)) except ValueError: page = 1 query = request.GET.get('query') users_query = self._user_query(query, page - 1, limit) total_records = users_query.count() users_data = users_query.run() return json_response({ 'response': { 'itemList': list(map(self._format_user, users_data.hits)), 'total': users_data.total, 'page': page, 'query': query, 'total_records': total_records }, }) def _user_query(self, search_string, page, limit): user_data_fields = [] return login_as_user_query(self.domain, self.couch_user, search_string, limit, page * limit, user_data_fields=user_data_fields) def _format_user(self, user_json): user = CouchUser.wrap_correctly(user_json) formatted_user = { 'username': user.raw_username, 'customFields': user.user_data, 'first_name': user.first_name, 'last_name': user.last_name, 'phoneNumbers': user.phone_numbers, 'user_id': user.user_id, 'location': user.sql_location.to_json() if user.sql_location else None, } return formatted_user
class CloudcareMain(View): @use_datatables @use_jquery_ui @method_decorator(require_cloudcare_access) @method_decorator( requires_privilege_for_commcare_user(privileges.CLOUDCARE)) def dispatch(self, request, *args, **kwargs): return super(CloudcareMain, self).dispatch(request, *args, **kwargs) 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}
class FormplayerMain(View): preview = False urlname = 'formplayer_main' @use_datatables @use_jquery_ui @method_decorator(require_cloudcare_access) @method_decorator( requires_privilege_for_commcare_user(privileges.CLOUDCARE)) def dispatch(self, request, *args, **kwargs): return super(FormplayerMain, self).dispatch(request, *args, **kwargs) def fetch_app(self, domain, app_id): username = self.request.couch_user.username if (toggles.CLOUDCARE_LATEST_BUILD.enabled(domain) or toggles.CLOUDCARE_LATEST_BUILD.enabled(username)): return get_latest_build_doc(domain, app_id) else: return get_latest_released_app_doc(domain, app_id) def get_web_apps_available_to_user(self, domain, user): app_access = get_application_access_for_domain(domain) app_ids = get_app_ids_in_domain(domain) apps = list( map( lambda app_id: self.fetch_app(domain, app_id), app_ids, )) apps = filter(None, apps) apps = filter(lambda app: app.get('cloudcare_enabled') or self.preview, apps) apps = filter(lambda app: app_access.user_can_access_app(user, app), apps) role = None try: role = user.get_role(domain) except DomainMembershipError: # User has access via domain mirroring pass if role: apps = [ _format_app(app) for app in apps if role.permissions.view_web_app(app['copy_of'] or app['_id']) ] apps = sorted(apps, key=lambda app: app['name']) return apps @staticmethod def get_restore_as_user(request, domain): """ returns (user, set_cookie), where set_cookie is a function to be called on the eventual response """ if not hasattr(request, 'couch_user'): raise Http404() def set_cookie(response): # set_coookie is a noop by default return response cookie_name = six.moves.urllib.parse.quote('restoreAs:{}:{}'.format( domain, request.couch_user.username)) username = request.COOKIES.get(cookie_name) if username: user = CouchUser.get_by_username(format_username(username, domain)) if user: return user, set_cookie else: def set_cookie( response): # overwrite the default noop set_cookie response.delete_cookie(cookie_name) return response elif request.couch_user.has_permission(domain, 'limited_login_as'): login_as_users = login_as_user_query(domain, request.couch_user, search_string='', limit=1, offset=0).run() if login_as_users.total == 1: def set_cookie(response): response.set_cookie(cookie_name, user.raw_username) return response user = CouchUser.get_by_username( login_as_users.hits[0]['username']) return user, set_cookie return request.couch_user, set_cookie def get(self, request, domain): option = request.GET.get('option') if option == 'apps': return self.get_option_apps(request, domain) else: return self.get_main(request, domain) def get_option_apps(self, request, domain): restore_as, set_cookie = self.get_restore_as_user(request, domain) apps = self.get_web_apps_available_to_user(domain, restore_as) return JsonResponse(apps, safe=False) def get_main(self, request, domain): restore_as, set_cookie = self.get_restore_as_user(request, domain) apps = self.get_web_apps_available_to_user(domain, restore_as) def _default_lang(): try: return apps[0]['langs'][0] except Exception: 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() domain_obj = Domain.get_by_name(domain) context = { "domain": domain, "default_geocoder_location": domain_obj.default_geocoder_location, "language": language, "apps": apps, "domain_is_on_trial": domain_is_on_trial(domain), "mapbox_access_token": settings.MAPBOX_ACCESS_TOKEN, "username": request.couch_user.username, "formplayer_url": settings.FORMPLAYER_URL, "single_app_mode": False, "home_url": reverse(self.urlname, args=[domain]), "environment": WEB_APPS_ENVIRONMENT, 'use_live_query': toggles.FORMPLAYER_USE_LIVEQUERY.enabled(domain), "integrations": integration_contexts(domain), "change_form_language": toggles.CHANGE_FORM_LANGUAGE.enabled(domain), "has_geocoder_privs": domain_has_privilege(domain, privileges.GEOCODER), } return set_cookie( render(request, "cloudcare/formplayer_home.html", context))