Skip to content
Snippets Groups Projects
views.py 51.9 KiB
Newer Older
    name = qdict.get('name', '%s Test' % username)
    # if they already are a user, log in
    try:
        user = User.objects.get(username=username)
Diana Huang's avatar
Diana Huang committed
        user = authenticate(username=username, password=password, request=request)
        login(request, user)

    # else create and activate account info
    except ObjectDoesNotExist:
        post_override = get_dummy_post_data(username, password, email, name)
        create_account(request, post_override=post_override)
        request.user.is_active = True
        request.user.save()

    # return empty success
    return HttpResponse('')
Piotr Mitros's avatar
Piotr Mitros committed
def activate_account(request, key):
    """When link in activation e-mail is clicked"""
    r = Registration.objects.filter(activation_key=key)
    if len(r) == 1:
        user_logged_in = request.user.is_authenticated()
        already_active = True
        if not r[0].user.is_active:
            r[0].activate()
        # Enroll student in any pending courses he/she may have if auto_enroll flag is set
        student = User.objects.filter(id=r[0].user_id)
        if student:
            ceas = CourseEnrollmentAllowed.objects.filter(email=student[0].email)
            for cea in ceas:
                if cea.auto_enroll:
                    CourseEnrollment.enroll(student[0], cea.course_id)

        resp = render_to_response(
            "registration/activation_complete.html",
            {
                'user_logged_in': user_logged_in,
                'already_active': already_active
            }
        )
    if len(r) == 0:
        return render_to_response(
            "registration/activation_invalid.html",
            {'csrf': csrf(request)['csrf_token']}
        )
David Baumgold's avatar
David Baumgold committed
    return HttpResponse(_("Unknown error. Please e-mail us to let us know how it happened."))
Piotr Mitros's avatar
Piotr Mitros committed

Piotr Mitros's avatar
Piotr Mitros committed
def password_reset(request):
    """ Attempts to send a password reset e-mail. """
Piotr Mitros's avatar
Piotr Mitros committed
    if request.method != "POST":
        raise Http404
    form = PasswordResetFormNoActive(request.POST)
Piotr Mitros's avatar
Piotr Mitros committed
    if form.is_valid():
Calen Pennington's avatar
Calen Pennington committed
        form.save(use_https=request.is_secure(),
                  from_email=settings.DEFAULT_FROM_EMAIL,
                  request=request,
                  domain_override=request.get_host())
    return HttpResponse(json.dumps({'success': True,
                                        'value': render_to_string('registration/password_reset_done.html', {})}))
David Baumgold's avatar
David Baumgold committed

