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 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): 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, path, app_id, **options): if options['deploy'] and not options['user']: raise CommandError('Deploy argument requires a user') elif options['deploy']: user = CouchUser.get_by_username(options['user']) if not user: raise CommandError("Couldn't find user with username {}".format(options['user'])) app = Application.get(app_id) for module_dir in os.listdir(path): module_index, name = module_dir.split(' - ') module = app.get_module(int(module_index)) for form_name in os.listdir(os.path.join(path, module_dir)): form_index, name = form_name.split(' - ') form = module.get_form(int(form_index)) with open(os.path.join(path, module_dir, form_name), 'rb') as f: save_xform(app, form, f.read()) app.save() print('successfully updated {}'.format(app.name)) if options['deploy']: # make build and star it comment = options.get('comment', 'form changes from {0}'.format(datetime.utcnow().strftime(SERVER_DATETIME_FORMAT_NO_SEC))) copy = app.make_build( comment=comment, user_id=user._id, ) copy.is_released = True copy.save(increment_version=False) print('successfully released new version')
def post(self, request, *args, **kwargs): if self.invite_web_user_form.is_valid(): # If user exists and has already requested access, just add them to the project # Otherwise, send an invitation create_invitation = True data = self.invite_web_user_form.cleaned_data domain_request = DomainRequest.by_email(self.domain, data["email"]) if domain_request is not None: domain_request.is_approved = True domain_request.save() user = CouchUser.get_by_username(domain_request.email) if user is not None: domain_request.send_approval_email() create_invitation = False user.add_as_web_user(self.domain, role=data["role"], location_id=data.get("supply_point", None), program_id=data.get("program", None)) messages.success(request, "%s added." % data["email"]) else: messages.success(request, "Invitation sent to %s" % data["email"]) if create_invitation: data["invited_by"] = request.couch_user.user_id data["invited_on"] = datetime.utcnow() data["domain"] = self.domain invite = DomainInvitation(**data) invite.save() invite.send_activation_email() return HttpResponseRedirect(reverse( ListWebUsersView.urlname, args=[self.domain] )) return self.get(request, *args, **kwargs)
def claim(request, domain): """ Allows a user to claim a case that they don't own. """ as_user = request.POST.get('commcare_login_as', None) as_user_obj = CouchUser.get_by_username(as_user) if as_user else None restore_user = get_restore_user(domain, request.couch_user, as_user_obj) case_id = request.POST.get('case_id', None) if case_id is None: return HttpResponse('A case_id is required', status=400) try: if get_first_claim(domain, restore_user.user_id, case_id): return HttpResponse('You have already claimed that {}'.format(request.POST.get('case_type', 'case')), status=409) claim_case(domain, restore_user.user_id, case_id, host_type=request.POST.get('case_type'), host_name=request.POST.get('case_name'), device_id=__name__ + ".claim") except CaseNotFound: return HttpResponse('The case "{}" you are trying to claim was not found'.format(case_id), status=410) return HttpResponse(status=200)
def get_id_from_name(uploaded_name, domain, cache): ''' :param uploaded_name: A username or group name :param domain: :param cache: :return: Looks for the given name and returns the corresponding id if the user or group exists and None otherwise. Searches for user first, then group. ''' if uploaded_name in cache: return cache[uploaded_name] try: name_as_address = uploaded_name if '@' not in name_as_address: name_as_address = format_username(uploaded_name, domain) user = CouchUser.get_by_username(name_as_address) id = getattr(user, 'couch_id', None) except NoResultFound: id = None if not id: group = Group.by_name(domain, uploaded_name, one=True) id = getattr(group, 'get_id', None) cache[uploaded_name] = id return id
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 is_permitted_to_restore(domain, couch_user, as_user, has_data_cleanup_privilege): """ This function determines if the couch_user is permitted to restore for the domain and/or as_user :param domain: Domain of restore :param couch_user: The couch user attempting authentication :param as_user: a string username that the couch_user is attempting to get a restore for. If None will get restore of the couch_user. :param has_data_cleanup_privelege: Whether the user has permissions to do DATA_CLEANUP :returns: a tuple - first a boolean if the user is permitted, secondly a message explaining why a user was rejected if not permitted """ try: _ensure_valid_domain(domain, couch_user) if as_user is not None and not _restoring_as_yourself(couch_user, as_user): as_user_obj = CouchUser.get_by_username(as_user) if not as_user_obj: raise RestorePermissionDenied(_(u'Invalid restore as user {}').format(as_user)) _ensure_cleanup_permission(domain, couch_user, as_user_obj, has_data_cleanup_privilege) _ensure_valid_restore_as_user(domain, couch_user, as_user_obj) _ensure_accessible_location(domain, couch_user, as_user_obj) _ensure_edit_data_permission(domain, couch_user) except RestorePermissionDenied as e: return False, unicode(e) else: return True, None
def _inner(request, *args, **kwargs): username = _get_username_from_request(request) user = CouchUser.get_by_username(username) if user and user.is_web_user() and user.is_locked_out(): return json_response({_("error"): _("maximum password attempts exceeded")}, status_code=401) else: return fn(request, *args, **kwargs)
def check_username_availability(self, data): email = data['email'].strip() duplicate = CouchUser.get_by_username(email) is_existing = User.objects.filter(username__iexact=email).count() > 0 or duplicate return { 'isValid': not is_existing, }
def filter_context(self): api_root = reverse('api_dispatch_list', kwargs={'domain': self.domain, 'resource_name': 'location', 'api_name': 'v0.3'}) selected_loc_id = self.request.GET.get('location_id') user = CouchUser.get_by_username(unicode(self.request.user)) domain = Domain.get_by_name(self.domain) context = {} location_id = None domain_membership = user.get_domain_membership(self.domain) if domain_membership: location_id = domain_membership.location_id if not selected_loc_id and location_id and domain.commtrack_enabled: selected_loc_id = location_id if domain.location_restriction_for_users: context.update({'restriction': domain.location_restriction_for_users}) context.update({ 'api_root': api_root, 'control_name': self.label, # todo: cleanup, don't follow this structure 'control_slug': self.slug, # todo: cleanup, don't follow this structure 'loc_id': selected_loc_id, 'locations': json.dumps(load_locs_json(self.domain, selected_loc_id)), 'hierarchy': location_hierarchy_config(self.domain) }) return context
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 get_restore_as_user(request, domain): """ returns (user, set_cookie), where set_cookie is a function to be called on the eventual response """ if not hasattr(request, 'couch_user'): raise Http404() def set_cookie(response): # set_coookie is a noop by default return response cookie_name = six.moves.urllib.parse.quote( 'restoreAs:{}:{}'.format(domain, request.couch_user.username)) username = request.COOKIES.get(cookie_name) if username: user = CouchUser.get_by_username(format_username(username, domain)) if user: return user, set_cookie else: def set_cookie(response): # overwrite the default noop set_cookie response.delete_cookie(cookie_name) return response return request.couch_user, set_cookie
def add_language_to_user(self, logistics_sms_user): domain_part = "%s.commcarehq.org" % self.domain username_part = "%s%d" % (logistics_sms_user.name.strip().replace(' ', '.').lower(), logistics_sms_user.id) username = "******" % (username_part[:(128 - (len(domain_part) + 1))], domain_part) user = CouchUser.get_by_username(username) if not user: return if user.language != logistics_sms_user.language: user.language = logistics_sms_user.language user.save() logistics_numbers = {apply_leniency(phone_number) for phone_number in logistics_sms_user.phone_numbers} if set(user.phone_numbers) == logistics_numbers: return for phone_number in user.phone_numbers: user.delete_phone_number(phone_number) if logistics_sms_user.phone_numbers: phone_number = apply_leniency(logistics_sms_user.phone_numbers[0]) if not phone_number: return user.set_default_phone_number(phone_number) self._save_verified_number(user, phone_number)
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 claim(request, domain): """ Allows a user to claim a case that they don't own. """ as_user = unquote(request.POST.get('commcare_login_as', '')) as_user_obj = CouchUser.get_by_username(as_user) if as_user else None restore_user = get_restore_user(domain, request.couch_user, as_user_obj) case_id = unquote(request.POST.get('case_id', '')) if not case_id: return HttpResponse('A case_id is required', status=400) try: if get_first_claim(domain, restore_user.user_id, case_id): return HttpResponse('You have already claimed that {}'.format( request.POST.get('case_type', 'case')), status=409) claim_case(domain, restore_user.user_id, case_id, host_type=unquote(request.POST.get('case_type', '')), host_name=unquote(request.POST.get('case_name', '')), device_id=__name__ + ".claim") except CaseNotFound: return HttpResponse( 'The case "{}" you are trying to claim was not found'.format( case_id), status=410) return HttpResponse(status=200)
def handle(self, account_id, username, **kwargs): self.couch_user = CouchUser.get_by_username(username) self.account_id = account_id if not self.couch_user: raise CommandError("Option: '--username' must be specified") self.now = datetime.utcnow() account = BillingAccount.objects.get(id=account_id) message = '' if kwargs.get('message'): message += kwargs.get('message') + "\n" message += "Report run {}\n".format(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')) attachments = [] for slug in ( EnterpriseReport.DOMAINS, EnterpriseReport.WEB_USERS, EnterpriseReport.MOBILE_USERS, EnterpriseReport.FORM_SUBMISSIONS, ): (attachment, count) = self._write_file(slug) attachments.append(attachment) message += "{}: {}\n".format(slug, count) cc = [] if kwargs.get('cc'): cc = kwargs.get('cc').split(",") send_html_email_async( "Report on enterprise account {}".format(account.name), self.couch_user.username, linebreaksbr(message), cc=cc, text_content=message, file_attachments=attachments, ) print('Emailed {}{}{}'.format(self.couch_user.username, " and " if cc else "", ", ".join(cc)))
def clear_login_attempts(user): if user and user.login_attempts > 0: try: user.login_attempts = 0 user.save() except ResourceConflict: updated_user = CouchUser.get_by_username(user.username) clear_login_attempts(updated_user)
def check_username_availability(self, data): email = data['email'].strip() duplicate = CouchUser.get_by_username(email) is_existing = User.objects.filter( username__iexact=email).count() > 0 or duplicate return { 'isValid': not is_existing, }
def clean(self): lockout_message = mark_safe(_('Sorry - you have attempted to login with an incorrect password too many times. Please <a href="/accounts/password_reset_email/">click here</a> to reset your password.')) username = self.cleaned_data.get('username') if username is None: raise ValidationError(_('Please enter a valid email address.')) try: cleaned_data = super(EmailAuthenticationForm, self).clean() except ValidationError: user = CouchUser.get_by_username(username) if user and user.is_web_user() and user.is_locked_out(): raise ValidationError(lockout_message) else: raise user = CouchUser.get_by_username(username) if user and user.is_web_user() and user.is_locked_out(): raise ValidationError(lockout_message) return cleaned_data
def get_user(name): try: name_as_address = name if '@' not in name_as_address: name_as_address = format_username(name, self.domain) return CouchUser.get_by_username(name_as_address) except NoResultFound: return None
def clean(self): try: cleaned_data = super(HQBackupTokenForm, self).clean() except ValidationError: user_login_failed.send( sender=__name__, credentials={'username': self.user.username}) couch_user = CouchUser.get_by_username(self.user.username) if couch_user and couch_user.is_locked_out( ) and couch_user.supports_lockout(): raise ValidationError(LOCKOUT_MESSAGE) else: raise couch_user = CouchUser.get_by_username(self.user.username) if couch_user and couch_user.is_locked_out( ) and couch_user.supports_lockout(): raise ValidationError(LOCKOUT_MESSAGE) return cleaned_data
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 = {} 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 context.update(extra_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 get_restore_as_user(request, domain): """ returns (user, set_cookie), where set_cookie is a function to be called on the eventual response """ if not hasattr(request, 'couch_user'): raise Http404() def set_cookie(response): # set_coookie is a noop by default return response cookie_name = urllib.parse.quote('restoreAs:{}:{}'.format( domain, request.couch_user.username)) username = request.COOKIES.get(cookie_name) if username: user = CouchUser.get_by_username(format_username(username, domain)) if user: return user, set_cookie else: def set_cookie( response): # overwrite the default noop set_cookie response.delete_cookie(cookie_name) return response elif request.couch_user.has_permission(domain, 'limited_login_as'): login_as_users = login_as_user_query(domain, request.couch_user, search_string='', limit=1, offset=0).run() if login_as_users.total == 1: def set_cookie(response): response.set_cookie(cookie_name, user.raw_username, secure=settings.SECURE_COOKIES) return response user = CouchUser.get_by_username( login_as_users.hits[0]['username']) return user, set_cookie return request.couch_user, set_cookie
def add_failed_attempt(sender, credentials, **kwargs): user = CouchUser.get_by_username(credentials['username']) if user and not user.is_locked_out() and user.supports_lockout(): if user.attempt_date == date.today(): user.login_attempts += 1 else: user.login_attempts = 1 user.attempt_date = date.today() user.save()
def get_from_user(name): try: name_as_address = name if '@' not in name_as_address: name_as_address = format_username(name, domain) user = CouchUser.get_by_username(name_as_address) return getattr(user, 'couch_id', None) except NoResultFound: return None
def check_user_access(domain, username, allow_mirroring=False): from corehq.apps.users.util import format_username from corehq.apps.users.models import CouchUser if '@' not in username: username = format_username(username, domain) user = CouchUser.get_by_username(username) if not user.is_member_of(domain, allow_mirroring=allow_mirroring): raise FormplayerAPIException(f"User '{username}' does not have access to domain '{domain}'") return user
def _set_in_charges(self, ews_user_id, location): ews_sms_user = self.endpoint.get_smsuser(ews_user_id) sms_user = CouchUser.get_by_username(self.get_username(ews_sms_user)[0]) if not sms_user: sms_user = self.sms_user_sync(ews_sms_user) FacilityInCharge.objects.get_or_create( location=location, user_id=sms_user.get_id )
def _inner(request, *args, **kwargs): username = _get_username_from_request(request) user = CouchUser.get_by_username(username) if user and user.is_web_user() and user.is_locked_out(): return json_response( {_("error"): _("maximum password attempts exceeded")}, status_code=401) else: return fn(request, *args, **kwargs)
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 validate_row(row, domain, data_cols): """pre-validate the information in a particular import row: valid location, reporting user, and data formats """ # identify location loc_code = row.get('outlet_code') or row.get('site_code') row['loc'] = get_supply_point(domain, loc_code)['case'] if row['loc'] is None: set_error(row, 'ERROR location code is invalid') return # identify user phone = row.get('phone') owner = None if phone: vn = VerifiedNumber.by_phone(phone) if not vn: set_error(row, 'ERROR phone number is not verified with any user') return owner = vn.owner row['phone'] = strip_plus(phone) username = row.get('reporter') if username: user = CouchUser.get_by_username('%s@%s.commcarehq.org' % (username, domain)) if not user: set_error(row, 'ERROR reporter user does not exist') return if owner: if user and user._id != owner._id: set_error(row, 'ERROR phone number does not belong to user') return user = owner row['user'] = user # validate other fields try: row['timestamp'] = datetime.strptime(row['date'], '%Y-%m-%d') # TODO: allow time? except ValueError: set_error(row, 'ERROR invalid date format') return for k in data_cols: val = row[k] if val: try: int(val) except ValueError: set_error(row, 'ERROR invalid data value "%s" in column "%s"' % (val, k)) return if all(not row[k] for k in data_cols): set_error(row, 'ERROR stock report is empty') return
def upload(dropbox_helper_id, access_token, size, max_retries): from .models import DropboxUploadHelper helper = DropboxUploadHelper.objects.get(id=dropbox_helper_id) def progress_callback(bytes_uploaded, helper=helper, size=size): helper.progress = float(bytes_uploaded) / size helper.save() try: dropbox_path = '/{}'.format(os.path.basename(helper.src)) path_display = upload_to_dropbox(access_token, dropbox_path, helper.src, progress_callback) except Exception as e: helper.failure_reason = str(e) helper.save() couch_user = CouchUser.get_by_username(helper.user.username) if helper.failure_reason is None: dbx = Dropbox(access_token) path_link_metadata = dbx.sharing_create_shared_link_with_settings( path_display, SharedLinkSettings( requested_visibility=RequestedVisibility.team_only, ), ) context = { 'share_url': path_link_metadata.url, 'path': os.path.join( 'Apps', settings.DROPBOX_APP_NAME, path_link_metadata.name, ) } with localize(couch_user.get_language_code()): subject = _('{} has been uploaded to dropbox!'.format(helper.dest)) html_content = render_to_string( 'dropbox/emails/upload_success.html', context) text_content = render_to_string( 'dropbox/emails/upload_success.txt', context) else: context = {'reason': helper.failure_reason, 'path': helper.dest} with localize(couch_user.get_language_code()): subject = _('{} has failed to upload to dropbox'.format( helper.dest)) html_content = render_to_string('dropbox/emails/upload_error.html', context) text_content = render_to_string('dropbox/emails/upload_error.txt', context) send_HTML_email( subject, helper.user.email, html_content, text_content=text_content, )
def clean_email(self): data = super().clean_email() # web user login emails should be globally unique duplicate = CouchUser.get_by_username(data) if duplicate: # sync django user duplicate.save() if User.objects.filter(username__iexact=data).count() > 0 or duplicate: raise forms.ValidationError('Username already taken; please try another') return data
def clean_email(self): data = self.cleaned_data['email'].strip().lower() validate_email(data) duplicate = CouchUser.get_by_username(data) if duplicate: # sync django user duplicate.save() if User.objects.filter(username__iexact=data).count() > 0 or duplicate: raise forms.ValidationError('Username already taken; please try another') return data
def _inner(request, *args, **kwargs): username, password = get_username_and_password_from_request(request) if not username or username.endswith('.commcarehq.org'): return fn(request, *args, **kwargs) user = CouchUser.get_by_username(username) if user and user.is_web_user() and user.is_locked_out(): return json_response({_("error"): _("maximum password attempts exceeded")}, status_code=401) else: return fn(request, *args, **kwargs)
def _inner(request, *args, **kwargs): username, password = get_username_and_password_from_request(request) if not username: return fn(request, *args, **kwargs) user = CouchUser.get_by_username(username) if user and user.is_locked_out() and user.supports_lockout(): return json_response({"error": _("maximum password attempts exceeded")}, status_code=401) else: return fn(request, *args, **kwargs)
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 add_failed_attempt(sender, credentials, **kwargs): user = CouchUser.get_by_username(credentials['username']) if user and (user.is_web_user() or toggles.MOBILE_LOGIN_LOCKOUT.enabled(user.domain)): if user.is_locked_out(): return if user.attempt_date == date.today(): user.login_attempts += 1 else: user.login_attempts = 1 user.attempt_date = date.today() user.save()
def get_payload(self, repeat_record, payload_doc): case_ids_to_forward = payload_doc.get_case_property('cases_to_forward') if not case_ids_to_forward: raise ReferralError( f'No cases included in transfer. Please add case ids to "cases_to_forward" property' ) else: case_ids_to_forward = case_ids_to_forward.split(' ') new_owner = payload_doc.get_case_property('new_owner') cases_to_forward = CaseAccessors( payload_doc.domain).get_cases(case_ids_to_forward) case_ids_to_forward = set(case_ids_to_forward) included_case_types = payload_doc.get_case_property( 'case_types').split(' ') case_type_configs = {} for case_type in included_case_types: constant_properties = [] for key, value in payload_doc.case_json.items(): constant_prefix = f'{case_type}_setter_' if key.startswith(constant_prefix): property_name = key[len(constant_prefix):] constant_properties.append((property_name, value)) whitelist = payload_doc.case_json.get(f'{case_type}_whitelist') blacklist = payload_doc.case_json.get(f'{case_type}_blacklist') if blacklist and whitelist: raise ReferralError( f'both blacklist and whitelist included for {case_type}') if not blacklist and not whitelist: raise ReferralError( f'blacklist or whitelist not included for {case_type}') if blacklist: listed_properties = blacklist.split(' ') use_blacklist = True else: listed_properties = whitelist.split(' ') use_blacklist = False case_type_configs[case_type] = CaseTypeReferralConfig( use_blacklist, listed_properties, constant_properties) case_blocks = self._get_case_blocks(cases_to_forward, case_ids_to_forward, case_type_configs, new_owner) return render_to_string( 'hqcase/xml/case_block.xml', { 'xmlns': SYSTEM_FORM_XMLNS, 'case_block': case_blocks, 'time': datetime.utcnow(), 'uid': uuid4().hex, 'username': self.repeater.username, 'user_id': CouchUser.get_by_username( self.repeater.username).user_id, 'device_id': "ReferCaseRepeater", })
def clean_email(self): data = self.cleaned_data["email"].strip().lower() validate_email(data) existing_member = CouchUser.get_by_username(data) if existing_member: org = Organization.get_by_name(self.org_name) for member in org.get_members(): if member.get_id == existing_member.get_id: raise forms.ValidationError("User is already part of this organization!") return data
def _get_user_info(username): user = CouchUser.get_by_username(username) if not user: return {"error": "User not found"} return { "user_is_dimagi": "@dimagi.com" in username, "user_is_mobile": "commcarehq.org" in username, "user_is_active": user.is_active, "user_last_login": user.last_login, "user_is_superuser": user.is_superuser, }
def _login(req, domain_name, template_name): 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 = {} custom_landing_page = getattr(settings, 'CUSTOM_LANDING_TEMPLATE', False) if custom_landing_page: template_name = custom_landing_page elif domain_name: domain = 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.display_name() if domain else domain_name, 'next': req_params.get('next', '/a/%s/' % domain), 'allow_domain_requests': domain.allow_domain_requests, 'current_page': { 'page_name': _('Welcome back to %s!') % domain.display_name() } }) else: context.update( {'current_page': { 'page_name': _('Welcome back to CommCare HQ!') }}) auth_view = HQLoginView if not domain_name else CloudCareLoginView return auth_view.as_view(template_name=template_name, extra_context=context)(req)
def clean(self): try: cleaned_data = super(HQBackupTokenForm, self).clean() except ValidationError: user_login_failed.send(sender=__name__, credentials={'username': self.user.username}, request=self.request, token_failure=True) couch_user = CouchUser.get_by_username(self.user.username) if couch_user and couch_user.is_locked_out(): metrics_counter('commcare.auth.token_lockout') raise ValidationError(LOCKOUT_MESSAGE) else: raise # Handle the edge-case where the user enters a correct token # after being locked out couch_user = CouchUser.get_by_username(self.user.username) if couch_user and couch_user.is_locked_out(): metrics_counter('commcare.auth.lockouts') raise ValidationError(LOCKOUT_MESSAGE) return cleaned_data
def clean(self): username = self.cleaned_data.get('username') if username is None: raise ValidationError(_('Please enter a valid email address.')) password = self.cleaned_data.get('password') if not password: raise ValidationError(_("Please enter a password.")) try: cleaned_data = super(EmailAuthenticationForm, self).clean() except ValidationError: user = CouchUser.get_by_username(username) if user and user.is_locked_out() and user.supports_lockout(): raise ValidationError(LOCKOUT_MESSAGE) else: raise user = CouchUser.get_by_username(username) if user and user.is_locked_out() and user.supports_lockout(): raise ValidationError(LOCKOUT_MESSAGE) return cleaned_data
def upload(dropbox_helper_id, access_token, size, max_retries): from .models import DropboxUploadHelper helper = DropboxUploadHelper.objects.get(id=dropbox_helper_id) def progress_callback(bytes_uploaded, helper=helper, size=size): helper.progress = float(bytes_uploaded) / size helper.save() try: dropbox_path = '/{}'.format(os.path.basename(helper.src)) path_display = upload_to_dropbox(access_token, dropbox_path, helper.src, progress_callback) except Exception as e: helper.failure_reason = str(e) helper.save() couch_user = CouchUser.get_by_username(helper.user.username) if helper.failure_reason is None: dbx = Dropbox(access_token) path_link_metadata = dbx.sharing_create_shared_link_with_settings( path_display, SharedLinkSettings( requested_visibility=RequestedVisibility.team_only, ), ) context = { 'share_url': path_link_metadata.url, 'path': os.path.join( 'Apps', settings.DROPBOX_APP_NAME, path_link_metadata.name, ) } with localize(couch_user.get_language_code()): subject = _('{} has been uploaded to dropbox!'.format(helper.dest)) html_content = render_to_string('dropbox/emails/upload_success.html', context) text_content = render_to_string('dropbox/emails/upload_success.txt', context) else: context = { 'reason': helper.failure_reason, 'path': helper.dest } with localize(couch_user.get_language_code()): subject = _('{} has failed to upload to dropbox'.format(helper.dest)) html_content = render_to_string('dropbox/emails/upload_error.html', context) text_content = render_to_string('dropbox/emails/upload_error.txt', context) send_HTML_email( subject, helper.user.email, html_content, text_content=text_content, )
def clean_email(self): data = self.cleaned_data['email'].strip().lower() validate_email(data) existing_member = CouchUser.get_by_username(data) if existing_member: org = Organization.get_by_name(self.org_name) for member in org.get_members(): if member.get_id == existing_member.get_id: raise forms.ValidationError( 'User is already part of this organization!') return data
def orgs_add_member(request, org): if request.method == "POST": form = AddMemberForm(org, request.POST) if form.is_valid(): username = form.cleaned_data['member_email'] user_id = CouchUser.get_by_username(username).userID organization = Organization.get_by_name(org) organization.add_member(user_id) messages.success(request, "Member Added!") else: messages.error(request, "Unable to add member") return orgs_landing(request, org, add_member_form=form) return HttpResponseRedirect(reverse('orgs_landing', args=[org]))
def clean(self): lockout_message = mark_safe(_('Sorry - you have attempted to login with an incorrect password too many times. Please <a href="/accounts/password_reset_email/">click here</a> to reset your password or contact the domain administrator.')) username = self.cleaned_data.get('username') if username is None: raise ValidationError(_('Please enter a valid email address.')) password = self.cleaned_data.get('password') if not password: raise ValidationError(_("Please enter a password.")) try: cleaned_data = super(EmailAuthenticationForm, self).clean() except ValidationError: user = CouchUser.get_by_username(username) if user and user.is_locked_out() and user.supports_lockout(): raise ValidationError(lockout_message) else: raise user = CouchUser.get_by_username(username) if user and user.is_locked_out() and user.supports_lockout(): raise ValidationError(lockout_message) return cleaned_data
def sms_user_sync(self, ilsgateway_smsuser, username_part=None, password=None, first_name="", last_name=""): username, username_part = self.get_username(ilsgateway_smsuser, username_part) # sanity check assert len(username) <= 128 user = CouchUser.get_by_username(username) splitted_value = ilsgateway_smsuser.name.split(" ", 1) if not first_name: first_name = splitted_value[0][:30] if splitted_value else "" if not last_name: last_name = splitted_value[1][:30] if len(splitted_value) > 1 else "" language = ilsgateway_smsuser.language user_dict = { "first_name": first_name, "last_name": last_name, "is_active": bool(ilsgateway_smsuser.is_active), "email": ilsgateway_smsuser.email, "user_data": {}, } if ilsgateway_smsuser.role: user_dict["user_data"]["role"] = ilsgateway_smsuser.role if user is None and username_part: try: user_password = password or User.objects.make_random_password() user = CommCareUser.create( domain=self.domain, username=username, password=user_password, email=ilsgateway_smsuser.email, commit=False, password_hashed=bool(password), ) user.first_name = first_name user.last_name = last_name user.language = language user.is_active = bool(ilsgateway_smsuser.is_active) user.user_data = user_dict["user_data"] user.save() self.add_phone_numbers(ilsgateway_smsuser, user) user.save() except Exception as e: logging.error(e) else: self.edit_phone_numbers(ilsgateway_smsuser, user) user.save() return user
def clean_member_email(self): data = self.cleaned_data['member_email'].strip().lower() validate_email(data) exists = CouchUser.get_by_username(data) if not exists: raise forms.ValidationError('User not found!') org = Organization.get_by_name(self.org_name) for id in org.members: if id == exists.get_id: raise forms.ValidationError('User is already part of this organization!') return data
def post(self, request, *args, **kwargs): try: data = json.loads(request.body.decode('utf-8')) 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() session = get_session(session_id) user = get_django_user_from_session(session) if user: couch_user = CouchUser.get_by_username(user.username) if not couch_user: raise Http404 else: raise Http404 domain = data.get('domain') if domain and DISABLE_WEB_APPS.enabled(domain): return HttpResponse('Service Temporarily Unavailable', content_type='text/plain', status=503) # reset the session's expiry if there's some formplayer activity secure_session = session.get('secure_session') TimeoutMiddleware.update_secure_session(session, secure_session, couch_user, domain=data.get('domain')) session.save() domains = set() for domain in couch_user.domains: domains.add(domain) mirror_domains = DomainPermissionsMirror.mirror_domains(domain) domains.update(mirror_domains) return JsonResponse({ 'username': user.username, 'djangoUserId': user.pk, 'superUser': user.is_superuser, 'authToken': None, 'domains': list(domains), 'anonymous': False })
def get_success_url(self): if self.user: # redirect mobile worker password reset to a domain-specific login with their username already set couch_user = CouchUser.get_by_username(self.user.username) if couch_user.is_commcare_user(): messages.success( self.request, _('Password for {} has successfully been reset. You can now login.' ).format(couch_user.raw_username)) return '{}?username={}'.format( reverse('domain_login', args=[couch_user.domain]), couch_user.raw_username, ) return super().get_success_url()
def _inner(request, *args, **kwargs): with mutable_querydict(request.GET): as_user = request.GET.pop('as', None) if not as_user: return HttpResponse('User required', status=401) couch_user = CouchUser.get_by_username(as_user[-1]) if not couch_user: return HttpResponse('Unknown user', status=401) request.user = couch_user.get_django_user() request.couch_user = couch_user return view(request, *args, **kwargs)