Example #1
0
    def handle(self, user, **options):
        try:
            self.user = CouchUser.get_by_username(user)
            if not self.user:
                self.user = CouchUser.get(user)
        except ResourceNotFound:
            print("Could not find user {}".format(user))
            return

        if not isinstance(self.user, CommCareUser):
            print ("Sorry, the user you specify has to be a mobile worker. "
                   "This changed when delete_cases was refactored to use "
                   "cases_by_owner/view instead of case/by_owner. "
                   "The new view needs an explicit domain, "
                   "and I didn't implement that for WebUsers who can belong "
                   "to multiple domains, but usually do not own cases.")
            exit(1)

        self.domain = self.user.domain

        if should_use_sql_backend(self.domain):
            raise CommandError('This command only works for couch-based domains.')

        if not options.get('no_prompt'):
            msg = "Delete all cases owned by {}? (y/n)\n".format(
                self.user.username,
            )
            if not input(msg) == 'y':
                print("cancelling")
                return

        self.delete_all()
        print("Cases successfully deleted, you monster!")
Example #2
0
def update_users_at_locations(domain, location_ids, supply_point_ids, ancestor_ids):
    """
    Update location fixtures for users given locations
    """
    from corehq.apps.users.models import CouchUser, update_fixture_status_for_users
    from corehq.apps.locations.dbaccessors import user_ids_at_locations
    from corehq.apps.fixtures.models import UserFixtureType
    from dimagi.utils.couch.database import iter_docs

    # close supply point cases
    for supply_point_id in supply_point_ids:
        close_supply_point_case(domain, supply_point_id)

    # unassign users from locations
    unassign_user_ids = user_ids_at_locations(location_ids)
    for doc in iter_docs(CouchUser.get_db(), unassign_user_ids):
        user = CouchUser.wrap_correctly(doc)
        for location_id in location_ids:
            if location_id not in user.get_location_ids(domain):
                continue
            if user.is_web_user():
                user.unset_location_by_id(domain, location_id, fall_back_to_next=True)
            elif user.is_commcare_user():
                user.unset_location_by_id(location_id, fall_back_to_next=True)

    # update fixtures for users at ancestor locations
    user_ids = user_ids_at_locations(ancestor_ids)
    update_fixture_status_for_users(user_ids, UserFixtureType.LOCATION)
Example #3
0
def can_edit_form_location(domain, web_user, form):
    # Domain admins can always edit locations.  If the user isn't an admin and
    # the location restriction is enabled, they can only edit forms that are
    # explicitly at or below them in the location tree.

    # This first block checks for old permissions, remove when that's gone
    if toggles.RESTRICT_FORM_EDIT_BY_LOCATION.enabled(domain):
        domain_obj = Domain.get_by_name(domain)
        if user_can_edit_any_location(web_user, domain_obj):
            return True
        if not form.user_id:
            return False
        form_user = CouchUser.get_by_user_id(form.user_id)
        if domain_obj.supports_multiple_locations_per_user:
            form_locations = [loc.sql_location for loc in form_user.locations]
        else:
            form_locations = form_user.get_sql_locations(domain)
        for location in form_locations:
            if user_can_edit_location(web_user, location, domain_obj):
                return True
        return False

    if web_user.has_permission(domain, 'access_all_locations'):
        return True

    if not form.user_id:
        return False

    form_user = CouchUser.get_by_user_id(form.user_id)
    if not form_user:
        return False  # It's a special form, deny to be safe
    form_location_ids = form_user.get_location_ids(domain)
    return user_can_access_any_location_id(domain, web_user, form_location_ids)
Example #4
0
 def test_web_user_flag(self):
     self.assertTrue(WebUser().is_web_user())
     self.assertTrue(CouchUser.wrap(WebUser().to_json()).is_web_user())
     self.assertFalse(CommCareUser().is_web_user())
     self.assertFalse(CouchUser.wrap(CommCareUser().to_json()).is_web_user())
     with self.assertRaises(NotImplementedError):
         CouchUser().is_web_user()
Example #5
0
    def _get_username(self, user_id):
        username = self.report.usernames.get(user_id)
        if not username:
            mc = cache.caches['default']
            cache_key = "%s.%s" % (CouchUser.__class__.__name__, user_id)

            try:
                if mc.has_key(cache_key):
                    user_dict = json.loads(mc.get(cache_key))
                else:
                    user_obj = CouchUser.get_by_user_id(user_id) if user_id else None
                    if user_obj:
                        user_dict = user_obj.to_json()
                    else:
                        user_dict = {}
                    cache_payload = json.dumps(user_dict)
                    mc.set(cache_key, cache_payload)
                if user_dict == {}:
                    return None
                else:
                    user_obj = CouchUser.wrap(user_dict)
                    username = user_obj.username
            except Exception:
                return None
        return username
Example #6
0
    def handle(self, *args, **options):
        self.last_submitter = options.get('last_submitter', False)
        if not len(args):
            print "Usage: ./manage.py delete_cases <user>"
            return
        try:
            self.user = CouchUser.get_by_username(args[0])
            if not self.user:
                self.user = CouchUser.get(args[0])
        except ResourceNotFound:
            print "Could not find user {}".format(args[0])
            return

        if not options.get('no_prompt'):
            msg = "Delete all {} cases {} by {}? (y/n)\n".format(
                self.get_case_count(),
                "submitted" if self.last_submitter else "owned",
                self.user.username,
            )
            if not raw_input(msg) == 'y':
                print "cancelling"
                return

        self.delete_all()
        print "Cases successfully deleted, you monster!"
Example #7
0
    def handle(self, *args, **options):
        if not len(args):
            print "Usage: ./manage.py delete_cases <user>"
            return
        try:
            self.user = CouchUser.get_by_username(args[0])
            if not self.user:
                self.user = CouchUser.get(args[0])
        except ResourceNotFound:
            print "Could not find user {}".format(args[0])
            return

        if not isinstance(self.user, CommCareUser):
            print ("Sorry, the user you specify has to be a mobile worker. "
                   "This changed when delete_cases was refactored to use "
                   "cases_by_owner/view instead of case/by_owner. "
                   "The new view needs an explicit domain, "
                   "and I didn't implement that for WebUsers who can belong "
                   "to multiple domains, but usually do not own cases.")
            exit(1)

        self.domain = self.user.domain

        if not options.get('no_prompt'):
            msg = "Delete all cases owned by {}? (y/n)\n".format(
                self.user.username,
            )
            if not raw_input(msg) == 'y':
                print "cancelling"
                return

        self.delete_all()
        print "Cases successfully deleted, you monster!"
Example #8
0
 def filter(self):
     user_ids = set(CouchUser.ids_by_domain(self.domain))
     user_ids.update(CouchUser.ids_by_domain(self.domain, is_active=False))
     f = SerializableFunction(form_matches_users, users=user_ids)
     if self.app_id is not None:
         f.add(reports.util.app_export_filter, app_id=self.app_id)
     if not self.include_errors:
         f.add(couchforms.filters.instances)
     return f
