def validate(self, request=None, add_messages=False): valid = True if not validator.name(self.name): if add_messages: messages.error(request, "Du har glemt å skrive inn navnet ditt.") valid = False if not validator.address(self.address): if add_messages: messages.error(request, "Du må oppgi din egen adresse da vi sender faktura og medlemskort hjem til deg.") valid = False if not validator.zipcode(self.zipcode) or self.area == '': # Empty area defines invalid zipcode, as stated in __init__ if add_messages: messages.error(request, "Postnummeret ditt ser ikke riktig ut. Du må oppgi et gyldig postnummer da vi sender faktura og medlemskort hjem til deg.") valid = False if not validator.memberid(self.memberid, req=False): if add_messages: messages.error(request, "Medlemsnummeret ditt kan kun bestå av tall. Du trenger ikke være medlem for å bestille gavemedlemskap, da kan du la medlemsnummerfeltet stå tomt.") valid = False if not validator.phone(self.phone, req=False): if add_messages: messages.error(request, "Telefonnummeret ditt må være minst 8 siffer. Du trenger ikke oppgi telefonnummeret ditt, men vi anbefaler at du gir oss minst én måte å kontakte deg.") valid = False if not validator.email(self.email, req=False): if add_messages: messages.error(request, "E-postadressen din er ikke en gyldig adresse. Du trenger ikke oppgi e-postadressen din, men vi anbefaler at du gir oss minst én måte å kontakte deg.") valid = False return valid
def is_valid(self, require_contact_info=False): # Name or address is empty if not validator.name(self.name): return False # Gender is not set if self.gender != 'm' and self.gender != 'f': return False # Use validator for phone number, require only if required if not validator.phone(self.phone, req=require_contact_info): return False # Use validator for email address, require only if required if not validator.email(self.email, req=require_contact_info): return False # Date of birth is saved as NULL when invalid if self.dob is None: return False # Birthyear is out of smalldatetime range (MSSQLs datetime datatype will barf) if self.dob.year < 1900 or self.dob.year > 2078: return False # Birthdate can't be in the future if self.dob > date.today(): return False # All tests passed! return True
def attempt_registration_nonmember(request): error_messages = [] # Check that name is provided if not validator.name(request.POST['name']): error_messages.append('invalid_name') # Check that the email address is valid if not validator.email(request.POST['email']): error_messages.append('invalid_email') # Check that the email address isn't in use if User.objects.filter(identifier=request.POST['email']).exists(): error_messages.append('email_exists') # Check that the password is long enough if len(request.POST['password']) < settings.USER_PASSWORD_LENGTH: error_messages.append('too_short_password') if len(error_messages) > 0: request.session['user.registration_nonmember_attempt'] = { 'name': request.POST['name'], 'email': request.POST['email'] } return None, error_messages user = User(identifier=request.POST['email'], email=request.POST['email']) user.first_name, user.last_name = request.POST['name'].rsplit(maxsplit=1) user.set_consent_accepted_privacy_policy_date(None, False) user.set_password(request.POST['password']) user.save() user.set_consent_dnt( Forening.DNT_CENTRAL_ID, 'email', True if request.POST.get('consent-dnt-communication-email') else False, save=True, ) authenticate(user=user) log_user_in(request, user) try: message = render_to_string('common/user/login/registered_nonmember_email.txt', request=request) send_mail(EMAIL_REGISTERED_SUBJECT, message, settings.DEFAULT_FROM_EMAIL, [user.get_email()]) except (SMTPException, SSLError, UnicodeEncodeError): # Silently log and ignore this error. Consider warning the user that the email wasn't sent? logger.warning( "Klarte ikke å sende registreringskvitteringepost", exc_info=sys.exc_info(), extra={'request': request} ) return user, None
def attempt_registration(request): # Check that the password is long enough if len(request.POST['password']) < settings.USER_PASSWORD_LENGTH: return None, 'too_short_password' # Check that the email address is valid if not validator.email(request.POST['email']): return None, 'invalid_email' try: user = verify_memberid( ip_address=request.META['REMOTE_ADDR'], memberid=request.POST['memberid'], country_code=request.POST['country'], zipcode=request.POST['zipcode'], ) if not user.is_inactive: return None, 'user_exists' user.set_contact_info({'email': request.POST['email'].strip()}) user.is_inactive = False user.activated = datetime.now() user.set_consent_accepted_privacy_policy_date(None, False) user.set_password(request.POST['password']) user.save() authenticate(user=user) log_user_in(request, user) try: message = render_to_string('common/user/login/registered_email.txt', request=request) send_mail(EMAIL_REGISTERED_SUBJECT, message, settings.DEFAULT_FROM_EMAIL, [user.get_email()]) except (SMTPException, SSLError, UnicodeEncodeError): # Silently log and ignore this error. Consider warning the user that the email wasn't sent? logger.warning( "Klarte ikke å sende registreringskvitteringepost", exc_info=sys.exc_info(), extra={'request': request} ) return user, None except MemberidLookupsExceeded: return None, 'memberid_lookups_exceeded' except CountryDoesNotExist: raise PermissionDenied except (NoMatchingMemberid, ActorIsNotPersonalMember, ValueError): return None, 'invalid_memberid'
def validate(self, request=None, add_messages=False): valid = True if self.type_index < 0 or self.type_index >= len(membership_types): if add_messages: messages.error(request, "Du har på en eller annen måte klart å angi en ugyldig medlemskapstype. Vennligst bruk select-boksen til å velge medlemskapstype.") valid = False if not validator.name(self.name): if add_messages: if len(self.name) > 0: messages.error(request, "Du må angi fullt navn til %s." % self.name) else: messages.error(request, "En av mottakerne mangler navn.") valid = False if not isinstance(self.dob, datetime): if add_messages: messages.error(request, "Fødselsdatoen til %s er ugyldig." % self.name) valid = False if isinstance(self.dob, datetime) and self.dob >= datetime.now(): if add_messages: messages.error(request, "Fødselsdatoen til %s kan ikke være i fremtiden." % self.name) valid = False if not validator.address(self.address): if add_messages: messages.error(request, "%s mangler adresse." % self.name) valid = False if not validator.zipcode(self.zipcode) or self.area == '': if add_messages: messages.error(request, "Postnummeret til %s er mangler eller er feil." % self.name) valid = False if not validator.phone(self.phone, req=False): if add_messages: messages.error(request, "Telefonnummeret til %s må bestå av minst 8 siffer." % self.name) valid = False if not validator.email(self.email, req=False): if add_messages: messages.error(request, "E-postadressen til %s er ikke gyldig." % self.name) valid = False return valid
def attempt_registration_nonmember(request): error_messages = [] # Check that name is provided if not validator.name(request.POST['name']): error_messages.append('invalid_name') # Check that the email address is valid if not validator.email(request.POST['email']): error_messages.append('invalid_email') # Check that the email address isn't in use if User.objects.filter(identifier=request.POST['email']).exists(): error_messages.append('email_exists') # Check that the password is long enough if len(request.POST['password']) < settings.USER_PASSWORD_LENGTH: error_messages.append('too_short_password') if len(error_messages) > 0: request.session['user.registration_nonmember_attempt'] = { 'name': request.POST['name'], 'email': request.POST['email'] } return None, error_messages user = User(identifier=request.POST['email'], email=request.POST['email']) user.first_name, user.last_name = request.POST['name'].rsplit(' ', 1) user.set_password(request.POST['password']) user.save() authenticate(user=user) log_user_in(request, user) try: t = loader.get_template('common/user/login/registered_nonmember_email.txt') c = RequestContext(request) send_mail(EMAIL_REGISTERED_SUBJECT, t.render(c), settings.DEFAULT_FROM_EMAIL, [user.get_email()]) except (SMTPException, SSLError): # Silently log and ignore this error. Consider warning the user that the email wasn't sent? logger.warning(u"Klarte ikke å sende registreringskvitteringepost", exc_info=sys.exc_info(), extra={'request': request} ) return user, None
def upload(request): try: image_file = request.FILES['file'] except KeyError: raise PermissionDenied if not validator.name(request.POST.get('name', '')): raise PermissionDenied if not validator.phone(request.POST.get('phone', '')): raise PermissionDenied if not validator.email(request.POST.get('email', '')): raise PermissionDenied if len(request.POST.get('description', '').strip()) == 0: raise PermissionDenied post_name = request.POST['name'].strip() post_phone = request.POST['phone'].strip() post_email = request.POST['email'].strip() post_description = request.POST['description'].strip() try: conn = boto.connect_s3(settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY) bucket = conn.get_bucket(s3_bucket()) image_key = Image.generate_unique_random_key() data = image_file.read() ext = image_file.name.split(".")[-1].lower() pil_image = PIL.Image.open(StringIO(data)) exif_json = json.dumps(get_exif_tags(pil_image)) image_file_tags = xmp.find_keywords(data) thumbs = [{'size': size, 'data': create_thumb(pil_image, ext, size)} for size in settings.THUMB_SIZES] if pil_image.size[0] < MIN_SIZE or pil_image.size[1] < MIN_SIZE: return HttpResponseBadRequest(json.dumps({ 'files': [{ 'name': image_file.name, 'size': image_file.size, 'error': u"Bildet må være minst 800x800 piksler", }] })) # Give boto an encoded str, not unicode content_type = image_file.content_type.encode('utf-8') key = boto.s3.key.Key(bucket, '%s%s.%s' % (settings.AWS_IMAGEGALLERY_PREFIX, image_key, ext)) key.content_type = content_type key.set_contents_from_string(data, policy='public-read') for thumb in thumbs: key = boto.s3.key.Key(bucket, '%s%s-%s.%s' % (settings.AWS_IMAGEGALLERY_PREFIX, image_key, thumb['size'], ext)) key.content_type = content_type key.set_contents_from_string(thumb['data'], policy='public-read') destination_album = Fotokonkurranse.objects.get().album licence_text = "Kan brukes i DNTs egne kommunikasjonskanaler som magasiner, nettsider og sosiale medier, i PR og for bruk av DNTs sponsorer." image = Image( key=image_key, extension=ext, hash=sha1(data).hexdigest(), description=post_description, album=destination_album, photographer=post_name, credits="%s / DNTs fotokonkurranse" % post_name, licence="%s Kontakt: %s (%s / %s)" % (licence_text, post_name, post_phone, post_email), exif=exif_json, uploader=request.user if not request.user.is_anonymous() else None, width=pil_image.size[0], height=pil_image.size[1]) image.save() for tag in [tag.lower() for tag in image_file_tags]: obj, created = Tag.objects.get_or_create(name=tag) image.tags.add(obj) # Note that we're caching the email address for one hour and not resending the email receipt # for further uploads from that address during this period. if cache.get('fotokonkurranse.emails.%s' % post_email) is None: # Set the cache quickly when we know we're going to send an email. Don't wait until after # it's sent, because other upload requests may try to send meanwhile and we don't want them to. cache.set('fotokonkurranse.emails.%s' % post_email, True, 60 * 60) try: t = loader.get_template('central/fotokonkurranse/email_confirmation.txt') c = RequestContext(request, { 'user_name': post_name, }) send_mail(EMAIL_CONFIRMATION_SUBJECT, t.render(c), settings.DEFAULT_FROM_EMAIL, [post_email]) except (SMTPException, SSLError): cache.delete('fotokonkurranse.emails.%s' % post_email) logger.warning(u"Kvitteringsepost for fotokonkurranse feilet", exc_info=sys.exc_info(), extra={'request': request} ) return HttpResponse(json.dumps({ 'files': [{ 'name': image_file.name, 'size': image_file.size, 'url': '', 'thumbnailUrl': '', 'deleteUrl': '', 'deleteType': '', }] })) except Exception as e: logger.error(u"Feil ved opplasting av bilde til fotokonkurranse", exc_info=sys.exc_info(), extra={'request': request} ) return HttpResponseBadRequest(json.dumps({ 'files': [{ 'name': image_file.name, 'size': image_file.size, 'error': "Exception ved bildeopplasting: %s" % e, }] }))
def send_restore_password_email(request): if 'email' not in request.POST: raise PermissionDenied email = request.POST['email'].strip() if not validator.email(email): return HttpResponse(json.dumps({'status': 'invalid_email'})) # The address might match one non-member, check it: local_matches = list(User.objects.filter(memberid__isnull=True, email=email)) # The address might match several members, registered or not focus_unregistered_matches = False # Search through matching Actors for actor in Actor.get_personal_members().filter(email=email): try: # Ok, look for any matching active user user = User.get_users( include_pending=True, include_expired=True ).get( memberid=actor.memberid, is_inactive=False # ignore inactive users; these need to register first ) # Reset state if this user was previously pending but is now a proper member if user.is_pending: user.is_pending = False user.save() # Reset state if this user was previously marked as expired for some reason if user.is_expired: user.is_expired = False user.save() local_matches.append(user) except User.DoesNotExist: # There is an actor but no corresponding user - inform the user that they need to register focus_unregistered_matches = True # Now search through matching active enrollments for enrollment in Enrollment.filter_on_email(email): try: # Ok, look for any matching active AND pending user user = User.get_users( include_pending=True, include_expired=True ).get( memberid=enrollment.memberid, is_pending=True, is_inactive=False # ignore inactive users; these need to register first ) # Reset state if this user was previously marked as expired for some reason if user.is_expired: user.is_expired = False user.save() # Check that the user isn't already matched as an Actor since this theoretically could be a duplicate if user not in local_matches: local_matches.append(user) except User.DoesNotExist: pass if len(local_matches) == 0: # No email-address matches. if focus_unregistered_matches: # Oh, the email address exists in Focus, but the user(s) aren't in our user-base. Let them know. return HttpResponse(json.dumps({'status': 'unregistered_email'})) else: return HttpResponse(json.dumps({'status': 'unknown_email'})) else: for user in local_matches: key = crypto.get_random_string(length=settings.RESTORE_PASSWORD_KEY_LENGTH) while User.objects.filter(password_restore_key=key).exists(): # Ensure that the key isn't already in use. With the current key length of 40, we'll have # ~238 bits of entropy which means that this will never ever happen, ever. # You will win the lottery before this happens. And I want to know if it does, so log it. logger.warning( "Noen fikk en random-generert password-restore-key som allerede finnes!", extra={ 'request': request, 'should_you_play_the_lottery': True, 'key': key } ) key = crypto.get_random_string(length=settings.RESTORE_PASSWORD_KEY_LENGTH) user.password_restore_key = key user.password_restore_date = datetime.now() user.save() if len(local_matches) == 1: context = { 'found_user': user, 'validity_period': settings.RESTORE_PASSWORD_VALIDITY, } message = render_to_string('common/user/login/restore-password-email.txt', context, request=request) else: context = { 'users': local_matches, 'validity_period': settings.RESTORE_PASSWORD_VALIDITY, } message = render_to_string( 'common/user/login/restore-password-email-multiple.txt', context, request=request, ) send_mail("Nytt passord på Min side", message, settings.DEFAULT_FROM_EMAIL, [email]) return HttpResponse(json.dumps({'status': 'success'}))
def save(request): if request.method != 'POST': return redirect('fjelltreffen:mine') # If user hasn't paid, allow editing, but not creating new annonser if not request.user.payment.status['is_paid'] and request.POST['id'] == '': raise PermissionDenied # Pre-save validations errors = False if request.POST.get('id', '') == '': # New annonse (not editing an existing one), create it annonse = Annonse() annonse.user = request.user else: annonse = Annonse.objects.get(id=request.POST['id']) if annonse.user != request.user: # someone is trying to edit an annonse that dosent belong to them raise PermissionDenied if request.POST.get('title', '') == '': messages.error(request, 'missing_title') errors = True if not validator.email(request.POST['email']): messages.error(request, 'invalid_email') errors = True if request.POST.get('text', '') == '': messages.error(request, 'missing_text') errors = True if 'image' in request.FILES: try: # Uploading image file = request.FILES['image'] data = file.read() extension = standardize_extension(file.name.split(".")[-1]) # Create the thumbnail thumb = PIL.Image.open(BytesIO(data)).copy() fp = BytesIO() thumb.thumbnail( [settings.FJELLTREFFEN_IMAGE_THUMB_SIZE, settings.FJELLTREFFEN_IMAGE_THUMB_SIZE], PIL.Image.ANTIALIAS, ) thumb.save(fp, extension) thumb_data = fp.getvalue() # Calculate sha1-hashes sha1 = hashlib.sha1() sha1.update(data) hash = sha1.hexdigest() sha1 = hashlib.sha1() sha1.update(thumb_data) thumb_hash = sha1.hexdigest() except Exception: logger.warning( "Kunne ikke laste opp Fjelltreffen-bilde", exc_info=sys.exc_info(), extra={'request': request} ) messages.error(request, 'image_upload_error') errors = True if errors: if request.POST.get('id', '') == '': return redirect('fjelltreffen:new') else: return redirect('fjelltreffen:edit', request.POST['id']) hidden = request.POST.get('hidden', 'hide') == 'hide' # Don't allow showing an already hidden annonse when you haven't paid if request.POST['id'] != '': if annonse.hidden and not request.user.payment.status['is_paid']: hidden = True # Don't create new annonser if you already have an active annonse if request.POST.get('id', '') == '': annonser_to_check = Annonse.get_active() else: annonser_to_check = Annonse.get_active().exclude(id=request.POST['id']) if annonser_to_check.filter(user=request.user).exists(): hidden = True if request.POST.get('county', '') == 'international': annonse.county = None else: annonse.county = County.typical_objects().get(id=request.POST.get('county', '')) # TODO: Validate and return form to user with error message annonse.title = request.POST.get('title', '')[:255] annonse.email = request.POST.get('email', '')[:255] if 'image' in request.FILES: # Delete any existing image annonse.delete_image() # Setup AWS connection conn = boto.connect_s3(settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY) bucket = conn.get_bucket(settings.AWS_S3_BUCKET) # Upload the original image to AWS key = bucket.new_key("%s/%s.%s" % (settings.AWS_S3_FOLDERS['fjelltreffen'], hash, extension)) key.content_type = file.content_type key.set_contents_from_string(data, policy='public-read') # Upload the thumbnail to AWS key = bucket.new_key("%s/%s.%s" % (settings.AWS_S3_FOLDERS['fjelltreffen'], thumb_hash, extension)) key.content_type = file.content_type key.set_contents_from_string(thumb_data, policy='public-read') # Update the DB fields with new images annonse.image = "%s.%s" % (hash, extension) annonse.image_thumb = "%s.%s" % (thumb_hash, extension) annonse.text = request.POST.get('text', '') annonse.hidden = hidden annonse.hideage = request.POST.get('hideage', '') == 'hide' annonse.save() return redirect('fjelltreffen:mine')
def register_membership(request): """This view should reuse the standard registration logic in user/login/util and still merge the user objects instead of reimplementing the logic.""" if request.user.is_member(): return redirect('user:home') if request.method == 'GET': context = { 'memberid_lookups_limit': settings.MEMBERID_LOOKUPS_LIMIT, 'countries': FocusCountry.get_sorted() } return render(request, 'common/user/account/register_membership.html', context) elif request.method == 'POST': try: user = request.user verified_user = verify_memberid( ip_address=request.META['REMOTE_ADDR'], memberid=request.POST['memberid'], country_code=request.POST['country'], zipcode=request.POST['zipcode'], ) if request.POST['email-equal'] == 'true': # Focus-email is empty, or equal to this email, so just use it chosen_email = user.get_email() elif request.POST['email-choice'] == 'sherpa': chosen_email = user.get_email() elif request.POST['email-choice'] == 'focus': chosen_email = verified_user.get_email() elif request.POST['email-choice'] == 'custom': # Check that the email address is valid if not validator.email(request.POST['email']): messages.error(request, 'invalid_email') return redirect('user:register_membership') chosen_email = request.POST['email'] else: raise Exception("Missing email-equal / email-choise-parameters") # Check that the user doesn't already have an account if not verified_user.is_inactive: messages.error(request, 'user_exists') return redirect('user:register_membership') # Ok, registration successful, update the user # The verified user might be pending. The merge method only merges related objects, so if that's the case, # set the new user's state to pending. if verified_user.is_pending: user.is_pending = True user.save() # The verification lookup will ensure there's already an inactive user, pending or not, so merge them user.merge_with(verified_user, move_password=True) # This will delete the other user # Point the user to its corresponding memberid and clear other personal information user.identifier = request.POST['memberid'] user.memberid = request.POST['memberid'] user.first_name = '' user.last_name = '' user.email = '' user.save() # Save the chosen email in Focus user.set_contact_info({'email': chosen_email}) return redirect('user:home') except MemberidLookupsExceeded: messages.error(request, 'memberid_lookups_exceeded') return redirect('user:register_membership') except CountryDoesNotExist: raise PermissionDenied except (NoMatchingMemberid, ActorIsNotPersonalMember, ValueError): messages.error(request, 'invalid_memberid') return redirect('user:register_membership')
def update_account(request): if not request.user.is_member(): if request.method == 'GET': context = { 'user_password_length': settings.USER_PASSWORD_LENGTH } return render(request, 'common/user/account/update_account_nonmember.html', context) elif request.method == 'POST': if not Settings.get_cached().focus_writes: return redirect('user:account') errors = False if not validator.email(request.POST['email']): messages.error(request, 'invalid_email_address') errors = True if request.user.has_perm('sherpa') and 'sherpa-email' in request.POST and not validator.email(request.POST['sherpa-email'], req=False): messages.error(request, 'invalid_sherpa_email_address') errors = True if User.objects.filter(identifier=request.POST['email']).exclude(id=request.user.id).exists(): messages.error(request, 'duplicate_email_address') errors = True if errors: return redirect('user:update_account') if request.user.has_perm('sherpa') and 'sherpa-email' in request.POST: user = request.user user.sherpa_email = request.POST['sherpa-email'] user.save() if 'phone_mobile' in request.POST: request.user.phone_mobile = request.POST['phone_mobile'] if all([key in request.POST for key in ['b_day', 'b_month', 'b_year']]): try: request.user.birth_date = datetime.strptime( "%s-%s-%s" % (request.POST['b_year'], request.POST['b_month'], request.POST['b_day']), "%Y-%m-%d", ).date() except ValueError: request.user.birth_date = None request.user.identifier = request.POST['email'] request.user.email = request.POST['email'] request.user.save() messages.info(request, 'update_success') return redirect('user:account') else: if request.method == 'GET': context = { 'address_field_max_length': ADDRESS_FIELD_MAX_LENGTH, 'settings': Settings.get_cached(), } return render(request, 'common/user/account/update_account.html', context) elif request.method == 'POST': errors = False if not validator.email(request.POST['email']): messages.error(request, 'invalid_email_address') errors = True if request.user.has_perm('sherpa') and 'sherpa-email' in request.POST and not validator.email(request.POST['sherpa-email'], req=False): messages.error(request, 'invalid_sherpa_email_address') errors = True if not validator.phone(request.POST['phone_home'], req=False): messages.error(request, 'invalid_phone_home') errors = True if not validator.phone(request.POST['phone_mobile'], req=False): messages.error(request, 'invalid_phone_mobile') errors = True if request.user.address.country.code == 'NO' and not request.user.is_related_member(): if not validator.address(request.POST['address']): messages.error(request, 'invalid_address') errors = True if len(request.POST['address']) >= ADDRESS_FIELD_MAX_LENGTH: messages.error(request, 'too_long_address') errors = True try: zipcode = Zipcode.get_by_zipcode(zipcode=request.POST['zipcode']) except Zipcode.DoesNotExist: messages.error(request, 'invalid_zipcode') errors = True if errors: return redirect('user:update_account') if request.user.has_perm('sherpa') and 'sherpa-email' in request.POST: user = request.user user.sherpa_email = request.POST['sherpa-email'] user.save() attributes = { 'email': request.POST['email'], 'phone_home': request.POST['phone_home'], 'phone_mobile': request.POST['phone_mobile'] } address_attributes = None if request.user.address.country.code == 'NO' and not request.user.is_related_member(): address_attributes = {} address_attributes['a1'] = request.POST['address'] if 'address2' in request.POST: address_attributes['a2'] = request.POST['address2'] if 'address3' in request.POST: address_attributes['a3'] = request.POST['address3'] address_attributes['zipcode_id'] = zipcode.zipcode address_attributes['area'] = zipcode.area request.user.set_contact_info(attributes, address_attributes, update_changedby=True) messages.info(request, 'update_success') return redirect('user:account')
def update_account(request): if not request.user.is_member(): if request.method == 'GET': context = { 'user_password_length': settings.USER_PASSWORD_LENGTH } return render(request, 'common/user/account/update_account_nonmember.html', context) elif request.method == 'POST': errors = False if not validator.email(request.POST['email']): messages.error(request, 'invalid_email_address') errors = True if request.user.has_perm('sherpa') and 'sherpa-email' in request.POST and not validator.email(request.POST['sherpa-email'], req=False): messages.error(request, 'invalid_sherpa_email_address') errors = True if User.objects.filter(identifier=request.POST['email']).exclude(id=request.user.id).exists(): messages.error(request, 'duplicate_email_address') errors = True if errors: return redirect('user.views.update_account') if request.user.has_perm('sherpa') and 'sherpa-email' in request.POST: user = request.user user.sherpa_email = request.POST['sherpa-email'] user.save() request.user.identifier = request.POST['email'] request.user.email = request.POST['email'] request.user.save() messages.info(request, 'update_success') return redirect('user.views.account') else: if request.method == 'GET': context = { 'address_field_max_length': ADDRESS_FIELD_MAX_LENGTH } return render(request, 'common/user/account/update_account.html', context) elif request.method == 'POST': errors = False if not validator.email(request.POST['email']): messages.error(request, 'invalid_email_address') errors = True if request.user.has_perm('sherpa') and 'sherpa-email' in request.POST and not validator.email(request.POST['sherpa-email'], req=False): messages.error(request, 'invalid_sherpa_email_address') errors = True if not validator.phone(request.POST['phone_home'], req=False): messages.error(request, 'invalid_phone_home') errors = True if not validator.phone(request.POST['phone_mobile'], req=False): messages.error(request, 'invalid_phone_mobile') errors = True if request.user.get_address().country.code == 'NO' and not request.user.is_household_member(): if not validator.address(request.POST['address']): messages.error(request, 'invalid_address') errors = True if len(request.POST['address']) >= ADDRESS_FIELD_MAX_LENGTH: messages.error(request, 'too_long_address') errors = True try: zipcode = Zipcode.objects.get(zipcode=request.POST['zipcode']) except Zipcode.DoesNotExist: messages.error(request, 'invalid_zipcode') errors = True if errors: return redirect('user.views.update_account') if request.user.has_perm('sherpa') and 'sherpa-email' in request.POST: user = request.user user.sherpa_email = request.POST['sherpa-email'] user.save() attributes = { 'email': request.POST['email'], 'phone_home': request.POST['phone_home'], 'phone_mobile': request.POST['phone_mobile'] } address_attributes = None if request.user.get_address().country.code == 'NO' and not request.user.is_household_member(): address_attributes = {} address_attributes['a1'] = request.POST['address'] if 'address2' in request.POST: address_attributes['a2'] = request.POST['address2'] if 'address3' in request.POST: address_attributes['a3'] = request.POST['address3'] address_attributes['zipcode'] = zipcode.zipcode address_attributes['area'] = zipcode.area request.user.update_personal_data(attributes, address_attributes, update_changedby=True) messages.info(request, 'update_success') return redirect('user.views.account')
def send_restore_password_email(request): if not 'email' in request.POST: raise PermissionDenied if not validator.email(request.POST['email']): return HttpResponse(json.dumps({'status': 'invalid_email'})) # The address might match one non-member, check it: local_matches = list(User.objects.filter(memberid__isnull=True, email=request.POST['email'])) # The address might match several members, registered or not focus_unregistered_matches = False # Search through matching Actors for actor in Actor.get_personal_members().filter(email=request.POST['email']): try: # Ok, look for any matching active user user = User.get_users( include_pending=True, include_expired=True ).get( memberid=actor.memberid, is_inactive=False # ignore inactive users; these need to register first ) # Reset state if this user was previously pending but is now a proper member if user.is_pending: user.is_pending = False user.save() # Reset state if this user was previously marked as expired for some reason if user.is_expired: user.is_expired = False user.save() local_matches.append(user) except User.DoesNotExist: # There is an actor but no corresponding user - inform the user that they need to register focus_unregistered_matches = True # Now search through matching active enrollments for enrollment in get_enrollment_email_matches(request.POST['email']): try: # Ok, look for any matching active AND pending user user = User.get_users( include_pending=True, include_expired=True ).get( memberid=enrollment.memberid, is_pending=True, is_inactive=False # ignore inactive users; these need to register first ) # Reset state if this user was previously marked as expired for some reason if user.is_expired: user.is_expired = False user.save() # Check that the user isn't already matched as an Actor since this theoretically could be a duplicate if user not in local_matches: local_matches.append(user) except User.DoesNotExist: pass # Check for matching old user system members - we'll generate a password so that they can login and be imported all_sherpa2_matches = Member.objects.filter(email=request.POST['email']) # Include expired users when excluding sherpa2 matches - if their current user object is expired, # it's irrelevant whether or not the old user account matches sherpa2_matches = [m for m in all_sherpa2_matches if not User.objects.filter(memberid=m.memberid, is_inactive=False).exists()] if len(local_matches) == 0 and len(sherpa2_matches) == 0: # No email-address matches. if focus_unregistered_matches: # Oh, the email address exists in Focus, but the user(s) aren't in our user-base. Let them know. return HttpResponse(json.dumps({'status': 'unregistered_email'})) else: return HttpResponse(json.dumps({'status': 'unknown_email'})) if len(sherpa2_matches) > 0: for member in sherpa2_matches: sha1 = hashlib.sha1() new_password = crypto.get_random_string(length=10) sha1.update(new_password) member.password = sha1.hexdigest() member.save() t = loader.get_template('common/user/login/restore-password-email-sherpa25.txt') c = RequestContext(request, { 'member': member, 'new_password': new_password }) send_mail("Nytt passord på Min side", t.render(c), settings.DEFAULT_FROM_EMAIL, [request.POST['email']]) if len(local_matches) > 0: for user in local_matches: key = crypto.get_random_string(length=settings.RESTORE_PASSWORD_KEY_LENGTH) while User.objects.filter(password_restore_key=key).exists(): # Ensure that the key isn't already in use. With the current key length of 40, we'll have # ~238 bits of entropy which means that this will never ever happen, ever. # You will win the lottery before this happens. And I want to know if it does, so log it. logger.warning(u"Noen fikk en random-generert password-restore-key som allerede finnes!", extra={ 'request': request, 'should_you_play_the_lottery': True, 'key': key } ) key = crypto.get_random_string(length=settings.RESTORE_PASSWORD_KEY_LENGTH) user.password_restore_key = key user.password_restore_date = datetime.now() user.save() if len(local_matches) == 1: t = loader.get_template('common/user/login/restore-password-email.txt') c = RequestContext(request, { 'found_user': user, 'validity_period': settings.RESTORE_PASSWORD_VALIDITY }) else: t = loader.get_template('common/user/login/restore-password-email-multiple.txt') c = RequestContext(request, { 'users': local_matches, 'validity_period': settings.RESTORE_PASSWORD_VALIDITY }) send_mail("Nytt passord på Min side", t.render(c), settings.DEFAULT_FROM_EMAIL, [request.POST['email']]) return HttpResponse(json.dumps({'status': 'success'}))
def has_confirmation_info(self): """ Returns True if this user has the contact information required for confirming their family membership. Focus supports only email, not SMS, so the email address is required. """ return validator.email(self.email, req=True)