def decorator(wrapper): @functools.wraps(wrapper) def view(request): if request.method == "POST": Spoon.from_request(request, jelly, get_fields, post_fields) return wrapper(request) if sensitive is not None and getattr(settings, 'JELLYGLASS_HIDE_SENSITIVE_POST_PARAMETERS', False): view = sensitive_post_parameters(*sensitive)(view) return view
def as_view(cls, **kwargs): """ Optionally wrap the base view in django.views.decorators.debug.sensitive_post_parameters(). """ # Normalize the setting. parameters = cls.sensitive_post_parameters if isinstance(parameters, six.string_types): parameters = (parameters,) elif isinstance(parameters, collections.Iterable): parameters = tuple(parameters) elif parameters: parameters = () else: parameters = None view = super(SensitivePostParameters, cls).as_view(**kwargs) return ( debug.sensitive_post_parameters(*parameters)(view) if parameters is not None else view)
class ChangePasswordView(ModelAdminView): model = User change_password_form = AdminPasswordChangeForm change_user_password_template = None @csrf_protect_m def get(self, request, object_id): if not self.has_change_permission(request): raise PermissionDenied self.obj = self.get_object(unquote(object_id)) self.form = self.change_password_form(self.obj) return self.get_response() def get_media(self): media = super(ChangePasswordView, self).get_media() media = media + self.vendor('xadmin.form.css', 'xadmin.page.form.js') + self.form.media return media def get_context(self): context = super(ChangePasswordView, self).get_context() helper = FormHelper() helper.form_tag = False helper.include_media = False self.form.helper = helper context.update({ 'title': _('Change password: %s') % escape(unicode(self.obj)), 'form': self.form, 'has_delete_permission': False, 'has_change_permission': True, 'has_view_permission': True, 'original': self.obj, }) return context def get_response(self): return TemplateResponse(self.request, [ self.change_user_password_template or 'xadmin/auth/user/change_password.html' ], self.get_context()) @method_decorator(sensitive_post_parameters()) @csrf_protect_m def post(self, request, object_id): if not self.has_change_permission(request): raise PermissionDenied self.obj = self.get_object(unquote(object_id)) self.form = self.change_password_form(self.obj, request.POST) if self.form.is_valid(): self.form.save() self.message_user(_('Password changed successfully.'), 'success') return HttpResponseRedirect( self.model_admin_url('change', self.obj.pk)) else: return self.get_response()
def sensitive(func): return sensitive_post_parameters()(csrf_protect(never_cache(func)))
class SetExpressCheckout(TemplateView): template_name = 'shopping/paypal/cancel.html' @method_decorator(sensitive_post_parameters()) @method_decorator(csrf_protect) @method_decorator(never_cache) def post(self, request, *args, **kwargs): service = get_service_instance() payment_mean = PaymentMean.objects.get(slug='paypal') if getattr(settings, 'DEBUG', False): paypal = json.loads(payment_mean.credentials) else: try: paypal = json.loads(payment_mean.credentials) except: return HttpResponse( "Error, Could not parse PayPal parameters.") try: order = parse_order_info(request) except: messages.error(request, "Failed to parse order information") return HttpResponseRedirect(reverse('mediashop:cart')) if getattr(settings, 'UNIT_TESTING', False): signature = 'dumb_signature' else: signature = ''.join([ random.SystemRandom().choice(string.ascii_letters + string.digits) for n in range(16) ]) request.session['signature'] = signature request.session['return_url'] = service.url + reverse( 'mediashop:download', args=(order.id, )) if getattr(settings, 'UNIT_TESTING', False): return HttpResponse(json.dumps({"order_id": order.id})) line_items = {} for i in range(len(order.album_list)): album = order.album_list[i] line_items.update({ "L_PAYMENTREQUEST_0_NAME%d" % i: album.title, "L_PAYMENTREQUEST_0_DESC%d" % i: album.title, "L_PAYMENTREQUEST_0_AMT%d" % i: do_currency(album.cost, order.currency.code), "L_PAYMENTREQUEST_0_QTY%d" % i: 1, "L_PAYMENTREQUEST_0_TAXAMT%d" % i: 0, "L_PAYMENTREQUEST_0_NUMBER%d" % i: i + 1, "L_PAYMENTREQUEST_0_ITEMURL%d" % i: service.url + reverse('mediashop:music_item_detail', args=( album.artist.slug, album.slug, )), "L_PAYMENTREQUEST_0_ITEMCATEGORY%d" % i: 'Digital' }) for i in range(len(order.song_list)): song = order.song_list[i] line_items.update({ "L_PAYMENTREQUEST_0_NAME%d" % i: song.title, "L_PAYMENTREQUEST_0_DESC%d" % i: song.title, "L_PAYMENTREQUEST_0_AMT%d" % i: do_currency(song.cost, order.currency.code), "L_PAYMENTREQUEST_0_QTY%d" % i: 1, "L_PAYMENTREQUEST_0_TAXAMT%d" % i: 0, "L_PAYMENTREQUEST_0_NUMBER%d" % i: i + 1, "L_PAYMENTREQUEST_0_ITEMURL%d" % i: service.url + reverse('mediashop:music_item_detail', args=( song.artist.slug, song.slug, )), "L_PAYMENTREQUEST_0_ITEMCATEGORY%d" % i: 'Digital' }) ec_data = { "USER": paypal['username'], "PWD": paypal['password'], "SIGNATURE": paypal['signature'], "METHOD": "SetExpressCheckout", "VERSION": 124.0, "RETURNURL": service.url + reverse('mediashop:paypal_get_details') + '?order_id=' + order.id, "CANCELURL": service.url + reverse('mediashop:cart'), "PAYMENTREQUEST_0_PAYMENTACTION": "Sale", "PAYMENTREQUEST_0_AMT": do_currency(order.total_cost, order.currency.code), "PAYMENTREQUEST_0_ITEMAMT": do_currency(order.total_cost, order.currency.code), "PAYMENTREQUEST_0_SHIPPINGAMT": 0, "PAYMENTREQUEST_0_TAXAMT": 0, "PAYMENTREQUEST_0_CURRENCYCODE": order.currency.code, "PAYMENTREQUEST_0_DESC": "Purchase on " + service.project_name } ec_data.update(line_items) try: response = requests.post(EC_ENDPOINT, data=ec_data) result = parse_paypal_response(response.content.decode('utf-8')) ACK = result['ACK'] if ACK == 'Success' or ACK == 'SuccessWithWarning': if getattr(settings, 'DEBUG', False): redirect_url = 'https://www.sandbox.paypal.com/checkoutnow?token=' + result[ 'TOKEN'] else: redirect_url = 'https://www.paypal.com/checkoutnow?token=' + result[ 'TOKEN'] return HttpResponseRedirect(redirect_url) else: order.delete() context = self.get_context_data(**kwargs) if getattr(settings, 'DEBUG', False): context['paypal_error'] = urlunquote( response.content.decode('utf-8')) else: context['paypal_error'] = urlunquote( result['L_LONGMESSAGE0']) messages.error(request, 'Initiating PayPal transaction failed.') return HttpResponseRedirect(reverse('mediashop:cart')) except Exception as e: logger.error("%s - PayPal error." % service.project_name, exc_info=True) if getattr(settings, 'DEBUG', False): raise e context = self.get_context_data(**kwargs) messages.error( request, 'Could not initiate transaction due to server error. Contact administrator.' ) return render(request, 'shopping/paypal/cancel.html', context)
import qrcode import qrcode.image.svg from ..compat import import_string from ..compat import get_current_site from ..forms import (MethodForm, TOTPDeviceForm, PhoneNumberMethodForm, DeviceValidationForm, AuthenticationTokenForm, PhoneNumberForm, BackupTokenForm, YubiKeyDeviceForm) from ..models import PhoneDevice, get_available_phone_methods from ..utils import (get_otpauth_url, default_device, backup_phones) from .utils import (IdempotentSessionWizardView, class_view_decorator) @class_view_decorator(sensitive_post_parameters()) @class_view_decorator(never_cache) class LoginView(IdempotentSessionWizardView): """ View for handling the login process, including OTP verification. The login process is composed like a wizard. The first step asks for the user's credentials. If the credentials are correct, the wizard proceeds to the OTP verification step. If the user has a default OTP device configured, that device is asked to generate a token (send sms / call phone) and the user is asked to provide the generated token. The backup devices are also listed, allowing the user to select a backup device for verification. """ template_name = 'two_factor/core/login.html' form_list = ( ('auth', AuthenticationForm),
__doc__ = decorator.__doc__ @classmethod def as_view(cls, *args, **kwargs): view = super(Mixin, cls).as_view(*args, **kwargs) return decorator(view) Mixin.__name__ = str('DecoratorMixin(%s)' % decorator.__name__) return Mixin NeverCacheMixin = DecoratorMixin(never_cache) CsrfProtectMixin = DecoratorMixin(csrf_protect) LoginRequiredMixin = DecoratorMixin(login_required) SensitivePostParametersMixin = DecoratorMixin( sensitive_post_parameters('password', 'old_password', 'password1', 'password2', 'new_password1', 'new_password2') ) class AuthDecoratorsMixin(NeverCacheMixin, CsrfProtectMixin, SensitivePostParametersMixin): pass class LoginView(AuthDecoratorsMixin, WithCurrentSiteMixin, WithNextUrlMixin, FormView): form_class = AuthenticationForm template_name = 'registration/login.html' disallow_authenticated = True success_url = resolve_url_lazy(settings.LOGIN_REDIRECT_URL) def dispatch(self, *args, **kwargs): if self.disallow_authenticated and self.request.user.is_authenticated(): return redirect(self.get_success_url())
) from .utils import sync_user_email_addresses from .models import EmailAddress, EmailConfirmation from . import signals from . import app_settings from .adapter import get_adapter try: from django.contrib.auth import update_session_auth_hash except ImportError: update_session_auth_hash = None sensitive_post_parameters_m = method_decorator(sensitive_post_parameters("password", "password1", "password2")) def _ajax_response(request, response, form=None): if request.is_ajax(): if isinstance(response, HttpResponseRedirect) or isinstance(response, HttpResponsePermanentRedirect): redirect_to = response["Location"] else: redirect_to = None response = get_adapter().ajax_response(request, response, form=form, redirect_to=redirect_to) return response class RedirectAuthenticatedUserMixin(object): def dispatch(self, request, *args, **kwargs): # WORKAROUND: https://code.djangoproject.com/ticket/19316
class RegistrationView(APIView): """HTTP end-points for creating a new user. """ DEFAULT_FIELDS = ["email", "name", "username", "password"] EXTRA_FIELDS = [ "confirm_email", "first_name", "last_name", "city", "state", "country", "gender", "year_of_birth", "level_of_education", "company", "title", "mailing_address", "goals", "honor_code", "terms_of_service", ] # This end-point is available to anonymous users, # so do not require authentication. authentication_classes = [] def _is_field_visible(self, field_name): """Check whether a field is visible based on Django settings. """ return self._extra_fields_setting.get(field_name) in [ "required", "optional" ] def _is_field_required(self, field_name): """Check whether a field is required based on Django settings. """ return self._extra_fields_setting.get(field_name) == "required" def __init__(self, *args, **kwargs): super(RegistrationView, self).__init__(*args, **kwargs) # Backwards compatibility: Honor code is required by default, unless # explicitly set to "optional" in Django settings. self._extra_fields_setting = copy.deepcopy( configuration_helpers.get_value('REGISTRATION_EXTRA_FIELDS')) if not self._extra_fields_setting: self._extra_fields_setting = copy.deepcopy( settings.REGISTRATION_EXTRA_FIELDS) self._extra_fields_setting[ "honor_code"] = self._extra_fields_setting.get( "honor_code", "required") # Check that the setting is configured correctly for field_name in self.EXTRA_FIELDS: if self._extra_fields_setting.get(field_name, "hidden") not in [ "required", "optional", "hidden" ]: msg = u"Setting REGISTRATION_EXTRA_FIELDS values must be either required, optional, or hidden." raise ImproperlyConfigured(msg) # Map field names to the instance method used to add the field to the form self.field_handlers = {} valid_fields = self.DEFAULT_FIELDS + self.EXTRA_FIELDS for field_name in valid_fields: handler = getattr( self, "_add_{field_name}_field".format(field_name=field_name)) self.field_handlers[field_name] = handler field_order = configuration_helpers.get_value( 'REGISTRATION_FIELD_ORDER') if not field_order: field_order = settings.REGISTRATION_FIELD_ORDER or valid_fields # Check that all of the valid_fields are in the field order and vice versa, if not set to the default order if set(valid_fields) != set(field_order): field_order = valid_fields self.field_order = field_order @method_decorator(ensure_csrf_cookie) def get(self, request): """Return a description of the registration form. This decouples clients from the API definition: if the API decides to modify the form, clients won't need to be updated. This is especially important for the registration form, since different edx-platform installations might collect different demographic information. See `user_api.helpers.FormDescription` for examples of the JSON-encoded form description. Arguments: request (HttpRequest) Returns: HttpResponse """ form_desc = FormDescription("post", reverse("user_api_registration")) self._apply_third_party_auth_overrides(request, form_desc) # Custom form fields can be added via the form set in settings.REGISTRATION_EXTENSION_FORM custom_form = get_registration_extension_form() if custom_form: # Default fields are always required for field_name in self.DEFAULT_FIELDS: self.field_handlers[field_name](form_desc, required=True) for field_name, field in custom_form.fields.items(): restrictions = {} if getattr(field, 'max_length', None): restrictions['max_length'] = field.max_length if getattr(field, 'min_length', None): restrictions['min_length'] = field.min_length field_options = getattr(getattr(custom_form, 'Meta', None), 'serialization_options', {}).get(field_name, {}) field_type = field_options.get( 'field_type', FormDescription.FIELD_TYPE_MAP.get(field.__class__)) if not field_type: raise ImproperlyConfigured( "Field type '{}' not recognized for registration extension field '{}'." .format(field_type, field_name)) form_desc.add_field( field_name, label=field.label, default=field_options.get('default'), field_type=field_options.get( 'field_type', FormDescription.FIELD_TYPE_MAP.get(field.__class__)), placeholder=field.initial, instructions=field.help_text, required=field.required, restrictions=restrictions, options=getattr(field, 'choices', None), error_messages=field.error_messages, include_default_option=field_options.get( 'include_default_option'), ) # Extra fields configured in Django settings # may be required, optional, or hidden for field_name in self.EXTRA_FIELDS: if self._is_field_visible(field_name): self.field_handlers[field_name]( form_desc, required=self._is_field_required(field_name)) else: # Go through the fields in the fields order and add them if they are required or visible for field_name in self.field_order: if field_name in self.DEFAULT_FIELDS: self.field_handlers[field_name](form_desc, required=True) elif self._is_field_visible(field_name): self.field_handlers[field_name]( form_desc, required=self._is_field_required(field_name)) return HttpResponse(form_desc.to_json(), content_type="application/json") @method_decorator(csrf_exempt) def post(self, request): """Create the user's account. You must send all required form fields with the request. You can optionally send a "course_id" param to indicate in analytics events that the user registered while enrolling in a particular course. Arguments: request (HTTPRequest) Returns: HttpResponse: 200 on success HttpResponse: 400 if the request is not valid. HttpResponse: 409 if an account with the given username or email address already exists HttpResponse: 403 operation not allowed """ data = request.POST.copy() email = data.get('email') username = data.get('username') # Handle duplicate email/username conflicts = check_account_exists(email=email, username=username) if conflicts: conflict_messages = { "email": accounts.EMAIL_CONFLICT_MSG.format(email_address=email), "username": accounts.USERNAME_CONFLICT_MSG.format(username=username), } errors = { field: [{ "user_message": conflict_messages[field] }] for field in conflicts } return JsonResponse(errors, status=409) # Backwards compatibility: the student view expects both # terms of service and honor code values. Since we're combining # these into a single checkbox, the only value we may get # from the new view is "honor_code". # Longer term, we will need to make this more flexible to support # open source installations that may have separate checkboxes # for TOS, privacy policy, etc. if data.get("honor_code") and "terms_of_service" not in data: data["terms_of_service"] = data["honor_code"] try: user = create_account_with_params(request, data) except AccountValidationError as err: errors = {err.field: [{"user_message": err.message}]} return JsonResponse(errors, status=409) except ValidationError as err: # Should only get non-field errors from this function assert NON_FIELD_ERRORS not in err.message_dict # Only return first error for each field errors = { field: [{ "user_message": error } for error in error_list] for field, error_list in err.message_dict.items() } return JsonResponse(errors, status=400) except PermissionDenied: return HttpResponseForbidden(_("Account creation not allowed.")) response = JsonResponse({"success": True}) set_logged_in_cookies(request, response, user) return response @method_decorator(sensitive_post_parameters("password")) def dispatch(self, request, *args, **kwargs): return super(RegistrationView, self).dispatch(request, *args, **kwargs) def _add_email_field(self, form_desc, required=True): """Add an email field to a form description. Arguments: form_desc: A form description Keyword Arguments: required (bool): Whether this field is required; defaults to True """ # Translators: This label appears above a field on the registration form # meant to hold the user's email address. email_label = _(u"Email") # Translators: This example email address is used as a placeholder in # a field on the registration form meant to hold the user's email address. email_placeholder = _(u"*****@*****.**") # Translators: These instructions appear on the registration form, immediately # below a field meant to hold the user's email address. email_instructions = _(u"This is what you will use to login.") form_desc.add_field("email", field_type="email", label=email_label, placeholder=email_placeholder, instructions=email_instructions, restrictions={ "min_length": accounts.EMAIL_MIN_LENGTH, "max_length": accounts.EMAIL_MAX_LENGTH, }, required=required) def _add_confirm_email_field(self, form_desc, required=True): """Add an email confirmation field to a form description. Arguments: form_desc: A form description Keyword Arguments: required (bool): Whether this field is required; defaults to True """ # Translators: This label appears above a field on the registration form # meant to confirm the user's email address. email_label = _(u"Confirm Email") error_msg = accounts.REQUIRED_FIELD_CONFIRM_EMAIL_MSG form_desc.add_field("confirm_email", label=email_label, required=required, error_messages={"required": error_msg}) def _add_name_field(self, form_desc, required=True): """Add a name field to a form description. Arguments: form_desc: A form description Keyword Arguments: required (bool): Whether this field is required; defaults to True """ # Translators: This label appears above a field on the registration form # meant to hold the user's full name. name_label = _(u"Full Name") # Translators: This example name is used as a placeholder in # a field on the registration form meant to hold the user's name. name_placeholder = _(u"Jane Q. Learner") # Translators: These instructions appear on the registration form, immediately # below a field meant to hold the user's full name. name_instructions = _( u"This name will be used on any certificates that you earn.") form_desc.add_field("name", label=name_label, placeholder=name_placeholder, instructions=name_instructions, restrictions={ "max_length": accounts.NAME_MAX_LENGTH, }, required=required) def _add_username_field(self, form_desc, required=True): """Add a username field to a form description. Arguments: form_desc: A form description Keyword Arguments: required (bool): Whether this field is required; defaults to True """ # Translators: This label appears above a field on the registration form # meant to hold the user's public username. username_label = _(u"Public Username") username_instructions = _( # Translators: These instructions appear on the registration form, immediately # below a field meant to hold the user's public username. u"The name that will identify you in your courses. " u"It cannot be changed later.") # Translators: This example username is used as a placeholder in # a field on the registration form meant to hold the user's username. username_placeholder = _(u"Jane_Q_Learner") form_desc.add_field("username", label=username_label, instructions=username_instructions, placeholder=username_placeholder, restrictions={ "min_length": accounts.USERNAME_MIN_LENGTH, "max_length": accounts.USERNAME_MAX_LENGTH, }, required=required) def _add_password_field(self, form_desc, required=True): """Add a password field to a form description. Arguments: form_desc: A form description Keyword Arguments: required (bool): Whether this field is required; defaults to True """ # Translators: This label appears above a field on the registration form # meant to hold the user's password. password_label = _(u"Password") form_desc.add_field("password", label=password_label, field_type="password", restrictions={ "min_length": accounts.PASSWORD_MIN_LENGTH, "max_length": accounts.PASSWORD_MAX_LENGTH, }, required=required) def _add_level_of_education_field(self, form_desc, required=True): """Add a level of education field to a form description. Arguments: form_desc: A form description Keyword Arguments: required (bool): Whether this field is required; defaults to True """ # Translators: This label appears above a dropdown menu on the registration # form used to select the user's highest completed level of education. education_level_label = _(u"Highest level of education completed") error_msg = accounts.REQUIRED_FIELD_LEVEL_OF_EDUCATION_MSG # The labels are marked for translation in UserProfile model definition. options = [(name, _(label)) for name, label in UserProfile.LEVEL_OF_EDUCATION_CHOICES] # pylint: disable=translation-of-non-string form_desc.add_field("level_of_education", label=education_level_label, field_type="select", options=options, include_default_option=True, required=required, error_messages={"required": error_msg}) def _add_gender_field(self, form_desc, required=True): """Add a gender field to a form description. Arguments: form_desc: A form description Keyword Arguments: required (bool): Whether this field is required; defaults to True """ # Translators: This label appears above a dropdown menu on the registration # form used to select the user's gender. gender_label = _(u"Gender") # The labels are marked for translation in UserProfile model definition. options = [(name, _(label)) for name, label in UserProfile.GENDER_CHOICES] # pylint: disable=translation-of-non-string form_desc.add_field("gender", label=gender_label, field_type="select", options=options, include_default_option=True, required=required) def _add_year_of_birth_field(self, form_desc, required=True): """Add a year of birth field to a form description. Arguments: form_desc: A form description Keyword Arguments: required (bool): Whether this field is required; defaults to True """ # Translators: This label appears above a dropdown menu on the registration # form used to select the user's year of birth. yob_label = _(u"Year of birth") options = [(unicode(year), unicode(year)) for year in UserProfile.VALID_YEARS] form_desc.add_field("year_of_birth", label=yob_label, field_type="select", options=options, include_default_option=True, required=required) def _add_mailing_address_field(self, form_desc, required=True): """Add a mailing address field to a form description. Arguments: form_desc: A form description Keyword Arguments: required (bool): Whether this field is required; defaults to True """ # Translators: This label appears above a field on the registration form # meant to hold the user's mailing address. mailing_address_label = _(u"Mailing address") error_msg = accounts.REQUIRED_FIELD_MAILING_ADDRESS_MSG form_desc.add_field("mailing_address", label=mailing_address_label, field_type="textarea", required=required, error_messages={"required": error_msg}) def _add_goals_field(self, form_desc, required=True): """Add a goals field to a form description. Arguments: form_desc: A form description Keyword Arguments: required (bool): Whether this field is required; defaults to True """ # Translators: This phrase appears above a field on the registration form # meant to hold the user's reasons for registering with edX. goals_label = _(u"Tell us why you're interested in {platform_name}" ).format(platform_name=configuration_helpers.get_value( "PLATFORM_NAME", settings.PLATFORM_NAME)) error_msg = accounts.REQUIRED_FIELD_GOALS_MSG form_desc.add_field("goals", label=goals_label, field_type="textarea", required=required, error_messages={"required": error_msg}) def _add_city_field(self, form_desc, required=True): """Add a city field to a form description. Arguments: form_desc: A form description Keyword Arguments: required (bool): Whether this field is required; defaults to True """ # Translators: This label appears above a field on the registration form # which allows the user to input the city in which they live. city_label = _(u"City") error_msg = accounts.REQUIRED_FIELD_CITY_MSG form_desc.add_field("city", label=city_label, required=required, error_messages={"required": error_msg}) def _add_state_field(self, form_desc, required=False): """Add a State/Province/Region field to a form description. Arguments: form_desc: A form description Keyword Arguments: required (bool): Whether this field is required; defaults to False """ # Translators: This label appears above a field on the registration form # which allows the user to input the State/Province/Region in which they live. state_label = _(u"State/Province/Region") form_desc.add_field("state", label=state_label, required=required) def _add_company_field(self, form_desc, required=False): """Add a Company field to a form description. Arguments: form_desc: A form description Keyword Arguments: required (bool): Whether this field is required; defaults to False """ # Translators: This label appears above a field on the registration form # which allows the user to input the Company company_label = _(u"Company") form_desc.add_field("company", label=company_label, required=required) def _add_title_field(self, form_desc, required=False): """Add a Title field to a form description. Arguments: form_desc: A form description Keyword Arguments: required (bool): Whether this field is required; defaults to False """ # Translators: This label appears above a field on the registration form # which allows the user to input the Title title_label = _(u"Title") form_desc.add_field("title", label=title_label, required=required) def _add_first_name_field(self, form_desc, required=False): """Add a First Name field to a form description. Arguments: form_desc: A form description Keyword Arguments: required (bool): Whether this field is required; defaults to False """ # Translators: This label appears above a field on the registration form # which allows the user to input the First Name first_name_label = _(u"First Name") form_desc.add_field("first_name", label=first_name_label, required=required) def _add_last_name_field(self, form_desc, required=False): """Add a Last Name field to a form description. Arguments: form_desc: A form description Keyword Arguments: required (bool): Whether this field is required; defaults to False """ # Translators: This label appears above a field on the registration form # which allows the user to input the First Name last_name_label = _(u"Last Name") form_desc.add_field("last_name", label=last_name_label, required=required) def _add_country_field(self, form_desc, required=True): """Add a country field to a form description. Arguments: form_desc: A form description Keyword Arguments: required (bool): Whether this field is required; defaults to True """ # Translators: This label appears above a dropdown menu on the registration # form used to select the country in which the user lives. country_label = _(u"Country") error_msg = accounts.REQUIRED_FIELD_COUNTRY_MSG # If we set a country code, make sure it's uppercase for the sake of the form. default_country = form_desc._field_overrides.get( 'country', {}).get('defaultValue') if default_country: form_desc.override_field_properties( 'country', default=default_country.upper()) form_desc.add_field("country", label=country_label, field_type="select", options=list(countries), include_default_option=True, required=required, error_messages={"required": error_msg}) def _add_honor_code_field(self, form_desc, required=True): """Add an honor code field to a form description. Arguments: form_desc: A form description Keyword Arguments: required (bool): Whether this field is required; defaults to True """ # Separate terms of service and honor code checkboxes if self._is_field_visible("terms_of_service"): terms_label = _(u"Honor Code") terms_link = marketing_link("HONOR") terms_text = _(u"Review the Honor Code") # Combine terms of service and honor code checkboxes else: # Translators: This is a legal document users must agree to # in order to register a new account. terms_label = _(u"Terms of Service and Honor Code") terms_link = marketing_link("HONOR") terms_text = _(u"Review the Terms of Service and Honor Code") # Translators: "Terms of Service" is a legal document users must agree to # in order to register a new account. label = _(u"I agree to the {platform_name} {terms_of_service}").format( platform_name=configuration_helpers.get_value( "PLATFORM_NAME", settings.PLATFORM_NAME), terms_of_service=terms_label) # Translators: "Terms of Service" is a legal document users must agree to # in order to register a new account. error_msg = _( u"You must agree to the {platform_name} {terms_of_service}" ).format(platform_name=configuration_helpers.get_value( "PLATFORM_NAME", settings.PLATFORM_NAME), terms_of_service=terms_label) form_desc.add_field("honor_code", label=label, field_type="checkbox", default=False, required=required, error_messages={"required": error_msg}, supplementalLink=terms_link, supplementalText=terms_text) def _add_terms_of_service_field(self, form_desc, required=True): """Add a terms of service field to a form description. Arguments: form_desc: A form description Keyword Arguments: required (bool): Whether this field is required; defaults to True """ # Translators: This is a legal document users must agree to # in order to register a new account. terms_label = _(u"Terms of Service") terms_link = marketing_link("TOS") terms_text = _(u"Review the Terms of Service") # Translators: "Terms of service" is a legal document users must agree to # in order to register a new account. label = _(u"I agree to the {platform_name} {terms_of_service}").format( platform_name=configuration_helpers.get_value( "PLATFORM_NAME", settings.PLATFORM_NAME), terms_of_service=terms_label) # Translators: "Terms of service" is a legal document users must agree to # in order to register a new account. error_msg = _( u"You must agree to the {platform_name} {terms_of_service}" ).format(platform_name=configuration_helpers.get_value( "PLATFORM_NAME", settings.PLATFORM_NAME), terms_of_service=terms_label) form_desc.add_field("terms_of_service", label=label, field_type="checkbox", default=False, required=required, error_messages={"required": error_msg}, supplementalLink=terms_link, supplementalText=terms_text) def _apply_third_party_auth_overrides(self, request, form_desc): """Modify the registration form if the user has authenticated with a third-party provider. If a user has successfully authenticated with a third-party provider, but does not yet have an account with EdX, we want to fill in the registration form with any info that we get from the provider. This will also hide the password field, since we assign users a default (random) password on the assumption that they will be using third-party auth to log in. Arguments: request (HttpRequest): The request for the registration form, used to determine if the user has successfully authenticated with a third-party provider. form_desc (FormDescription): The registration form description """ if third_party_auth.is_enabled(): running_pipeline = third_party_auth.pipeline.get(request) if running_pipeline: current_provider = third_party_auth.provider.Registry.get_from_pipeline( running_pipeline) if current_provider: # Override username / email / full name field_overrides = current_provider.get_register_form_data( running_pipeline.get('kwargs')) # When the TPA Provider is configured to skip the registration form and we are in an # enterprise context, we need to hide all fields except for terms of service and # ensure that the user explicitly checks that field. hide_registration_fields_except_tos = ( current_provider.skip_registration_form and enterprise_customer_for_request(request)) for field_name in self.DEFAULT_FIELDS + self.EXTRA_FIELDS: if field_name in field_overrides: form_desc.override_field_properties( field_name, default=field_overrides[field_name]) if (field_name not in ['terms_of_service', 'honor_code'] and field_overrides[field_name] and hide_registration_fields_except_tos): form_desc.override_field_properties( field_name, field_type="hidden", label="", instructions="", ) # Hide the password field form_desc.override_field_properties("password", default="", field_type="hidden", required=False, label="", instructions="", restrictions={}) # used to identify that request is running third party social auth form_desc.add_field( "social_auth_provider", field_type="hidden", label="", default=current_provider.name if current_provider.name else "Third Party", required=False, )
class LoginView(SuccessURLAllowedHostsMixin, IdempotentSessionWizardView): """ View for handling the login process, including OTP verification. The login process is composed like a wizard. The first step asks for the user's credentials. If the credentials are correct, the wizard proceeds to the OTP verification step. If the user has a default OTP device configured, that device is asked to generate a token (send sms / call phone) and the user is asked to provide the generated token. The backup devices are also listed, allowing the user to select a backup device for verification. """ template_name = 'two_factor/core/login.html' form_list = ( ('auth', AuthenticationForm), ('token', AuthenticationTokenForm), ('backup', BackupTokenForm), ) idempotent_dict = { 'token': False, 'backup': False, } redirect_authenticated_user = False storage_name = 'two_factor.views.utils.LoginStorage' def has_token_step(self): return (default_device(self.get_user()) and not self.remember_agent) def has_backup_step(self): return (default_device(self.get_user()) and 'token' not in self.storage.validated_step_data and not self.remember_agent) @cached_property def expired(self): login_timeout = getattr(settings, 'TWO_FACTOR_LOGIN_TIMEOUT', 600) if login_timeout == 0: return False expiration_time = self.storage.data.get("authentication_time", 0) + login_timeout return int(time.time()) > expiration_time condition_dict = { 'token': has_token_step, 'backup': has_backup_step, } redirect_field_name = REDIRECT_FIELD_NAME def __init__(self, **kwargs): super().__init__(**kwargs) self.user_cache = None self.device_cache = None self.cookies_to_delete = [] self.show_timeout_error = False def post(self, *args, **kwargs): """ The user can select a particular device to challenge, being the backup devices added to the account. """ wizard_goto_step = self.request.POST.get('wizard_goto_step', None) if wizard_goto_step == 'auth': self.storage.reset() if self.expired and self.steps.current != 'auth': logger.info("User's authentication flow has timed out. The user " "has been redirected to the initial auth form.") self.storage.reset() self.show_timeout_error = True return self.render_goto_step('auth') # Generating a challenge doesn't require to validate the form. if 'challenge_device' in self.request.POST: return self.render_goto_step('token') response = super().post(*args, **kwargs) return self.delete_cookies_from_response(response) def done(self, form_list, **kwargs): """ Login the user and redirect to the desired page. """ # Check if remember cookie should be set after login current_step_data = self.storage.get_step_data(self.steps.current) remember = bool(current_step_data and current_step_data.get('token-remember') == 'on') login(self.request, self.get_user()) redirect_to = self.get_success_url() device = getattr(self.get_user(), 'otp_device', None) response = redirect(redirect_to) if device: signals.user_verified.send(sender=__name__, request=self.request, user=self.get_user(), device=device) # Set a remember cookie if activated if getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_AGE', None) and remember: # choose a unique cookie key to remember devices for multiple users in the same browser cookie_key = REMEMBER_COOKIE_PREFIX + str(uuid4()) cookie_value = get_remember_device_cookie( user=self.get_user(), otp_device_id=device.persistent_id) response.set_cookie( cookie_key, cookie_value, max_age=settings.TWO_FACTOR_REMEMBER_COOKIE_AGE, domain=getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_DOMAIN', None), path=getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_PATH', '/'), secure=getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_SECURE', False), httponly=getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_HTTPONLY', True), samesite=getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_SAMESITE', 'Lax'), ) return response # Copied from django.conrib.auth.views.LoginView (Branch: stable/1.11.x) # https://github.com/django/django/blob/58df8aa40fe88f753ba79e091a52f236246260b3/django/contrib/auth/views.py#L63 def get_success_url(self): url = self.get_redirect_url() return url or resolve_url(settings.LOGIN_REDIRECT_URL) # Copied from django.conrib.auth.views.LoginView (Branch: stable/1.11.x) # https://github.com/django/django/blob/58df8aa40fe88f753ba79e091a52f236246260b3/django/contrib/auth/views.py#L67 def get_redirect_url(self): """Return the user-originating redirect URL if it's safe.""" redirect_to = self.request.POST.get( self.redirect_field_name, self.request.GET.get(self.redirect_field_name, '')) url_is_safe = url_has_allowed_host_and_scheme( url=redirect_to, allowed_hosts=self.get_success_url_allowed_hosts(), require_https=self.request.is_secure(), ) return redirect_to if url_is_safe else '' def get_form_kwargs(self, step=None): """ AuthenticationTokenForm requires the user kwarg. """ if step == 'auth': return {'request': self.request} if step in ('token', 'backup'): return { 'user': self.get_user(), 'initial_device': self.get_device(step), } return {} def get_done_form_list(self): """ Return the forms that should be processed during the final step """ # Intentionally do not process the auth form on the final step. We # haven't stored this data, and it isn't required to login the user form_list = self.get_form_list() form_list.pop('auth') return form_list def process_step(self, form): """ Process an individual step in the flow """ # To prevent saving any private auth data to the session store, we # validate the authentication form, determine the resulting user, then # only store the minimum needed to login that user (the user's primary # key and the backend used) if self.steps.current == 'auth': user = form.is_valid() and form.user_cache self.storage.reset() self.storage.authenticated_user = user self.storage.data["authentication_time"] = int(time.time()) # By returning None when the user clicks the "back" button to the # auth step the form will be blank with validation warnings return None return super().process_step(form) def process_step_files(self, form): """ Process the files submitted from a specific test """ if self.steps.current == 'auth': return {} return super().process_step_files(form) def get_form(self, *args, **kwargs): """ Returns the form for the step """ form = super().get_form(*args, **kwargs) if self.show_timeout_error: form.cleaned_data = getattr(form, 'cleaned_data', {}) form.add_error( None, ValidationError( _('Your session has timed out. Please login again.'))) return form def get_device(self, step=None): """ Returns the OTP device selected by the user, or his default device. """ if not self.device_cache: challenge_device_id = self.request.POST.get( 'challenge_device', None) if challenge_device_id: for device in backup_phones(self.get_user()): if device.persistent_id == challenge_device_id: self.device_cache = device break if step == 'backup': try: self.device_cache = self.get_user().staticdevice_set.get( name='backup') except StaticDevice.DoesNotExist: pass if not self.device_cache: self.device_cache = default_device(self.get_user()) return self.device_cache def render(self, form=None, **kwargs): """ If the user selected a device, ask the device to generate a challenge; either making a phone call or sending a text message. """ if self.steps.current == 'token': self.get_device().generate_challenge() return super().render(form, **kwargs) def get_user(self): """ Returns the user authenticated by the AuthenticationForm. Returns False if not a valid user; see also issue #65. """ if not self.user_cache: self.user_cache = self.storage.authenticated_user return self.user_cache def get_context_data(self, form, **kwargs): """ Adds user's default and backup OTP devices to the context. """ context = super().get_context_data(form, **kwargs) if self.steps.current == 'token': context['device'] = self.get_device() context['other_devices'] = [ phone for phone in backup_phones(self.get_user()) if phone != self.get_device() ] try: context['backup_tokens'] = self.get_user().staticdevice_set\ .get(name='backup').token_set.count() except StaticDevice.DoesNotExist: context['backup_tokens'] = 0 if getattr(settings, 'LOGOUT_REDIRECT_URL', None): context['cancel_url'] = resolve_url(settings.LOGOUT_REDIRECT_URL) elif getattr(settings, 'LOGOUT_URL', None): warnings.warn( "LOGOUT_URL has been replaced by LOGOUT_REDIRECT_URL, please " "review the URL and update your settings.", DeprecationWarning) context['cancel_url'] = resolve_url(settings.LOGOUT_URL) return context @cached_property def remember_agent(self): """ Returns True if a user, browser and device is remembered using the remember cookie. """ if not getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_AGE', None): return False user = self.get_user() devices = list(devices_for_user(user)) for key, value in self.request.COOKIES.items(): if key.startswith(REMEMBER_COOKIE_PREFIX) and value: for device in devices: verify_is_allowed, extra = device.verify_is_allowed() try: if verify_is_allowed and validate_remember_device_cookie( value, user=user, otp_device_id=device.persistent_id): user.otp_device = device device.throttle_reset() return True except BadSignature: device.throttle_increment() # Remove remember cookies with invalid signature to omit unnecessary throttling self.cookies_to_delete.append(key) return False def delete_cookies_from_response(self, response): """ Deletes the cookies_to_delete in the response """ for cookie in self.cookies_to_delete: response.delete_cookie(cookie) return response # Copied from django.conrib.auth.views.LoginView (Branch: stable/1.11.x) # https://github.com/django/django/blob/58df8aa40fe88f753ba79e091a52f236246260b3/django/contrib/auth/views.py#L49 @method_decorator(sensitive_post_parameters()) @method_decorator(csrf_protect) @method_decorator(never_cache) def dispatch(self, request, *args, **kwargs): if self.redirect_authenticated_user and self.request.user.is_authenticated: redirect_to = self.get_success_url() if redirect_to == self.request.path: raise ValueError( "Redirection loop for authenticated user detected. Check that " "your LOGIN_REDIRECT_URL doesn't point to a login page.") return HttpResponseRedirect(redirect_to) return super().dispatch(request, *args, **kwargs)
class RegistrationView(APIView): # pylint: disable=missing-docstring """HTTP end-points for creating a new user. """ # This end-point is available to anonymous users, # so do not require authentication. authentication_classes = [] @method_decorator(transaction.non_atomic_requests) @method_decorator(sensitive_post_parameters("password")) def dispatch(self, request, *args, **kwargs): return super(RegistrationView, self).dispatch(request, *args, **kwargs) @method_decorator(ensure_csrf_cookie) def get(self, request): return HttpResponse( RegistrationFormFactory().get_registration_form(request).to_json(), content_type="application/json") @method_decorator(csrf_exempt) def post(self, request): """Create the user's account. You must send all required form fields with the request. You can optionally send a "course_id" param to indicate in analytics events that the user registered while enrolling in a particular course. Arguments: request (HTTPRequest) Returns: HttpResponse: 200 on success HttpResponse: 400 if the request is not valid. HttpResponse: 409 if an account with the given username or email address already exists HttpResponse: 403 operation not allowed """ data = request.POST.copy() self._handle_terms_of_service(data) response = self._handle_duplicate_email_username(data) if response: return response response, user = self._create_account(request, data) if response: return response response = self._create_response({}, status_code=200) set_logged_in_cookies(request, response, user) return response def _handle_duplicate_email_username(self, data): # TODO Verify whether this check is needed here - it may be duplicated in user_api. email = data.get('email') username = data.get('username') conflicts = check_account_exists(email=email, username=username) if conflicts: conflict_messages = { "email": accounts_settings.EMAIL_CONFLICT_MSG.format( email_address=email), # pylint: disable=no-member "username": accounts_settings.USERNAME_CONFLICT_MSG.format( username=username), # pylint: disable=no-member } errors = { field: [{ "user_message": conflict_messages[field] }] for field in conflicts } return self._create_response(errors, status_code=409) def _handle_terms_of_service(self, data): # Backwards compatibility: the student view expects both # terms of service and honor code values. Since we're combining # these into a single checkbox, the only value we may get # from the new view is "honor_code". # Longer term, we will need to make this more flexible to support # open source installations that may have separate checkboxes # for TOS, privacy policy, etc. if data.get("honor_code") and "terms_of_service" not in data: data["terms_of_service"] = data["honor_code"] def _create_account(self, request, data): response, user = None, None try: user = create_account_with_params(request, data) except AccountValidationError as err: errors = {err.field: [{"user_message": text_type(err)}]} response = self._create_response(errors, status_code=409) except ValidationError as err: # Should only get field errors from this exception assert NON_FIELD_ERRORS not in err.message_dict # Only return first error for each field errors = { field: [{ "user_message": error } for error in error_list] for field, error_list in err.message_dict.items() } response = self._create_response(errors, status_code=400) except PermissionDenied: response = HttpResponseForbidden( _("Account creation not allowed.")) return response, user def _create_response(self, response_dict, status_code): if status_code == 200: # keeping this `success` field in for now, as we have outstanding clients expecting this response_dict['success'] = True return JsonResponse(response_dict, status=status_code)
from django.utils.decorators import method_decorator from django.utils.translation import ugettext_lazy as _ from django.views.decorators.debug import sensitive_post_parameters from rest_auth.app_settings import (TokenSerializer, JWTSerializer, create_token) from rest_auth.models import TokenModel from rest_auth.utils import jwt_encode from rest_framework import status from rest_framework.generics import CreateAPIView from rest_framework.response import Response from rest_framework.permissions import AllowAny from .serializers import RegisterSerializer sensitive_post_parameters_m = method_decorator( sensitive_post_parameters('password')) class RegisterView(CreateAPIView): serializer_class = RegisterSerializer permission_classes = (AllowAny, ) token_model = TokenModel @sensitive_post_parameters_m def dispatch(self, *args, **kwargs): return super(RegisterView, self).dispatch(*args, **kwargs) def get_response_data(self, user): if allauth_settings.EMAIL_VERIFICATION == \ allauth_settings.EmailVerificationMethod.MANDATORY: return {"detail": _("Verification e-mail sent.")}
class UserProfileAdmin(UserAdmin): search_fields = [ 'userprofile__persona__num_identificacion', 'username', 'email', ] inlines = [ UserProfileInline, ] staff_fieldsets = ((None, { 'fields': ('username', 'password') }), (_('Personal info'), { 'fields': ('first_name', 'last_name', 'email') }), (_('Permissions'), { 'fields': ('is_active', ) }), (_('Important dates'), { 'fields': ('last_login', 'date_joined') }), (_('Groups'), { 'fields': ('groups', ) })) staff_fieldsets_sinpass = ((None, { 'fields': ('username', ) }), (_('Personal info'), { 'fields': ('first_name', 'last_name', 'email') }), (_('Permissions'), { 'fields': ('is_active', ) }), (_('Important dates'), { 'fields': ('last_login', 'date_joined') }), (_('Groups'), { 'fields': ('groups', ) })) add_fieldsets = ((None, { 'classes': ('wide', ), 'fields': ('username', 'password1', 'password2') }), ) def queryset(self, request): qs = super(UserProfileAdmin, self).queryset(request) if not request.user.is_superuser: qs = qs.exclude(is_superuser=True) return qs ''' Para poder obtener el usuario desde el formulario UserFormChange definimos la variable aqui''' def get_form(self, request, obj=None, **kwargs): form = super(UserProfileAdmin, self).get_form(request, obj, **kwargs) form.current_user = request.user ''' Si se esta editando el mismo usuario y no es superusuario se muestran los grupos a los que pertenece el usuario, si no es el mismo usuario solo muestra estudiantes ''' ''' if not request.user.is_superuser: from django.db.models import Q if obj==request.user: form.base_fields['groups'].queryset=(grupos|request.user.groups.all()).distinct() else: form.base_fields['groups'].queryset=grupos ''' return form ''' Evita escalabilidad de privilegios cuando un usuario staff NO superUsuario intente cambiar la clave de un SuperUsuario. ''' from django.views.decorators.debug import sensitive_post_parameters @method_decorator(sensitive_post_parameters()) def user_change_password(self, request, id, form_url=''): if not request.user.is_superuser and self.queryset(request).get( pk=id).is_superuser: from django.core.exceptions import PermissionDenied raise PermissionDenied else: return super(UserProfileAdmin, self).user_change_password(request, id, form_url) ''' No mostrar la opcion de SuperUsuario si no se es un superusuario. Evitar bug de escalabilida de permisos ''' def change_view(self, request, *args, **kwargs): # for non-superuser if not request.user.is_superuser: try: #Si el usuario editado es un SuperUsuario y el editor no lo es,o Si el usuario editado es staff NO se muestra el enlace de cambiar clave. Evitando escalabilidad de privilegios if self.queryset(request).get( pk=args[0]).is_superuser or self.queryset(request).get( pk=args[0]).is_staff: self.fieldsets = self.staff_fieldsets_sinpass else: self.fieldsets = self.staff_fieldsets ''' Se limita los grupos disponibles a los que posee el usuario y a Estudiante''' response = super(UserAdmin, self).change_view(request, *args, **kwargs) #response = super(UserAdmin,self).change_view( request, *args, **kwargs) finally: # Reset fieldsets to its original value self.fieldsets = super(UserAdmin, self).fieldsets return response else: return super(UserAdmin, self).change_view(request, *args, **kwargs)
from django.conf import settings from django.http import HttpResponseRedirect from django.contrib.auth.forms import AuthenticationForm from django.template.response import TemplateResponse from django.utils.http import is_safe_url from django.shortcuts import resolve_url from django.views.decorators.debug import sensitive_post_parameters from django.views.decorators.cache import never_cache from django.views.decorators.csrf import csrf_protect from django.contrib.auth import REDIRECT_FIELD_NAME, login as auth_login from django.contrib.sites.models import get_current_site sensitive_post_parameters() @csrf_protect @never_cache def login(request, template_name='admin/login.html', redirect_field_name=REDIRECT_FIELD_NAME, authentication_form=AuthenticationForm, current_app=None, extra_context=None): """ Displays the login form and handles the login action. """ redirect_to = request.REQUEST.get(redirect_field_name, '') if request.method == "POST": form = authentication_form(data=request.POST) if form.is_valid(): # Check for remember me tick. if request.REQUEST.get('remember_me', None):
def update(self, request, *args, **kwargs): try: self.get_object() return Response({}, status=status.HTTP_200_OK) except Http404: data = { 'user': self.user.pk, 'name': kwargs.get('name') or '', } serializer = self.get_serializer(data=data) serializer.is_valid(raise_exception=True) serializer.save() return Response({}, status=status.HTTP_201_CREATED) @method_decorator(sensitive_post_parameters('old_password', 'new_password'), name='dispatch') class ChangePasswordView(generics.GenericAPIView): permission_classes = (IsAuthenticated, AnyAdminClientIDPermissions) serializer_class = ChangePasswordSerializer @atomic @method_decorator(sensitive_variables('old_password', 'new_password')) def post(self, request): serializer = self.get_serializer(data=request.data) if serializer.is_valid(): old_password = serializer.validated_data['old_password'] new_password = serializer.validated_data['new_password'] try: if not FailedLoginAttempt.objects.is_locked_out( request.user, request.auth.application):
) from django.contrib.auth.models import Group, User from django.core.exceptions import PermissionDenied from django.db import transaction from django.http import Http404, HttpResponseRedirect from django.template.response import TemplateResponse from django.urls import reverse from django.utils.decorators import method_decorator from django.utils.encoding import force_text from django.utils.html import escape from django.utils.translation import ugettext, ugettext_lazy as _ from django.views.decorators.csrf import csrf_protect from django.views.decorators.debug import sensitive_post_parameters csrf_protect_m = method_decorator(csrf_protect) sensitive_post_parameters_m = method_decorator(sensitive_post_parameters()) @admin.register(Group) class GroupAdmin(admin.ModelAdmin): search_fields = ('name', ) ordering = ('name', ) filter_horizontal = ('permissions', ) def formfield_for_manytomany(self, db_field, request=None, **kwargs): if db_field.name == 'permissions': qs = kwargs.get('queryset', db_field.remote_field.model.objects) # Avoid a major performance hit resolving permission names which # triggers a content_type load: kwargs['queryset'] = qs.select_related('content_type') return super(GroupAdmin,
class LoginView(SuccessURLAllowedHostsMixin, FormView): """ Display the login form and handle the login action. """ form_class = AuthenticationForm authentication_form = None redirect_field_name = REDIRECT_FIELD_NAME template_name = 'registration/login.html' redirect_authenticated_user = False extra_context = None @method_decorator(sensitive_post_parameters()) @method_decorator(csrf_protect) @method_decorator(never_cache) def dispatch(self, request, *args, **kwargs): if self.redirect_authenticated_user and self.request.user.is_authenticated: redirect_to = self.get_success_url() if redirect_to == self.request.path: raise ValueError( "Redirection loop for authenticated user detected. Check that " "your LOGIN_REDIRECT_URL doesn't point to a login page.") return HttpResponseRedirect(redirect_to) return super().dispatch(request, *args, **kwargs) def get_success_url(self): url = self.get_redirect_url() return url or resolve_url(settings.LOGIN_REDIRECT_URL) def get_redirect_url(self): """Return the user-originating redirect URL if it's safe.""" redirect_to = self.request.POST.get( self.redirect_field_name, self.request.GET.get(self.redirect_field_name, '')) url_is_safe = url_has_allowed_host_and_scheme( url=redirect_to, allowed_hosts=self.get_success_url_allowed_hosts(), require_https=self.request.is_secure(), ) return redirect_to if url_is_safe else '' def get_form_class(self): return self.authentication_form or self.form_class def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs['request'] = self.request return kwargs def form_valid(self, form): """Security check complete. Log the user in.""" auth_login(self.request, form.get_user()) return HttpResponseRedirect(self.get_success_url()) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) current_site = get_current_site(self.request) context.update({ self.redirect_field_name: self.get_redirect_url(), 'site': current_site, 'site_name': current_site.name, **(self.extra_context or {}) }) return context
class ChangeInformationView(CustomerRequiredMixin, FormView): template_name = 'pretixpresale/organizers/customer_info.html' form_class = ChangeInfoForm @method_decorator(sensitive_post_parameters()) @method_decorator(csrf_protect) @method_decorator(never_cache) def dispatch(self, request, *args, **kwargs): if not request.organizer.settings.customer_accounts: raise Http404('Feature not enabled') if self.request.customer: self.initial_email = self.request.customer.email return super().dispatch(request, *args, **kwargs) def get_success_url(self): return eventreverse(self.request.organizer, 'presale:organizer.customer.profile', kwargs={}) def form_valid(self, form): if form.cleaned_data['email'] != self.initial_email: new_email = form.cleaned_data['email'] form.cleaned_data[ 'email'] = form.instance.email = self.initial_email ctx = form.instance.get_email_context() ctx['url'] = build_absolute_uri( self.request.organizer, 'presale:organizer.customer.change.confirm' ) + '?token=' + dumps( { 'customer': form.instance.pk, 'email': new_email }, salt='pretix.presale.views.customer.ChangeInformationView') mail( new_email, _('Confirm email address for your account at {organizer}' ).format(organizer=self.request.organizer.name), self.request.organizer.settings. mail_text_customer_email_change, ctx, locale=form.instance.locale, customer=form.instance, organizer=self.request.organizer, ) messages.success( self.request, _('Your changes have been saved. We\'ve sent you an email with a link to update your ' 'email address. The email address of your account will be changed as soon as you ' 'click that link.')) else: messages.success(self.request, _('Your changes have been saved.')) with transaction.atomic(): form.save() d = dict(form.cleaned_data) del d['email'] self.request.customer.log_action('pretix.customer.changed', d) update_customer_session_auth_hash(self.request, form.instance) return HttpResponseRedirect(self.get_success_url()) def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs['request'] = self.request kwargs['instance'] = self.request.customer return kwargs
class RefreshApiView(CsrfExemptMixin, TokenView): @method_decorator(sensitive_post_parameters('password')) def post(self, request, *args, **kwargs): request = services.config_refresh_request(request) url, headers, body, status = self.create_token_response(request) return services.create_auth_response(body, headers, status)
class ProfileUpdate(View): """Class for creating user with no priviledges""" template_name = "account/dashboard/profile_edit.html" profile_form_class = ProfileUpdateForm user_form_class = UserUpdateForm title = _('CodeTopia | Update Profile') extra_context = None # Error messages for the view error_messages = { "already_have_account": _("You already have an account and can not create another account.") } # Success messages for the view success_messages = { "profile_updated": _("Congradulation %s you have updated your profile succesfully.") } def get_context_data(self, *args, **kwargs): """Return all context data by collecting it.""" current_site = get_current_site(self.request) context = { "site": current_site, "site_name": current_site.name, "title": self.title } context.update(**(self.extra_context or {})) return context def get_profile_form_class(self, *args, **kwargs): """Return the instance of the for class to be used.""" return self.profile_form_class(*args) def get_user_form_class(self, *args, **kwargs): """Return the instance of the for class to be used.""" return self.user_form_class(*args) def get(self, request, *args, **kwargs): self.extra_context = { "user_form": self.user_form_class(instance=request.user), "profile_form": self.profile_form_class(instance=request.user.profile) } return render(request=request, template_name=self.template_name, context=self.get_context_data()) @method_decorator(sensitive_post_parameters()) @method_decorator(csrf_protect) def post(self, request, *args, **kwargs): user_form = self.user_form_class(instance=request.user, data=request.POST), profile_form = self.profile_form_class(instance=request.user.profile, data=request.POST, files=request.FILES) if user_form.is_valid() and profile_form.is_valid(): user_cache = user_form.save() profile_form.save() messages.success( request=self.request, message=self.success_messages.get("profile_updated") % user_cache.username) return HttpResponseRedirect( reverse(viewname="account:user_dashboard")) # If the form is invalid return the form with error messages self.extra_context = { **self.get_context_data(), "user_form": user_form, "profile_form": profile_form } return render(request=self.request, template_name=self.template_name, context=self.get_context_data())
from django.shortcuts import redirect from django.utils.decorators import method_decorator from django.views.decorators.cache import never_cache from django.views.decorators.csrf import csrf_protect from django.views.decorators.debug import sensitive_post_parameters from django.views.generic import TemplateView from django.views.generic.detail import DetailView from django.views.generic.edit import FormView, UpdateView from pepysdiary.annotations.models import Annotation from pepysdiary.common.models import Config from pepysdiary.membership import forms from pepysdiary.membership.models import Person @method_decorator([csrf_protect, never_cache, sensitive_post_parameters('password1', 'password2')], name='dispatch') class RegisterView(FormView): template_name = 'register.html' form_class = forms.RegistrationForm def get(self, request, *args, **kwargs): if request.user.is_authenticated(): return redirect('home') else: return super(RegisterView, self).get(request, *args, **kwargs) def get_success_url(self): if self.success_url: return self.success_url return reverse('register_complete')
class UserPasswordChangeView(PasswordContextMixin, FormView): """ View for changing user password using validated old password. Interface for UserDashboard """ form_class = PasswordChangeForm success_url = None template_name = "account/dashboard/change_password.html" title = _("CodeTopia | Chnage Password") success_messages = { "succesfull": _("You have successfully changed your password.") } @method_decorator(sensitive_post_parameters()) @method_decorator(csrf_protect) @method_decorator(login_required) def dispatch(self, *args, **kwargs): return super().dispatch(*args, **kwargs) def get_success_url(self): """Return the URL to redirect to after processing a valid form.""" if self.success_url is not None: url = self.success_url.format(**self.object.__dict__) url = reverse(viewname="account:user_dashboard", kwargs={"username": self.request.user.username}) return url def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs['user'] = self.request.user return kwargs def form_valid(self, form): form.save() # Log out the user from other sessions and update the current session with # new password hash update_session_auth_hash(self.request, form.user) # send password changed message messages.success(request=self.request, message=self.success_messages.get("succesfull")) return super().form_valid(form) def post(self, request, *args, **kwargs): """ Handle POST requests: instantiate a form instance with the passed POST variables and then check if it's valid. """ form = self.get_form() if form.is_valid(): return self.form_valid(form) else: return self.form_invalid(form) # PUT is a valid HTTP verb for creating (with a known URL) or editing an # object, note that browsers only support POST for now. def put(self, *args, **kwargs): return self.post(*args, **kwargs)
from common.mixins import DatetimeSearchMixin from ..models import User, LoginLog from ..utils import send_reset_password_mail from ..tasks import write_login_log_async from .. import forms __all__ = [ 'UserLoginView', 'UserLogoutView', 'UserForgotPasswordView', 'UserForgotPasswordSendmailSuccessView', 'UserResetPasswordView', 'UserResetPasswordSuccessView', 'UserFirstLoginView', 'LoginLogListView' ] @method_decorator(sensitive_post_parameters(), name='dispatch') @method_decorator(csrf_protect, name='dispatch') @method_decorator(never_cache, name='dispatch') class UserLoginView(FormView): template_name = 'users/login.html' form_class = forms.UserLoginForm redirect_field_name = 'next' def get(self, request, *args, **kwargs): if request.user.is_staff: return redirect(self.get_success_url()) request.session.set_test_cookie() return super().get(request, *args, **kwargs) def form_valid(self, form): if not self.request.session.test_cookie_worked():
class CreateUserView(View): """Class for creating user with no priviledges""" template_name = "account/create_account.html" form_class = UserCreationForm title = _('CodeTopia | Create Account') extra_context = None # Error messages for the view error_messages = { "already_have_account": _("You already have an account and can not create another account.") } # Success messages for the view success_messages = { "account_created": _("Congradulation %s you have created an account succesfully.") } def get_context_data(self, *args, **kwargs): """Return all context data by collecting it.""" current_site = get_current_site(self.request) context = { "site": current_site, "site_name": current_site.name, "title": self.title } context.update(**(self.extra_context or {})) return context def get_form_class(self, *args, **kwargs): """Return the instance of the for class to be used.""" return self.form_class(*args) def get(self, *args, **kwargs): if self.request.user.is_authenticated: messages.error( request=self.request, message=self.error_messages.get("already_have_account")) return HttpResponseRedirect(reverse("core:homepage")) self.extra_context = {"form": self.get_form_class()} return render(request=self.request, template_name=self.template_name, context=self.get_context_data()) @method_decorator(sensitive_post_parameters()) @method_decorator(csrf_protect) def post(self, *args, **kwargs): form = self.get_form_class(self.request.POST) if form.is_valid(): user_cache = form.save() messages.success( request=self.request, message=self.success_messages.get("account_created") % user_cache.username) return HttpResponseRedirect(reverse(viewname="account:user_login")) # If the form is invalid return the form with error messages self.extra_context = {**self.get_context_data(), "form": form} return render(request=self.request, template_name=self.template_name, context=self.get_context_data())
from django.views.generic import RedirectView from django.views.decorators.debug import sensitive_post_parameters, sensitive_variables from cas_server import views app_name = "cas_server" urlpatterns = [ url( r'^$', RedirectView.as_view(pattern_name="cas_server:login", permanent=False, query_string=True) ), url( '^login$', sensitive_post_parameters('password')( views.LoginView.as_view() ), name='login' ), url('^logout$', views.LogoutView.as_view(), name='logout'), url('^validate$', views.Validate.as_view(), name='validate'), url( '^serviceValidate$', views.ValidateService.as_view(allow_proxy_ticket=False), name='serviceValidate' ), url( '^proxyValidate$', views.ValidateService.as_view(allow_proxy_ticket=True), name='proxyValidate' ),
class PrescriptionSite(AuditSite): def has_permission(self, request): return request.user.is_active def get_urls(self): """ Add a view to clear the current prescription from the session """ from django.conf.urls import patterns, url def wrap(view, cacheable=False): def wrapper(*args, **kwargs): return self.admin_view(view, cacheable)(*args, **kwargs) return update_wrapper(wrapper, view) urlpatterns = patterns( '', url(r'^administration/$', wrap(self.site_admin), name='site_admin'), url(r'^profile/$', wrap(self.profile), name='profile'), url(r'^endorse-authorise/$', wrap(self.endorse_authorise_summary), name='endorse_authorise_summary'), # url(r'^daily-burn-program/$', # wrap(self.daily_burn_program), # name='daily_burn_program'), # url(r'^daily-burn-program/add$', # wrap(self.daily_burn_program_add), # name='daily_burn_program_add'), url(r'^endorse-authorise/export_csv/$', wrap(self.export_to_csv), name='endorse_authorise_exportcsv'), ) return urlpatterns + super(PrescriptionSite, self).get_urls() def index(self, request): try: profile = request.user.profile except: profile = None url = reverse('admin:prescription_prescription_changelist') if profile is not None and profile.region: url += '?region__id__exact=%s' % profile.region.id return HttpResponseRedirect(url) def password_change(self, request): if request.user.profile.is_fpc_user(): return super(PrescriptionSite, self).password_change(request) else: return HttpResponseForbidden("You are not an FPC user. Only FPC " "users can change their password " "via this interface.") def register(self, model, admin_class=None, **options): try: super(PrescriptionSite, self).register(model, admin_class, **options) except ImproperlyConfigured: self._registry[model] = admin_class(model, self) @method_decorator(sensitive_post_parameters()) @never_cache def login(self, request, redirect_field_name=REDIRECT_FIELD_NAME, authentication_form=PbsAdminAuthenticationForm, extra_context=None): """ Displays the login form and handles the login action. """ redirect_to = request.REQUEST.get(redirect_field_name, '') if request.method == 'POST': form = authentication_form(request, data=request.POST) if form.is_valid(): # Ensure the user-originating redirection url is safe. if not is_safe_url(url=redirect_to, host=request.get_host()): redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL) # If this is the user's first login, redirect them to # edit their profile. user = form.get_user() if user.last_login == user.date_joined: request.session['first_login'] = True redirect_to = reverse('admin:profile') # Okay, security check complete. Log the user in. login(request, user) return HttpResponseRedirect(redirect_to) else: form = authentication_form(request) current_site = get_current_site(request) # We won't need this in Django 1.6 request.session.set_test_cookie() context = { 'title': _('Log in'), 'app_path': request.get_full_path(), 'form': form, redirect_field_name: request.get_full_path(), 'site': current_site, 'site_name': current_site.name, } if extra_context is not None: context.update(extra_context) return TemplateResponse(request, self.login_template or 'admin/login.html', context, current_app=self.name) @never_cache def logout(self, request, extra_context=None): from django.contrib.auth.views import logout return logout(request, reverse('admin:index', current_app=self.name)) def site_admin(self, request, extra_context=None): context = {} context.update(extra_context or {}) return TemplateResponse(request, "admin/site_admin.html", context, current_app=self.name) def profile(self, request): profile = request.user.get_profile() if request.method == 'POST': form = ProfileForm(request.POST, instance=profile) if form.is_valid(): form.save() return HttpResponseRedirect( reverse('admin:index', current_app=self.name)) else: form = ProfileForm(instance=profile) context = {'title': _('Edit profile'), 'form': form} return TemplateResponse(request, "admin/profile.html", context, current_app=self.name) def endorse_authorise_summary(self, request, extra_context=None): """ Display summaries of prescriptions, approvals and ignitions. DEV: """ form = EndorseAuthoriseSummaryForm(request.GET) report_set = {'summary', 'approvals', 'ignitions'} report = request.GET.get('report', 'summary') if report not in report_set: report = 'summary' export_csv = True if request.GET.get( 'Export_CSV') == 'export_csv' else False if request.GET.get('fromDate'): fromDate = request.GET.get('fromDate') fromDate = datetime.datetime.strptime(fromDate, '%d-%m-%Y').date() else: # default - beginning of current financial year today = datetime.date.today() financial_year = datetime.date(today.year, 7, 1) if today < financial_year: #today is early than the first day of this year's financial year, set fromDate to last year's financial year fromDate = datetime.date(today.year - 1, 7, 1) else: #today is later than the first day of this year's financial year, set fromDate to this year's financial year fromDate = financial_year if request.GET.get('toDate'): toDate = request.GET.get('toDate') toDate = datetime.datetime.strptime(toDate, '%d-%m-%Y').date() else: toDate = datetime.date.today() burns = [] if report == 'summary': title = _("Endorsements summary") queryset = Prescription.objects.filter( endorsement_status=Prescription.ENDORSEMENT_SUBMITTED) elif report == 'approvals': title = _("Approvals summary") queryset = Prescription.objects.filter( approval_status=Prescription.APPROVAL_SUBMITTED) elif report == 'ignitions': title = _("Ignitions summary") queryset = None burns = self.get_burns(fromDate, toDate) else: raise ValueError("Report {} must be in {}".format( report, report_set)) if export_csv: return self.export_to_csv(request, fromDate, toDate, burns) if queryset: queryset.prefetch_related('endorsing_roles') if form.is_valid(): region = form.cleaned_data.get('region', None) district = form.cleaned_data.get('district', None) if region: queryset = queryset.filter(region=region) if district: queryset = queryset.filter(district=district) context = { 'title': title, 'prescriptions': queryset, 'form': form, 'report': report, 'burns': burns, 'fromDate': fromDate, 'toDate': toDate, } context.update(extra_context or {}) return TemplateResponse(request, "admin/endorse_authorise_summary.html", context, current_app=self.name) def get_burns(self, fromDate, toDate): query_list = [] for p in Prescription.objects.all(): for a in p.areaachievement_set.all(): region_type = 'Forest' if str( p.region) in forest_regions else 'Non-forest' if a.ignition >= fromDate and a.ignition <= toDate and p.ignition_status != p.IGNITION_COMPLETE: query_list.append([ int(p.id), str(p.burn_id), str(p.region), str(p.district), 'commenced', str(a.ignition), float(a.area_treated), region_type ]) elif a.ignition >= fromDate and a.ignition <= toDate and p.ignition_status == p.IGNITION_COMPLETE: query_list.append([ int(p.id), str(p.burn_id), str(p.region), str(p.district), 'completed', str(a.ignition), float(a.area_treated), region_type ]) result = [] # collate the results sub_results = self.collate_results(query_list, 'Forest') result += sub_results sub_results = self.collate_results(query_list, 'Non-forest') result += sub_results # don't double count Sub-Totals in Total, and ignore blank rows total_completed = sum([ ll[1] for ll in result if len(ll) > 0 and re.search('Total', ll[0]) ]) total_commenced = sum([ ll[2] for ll in result if len(ll) > 0 and re.search('Total', ll[0]) ]) total_area = sum([ ll[3] for ll in result if len(ll) > 0 and re.search('Total', ll[0]) ]) result.append(['Total', total_completed, total_commenced, total_area]) return result def collate_results(self, query_list, region_type): results = [] regions = set([ll[2] for ll in query_list if region_type in ll]) # unique list of region's for region in regions: # count of completed/commenced burns and sum(area) for given region completed_burns = len( set([ ll[1] for ll in query_list if (region in ll and 'completed' in ll) ])) commenced_burns = len( set([ ll[1] for ll in query_list if (region in ll and 'commenced' in ll) ])) area = sum([ll[6] for ll in query_list if (region in ll)]) results.append([region, completed_burns, commenced_burns, area]) total_completed = sum([ll[1] for ll in results]) total_commenced = sum([ll[2] for ll in results]) total_area = sum([ll[3] for ll in results]) results.append([ '{} Sub-Total'.format(region_type), total_completed, total_commenced, total_area ]) results.append([] * 4) return results def export_to_csv(self, request, fromDate, toDate, burns=None): local_zone = tz.tzlocal() query_list = [] id_list = [] for p in Prescription.objects.all(): for a in p.areaachievement_set.all(): if a.ignition >= fromDate and a.ignition <= toDate: p_id = p.id p_count = 0 if p_id in id_list else 1 # get a unique count of prescription id_list.append(p_id) region = str(p.region) region_type = 'Forest' if region in forest_regions else 'Non-forest' district = str(p.district) burn_name = str(p.name) burn_id = str(p.burn_id) date_updated = str( p.modified.astimezone(local_zone).strftime( '%d/%m/%Y %H:%M:%S')) ignition_status = p.get_ignition_status_display() burn_closed = "Yes" if p.status == p.STATUS_CLOSED else "No" burn_complexity = p.maximum_complexity burn_priority = p.get_priority_display() burn_risk = p.maximum_risk contentious = "Yes" if p.contentious else "No" year = p.planned_year season = p.financial_year actual_ignitions = ('"%s"' % ",".join( ",".join('{0}:{1}'.format( x.ignition.strftime('%d/%m/%Y'), ignition_type) for ignition_type in (x.ignition_types.all() or ("Unset", ))) for x in p.areaachievement_set.order_by('ignition'))) planned_burn_area = p.area total_treatment_area = p.total_treatment_area burnt_area_estimate = p.total_burnt_area_estimate length_of_edging = p.total_edging_length depth_of_edging = p.total_edging_depth shires = '"%s"' % ",".join(x.name for x in p.shires.all()) purposes = '"%s"' % ",".join(x.name for x in p.purposes.all()) allocations = p.allocations tenures = '"%s"' % ",".join(x.name for x in p.tenures.all()) #escape_dates = ", ".join([datetime.strftime(x.date_escaped, '%d/%m/%Y') for x in a.filter(date_escaped__isnull=False).order_by('ignition')]) #dpaw_fire_nums = '"%s"' % ",".join(x.dpaw_fire_no for x in a.exclude(dpaw_fire_no__isnull=True).exclude(dpaw_fire_no__exact='').order_by('ignition')) #dfes_fire_nums = '"%s"' % ",".join(x.dfes_fire_no for x in a.exclude(dfes_fire_no__isnull=True).exclude(dfes_fire_no__exact='').order_by('ignition')) success_criterias = '"%s"' % ",".join( x.criteria for x in p.successcriteria_set.all().order_by('id')) if p.ignition_status != p.IGNITION_COMPLETE: query_list.append([ p_id, p_count, burn_id, burn_name, region, district, 'commenced', str(a.ignition), float(a.area_treated), region_type, date_updated, ignition_status, burn_closed, burn_complexity, burn_priority, burn_risk, contentious, year, season, actual_ignitions, planned_burn_area, total_treatment_area, burnt_area_estimate, length_of_edging, depth_of_edging, shires, purposes, allocations, tenures, #escape_dates, dpaw_fire_nums, dfes_fire_nums,. success_criterias ]) elif p.ignition_status == p.IGNITION_COMPLETE: query_list.append([ p_id, p_count, burn_id, burn_name, region, district, 'completed', str(a.ignition), float(a.area_treated), region_type, date_updated, ignition_status, burn_closed, burn_complexity, burn_priority, burn_risk, contentious, year, season, actual_ignitions, planned_burn_area, total_treatment_area, burnt_area_estimate, length_of_edging, depth_of_edging, shires, purposes, allocations, tenures, #escape_dates, dpaw_fire_nums, dfes_fire_nums,. success_criterias ]) filename = 'export_burn_{0}-{1}.csv'.format( fromDate.strftime('%d%b%Y'), toDate.strftime('%d%b%Y')) response = HttpResponse(content_type="text/csv") response['Content-Disposition'] = 'attachment; filename={}'.format( filename) writer = unicodecsv.writer(response, quoting=unicodecsv.QUOTE_ALL) writer.writerow([ 'Prescription_ID', 'Prescription Count', 'Burn ID', 'Name of Burn', 'Region', 'District', 'Status', 'Ignition Date', 'Burn area (ha)', 'Region Type', 'Date Updated', 'Ignition Status', 'Burn Closed', 'Burn Complexity', 'Burn Priority', 'Burn Risk', 'Contentious', 'Year', 'Season', 'Actual Ignition Type', 'Planned Burn Area', 'Total Area Where Treatment Is Complete', 'Total Treatment Activity', 'Length of Edging/Perimeter', 'Depth of Edging', 'Shire', 'Burn Purpose/s', 'Program Allocations', 'Land Tenure', 'Success Criteria' ]) for burn in query_list: writer.writerow([unicode(s).encode("utf-8") for s in burn]) return response export_to_csv.short_description = ugettext_lazy("Export to CSV")
class LDAPAuthenticationBackend(ModelBackend): """ This class provides LDAP authentication against an LDAP or Active Directory server. """ @method_decorator(sensitive_post_parameters('password')) def authenticate(self, request, username=None, password=None, **keyword_arguments): # Check for remote user in extra arguments if no username and password. # In case of basic authentication if not username or not password: if 'remote_user' in keyword_arguments: credentials = base_64_decode_basic_auth( keyword_arguments['remote_user']) if credentials: username, password = credentials[0], credentials[1] else: return None else: return None user = check_user_exists_and_active(self, username) is_authenticated_with_ldap = False errors = [] for server in settings.LDAP_SERVERS: try: port = server.get('port', 636) use_ssl = server.get('use_ssl', True) bind_as_authentication = server.get('bind_as_authentication', True) domain = server.get('domain') t = Tls(validate=CERT_REQUIRED, version=PROTOCOL_TLSv1_2, ca_certs_file=server.get('certificate')) s = Server(server['url'], port=port, use_ssl=use_ssl, tls=t) auto_bind = AUTO_BIND_TLS_BEFORE_BIND if use_ssl else AUTO_BIND_NO_TLS ldap_bind_user = f"{domain}\\{username}" if domain else username if not bind_as_authentication: # binding to LDAP first, then search for user bind_username = server.get('bind_username', None) bind_username = f"{domain}\\{bind_username}" if domain and bind_username else bind_username bind_password = server.get('bind_password', None) authentication = SIMPLE if bind_username and bind_password else ANONYMOUS c = Connection(s, user=bind_username, password=bind_password, auto_bind=auto_bind, authentication=authentication, raise_exceptions=True) search_username_field = server.get('search_username_field', 'uid') search_attribute = server.get('search_attribute', 'cn') search = c.search(server['base_dn'], f"({search_username_field}={username})", attributes=[search_attribute]) if not search or search_attribute not in c.response[0].get( 'attributes', []): # no results, unbind and continue to next server c.unbind() errors.append( f"User {username} attempted to authenticate with LDAP ({server['url']}), but the search with dn:{server['base_dn']}, username_field:{search_username_field} and attribute:{search_attribute} did not return any results. The user was denied access" ) continue else: # we got results, get the dn that will be used for binding authentication response = c.response[0] ldap_bind_user = response['dn'] c.unbind() # let's proceed with binding using the user trying to authenticate c = Connection(s, user=ldap_bind_user, password=password, auto_bind=auto_bind, authentication=SIMPLE, raise_exceptions=True) c.unbind() # At this point the user successfully authenticated to at least one LDAP server. is_authenticated_with_ldap = True auth_logger.debug( f"User {username} was successfully authenticated with LDAP ({server['url']})" ) break except LDAPBindError as e: errors.append( f"User {username} attempted to authenticate with LDAP ({server['url']}), but entered an incorrect password. The user was denied access: {str(e)}" ) except LDAPException as e: errors.append( f"User {username} attempted to authenticate with LDAP ({server['url']}), but an error occurred. The user was denied access: {str(e)}" ) if is_authenticated_with_ldap: return user else: for error in errors: auth_logger.warning(error) return None
class SignupView(PasswordMixin, FormView): template_name = "account/signup.html" template_name_ajax = "account/ajax/signup.html" template_name_email_confirmation_sent = "account/email_confirmation_sent.html" template_name_email_confirmation_sent_ajax = "account/ajax/email_confirmation_sent.html" template_name_signup_closed = "account/signup_closed.html" template_name_signup_closed_ajax = "account/ajax/signup_closed.html" form_class = SignupForm form_kwargs = {} form_password_field = "password" redirect_field_name = "next" identifier_field = "username" messages = { "email_confirmation_sent": { "level": messages.INFO, "text": _("Confirmation email sent to {email}.") }, "invalid_signup_code": { "level": messages.WARNING, "text": _("The code {code} is invalid.") } } fallback_url_setting = "ACCOUNT_SIGNUP_REDIRECT_URL" def __init__(self, *args, **kwargs): self.created_user = None kwargs["signup_code"] = None super(SignupView, self).__init__(*args, **kwargs) @method_decorator(sensitive_post_parameters()) @method_decorator(csrf_protect) @method_decorator(never_cache) def dispatch(self, request, *args, **kwargs): self.request = request self.args = args self.kwargs = kwargs self.setup_signup_code() return super(SignupView, self).dispatch(request, *args, **kwargs) def get_context_data(self, **kwargs): context = super(SignupView, self).get_context_data(**kwargs) context['title'] = "Welcome!" return context def setup_signup_code(self): code = self.get_code() if code: try: self.signup_code = SignupCode.check_code(code) except SignupCode.InvalidCode: self.signup_code = None self.signup_code_present = True else: self.signup_code = None self.signup_code_present = False def get(self, *args, **kwargs): if is_authenticated(self.request.user): return redirect( default_redirect(self.request, settings.ACCOUNT_LOGIN_REDIRECT_URL)) if not self.is_open(): return self.closed() return super(SignupView, self).get(*args, **kwargs) def post(self, *args, **kwargs): if is_authenticated(self.request.user): raise Http404() if not self.is_open(): return self.closed() return super(SignupView, self).post(*args, **kwargs) def get_initial(self): initial = super(SignupView, self).get_initial() if self.signup_code: initial["code"] = self.signup_code.code if self.signup_code.email: initial["email"] = self.signup_code.email return initial def get_template_names(self): if self.request.is_ajax(): return [self.template_name_ajax] else: return [self.template_name] def get_form_kwargs(self): kwargs = super(SignupView, self).get_form_kwargs() kwargs.update(self.form_kwargs) return kwargs def form_invalid(self, form): signals.user_sign_up_attempt.send(sender=SignupForm, username=get_form_data( form, self.identifier_field), email=get_form_data(form, "email"), result=form.is_valid()) return super(SignupView, self).form_invalid(form) def form_valid(self, form): self.created_user = self.create_user(form, commit=False) # prevent User post_save signal from creating an Account instance # we want to handle that ourself. self.created_user._disable_account_creation = True self.created_user.save() self.use_signup_code(self.created_user) email_address = self.create_email_address(form) if settings.ACCOUNT_EMAIL_CONFIRMATION_REQUIRED and not email_address.verified: self.created_user.is_active = False self.created_user.save() self.create_account(form) self.create_password_history(form, self.created_user) self.after_signup(form) if settings.ACCOUNT_EMAIL_CONFIRMATION_EMAIL and not email_address.verified: self.send_email_confirmation(email_address) if settings.ACCOUNT_EMAIL_CONFIRMATION_REQUIRED and not email_address.verified: return self.email_confirmation_required_response() else: show_message = [ settings.ACCOUNT_EMAIL_CONFIRMATION_EMAIL, self.messages.get("email_confirmation_sent"), not email_address.verified ] if all(show_message): messages.add_message( self.request, self.messages["email_confirmation_sent"]["level"], self.messages["email_confirmation_sent"]["text"].format( **{"email": form.cleaned_data["email"]})) # attach form to self to maintain compatibility with login_user # API. this should only be relied on by d-u-a and it is not a stable # API for site developers. self.form = form self.login_user() return redirect(self.get_success_url()) def create_user(self, form, commit=True, model=None, **kwargs): User = model if User is None: User = get_user_model() user = User(**kwargs) username = form.cleaned_data.get("username") if username is None: username = self.generate_username(form) user.username = username user.email = form.cleaned_data["email"].strip() user.first_name = form.cleaned_data.get("first_name") user.last_name = form.cleaned_data.get("last_name") password = form.cleaned_data.get("password") if password: user.set_password(password) else: user.set_unusable_password() if commit: user.save() return user def create_account(self, form): new_account = Account.create(request=self.request, user=self.created_user, create_email=False) # new_account.initial_password = form.cleaned_data.get("initial_password") new_account.spouse_name = form.cleaned_data.get("spouse_name") new_account.street_address = form.cleaned_data.get("street_address") new_account.city = form.cleaned_data.get("city") new_account.state = form.cleaned_data.get("state") new_account.zip_code = form.cleaned_data.get("zip_code") new_account.main_phone = form.cleaned_data.get("main_phone") new_account.alt_phone = form.cleaned_data.get("alt_phone") new_account.save() return new_account def generate_username(self, form): raise NotImplementedError( "Unable to generate username by default. " "Override SignupView.generate_username in a subclass.") def create_email_address(self, form, **kwargs): kwargs.setdefault("primary", True) kwargs.setdefault("verified", False) if self.signup_code: kwargs[ "verified"] = self.created_user.email == self.signup_code.email if self.signup_code.email else False return EmailAddress.objects.add_email(self.created_user, self.created_user.email, **kwargs) def use_signup_code(self, user): if self.signup_code: self.signup_code.use(user) def send_email_confirmation(self, email_address): email_address.send_confirmation(site=get_current_site(self.request)) def after_signup(self, form): signals.user_signed_up.send(sender=SignupForm, user=self.created_user, form=form) def login_user(self): user = auth.authenticate(**self.user_credentials()) auth.login(self.request, user) self.request.session.set_expiry(0) def user_credentials(self): return hookset.get_user_credentials(self.form, self.identifier_field) def get_code(self): return self.request.POST.get("code", self.request.GET.get("code")) def is_open(self): if self.signup_code: return True else: if self.signup_code_present: if self.messages.get("invalid_signup_code"): messages.add_message( self.request, self.messages["invalid_signup_code"]["level"], self.messages["invalid_signup_code"]["text"].format( **{ "code": self.get_code(), })) return settings.ACCOUNT_OPEN_SIGNUP def email_confirmation_required_response(self): if self.request.is_ajax(): template_name = self.template_name_email_confirmation_sent_ajax else: template_name = self.template_name_email_confirmation_sent response_kwargs = { "request": self.request, "template": template_name, "context": { "email": self.created_user.email, "success_url": self.get_success_url(), } } return self.response_class(**response_kwargs) def closed(self): if self.request.is_ajax(): template_name = self.template_name_signup_closed_ajax else: template_name = self.template_name_signup_closed response_kwargs = { "request": self.request, "template": template_name, } return self.response_class(**response_kwargs)
WizardAuthenticationForm, YubiKeyDeviceForm, ) from ..models import PhoneDevice, get_available_phone_methods from ..utils import backup_phones, default_device, get_otpauth_url from .utils import IdempotentSessionWizardView, class_view_decorator try: from otp_yubikey.models import ValidationService, RemoteYubikeyDevice except ImportError: ValidationService = RemoteYubikeyDevice = None logger = logging.getLogger(__name__) @class_view_decorator(sensitive_post_parameters()) @class_view_decorator(never_cache) class LoginView(IdempotentSessionWizardView): """ View for handling the login process, including OTP verification. The login process is composed like a wizard. The first step asks for the user's credentials. If the credentials are correct, the wizard proceeds to the OTP verification step. If the user has a default OTP device configured, that device is asked to generate a token (send sms / call phone) and the user is asked to provide the generated token. The backup devices are also listed, allowing the user to select a backup device for verification. """ template_name = 'two_factor/core/login.html' form_list = ( ('auth', WizardAuthenticationForm),
class LoginView(FormView): template_name = "account/login.html" template_name_ajax = "account/ajax/login.html" form_class = LoginUsernameForm form_kwargs = {} redirect_field_name = "next" @method_decorator(sensitive_post_parameters()) @method_decorator(csrf_protect) @method_decorator(never_cache) def dispatch(self, *args, **kwargs): return super(LoginView, self).dispatch(*args, **kwargs) def get(self, *args, **kwargs): if is_authenticated(self.request.user): return redirect(self.get_success_url()) return super(LoginView, self).get(*args, **kwargs) def get_template_names(self): if self.request.is_ajax(): return [self.template_name_ajax] else: return [self.template_name] def get_context_data(self, **kwargs): ctx = super(LoginView, self).get_context_data(**kwargs) redirect_field_name = self.get_redirect_field_name() ctx.update({ "redirect_field_name": redirect_field_name, "redirect_field_value": self.request.POST.get( redirect_field_name, self.request.GET.get(redirect_field_name, "")), }) return ctx def get_form_kwargs(self): kwargs = super(LoginView, self).get_form_kwargs() kwargs.update(self.form_kwargs) return kwargs def form_invalid(self, form): signals.user_login_attempt.send(sender=LoginView, username=get_form_data( form, form.identifier_field), result=form.is_valid()) return super(LoginView, self).form_invalid(form) def form_valid(self, form): self.login_user(form) if self.request.user.account.initial_password: messages.add_message( self.request, messages.INFO, "In order to use this site, PLEASE CHANGE OUR TEMPORARY PASSWORD. \ This is required for security reasons.") return redirect("account_password", permanent=True) self.after_login(form) return redirect(self.get_success_url()) def after_login(self, form): signals.user_logged_in.send(sender=LoginView, user=form.user, form=form) def get_success_url(self, fallback_url=None, **kwargs): if fallback_url is None: fallback_url = settings.ACCOUNT_LOGIN_REDIRECT_URL kwargs.setdefault("redirect_field_name", self.get_redirect_field_name()) return default_redirect(self.request, fallback_url, **kwargs) def get_redirect_field_name(self): return self.redirect_field_name def login_user(self, form): auth.login(self.request, form.user) expiry = settings.ACCOUNT_REMEMBER_ME_EXPIRY if form.cleaned_data.get( "remember") else 0 self.request.session.set_expiry(expiry)
from common.utils import FlashMessageUtil from users.utils import (redirect_user_first_login_or_index) from ..const import RSA_PRIVATE_KEY, RSA_PUBLIC_KEY from .. import mixins, errors from ..forms import get_user_login_form_cls __all__ = [ 'UserLoginView', 'UserLogoutView', 'UserLoginGuardView', 'UserLoginWaitConfirmView', ] @method_decorator(sensitive_post_parameters(), name='dispatch') @method_decorator(csrf_protect, name='dispatch') @method_decorator(never_cache, name='dispatch') class UserLoginView(mixins.AuthMixin, FormView): redirect_field_name = 'next' template_name = 'authentication/login.html' def redirect_third_party_auth_if_need(self, request): # show jumpserver login page if request http://{JUMP-SERVER}/?admin=1 if self.request.GET.get("admin", 0): return None auth_types = [ m for m in self.get_support_auth_methods() if m.get('auto_redirect') ]
class PasswordResetTokenView(PasswordMixin, FormView): template_name = "account/password_reset_token.html" template_name_fail = "account/password_reset_token_fail.html" form_class = PasswordResetTokenForm token_generator = default_token_generator form_password_field = "password" fallback_url_setting = "ACCOUNT_PASSWORD_RESET_REDIRECT_URL" @method_decorator(sensitive_post_parameters()) @method_decorator(never_cache) def dispatch(self, *args, **kwargs): user = self.get_user() if user is not None: token = kwargs["token"] if token == INTERNAL_RESET_URL_TOKEN: session_token = self.request.session.get( INTERNAL_RESET_SESSION_TOKEN) if self.check_token(user, session_token): return super(PasswordResetTokenView, self).dispatch(*args, **kwargs) else: if self.check_token(user, token): # Store the token in the session and redirect to the # password reset form at a URL without the token. That # avoids the possibility of leaking the token in the # HTTP Referer header. self.request.session[INTERNAL_RESET_SESSION_TOKEN] = token redirect_url = self.request.path.replace( token, INTERNAL_RESET_URL_TOKEN) return redirect(redirect_url) return self.token_fail() def get(self, request, **kwargs): form_class = self.get_form_class() form = self.get_form(form_class) ctx = self.get_context_data(form=form) return self.render_to_response(ctx) def get_context_data(self, **kwargs): ctx = super(PasswordResetTokenView, self).get_context_data(**kwargs) ctx.update({ "uidb36": self.kwargs["uidb36"], "token": self.kwargs["token"], }) return ctx def form_valid(self, form): self.change_password(form) self.create_password_history(form, self.request.user) self.after_change_password() return redirect(self.get_success_url()) def get_user(self): try: uid_int = base36_to_int(self.kwargs["uidb36"]) except ValueError: raise Http404() return get_object_or_404(get_user_model(), id=uid_int) def check_token(self, user, token): return self.token_generator.check_token(user, token) def token_fail(self): response_kwargs = { "request": self.request, "template": self.template_name_fail, "context": self.get_context_data() } return self.response_class(**response_kwargs)
class PasswordResetConfirmView(PasswordContextMixin, FormView): form_class = SetPasswordForm post_reset_login = False post_reset_login_backend = None reset_url_token = 'set-password' success_url = reverse_lazy('authy:password_reset_complete') template_name = 'registration/password_reset_confirm.html' title = _('Enter new password') token_generator = default_token_generator @method_decorator(sensitive_post_parameters()) @method_decorator(never_cache) def dispatch(self, *args, **kwargs): assert 'uidb64' in kwargs and 'token' in kwargs self.validlink = False self.user = self.get_user(kwargs['uidb64']) if self.user is not None: token = kwargs['token'] if token == self.reset_url_token: session_token = self.request.session.get( INTERNAL_RESET_SESSION_TOKEN) if self.token_generator.check_token(self.user, session_token): # If the token is valid, display the password reset form. self.validlink = True return super().dispatch(*args, **kwargs) else: if self.token_generator.check_token(self.user, token): # Store the token in the session and redirect to the # password reset form at a URL without the token. That # avoids the possibility of leaking the token in the # HTTP Referer header. self.request.session[INTERNAL_RESET_SESSION_TOKEN] = token redirect_url = self.request.path.replace( token, self.reset_url_token) return HttpResponseRedirect(redirect_url) # Display the "Password reset unsuccessful" page. return self.render_to_response(self.get_context_data()) def get_user(self, uidb64): try: # urlsafe_base64_decode() decodes to bytestring uid = urlsafe_base64_decode(uidb64).decode() user = UserModel._default_manager.get(pk=uid) except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist, ValidationError): user = None return user def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs['user'] = self.user return kwargs def form_valid(self, form): user = form.save() del self.request.session[INTERNAL_RESET_SESSION_TOKEN] if self.post_reset_login: auth_login(self.request, user, self.post_reset_login_backend) return super().form_valid(form) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) if self.validlink: context['validlink'] = True else: context.update({ 'form': None, 'title': _('Password reset unsuccessful'), 'validlink': False, }) return context
from django.conf import settings from django.conf.urls import url from django.contrib import admin, messages from django.contrib.admin.options import IS_POPUP_VAR from django.contrib.admin.utils import unquote from django.contrib.auth import update_session_auth_hash from django.contrib.auth.forms import ( AdminPasswordChangeForm, UserChangeForm, UserCreationForm, ) from django.contrib.auth.models import Group, User from django.core.exceptions import PermissionDenied from django.core.urlresolvers import reverse from django.db import transaction from django.http import Http404, HttpResponseRedirect from django.template.response import TemplateResponse from django.utils.decorators import method_decorator from django.utils.encoding import force_text from django.utils.html import escape from django.utils.translation import ugettext, ugettext_lazy as _ from django.views.decorators.csrf import csrf_protect from django.views.decorators.debug import sensitive_post_parameters csrf_protect_m = method_decorator(csrf_protect) sensitive_post_parameters_m = method_decorator(sensitive_post_parameters()) @admin.register(Group) class GroupAdmin(admin.ModelAdmin): search_fields = ('name',) ordering = ('name',) filter_horizontal = ('permissions',) def formfield_for_manytomany(self, db_field, request=None, **kwargs):
from django.utils.decorators import method_decorator from django.views.decorators.debug import sensitive_post_parameters from rest_framework.response import Response from rest_framework.generics import CreateAPIView from rest_framework import status from allauth.account.utils import complete_signup from allauth.account import app_settings as allauth_settings from rest_auth.models import TokenModel from rest_auth.views import LoginView from rest_auth.registration.app_settings import RegisterSerializer, register_permission_classes from django.contrib.auth.models import User sensitive_post_parameters_m = method_decorator( sensitive_post_parameters('password1', 'password2')) class RegistroView(CreateAPIView): serializer_class = RegisterSerializer permission_classes = register_permission_classes() token_model = TokenModel @sensitive_post_parameters_m def dispatch(self, *args, **kwargs): return super(RegistroView, self).dispatch(*args, **kwargs) def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) user = self.perform_create(serializer) headers = self.get_success_headers(serializer.data) content = {"details": "Registrado"}
class RegistrationView(FormView): """ Base class for user registration views. """ disallowed_url = 'registration_disallowed' form_class = REGISTRATION_FORM http_method_names = ['get', 'post', 'head', 'options', 'trace'] success_url = None template_name = 'registration/registration_form.html' @method_decorator(sensitive_post_parameters('password1', 'password2')) def dispatch(self, request, *args, **kwargs): """ Check that user signup is allowed and if user is logged in before even bothering to dispatch or do other processing. """ if ACCOUNT_AUTHENTICATED_REGISTRATION_REDIRECTS: if self.request.user.is_authenticated(): if settings.LOGIN_REDIRECT_URL is not None: return redirect(settings.LOGIN_REDIRECT_URL) else: raise Exception(( 'You must set a URL with LOGIN_REDIRECT_URL in ' 'settings.py or set ' 'ACCOUNT_AUTHENTICATED_REGISTRATION_REDIRECTS=False')) if not self.registration_allowed(): return redirect(self.disallowed_url) return super(RegistrationView, self).dispatch(request, *args, **kwargs) def form_valid(self, form): new_user = self.register(form) success_url = self.get_success_url(new_user) # success_url may be a simple string, or a tuple providing the # full argument set for redirect(). Attempting to unpack it # tells us which one it is. try: to, args, kwargs = success_url except ValueError: return redirect(success_url) else: return redirect(to, *args, **kwargs) def registration_allowed(self): """ Override this to enable/disable user registration, either globally or on a per-request basis. """ return True def register(self, form): """ Implement user-registration logic here. """ raise NotImplementedError def get_success_url(self, user=None): """ Use the new user when constructing success_url. """ return super(RegistrationView, self).get_success_url()
:: LoginRequiredMixin = DecoratorMixin(login_required) class MyView(LoginRequiredMixin): pass class SomeView(DecoratorMixin(some_decorator), DecoratorMixin(something_else)): pass """ class Mixin(object): __doc__ = decorator.__doc__ @classmethod def as_view(cls, *args, **kwargs): view = super(Mixin, cls).as_view(*args, **kwargs) return decorator(view) Mixin.__name__ = str('DecoratorMixin(%s)' % decorator.__name__) return Mixin NeverCacheMixin = DecoratorMixin(never_cache) CsrfProtectMixin = DecoratorMixin(csrf_protect) LoginRequiredMixin = DecoratorMixin(login_required) SensitivePostParametersMixin = DecoratorMixin(sensitive_post_parameters('password', 'old_password', 'password1', 'password2', 'new_password1', 'new_password2')) class AuthDecoratorsMixin(NeverCacheMixin, CsrfProtectMixin, SensitivePostParametersMixin): pass
class LoginView(SuccessURLAllowedHostsMixin, FormView): """ Display the login form and handle the login action. """ form_class = AuthenticationForm authentication_form = None redirect_field_name = REDIRECT_FIELD_NAME template_name = 'landing_page/index.html' redirect_authenticated_user = False extra_context = None @method_decorator(sensitive_post_parameters()) @method_decorator(csrf_protect) @method_decorator(never_cache) def dispatch(self, request, *args, **kwargs): if self.redirect_authenticated_user and self.request.user.is_authenticated: redirect_to = self.get_success_url() if redirect_to == self.request.path: raise ValueError( "Redirection loop for authenticated user detected. Check that " "your LOGIN_REDIRECT_URL doesn't point to a login page.") return HttpResponseRedirect(redirect_to) return super().dispatch(request, *args, **kwargs) def get_success_url(self): url = self.get_redirect_url() return url or resolve_url(settings.LOGIN_REDIRECT_URL) def get_redirect_url(self): """Return the user-originating redirect URL if it's safe.""" redirect_to = self.request.POST.get( self.redirect_field_name, self.request.GET.get(self.redirect_field_name, '')) url_is_safe = is_safe_url( url=redirect_to, allowed_hosts=self.get_success_url_allowed_hosts(), require_https=self.request.is_secure(), ) return redirect_to if url_is_safe else '' def get_form_class(self): return self.authentication_form or self.form_class def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs['request'] = self.request return kwargs def form_valid(self, form): """Security check complete. Log the user in.""" auth_login(self.request, form.get_user()) return HttpResponseRedirect(self.get_success_url()) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) current_site = get_current_site(self.request) active = "login" teachers = User.objects.filter(is_teacher=True).count() students = User.objects.filter(is_student=True).count() schools = School.objects.all().count() users = User.objects.all().count() context.update({ self.redirect_field_name: self.get_redirect_url(), 'site': current_site, 'site_name': current_site.name, **(self.extra_context or {}), 'active': active, 'meta_title': "African Fashion | Login", 'meta_tags': ["login", 'African fashion'], 'GOOGLE_RECAPTCHA_SITE_KEY': settings.GOOGLE_RECAPTCHA_SITE_KEY, "teachers": teachers, "students": students, "schools": schools, "users": users }) return context
""" def get_object(self, *args, **kwargs): """ Get the beta test application for the logged in user, if any. """ if self.request.user.is_authenticated: if hasattr(self.request.user, 'betatestapplication'): return self.request.user.betatestapplication application = BetaTestApplication() application.user = self.request.user return application return None @method_decorator( sensitive_post_parameters('password', 'password_confirmation'), name='post' ) class BetaTestApplicationView(BetaTestApplicationMixin, UpdateView): """ Display the beta test application form. """ template_name = 'registration/registration.html' form_class = BetaTestApplicationForm success_url = reverse_lazy('registration:register') @transaction.atomic def form_valid(self, form): """ If the form is valid, log the user in and send verification emails for the user's email address and the given public contact email. """
class Login(FormView): success_url = '/account/dashboard/0' form_class = LoginForm redirect_field_name = REDIRECT_FIELD_NAME template_name = "login.html" @method_decorator(sensitive_post_parameters('password')) @method_decorator(csrf_protect) @method_decorator(never_cache) def dispatch(self, request, *args, **kwargs): # Sets a test cookie to make sure the user has cookies enabled request.session.set_test_cookie() return super(Login, self).dispatch(request, *args, **kwargs) def form_valid(self, form): username = form.cleaned_data['username'] password = form.cleaned_data['password'] if self.kwargs['role'] == 0: user = authenticate(username=username, password=password) else: teacher = form.cleaned_data['teacher'] user = authenticate(username=teacher+"_"+username, password=password) if user is not None: auth_login(self.request, user) else : return redirect("/account/login/"+str(self.kwargs['role'])) if user.id == 1 and user.first_name == "": user.first_name = "管理員" user.save() # 學習領域 domains = ['生物'] for domain_name in domains: domain = Domain(title=domain_name) domain.save() levels = ['高一','高二','高三'] for level_name in levels: level = Level(title=level_name) level.save() zones = Zone.objects.all() if len(zones) == 0: for city_name, zones, mapx, mapy in county: city = County(name=city_name, mapx=mapx, mapy=mapy) city.save() for zone_name in zones: zone = Zone(name=zone_name, county=city.id) zone.save() school = School(county=2, zone=38, system=3, name="南港高中") school.save() user.last_name = "1" user.save() try : group = Group.objects.get(name="apply") except ObjectDoesNotExist : group = Group(name="apply") group.save() group.user_set.add(user) # create Message title = "請修改您的姓名" url = "/account/realname" message = Message(title=title, url=url, time=timezone.now()) message.save() # message for group member messagepoll = MessagePoll(message_id = message.id,reader_id=1) messagepoll.save() # 記錄訪客資訊 admin_user = User.objects.get(id=1) try: profile = Profile.objects.get(user=admin_user) except ObjectDoesNotExist: profile = Profile(user=admin_user) profile.save() profile.visitor_count = profile.visitor_count + 1 profile.save() year = localtime(timezone.now()).year month = localtime(timezone.now()).month day = localtime(timezone.now()).day date_number = year * 10000 + month*100 + day try: visitor = Visitor.objects.get(date=date_number) except ObjectDoesNotExist: visitor = Visitor(date=date_number) visitor.count = visitor.count + 1 visitor.save() visitorlog = VisitorLog(visitor_id=visitor.id, user_id=user.id, IP=self.request.META.get('REMOTE_ADDR')) visitorlog.save() # If the test cookie worked, go ahead and # delete it since its no longer needed if self.request.session.test_cookie_worked(): self.request.session.delete_test_cookie() return super(Login, self).form_valid(form) def get_success_url(self): redirect_to = self.request.GET.get(self.redirect_field_name) #if not is_safe_url(url=redirect_to, host=self.request.get_host()): # redirect_to = self.success_url return redirect_to def get_form_class(self): if self.kwargs['role'] == 0: return LoginForm else : return LoginStudentForm
from django.conf.urls import include, url from django.contrib import admin from django.views.decorators.debug import sensitive_post_parameters from views.user.sign import SignIn, SignUp, SignOut from views.timeline import BaseTimeline, UserTimeline, TagTimeline, TagUserTimeline from views.user.photo import EditPhoto, DeletePhoto urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url(r'^$', BaseTimeline.as_view(), name='index'), url(r'^tag/(?P<tag>[\w]+)/$', TagTimeline.as_view(), name='timeline-tag'), url(r'^user/(?P<username>[\w.@+-]+)/$', UserTimeline.as_view(), name='timeline-user'), url(r'^user/(?P<username>[\w.@+-]+)/tag/(?P<tag>[\w]+)/$', TagUserTimeline.as_view(), name='timeline-user-tag'), url(r'^photo/edit/(?P<photo_id>[\d]+)/$', EditPhoto.as_view(), name='photo-edit'), url(r'^photo/delete/(?P<photo_id>[\d]+)/$', DeletePhoto.as_view(), name='photo-delete'), url(r'^api/$', BaseTimeline.as_view(), {'type': 'api'}, name='api-index'), url(r'^api/tag/(?P<tag>[\w]+)/$', TagTimeline.as_view(), {'type': 'api'}, name='api-timeline-tag'), url(r'^api/user/(?P<username>[\w.@+-]+)/$', UserTimeline.as_view(), {'type': 'api'}, name='api-timeline-user'), url(r'^api/user/(?P<username>[\w.@+-]+)/tag/(?P<tag>[\w]+)/$', TagUserTimeline.as_view(), {'type': 'api'}, name='api-timeline-user-tag'), url(r'^login/$', sensitive_post_parameters()(SignIn.as_view()), name='user-sign-in'), url(r'^join/$', SignUp.as_view(), name='user-sign-up'), url(r'^logout/$', SignOut.as_view(), name='user-sign-out'), ]
class LoginView(View): """ Perform user authentication via the web UI. """ template_name = 'login.html' @method_decorator(sensitive_post_parameters('password')) def dispatch(self, *args, **kwargs): return super().dispatch(*args, **kwargs) def get(self, request): form = LoginForm(request) if request.user.is_authenticated: logger = logging.getLogger('netbox.auth.login') return self.redirect_to_next(request, logger) return render(request, self.template_name, { 'form': form, 'auth_backends': load_backends(settings.AUTHENTICATION_BACKENDS), }) def post(self, request): logger = logging.getLogger('netbox.auth.login') form = LoginForm(request, data=request.POST) if form.is_valid(): logger.debug("Login form validation was successful") # If maintenance mode is enabled, assume the database is read-only, and disable updating the user's # last_login time upon authentication. if get_config().MAINTENANCE_MODE: logger.warning("Maintenance mode enabled: disabling update of most recent login time") user_logged_in.disconnect(update_last_login, dispatch_uid='update_last_login') # Authenticate user auth_login(request, form.get_user()) logger.info(f"User {request.user} successfully authenticated") messages.info(request, "Logged in as {}.".format(request.user)) return self.redirect_to_next(request, logger) else: logger.debug("Login form validation failed") return render(request, self.template_name, { 'form': form, 'auth_backends': load_backends(settings.AUTHENTICATION_BACKENDS), }) def redirect_to_next(self, request, logger): if request.method == "POST": redirect_to = request.POST.get('next', settings.LOGIN_REDIRECT_URL) else: redirect_to = request.GET.get('next', settings.LOGIN_REDIRECT_URL) if redirect_to and not is_safe_url(url=redirect_to, allowed_hosts=request.get_host()): logger.warning(f"Ignoring unsafe 'next' URL passed to login form: {redirect_to}") redirect_to = reverse('home') logger.debug(f"Redirecting user to {redirect_to}") return HttpResponseRedirect(redirect_to)
__doc__ = decorator.__doc__ @classmethod def as_view(cls, *args, **kwargs): view = super(Mixin, cls).as_view(*args, **kwargs) return decorator(view) Mixin.__name__ = str("DecoratorMixin(%s)" % decorator.__name__) return Mixin NeverCacheMixin = DecoratorMixin(never_cache) CsrfProtectMixin = DecoratorMixin(csrf_protect) LoginRequiredMixin = DecoratorMixin(login_required) SensitivePostParametersMixin = DecoratorMixin( sensitive_post_parameters("password", "old_password", "password1", "password2", "new_password1", "new_password2") ) class AuthDecoratorsMixin(NeverCacheMixin, CsrfProtectMixin, SensitivePostParametersMixin): pass class LoginView(AuthDecoratorsMixin, WithCurrentSiteMixin, WithNextUrlMixin, FormView): form_class = AuthenticationForm template_name = "registration/login.html" disallow_authenticated = True success_url = resolve_url_lazy(settings.LOGIN_REDIRECT_URL) def dispatch(self, *args, **kwargs): if self.disallow_authenticated and self.request.user.is_authenticated():
class EmailVerifyConfirmView(generics.GenericAPIView): serializer_class = serializers.EmailVerifyConfirmSerializer permission_classes = (AllowAny, ) def post(self, request): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save() return Response({'detail': _('Email has been verified.')}) # Source: django-rest-auth v0.9.3 (https://github.com/Tivix/django-rest-auth) sensitive_post_parameters_m = method_decorator( sensitive_post_parameters('password', 'old_password', 'new_password1', 'new_password2')) # Source: django-rest-auth v0.9.3 (https://github.com/Tivix/django-rest-auth) class PasswordResetView(generics.GenericAPIView): serializer_class = serializers.PasswordResetSerializer permission_classes = (AllowAny, ) def post(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save() return Response({'detail': _('Password reset email has been sent.')}) # Source: django-rest-auth v0.9.3 (https://github.com/Tivix/django-rest-auth)
def login_decorator(func): return csrf_protect(never_cache(sensitive_post_parameters()(func)))
class UserAdmin(admin.ModelAdmin): list_display = ('get_name', 'email', 'get_date_joined', 'is_staff', 'is_superuser') list_filter = ('is_staff', 'is_superuser', 'profile__joined') search_fields = ('email', ) ordering = ('email', ) list_display_links = ('get_name', 'email') add_form = UserCreationForm fieldsets = ( (None, { 'fields': ('email', 'password') }), ('Permissions', { 'classes': ('collapse', ), 'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions') }), ('Important dates', { 'classes': ('collapse', ), 'fields': ('last_login', ) }), ) filter_horizontal = ( 'groups', 'user_permissions', ) add_fieldsets = ((None, { 'classes': ('wide', ), 'fields': ('name', 'email', 'password1', 'password2') }), ) change_password_form = AdminPasswordChangeForm change_user_password_template = 'admin/auth/user/change_password.html' form = UserChangeForm actions = ['make_staff'] def get_date_joined(self, user): return user.profile.joined get_date_joined.short_description = 'Joined' get_date_joined.admin_order_field = 'profile__joined' def get_name(self, user): return user.profile.name get_name.short_description = 'Name' get_name.admin_order_field = 'profile__name' def get_form(self, request, obj=None, **kwargs): if obj is None: kwargs['form'] = self.add_form return super().get_form(request, obj, **kwargs) def get_fieldsets(self, request, obj=None): if not obj: return self.add_fieldsets return super().get_fieldsets(request, obj) def get_urls(self): password_change = [ url(r'^(.+)/password/$', self.admin_site.admin_view(self.user_change_password), name='auth_user_password_change'), ] urls = super().get_urls() urls = password_change + urls return urls @method_decorator(sensitive_post_parameters()) def user_change_password(self, request, user_id, form_url=''): if not self.has_change_permission(request): raise PermissionDenied user = self.get_object(request, unquote(user_id)) if user is None: raise Http404('{name} object with primary key ' '{key} does not exist.'.format(name=force_text( self.model._meta.verbose_name), key=escape(user_id))) if request.method == 'POST': form = self.change_password_form(user, request.POST) if form.is_valid(): form.save() change_message = (self.construct_change_message( request, form, None)) self.log_change(request, user, change_message) success(request, 'Password changed.') update_session_auth_hash(request, form.user) return HttpResponseRedirect('..') else: form = self.change_password_form(user) context = { 'title': 'Change password:{}'.format(escape(user.get_username())), 'form_url': form_url, 'form': form, 'is_popup': (IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET), 'opts': self.model._meta, 'original': user, } context.update(admin.site.each_context(request)) request.current_app = self.admin_site.name return TemplateResponse(request, self.change_user_password_template, context) def get_inline_instances(self, request, obj=None): if obj is None: return tuple() inline_instance = ProfileAdminInline(self.model, self.admin_site) return (inline_instance, ) def make_staff(self, request, queryset): rows_updated = queryset.update(is_staff=True) if rows_updated == 1: message = '1 user was' else: message = '{} users were'.format(rows_updated) message += ' successfully made staff.' self.message_user(request, message) make_staff.short_description = 'Allow user to access Admin Site.'
passthrough_next_redirect_url, url_str_to_user_pk) from .forms import AddEmailForm, ChangePasswordForm from .forms import LoginForm, ResetPasswordKeyForm from .forms import ResetPasswordForm, SetPasswordForm, SignupForm from .utils import sync_user_email_addresses from .models import EmailAddress, EmailConfirmation from . import signals from . import app_settings from .adapter import get_adapter sensitive_post_parameters_m = method_decorator( sensitive_post_parameters('password', 'password1', 'password2')) def _ajax_response(request, response, form=None): if request.is_ajax(): if (isinstance(response, HttpResponseRedirect) or isinstance(response, HttpResponsePermanentRedirect)): redirect_to = response['Location'] else: redirect_to = None response = get_adapter().ajax_response(request, response, form=form, redirect_to=redirect_to) return response
class DoExpressCheckout(TemplateView): template_name = 'shopping/paypal/cancel.html' @method_decorator(sensitive_post_parameters()) @method_decorator(csrf_protect) @method_decorator(never_cache) def post(self, request, *args, **kwargs): if getattr(settings, 'UNIT_TESTING', False): return confirm_checkout(request, signature=request.session['signature'], *args, **kwargs) service = get_service_instance() paypal = json.loads(PaymentMean.objects.get(slug='paypal').credentials) order_id = request.POST['order_id'] order = Order.objects.get(pk=order_id) line_items = {} for i in range(len(order.album_list)): album = order.album_list[i] line_items.update({ "L_PAYMENTREQUEST_0_NAME%d" % i: album.title, "L_PAYMENTREQUEST_0_DESC%d" % i: album.title, "L_PAYMENTREQUEST_0_AMT%d" % i: do_currency(album.cost, order.currency.code), "L_PAYMENTREQUEST_0_QTY%d" % i: 1, "L_PAYMENTREQUEST_0_TAXAMT%d" % i: 0, "L_PAYMENTREQUEST_0_NUMBER%d" % i: i + 1, "L_PAYMENTREQUEST_0_ITEMURL%d" % i: service.url + reverse('mediashop:music_item_detail', args=( album.artist.slug, album.slug, )), "L_PAYMENTREQUEST_0_ITEMCATEGORY%d" % i: 'Digital' }) for i in range(len(order.song_list)): song = order.song_list[i] line_items.update({ "L_PAYMENTREQUEST_0_NAME%d" % i: song.title, "L_PAYMENTREQUEST_0_DESC%d" % i: song.title, "L_PAYMENTREQUEST_0_AMT%d" % i: do_currency(song.cost, order.currency.code), "L_PAYMENTREQUEST_0_QTY%d" % i: 1, "L_PAYMENTREQUEST_0_TAXAMT%d" % i: 0, "L_PAYMENTREQUEST_0_NUMBER%d" % i: i + 1, "L_PAYMENTREQUEST_0_ITEMURL%d" % i: service.url + reverse('mediashop:music_item_detail', args=( song.artist.slug, song.slug, )), "L_PAYMENTREQUEST_0_ITEMCATEGORY%d" % i: 'Digital' }) ec_data = { "USER": paypal['username'], "PWD": paypal['password'], "SIGNATURE": paypal['signature'], "METHOD": "DoExpressCheckoutPayment", "VERSION": 124.0, "TOKEN": request.session['token'], "PAYERID": request.session['payer_id'], "PAYMENTREQUEST_0_PAYMENTACTION": "Sale", "PAYMENTREQUEST_0_AMT": do_currency(order.total_cost, order.currency.code), "PAYMENTREQUEST_0_ITEMAMT": do_currency(order.total_cost, order.currency.code), "PAYMENTREQUEST_0_SHIPPINGAMT": 0, "PAYMENTREQUEST_0_TAXAMT": 0, "PAYMENTREQUEST_0_CURRENCYCODE": order.currency.code, "PAYMENTREQUEST_0_DESC": "Purchase on " + service.project_name } ec_data.update(line_items) if getattr(settings, 'DEBUG', False): response = requests.post(EC_ENDPOINT, data=ec_data) result = parse_paypal_response(response.content.decode('utf-8')) ACK = result['ACK'] if ACK == 'Success' or ACK == 'SuccessWithWarning': return confirm_checkout(request, signature=request.session['signature'], *args, **kwargs) else: try: Order.objects.get(pk=request.POST['order_id']).delete() except Order.DoesNotExist: pass context = self.get_context_data(**kwargs) if getattr(settings, 'DEBUG', False): context['paypal_error'] = urlunquote( response.content.decode('utf-8')) else: context['paypal_error'] = urlunquote( result['L_LONGMESSAGE0']) messages.error( request, 'API Error: Terminating PayPal transaction failed.') return HttpResponseRedirect(reverse('mediashop:cart')) else: try: response = requests.post(EC_ENDPOINT, data=ec_data) result = parse_paypal_response( response.content.decode('utf-8')) ACK = result['ACK'] if ACK == 'Success' or ACK == 'SuccessWithWarning': return confirm_checkout( request, signature=request.session['signature'], *args, **kwargs) else: try: Order.objects.get(pk=request.POST['order_id']).delete() except Order.DoesNotExist: pass context = self.get_context_data(**kwargs) if getattr(settings, 'DEBUG', False): context['paypal_error'] = urlunquote( response.content.decode('utf-8')) else: context['paypal_error'] = urlunquote( result['L_LONGMESSAGE0']) messages.error( request, 'API Error: Terminating PayPal transaction failed.') return HttpResponseRedirect(reverse('mediashop:cart')) except Exception as e: logger.error("%s - PayPal error. Order ID: %s" % (service.project_name, order.id), exc_info=True) messages.error( request, 'Could not terminate transaction due to server error. Contact administrator.' ) return HttpResponseRedirect(reverse('mediashop:cart'))
from django.contrib import admin from django.contrib.auth.admin import UserAdmin as ContribUserAdmin from django.utils.translation import ugettext_lazy as _ from django.utils.decorators import method_decorator from django.views.decorators.debug import sensitive_post_parameters from .forms import * # from .models import User, Organization from reversion.admin import VersionAdmin from django_inline_wrestler.admin import TabularInlineOrderable from carbon.atoms.admin.content import BaseVersionableAdmin, BaseVersionableTitleAdmin sensitive_post_parameters_m = method_decorator(sensitive_post_parameters()) class UserAdmin(ContribUserAdmin): def preview(self, obj): if obj.image: try: return mark_safe("<img src='%s' alt='%s preview'/>"%(obj.image.thumbnail_url, obj.image.title)) except: return "" return '' autocomplete_lookup_fields = { 'fk': ['image',], } raw_id_fields = ('image',)
class LoginView(GenericAPIView): serializer_class = serializers.LoginSerializer permission_classes = (AllowAny,) def post(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save() return Response( {"detail": _("Login code has been sent.")}, status=status.HTTP_200_OK ) @method_decorator(sensitive_post_parameters('code'), 'dispatch') class LoginCodeView(GenericAPIView): permission_classes = (AllowAny,) serializer_class = serializers.LoginCodeSerializer token_serializer_class = serializers.TokenSerializer token_model = Token def process_login(self): django_login(self.request, self.user) def login(self): self.user = self.serializer.validated_data['user'] self.token, created = self.token_model.objects.get_or_create(user=self.user) if getattr(settings, 'REST_SESSION_LOGIN', True): self.process_login()