Esempio n. 1
0
    def dispatch_to_register():
        """Force user creation on login or register"""

        request = strategy.request
        data['terms_of_service'] = True
        data['honor_code'] = True
        data['password'] = make_random_password()
        # force name creation if it is empty in sso-profile
        data['name'] = ' '.join([data.get('firstname', ''),
                                 data.get('lastname', '')]).strip() or data['username']
        data['provider'] = backend.name

        if request.session.get('ExternalAuthMap'):
            del request.session['ExternalAuthMap']

        try:
            user = User.objects.get(email=data['email'])
        except User.DoesNotExist:
            create_account_with_params(request, data)
            user = request.user
            user.first_name = data.get('firstname')
            user.last_name = data.get('lastname')
            user.is_active = True
            user.save()

        return {'user': user}
Esempio n. 2
0
    def dispatch_to_register():
        """Force user creation on login or register"""

        request = strategy.request
        data['terms_of_service'] = True
        data['honor_code'] = True
        data['password'] = make_random_password()
        # force name creation if it is empty in sso-profile
        data['name'] = ' '.join([data['firstname'], data['lastname']
                                 ]).strip() or data['username']
        data['provider'] = backend.name

        if request.session.get('ExternalAuthMap'):
            del request.session['ExternalAuthMap']

        try:
            user = User.objects.get(email=data['email'])
        except User.DoesNotExist:
            try:
                create_account_with_params(request, data)
            except AccountValidationError:
                data['username'] = data['email']
                create_account_with_params(request, data)
            user = request.user
            user.is_active = True
            user.set_unusable_password()
            user.save()

        del data['password']

        return {'user': user}
Esempio n. 3
0
    def dispatch_to_register():
        """Redirects to the registration page."""

        request = strategy.request
        data = kwargs['response']
        data['terms_of_service'] = True
        data['honor_code'] = True
        data['password'] = '******'
        data['name'] = ' '.join([data['firstname'], data['lastname']])
        data['provider'] = backend.name

        if request.session.get('ExternalAuthMap'):
            del request.session['ExternalAuthMap']
        if User.objects.filter(email=data['email']).exists():
            return redirect(AUTH_DISPATCH_URLS[AUTH_ENTRY_LOGIN])

        create_account_with_params(request, data)
        user = request.user
        user.is_active = True
        user.save()
        set_logged_in_cookies(request, JsonResponse({"success": True}))

        # add roles for User
        add_user_roles(user, data['permissions'])

        return redirect(AUTH_DISPATCH_URLS[AUTH_ENTRY_LOGIN])
Esempio n. 4
0
    def dispatch_to_register():
        """Force user creation on login or register"""

        request = strategy.request
        data['terms_of_service'] = "True"
        data['honor_code'] = 'True'
        data['password'] = make_random_password()

        data['provider'] = backend.name

        if request.session.get('ExternalAuthMap'):
            del request.session['ExternalAuthMap']

        try:
            user = User.objects.get(email=data['email'])
        except User.DoesNotExist:
            create_account_with_params(request, data)
            user = request.user
            user.first_name = data['first_name']
            user.last_name = data['last_name']
            user.is_active = True
            user.save()
            CourseCreator.objects.get_or_create(
                user=user,
                state=CourseCreator.UNREQUESTED
            )
        return {'user': user}
    def dispatch_to_register():
        """Force user creation on login or register"""

        request = strategy.request
        data['terms_of_service'] = "True"
        data['honor_code'] = 'True'
        data['password'] = make_random_password()

        data['provider'] = backend.name

        if request.session.get('ExternalAuthMap'):
            del request.session['ExternalAuthMap']

        try:
            user = User.objects.get(email=data['email'])
        except User.DoesNotExist:
            create_account_with_params(request, data)
            user = request.user
            user.first_name = data['first_name']
            user.last_name = data['last_name']
            user.is_active = True
            user.save()
            CourseCreator.objects.get_or_create(
                user=user, state=CourseCreator.UNREQUESTED)
        return {'user': user}
Esempio n. 6
0
    def create_user(self, *args, **kwargs):
        """
        # Creates user using information provided by pipeline. This method is called in create_user pipeline step.
        # Unless the workflow is changed, create_user immediately terminates if the user already found/
        # So far, user is either created in ensure_user_information via registration form or account needs to be
        # autoprovisioned. So, this method is only called when autoprovisioning account.
        """
        from student.views import create_account_with_params
        from .pipeline import make_random_password

        user_fields = dict(kwargs)
        # needs to be >2 chars to pass validation
        name = self._ensure_passes_length_check(
            user_fields, 'fullname', self.setting("THIRD_PARTY_AUTH_FALLBACK_FULL_NAME")
        )
        password = self._ensure_passes_length_check(user_fields, 'password', make_random_password())

        user_fields['name'] = name
        user_fields['password'] = password
        user_fields['honor_code'] = True
        user_fields['terms_of_service'] = True

        if not user_fields.get('email'):
            user_fields['email'] = "{username}@{domain}".format(
                username=user_fields['username'], domain=self.setting("FAKE_EMAIL_DOMAIN")
            )

        # when autoprovisioning we need to skip email activation, hence skip_email is True
        return create_account_with_params(self.request, user_fields, skip_email=True)
