本文整理汇总了Python中util.bad_request_rate_limiter.BadRequestRateLimiter类的典型用法代码示例。如果您正苦于以下问题:Python BadRequestRateLimiter类的具体用法?Python BadRequestRateLimiter怎么用?Python BadRequestRateLimiter使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了BadRequestRateLimiter类的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: register_code_redemption
def register_code_redemption(request, registration_code):
"""
This view allows the student to redeem the registration code
and enroll in the course.
"""
# Add some rate limiting here by re-using the RateLimitMixin as a helper class
site_name = microsite.get_value('SITE_NAME', settings.SITE_NAME)
limiter = BadRequestRateLimiter()
if limiter.is_rate_limit_exceeded(request):
AUDIT_LOG.warning("Rate limit exceeded in registration code redemption.")
return HttpResponseForbidden()
template_to_render = 'shoppingcart/registration_code_receipt.html'
if request.method == "GET":
reg_code_is_valid, reg_code_already_redeemed, course_registration = get_reg_code_validity(registration_code,
request, limiter)
course = get_course_by_id(getattr(course_registration, 'course_id'), depth=0)
context = {
'reg_code_already_redeemed': reg_code_already_redeemed,
'reg_code_is_valid': reg_code_is_valid,
'reg_code': registration_code,
'site_name': site_name,
'course': course,
'registered_for_course': registered_for_course(course, request.user)
}
return render_to_response(template_to_render, context)
elif request.method == "POST":
reg_code_is_valid, reg_code_already_redeemed, course_registration = get_reg_code_validity(registration_code,
request, limiter)
course = get_course_by_id(getattr(course_registration, 'course_id'), depth=0)
if reg_code_is_valid and not reg_code_already_redeemed:
#now redeem the reg code.
RegistrationCodeRedemption.create_invoice_generated_registration_redemption(course_registration, request.user)
CourseEnrollment.enroll(request.user, course.id)
context = {
'redemption_success': True,
'reg_code': registration_code,
'site_name': site_name,
'course': course,
}
else:
context = {
'reg_code_is_valid': reg_code_is_valid,
'reg_code_already_redeemed': reg_code_already_redeemed,
'redemption_success': False,
'reg_code': registration_code,
'site_name': site_name,
'course': course,
}
return render_to_response(template_to_render, context)
示例2: password_change_request_handler
def password_change_request_handler(request):
"""Handle password change requests originating from the account page.
Uses the Account API to email the user a link to the password reset page.
Note:
The next step in the password reset process (confirmation) is currently handled
by student.views.password_reset_confirm_wrapper, a custom wrapper around Django's
password reset confirmation view.
Args:
request (HttpRequest)
Returns:
HttpResponse: 200 if the email was sent successfully
HttpResponse: 400 if there is no 'email' POST parameter
HttpResponse: 403 if the client has been rate limited
HttpResponse: 405 if using an unsupported HTTP method
Example usage:
POST /account/password
"""
limiter = BadRequestRateLimiter()
if limiter.is_rate_limit_exceeded(request):
AUDIT_LOG.warning("Password reset rate limit exceeded")
return HttpResponseForbidden()
user = request.user
# Prefer logged-in user's email
email = user.email if user.is_authenticated() else request.POST.get('email')
if email:
try:
request_password_change(email, request.is_secure())
user = user if user.is_authenticated() else User.objects.get(email=email)
destroy_oauth_tokens(user)
except UserNotFound:
AUDIT_LOG.info("Invalid password reset attempt")
# Increment the rate limit counter
limiter.tick_bad_request_counter(request)
except UserAPIInternalError as err:
log.exception('Error occured during password change for user {email}: {error}'
.format(email=email, error=err))
return HttpResponse(_("Some error occured during password change. Please try again"), status=500)
return HttpResponse(status=200)
else:
return HttpResponseBadRequest(_("No email address provided."))
示例3: password_change_request_handler
def password_change_request_handler(request):
"""Handle password change requests originating from the account page.
Uses the Account API to email the user a link to the password reset page.
Note:
The next step in the password reset process (confirmation) is currently handled
by student.views.password_reset_confirm_wrapper, a custom wrapper around Django's
password reset confirmation view.
Args:
request (HttpRequest)
Returns:
HttpResponse: 200 if the email was sent successfully
HttpResponse: 400 if there is no 'email' POST parameter, or if no user with
the provided email exists
HttpResponse: 403 if the client has been rate limited
HttpResponse: 405 if using an unsupported HTTP method
Example usage:
POST /account/password
"""
limiter = BadRequestRateLimiter()
if limiter.is_rate_limit_exceeded(request):
AUDIT_LOG.warning("Password reset rate limit exceeded")
return HttpResponseForbidden()
user = request.user
# Prefer logged-in user's email
email = user.email if user.is_authenticated() else request.POST.get('email')
if email:
try:
request_password_change(email, request.get_host(), request.is_secure())
except UserNotFound:
AUDIT_LOG.info("Invalid password reset attempt")
# Increment the rate limit counter
limiter.tick_bad_request_counter(request)
return HttpResponseBadRequest(_("No user with the provided email address exists."))
return HttpResponse(status=200)
else:
return HttpResponseBadRequest(_("No email address provided."))
示例4: password_reset
def password_reset(request):
"""
Attempts to send a password reset e-mail.
"""
# Add some rate limiting here by re-using the RateLimitMixin as a helper class
limiter = BadRequestRateLimiter()
if limiter.is_rate_limit_exceeded(request):
AUDIT_LOG.warning("Rate limit exceeded in password_reset")
return HttpResponseForbidden()
form = PasswordResetFormNoActive(request.POST)
if form.is_valid():
form.save(use_https=request.is_secure(),
from_email=configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL),
request=request)
# When password change is complete, a "edx.user.settings.changed" event will be emitted.
# But because changing the password is multi-step, we also emit an event here so that we can
# track where the request was initiated.
tracker.emit(
SETTING_CHANGE_INITIATED,
{
"setting": "password",
"old": None,
"new": None,
"user_id": request.user.id,
}
)
destroy_oauth_tokens(request.user)
else:
# bad user? tick the rate limiter counter
AUDIT_LOG.info("Bad password_reset user passed in.")
limiter.tick_bad_request_counter(request)
return JsonResponse({
'success': True,
'value': render_to_string('registration/password_reset_done.html', {}),
})
示例5: update_example_certificate
def update_example_certificate(request):
"""Callback from the XQueue that updates example certificates.
Example certificates are used to verify that certificate
generation is configured correctly for a course.
Unlike other certificates, example certificates
are not associated with a particular user or displayed
to students.
For this reason, we need a different end-point to update
the status of generated example certificates.
Arguments:
request (HttpRequest)
Returns:
HttpResponse (200): Status was updated successfully.
HttpResponse (400): Invalid parameters.
HttpResponse (403): Rate limit exceeded for bad requests.
HttpResponse (404): Invalid certificate identifier or access key.
"""
logger.info(u"Received response for example certificate from XQueue.")
rate_limiter = BadRequestRateLimiter()
# Check the parameters and rate limits
# If these are invalid, return an error response.
if rate_limiter.is_rate_limit_exceeded(request):
logger.info(u"Bad request rate limit exceeded for update example certificate end-point.")
return HttpResponseForbidden("Rate limit exceeded")
if 'xqueue_body' not in request.POST:
logger.info(u"Missing parameter 'xqueue_body' for update example certificate end-point")
rate_limiter.tick_bad_request_counter(request)
return JsonResponseBadRequest("Parameter 'xqueue_body' is required.")
if 'xqueue_header' not in request.POST:
logger.info(u"Missing parameter 'xqueue_header' for update example certificate end-point")
rate_limiter.tick_bad_request_counter(request)
return JsonResponseBadRequest("Parameter 'xqueue_header' is required.")
try:
xqueue_body = json.loads(request.POST['xqueue_body'])
xqueue_header = json.loads(request.POST['xqueue_header'])
except (ValueError, TypeError):
logger.info(u"Could not decode params to example certificate end-point as JSON.")
rate_limiter.tick_bad_request_counter(request)
return JsonResponseBadRequest("Parameters must be JSON-serialized.")
# Attempt to retrieve the example certificate record
# so we can update the status.
try:
uuid = xqueue_body.get('username')
access_key = xqueue_header.get('lms_key')
cert = ExampleCertificate.objects.get(uuid=uuid, access_key=access_key)
except ExampleCertificate.DoesNotExist:
# If we are unable to retrieve the record, it means the uuid or access key
# were not valid. This most likely means that the request is NOT coming
# from the XQueue. Return a 404 and increase the bad request counter
# to protect against a DDOS attack.
logger.info(u"Could not find example certificate with uuid '%s' and access key '%s'", uuid, access_key)
rate_limiter.tick_bad_request_counter(request)
raise Http404
if 'error' in xqueue_body:
# If an error occurs, save the error message so we can fix the issue.
error_reason = xqueue_body.get('error_reason')
cert.update_status(ExampleCertificate.STATUS_ERROR, error_reason=error_reason)
logger.warning(
(
u"Error occurred during example certificate generation for uuid '%s'. "
u"The error response was '%s'."
), uuid, error_reason
)
else:
# If the certificate generated successfully, save the download URL
# so we can display the example certificate.
download_url = xqueue_body.get('url')
if download_url is None:
rate_limiter.tick_bad_request_counter(request)
logger.warning(u"No download URL provided for example certificate with uuid '%s'.", uuid)
return JsonResponseBadRequest(
"Parameter 'download_url' is required for successfully generated certificates."
)
else:
cert.update_status(ExampleCertificate.STATUS_SUCCESS, download_url=download_url)
logger.info("Successfully updated example certificate with uuid '%s'.", uuid)
# Let the XQueue know that we handled the response
return JsonResponse({'return_code': 0})
示例6: register_code_redemption
def register_code_redemption(request, registration_code):
"""
This view allows the student to redeem the registration code
and enroll in the course.
"""
# Add some rate limiting here by re-using the RateLimitMixin as a helper class
site_name = configuration_helpers.get_value('SITE_NAME', settings.SITE_NAME)
limiter = BadRequestRateLimiter()
if limiter.is_rate_limit_exceeded(request):
AUDIT_LOG.warning("Rate limit exceeded in registration code redemption.")
return HttpResponseForbidden()
template_to_render = 'shoppingcart/registration_code_redemption.html'
if request.method == "GET":
reg_code_is_valid, reg_code_already_redeemed, course_registration = get_reg_code_validity(registration_code,
request, limiter)
course = get_course_by_id(course_registration.course_id, depth=0)
# Restrict the user from enrolling based on country access rules
embargo_redirect = embargo_api.redirect_if_blocked(
course.id, user=request.user, ip_address=get_ip(request),
url=request.path
)
if embargo_redirect is not None:
return redirect(embargo_redirect)
context = {
'reg_code_already_redeemed': reg_code_already_redeemed,
'reg_code_is_valid': reg_code_is_valid,
'reg_code': registration_code,
'site_name': site_name,
'course': course,
'registered_for_course': not _is_enrollment_code_an_update(course, request.user, course_registration)
}
return render_to_response(template_to_render, context)
elif request.method == "POST":
reg_code_is_valid, reg_code_already_redeemed, course_registration = get_reg_code_validity(
registration_code,
request,
limiter
)
course = get_course_by_id(course_registration.course_id, depth=0)
# Restrict the user from enrolling based on country access rules
embargo_redirect = embargo_api.redirect_if_blocked(
course.id, user=request.user, ip_address=get_ip(request),
url=request.path
)
if embargo_redirect is not None:
return redirect(embargo_redirect)
context = {
'reg_code': registration_code,
'site_name': site_name,
'course': course,
'reg_code_is_valid': reg_code_is_valid,
'reg_code_already_redeemed': reg_code_already_redeemed,
}
if reg_code_is_valid and not reg_code_already_redeemed:
# remove the course from the cart if it was added there.
cart = Order.get_cart_for_user(request.user)
try:
cart_items = cart.find_item_by_course_id(course_registration.course_id)
except ItemNotFoundInCartException:
pass
else:
for cart_item in cart_items:
if isinstance(cart_item, PaidCourseRegistration) or isinstance(cart_item, CourseRegCodeItem):
# Reload the item directly to prevent select_subclasses() hackery from interfering with
# deletion of all objects in the model inheritance hierarchy
cart_item = cart_item.__class__.objects.get(id=cart_item.id)
cart_item.delete()
#now redeem the reg code.
redemption = RegistrationCodeRedemption.create_invoice_generated_registration_redemption(course_registration, request.user)
try:
kwargs = {}
if course_registration.mode_slug is not None:
if CourseMode.mode_for_course(course.id, course_registration.mode_slug):
kwargs['mode'] = course_registration.mode_slug
else:
raise RedemptionCodeError()
redemption.course_enrollment = CourseEnrollment.enroll(request.user, course.id, **kwargs)
redemption.save()
context['redemption_success'] = True
except RedemptionCodeError:
context['redeem_code_error'] = True
context['redemption_success'] = False
except EnrollmentClosedError:
context['enrollment_closed'] = True
context['redemption_success'] = False
except CourseFullError:
context['course_full'] = True
context['redemption_success'] = False
except AlreadyEnrolledError:
context['registered_for_course'] = True
context['redemption_success'] = False
else:
#.........这里部分代码省略.........
示例7: password_change_request_handler
def password_change_request_handler(request):
"""Handle password change requests originating from the account page.
Uses the Account API to email the user a link to the password reset page.
Note:
The next step in the password reset process (confirmation) is currently handled
by student.views.password_reset_confirm_wrapper, a custom wrapper around Django's
password reset confirmation view.
Args:
request (HttpRequest)
Returns:
HttpResponse: 200 if the email was sent successfully
HttpResponse: 400 if there is no 'email' POST parameter
HttpResponse: 403 if the client has been rate limited
HttpResponse: 405 if using an unsupported HTTP method
Example usage:
POST /account/password
"""
limiter = BadRequestRateLimiter()
if limiter.is_rate_limit_exceeded(request):
AUDIT_LOG.warning("Password reset rate limit exceeded")
return HttpResponseForbidden()
user = request.user
# Prefer logged-in user's email
email = user.email if user.is_authenticated else request.POST.get('email')
if email:
try:
request_password_change(email, request.is_secure())
user = user if user.is_authenticated else User.objects.get(email=email)
destroy_oauth_tokens(user)
except UserNotFound:
AUDIT_LOG.info("Invalid password reset attempt")
# Increment the rate limit counter
limiter.tick_bad_request_counter(request)
# If enabled, send an email saying that a password reset was attempted, but that there is
# no user associated with the email
if configuration_helpers.get_value('ENABLE_PASSWORD_RESET_FAILURE_EMAIL',
settings.FEATURES['ENABLE_PASSWORD_RESET_FAILURE_EMAIL']):
site = get_current_site()
message_context = get_base_template_context(site)
message_context.update({
'failed': True,
'request': request, # Used by google_analytics_tracking_pixel
'email_address': email,
})
msg = PasswordReset().personalize(
recipient=Recipient(username='', email_address=email),
language=settings.LANGUAGE_CODE,
user_context=message_context,
)
ace.send(msg)
except UserAPIInternalError as err:
log.exception('Error occured during password change for user {email}: {error}'
.format(email=email, error=err))
return HttpResponse(_("Some error occured during password change. Please try again"), status=500)
return HttpResponse(status=200)
else:
return HttpResponseBadRequest(_("No email address provided."))
示例8: post
def post(self, request):
response_data = {}
# Add some rate limiting here by re-using the RateLimitMixin as a helper class
limiter = BadRequestRateLimiter()
if limiter.is_rate_limit_exceeded(request):
response_data['message'] = _('Rate limit exceeded in api login.')
return Response(response_data, status=status.HTTP_403_FORBIDDEN)
base_uri = generate_base_uri(request)
try:
existing_user = User.objects.get(username=request.DATA['username'])
except ObjectDoesNotExist:
existing_user = None
# see if account has been locked out due to excessive login failures
if existing_user and LoginFailures.is_feature_enabled():
if LoginFailures.is_user_locked_out(existing_user):
response_status = status.HTTP_403_FORBIDDEN
response_data['message'] = _('This account has been temporarily locked due to excessive login failures. '
'Try again later.')
return Response(response_data, status=response_status)
# see if the user must reset his/her password due to any policy settings
if existing_user and PasswordHistory.should_user_reset_password_now(existing_user):
response_status = status.HTTP_403_FORBIDDEN
response_data['message'] = _(
'Your password has expired due to password policy on this account. '
'You must reset your password before you can log in again.'
)
return Response(response_data, status=response_status)
if existing_user:
user = authenticate(username=existing_user.username, password=request.DATA['password'])
if user is not None:
# successful login, clear failed login attempts counters, if applicable
if LoginFailures.is_feature_enabled():
LoginFailures.clear_lockout_counter(user)
if user.is_active:
login(request, user)
response_data['token'] = request.session.session_key
response_data['expires'] = request.session.get_expiry_age()
user_dto = UserSerializer(user)
response_data['user'] = user_dto.data
response_data['uri'] = '{}/{}'.format(base_uri, request.session.session_key)
response_status = status.HTTP_201_CREATED
# add to audit log
AUDIT_LOG.info(u"API::User logged in successfully with user-id - {0}".format(user.id))
else:
response_status = status.HTTP_403_FORBIDDEN
else:
limiter.tick_bad_request_counter(request)
# tick the failed login counters if the user exists in the database
if LoginFailures.is_feature_enabled():
LoginFailures.increment_lockout_counter(existing_user)
response_status = status.HTTP_401_UNAUTHORIZED
AUDIT_LOG.warn(u"API::User authentication failed with user-id - {0}".format(existing_user.id))
else:
AUDIT_LOG.warn(u"API::Failed login attempt with unknown email/username")
response_status = status.HTTP_404_NOT_FOUND
return Response(response_data, status=response_status)
示例9: register_code_redemption
def register_code_redemption(request, registration_code):
"""
This view allows the student to redeem the registration code
and enroll in the course.
"""
# Add some rate limiting here by re-using the RateLimitMixin as a helper class
site_name = microsite.get_value('SITE_NAME', settings.SITE_NAME)
limiter = BadRequestRateLimiter()
if limiter.is_rate_limit_exceeded(request):
AUDIT_LOG.warning("Rate limit exceeded in registration code redemption.")
return HttpResponseForbidden()
template_to_render = 'shoppingcart/registration_code_redemption.html'
if request.method == "GET":
reg_code_is_valid, reg_code_already_redeemed, course_registration = get_reg_code_validity(registration_code,
request, limiter)
course = get_course_by_id(getattr(course_registration, 'course_id'), depth=0)
context = {
'reg_code_already_redeemed': reg_code_already_redeemed,
'reg_code_is_valid': reg_code_is_valid,
'reg_code': registration_code,
'site_name': site_name,
'course': course,
'registered_for_course': registered_for_course(course, request.user)
}
return render_to_response(template_to_render, context)
elif request.method == "POST":
reg_code_is_valid, reg_code_already_redeemed, course_registration = get_reg_code_validity(registration_code,
request, limiter)
course = get_course_by_id(getattr(course_registration, 'course_id'), depth=0)
if reg_code_is_valid and not reg_code_already_redeemed:
# remove the course from the cart if it was added there.
cart = Order.get_cart_for_user(request.user)
try:
cart_items = cart.find_item_by_course_id(course_registration.course_id)
except ItemNotFoundInCartException:
pass
else:
for cart_item in cart_items:
if isinstance(cart_item, PaidCourseRegistration) or isinstance(cart_item, CourseRegCodeItem):
cart_item.delete()
#now redeem the reg code.
redemption = RegistrationCodeRedemption.create_invoice_generated_registration_redemption(course_registration, request.user)
redemption.course_enrollment = CourseEnrollment.enroll(request.user, course.id)
redemption.save()
context = {
'redemption_success': True,
'reg_code': registration_code,
'site_name': site_name,
'course': course,
}
else:
context = {
'reg_code_is_valid': reg_code_is_valid,
'reg_code_already_redeemed': reg_code_already_redeemed,
'redemption_success': False,
'reg_code': registration_code,
'site_name': site_name,
'course': course,
}
return render_to_response(template_to_render, context)
示例10: register_code_redemption
def register_code_redemption(request, registration_code):
"""
This view allows the student to redeem the registration code
and enroll in the course.
"""
# Add some rate limiting here by re-using the RateLimitMixin as a helper class
site_name = microsite.get_value("SITE_NAME", settings.SITE_NAME)
limiter = BadRequestRateLimiter()
if limiter.is_rate_limit_exceeded(request):
AUDIT_LOG.warning("Rate limit exceeded in registration code redemption.")
return HttpResponseForbidden()
template_to_render = "shoppingcart/registration_code_redemption.html"
if request.method == "GET":
reg_code_is_valid, reg_code_already_redeemed, course_registration = get_reg_code_validity(
registration_code, request, limiter
)
course = get_course_by_id(getattr(course_registration, "course_id"), depth=0)
context = {
"reg_code_already_redeemed": reg_code_already_redeemed,
"reg_code_is_valid": reg_code_is_valid,
"reg_code": registration_code,
"site_name": site_name,
"course": course,
"registered_for_course": not _is_enrollment_code_an_update(course, request.user, course_registration),
}
return render_to_response(template_to_render, context)
elif request.method == "POST":
reg_code_is_valid, reg_code_already_redeemed, course_registration = get_reg_code_validity(
registration_code, request, limiter
)
course = get_course_by_id(getattr(course_registration, "course_id"), depth=0)
context = {
"reg_code": registration_code,
"site_name": site_name,
"course": course,
"reg_code_is_valid": reg_code_is_valid,
"reg_code_already_redeemed": reg_code_already_redeemed,
}
if reg_code_is_valid and not reg_code_already_redeemed:
# remove the course from the cart if it was added there.
cart = Order.get_cart_for_user(request.user)
try:
cart_items = cart.find_item_by_course_id(course_registration.course_id)
except ItemNotFoundInCartException:
pass
else:
for cart_item in cart_items:
if isinstance(cart_item, PaidCourseRegistration) or isinstance(cart_item, CourseRegCodeItem):
cart_item.delete()
# now redeem the reg code.
redemption = RegistrationCodeRedemption.create_invoice_generated_registration_redemption(
course_registration, request.user
)
try:
kwargs = {}
if course_registration.mode_slug is not None:
if CourseMode.mode_for_course(course.id, course_registration.mode_slug):
kwargs["mode"] = course_registration.mode_slug
else:
raise RedemptionCodeError()
redemption.course_enrollment = CourseEnrollment.enroll(request.user, course.id, **kwargs)
redemption.save()
context["redemption_success"] = True
except RedemptionCodeError:
context["redeem_code_error"] = True
context["redemption_success"] = False
except EnrollmentClosedError:
context["enrollment_closed"] = True
context["redemption_success"] = False
except CourseFullError:
context["course_full"] = True
context["redemption_success"] = False
except AlreadyEnrolledError:
context["registered_for_course"] = True
context["redemption_success"] = False
else:
context["redemption_success"] = False
return render_to_response(template_to_render, context)
示例11: password_change_request_handler
def password_change_request_handler(request):
"""Handle password change requests originating from the account page.
Uses the Account API to email the user a link to the password reset page.
Note:
The next step in the password reset process (confirmation) is currently handled
by student.views.password_reset_confirm_wrapper, a custom wrapper around Django's
password reset confirmation view.
Args:
request (HttpRequest)
Returns:
HttpResponse: 200 if the email was sent successfully
HttpResponse: 400 if there is no 'email' POST parameter
HttpResponse: 403 if the client has been rate limited
HttpResponse: 405 if using an unsupported HTTP method
Example usage:
POST /account/password
"""
limiter = BadRequestRateLimiter()
if limiter.is_rate_limit_exceeded(request):
AUDIT_LOG.warning("Password reset rate limit exceeded")
return HttpResponseForbidden()
user = request.user
# Prefer logged-in user's email
email = user.email if user.is_authenticated() else request.POST.get('email')
if email:
try:
request_password_change(email, request.is_secure())
user = user if user.is_authenticated() else User.objects.get(email=email)
destroy_oauth_tokens(user)
except UserNotFound:
AUDIT_LOG.info("Invalid password reset attempt")
# Increment the rate limit counter
limiter.tick_bad_request_counter(request)
# If enabled, send an email saying that a password reset was attempted, but that there is
# no user associated with the email
if configuration_helpers.get_value('ENABLE_PASSWORD_RESET_FAILURE_EMAIL',
settings.FEATURES['ENABLE_PASSWORD_RESET_FAILURE_EMAIL']):
context = {
'failed': True,
'email_address': email,
'platform_name': configuration_helpers.get_value('platform_name', settings.PLATFORM_NAME),
}
subject = loader.render_to_string('emails/password_reset_subject.txt', context)
subject = ''.join(subject.splitlines())
message = loader.render_to_string('registration/password_reset_email.html', context)
from_email = configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL)
try:
send_mail(subject, message, from_email, [email])
except Exception: # pylint: disable=broad-except
log.exception(u'Unable to send password reset failure email notification from "%s"', from_email)
except UserAPIInternalError as err:
log.exception('Error occured during password change for user {email}: {error}'
.format(email=email, error=err))
return HttpResponse(_("Some error occured during password change. Please try again"), status=500)
return HttpResponse(status=200)
else:
return HttpResponseBadRequest(_("No email address provided."))
示例12: post
def post(self, request):
response_data = {}
# Add some rate limiting here by re-using the RateLimitMixin as a helper class
limiter = BadRequestRateLimiter()
if limiter.is_rate_limit_exceeded(request):
response_data['message'] = _('Rate limit exceeded in api login.')
return Response(response_data, status=status.HTTP_403_FORBIDDEN)
base_uri = generate_base_uri(request)
try:
existing_user = User.objects.get(username=request.DATA['username'])
except ObjectDoesNotExist:
existing_user = None
# see if account has been locked out due to excessive login failures
if existing_user and LoginFailures.is_feature_enabled():
if LoginFailures.is_user_locked_out(existing_user):
response_status = status.HTTP_403_FORBIDDEN
response_data['message'] = _('This account has been temporarily locked due to excessive login failures. '
'Try again later.')
return Response(response_data, status=response_status)
# see if the user must reset his/her password due to any policy settings
if existing_user and PasswordHistory.should_user_reset_password_now(existing_user):
response_status = status.HTTP_403_FORBIDDEN
response_data['message'] = _(
'Your password has expired due to password policy on this account. '
'You must reset your password before you can log in again.'
)
return Response(response_data, status=response_status)
if existing_user:
user = authenticate(username=existing_user.username, password=request.DATA['password'])
if user is not None:
# successful login, clear failed login attempts counters, if applicable
if LoginFailures.is_feature_enabled():
LoginFailures.clear_lockout_counter(user)
if user.is_active:
#
# Create a new session directly with the SESSION_ENGINE
# We don't call the django.contrib.auth login() method
# because it is bound with the HTTP request.
#
# Since we are a server-to-server API, we shouldn't
# be stateful with respect to the HTTP request
# and anything that might come with it, as it could
# violate our RESTfulness
#
engine = import_module(settings.SESSION_ENGINE)
new_session = engine.SessionStore()
new_session.create()
# These values are expected to be set in any new session
new_session[SESSION_KEY] = user.id
new_session[BACKEND_SESSION_KEY] = user.backend
new_session.save()
response_data['token'] = new_session.session_key
response_data['expires'] = new_session.get_expiry_age()
user_dto = UserSerializer(user)
response_data['user'] = user_dto.data
response_data['uri'] = '{}/{}'.format(base_uri, new_session.session_key)
response_status = status.HTTP_201_CREATED
# generate a CSRF tokens for any web clients that may need to
# call into the LMS via Ajax (for example Notifications)
response_data['csrftoken'] = RequestContext(request, {}).get('csrf_token')
# update the last_login fields in the auth_user table for this user
user.last_login = timezone.now()
user.save()
# add to audit log
AUDIT_LOG.info(u"API::User logged in successfully with user-id - {0}".format(user.id))
else:
response_status = status.HTTP_403_FORBIDDEN
else:
limiter.tick_bad_request_counter(request)
# tick the failed login counters if the user exists in the database
if LoginFailures.is_feature_enabled():
LoginFailures.increment_lockout_counter(existing_user)
response_status = status.HTTP_401_UNAUTHORIZED
AUDIT_LOG.warn(u"API::User authentication failed with user-id - {0}".format(existing_user.id))
else:
AUDIT_LOG.warn(u"API::Failed login attempt with unknown email/username")
response_status = status.HTTP_404_NOT_FOUND
return Response(response_data, status=response_status)