Esempio n. 1
0
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)
Esempio n. 2
0
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)
Esempio n. 3
0
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)
Esempio n. 4
0
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))
Esempio n. 5
0
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
Esempio n. 6
0
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}
Esempio n. 7
0
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))