Esempio n. 7
0
    def dispatch_to_register():
        """Redirects to the registration page."""

        request = strategy.request
        data = kwargs['response']
        data['terms_of_service'] = True
        data['honor_code'] = True
        data['password'] = '******'
        data['name'] = ' '.join([data['firstname'], data['lastname']])
        data['provider'] = backend.name

        if request.session.get('ExternalAuthMap'):
            del request.session['ExternalAuthMap']

        create_account_with_params(request, data)
        user = request.user
        user.is_active = True
        user.save()
        set_logged_in_cookies(request, JsonResponse({"success": True}))
        return redirect(AUTH_DISPATCH_URLS[AUTH_ENTRY_LOGIN])
Esempio n. 8
0
    def dispatch_to_register():
        """Force user creation on login or register"""

        request = strategy.request
        data["terms_of_service"] = True
        data["honor_code"] = True
        data["password"] = make_random_password()
        # force name creation if it is empty in sso-profile
        data["name"] = " ".join([data.get("firstname", ""), data.get("lastname", "")]).strip() or data["username"]
        data["provider"] = backend.name

        if request.session.get("ExternalAuthMap"):
            del request.session["ExternalAuthMap"]

        try:
            user = User.objects.get(email=data["email"])
        except User.DoesNotExist:
            create_account_with_params(request, data)
            user = request.user
            user.is_active = True
            user.save()

        return {"user": user}
Esempio n. 9
0
    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":
                _(
                    # Translators: This message is shown to users who attempt to create a new
                    # account using an email address associated with an existing account.
                    u"It looks like {email_address} belongs to an existing account. "
                    u"Try again with a different email address.").format(
                        email_address=email),
                "username":
                _(
                    # Translators: This message is shown to users who attempt to create a new
                    # account using a username associated with an existing account.
                    u"It looks like {username} belongs to an existing account. "
                    u"Try again with a different username.").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 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
Esempio n. 10
0
    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
        """
        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": _(
                    # Translators: This message is shown to users who attempt to create a new
                    # account using an email address associated with an existing account.
                    u"It looks like {email_address} belongs to an existing account. "
                    u"Try again with a different email address."
                ).format(email_address=email),
                "username": _(
                    # Translators: This message is shown to users who attempt to create a new
                    # account using a username associated with an existing account.
                    u"It looks like {username} belongs to an existing account. "
                    u"Try again with a different username."
                ).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 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)

        response = JsonResponse({"success": True})
        set_logged_in_cookies(request, response, user)
        return response
Esempio n. 11
0
    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
        """
        import logging
        import datetime
        LOGGER = logging.getLogger(__name__)
        start_time = datetime.datetime.now()

        data = request.POST.copy()
        email = data.get('email')
        username = data.get('username')
        LOGGER.info(
            "*************** Request received for registration Username = {username}. Start time {start_time}: **************"
            .format(username=username, start_time=start_time))

        # 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
            }
            LOGGER.info(
                "*************** Registration failed for Username. Error: Username and email conflicts **************"
                .format(username=username))
            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": text_type(err)}]}
            LOGGER.info(
                "*************** Registration failed for Username = {username}. Error: {error} **************"
                .format(username=username, error=err))
            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()
            }
            LOGGER.info(
                "*************** Registration failed for Username = {username}. Error: {error} **************"
                .format(username=username, error=err))
            return JsonResponse(errors, status=400)
        except PermissionDenied:
            LOGGER.info(
                "*************** Registration failed for Username. Error: PermissionDenied **************"
                .format(username=username))
            return HttpResponseForbidden(_("Account creation not allowed."))

        except Exception as err:
            LOGGER.exception(
                "*************** Registration failed for Username = {username}. Error: {error}"
                .format(username=username, error=err))

        response = JsonResponse({"success": True})
        set_logged_in_cookies(request, response, user)
        end_time = datetime.datetime.now()
        LOGGER.info(
            "*************** Request completed for registration Username = {username}. End time: {end_time} **************"
            .format(username=username, end_time=end_time))
        time_diff = end_time - start_time
        LOGGER.info(
            "*************** Time Difference for User = {username}:  {time_diff} **************"
            .format(username=username, time_diff=time_diff))

        return response
Esempio n. 12
0
    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": text_type(err)}]
            }
            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