Example #9
0
def save_copy(request, domain, app_id):
    """
    Saves a copy of the app to a new doc.
    See VersionedDoc.save_copy

    """
    track_built_app_on_hubspot_v2.delay(request.couch_user)
    comment = request.POST.get('comment')
    app = get_app(domain, app_id)
    try:
        errors = app.validate_app()
    except ModuleIdMissingException:
        # For apps (mainly Exchange apps) that lost unique_id attributes on Module
        app.ensure_module_unique_ids(should_save=True)
        errors = app.validate_app()

    if not errors:
        try:
            user_id = request.couch_user.get_id
            timer = datadog_bucket_timer('commcare.app_build.new_release', tags=[],
                                         timing_buckets=(1, 10, 30, 60, 120, 240))
            with timer:
                copy = app.make_build(
                    comment=comment,
                    user_id=user_id,
                )
                copy.save(increment_version=False)
            CouchUser.get(user_id).set_has_built_app()
        finally:
            # To make a RemoteApp always available for building
            if app.is_remote_app():
                app.save(increment_version=True)

        _track_build_for_app_preview(domain, request.couch_user, app_id, 'User created a build')

    else:
        copy = None
    copy = copy and SavedAppBuild.wrap(copy.to_json()).releases_list_json(
        get_timezone_for_user(request.couch_user, domain)
    )
    lang, langs = get_langs(request, app)
    if copy:
        # Set if build is supported for Java Phones
        j2me_enabled_configs = CommCareBuildConfig.j2me_enabled_config_labels()
        copy['j2me_enabled'] = copy['menu_item_label'] in j2me_enabled_configs

    return json_response({
        "saved_app": copy,
        "error_html": render_to_string("app_manager/partials/build_errors.html", {
            'request': request,
            'app': get_app(domain, app_id),
            'build_errors': errors,
            'domain': domain,
            'langs': langs,
            'lang': lang
        }),
    })
Example #10
0
def get_users_assigned_to_locations(domain):
    from corehq.apps.users.models import CouchUser
    ids = [res['id'] for res in CouchUser.get_db().view(
        'users_extra/users_by_location_id',
        startkey=[domain],
        endkey=[domain, {}],
        include_docs=False,
        reduce=False,
    )]
    return map(CouchUser.wrap_correctly, iter_docs(CouchUser.get_db(), ids))
Example #11
0
def get_all_users_by_location(domain, location_id):
    from corehq.apps.users.models import CouchUser
    results = CouchUser.get_db().view(
        'users_extra/users_by_location_id',
        startkey=[domain, location_id],
        endkey=[domain, location_id, {}],
        include_docs=True,
        reduce=False,
    )
    return (CouchUser.wrap_correctly(res['doc']) for res in results)
Example #12
0
    def recipient(self):
        if self.recipient_type == self.RECIPIENT_TYPE_CASE:
            try:
                case = CaseAccessors(self.domain).get_case(self.recipient_id)
            except CaseNotFound:
                return None

            if case.domain != self.domain:
                return None

            return case
        elif self.recipient_type == self.RECIPIENT_TYPE_MOBILE_WORKER:
            user = CouchUser.get_by_user_id(self.recipient_id, domain=self.domain)
            if not isinstance(user, CommCareUser):
                return None

            return user
        elif self.recipient_type == self.RECIPIENT_TYPE_WEB_USER:
            user = CouchUser.get_by_user_id(self.recipient_id, domain=self.domain)
            if not isinstance(user, WebUser):
                return None

            return user
        elif self.recipient_type == self.RECIPIENT_TYPE_CASE_GROUP:
            try:
                group = CommCareCaseGroup.get(self.recipient_id)
            except ResourceNotFound:
                return None

            if group.domain != self.domain:
                return None

            return group
        elif self.recipient_type == self.RECIPIENT_TYPE_USER_GROUP:
            try:
                group = Group.get(self.recipient_id)
            except ResourceNotFound:
                return None

            if group.domain != self.domain:
                return None

            return group
        elif self.recipient_type == self.RECIPIENT_TYPE_LOCATION:
            location = SQLLocation.by_location_id(self.recipient_id)

            if location is None:
                return None

            if location.domain != self.domain:
                return None

            return location
        else:
            raise UnknownRecipientType(self.recipient_type)
Example #13
0
    def handle(self, *args, **options):
        self.stdout.write("Population location_id field...\n")

        relevant_ids = set([r['id'] for r in CouchUser.get_db().view(
            'users/by_username',
            reduce=False,
        ).all()])

        to_save = []

        domain_cache = {}

        exclude = (
            "drewpsi",
            "psi",
            "psi-ors",
            "psi-test",
            "psi-test2",
            "psi-test3",
            "psi-unicef",
            "psi-unicef-wb",
        )

        def _is_location_domain(domain):
            if domain in domain_cache:
                return domain_cache[domain]
            else:
                domain_obj = Domain.get_by_name(domain)
                val = domain_obj.uses_locations
                domain_cache[domain] = val
                return val

        for user_doc in iter_docs(CommCareUser.get_db(), relevant_ids):
            if user_doc['doc_type'] == 'WebUser':
                continue

            if user_doc['domain'] in exclude:
                continue

            if not _is_location_domain(user_doc['domain']):
                continue

            user = CommCareUser.get(user_doc['_id'])

            if user._locations:
                user_doc['location_id'] = user._locations[0]._id
                to_save.append(user_doc)

            if len(to_save) > 500:
                self.stdout.write("Saving 500")
                CouchUser.get_db().bulk_save(to_save)
                to_save = []

        if to_save:
            CouchUser.get_db().bulk_save(to_save)
Example #14
0
 def testChangeUsername(self):
     new_username = '******'
     self.assertEqual(CouchUser.get_by_username(self.username).user_id, self.couch_user.user_id)
     self.assertEqual(User.objects.filter(username=self.username).count(), 1)
     self.couch_user.change_username(new_username)
     self.assertEqual(CouchUser.get_by_username(self.username), None)
     self.assertEqual(CouchUser.get_by_username(new_username).user_id, self.couch_user.user_id)
     self.assertEqual(self.couch_user.get_django_user().username, new_username)
     self.assertEqual(User.objects.filter(username=new_username).count(), 1)
     self.assertEqual(User.objects.get(username=new_username).id, self.couch_user.get_django_user().id)
     self.assertEqual(User.objects.filter(username=self.username).count(), 0)
Example #15
0
    def __call__(self, request, invitation_id, **kwargs):
        # add the correct parameters to this instance
        self.request = request
        for k, v in kwargs.iteritems():
            if k in self.need:
                setattr(self, k, v)

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

        invitation = self.inv_type.get(invitation_id)

        if invitation.is_accepted:
            messages.error(request, "Sorry, that invitation has already been used up. "
                                    "If you feel this is a mistake please ask the inviter for "
                                    "another invitation.")
            return HttpResponseRedirect(reverse("login"))

        self.validate_invitation(invitation)

        if request.user.is_authenticated():
            if request.couch_user.username != invitation.email:
                messages.error(request, "The invited user %s and your user %s do not match!" % (invitation.email, request.couch_user.username))

            if request.method == "POST":
                couch_user = CouchUser.from_django_user(request.user)
                self._invite(invitation, couch_user)
                return HttpResponseRedirect(self.redirect_to_on_success)
            else:
                mobile_user = CouchUser.from_django_user(request.user).is_commcare_user()
                context = self.added_context()
                context.update({
                    'mobile_user': mobile_user,
                    "invited_user": invitation.email if request.couch_user.username != invitation.email else "",
                })
                return render(request, self.template, context)
        else:
            if request.method == "POST":
                form = NewWebUserRegistrationForm(request.POST)
                if form.is_valid():
                    # create the new user
                    user = activate_new_user(form)
                    user.save()
                    messages.success(request, "User account for %s created! You may now login." % form.cleaned_data["email"])
                    self._invite(invitation, user)
                    return HttpResponseRedirect(reverse("login"))
            else:
                form = NewWebUserRegistrationForm(initial={'email': invitation.email})

        return render(request, self.template, {"form": form})
