def handle(self, *args, **options): region_ids = Region.objects.all().values_list('id', flat=True) time_diff_3_day = self.diff_3_day() for region_id in region_ids: region_admin_emails = list( UserRegion.objects.filter(region_id=region_id).values_list( 'user__email', flat=True)) pending3days = Pending.objects.filter( user__profile__country__region_id=region_id).filter( reminder_sent_to_admin=False).filter( created_at__lte=time_diff_3_day) userlist = self.create_html_list_of_pending_users(pending3days) email_context = { 'userlist': userlist, } if len(pending3days) > 0 and len(region_admin_emails) > 0: send_notification( 'Pending registrations for more than 3 days', region_admin_emails, render_to_string('email/registration/reminder.html', email_context), 'Reminder') pending3days.update(reminder_sent_to_admin=True)
def handle_get(self, request, *args, **kwargs): token = request.GET.get('token', None) user = request.GET.get('user', None) if not token or not user: return bad_http_request( 'Credentials not found', 'The URL must include a token and user. Please check your email and try again.' ) try: pending_user = Pending.objects.get(admin_token=token, user__username=user) except ObjectDoesNotExist: return bad_http_request( 'User not found, or token incorrect', 'We could not find a user and token that matched those supplied.' ) if pending_user.user.is_active: return bad_http_request( '%s is active' % user, 'The user is already active. You can modify user accounts any time using the admin interface.' ) pending_user.user.is_active = True pending_user.user.save() email_context = {frontend_url: frontend_url} send_notification( 'Your account has been approved', [pending_user.user.email], render_to_string('email/registration/outside-email-success.html', email_context)) pending_user.delete() return HttpResponse( render_to_string('registration/validation-success.html'))
def response_change(self, request, obj): if "_activate-user" in request.POST: usr = User.objects.get(id=obj.user.id) if usr: if usr.is_active is False: email_context = {'frontend_url': settings.FRONTEND_URL} send_notification( 'Your account has been approved', [usr.email], render_to_string( 'email/registration/outside-email-success.html', email_context), f'Approved account successfully - {usr.username}') usr.is_active = True usr.save() else: logger.info(f'User {usr.username} was already active') else: logger.info( f'There is no User record with the ID: {obj.user.id}') return HttpResponseRedirect(".") return super().response_change(request, obj)
def check_ingest_issues(self, having_ingest_issue): # having_ingest_issue = CronJob.objects.raw('SELECT * FROM api_cronjob WHERE status=' + str(CronJobStatus.ERRONEOUS.value)) ingest_issue_id = having_ingest_issue[0].id if len(having_ingest_issue) > 0 else -1 ingestor_name = having_ingest_issue[0].name if len(having_ingest_issue) > 0 else '' if len(having_ingest_issue) > 0: # Would be better in ENV variable: send_notification('API monitor – ingest issues!', ['*****@*****.**'], 'Ingest issue(s) occured, one of them is ' + ingestor_name + ', via CronJob log record id: https://' + settings.BASE_URL + '/api/cronjob/' + str(ingest_issue_id) + '. Please fix it ASAP.') logger.info('Ingest issue occured, e.g. by ' + ingestor_name + ', via CronJob log record id: ' + str(ingest_issue_id) + ', notification sent to IM team')
def handle_get(self, request, *args, **kwargs): token = request.GET.get('token', None) user = request.GET.get('user', None) if not token or not user: return bad_http_request( 'Credentials not found', 'The URL must include a token and user. Please check your email and try again.' ) try: pending_user = Pending.objects.get(Q(admin_token_1=token) | Q(admin_token_2=token), user__username=user) except ObjectDoesNotExist: return bad_http_request( 'User not found, or token incorrect', 'We could not find a user and token that matched those supplied.' ) if pending_user.user.is_active: return bad_http_request( '%s is active' % user, 'The user is already active. You can modify user accounts any time using the admin interface.' ) # Determine which admin we're responding to. admin = '1' if token == pending_user.admin_token_1 else '2' did_validate = getattr(pending_user, 'admin_%s_validated' % admin) if did_validate: return bad_http_request('Already confirmed', 'You have already confirmed this user.') else: setattr(pending_user, 'admin_%s_validated' % admin, True) pending_user.save() if pending_user.admin_1_validated and pending_user.admin_2_validated: pending_user.user.is_active = True pending_user.user.save() email_context = {'frontend_url': frontend_url} send_notification( 'Your account has been approved', [pending_user.user.email], render_to_string( 'email/registration/outside-email-success.html', email_context)) pending_user.delete() return HttpResponse( render_to_string('registration/validation-success.html')) else: return HttpResponse( render_to_string('registration/validation-halfsuccess.html'))
def handle(self, *args, **options): now = timezone.now().date() for projects, new_status in [ (Project.objects.filter(start_date__gt=now), Statuses.PLANNED), (Project.objects.filter(start_date__lte=now, end_date__gte=now), Statuses.ONGOING), (Project.objects.filter(end_date__lt=now), Statuses.COMPLETED), ]: updated_projects = projects.exclude(status=new_status) print( f'{str(new_status)} projects' f' Total: {projects.count()},' f' Updated: {updated_projects.count()}' ) updated_projects.update(status=new_status) # Send alert if project status will change in COMPLETE_STATUS_CHANGE_ALERT_DAYS. coming_end_date = now + relativedelta(days=COMPLETE_STATUS_CHANGE_ALERT_DAYS) notify_projects = Project.objects.filter(end_date=coming_end_date).exclude( # Can't send email to user without email Q(user__email__isnull=True) | Q(user__email='') ) for project in notify_projects.distinct(): user = project.user subject = ugettext('3W Project Notification') admin_uri = f'admin:{Project._meta.app_label}_{Project._meta.model_name}_change' records = [{ 'title': ugettext('1 new 3W project notification'), 'is_staff': user.is_staff, 'resource_uri': get_project_url(project.id), 'admin_uri': reverse(admin_uri, args=(project.id,)), 'content': PROJECT_STATUS_WILL_COMPLETE_MESSAGE % { 'project_name': project.name, 'days': COMPLETE_STATUS_CHANGE_ALERT_DAYS, 'end_date': coming_end_date, }, }] send_notification( subject, [user.email], render_to_string( 'design/generic_notification.html', { 'records': records, 'hide_preferences': True, } ), f'Project will change to {str(Statuses.COMPLETED)} notifications - {subject}', ) print(f'Notified users for {notify_projects.count()} projects for coming {str(Statuses.COMPLETED)} status')
def get(self, request): token = request.GET.get('token', None) user = request.GET.get('user', None) if not token or not user: return bad_http_request( 'Credentials not found', 'The URL must include a token and user. Please check your email and try again.' ) try: pending_user = Pending.objects.get(Q(admin_token_1=token) | Q(admin_token_2=token), user__username=user) except ObjectDoesNotExist: return bad_http_request( 'User not found, or token incorrect', 'We could not find a user and token that matched those supplied.' ) if pending_user.user.is_active: return bad_http_request( '%s is active' % user, 'The user is already active. \ You can modify user accounts any time using the admin interface.' ) did_validate = getattr(pending_user, 'admin_1_validated') if did_validate: return bad_http_request('Already confirmed', 'You have already confirmed this user.') setattr(pending_user, 'admin_1_validated', True) setattr(pending_user, 'admin_1_validated_date', timezone.now()) pending_user.save() if pending_user.admin_1_validated: # and pending_user.admin_2_validated: pending_user.user.is_active = True pending_user.user.save() email_context = {'frontend_url': settings.FRONTEND_URL} send_notification( 'Your account has been approved', [pending_user.user.email], render_to_string( 'email/registration/outside-email-success.html', email_context), f'Approved account successfully - {pending_user.user.username}' ) pending_user.delete() return HttpResponse( render_to_string('registration/validation-success.html'))
def handle_post(self, request, *args, **kwargs): body = json.loads(request.body.decode('utf-8')) if not 'email' in body: return bad_request('Must include an `email` property') try: user = User.objects.get(email=body['email']) except ObjectDoesNotExist: return bad_request('That email is not associated with a user') email_context = { 'username': user.username, } send_notification( 'Showing your username', [user.email], render_to_string('email/show_username.html', email_context)) return JsonResponse({'status': 'ok'})
def post(self, request): email = request.data.get('email', None) if email is None: return bad_request('Must include an `email` property') user = User.objects.filter(email__iexact=email).first() if user is None: return bad_request('That email is not associated with a user') email_context = { 'username': user.username, } send_notification('Showing your username', [user.email], render_to_string('email/show_username.html', email_context), 'Username recovery - ' + user.username) return JsonResponse({'status': 'ok'})
def post(self, request): username = request.data.get('username', None) if username: # Now we allow requesting with either email or username pending_user = Pending.objects.select_related('user')\ .filter(Q(user__username__iexact=username) | Q(user__email__iexact=username))\ .first() if pending_user: if pending_user.user.is_active is True: return bad_request('Your registration is already active, \ you can try logging in with your registered username and password') if pending_user.created_at < timezone.now() - timedelta(days=30): return bad_request('The verification period is expired. \ You must verify your email within 30 days. \ Please contact your system administrator.') # Construct and re-send the email email_context = { 'confirmation_link': 'https://%s/verify_email/?token=%s&user=%s' % ( settings.BASE_URL, # on PROD it should point to goadmin... pending_user.token, username, ) } if pending_user.user.is_staff: template = 'email/registration/verify-staff-email.html' else: template = 'email/registration/verify-outside-email.html' send_notification('Validate your account', [pending_user.user.email], render_to_string(template, email_context), 'Validate account - ' + username) return Response({'data': 'Success'}) else: return bad_request('No pending registration found with the provided username. \ Please check your input.') else: return bad_request('Please provide your username in the request.')
def notify(self, records, rtype, stype): record_count = records.count() if not record_count: return emails = self.gather_subscribers(records, rtype, stype) if not len(emails): return # Only serialize the first 10 records entries = list(records) if record_count <= 10 else list(records[:10]) record_entries = [] for record in entries: record_entries.append({ 'resource_uri': self.get_resource_uri(record, rtype), 'admin_uri': self.get_admin_uri(record, rtype), 'title': self.get_record_title(record, rtype), }) template_path = self.get_template() html = render_to_string( template_path, { 'hello': get_hello(), 'count': record_count, 'records': record_entries, }) recipients = emails adj = 'New' if stype == SubscriptionType.NEW else 'Modified' record_type = self.get_record_display(rtype, record_count) subject = '%s %s %s(s) in IFRC GO ' % ( record_count, adj, record_type, ) logger.info('Notifying %s subscriber(s) about %s %s %s' % (len(emails), record_count, adj.lower(), record_type)) send_notification(subject, recipients, html)
def activate_users(self, request, queryset): for pu in queryset: usr = User.objects.filter(id=pu.user_id).first() if usr: if usr.is_active is False: email_context = {'frontend_url': settings.FRONTEND_URL} send_notification( 'Your account has been approved', [usr.email], render_to_string( 'email/registration/outside-email-success.html', email_context), f'Approved account successfully - {usr.username}') usr.is_active = True usr.save() else: logger.info(f'User {usr.username} was already active') else: logger.info( f'There is no User record with the ID: {pu.user_id}')
def handle_post(self, request, *args, **kwargs): body = json.loads(request.body.decode('utf-8')) if not 'email' in body: return bad_request('Must include an `email` property') try: user = User.objects.get(email=body['email']) except ObjectDoesNotExist: return bad_request('That email is not associated with a user') token = get_random_string(length=32) Recovery.objects.filter(user=user).delete() recovery = Recovery.objects.create(user=user, token=token) email_context = { 'frontend_url': frontend_url, 'username': user.username, 'token': token } send_notification( 'Reset your password', [user.email], render_to_string('email/recover_password.html', email_context)) return JsonResponse({'status': 'ok'})
def post(self, request): email = request.data.get('email', None) if email is None: return bad_request('Must include an `email` property') user = User.objects.filter(email__iexact=email).first() if user is None: return bad_request('That email is not associated with a user') token = get_random_string(length=32) Recovery.objects.filter(user=user).delete() Recovery.objects.create(user=user, token=token) email_context = { 'frontend_url': settings.FRONTEND_URL, 'username': user.username, 'token': token } send_notification('Reset your password', [user.email], render_to_string('email/recover_password.html', email_context), 'Password recovery - ' + user.username) return JsonResponse({'status': 'ok'})
# determinamos la cara reconocida con el mayor número de coincidencias name = max(counts, key=counts.get) if name != "Unknown": match_notification = name if notification and int(seconds) == 0: print( "Enviar notificacion: {mn}".format(mn=match_notification)) fecha_actual = datetime.today().strftime("%d/%m/%Y %H:%M:%S") n_a = match_notification.split('_') nombre_apellido = n_a[0].capitalize( ) + ' ' + n_a[1].capitalize() send_notification( to= 'eO4n_KwRSI6SeAUtgZLReY:APA91bFeA9DXW-AW7o2Fv3mrPRzViDlT5qQzHB6GReSL2oi5cGqNq1hCtVxVQbfBhzhxZhzdnJuWb0yV387w7VpFu4HCMEm8pU_7owavetA5tK_o2pr37jbuiFYVxbrZdhG1201PjGTm', title='Detección', subtitle='Se encontró a {n_a} el {fecha}'.format( n_a=nombre_apellido, fecha=fecha_actual), description='Notifiacion: se encontró a {n_a} el {fecha}'. format(n_a=nombre_apellido, fecha=fecha_actual)) insert_into_historial(fecha_actual=fecha_actual, nombre_apellido=nombre_apellido) notification = False # actualizamos la lista de nombres names.append(name) # recorremos con un for las caras reconocidas for ((top, right, bottom, left), name) in zip(boxes, names): # colocamos el nombre de la cara coincidente de la imagen cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2) y = top - 15 if top - 15 > 15 else top + 15
def notify(self, records, rtype, stype, uid=None): record_count = 0 if records: if isinstance(records, QuerySet): record_count = records.count() elif isinstance(records, list): record_count = len(records) if not record_count and rtype != RecordType.WEEKLY_DIGEST: return # Decide if it is a personal notification or batch if uid is None: emails = self.gather_subscribers(records, rtype, stype) if not len(emails): return else: usr = User.objects.filter(pk=uid, is_active=True) if not len(usr): return else: emails = list(usr.values_list( 'email', flat=True)) # Only one email in this case # Only serialize the first 10 records record_entries = [] if rtype == RecordType.WEEKLY_DIGEST: record_entries.append(self.construct_template_record(rtype, None)) else: entries = list(records) if record_count <= 10 else list( records[:10]) for record in entries: record_entries.append( self.construct_template_record(rtype, record)) if uid is not None: is_staff = usr.values_list('is_staff', flat=True)[0] if rtype == RecordType.WEEKLY_DIGEST: record_type = 'weekly digest' else: record_type = self.get_record_display(rtype, record_count) if uid is None: adj = 'new' if stype == SubscriptionType.NEW else 'modified' # subject = '%s %s %s in IFRC GO' % ( if rtype == RecordType.WEEKLY_DIGEST: subject = '%s' % (record_type, ) # subject = '%s %s' % ( # adj, # record_type, # ) else: subject = '%s %s %s' % ( record_count, adj, record_type, ) else: # subject = '%s followed %s modified in IFRC GO' % ( subject = '%s followed %s modified' % ( record_count, record_type, ) if rtype == RecordType.SURGE_ALERT and record_count == 1: # go-frontend/issues/2041 if record.country: if record.country.name in record.event.name: subject += f": {record.event.name}" else: subject += f": {record.event.name}, {record.country.name}" else: subject += f": {record.event.name}" if self.is_daily_checkup_time(): subject += ' [daily followup]' template_path = self.get_template() if rtype == RecordType.FIELD_REPORT or rtype == RecordType.APPEAL or rtype == RecordType.WEEKLY_DIGEST: template_path = self.get_template(rtype) html = render_to_string( template_path, { 'hello': get_hello(), 'count': record_count, 'records': record_entries, 'is_staff': True if uid is None else is_staff, # TODO: fork the sending to "is_staff / not ~" groups 'subject': subject, 'hide_preferences': False, }) recipients = emails if uid is None: # Handle Visibility for Field Reports if rtype == RecordType.FIELD_REPORT: rtype_of_subscr, stype = self.fix_types_for_subs(rtype, stype) non_ifrc_records = [ rec for rec in record_entries if int(rec['visibility']) != 2 ] if non_ifrc_records: non_ifrc_filters = (Q(subscription__rtype=rtype_of_subscr) & Q(subscription__stype=stype) & Q(is_active=True) & (~Q(groups__name='IFRC Admins') & ~Q(is_superuser=True))) non_ifrc_recipients = list( User.objects.filter(non_ifrc_filters).values_list( 'email', flat=True)) # FIXME: Code duplication but this whole thing would need a huge refactor # (almost the same as above and in the 'else' part) if non_ifrc_recipients: non_ifrc_html = render_to_string( template_path, { 'hello': get_hello(), 'count': len(non_ifrc_records), 'records': non_ifrc_records, 'is_staff': True if uid is None else is_staff, 'subject': subject, 'hide_preferences': False, }) send_notification( subject, non_ifrc_recipients, non_ifrc_html, RTYPE_NAMES[rtype] + ' notification (non_ifrc) - ' + subject) ifrc_filters = ( Q(subscription__rtype=rtype_of_subscr) & Q(subscription__stype=stype) & Q(is_active=True) & (Q(groups__name='IFRC Admins') | Q(is_superuser=True))) ifrc_emails = list( User.objects.filter(ifrc_filters).values_list('email', flat=True)) ifrc_recipients = ifrc_emails # FIXME: Code duplication but this whole thing would need a huge refactor # (almost the same as above and in the 'else' part) ifrc_html = render_to_string( template_path, { 'hello': get_hello(), 'count': record_count, 'records': record_entries, 'is_staff': True if uid is None else is_staff, 'subject': subject, 'hide_preferences': False, }) if record_count == 1: subject += ': ' + record_entries[0]['title'] # TODO: check if this is even needed in any case if stype == SubscriptionType.EDIT: for e in list(records.values('id'))[:10]: i = e['id'] if i not in events_sent_to: events_sent_to[i] = [] email_list_to_add = list( set(events_sent_to[i] + non_ifrc_recipients)) if email_list_to_add: events_sent_to[i] = list( filter(None, email_list_to_add)) # record_type has its possible plural thanks to get_record_display() plural = '' if len(emails) == 1 else 's' logger.info( 'Notifying %s subscriber%s about %s %s %s' % (len(emails), plural, record_count, adj, record_type)) send_notification( subject, ifrc_recipients, ifrc_html, RTYPE_NAMES[rtype] + ' notification (ifrc) - ' + subject) else: if record_count == 1: # On purpose after rendering – the subject changes only, not email body subject += ': ' + record_entries[0]['title'] # TODO: check if this is even needed in any case # For new (email-documented :10) events we store data to events_sent_to{ event_id: recipients } if stype == SubscriptionType.EDIT: # Recently we do not allow EDIT substription for e in list(records.values('id'))[:10]: i = e['id'] if i not in events_sent_to: events_sent_to[i] = [] email_list_to_add = list( set(events_sent_to[i] + recipients)) if email_list_to_add: events_sent_to[i] = list( filter(None, email_list_to_add) ) # filter to skip empty elements plural = '' if len( emails ) == 1 else 's' # record_type has its possible plural thanks to get_record_display() logger.info( 'Notifying %s subscriber%s about %s %s %s' % (len(emails), plural, record_count, adj, record_type)) send_notification( subject, recipients, html, RTYPE_NAMES[rtype] + ' notification - ' + subject) else: if len(recipients): # check if email is not in events_sent_to{event_id: recipients} if not emails: logger.info( 'Silent about the one-by-one subscribed %s – user %s has not set email address' % (record_type, uid)) # Recently we do not allow EDIT (modif.) subscription # , so it is irrelevant recently (do not check the 1+ events in loop) : elif (records[0].id not in events_sent_to) or ( emails[0] not in events_sent_to[records[0].id]): logger.info( 'Notifying %s subscriber about %s one-by-one subscribed %s' % ( len(emails), record_count, record_type, )) send_notification( subject, recipients, html, RTYPE_NAMES[rtype] + ' notification - ' + subject) else: logger.info( 'Silent about a one-by-one subscribed %s – user already notified via generic subscription' % (record_type))
def handle_get(self, request, *args, **kwargs): token = request.GET.get('token', None) user = request.GET.get('user', None) if not token or not user: return bad_http_request( 'Credentials not found', 'The URL must include a token and user. Please check your verification email and try again. If this problem persists, contact a system administrator.' ) try: pending_user = Pending.objects.get(token=token, user__username=user) except ObjectDoesNotExist: return bad_http_request( 'User not found, or token incorrect', 'We could not find a user and token that matched those supplied. Please contact your system administrator.' ) if pending_user.user.is_active: return bad_http_request( '%s is active' % user, 'The user is already active. If you need to reset your password, contact your system administrator.' ) if pending_user.email_verified: return bad_http_request( 'You have already verified your email', 'A validation email has been sent to the administrators you listed.' ) if pending_user.created_at < datetime.utcnow().replace( tzinfo=pytz.utc) - timedelta(days=1): return bad_http_request( 'This link is expired', 'You must verify your email within 24 hours. Please contact your system administrator.' ) if is_valid_domain(pending_user.user.email): pending_user.user.is_active = True pending_user.user.save() pending_user.delete() return HttpResponse(render_to_string('registration/success.html')) else: admins = [ pending_user.admin_contact_1, pending_user.admin_contact_2 ] for idx, admin in enumerate(admins): token = pending_user.admin_token_1 if idx == 1 else pending_user.admin_token_2 email_context = { 'validation_link': '%s/validate_user/?token=%s&user=%s' % ( settings.BASE_URL, token, user, ), 'first_name': pending_user.user.first_name, 'last_name': pending_user.user.last_name, 'email': pending_user.user.email, } send_notification( 'Reference to approve an account', [admin], render_to_string('email/registration/validate.html', email_context)) pending_user.email_verified = True pending_user.save() return HttpResponse( render_to_string('registration/validation-sent.html'))
def handle_post(self, request, *args, **kwargs): body = json.loads(request.body.decode('utf-8')) required_fields = [ 'email', 'username', 'password', 'country', 'organizationType', 'organization', 'firstname', 'lastname', ] missing_fields = [ field for field in required_fields if field not in body ] if len(missing_fields): return bad_request('Could not complete request. Please submit %s' % ', '.join(missing_fields)) is_staff = is_valid_domain(body['email']) admins = True if is_staff else get_valid_admins(body['contact']) if not admins: return bad_request( 'Non-IFRC users must submit two valid admin emails.') if User.objects.filter(email=body['email']).count() > 0: return bad_request( 'A user with that email address already exists.') if User.objects.filter(username=body['username']).count() > 0: return bad_request( 'That username is taken, please choose a different one.') try: user = create_active_user(body) except: return bad_request('Could not create user.') try: # Note, this also sets the user's active status to False set_user_profile_inactive(user, body) except: User.objects.filter(username=body['username']).delete() return bad_request('Could not create user profile.') pending = Pending.objects.create(user=user, token=get_random_string(length=32)) if not is_staff: pending.admin_contact_1 = admins[0] pending.admin_contact_2 = admins[1] pending.admin_token_1 = get_random_string(length=32) pending.admin_token_2 = get_random_string(length=32) pending.admin_1_validated = False pending.admin_2_did_validation = False pending.save() email_context = { 'confirmation_link': '%s/verify_email/?token=%s&user=%s' % ( settings.BASE_URL, pending.token, body['username'], ) } # if validated email accounts get a different message if is_staff: template = 'email/registration/verify-staff-email.html' else: template = 'email/registration/verify-outside-email.html' send_notification('Validate your account', [body['email']], render_to_string(template, email_context)) return JsonResponse({'status': 'ok'})
def notify(self, records, rtype, stype, uid=None): record_count = 0 if records: record_count = records.count() if not record_count and rtype != RecordType.WEEKLY_DIGEST: return # Decide if it is a personal notification or batch if uid is None: emails = self.gather_subscribers(records, rtype, stype) if not len(emails): return else: usr = User.objects.filter(pk=uid, is_active=True) if not len(usr): return else: emails = list(usr.values_list( 'email', flat=True)) # Only one email in this case # TODO: maybe this needs to be adjusted based on the new functionality (at first only handling Weekly Digest) # Only serialize the first 10 records record_entries = [] if rtype == RecordType.WEEKLY_DIGEST: record_entries.append(self.construct_template_record(rtype, None)) else: entries = list(records) if record_count <= 10 else list( records[:10]) for record in entries: record_entries.append( self.construct_template_record(rtype, record)) if uid is not None: is_staff = usr.values_list('is_staff', flat=True)[0] if rtype == RecordType.WEEKLY_DIGEST: record_type = 'weekly digest' else: record_type = self.get_record_display(rtype, record_count) if uid is None: adj = 'new' if stype == SubscriptionType.NEW else 'modified' #subject = '%s %s %s in IFRC GO' % ( if rtype == RecordType.WEEKLY_DIGEST: subject = '%s %s' % ( adj, record_type, ) else: subject = '%s %s %s' % ( record_count, adj, record_type, ) else: #subject = '%s followed %s modified in IFRC GO' % ( subject = '%s followed %s modified' % ( record_count, record_type, ) if self.is_retro_mode(): subject += ' [daily followup]' template_path = self.get_template() if rtype == RecordType.FIELD_REPORT or rtype == RecordType.APPEAL or rtype == RecordType.WEEKLY_DIGEST: template_path = self.get_template(rtype) html = render_to_string( template_path, { 'hello': get_hello(), 'count': record_count, 'records': record_entries, 'is_staff': True if uid is None else is_staff, # TODO: fork the sending to "is_staff / not ~" groups 'subject': subject, }) recipients = emails if uid is None: if record_count == 1: subject += ': ' + record_entries[0][ 'title'] # On purpose after rendering – the subject changes only, not email body # For new (email-documented :10) events we store data to events_sent_to{ event_id: recipients } if stype == SubscriptionType.EDIT: # Recently we do not allow EDIT substription for e in list(records.values('id'))[:10]: i = e['id'] if i not in events_sent_to: events_sent_to[i] = [] email_list_to_add = list( set(events_sent_to[i] + recipients)) if email_list_to_add: events_sent_to[i] = list( filter(None, email_list_to_add) ) # filter to skip empty elements plural = '' if len( emails ) == 1 else 's' # record_type has its possible plural thanks to get_record_display() logger.info('Notifying %s subscriber%s about %s %s %s' % (len(emails), plural, record_count, adj, record_type)) send_notification(subject, recipients, html) else: if len(recipients): # check if email is not in events_sent_to{event_id: recipients} if not emails: logger.info( 'Silent about the one-by-one subscribed %s – user %s has not set email address' % (record_type, uid)) # Recently we do not allow EDIT (modif.) subscription, so it is irrelevant recently (do not check the 1+ events in loop) : elif (records[0].id not in events_sent_to) or ( emails[0] not in events_sent_to[records[0].id]): logger.info( 'Notifying %s subscriber about %s one-by-one subscribed %s' % (len(emails), record_count, record_type)) send_notification(subject, recipients, html) else: logger.info( 'Silent about a one-by-one subscribed %s – user already notified via generic subscription' % (record_type))
def post(self, request): required_fields = ( 'email', # 'username', 'password', 'country', 'organizationType', 'organization', 'firstname', 'lastname', ) missing_fields = [ field for field in required_fields if field not in request.data ] if missing_fields: return bad_request('Could not complete request. Please submit %s' % ', '.join(missing_fields)) email = request.data.get('email', None) # Since username is a required field we still need to fill it in # but now only email is being used for new registrations username = request.data.get('email', None) password = request.data.get('password', None) firstname = request.data.get('firstname', None) lastname = request.data.get('lastname', None) country = request.data.get('country', None) city = request.data.get('city', None) organization_type = request.data.get('organizationType', None) organization = request.data.get('organization', None) department = request.data.get('department', None) position = request.data.get('position', None) phone_number = request.data.get('phoneNumber', None) justification = request.data.get('justification', None) is_staff = is_valid_domain(email) if User.objects.filter(email__iexact=email).exists(): return bad_request( 'A user with that email address already exists.') if User.objects.filter(username__iexact=username).exists(): return bad_request( 'That username is taken, please choose a different one.') if ' ' in username: return bad_request( 'Username can not contain spaces, please choose a different one.' ) # Create the User object try: user = create_inactive_user(username, firstname, lastname, email, password) except Exception: return bad_request('Could not create user.') # Set the User Profile properties try: set_user_profile(user, country, organization_type, organization, city, department, position, phone_number) except Exception: User.objects.filter(username=username).delete() return bad_request('Could not create user profile.') pending = Pending.objects.create(user=user, justification=justification, token=get_random_string(length=32)) if not is_staff: pending.admin_token_1 = get_random_string(length=32) pending.save() email_context = { 'confirmation_link': 'https://%s/verify_email/?token=%s&user=%s' % ( settings.BASE_URL, # on PROD it should point to goadmin... pending.token, username, ) } # if validated email accounts get a different message if is_staff: template = 'email/registration/verify-staff-email.html' else: template = 'email/registration/verify-outside-email.html' send_notification('Validate your account', [email], render_to_string(template, email_context), 'Validate account - ' + username) return JsonResponse({'status': 'ok'})
def on_commit(): record_type = instance.record_type() rtype = getattr(RecordType, record_type) stype = SubscriptionType.NEW if created else SubscriptionType.EDIT subscribers = User.objects.filter( subscription__rtype=rtype, subscription__stype=stype).values('email') lookups = [] # add subscribers who have subscribed to this specific disaster type if instance.dtype is not None: lookups.append('d%s' % instance.dtype.id) # appeals have one country, events and reports have multiple # also include attached regions if record_type == 'APPEAL': if instance.country is not None: lookups.append('c%s' % instance.country.id) if instance.country.region is not None: lookups.append('%rs' % instance.country.region.id) elif instance.countries is not None: countries = instance.countries.prefetch_related('region').all() lookups += ['c%s' % country.id for country in countries] lookups += [ 'r%s' % getattr(country, 'region.id', None) for country in countries ] if len(lookups): subscribers = (subscribers | User.objects.filter( subscription__lookup_id__in=lookups).values('email') ).distinct() if len(subscribers): context = instance.to_dict() # Appeals do not have their own page, currently, # but they do display on the homepage. if record_type == 'APPEAL': context['resource_uri'] = frontend_url else: frontend_path = { 'EVENT': 'emergencies', 'FIELD_REPORT': 'reports', }[record_type] context['resource_uri'] = '%s/%s/%s/' % ( frontend_url, frontend_path, instance.id) context['admin_uri'] = '%s/%s/' % (settings.BASE_URL, 'admin') if instance.dtype is not None: context['dtype'] = instance.dtype.name template_path = template_paths['%s%s' % (rtype, stype)] html = render_to_string(template_path, context) recipients = [s['email'] for s in subscribers] adj = 'New' if created else 'Modified' subject = '%s %s in IFRC GO' % (adj, record_type.lower()) send_notification(subject, recipients, html)
def get(self, request): token = request.GET.get('token', None) user = request.GET.get('user', None) if not token or not user: return bad_http_request( 'Credentials not found', 'The URL must include a token and user. \ Please check your verification email and try again. \ If this problem persists, contact a system administrator.' ) try: pending_user = Pending.objects.get(token=token, user__username=user) except ObjectDoesNotExist: return bad_http_request( 'User not found, or token incorrect', 'We could not find a user and token that matched those supplied. \ Please contact your system administrator.') if pending_user.user.is_active: return bad_http_request( '%s is active' % user, 'The user is already active. If you need to reset your password, \ contact your system administrator.') if pending_user.email_verified: return bad_http_request( 'You have already verified your email', 'A validation email has been sent to the administrators you listed.' ) if pending_user.created_at < timezone.now() - timedelta(days=30): return bad_http_request( 'This link is expired', 'You must verify your email within 30 days. \ Please contact your system administrator.') if is_valid_domain(pending_user.user.email): pending_user.user.is_active = True pending_user.user.save() pending_user.delete() email_context = {'frontend_url': settings.FRONTEND_URL} return HttpResponse( render_to_string('registration/success.html', email_context)) else: admins = getRegionalAdmins(pending_user.user_id) for admin in admins: token = pending_user.admin_token_1 email_context = { 'validation_link': 'https://%s/validate_user/?token=%s&user=%s' % ( settings. BASE_URL, # on PROD it should point to goadmin... token, user, ), 'first_name': pending_user.user.first_name, 'last_name': pending_user.user.last_name, 'username': pending_user.user.username, 'email': pending_user.user.email, 'region': pending_user.user.profile.country.region, 'country': pending_user.user.profile.country, 'organization': pending_user.user.profile.org, 'city': pending_user.user.profile.city, 'department': pending_user.user.profile.department, 'position': pending_user.user.profile.position, 'phone': pending_user.user.profile.phone_number, 'justification': pending_user.justification, } send_notification( 'Reference to approve an account', [admin], render_to_string('email/registration/validate.html', email_context), 'Approve an account - ' + pending_user.user.username) pending_user.email_verified = True pending_user.save() return HttpResponse( render_to_string('registration/validation-sent.html'))