Esempio n. 13
0
def ensure_user_information(
        strategy, auth_entry, backend=None, user=None, social=None, allow_inactive_user=False, *args, **kwargs
):
    """
    Ensure that we have the necessary information about a user to proceed with the pipeline.

    Either an existing account or registration data.
    """

    data = {}
    try:
        if 'data' in kwargs['response']:
            user_data = kwargs['response']['data'][0]
        else:
            user_data = kwargs['response']
        log.info('Get user data: %s', str(user_data))
        access_token = kwargs['response']['access_token']

        country = user_data.get('country')
        if not country:
            log.info('No country in response.')

        # Received fields could be pretty different from the expected, mandatory are only 'username' and 'email'
        data['username'] = user_data.get('username', user_data.get('name'))
        data['first_name'] = user_data.get('firstName', user_data.get('first_name'))
        data['last_name'] = user_data.get('lastName', user_data.get('last_name'))
        data['email'] = user_data.get('email')
        data['country'] = country
        data['access_token'] = access_token
        if any((data['first_name'], data['last_name'])):
            data['name'] = '{} {}'.format(['first_name'], data['last_name']).strip()
        else:
            data['name'] = user_data.get('username')
        if not all((data['username'], data['email'])):
            raise AuthEntryError(
                backend,
                "One of the required parameters (username or email) is not received with the user data."
            )
    except AuthEntryError as e:
        log.exception(e)
        raise
    except Exception as e:
        log.exception(e)
        raise AuthEntryError(backend, "Cannot receive user's data")

    if not user:
        request = strategy.request
        data['terms_of_service'] = "True"
        data['honor_code'] = 'True'
        data['password'] = make_random_password()

        data['provider'] = backend.name

        try:
            user = User.objects.get(email=data['email'])
        except User.DoesNotExist:
            create_account_with_params(request, data)
            user.is_active = True
            user.save()

    return {'user': user}
Esempio n. 14
0
    def create(self, request):
        """Creates a new user account for the site that calls this view
        To use, perform a token authenticated POST to the URL::
            /tahoe/api/v1/registrations/
        Required arguments (JSON data):
            "username"
            "email"
            "name"
        Optional arguments:
            "password"
            "send_activation_email"
        Returns:
            HttpResponse: 200 on success, {"user_id ": 9}
            HttpResponse: 400 if the request is not valid.
            HttpResponse: 409 if an account with the given username or email
                address already exists
        The code here is adapted from the LMS ``appsembler_api`` bulk registration
        code. See the ``appsembler/ginkgo/master`` branch
        """
        data = request.data
        password_provided = 'password' in data

        # set the honor_code and honor_code like checked,
        # so we can use the already defined methods for creating an user
        data['honor_code'] = "True"
        data['terms_of_service'] = "True"

        if password_provided:
            if 'send_activation_email' in data and data[
                    'send_activation_email'] == "False":
                data['send_activation_email'] = False
            else:
                data['send_activation_email'] = True
        else:
            data['password'] = create_password()
            data['send_activation_email'] = False

        email = request.data.get('email')
        username = request.data.get('username')

        # Handle duplicate email/username
        conflicts = check_account_exists(email=email, username=username)
        if conflicts:
            errors = {"user_message": "User already exists"}
            return Response(errors, status=409)

        try:
            user = create_account_with_params(
                request=request,
                params=data,
                send_activation_email_flag=data['send_activation_email'])
            # set the user as active if password is provided
            # meaning we don't have to send a password reset email
            user.is_active = password_provided
            user.save()
            user_id = user.id
            if not password_provided:
                success = send_password_reset_email(request)
                if not success:
                    log.error('Tahoe Reg API: Error sending password reset '
                              'email to user {}'.format(user.username))
        except ValidationError as err:
            log.error('ValidationError. err={}'.format(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

            # TODO: Let's give a clue as to which are the error causing fields
            errors = {"user_message": "Invalid parameters on user creation"}
            return Response(errors, status=400)
        return Response({'user_id ': user_id}, status=200)
Esempio n. 15
0
    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()

        # Decrypt form data if it is encrypted
        if 'data_token' in request.POST:
            data_token = request.POST.get('data_token')

            try:
                decoded_data = jwt.decode(
                    data_token,
                    settings.EDRAAK_LOGISTRATION_SECRET_KEY,
                    verify=False,
                    algorithms=[
                        settings.EDRAAK_LOGISTRATION_SIGNING_ALGORITHM
                    ])
                data.update(decoded_data)

            except jwt.ExpiredSignatureError:
                err_msg = u"The provided data_token has been expired"
                log.warning(err_msg)

                return JsonResponse({
                    "success": False,
                    "value": err_msg,
                },
                                    status=400)

            except jwt.DecodeError:
                err_msg = u"Signature verification failed"
                log.warning(err_msg)

                return JsonResponse({
                    "success": False,
                    "value": err_msg,
                },
                                    status=400)

            except (jwt.InvalidTokenError, ValueError):
                err_msg = u"Invalid token"
                log.warning(err_msg)

                return JsonResponse({
                    "success": False,
                    "value": err_msg,
                },
                                    status=400)

        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": text_type(err)}]}
            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