Example #16
0
def sync_phone_numbers_for_domain(domain):
    for user_id in CouchUser.ids_by_domain(domain, is_active=True):
        _sync_user_phone_numbers(user_id)

    for user_id in CouchUser.ids_by_domain(domain, is_active=False):
        _sync_user_phone_numbers(user_id)

    case_ids = CaseAccessors(domain).get_case_ids_in_domain()
    for case in CaseAccessors(domain).iter_cases(case_ids):
        _sync_case_phone_number(case)

    MigrationStatus.set_migration_completed('phone_sync_domain_%s' % domain)
Example #17
0
    def testPhoneUsersViewLastCommCareUsername(self):
        self.couch_user.delete()
        phone_user_count = CouchUser.phone_users_by_domain(self.domain).count()
        self.assertEquals(phone_user_count, 0)

        couch_user = WebUser.create(self.domain, 'commcare_username_2', 'password')
        couch_user.add_phone_number(123)
        couch_user.save()

        phone_user_count = CouchUser.phone_users_by_domain(self.domain).count()
        self.assertEquals(phone_user_count, 1)
        phone_user = CouchUser.phone_users_by_domain(self.domain).one()
        self.assertEquals(phone_user.username, 'commcare_username_2')
 def handle(self, *args, **options):
     db = CouchUser.get_db()
     # This view includes users with base_doc == CouchUser-Deleted
     for res in db.view("users/by_default_phone", include_docs=True, reduce=False):
         doc = res['doc']
         # if this condition is met, the doc can't be wrapped
         if doc['email'] and not doc['email'].islower():
             print doc['email']
             doc['email'] = doc['email'].lower()
             try:
                 user = CouchUser.wrap_correctly(doc)
                 user.save()
             except:
                 print doc['_id'], "failed to save"
 def handle(self, *args, **options):
     run_fix = options.get(RUN_FIX, False)
     for user in CouchUser.all():
         doc_json = CouchUser.get_db().get(user.get_id)
         if doc_json.get("doc_type", None) == "WebUser" and (
             user.created_on is not None and user.created_on >= datetime.datetime(*[int(_) for _ in args[0:3]])
         ):
             if user.email_opt_out:
                 if run_fix:
                     user.email_opt_out = False
                     user.save()
                     print("fixed %s, created on %s" % (user.get_id, user.created_on))
                 else:
                     print("should fix %s, created on %s" % (user.get_id, user.created_on))
Example #20
0
    def filter(self):
        user_ids = set(CouchUser.ids_by_domain(self.domain))
        user_ids.update(CouchUser.ids_by_domain(self.domain, is_active=False))
        def _top_level_filter(form):
            # careful, closures used
            return form_matches_users(form, user_ids) or is_commconnect_form(form)

        f = SerializableFunction(_top_level_filter)
        if self.app_id is not None:
            f.add(reports.util.app_export_filter, app_id=self.app_id)
        if not self.include_errors:
            f.add(couchforms.filters.instances)
        actual = SerializableFunction(default_form_filter, filter=f)
        return actual
Example #21
0
    def process_view(self, request, view_func, view_args, view_kwargs):
        if 'domain' in view_kwargs:
            request.domain = view_kwargs['domain']
        if 'org' in view_kwargs:
            request.org = view_kwargs['org']
        if request.user and hasattr(request.user, 'get_profile'):
            sessionid = request.COOKIES.get('sessionid', None)
            if sessionid:
                # roundabout way to keep doc_id based caching consistent.
                # get user doc_id from session_id
                MISSING = object()
                INTERRUPTED = object()
                try:
                    cached_user_doc_id = rcache.get(SESSION_USER_KEY_PREFIX % sessionid, MISSING)
                except ConnectionInterrumped:
                    cached_user_doc_id = INTERRUPTED

                # disable session based couch user caching - to be enabled later.
                if cached_user_doc_id not in (MISSING, INTERRUPTED):
                    # cache hit
                    couch_user = CouchUser.wrap_correctly(
                        cache_core.cached_open_doc(
                            CouchUser.get_db(), cached_user_doc_id
                        )
                    )
                else:
                    # cache miss, write to cache
                    couch_user = CouchUser.from_django_user(request.user)
                    if couch_user:
                        cache_core.do_cache_doc(couch_user.to_json())
                        if cached_user_doc_id is not INTERRUPTED:
                            rcache.set(SESSION_USER_KEY_PREFIX % sessionid, couch_user.get_id)
                request.couch_user = couch_user

            if 'domain' in view_kwargs:
                domain = request.domain
                if not request.couch_user:
                    couch_domain = Domain.view("domain/domains",
                        key=domain,
                        reduce=False,
                        include_docs=True,
                    ).one()
                    if couch_domain and couch_domain.is_public:
                        request.couch_user = PublicUser(domain)
                    else:
                        request.couch_user = InvalidUser()
                if request.couch_user:
                    request.couch_user.current_domain = domain
        return None
Example #22
0
def _unassign_users_from_location(domain, location_id):
    """
    Unset location for all users assigned to that location.
    """
    from corehq.apps.locations.dbaccessors import user_ids_at_locations
    from corehq.apps.users.models import CouchUser
    from dimagi.utils.couch.database import iter_docs

    user_ids = user_ids_at_locations([location_id])
    for doc in iter_docs(CouchUser.get_db(), user_ids):
        user = CouchUser.wrap_correctly(doc)
        if user.is_web_user():
            user.unset_location_by_id(domain, location_id, fall_back_to_next=True)
        elif user.is_commcare_user():
            user.unset_location_by_id(location_id, fall_back_to_next=True)
Example #23
0
    def clean(self):
        try:
            password = self.cleaned_data['password']
            password_2 = self.cleaned_data['password_2']
        except KeyError:
            pass
        else:
            if password != password_2:
                raise forms.ValidationError("Passwords do not match")
            if self.password_format == 'n' and not password.isnumeric():
                raise forms.ValidationError("Password is not numeric")

        try:
            username = self.cleaned_data['username']
        except KeyError:
            pass
        else:
            if len(username) > CommCareAccountForm.max_len_username:
                raise forms.ValidationError(
                    "Username %s is too long.  Must be under %d characters."
                    % (username, CommCareAccountForm.max_len_username))
            validate_username('*****@*****.**' % username)
            domain = self.cleaned_data['domain']
            username = format_username(username, domain)
            num_couch_users = len(CouchUser.view("users/by_username",
                                                 key=username,
                                                 reduce=False))
            if num_couch_users > 0:
                raise forms.ValidationError("CommCare user already exists")

            # set the cleaned username to [email protected]
            self.cleaned_data['username'] = username
        return self.cleaned_data
Example #24
0
    def post(self, request, *args, **kwargs):
        try:
            data = json.loads(request.body)
        except ValueError:
            return HttpResponseBadRequest()

        if not data or not isinstance(data, dict):
            return HttpResponseBadRequest()

        session_id = data.get('sessionId', None)
        if not session_id:
            return HttpResponseBadRequest()

        user = get_django_user_from_session_key(session_id)
        if user:
            couch_user = CouchUser.get_by_username(user.username)
            if not couch_user:
                raise Http404
        else:
            raise Http404

        return JsonResponse({
            'username': user.username,
            'djangoUserId': user.pk,
            'superUser': user.is_superuser,
            'authToken': None,
            'domains': couch_user.domains,
            'anonymous': False
        })
