コード例 #1
0
ファイル: models.py プロジェクト: Turistforeningen/sherpa
    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
コード例 #2
0
    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
コード例 #3
0
ファイル: util.py プロジェクト: Turistforeningen/sherpa
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
コード例 #4
0
ファイル: util.py プロジェクト: Turistforeningen/sherpa
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'
コード例 #5
0
ファイル: models.py プロジェクト: Turistforeningen/sherpa
    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
コード例 #6
0
ファイル: util.py プロジェクト: simensma/sherpa
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
コード例 #7
0
ファイル: views.py プロジェクト: simensma/sherpa
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,
            }]
        }))
コード例 #8
0
ファイル: views.py プロジェクト: Turistforeningen/sherpa
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'}))
コード例 #9
0
ファイル: views.py プロジェクト: Turistforeningen/sherpa
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')
コード例 #10
0
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')
コード例 #11
0
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')
コード例 #12
0
ファイル: views.py プロジェクト: simensma/sherpa
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')
コード例 #13
0
ファイル: views.py プロジェクト: simensma/sherpa
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'}))
コード例 #14
0
 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)