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!")
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)
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)
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()
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
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!"
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!"
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
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 }), })
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))
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)
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)
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)
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)
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})
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)
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))
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
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
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)
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
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 })
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()
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)
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
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)
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()))
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
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
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
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
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)
def _clear_cache(doc): user = CouchUser.wrap_correctly(doc, allow_deleted_doc_types=True) user.clear_quickcache_for_user()
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
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("@", "​@") 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)
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
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
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)
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
def request_new_domain(request, form, is_new_user=True): now = datetime.utcnow() current_user = CouchUser.from_django_user(request.user) dom_req = RegistrationRequest() if is_new_user: dom_req.request_time = now dom_req.request_ip = get_ip(request) dom_req.activation_guid = uuid.uuid1().hex project_name = form.cleaned_data.get('hr_name') or form.cleaned_data.get( 'project_name') name = name_to_url(project_name, "project") with CriticalSection(['request_domain_name_{}'.format(name)]): name = Domain.generate_name(name) new_domain = Domain(name=name, hr_name=project_name, is_active=False, date_created=datetime.utcnow(), creating_user=current_user.username, secure_submissions=True, use_sql_backend=True, first_domain_for_user=is_new_user) if form.cleaned_data.get('domain_timezone'): new_domain.default_timezone = form.cleaned_data['domain_timezone'] if not is_new_user: new_domain.is_active = True # ensure no duplicate domain documents get created on cloudant new_domain.save(**get_safe_write_kwargs()) if not new_domain.name: new_domain.name = new_domain._id new_domain.save() # we need to get the name from the _id if is_new_user: # Only new-user domains are eligible for Advanced trial # domains with no subscription are equivalent to be on free Community plan create_30_day_advanced_trial(new_domain, current_user.username) else: ensure_explicit_community_subscription(new_domain.name, date.today()) UserRole.init_domain_with_presets(new_domain.name) # add user's email as contact email for billing account for the domain account = BillingAccount.get_account_by_domain(new_domain.name) billing_contact, _ = BillingContactInfo.objects.get_or_create( account=account) billing_contact.email_list = [current_user.email] billing_contact.save() dom_req.domain = new_domain.name if request.user.is_authenticated(): if not current_user: current_user = WebUser() current_user.sync_from_django_user(request.user) current_user.save() current_user.add_domain_membership(new_domain.name, is_admin=True) current_user.save() dom_req.requesting_user_username = request.user.username dom_req.new_user_username = request.user.username if is_new_user: dom_req.save() send_domain_registration_email(request.user.email, dom_req.domain, dom_req.activation_guid, request.user.get_full_name()) send_new_request_update_email(request.user, get_ip(request), new_domain.name, is_new_user=is_new_user) meta = get_meta(request) track_created_new_project_space_on_hubspot.delay(current_user, request.COOKIES, meta) return new_domain.name
def django_user_post_save_signal(sender, instance, created, **kwargs): return CouchUser.django_user_post_save_signal(sender, instance, created)
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
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)
def owner(self): id = self.owner_id return CouchUser.get_by_user_id(id)
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
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})
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
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()
@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))
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
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))
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))
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
def user_db(): return CouchUser.get_db()