Example #25
0
    def __setstate__(self, state):
        """
            For unpickling a pickled report.
        """
        logging = get_task_logger(__name__) # logging lis likely to happen within celery.
        self.domain = state.get('domain')
        self.context = state.get('context', {})

        class FakeHttpRequest(object):
            GET = {}
            META = {}
            couch_user = None
            datespan = None

        request_data = state.get('request')
        request = FakeHttpRequest()
        request.GET = request_data.get('GET', {})
        request.META = request_data.get('META', {})
        request.datespan = request_data.get('datespan')

        try:
            couch_user = CouchUser.get(request_data.get('couch_user'))
            request.couch_user = couch_user
        except Exception as e:
            logging.error("Could not unpickle couch_user from request for report %s. Error: %s" %
                            (self.name, e))
        self.request = request
        self._caching = True
        self.request_params = state.get('request_params')
        self._update_initial_context()
Example #26
0
def verify_phone_number(request, domain, couch_user_id):
    """
    phone_number cannot be passed in the url due to special characters
    but it can be passed as %-encoded GET parameters
    """
    if 'phone_number' not in request.GET:
        return Http404('Must include phone number in request.')
    phone_number = urllib.unquote(request.GET['phone_number'])
    user = CouchUser.get_by_user_id(couch_user_id, domain)

    try:
        # send verification message
        smsverify.send_verification(domain, user, phone_number)

        # create pending verified entry if doesn't exist already
        user.save_verified_number(domain, phone_number, False, None)
    except BadSMSConfigException:
        messages.error(request, "Could not verify phone number. It seems there is no usable SMS backend.")

    if user.is_commcare_user():
        from corehq.apps.users.views.mobile import EditCommCareUserView
        redirect = reverse(EditCommCareUserView.urlname, args=[domain, couch_user_id])
    else:
        redirect = reverse(EditMyAccountDomainView.urlname, args=[domain])
    return HttpResponseRedirect(redirect)
Example #27
0
    def update_user(self, existing_user=None, save=True, **kwargs):
        is_update_successful = False

        # From what I can tell, everything that invokes this method invokes it
        # with a value for existing_user. It also looks like the code below is
        # not behaving properly for mobile workers when existing_user is None.
        # If the soft asserts confirm this isn't ever being passed existing_user=None,
        # I propose making existing_user a required arg and removing the code below
        # that creates the user.
        _assert = soft_assert('@'.join(['gcapalbo', 'dimagi.com']), exponential_backoff=False)
        _assert(existing_user is not None, "existing_user is None")

        if not existing_user and 'email' in self.cleaned_data:
            from django.contrib.auth.models import User
            django_user = User()
            django_user.username = self.cleaned_data['email']
            django_user.save()
            existing_user = CouchUser.from_django_user(django_user)
            existing_user.save()
            is_update_successful = True

        for prop in self.direct_properties:
            setattr(existing_user, prop, self.cleaned_data[prop])
            is_update_successful = True

        if is_update_successful and save:
            existing_user.save()
        return is_update_successful
Example #28
0
    def post_list(self, request, **kwargs):
        domain = kwargs.get('domain')
        request.domain = domain
        username = request.POST.get('username')
        password = request.POST.get('password')

        if username is None:
            return HttpResponseBadRequest('Missing required parameter: username')

        if password is None:
            return HttpResponseBadRequest('Missing required parameter: password')

        if '@' not in username:
            username = format_username(username, domain)

        # Convert to the appropriate type of user
        couch_user = CouchUser.get_by_username(username)
        if couch_user is None or not couch_user.is_member_of(domain) or not couch_user.check_password(password):
            return HttpResponseForbidden()

        if couch_user.is_commcare_user():
            user_resource = v0_1.CommCareUserResource()
        elif couch_user.is_web_user():
            user_resource = v0_1.WebUserResource()
        else:
            return HttpResponseForbidden()

        bundle = user_resource.build_bundle(obj=couch_user, request=request)
        bundle = user_resource.full_dehydrate(bundle)
        return user_resource.create_response(request, bundle, response_class=HttpResponse)
Example #29
0
    def handle(self, *args, **options):
        if len(args) != 3:
            raise CommandError('Usage is duplicate_cases %s' % self.args)

        start = datetime.now()
        case_id_file, user_id, domain = args
        self.submit_url = URL_BASE + get_submit_url(domain)
        print self.submit_url

        user = CouchUser.get_by_user_id(user_id, domain)
        user_id = user._id
        if not user.is_member_of(domain):
            raise CommandError("%s can't access %s" % (user, domain))

        self.read_progress()

        with open(case_id_file, 'r') as f:
            case_ids = f.readlines()

        try:
            for id in case_ids:
                self.duplicate_case(id.strip(), domain, user_id)
        finally:
            self.write_progress()

        print 'finished in %s seconds' % (datetime.now() - start).seconds
        print '{} cases processed'.format(len(self.cases_processing.keys()))
        print '{} forms processed'.format(len(self.forms_processing.keys()))
Example #30
0
    def recipient(self):
        if self.recipient_type == self.RECIPIENT_TYPE_SELF:
            return self.case
        elif self.recipient_type == self.RECIPIENT_TYPE_CASE_OWNER:
            return self.case_owner
        elif self.recipient_type == self.RECIPIENT_TYPE_LAST_SUBMITTING_USER:
            if self.case and self.case.modified_by:
                return CouchUser.get_by_user_id(self.case.modified_by, domain=self.domain)

            return None
        elif self.recipient_type == self.RECIPIENT_TYPE_PARENT_CASE:
            if self.case:
                return self.case.parent

            return None
        elif self.recipient_type == self.RECIPIENT_TYPE_ALL_CHILD_CASES:
            if self.case:
                return list(self.case.get_subcases(index_identifier=DEFAULT_PARENT_IDENTIFIER))

            return None
        elif self.recipient_type == self.RECIPIENT_TYPE_CUSTOM:
            custom_function = to_function(
                settings.AVAILABLE_CUSTOM_SCHEDULING_RECIPIENTS[self.recipient_id][0]
            )
            return custom_function(self)
        else:
            return super(CaseScheduleInstanceMixin, self).recipient
Example #31
0
    def obj_get_list(self, bundle, **kwargs):
        application_id = bundle.request.GET.get('application_id')
        if not application_id:
            raise NotFound('application_id parameter required')

        domain = kwargs['domain']
        couch_user = CouchUser.from_django_user(bundle.request.user)
        if not domain_has_privilege(domain, privileges.ZAPIER_INTEGRATION) or not couch_user.is_member_of(domain):
            raise ImmediateHttpResponse(
                HttpForbidden('You are not allowed to get list of forms for this domain')
            )

        results = []
        application = Application.get(docid=application_id)
        if not application:
            return []
        forms_objects = application.get_forms(bare=False)

        for form_object in forms_objects:
            form = form_object['form']
            module = form_object['module']
            form_name = u'{} > {} > {}'.format(application.name, module.name['en'], form.name['en'])
            results.append(Form(form_xmlns=form.xmlns, form_name=form_name))
        return results