def password_reset_confirm_wrapper(
    request,
    uidb36=None,
    token=None,
):
    """ A wrapper around django.contrib.auth.views.password_reset_confirm.
        Needed because we want to set the user as active at this step.
    # cribbed from django.contrib.auth.views.password_reset_confirm
    try:
        uid_int = base36_to_int(uidb36)
        user = User.objects.get(id=uid_int)
        user.is_active = True
        user.save()
    except (ValueError, User.DoesNotExist):
        pass
    # we also want to pass settings.PLATFORM_NAME in as extra_context

    extra_context = {"platform_name": settings.PLATFORM_NAME}
    return password_reset_confirm(
        request, uidb36=uidb36, token=token, extra_context=extra_context
    )
Calen Pennington's avatar
Calen Pennington committed

def reactivation_email_for_user(user):
    try:
        reg = Registration.objects.get(user=user)
    except Registration.DoesNotExist:
        return HttpResponse(json.dumps({'success': False,
David Baumgold's avatar
David Baumgold committed
                                        'error': _('No inactive user with this e-mail exists')}))
    d = {'name': user.profile.name,
         'key': reg.activation_key}
    subject = render_to_string('emails/activation_email_subject.txt', d)
    subject = ''.join(subject.splitlines())
    message = render_to_string('emails/activation_email.txt', d)
        _res = user.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)
    except:
        log.warning('Unable to send reactivation email', exc_info=True)
David Baumgold's avatar
David Baumgold committed
        return HttpResponse(json.dumps({'success': False, 'error': _('Unable to send reactivation email')}))
    return HttpResponse(json.dumps({'success': True}))

@ensure_csrf_cookie
def change_email_request(request):
    """ AJAX call from the profile page. User wants a new e-mail.
    """
    ## Make sure it checks for existing e-mail conflicts
    if not request.user.is_authenticated:
        raise Http404
    user = request.user

    if not user.check_password(request.POST['password']):
        return HttpResponse(json.dumps({'success': False,
David Baumgold's avatar
David Baumgold committed
                                        'error': _('Invalid password')}))
    new_email = request.POST['new_email']
    try:
        validate_email(new_email)
    except ValidationError:
        return HttpResponse(json.dumps({'success': False,
David Baumgold's avatar
David Baumgold committed
                                        'error': _('Valid e-mail address required.')}))
    if User.objects.filter(email=new_email).count() != 0:
        ## CRITICAL TODO: Handle case sensitivity for e-mails
        return HttpResponse(json.dumps({'success': False,
David Baumgold's avatar
David Baumgold committed
                                        'error': _('An account with this e-mail already exists.')}))
    pec_list = PendingEmailChange.objects.filter(user=request.user)
Matthew Mongeau's avatar
Matthew Mongeau committed
    if len(pec_list) == 0:
        pec = PendingEmailChange()
        pec.user = user
        pec = pec_list[0]

    pec.new_email = request.POST['new_email']
    pec.activation_key = uuid.uuid4().hex
    pec.save()

Matthew Mongeau's avatar
Matthew Mongeau committed
    if pec.new_email == user.email:
        pec.delete()
        return HttpResponse(json.dumps({'success': False,
David Baumgold's avatar
David Baumgold committed
                                        'error': _('Old email is the same as the new email.')}))
    d = {'key': pec.activation_key,
         'old_email': user.email,
         'new_email': pec.new_email}
    subject = render_to_string('emails/email_change_subject.txt', d)
    subject = ''.join(subject.splitlines())
    message = render_to_string('emails/email_change.txt', d)

    _res = send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [pec.new_email])
    return HttpResponse(json.dumps({'success': True}))

@ensure_csrf_cookie
def confirm_email_change(request, key):
    """ User requested a new e-mail. This is called when the activation
    link is clicked. We confirm with the old e-mail, and update
        try:
            pec = PendingEmailChange.objects.get(activation_key=key)
        except PendingEmailChange.DoesNotExist:
            response = render_to_response("invalid_email_key.html", {})

        user = pec.user
        address_context = {
            'old_email': user.email,
            'new_email': pec.new_email
        }
        if len(User.objects.filter(email=pec.new_email)) != 0:
            response = render_to_response("email_exists.html", {})

        subject = render_to_string('emails/email_change_subject.txt', address_context)
        subject = ''.join(subject.splitlines())
        message = render_to_string('emails/confirm_email_change.txt', address_context)
        up = UserProfile.objects.get(user=user)
        meta = up.get_meta()
        if 'old_emails' not in meta:
            meta['old_emails'] = []
        meta['old_emails'].append([user.email, datetime.datetime.now(UTC).isoformat()])
        up.set_meta(meta)
        up.save()
        # Send it to the old email...
        try:
            user.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)
        except Exception:
            log.warning('Unable to send confirmation email to old address', exc_info=True)
            response = render_to_response("email_change_failed.html", {'email': user.email})
            transaction.rollback()
            return response
        user.email = pec.new_email
        user.save()
        pec.delete()
        # And send it to the new email...
        try:
            user.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)
        except Exception:
            log.warning('Unable to send confirmation email to new address', exc_info=True)
            response = render_to_response("email_change_failed.html", {'email': pec.new_email})
            transaction.rollback()
            return response
        response = render_to_response("email_change_successful.html", address_context)
    except Exception:
        # If we get an unexpected exception, be sure to rollback the transaction
        transaction.rollback()
        raise
@ensure_csrf_cookie
def change_name_request(request):
    """ Log a request for a new name. """
    if not request.user.is_authenticated:
        raise Http404
        pnc = PendingNameChange.objects.get(user=request.user)
    except PendingNameChange.DoesNotExist:
        pnc = PendingNameChange()
    pnc.user = request.user
    pnc.new_name = request.POST['new_name']
    pnc.rationale = request.POST['rationale']
    if len(pnc.new_name) < 2:
David Baumgold's avatar
David Baumgold committed
        return HttpResponse(json.dumps({'success': False, 'error': _('Name required')}))
    pnc.save()

    # The following automatically accepts name change requests. Remove this to
    # go back to the old system where it gets queued up for admin approval.
    accept_name_change_by_id(pnc.id)

    return HttpResponse(json.dumps({'success': True}))
@ensure_csrf_cookie
def pending_name_changes(request):
    """ Web page which allows staff to approve or reject name changes. """
    if not request.user.is_staff:
        raise Http404

    changes = list(PendingNameChange.objects.all())
    js = {'students': [{'new_name': c.new_name,
Calen Pennington's avatar
Calen Pennington committed
                        'rationale': c.rationale,
                        'old_name': UserProfile.objects.get(user=c.user).name,
                        'email': c.user.email,
                        'uid': c.user.id,
                        'cid': c.id} for c in changes]}
Matthew Mongeau's avatar
Matthew Mongeau committed
    return render_to_response('name_changes.html', js)
@ensure_csrf_cookie
def reject_name_change(request):
    """ JSON: Name change process. Course staff clicks 'reject' on a given name change """
    if not request.user.is_staff:
        raise Http404

Matthew Mongeau's avatar
Matthew Mongeau committed
    try:
        pnc = PendingNameChange.objects.get(id=int(request.POST['id']))
Matthew Mongeau's avatar
Matthew Mongeau committed
    except PendingNameChange.DoesNotExist:
David Baumgold's avatar
David Baumgold committed
        return HttpResponse(json.dumps({'success': False, 'error': _('Invalid ID')}))
    pnc.delete()
    return HttpResponse(json.dumps({'success': True}))

def accept_name_change_by_id(id):
Matthew Mongeau's avatar
Matthew Mongeau committed
    try:
        pnc = PendingNameChange.objects.get(id=id)
Matthew Mongeau's avatar
Matthew Mongeau committed
    except PendingNameChange.DoesNotExist:
David Baumgold's avatar
David Baumgold committed
        return HttpResponse(json.dumps({'success': False, 'error': _('Invalid ID')}))

    u = pnc.user
    up = UserProfile.objects.get(user=u)

    # Save old name
    meta = up.get_meta()
    if 'old_names' not in meta:
        meta['old_names'] = []
    meta['old_names'].append([up.name, pnc.rationale, datetime.datetime.now(UTC).isoformat()])
    up.set_meta(meta)

    up.name = pnc.new_name
    up.save()
    pnc.delete()

    return HttpResponse(json.dumps({'success': True}))


@ensure_csrf_cookie
def accept_name_change(request):
    """ JSON: Name change process. Course staff clicks 'accept' on a given name change
    We used this during the prototype but now we simply record name changes instead
    of manually approving them. Still keeping this around in case we want to go
    back to this approval method.
    if not request.user.is_staff:
        raise Http404

    return accept_name_change_by_id(int(request.POST['id']))
@require_POST
@login_required
@ensure_csrf_cookie
def change_email_settings(request):
    """Modify logged-in user's setting for receiving emails from a course."""
    user = request.user

    course_id = request.POST.get("course_id")
    receive_emails = request.POST.get("receive_emails")
    if receive_emails:
        optout_object = Optout.objects.filter(user=user, course_id=course_id)
        if optout_object:
            optout_object.delete()
        log.info(u"User {0} ({1}) opted in to receive emails from course {2}".format(user.username, user.email, course_id))
        track.views.server_track(request, "change-email-settings", {"receive_emails": "yes", "course": course_id}, page='dashboard')
    else:
        Optout.objects.get_or_create(user=user, course_id=course_id)
        log.info(u"User {0} ({1}) opted out of receiving emails from course {2}".format(user.username, user.email, course_id))
        track.views.server_track(request, "change-email-settings", {"receive_emails": "no", "course": course_id}, page='dashboard')

    return HttpResponse(json.dumps({'success': True}))