Example #32
0
    def get_recipient_info(self, message, contact_cache):
        recipient_id = message.couch_recipient

        if recipient_id in contact_cache:
            return contact_cache[recipient_id]

        doc = None
        if recipient_id not in [None, ""]:
            try:
                if message.couch_recipient_doc_type == "CommCareCase":
                    doc = CommCareCase.get(recipient_id)
                else:
                    doc = CouchUser.get_by_user_id(recipient_id)
            except Exception:
                pass

        if doc:
            doc_info = get_doc_info(doc.to_json(), self.domain)
        else:
            doc_info = None

        contact_cache[recipient_id] = doc_info

        return doc_info
Example #33
0
def _sync_user_phone_numbers(couch_user_id):
    couch_user = CouchUser.get_by_user_id(couch_user_id)

    if not isinstance(couch_user, CommCareUser):
        # It isn't necessary to sync WebUser's phone numbers right now
        # and we need to think through how to support entries when a user
        # can belong to multiple domains
        return

    with CriticalSection([couch_user.phone_sync_key], timeout=5 * 60):
        phone_entries = couch_user.get_phone_entries()

        if (couch_user.is_deleted() or
            (not couch_user.is_active and
             not USE_SMS_WITH_INACTIVE_CONTACTS.enabled(couch_user.domain))):
            for phone_number in phone_entries.values():
                phone_number.delete()
            return

        numbers_that_should_exist = [
            apply_leniency(phone_number)
            for phone_number in couch_user.phone_numbers
        ]

        # Delete entries that should not exist
        for phone_number in phone_entries.keys():
            if phone_number not in numbers_that_should_exist:
                phone_entries[phone_number].delete()

        # Create entries that should exist but do not exist
        for phone_number in numbers_that_should_exist:
            if phone_number not in phone_entries:
                try:
                    couch_user.create_phone_entry(phone_number)
                except InvalidFormatException:
                    pass
Example #34
0
def claim(request, domain):
    """
    Allows a user to claim a case that they don't own.
    """
    couch_user = CouchUser.from_django_user(request.user)
    case_id = request.POST['case_id']
    if (request.session.get('last_claimed_case_id') == case_id
            or get_first_claim(domain, couch_user.user_id, case_id)):
        return HttpResponse('You have already claimed that {}'.format(
            request.POST.get('case_type', 'case')),
                            status=409)
    try:
        claim_case(domain,
                   couch_user.user_id,
                   case_id,
                   host_type=request.POST.get('case_type'),
                   host_name=request.POST.get('case_name'))
    except CaseNotFound:
        return HttpResponse(
            'The case "{}" you are trying to claim was not found'.format(
                case_id),
            status=410)
    request.session['last_claimed_case_id'] = case_id
    return HttpResponse(status=200)
Example #35
0
 def _clear_cache(doc):
     user = CouchUser.wrap_correctly(doc, allow_deleted_doc_types=True)
     user.clear_quickcache_for_user()
Example #36
0
def _ensure_request_couch_user(request):
    couch_user = getattr(request, 'couch_user', None)
    if not couch_user and hasattr(request, 'user'):
        request.couch_user = couch_user = CouchUser.from_django_user(
            request.user)
    return couch_user
Example #37
0
    def __call__(self, request, uuid, **kwargs):
        # add the correct parameters to this instance
        self.request = request
        if 'domain' in kwargs:
            self.domain = kwargs['domain']

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

        # Recently-sent invitations will use a URL based on UUID
        try:
            invitation = SQLInvitation.objects.get(uuid=uuid)
        except (SQLInvitation.DoesNotExist, ValidationError):
            invitation = None

        # Older invitations, created before PR#26975, will use a URL based on SQL id
        if not invitation:
            try:
                invitation = SQLInvitation.objects.get(id=int(uuid))
            except (SQLInvitation.DoesNotExist, ValueError):
                invitation = None

        # The oldest invitations, created before PR#26686, will use a URL based on couch id.
        if not invitation:
            invitation = SQLInvitation.objects.filter(couch_id=uuid).first()

        if not invitation:
            messages.error(
                request,
                _("Sorry, it looks like your invitation has expired. "
                  "Please check the invitation link you received and try again, or "
                  "request a project administrator to send you the invitation again."
                  ))
            return HttpResponseRedirect(reverse("login"))

        if invitation.is_accepted:
            messages.error(
                request,
                _("Sorry, that invitation has already been used up. "
                  "If you feel this is a mistake please ask the inviter for "
                  "another invitation."))
            return HttpResponseRedirect(reverse("login"))

        self.validate_invitation(invitation)

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

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

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

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

        context.update({"form": form})
        return render(request, self.template, context)
Example #38
0
def get_display_name_for_user_id(domain, user_id, default=None):
    if user_id:
        user = CouchUser.get_by_user_id(user_id, domain)
        if user:
            return user.full_name
    return default
Example #39
0
 def all_users(self):
     from corehq.apps.users.models import CouchUser
     return CouchUser.by_domain(self.name)
 def create_request(cls, request_url):
     request = RequestFactory().get(request_url)
     request.couch_user = CouchUser()
     return request
Example #41
0
def account(request, domain, couch_user_id, template="users/account.html"):
    context = _users_context(request, domain)
    try:
        couch_user = CouchUser.get_by_user_id(couch_user_id, domain)
    except ResourceNotFound:
        raise Http404

    if not couch_user:
        raise Http404

    editing_commcare_user = couch_user.is_commcare_user() and request.couch_user.can_edit_commcare_users
    context.update({
        'couch_user': couch_user,
        'editing_commcare_user': editing_commcare_user,
    })
    if couch_user.is_commcare_user():
        context.update({
            'reset_password_form': SetPasswordForm(user=""),
            'only_numeric': (request.project.password_format() == 'n'),
        })

    if couch_user.is_deleted():
        if couch_user.is_commcare_user():
            return render(request, 'users/deleted_account.html', context)
        else:
            raise Http404

    # phone-numbers tab
    if request.method == "POST" and \
       request.POST['form_type'] == "phone-numbers" and \
       (couch_user.is_current_web_user(request) or couch_user.is_commcare_user()):
        phone_number = request.POST['phone_number']
        phone_number = re.sub('\s', '', phone_number)
        if re.match(r'\d+$', phone_number):
            couch_user.add_phone_number(phone_number)
            couch_user.save()
        else:
            messages.error(request, "Please enter digits only")

    # domain-accounts tab
    if not couch_user.is_commcare_user():
        all_domains = couch_user.get_domains()
        admin_domains = []
        for d in all_domains:
            if couch_user.is_domain_admin(d):
                admin_domains.append(d)
        context.update({"user": request.user,
                        "domains": admin_domains
        })
        # scheduled reports tab
    context.update({
        'phone_numbers_extended': couch_user.phone_numbers_extended(request.couch_user),
    })

    #project settings tab
    if couch_user.user_id == request.couch_user.user_id:
        dm = couch_user.get_domain_membership(domain)
        if dm:
            domain_obj = Domain.get_by_name(domain)
            if request.method == "POST" and request.POST['form_type'] == "project-settings":
                # deal with project settings data
                project_settings_form = ProjectSettingsForm(request.POST)
                if project_settings_form.is_valid():
                    if project_settings_form.save(couch_user, domain):
                        messages.success(request, "Your project settings were successfully saved!")
                    else:
                        messages.error(request, "There seems to have been an error saving your project settings. Please try again!")
            else:
                project_settings_form = ProjectSettingsForm(initial={'global_timezone': domain_obj.default_timezone,
                                                                     'user_timezone': dm.timezone,
                                                                     'override_global_tz': dm.override_global_tz})
            context.update({
                'proj_settings_form': project_settings_form,
                'override_global_tz': dm.override_global_tz
            })

    # commtrack
    if request.method == "POST" and request.POST['form_type'] == "commtrack":
        commtrack_form = CommtrackUserForm(request.POST, domain=domain)
        if commtrack_form.is_valid():
            commtrack_form.save(couch_user)
    else:
        linked_loc = couch_user.dynamic_properties().get('commtrack_location') # FIXME update user model appropriately
        commtrack_form = CommtrackUserForm(domain=domain, initial={'supply_point': linked_loc})
    context.update({
            'commtrack_enabled': Domain.get_by_name(domain).commtrack_enabled,
            'commtrack_form': commtrack_form,
    })

    # for basic tab
    context.update(_handle_user_form(request, domain, couch_user))
    return render(request, template, context)
Example #42
0
def _login(req, domain_name, custom_login_page, extra_context=None):
    extra_context = extra_context or {}
    if req.user.is_authenticated and req.method == "GET":
        redirect_to = req.GET.get('next', '')
        if redirect_to:
            return HttpResponseRedirect(redirect_to)
        if not domain_name:
            return HttpResponseRedirect(reverse('homepage'))
        else:
            return HttpResponseRedirect(
                reverse('domain_homepage', args=[domain_name]))

    if req.method == 'POST' and domain_name and '@' not in req.POST.get(
            'auth-username', '@'):
        with mutable_querydict(req.POST):
            req.POST['auth-username'] = format_username(
                req.POST['auth-username'], domain_name)

    if 'auth-username' in req.POST:
        couch_user = CouchUser.get_by_username(
            req.POST['auth-username'].lower())
        if couch_user:
            new_lang = couch_user.language
            old_lang = req.session.get(LANGUAGE_SESSION_KEY)
            update_session_language(req, old_lang, new_lang)

    req.base_template = settings.BASE_TEMPLATE

    context = {}
    context.update(extra_context)
    template_name = custom_login_page if custom_login_page else 'login_and_password/login.html'
    if not custom_login_page and domain_name:
        domain_obj = Domain.get_by_name(domain_name)
        req_params = req.GET if req.method == 'GET' else req.POST
        context.update({
            'domain': domain_name,
            'hr_name': domain_obj.display_name(),
            'next': req_params.get('next', '/a/%s/' % domain_name),
            'allow_domain_requests': domain_obj.allow_domain_requests,
            'current_page': {
                'page_name':
                _('Welcome back to %s!') % domain_obj.display_name()
            },
        })
    else:
        commcare_hq_name = commcare_hq_names(
            req)['commcare_hq_names']["COMMCARE_HQ_NAME"]
        context.update({
            'current_page': {
                'page_name': _('Welcome back to %s!') % commcare_hq_name
            },
        })
    if settings.SERVER_ENVIRONMENT in settings.ICDS_ENVS:
        auth_view = CloudCareLoginView
    else:
        auth_view = HQLoginView if not domain_name else CloudCareLoginView

    demo_workflow_ab_v2 = ab_tests.SessionAbTest(ab_tests.DEMO_WORKFLOW_V2,
                                                 req)

    if settings.IS_SAAS_ENVIRONMENT:
        context['demo_workflow_ab_v2'] = demo_workflow_ab_v2.context

    response = auth_view.as_view(template_name=template_name,
                                 extra_context=context)(req)

    if settings.IS_SAAS_ENVIRONMENT:
        demo_workflow_ab_v2.update_response(response)

    return response
Example #43
0
def request_new_domain(request, form, is_new_user=True):
    now = datetime.utcnow()
    current_user = CouchUser.from_django_user(request.user)

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

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

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

        if not is_new_user:
            new_domain.is_active = True

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

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

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

    UserRole.init_domain_with_presets(new_domain.name)

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

    dom_req.domain = new_domain.name

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

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

    meta = get_meta(request)
    track_created_new_project_space_on_hubspot.delay(current_user,
                                                     request.COOKIES, meta)
    return new_domain.name
Example #44
0
def django_user_post_save_signal(sender, instance, created, **kwargs):
    return CouchUser.django_user_post_save_signal(sender, instance, created)
Example #45
0
    def get(self, *args, **kwargs):
        """
        Download prior progress note submissions for local access
        """
        db = XFormInstance.get_db()
        couch_user = CouchUser.from_django_user(self.request.user)
        username = couch_user.raw_username
        if hasattr(localsettings, 'debug_pact_user'):
            username = getattr(localsettings, 'debug_pact_user')(username)

        offset =0
        limit_count=200
        total_count = 0

        query = {
            "query": {
                "filtered": {
                    "filter": {
                        "and": [
                            {"term": {"domain.exact": "pact"}},
                            {"term": {"form.#type": "progress_note"}},
                            {"term": {"form.meta.username": username}}
                        ]
                    },
                    "query": {"match_all": {}}
                }
            },
            "sort": {"received_on": "asc"},
            "size": limit_count,
            "fields": ['_id', 'external_blobs']
        }
        query['script_fields'] = {}
        query['script_fields'].update(pact_script_fields())
        query['script_fields'].update(case_script_field())

        res = self.xform_es.run_query(query)

        my_patients_ever_submitted_query = query_per_case_submissions_facet(PACT_DOMAIN, username)
        patients_res = self.xform_es.run_query(my_patients_ever_submitted_query)

        #filter by active/discharged?
        #get all the forms
        #get all the patients
        #get all patients to determine which to filter.

        active_patients = []
        for pt in []:
            #if pt.hp_status == "Discharged":
                #continue
            case_id = pt['script_case_id']
            active_patients.append(case_id)

        def return_iterator():
            yield "<restoredata>"
            for result in res['hits']['hits']:
                data_row = result['fields']

#                if data_row['script_case_id'] not in active_patients:
#                    continue
                try:
                    xml_str = (BlobHelper(data_row, db, CODES.form_xml)
                        .fetch_attachment('form.xml').decode('utf-8')
                        .replace("<?xml version=\'1.0\' ?>", '')
                        .replace("<?xml version='1.0' encoding='UTF-8' ?>", ''))
                    yield xml_str
                except Exception as ex:
                    logging.error("for downloader: error fetching attachment: %s" % ex)
            yield "</restoredata>"

        response = HttpResponse(return_iterator(), content_type='text/xml')
        return response
Example #46
0
    def _get_success_message(self, instance, cases=None):
        '''
        Formplayer requests get a detailed success message pointing to the form/case affected.
        All other requests get a generic message.

        Message is formatted with markdown.
        '''

        if not instance.metadata or instance.metadata.deviceID != FORMPLAYER_DEVICE_ID:
            return '   √   '

        messages = []
        user = CouchUser.get_by_user_id(instance.user_id)
        if not user or not user.is_web_user():
            return _('Form successfully saved!')

        from corehq.apps.export.views import CaseExportListView, FormExportListView
        from corehq.apps.reports.views import CaseDataView, FormDataView
        form_link = case_link = form_export_link = case_export_link = None
        form_view = 'corehq.apps.reports.standard.inspect.SubmitHistory'
        if has_permission_to_view_report(user, instance.domain, form_view):
            form_link = reverse(FormDataView.urlname, args=[instance.domain, instance.form_id])
        case_view = 'corehq.apps.reports.standard.cases.basic.CaseListReport'
        if cases and has_permission_to_view_report(user, instance.domain, case_view):
            if len(cases) == 1:
                case_link = reverse(CaseDataView.urlname, args=[instance.domain, cases[0].case_id])
            else:
                case_link = ", ".join(["[{}]({})".format(
                    c.name, reverse(CaseDataView.urlname, args=[instance.domain, c.case_id])
                ) for c in cases])
        if can_view_form_exports(user, instance.domain):
            form_export_link = reverse(FormExportListView.urlname, args=[instance.domain])
        if cases and can_view_case_exports(user, instance.domain):
            case_export_link = reverse(CaseExportListView.urlname, args=[instance.domain])

        # Start with generic message
        messages.append(_('Form successfully saved!'))

        # Add link to form/case if possible
        if form_link and case_link:
            if len(cases) == 1:
                messages.append(
                    _("You submitted [this form]({}), which affected [this case]({}).")
                    .format(form_link, case_link))
            else:
                messages.append(
                    _("You submitted [this form]({}), which affected these cases: {}.")
                    .format(form_link, case_link))
        elif form_link:
            messages.append(_("You submitted [this form]({}).").format(form_link))
        elif case_link:
            if len(cases) == 1:
                messages.append(_("Your form affected [this case]({}).").format(case_link))
            else:
                messages.append(_("Your form affected these cases: {}.").format(case_link))

        # Add link to all form/case exports
        if form_export_link and case_export_link:
            messages.append(
                _("Click to export your [case]({}) or [form]({}) data.")
                .format(case_export_link, form_export_link))
        elif form_export_link:
            messages.append(_("Click to export your [form data]({}).").format(form_export_link))
        elif case_export_link:
            messages.append(_("Click to export your [case data]({}).").format(case_export_link))

        return "\n\n".join(messages)
Example #47
0
 def owner(self):
     id = self.owner_id
     return CouchUser.get_by_user_id(id)
Example #48
0
 def process_response(self, request, response):
     if is_login_page(request) and request.user.is_authenticated and is_icds_domain(request):
         couch_user = CouchUser.get_by_username(request.user.username)
         ICDSAuditEntryRecord.create_entry(request, couch_user, is_login_page=True)
     return response
Example #49
0
    def __call__(self, request, invitation_id, **kwargs):
        logging.warning(
            "Don't use this view in more apps until it gets cleaned up.")
        # add the correct parameters to this instance
        self.request = request
        for k, v in kwargs.iteritems():
            if k in self.need:
                setattr(self, k, v)

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

        try:
            invitation = self.inv_type.get(invitation_id)
        except ResourceNotFound:
            messages.error(
                request,
                _("Sorry, we couldn't find that invitation. Please double check "
                  "the invitation link you received and try again."))
            return HttpResponseRedirect(reverse("login"))
        if invitation.is_accepted:
            messages.error(
                request,
                _("Sorry, that invitation has already been used up. "
                  "If you feel this is a mistake please ask the inviter for "
                  "another invitation."))
            return HttpResponseRedirect(reverse("login"))

        self.validate_invitation(invitation)

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

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

            if request.method == "POST":
                couch_user = CouchUser.from_django_user(request.user)
                self._invite(invitation, couch_user)
                return HttpResponseRedirect(self.redirect_to_on_success)
            else:
                mobile_user = CouchUser.from_django_user(
                    request.user).is_commcare_user()
                context = self.added_context()
                context.update({
                    'mobile_user':
                    mobile_user,
                    "invited_user":
                    invitation.email
                    if request.couch_user.username != invitation.email else "",
                })
                return render(request, self.template, context)
        else:
            if request.method == "POST":
                form = NewWebUserRegistrationForm(request.POST)
                if form.is_valid():
                    # create the new user
                    user = activate_new_user(form)
                    user.save()
                    messages.success(
                        request,
                        _("User account for %s created! You may now login.") %
                        form.cleaned_data["email"])
                    self._invite(invitation, user)
                    return HttpResponseRedirect(reverse("login"))
            else:
                form = NewWebUserRegistrationForm(
                    initial={'email': invitation.email})

        return render(request, self.template, {"form": form})
Example #50
0
def request_new_domain(request, form, is_new_user=True):
    now = datetime.utcnow()
    current_user = CouchUser.from_django_user(request.user, strict=True)

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

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

        # Avoid projects created by dimagi.com staff members as self started
        new_domain.internal.self_started = not current_user.is_dimagi

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

        if not is_new_user:
            new_domain.is_active = True

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

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

    if not settings.ENTERPRISE_MODE:
        _setup_subscription(new_domain.name, current_user)

    UserRole.init_domain_with_presets(new_domain.name)

    if request.user.is_authenticated:
        if not current_user:
            current_user = WebUser()
            current_user.sync_from_django_user(request.user)
            current_user.save()
        current_user.add_domain_membership(new_domain.name, is_admin=True)
        current_user.save()
        dom_req.requesting_user_username = request.user.username
        dom_req.new_user_username = request.user.username
    elif is_new_user:
        _soft_assert_registration_issues(
            f"A new user {request.user.username} was not added to their domain "
            f"{new_domain.name} during registration")

    if is_new_user:
        dom_req.save()
        if settings.IS_SAAS_ENVIRONMENT:
            #  Load template apps to the user's new domain in parallel
            from corehq.apps.app_manager.tasks import load_appcues_template_app
            header = [
                load_appcues_template_app.si(new_domain.name,
                                             current_user.username, slug)
                for slug in APPCUES_APP_SLUGS
            ]
            callback = send_domain_registration_email.si(
                request.user.email, dom_req.domain, dom_req.activation_guid,
                request.user.get_full_name(), request.user.first_name)
            chord(header)(callback)
        else:
            send_domain_registration_email(request.user.email, dom_req.domain,
                                           dom_req.activation_guid,
                                           request.user.get_full_name(),
                                           request.user.first_name)
    send_new_request_update_email(request.user,
                                  get_ip(request),
                                  new_domain.name,
                                  is_new_user=is_new_user)

    send_hubspot_form(HUBSPOT_CREATED_NEW_PROJECT_SPACE_FORM_ID, request)
    return new_domain.name
Example #51
0
 def _inner(request, domain, *args, **kwargs):
     if request.user.is_authenticated():
         request.couch_user = CouchUser.from_django_user(request.user)
         return view(request, domain, *args, **kwargs)
     else:
         return HttpResponseForbidden()
Example #52
0
    @property
    @memoized
    def recipient(self):
        if self.recipient_type == self.RECIPIENT_TYPE_CASE:
            try:
                case = CaseAccessors(self.domain).get_case(self.recipient_id)
            except CaseNotFound:
                return None

            if case.domain != self.domain:
                return None

            return case
        elif self.recipient_type == self.RECIPIENT_TYPE_MOBILE_WORKER:
            user = CouchUser.get_by_user_id(self.recipient_id, domain=self.domain)
            if not isinstance(user, CommCareUser):
                return None

            return user
        elif self.recipient_type == self.RECIPIENT_TYPE_WEB_USER:
            user = CouchUser.get_by_user_id(self.recipient_id, domain=self.domain)
            if not isinstance(user, WebUser):
                return None

            return user
        elif self.recipient_type == self.RECIPIENT_TYPE_CASE_GROUP:
            try:
                group = CommCareCaseGroup.get(self.recipient_id)
            except ResourceNotFound:
                return None
def test_contractor():
    user = CouchUser(username="******")
    with flag_enabled('IS_CONTRACTOR'):
        assert_true(is_superuser_or_contractor(user))
Example #54
0
def _handle_user_form(request, domain, couch_user=None):
    context = {}
    if couch_user:
        create_user = False
    else:
        create_user = True
    can_change_admin_status = ((request.user.is_superuser or request.couch_user.can_edit_web_users(domain=domain))
        and request.couch_user.user_id != couch_user.user_id)

    if couch_user.is_commcare_user():
        role_choices = UserRole.commcareuser_role_choices(domain)
    else:
        role_choices = UserRole.role_choices(domain)

    results = get_db().view('languages/list', startkey=[domain], endkey=[domain, {}], group='true').all()
    language_choices = []

    if results:
        for result in results:
            lang_code = result['key'][1]
            label = result['key'][1]
            long_form = langcodes.get_name(lang_code)
            if long_form:
                label += " (" + langcodes.get_name(lang_code) + ")"
            language_choices.append((lang_code, label))
    else:
        language_choices = langcodes.get_all_langs_for_select()

    if request.method == "POST" and request.POST['form_type'] == "basic-info":
        if couch_user.is_commcare_user():
            form = UserForm(request.POST, role_choices=role_choices, language_choices=language_choices)
        else:
            form = WebUserForm(request.POST, role_choices=role_choices, language_choices=language_choices)
        if form.is_valid():
            if create_user:
                django_user = User()
                django_user.username = form.cleaned_data['email']
                django_user.save()
                couch_user = CouchUser.from_django_user(django_user)
            if couch_user.is_current_web_user(request) or couch_user.is_commcare_user():
                couch_user.first_name = form.cleaned_data['first_name']
                couch_user.last_name = form.cleaned_data['last_name']
                couch_user.email = form.cleaned_data['email']
                if not couch_user.is_commcare_user():
                    couch_user.email_opt_in = form.cleaned_data['email_opt_in']
                couch_user.language = form.cleaned_data['language']
            if can_change_admin_status:
                role = form.cleaned_data['role']
                if role:
                    couch_user.set_role(domain, role)
            couch_user.save()
            if request.couch_user.get_id == couch_user.get_id and couch_user.language:
                # update local language in the session
                request.session['django_language'] = couch_user.language

            messages.success(request, 'Changes saved for user "%s"' % couch_user.username)
    else:
        form = UserForm(role_choices=role_choices, language_choices=language_choices)
        if couch_user.is_commcare_user():
            form = UserForm(role_choices=role_choices, language_choices=language_choices)
        else:
            form = WebUserForm(role_choices=role_choices, language_choices=language_choices)

        if not create_user:
            form.initial['first_name'] = couch_user.first_name
            form.initial['last_name'] = couch_user.last_name
            form.initial['email'] = couch_user.email
            form.initial['email_opt_in'] = couch_user.email_opt_in
            form.initial['language'] = couch_user.language
            if can_change_admin_status:
                if couch_user.is_commcare_user():
                    role = couch_user.get_role(domain)
                    if role is None:
                        initial = "none"
                    else:
                        initial = role.get_qualified_id()
                    form.initial['role'] = initial
                else:
                    form.initial['role'] = couch_user.get_role(domain, include_teams=False).get_qualified_id() or ''

    if not can_change_admin_status:
        del form.fields['role']

    context.update({"form": form,
                    "current_users_page": couch_user.is_current_web_user(request)})
    return context
Example #55
0
 def users(self):
     return CouchUser.by_domain(self.domain) if self.filter_data.get(
         'gp', []) else []
def test_superuser():
    user = CouchUser(username="******", is_superuser=True)
    assert_true(is_superuser_or_contractor(user))
Example #57
0
 def owner(self):
     return CouchUser.get_by_user_id(self.owner_id)
def test_normal_user():
    user = CouchUser(username="******")
    assert_false(is_superuser_or_contractor(user))
Example #59
0
def get_restore_response(domain,
                         couch_user,
                         app_id=None,
                         since=None,
                         version='1.0',
                         state=None,
                         items=False,
                         force_cache=False,
                         cache_timeout=None,
                         overwrite_cache=False,
                         as_user=None,
                         device_id=None,
                         user_id=None,
                         openrosa_version=None,
                         case_sync=None):
    """
    :param domain: Domain being restored from
    :param couch_user: User performing restore
    :param app_id: App ID of the app making the request
    :param since: ID of current sync log used to generate incremental sync
    :param version: Version of the sync response required
    :param state: Hash value of the current database of cases on the device for consistency checking
    :param items: Include item count if True
    :param force_cache: Force response to be cached
    :param cache_timeout: Override the default cache timeout of 1 hour.
    :param overwrite_cache: Ignore cached response if True
    :param as_user: Username of user to generate restore for (if different from current user)
    :param device_id: ID of device performing restore
    :param user_id: ID of user performing restore (used in case of deleted user with same username)
    :param openrosa_version:
    :param case_sync: Override default case sync algorithm
    :return: Tuple of (http response, timing context or None)
    """

    if user_id and user_id != couch_user.user_id:
        # sync with a user that has been deleted but a new
        # user was created with the same username and password
        from couchforms.openrosa_response import get_simple_response_xml
        from couchforms.openrosa_response import ResponseNature
        response = get_simple_response_xml(
            'Attempt to sync with invalid user.',
            ResponseNature.OTA_RESTORE_ERROR)
        return HttpResponse(response,
                            content_type="text/xml; charset=utf-8",
                            status=412), None

    is_demo_restore = couch_user.is_commcare_user() and couch_user.is_demo_user
    if is_demo_restore:
        # if user is in demo-mode, return demo restore
        return demo_user_restore_response(couch_user), None

    uses_login_as = bool(as_user)
    as_user_obj = CouchUser.get_by_username(as_user) if uses_login_as else None
    if uses_login_as and not as_user_obj:
        msg = _('Invalid restore as user {}').format(as_user)
        return HttpResponse(msg, status=401), None
    is_permitted, message = is_permitted_to_restore(
        domain,
        couch_user,
        as_user_obj,
    )
    if not is_permitted:
        return HttpResponse(message, status=401), None

    restore_user = get_restore_user(domain, couch_user, as_user_obj)
    if not restore_user:
        return HttpResponse('Could not find user', status=404), None

    project = Domain.get_by_name(domain)
    async_restore_enabled = (toggles.ASYNC_RESTORE.enabled(domain)
                             and openrosa_version and
                             LooseVersion(openrosa_version) >= LooseVersion(
                                 OPENROSA_VERSION_MAP['ASYNC_RESTORE']))

    app = get_app_cached(domain, app_id) if app_id else None
    restore_config = RestoreConfig(
        project=project,
        restore_user=restore_user,
        params=RestoreParams(
            sync_log_id=since,
            version=version,
            state_hash=state,
            include_item_count=items,
            app=app,
            device_id=device_id,
            openrosa_version=openrosa_version,
        ),
        cache_settings=RestoreCacheSettings(force_cache=force_cache
                                            or async_restore_enabled,
                                            cache_timeout=cache_timeout,
                                            overwrite_cache=overwrite_cache),
        is_async=async_restore_enabled,
        case_sync=case_sync,
    )
    return restore_config.get_response(), restore_config.timing_context
Example #60
0
def user_db():
    return CouchUser.get_db()