示例#1
0
    def handle(self, *args, **options):
        username = options['username']
        name = options['name']
        if not username:
            username = options['email'].split('@')[0]
        if not name:
            name = options['email'].split('@')[0]

        post_data = {
            'username': username,
            'email': options['email'],
            'password': options['password'],
            'name': name,
            'honor_code': u'true',
            'terms_of_service': u'true',
        }
        # django.utils.translation.get_language() will be used to set the new
        # user's preferred language.  This line ensures that the result will
        # match this installation's default locale.  Otherwise, inside a
        # management command, it will always return "en-us".
        translation.activate(settings.LANGUAGE_CODE)
        try:
            user, profile, reg = _do_create_account(post_data)
            if options['staff']:
                user.is_staff = True
                user.save()
            reg.activate()
            reg.save()
            create_comments_service_user(user)
        except AccountValidationError as e:
            print e.message
            user = User.objects.get(email=options['email'])
        if options['course']:
            CourseEnrollment.enroll(user, options['course'], mode=options['mode'])
        translation.deactivate()
示例#2
0
    def create_user_by_data(self, user_data):
        """
        Create the user by the Django model
        """
        from student.forms import AccountCreationForm
        from student.helpers import do_create_account

        # Check and remove email if its already registered

        if User.objects.filter(email=user_data['email']).exists():
            user_data['email'] = str(uuid.uuid4()) + '@invalid.invalid'

        form = AccountCreationForm(
            data={
                "username": self.generate_username(user_data),
                "email": user_data['email'],
                "password": "******",  # Temporary password
                "name": user_data['nombreCompleto'],
            },
            tos_required=False,
        )

        user, _, reg = do_create_account(form)
        reg.activate()
        reg.save()
        from student.models import create_comments_service_user
        create_comments_service_user(user)

        # Invalidate the user password, as it will be never be used
        user.set_unusable_password()
        user.save()

        return user
示例#3
0
    def handle(self, *args, **options):
        username = options['username']
        name = options['name']
        if not username:
            username = options['email'].split('@')[0]
        if not name:
            name = options['email'].split('@')[0]

        post_data = {
            'username': username,
            'email': options['email'],
            'password': options['password'],
            'name': name,
            'honor_code': u'true',
            'terms_of_service': u'true',
        }
        try:
            user, profile, reg = _do_create_account(post_data)
            if options['staff']:
                user.is_staff = True
                user.save()
            reg.activate()
            reg.save()
            create_comments_service_user(user)
        except AccountValidationError as e:
            print e.message
            user = User.objects.get(email=options['email'])
        if options['course']:
            CourseEnrollment.enroll(user,
                                    options['course'],
                                    mode=options['mode'])
示例#4
0
    def handle(self, *args, **options):
        username = options['username']
        name = options['name']
        if not username:
            username = options['email'].split('@')[0]
        if not name:
            name = options['email'].split('@')[0]

        post_data = {
            'username': username,
            'email': options['email'],
            'password': options['password'],
            'name': name,
            'honor_code': u'true',
            'terms_of_service': u'true',
        }
        try:
            user, profile, reg = _do_create_account(post_data)
            if options['staff']:
                user.is_staff = True
                user.save()
            reg.activate()
            reg.save()
            create_comments_service_user(user)
        except AccountValidationError as e:
            print e.message
            user = User.objects.get(email=options['email'])
        if options['course']:
            CourseEnrollment.enroll(user, options['course'], mode=options['mode'])
示例#5
0
def register_user_from_mobile_request(request, user_data):
    params = user_data.copy()
    params = _add_extras_in_params(params)
    extra_fields = configuration_helpers.get_value(
        'REGISTRATION_EXTRA_FIELDS',
        getattr(settings, 'REGISTRATION_EXTRA_FIELDS', {})
    )

    params["password"] = generate_password()

    extended_profile_fields = configuration_helpers.get_value('extended_profile_fields', [])

    registration_fields = getattr(settings, 'REGISTRATION_EXTRA_FIELDS', {})
    tos_required = (
       registration_fields.get('terms_of_service') != 'hidden' or
       registration_fields.get('honor_code') != 'hidden'
    )

    form = AccountCreationForm(
        data=params,
        extra_fields=extra_fields,
        extended_profile_fields=extended_profile_fields,
        do_third_party_auth=False,
        tos_required=tos_required,
    )
    custom_form = get_registration_extension_form(data=params)

    (user, profile, registration) = do_create_account(form, custom_form, True)

    new_user = authenticate_new_user(request, user.username, params['password'])

    registration.activate()

    # Perform operations that are non-critical parts of account creation
    create_or_set_user_attribute_created_on_site(user, request.site)

    preferences_api.set_user_preference(user, LANGUAGE_KEY, get_language())

    if settings.FEATURES.get('ENABLE_DISCUSSION_EMAIL_DIGEST'):
        try:
            enable_notifications(user)
        except Exception:  # pylint: disable=broad-except
            LOGGER.exception("Enable discussion notifications failed for user {id}.".format(id=user.id))

    # Announce registration
    REGISTER_USER.send(sender=None, user=user, registration=registration)

    create_comments_service_user(user)

    return new_user
示例#6
0
def create_user_from_oauth(strategy, details, user, is_new, *args, **kwargs):
    if is_new:
        profile = UserProfile(user=user)
        profile.name = details.get('fullname')

        try:
            profile.save()
        except Exception:
            log.error("UserProfile creation failed for user {id}.".format(id=user.id))
            raise

        ceas = CourseEnrollmentAllowed.objects.filter(email=user.email)
        for cea in ceas:
            if cea.auto_enroll:
                CourseEnrollment.enroll(user, cea.course_id)

        create_comments_service_user(user)
示例#7
0
    def handle(self, *args, **options):
        username = options['username']
        name = options['name']
        if not username:
            username = options['email'].split('@')[0]
        if not name:
            name = options['email'].split('@')[0]

        # parse out the course into a coursekey
        if options['course']:
            try:
                course = CourseKey.from_string(options['course'])
            # if it's not a new-style course key, parse it from an old-style
            # course key
            except InvalidKeyError:
                course = SlashSeparatedCourseKey.from_deprecated_string(options['course'])

        form = AccountCreationForm(
            data={
                'username': username,
                'email': options['email'],
                'password': options['password'],
                'name': name,
            },
            tos_required=False
        )
        # django.utils.translation.get_language() will be used to set the new
        # user's preferred language.  This line ensures that the result will
        # match this installation's default locale.  Otherwise, inside a
        # management command, it will always return "en-us".
        translation.activate(settings.LANGUAGE_CODE)
        try:
            user, _, reg = _do_create_account(form)
            if options['staff']:
                user.is_staff = True
                user.save()
            reg.activate()
            reg.save()
            create_comments_service_user(user)
        except AccountValidationError as e:
            print e.message
            user = User.objects.get(email=options['email'])
        if options['course']:
            CourseEnrollment.enroll(user, course, mode=options['mode'])
        translation.deactivate()
    def handle(self, *args, **options):
        username = options['username'] if options['username'] else options['email'].split('@')[0]
        name = options['proper_name'] if options['proper_name'] else options['email'].split('@')[0]

        # parse out the course into a coursekey
        course = CourseKey.from_string(options['course']) if options['course'] else None

        form = AccountCreationForm(
            data={
                'username': username,
                'email': options['email'],
                'password': options['password'],
                'name': name,
            },
            tos_required=False
        )

        # django.utils.translation.get_language() will be used to set the new
        # user's preferred language.  This line ensures that the result will
        # match this installation's default locale.  Otherwise, inside a
        # management command, it will always return "en-us".
        translation.activate(settings.LANGUAGE_CODE)

        try:
            user, _, reg = do_create_account(form)
            if options['staff']:
                user.is_staff = True
                user.save()
            reg.activate()
            reg.save()
            create_comments_service_user(user)
        except AccountValidationError as e:
            print(text_type(e))
            user = User.objects.get(email=options['email'])

        if course:
            CourseEnrollment.enroll(user, course, mode=options['mode'])

        translation.deactivate()
示例#9
0
def create_account_with_params(request, params):
    """
    Given a request and a dict of parameters (which may or may not have come
    from the request), create an account for the requesting user, including
    creating a comments service user object and sending an activation email.
    This also takes external/third-party auth into account, updates that as
    necessary, and authenticates the user for the request's session.

    Does not return anything.

    Raises AccountValidationError if an account with the username or email
    specified by params already exists, or ValidationError if any of the given
    parameters is invalid for any other reason.

    Issues with this code:
    * It is non-transactional except where explicitly wrapped in atomic to
      alleviate deadlocks and improve performance. This means failures at
      different places in registration can leave users in inconsistent
      states.
    * Third-party auth passwords are not verified. There is a comment that
      they are unused, but it would be helpful to have a sanity check that
      they are sane.
    * The user-facing text is rather unfriendly (e.g. "Username must be a
      minimum of two characters long" rather than "Please use a username of
      at least two characters").
    * Duplicate email raises a ValidationError (rather than the expected
      AccountValidationError). Duplicate username returns an inconsistent
      user message (i.e. "An account with the Public Username '{username}'
      already exists." rather than "It looks like {username} belongs to an
      existing account. Try again with a different username.") The two checks
      occur at different places in the code; as a result, registering with
      both a duplicate username and email raises only a ValidationError for
      email only.
    """
    # Copy params so we can modify it; we can't just do dict(params) because if
    # params is request.POST, that results in a dict containing lists of values
    params = dict(params.items())

    # allow to define custom set of required/optional/hidden fields via configuration
    extra_fields = configuration_helpers.get_value(
        'REGISTRATION_EXTRA_FIELDS',
        getattr(settings, 'REGISTRATION_EXTRA_FIELDS', {})
    )
    # registration via third party (Google, Facebook) using mobile application
    # doesn't use social auth pipeline (no redirect uri(s) etc involved).
    # In this case all related info (required for account linking)
    # is sent in params.
    # `third_party_auth_credentials_in_api` essentially means 'request
    # is made from mobile application'
    third_party_auth_credentials_in_api = 'provider' in params
    is_third_party_auth_enabled = third_party_auth.is_enabled()

    if is_third_party_auth_enabled and (pipeline.running(request) or third_party_auth_credentials_in_api):
        params["password"] = generate_password()

    # in case user is registering via third party (Google, Facebook) and pipeline has expired, show appropriate
    # error message
    if is_third_party_auth_enabled and ('social_auth_provider' in params and not pipeline.running(request)):
        raise ValidationError(
            {'session_expired': [
                _(u"Registration using {provider} has timed out.").format(
                    provider=params.get('social_auth_provider'))
            ]}
        )

    do_external_auth, eamap = pre_account_creation_external_auth(request, params)

    extended_profile_fields = configuration_helpers.get_value('extended_profile_fields', [])
    # Can't have terms of service for certain SHIB users, like at Stanford
    registration_fields = getattr(settings, 'REGISTRATION_EXTRA_FIELDS', {})
    tos_required = (
        registration_fields.get('terms_of_service') != 'hidden' or
        registration_fields.get('honor_code') != 'hidden'
    ) and (
        not settings.FEATURES.get("AUTH_USE_SHIB") or
        not settings.FEATURES.get("SHIB_DISABLE_TOS") or
        not do_external_auth or
        not eamap.external_domain.startswith(settings.SHIBBOLETH_DOMAIN_PREFIX)
    )

    form = AccountCreationForm(
        data=params,
        extra_fields=extra_fields,
        extended_profile_fields=extended_profile_fields,
        do_third_party_auth=do_external_auth,
        tos_required=tos_required,
    )
    custom_form = get_registration_extension_form(data=params)

    # Perform operations within a transaction that are critical to account creation
    with outer_atomic(read_committed=True):
        # first, create the account
        (user, profile, registration) = do_create_account(form, custom_form)

        third_party_provider, running_pipeline = _link_user_to_third_party_provider(
            is_third_party_auth_enabled, third_party_auth_credentials_in_api, user, request, params,
        )

        new_user = authenticate_new_user(request, user.username, params['password'])
        django_login(request, new_user)
        request.session.set_expiry(0)

        post_account_creation_external_auth(do_external_auth, eamap, new_user)

    # Check if system is configured to skip activation email for the current user.
    skip_email = _skip_activation_email(
        user, do_external_auth, running_pipeline, third_party_provider,
    )

    if skip_email:
        registration.activate()
    else:
        compose_and_send_activation_email(user, profile, registration)

    # Perform operations that are non-critical parts of account creation
    create_or_set_user_attribute_created_on_site(user, request.site)

    preferences_api.set_user_preference(user, LANGUAGE_KEY, get_language())

    if settings.FEATURES.get('ENABLE_DISCUSSION_EMAIL_DIGEST'):
        try:
            enable_notifications(user)
        except Exception:  # pylint: disable=broad-except
            log.exception("Enable discussion notifications failed for user {id}.".format(id=user.id))

    dog_stats_api.increment("common.student.account_created")

    _track_user_registration(user, profile, params, third_party_provider)

    # Announce registration
    REGISTER_USER.send(sender=None, user=user, registration=registration)

    create_comments_service_user(user)

    try:
        _record_registration_attributions(request, new_user)
    # Don't prevent a user from registering due to attribution errors.
    except Exception:   # pylint: disable=broad-except
        log.exception('Error while attributing cookies to user registration.')

    # TODO: there is no error checking here to see that the user actually logged in successfully,
    # and is not yet an active user.
    if new_user is not None:
        AUDIT_LOG.info(u"Login success on new account creation - {0}".format(new_user.username))

    return new_user
示例#10
0
        })

        registration_course_id = request.session.get('registration_course_id')
        analytics.track(user.id,
                        "edx.bi.user.account.registered", {
                            "category": "conversion",
                            "label": registration_course_id
                        },
                        context={
                            'Google Analytics': {
                                'clientId': tracking_context.get('client_id')
                            }
                        })
        request.session['registration_course_id'] = None

    create_comments_service_user(user)

    context = {
        'name': post_vars['name'],
        'key': registration.activation_key,
    }

    # composes activation email
    subject = render_to_string('emails/activation_email_subject.txt', context)
    # Email subject *must not* contain newlines
    subject = ''.join(subject.splitlines())
    message = render_to_string('emails/activation_email.txt', context)

    # don't send email if we are doing load testing or random user generation for some reason
    if not (settings.FEATURES.get('AUTOMATIC_AUTH_FOR_TESTING')):
        from_address = microsite.get_value('email_from_address',
示例#11
0
    def post(self, request, **kwargs):
        logs.info('request-->%s', request.__dict__)
        popular_topic_list = []
        data = request.data
        if 'HTTP_KEY' and 'HTTP_SECRET' in request.data:
            popular_topic_list = []
            logs.info('key and secret parameter in header')
            key = data.get('HTTP_KEY')
            secret = data.get('HTTP_SECRET')
            logs.info('key, secret %s,%s', key, secret)
            from oauth2_provider.models import Application
            cliet_obj = Application.objects.filter(client_id=key,
                                                   client_secret=secret)
            if not cliet_obj:
                popular_topic_dict = {}
                popular_topic_dict["result"] = "Invalid Key and Secret"
                popular_topic_list.append(popular_topic_dict)
                return JsonResponse(popular_topic_list, status=200, safe=False)
        else:
            popular_topic_dict = {}
            popular_topic_dict["result"] = "Invalid Key and Secret"
            popular_topic_list.append(popular_topic_dict)
            return JsonResponse(popular_topic_list, status=200, safe=False)
        generated_password = generate_password()
        if 'emailid' in request.data:
            if request.method == 'POST':
                mandatory_fields = [
                    "username", "emailid", "password", "name", "phone",
                    "user_type", "specialization", "hcspecialization",
                    "pincode", "country", "state", "city",
                    "csrfmiddlewaretoken", "HTTP_KEY", "HTTP_SECRET", "web"
                ]
                extradata = {}

                vfields = request.data
                for key in vfields:
                    if key not in mandatory_fields:
                        extradata[key] = vfields[key]
                logs.info('extradata --> %s', extradata)
                extradata['daphealth_user'] = "******"
                logs.info('extradata --> %s', extradata)

                email = data.get("emailid", "")
                password = '******'
                name = data.get('name', "")
                phone = data.get('phone', "")
                user_type = "dr"
                pincode = data.get('pincode', "")
                country = data.get('country', "")
                state = data.get('state', "")
                city = data.get('city', "")
                is_active = True

                username = email.split('@')
                uname = username[0]
                uname = uname.replace('.', '-')
                try:
                    username_validation = User.objects.get(username=uname)
                    if username_validation:
                        date = datetime.datetime.now()
                        curr_time = date.strftime('%f')
                        username = uname + '_' + curr_time
                except ObjectDoesNotExist:
                    username = uname
                logs.info(u'username--> %s', username)
                form = AccountCreationForm(data={
                    'username': username,
                    'email': email,
                    'password': password,
                    'name': name,
                },
                                           tos_required=False)

                restricted = settings.FEATURES.get('RESTRICT_AUTOMATIC_AUTH',
                                                   True)
                try:
                    user, profile, reg = do_create_account(form)
                    logs.info(u'user--> %s', user)
                except (AccountValidationError, ValidationError):
                    # if restricted:
                    #     return HttpResponseForbidden(_('Account modification not allowed.'))
                    # Attempt to retrieve the existing user.
                    #     user = User.objects.get(username=username)
                    #     user.email = email
                    #     user.set_password(password)
                    #     user.is_active = is_active
                    #     user.save()
                    #     profile = UserProfile.objects.get(user=user)
                    #     reg = Registration.objects.get(user=user)
                    # except PermissionDenied:
                    registration_log = third_party_user_registration_log(
                        email=email,
                        status=
                        'Account creation not allowed either the user is already registered or email-id not valid',
                        data=request.data)
                    registration_log.save()

                if is_active:
                    reg.activate()
                    reg.save()

                # ensure parental consent threshold is met
                year = datetime.date.today().year
                age_limit = settings.PARENTAL_CONSENT_AGE_LIMIT
                profile.year_of_birth = (year - age_limit) - 1
                profile.save()
                user_extrainfo = extrafields(phone=phone,
                                             rcountry=country,
                                             rstate=state,
                                             rcity=city,
                                             rpincode=pincode,
                                             user_type=user_type,
                                             user=user,
                                             user_extra_data=extradata,
                                             user_email_verification=0)
                user_extrainfo.save()
                course_key = CourseKey.from_string(
                    "course-v1:MayoClinic+MYC001+2022_Apr_MYC001")
                if not CourseEnrollment.is_enrolled(user, course_key):
                    logs.info("course enrollment function will be call")
                    CourseEnrollment.enroll(user=user,
                                            course_key=course_key,
                                            mode='honor')
                    logs.info('extrainfo --> %s', user_extrainfo)
                    create_comments_service_user(user)

                create_or_set_user_attribute_created_on_site(
                    user, request.site)
                registration_log = third_party_user_registration_log(
                    email=email, status='succesful', data=request.data)
                registration_log.save()
                home_ongoing_course_list = []
                home_ongoing_course_dict = {}
                home_ongoing_course_dict['response'] = "Success"
                return Response(data={
                    'status': 200,
                    'sucess': 1,
                    'message': 'Registration successfully'
                },
                                status=200)

                #return HttpResponse('Registration successfully')
            else:
                home_ongoing_course_list = []
                home_ongoing_course_dict = {}
                home_ongoing_course_dict['response'] = "Failed"
                registration_log = third_party_user_registration_log(
                    email=email, status='failed', data=request.POST.dict())
                registration_logs.save()
                return Response(data={
                    'status': 400,
                    'message': 'Registration failed'
                },
                                status=200)
        else:
            return Response(data={
                'status': 400,
                'message': 'Email id is not present'
            },
                            status=200)
示例#12
0
def create_edxapp_user(*args, **kwargs):
    """
    Creates a user on the open edx django site using calls to
    functions defined in the edx-platform codebase

    Example call:

    data = {
        'email': "*****@*****.**",
        'username': "******",
        'password': "******",
        'fullname': "Full Name",
        'activate': True,
        'site': request.site,
        'language_preference': 'es-419',
    }
    user = create_edxapp_user(**data)

    """
    errors = []

    email = kwargs.pop("email")
    username = kwargs.pop("username")
    conflicts = check_edxapp_account_conflicts(email=email, username=username)
    if conflicts:
        return None, [
            "Fatal: account collition with the provided: {}".format(
                ", ".join(conflicts))
        ]

    data = {
        'username': username,
        'email': email,
        'password': kwargs.pop("password"),
        'name': kwargs.pop("fullname"),
    }
    # Go ahead and create the new user
    with transaction.atomic():
        # In theory is possible to extend the registration form with a custom app
        # An example form app for this can be found at http://github.com/open-craft/custom-form-app
        # form = get_registration_extension_form(data=params)
        # if not form:
        form = AccountCreationForm(
            data=data,
            tos_required=False,
            # TODO: we need to support the extra profile fields as defined in the django.settings
            # extra_fields=extra_fields,
            # extended_profile_fields=extended_profile_fields,
            # enforce_password_policy=enforce_password_policy,
        )
        (user, profile, registration) = do_create_account(form)  # pylint: disable=unused-variable

    site = kwargs.pop("site", False)
    if site:
        create_or_set_user_attribute_created_on_site(user, site)
    else:
        errors.append("The user was not assigned to any site")

    try:
        create_comments_service_user(user)
    except Exception:  # pylint: disable=broad-except
        errors.append("No comments_service_user was created")

    # TODO: link account with third party auth

    lang_pref = kwargs.pop("language_preference", False)
    if lang_pref:
        try:
            preferences_api.set_user_preference(user, LANGUAGE_KEY, lang_pref)
        except Exception:  # pylint: disable=broad-except
            errors.append(
                "Could not set lang preference '{} for user '{}'".format(
                    lang_pref,
                    user.username,
                ))

    if kwargs.pop("activate_user", False):
        user.is_active = True
        user.save()

    # TODO: run conditional email sequence

    return user, errors
示例#13
0
    def post(self, request, **kwargs):
        if "fullname" and "registeremail" and "password" and "number" and "phonenumber" and "countryname" in request.POST:
            full_name = request.POST.get('fullname')
            email = request.POST.get('registeremail')
            password = request.POST.get('password')
            number = request.POST.get('number')
            phonenumber = request.POST.get('phonenumber')
            countryname = request.POST.get('countryname')
            if not email:
                return JsonResponse({
                    "status": 400,
                    "message": "email can not blank",
                })
            if not full_name:
                return JsonResponse({
                    "status": 400,
                    "message": "full name can not be blank",
                })
            if not password:
                return JsonResponse({
                    "status": 400,
                    "message": "password can not be blank",
                })
            if not number:
                return JsonResponse({
                    "status": 400,
                    "message": "country code can not be blank",
                })
            if not phonenumber:
                return JsonResponse({
                    "status": 400,
                    "message": "phone number can not be blank",
                })
            if not countryname:
                return JsonResponse({
                    "status": 400,
                    "message": "something wrong on country code, country name not found",
                })
            try:
                phone_number = '+' + number + phonenumber
                phone_number1 = phonenumbers.parse(phone_number)
                valid = phonenumbers.is_valid_number(phone_number1)
                if not valid :
                    return JsonResponse({
                        "status": 400,
                        "message": "phone number not valid",
                    })
            except:
                return JsonResponse({
                    "status": 400,
                    "message": "phone number not valid",
                })
            uname = email.split('@')
            username = uname[0].replace('.','_')
            uname = email.split('@')
            uname = uname[0].replace('.','_')
            try:
                username_validation = User.objects.get(username=uname)
                if username_validation :
                    date = datetime.datetime.now()
                    curr_time = date.strftime('%f')
                    username = uname + '_'+curr_time
            except ObjectDoesNotExist:
                username = uname
            if username and email and password and full_name:
                form = AccountCreationForm(
                data={
                        'username': username,
                        'email': email,
                        'password': password,
                        'name': full_name,
                },
                tos_required=False
                )
                restricted = settings.FEATURES.get('RESTRICT_AUTOMATIC_AUTH', True)
                try:
                    user, profile, reg = do_create_account(form)
                    extradata = {
                            'docvidya_user' : 1
                    }
                    user_extrainfo = extrafields(phone=phonenumber,user=user,rcountry_code=number,rcountry=countryname,user_extradata=extradata)
                    user_extrainfo.save()

                    create_comments_service_user(user)

                    create_or_set_user_attribute_created_on_site(user, request.site)
                    return JsonResponse({
                        "status": 200,
                        "message": "",
                        "userid":user.id,
                        "number":number,
                    })

                    log.info('username--> %s',user)
                except (AccountValidationError, ValidationError):
                    return JsonResponse({
                        "status": 400,
                        "message": "Something Error on user creating",
                    })
            else:
                return JsonResponse({
                    "status": 400,
                    "message": "required parameter missing",
                })
        else:
            return JsonResponse({
                "status": 400,
                "message": "Required Parameter missing",
            })
示例#14
0
def callback(request, next_page=None, required=False):
    try:
        if request.method != 'POST':
            raise PermissionDenied('0005')

        try:
            # Verifies signature and expiry time
            verified_jwt = jwt.decode(
                request.POST['assertion'],
                key=settings.AAF_SECRET,
                # audience=settings.AAF_AUDIENCE,
                # issuer=settings.AAF_ISSUER)
            )
        except jwt.ExpiredSignature:
            # Security cookie has expired
            raise PermissionDenied('0001')

        # for PyJWT > 0.4.1:
        '''
        except jwt.InvalidAudience:
            # Not for this audience
            raise PermissionDenied('0004')
            '''
        # for older PyJWT:
        if verified_jwt['aud'] != settings.AAF_AUDIENCE or verified_jwt['iss'] != settings.AAF_ISSUER:
            raise PermissionDenied('0004')

        import logging
        logging.warning(verified_jwt)

        # Verify that we haven't seen this jti value before (prevents replay
        # attacks)
        if 'jti' not in verified_jwt.keys():
            raise PermissionDenied('0002')

        jti = verified_jwt['jti']
        if JTILog.objects.filter(jti=jti).exists():
            # looks like replay
            raise PermissionDenied('0003')

        # add jti to the log
        jl = JTILog(jti=jti)
        jl.save()

        attributes = verified_jwt['https://aaf.edu.au/attributes']

        request.session['attributes'] = attributes
        request.session['jwt'] = verified_jwt
        request.session['jws'] = request.POST['assertion']

        assert 'edupersonprincipalname' in attributes.keys(), 'edupersonprincipalname not in attributes'

        # If you want to restrict access to your institution, fill in PRINCIPAL_NAME_RE and uncomment
        # The first group should be the username
        '''
        match = PRINCIPAL_NAME_RE.match(attributes['edupersonprincipalname'])
        if match is None:
            # Principal name not in expected format
            raise PermissionDenied('0006')
        username = match.groups()[0]
        '''
        username = attributes['edupersonprincipalname']  # Remove this if you have a better/shorter username you'd like to use

        email = attributes['edupersonprincipalname']

        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            user = User.objects.create_user(
                username=username,
                email=email,
                password=None)  # non-usable password
            user.save()

            UserPreference.set_preference(user, LANGUAGE_KEY, get_language())

        # blech - we're caching the user's name both in the Django User object
        # and the edX UserProfile object, and we don't really want either.

        # cache some attributes
        # Django shouldn't touch the database if they haven't changed, so no perf issue
        if 'givenname' in attributes.keys():
            user.first_name = attributes['givenname']

        if 'surname' in attributes.keys():
            user.last_name = attributes['surname']

        # This should only be done at user creation time. We do it here
        # because we have some old entries in the database that we'd like to
        # clean up automatically.
        if 'edupersonprincipalname' in attributes.keys():
            user.email = attributes['edupersonprincipalname']

        user.save()

        # Look up the UserProfile and update it
        try:
            profile = UserProfile.objects.get(user=user)
        except UserProfile.DoesNotExist:
            # create a new one
            profile = UserProfile(user=user)
            profile.save()

        # update the profile's name
        profile.update_name('%s %s' % (user.first_name, user.last_name))

        create_comments_service_user(user)

        # Temporary workaround: http://stackoverflow.com/a/23771930
        user.backend = 'django.contrib.auth.backends.ModelBackend'

        djauth.login(request, user)

        # done!
        if next_page:
            return redirect(next_page)
        else:
            # If we're in lms, we want to go to dashboard. For cms, go to homepage.
            print 'doing the fallback thing'
            try:
                return redirect('dashboard')
            except NoReverseMatch:
                return redirect('homepage')

    except PermissionDenied as e:
        if 'attributes' in request.session.keys():
            del request.session['attributes']
        djauth.logout(request)

        # messages.add_message(request, messages.ERROR, 'Could not log you in (error %s). Please try again.' % e.message)

        # bounce back to login page
        # TODO you could bounce to a message page if the messages thing above doesn't integrate nicely
        return redirect('dashboard')  # TODO: probably better to send directly to index, but I can't find it
示例#15
0
def import_user_registration_list(self,list_values,filename):
    password = '******'
    date = datetime.datetime.now()
    curr_time = date.strftime('%f')
    file_name = filename + '_' + curr_time + '.' + 'xlsx'
    workbook = xlsxwriter.Workbook(settings.MEDIA_ROOT + file_name)
    worksheet = workbook.add_worksheet()
    columns_list = ["Email ID"]
    col = 0
    row = 0
    for column in columns_list:
        worksheet.write(0, col, column)
    row +=1
    #log.info("list_values ----> %s",list_values)
    for value in list_values:
        #log.info("value ---> %s",value)
        employee_id = value[1]
        full_name = value[2]
        education = value[3]
        specialization = value[4]
        email = value[5]
        phone = value[6]
        city = value[7]
        state = value[8]
        uname = email.split('@')
        uname = uname[0].replace('.','_')
        #log.info('user detail --> %s,%s,%s,%s,%s,%s,%s,%s,%s',email,first_name,last_name,country_code,phone,country,city,place_of_work,profession)
        user_obj = User.objects.filter(email=email)
        #log.info('user_obj--> %s',user_obj)
        #site = Site.objects.get(id=9)
        #workbook = xlsxwriter.Workbook(settings.MEDIA_ROOT + filename)
        #worksheet = workbook.add_worksheet
        #columns_list = ["Email ID"]
        if user_obj:
            user = user_obj[0]
            extradata = {
                        'biocon_survey_user' : 1,
                        'specialization' : specialization,
                        'docmode_user_exist' : 1,
                }
            obj, created = extrafields.objects.get_or_create(user=user)
            obj.phone = phone
            obj.rcity=city
            obj.rstate=state
            obj.education=education
            obj.user_extra_data=extradata
            obj.save()
            log.info('user %s already registered', email)
        else:
            try:
                username_validation = User.objects.get(username=uname)
                if username_validation :
                    date = datetime.datetime.now()
                    curr_time = date.strftime('%f')
                    username = uname + '_'+curr_time
                log.info('username--> %s',username)
            except ObjectDoesNotExist:
                username = uname
            form = AccountCreationForm(
                data={
                    'username': username,
                    'email': email,
                    'password': password,
                    'name': full_name
                },
                tos_required=False
            )
            restricted = settings.FEATURES.get('RESTRICT_AUTOMATIC_AUTH', True)
            try:
                user, profile, reg = do_create_account(form)
                reg.save()
                user.is_active = True
                user.save()
                # ensure parental consent threshold is met
                extradata = {
                            'biocon_survey_user' : 1,
                            'specialization' : specialization,
                }
                user_extrainfo = extrafields(phone=phone,user=user,user_extra_data=extradata,rcity=city,user_type="dr",rstate=state,education=education)
                user_extrainfo.save()
                year = datetime.date.today().year
                age_limit = settings.PARENTAL_CONSENT_AGE_LIMIT
                profile.year_of_birth = (year - age_limit) - 1
                profile.save()
                create_comments_service_user(user)
                #create_or_set_user_attribute_created_on_site(user,site)
                #usersignup_obj = UserSignupSource.objects.create(user=user,site="lvpei.learn.docmode.org")
            except (AccountValidationError, ValidationError):
                worksheet.write(row,col,email)
                row +=1
    workbook.close()
示例#16
0
def create_account_with_params(request, params):
    """
    Given a request and a dict of parameters (which may or may not have come
    from the request), create an account for the requesting user, including
    creating a comments service user object and sending an activation email.
    This also takes external/third-party auth into account, updates that as
    necessary, and authenticates the user for the request's session.

    Does not return anything.

    Raises AccountValidationError if an account with the username or email
    specified by params already exists, or ValidationError if any of the given
    parameters is invalid for any other reason.

    Issues with this code:
    * It is non-transactional except where explicitly wrapped in atomic to
      alleviate deadlocks and improve performance. This means failures at
      different places in registration can leave users in inconsistent
      states.
    * Third-party auth passwords are not verified. There is a comment that
      they are unused, but it would be helpful to have a sanity check that
      they are sane.
    * The user-facing text is rather unfriendly (e.g. "Username must be a
      minimum of two characters long" rather than "Please use a username of
      at least two characters").
    * Duplicate email raises a ValidationError (rather than the expected
      AccountValidationError). Duplicate username returns an inconsistent
      user message (i.e. "An account with the Public Username '{username}'
      already exists." rather than "It looks like {username} belongs to an
      existing account. Try again with a different username.") The two checks
      occur at different places in the code; as a result, registering with
      both a duplicate username and email raises only a ValidationError for
      email only.
    """
    # Copy params so we can modify it; we can't just do dict(params) because if
    # params is request.POST, that results in a dict containing lists of values
    params = dict(params.items())

    # allow to define custom set of required/optional/hidden fields via configuration
    extra_fields = configuration_helpers.get_value(
        'REGISTRATION_EXTRA_FIELDS',
        getattr(settings, 'REGISTRATION_EXTRA_FIELDS', {})
    )
    # registration via third party (Google, Facebook) using mobile application
    # doesn't use social auth pipeline (no redirect uri(s) etc involved).
    # In this case all related info (required for account linking)
    # is sent in params.
    # `third_party_auth_credentials_in_api` essentially means 'request
    # is made from mobile application'
    third_party_auth_credentials_in_api = 'provider' in params
    is_third_party_auth_enabled = third_party_auth.is_enabled()

    if is_third_party_auth_enabled and (pipeline.running(request) or third_party_auth_credentials_in_api):
        params["password"] = generate_password()

    # in case user is registering via third party (Google, Facebook) and pipeline has expired, show appropriate
    # error message
    if is_third_party_auth_enabled and ('social_auth_provider' in params and not pipeline.running(request)):
        raise ValidationError(
            {'session_expired': [
                _(u"Registration using {provider} has timed out.").format(
                    provider=params.get('social_auth_provider'))
            ]}
        )

    do_external_auth, eamap = pre_account_creation_external_auth(request, params)

    extended_profile_fields = configuration_helpers.get_value('extended_profile_fields', [])
    # Can't have terms of service for certain SHIB users, like at Stanford
    registration_fields = getattr(settings, 'REGISTRATION_EXTRA_FIELDS', {})
    tos_required = (
        registration_fields.get('terms_of_service') != 'hidden' or
        registration_fields.get('honor_code') != 'hidden'
    ) and (
        not settings.FEATURES.get("AUTH_USE_SHIB") or
        not settings.FEATURES.get("SHIB_DISABLE_TOS") or
        not do_external_auth or
        not eamap.external_domain.startswith(settings.SHIBBOLETH_DOMAIN_PREFIX)
    )

    form = AccountCreationForm(
        data=params,
        extra_fields=extra_fields,
        extended_profile_fields=extended_profile_fields,
        do_third_party_auth=do_external_auth,
        tos_required=tos_required,
    )
    custom_form = get_registration_extension_form(data=params)

    # Perform operations within a transaction that are critical to account creation
    with outer_atomic(read_committed=True):
        # first, create the account
        (user, profile, registration) = do_create_account(form, custom_form)

        third_party_provider, running_pipeline = _link_user_to_third_party_provider(
            is_third_party_auth_enabled, third_party_auth_credentials_in_api, user, request, params,
        )

        new_user = authenticate_new_user(request, user.username, params['password'])
        django_login(request, new_user)
        request.session.set_expiry(0)

        post_account_creation_external_auth(do_external_auth, eamap, new_user)

    # Check if system is configured to skip activation email for the current user.
    skip_email = _skip_activation_email(
        user, do_external_auth, running_pipeline, third_party_provider,
    )

    if skip_email:
        registration.activate()
    else:
        compose_and_send_activation_email(user, profile, registration)

    # Perform operations that are non-critical parts of account creation
    create_or_set_user_attribute_created_on_site(user, request.site)

    preferences_api.set_user_preference(user, LANGUAGE_KEY, get_language())

    if settings.FEATURES.get('ENABLE_DISCUSSION_EMAIL_DIGEST'):
        try:
            enable_notifications(user)
        except Exception:  # pylint: disable=broad-except
            log.exception(u"Enable discussion notifications failed for user {id}.".format(id=user.id))

    _track_user_registration(user, profile, params, third_party_provider)

    # Announce registration
    REGISTER_USER.send(sender=None, user=user, registration=registration)

    create_comments_service_user(user)

    try:
        _record_registration_attributions(request, new_user)
    # Don't prevent a user from registering due to attribution errors.
    except Exception:   # pylint: disable=broad-except
        log.exception('Error while attributing cookies to user registration.')

    # TODO: there is no error checking here to see that the user actually logged in successfully,
    # and is not yet an active user.
    if new_user is not None:
        AUDIT_LOG.info(u"Login success on new account creation - {0}".format(new_user.username))

    return new_user
示例#17
0
def custom_registration_without_zerobounce(request):
    generated_password = generate_password()

    mandatory_fields = [
        "username",
        "emailid",
        "password",
        "name",
        "phone",
        "user_type",
        "specialization",
        "hcspecialization",
        "pincode",
        "country",
        "state",
        "city",
        "csrfmiddlewaretoken",
    ]
    extradata = {}
    if request.is_ajax():
        if request.method == "POST":
            vfields = request.POST
            for key in vfields:
                if key not in mandatory_fields:
                    extradata[key] = vfields[key]

            uname = request.POST.get("username", "")
            email = request.POST.get("emailid", "")
            password = request.POST.get("password", generated_password)
            if "fname" and "lname" in request.POST:
                fname = request.POST.get("fname", "")
                lname = request.POST.get("lname", "")
                full_name = fname + " " + lname
            else:
                full_name = request.POST.get("name", "")
            phone = request.POST.get("phone", "")
            user_type = "dr"
            specialization = request.POST.get("specialization", "")
            hcspecialization = request.POST.get("hcspecialization", "")
            pincode = request.POST.get("pincode", "")
            country = request.POST.get("country", "")
            state = request.POST.get("state", "")
            city = request.POST.get("city", "")
            is_active = str2bool(request.POST.get("is_active", True))

            try:
                username_validation = User.objects.get(username=uname)
                if username_validation:
                    date = datetime.datetime.now()
                    curr_time = date.strftime("%f")
                    username = uname + "_" + curr_time

            except ObjectDoesNotExist:
                username = uname

            log.info("username--> %s", username)

            form = AccountCreationForm(
                data={
                    "username": username,
                    "email": email,
                    "password": password,
                    "name": full_name,
                },
                tos_required=False,
            )
            restricted = settings.FEATURES.get("RESTRICT_AUTOMATIC_AUTH", True)
            try:
                user, profile, reg = custom_do_create_account(form)
            except (AccountValidationError, ValidationError):
                # if restricted:
                #     return HttpResponseForbidden(_('Account modification not allowed.'))
                # Attempt to retrieve the existing user.
                #     user = User.objects.get(username=username)
                #     user.email = email
                #     user.set_password(password)
                #     user.is_active = is_active
                #     user.save()
                #     profile = UserProfile.objects.get(user=user)
                #     reg = Registration.objects.get(user=user)
                # except PermissionDenied:
                return JsonResponse(
                    {
                        "status": "403",
                        "msg": "Account creation not allowed either the username is already taken.",
                    }
                )

            # ensure parental consent threshold is met
            year = datetime.date.today().year
            age_limit = settings.PARENTAL_CONSENT_AGE_LIMIT
            profile.year_of_birth = (year - age_limit) - 1
            profile.save()
            user_extrainfo = extrafields(
                phone=phone,
                rcountry=country,
                rstate=state,
                rcity=city,
                rpincode=pincode,
                user_type=user_type,
                specialization_id=specialization,
                hcspecialization_id=hcspecialization,
                user_extra_data=extradata,
                user=user,
            )
            user_extrainfo.save()

            new_user = authenticate_new_user(request, user.username, password)
            django_login(request, new_user)
            request.session.set_expiry(604800)
            # log.info(u'details--> %s,%s,%s', user, profile,reg)

            create_comments_service_user(user)

            create_or_set_user_attribute_created_on_site(user, request.site)
            if "viatris" in str(request.site):
                log.info("newmail12%s", request.site)
                viatris_send_activation_email(user, profile, reg, request.site)
            else:
                log.info("oldmail %s", request.site)
                compose_and_send_activation_email(user, profile, reg)
            messages.success(request, "Kol registration successful.")

            response = JsonResponse(
                {
                    "success": True,
                    "userid": user.id,
                    "mobile": phone,
                    "email": email,
                    "name": full_name,
                    "signupdate": datetime.date.today(),
                    "usertype": "dr",
                    "pincode": pincode,
                    "country": country,
                    "redirect_url": "https://mylan.learn.docmode.org/register?next=/oauth2/authorize/confirm",
                }
            )
            return set_logged_in_cookies(request, response, new_user)
    else:
        messages.success(request, "Welcome to KOL registration page.")

        context = {"errors": "welcome", "csrf": csrf(request)["csrf_token"]}
        return render_to_response("associations/custom_registration.html", context)
示例#18
0
def new_kol_registration(request):

    generated_password = generate_password()
    user = request.user

    if user.is_staff:
        if request.method == "POST":
            username = request.POST.get("username", "")
            email = request.POST.get("emailid", "")
            password = request.POST.get("password", generated_password)
            full_name = request.POST.get("name", "")
            phone = request.POST.get("phone", "")
            user_type = request.POST.get("user_type", "")
            specialization = request.POST.get("specialization", "")
            hcspecialization = request.POST.get("hcspecialization", "")
            pincode = request.POST.get("pincode", "")
            country = request.POST.get("country", "")
            state = request.POST.get("state", "")
            city = request.POST.get("city", "")
            is_active = str2bool(request.POST.get("is_active", True))

            form = AccountCreationForm(
                data={
                    "username": username,
                    "email": email,
                    "password": password,
                    "name": full_name,
                },
                tos_required=False,
            )
            restricted = settings.FEATURES.get("RESTRICT_AUTOMATIC_AUTH", True)
            try:
                user, profile, reg = custom_do_create_account(form)
            except (AccountValidationError, ValidationError):
                # if restricted:
                #     return HttpResponseForbidden(_('Account modification not allowed.'))
                # Attempt to retrieve the existing user.
                #     user = User.objects.get(username=username)
                #     user.email = email
                #     user.set_password(password)
                #     user.is_active = is_active
                #     user.save()
                #     profile = UserProfile.objects.get(user=user)
                #     reg = Registration.objects.get(user=user)
                # except PermissionDenied:
                return HttpResponseForbidden(
                    "Account creation not allowed either the user is already registered or email-id not valid."
                )

            if is_active:
                reg.activate()
                reg.save()

            # ensure parental consent threshold is met
            year = datetime.date.today().year
            age_limit = settings.PARENTAL_CONSENT_AGE_LIMIT
            profile.year_of_birth = (year - age_limit) - 1
            profile.save()
            user_extrainfo = extrafields(
                phone=phone,
                rcountry=country,
                rstate=state,
                rcity=city,
                rpincode=pincode,
                user_type=user_type,
                specialization_id=specialization,
                hcspecialization_id=hcspecialization,
                user=user,
            )
            user_extrainfo.save()
            create_comments_service_user(user)

            create_or_set_user_attribute_created_on_site(user, request.site)
            messages.success(request, "Kol registration successful.")
            context = {"errors": "welcome", "csrf": csrf(request)["csrf_token"]}
            return render_to_response("associations/new_kol_registration.html", context)
        else:
            messages.success(request, "Welcome to KOL registration page.")

            context = {"errors": "welcome", "csrf": csrf(request)["csrf_token"]}
            return render_to_response("associations/new_kol_registration.html", context)
示例#19
0
def auto_auth(request):
    """
    Create or configure a user account, then log in as that user.

    Enabled only when
    settings.FEATURES['AUTOMATIC_AUTH_FOR_TESTING'] is true.

    Accepts the following querystring parameters:
    * `username`, `email`, and `password` for the user account
    * `full_name` for the user profile (the user's full name; defaults to the username)
    * `staff`: Set to "true" to make the user global staff.
    * `course_id`: Enroll the student in the course with `course_id`
    * `roles`: Comma-separated list of roles to grant the student in the course with `course_id`
    * `no_login`: Define this to create the user but not login
    * `redirect`: Set to "true" will redirect to the `redirect_to` value if set, or
        course home page if course_id is defined, otherwise it will redirect to dashboard
    * `redirect_to`: will redirect to to this url
    * `is_active` : make/update account with status provided as 'is_active'
    If username, email, or password are not provided, use
    randomly generated credentials.
    """

    # Generate a unique name to use if none provided
    generated_username = uuid.uuid4().hex[0:30]
    generated_password = generate_password()

    # Use the params from the request, otherwise use these defaults
    username = request.GET.get('username', generated_username)
    password = request.GET.get('password', generated_password)
    email = request.GET.get('email', username + "@example.com")
    full_name = request.GET.get('full_name', username)
    is_staff = str2bool(request.GET.get('staff', False))
    is_superuser = str2bool(request.GET.get('superuser', False))
    course_id = request.GET.get('course_id')
    redirect_to = request.GET.get('redirect_to')
    is_active = str2bool(request.GET.get('is_active', True))

    # Valid modes: audit, credit, honor, no-id-professional, professional, verified
    enrollment_mode = request.GET.get('enrollment_mode', 'honor')

    # Parse roles, stripping whitespace, and filtering out empty strings
    roles = _clean_roles(request.GET.get('roles', '').split(','))
    course_access_roles = _clean_roles(request.GET.get('course_access_roles', '').split(','))

    redirect_when_done = str2bool(request.GET.get('redirect', '')) or redirect_to
    login_when_done = 'no_login' not in request.GET

    restricted = settings.FEATURES.get('RESTRICT_AUTOMATIC_AUTH', True)
    if is_superuser and restricted:
        return HttpResponseForbidden(_('Superuser creation not allowed'))

    form = AccountCreationForm(
        data={
            'username': username,
            'email': email,
            'password': password,
            'name': full_name,
        },
        tos_required=False
    )

    # Attempt to create the account.
    # If successful, this will return a tuple containing
    # the new user object.
    try:
        user, profile, reg = do_create_account(form)
    except (AccountValidationError, ValidationError):
        if restricted:
            return HttpResponseForbidden(_('Account modification not allowed.'))
        # Attempt to retrieve the existing user.
        user = User.objects.get(username=username)
        user.email = email
        user.set_password(password)
        user.is_active = is_active
        user.save()
        profile = UserProfile.objects.get(user=user)
        reg = Registration.objects.get(user=user)
    except PermissionDenied:
        return HttpResponseForbidden(_('Account creation not allowed.'))

    user.is_staff = is_staff
    user.is_superuser = is_superuser
    user.save()

    if is_active:
        reg.activate()
        reg.save()

    # ensure parental consent threshold is met
    year = datetime.date.today().year
    age_limit = settings.PARENTAL_CONSENT_AGE_LIMIT
    profile.year_of_birth = (year - age_limit) - 1
    profile.save()

    create_or_set_user_attribute_created_on_site(user, request.site)

    # Enroll the user in a course
    course_key = None
    if course_id:
        course_key = CourseLocator.from_string(course_id)
        CourseEnrollment.enroll(user, course_key, mode=enrollment_mode)

        # Apply the roles
        for role in roles:
            assign_role(course_key, user, role)

        for role in course_access_roles:
            CourseAccessRole.objects.update_or_create(user=user, course_id=course_key, org=course_key.org, role=role)

    # Log in as the user
    if login_when_done:
        user = authenticate_new_user(request, username, password)
        django_login(request, user)

    create_comments_service_user(user)

    if redirect_when_done:
        if redirect_to:
            # Redirect to page specified by the client
            redirect_url = redirect_to
        elif course_id:
            # Redirect to the course homepage (in LMS) or outline page (in Studio)
            try:
                redirect_url = reverse(course_home_url_name(course_key), kwargs={'course_id': course_id})
            except NoReverseMatch:
                redirect_url = reverse('course_handler', kwargs={'course_key_string': course_id})
        else:
            # Redirect to the learner dashboard (in LMS) or homepage (in Studio)
            try:
                redirect_url = reverse('dashboard')
            except NoReverseMatch:
                redirect_url = reverse('home')

        return redirect(redirect_url)
    else:
        response = JsonResponse({
            'created_status': 'Logged in' if login_when_done else 'Created',
            'username': username,
            'email': email,
            'password': password,
            'user_id': user.id,  # pylint: disable=no-member
            'anonymous_id': anonymous_id_for_user(user, None),
        })
    response.set_cookie('csrftoken', csrf(request)['csrf_token'])
    return response
示例#20
0
def create_account_with_params_custom(request, params):
    """
    Given a request and a dict of parameters (which may or may not have come
    from the request), create an account for the requesting user, including
    creating a comments service user object and sending an activation email.
    This also takes external/third-party auth into account, updates that as
    necessary, and authenticates the user for the request's session.

    Does not return anything.

    Raises AccountValidationError if an account with the username or email
    specified by params already exists, or ValidationError if any of the given
    parameters is invalid for any other reason.

    Issues with this code:
    * It is not transactional. If there is a failure part-way, an incomplete
      account will be created and left in the database.
    * Third-party auth passwords are not verified. There is a comment that
      they are unused, but it would be helpful to have a sanity check that
      they are sane.
    * It is over 300 lines long (!) and includes disprate functionality, from
      registration e-mails to all sorts of other things. It should be broken
      up into semantically meaningful functions.
    * The user-facing text is rather unfriendly (e.g. "Username must be a
      minimum of two characters long" rather than "Please use a username of
      at least two characters").
    """
    # Copy params so we can modify it; we can't just do dict(params) because if
    # params is request.POST, that results in a dict containing lists of values
    params = dict(params.items())

    # allow to define custom set of required/optional/hidden fields via configuration
    extra_fields = configuration_helpers.get_value(
        'REGISTRATION_EXTRA_FIELDS',
        getattr(settings, 'REGISTRATION_EXTRA_FIELDS', {}))

    # Boolean of whether a 3rd party auth provider and credentials were provided in
    # the API so the newly created account can link with the 3rd party account.
    #
    # Note: this is orthogonal to the 3rd party authentication pipeline that occurs
    # when the account is created via the browser and redirect URLs.
    should_link_with_social_auth = third_party_auth.is_enabled(
    ) and 'provider' in params

    if should_link_with_social_auth or (third_party_auth.is_enabled()
                                        and pipeline.running(request)):
        params["password"] = pipeline.make_random_password()

    # Add a form requirement for data sharing consent if the EnterpriseCustomer
    # for the request requires it at login
    extra_fields[
        'data_sharing_consent'] = data_sharing_consent_requirement_at_login(
            request)

    # if doing signup for an external authorization, then get email, password, name from the eamap
    # don't use the ones from the form, since the user could have hacked those
    # unless originally we didn't get a valid email or name from the external auth
    # TODO: We do not check whether these values meet all necessary criteria, such as email length
    do_external_auth = 'ExternalAuthMap' in request.session
    if do_external_auth:
        eamap = request.session['ExternalAuthMap']
        try:
            validate_email(eamap.external_email)
            params["email"] = eamap.external_email
        except ValidationError:
            pass
        if eamap.external_name.strip() != '':
            params["name"] = eamap.external_name
        params["password"] = eamap.internal_password
        log.debug(u'In create_account with external_auth: user = %s, email=%s',
                  params["name"], params["email"])

    extended_profile_fields = configuration_helpers.get_value(
        'extended_profile_fields', [])
    enforce_password_policy = (settings.FEATURES.get(
        "ENFORCE_PASSWORD_POLICY", False) and not do_external_auth)
    # Can't have terms of service for certain SHIB users, like at Stanford
    registration_fields = getattr(settings, 'REGISTRATION_EXTRA_FIELDS', {})
    tos_required = (registration_fields.get('terms_of_service') != 'hidden'
                    or registration_fields.get('honor_code') != 'hidden') and (
                        not settings.FEATURES.get("AUTH_USE_SHIB")
                        or not settings.FEATURES.get("SHIB_DISABLE_TOS")
                        or not do_external_auth
                        or not eamap.external_domain.startswith(
                            openedx.core.djangoapps.external_auth.views.
                            SHIBBOLETH_DOMAIN_PREFIX))

    params['name'] = "{} {}".format(params.get('first_name'),
                                    params.get('last_name'))
    form = AccountCreationForm(
        data=params,
        extra_fields=extra_fields,
        extended_profile_fields=extended_profile_fields,
        enforce_username_neq_password=True,
        enforce_password_policy=enforce_password_policy,
        tos_required=tos_required,
    )
    custom_form = get_registration_extension_form(data=params)

    # Perform operations within a transaction that are critical to account creation
    with transaction.atomic():
        # first, create the account
        (user, profile,
         registration) = _do_create_account_custom(form, custom_form)

        # next, link the account with social auth, if provided via the API.
        # (If the user is using the normal register page, the social auth pipeline does the linking, not this code)
        if should_link_with_social_auth:
            backend_name = params['provider']
            request.social_strategy = social_utils.load_strategy(request)
            redirect_uri = reverse('social:complete', args=(backend_name, ))
            request.backend = social_utils.load_backend(
                request.social_strategy, backend_name, redirect_uri)
            social_access_token = params.get('access_token')
            if not social_access_token:
                raise ValidationError({
                    'access_token': [
                        _("An access_token is required when passing value ({}) for provider."
                          ).format(params['provider'])
                    ]
                })
            request.session[
                pipeline.AUTH_ENTRY_KEY] = pipeline.AUTH_ENTRY_REGISTER_API
            pipeline_user = None
            error_message = ""
            try:
                pipeline_user = request.backend.do_auth(social_access_token,
                                                        user=user)
            except AuthAlreadyAssociated:
                error_message = _(
                    "The provided access_token is already associated with another user."
                )
            except (HTTPError, AuthException):
                error_message = _("The provided access_token is not valid.")
            if not pipeline_user or not isinstance(pipeline_user, User):
                # Ensure user does not re-enter the pipeline
                request.social_strategy.clean_partial_pipeline()
                raise ValidationError({'access_token': [error_message]})

    # Perform operations that are non-critical parts of account creation
    preferences_api.set_user_preference(user, LANGUAGE_KEY, get_language())

    if settings.FEATURES.get('ENABLE_DISCUSSION_EMAIL_DIGEST'):
        try:
            enable_notifications(user)
        except Exception:  # pylint: disable=broad-except
            log.exception(
                "Enable discussion notifications failed for user {id}.".format(
                    id=user.id))

    dog_stats_api.increment("common.student.account_created")

    # If the user is registering via 3rd party auth, track which provider they use
    third_party_provider = None
    running_pipeline = None
    if third_party_auth.is_enabled() and pipeline.running(request):
        running_pipeline = pipeline.get(request)
        third_party_provider = provider.Registry.get_from_pipeline(
            running_pipeline)
        # Store received data sharing consent field values in the pipeline for use
        # by any downstream pipeline elements which require them.
        running_pipeline['kwargs'][
            'data_sharing_consent'] = form.cleaned_data.get(
                'data_sharing_consent', None)

    # Track the user's registration
    if hasattr(settings, 'LMS_SEGMENT_KEY') and settings.LMS_SEGMENT_KEY:
        tracking_context = tracker.get_tracker().resolve_context()
        identity_args = [
            user.id,  # pylint: disable=no-member
            {
                'email':
                user.email,
                'username':
                user.username,
                'name':
                profile.name,
                # Mailchimp requires the age & yearOfBirth to be integers, we send a sane integer default if falsey.
                'age':
                profile.age or -1,
                'yearOfBirth':
                profile.year_of_birth or datetime.datetime.now(UTC).year,
                'education':
                profile.level_of_education_display,
                'address':
                profile.mailing_address,
                'gender':
                profile.gender_display,
                'country':
                unicode(profile.country),
            }
        ]

        if hasattr(settings, 'MAILCHIMP_NEW_USER_LIST_ID'):
            identity_args.append(
                {"MailChimp": {
                    "listId": settings.MAILCHIMP_NEW_USER_LIST_ID
                }})

        analytics.identify(*identity_args)

        analytics.track(
            user.id,
            "edx.bi.user.account.registered", {
                'category':
                'conversion',
                'label':
                params.get('course_id'),
                'provider':
                third_party_provider.name if third_party_provider else None
            },
            context={
                'ip': tracking_context.get('ip'),
                'Google Analytics': {
                    'clientId': tracking_context.get('client_id')
                }
            })

    # Announce registration
    REGISTER_USER.send(sender=None, user=user, profile=profile)

    create_comments_service_user(user)

    # Don't send email if we are:
    #
    # 1. Doing load testing.
    # 2. Random user generation for other forms of testing.
    # 3. External auth bypassing activation.
    # 4. Have the platform configured to not require e-mail activation.
    # 5. Registering a new user using a trusted third party provider (with skip_email_verification=True)
    #
    # Note that this feature is only tested as a flag set one way or
    # the other for *new* systems. we need to be careful about
    # changing settings on a running system to make sure no users are
    # left in an inconsistent state (or doing a migration if they are).
    send_email = (
        not settings.FEATURES.get('SKIP_EMAIL_VALIDATION', None)
        and not settings.FEATURES.get('AUTOMATIC_AUTH_FOR_TESTING')
        and not (do_external_auth and
                 settings.FEATURES.get('BYPASS_ACTIVATION_EMAIL_FOR_EXTAUTH'))
        and
        not (third_party_provider
             and third_party_provider.skip_email_verification and user.email
             == running_pipeline['kwargs'].get('details', {}).get('email')))
    if send_email:
        send_account_activation_email(request, registration, user)
    else:
        registration.activate()
        _enroll_user_in_pending_courses(
            user)  # Enroll student in any pending courses

    # Immediately after a user creates an account, we log them in. They are only
    # logged in until they close the browser. They can't log in again until they click
    # the activation link from the email.
    new_user = authenticate(username=user.username,
                            password=params['password'])
    login(request, new_user)
    request.session.set_expiry(0)

    try:
        record_registration_attributions(request, new_user)
    # Don't prevent a user from registering due to attribution errors.
    except Exception:  # pylint: disable=broad-except
        log.exception('Error while attributing cookies to user registration.')

    # TODO: there is no error checking here to see that the user actually logged in successfully,
    # and is not yet an active user.
    if new_user is not None:
        AUDIT_LOG.info(u"Login success on new account creation - {0}".format(
            new_user.username))

    if do_external_auth:
        eamap.user = new_user
        eamap.dtsignup = datetime.datetime.now(UTC)
        eamap.save()
        AUDIT_LOG.info(u"User registered with external_auth %s",
                       new_user.username)
        AUDIT_LOG.info(u'Updated ExternalAuthMap for %s to be %s',
                       new_user.username, eamap)

        if settings.FEATURES.get('BYPASS_ACTIVATION_EMAIL_FOR_EXTAUTH'):
            log.info('bypassing activation email')
            new_user.is_active = True
            new_user.save()
            AUDIT_LOG.info(
                u"Login activated on extauth account - {0} ({1})".format(
                    new_user.username, new_user.email))

    return new_user
示例#21
0
def auto_auth(request):
    """
    Create or configure a user account, then log in as that user.

    Enabled only when
    settings.FEATURES['AUTOMATIC_AUTH_FOR_TESTING'] is true.

    Accepts the following querystring parameters:
    * `username`, `email`, and `password` for the user account
    * `full_name` for the user profile (the user's full name; defaults to the username)
    * `staff`: Set to "true" to make the user global staff.
    * `course_id`: Enroll the student in the course with `course_id`
    * `roles`: Comma-separated list of roles to grant the student in the course with `course_id`
    * `no_login`: Define this to create the user but not login
    * `redirect`: Set to "true" will redirect to the `redirect_to` value if set, or
        course home page if course_id is defined, otherwise it will redirect to dashboard
    * `redirect_to`: will redirect to to this url
    * `is_active` : make/update account with status provided as 'is_active'
    If username, email, or password are not provided, use
    randomly generated credentials.
    """

    # Generate a unique name to use if none provided
    generated_username = uuid.uuid4().hex[0:30]
    generated_password = generate_password()

    # Use the params from the request, otherwise use these defaults
    username = request.GET.get('username', generated_username)
    password = request.GET.get('password', generated_password)
    email = request.GET.get('email', username + "@example.com")
    full_name = request.GET.get('full_name', username)
    is_staff = str2bool(request.GET.get('staff', False))
    is_superuser = str2bool(request.GET.get('superuser', False))
    course_id = request.GET.get('course_id')
    redirect_to = request.GET.get('redirect_to')
    is_active = str2bool(request.GET.get('is_active', True))

    # Valid modes: audit, credit, honor, no-id-professional, professional, verified
    enrollment_mode = request.GET.get('enrollment_mode', 'honor')

    # Parse roles, stripping whitespace, and filtering out empty strings
    roles = _clean_roles(request.GET.get('roles', '').split(','))
    course_access_roles = _clean_roles(request.GET.get('course_access_roles', '').split(','))

    redirect_when_done = str2bool(request.GET.get('redirect', '')) or redirect_to
    login_when_done = 'no_login' not in request.GET

    form = AccountCreationForm(
        data={
            'username': username,
            'email': email,
            'password': password,
            'confirm_password': password,
            'name': full_name,
        },
        tos_required=False
    )

    # Attempt to create the account.
    # If successful, this will return a tuple containing
    # the new user object.
    try:
        user, profile, reg = do_create_account(form)
    except (AccountValidationError, ValidationError):
        # Attempt to retrieve the existing user.
        user = User.objects.get(username=username)
        user.email = email
        user.set_password(password)
        user.is_active = is_active
        user.save()
        profile = UserProfile.objects.get(user=user)
        reg = Registration.objects.get(user=user)
    except PermissionDenied:
        return HttpResponseForbidden(_('Account creation not allowed.'))

    user.is_staff = is_staff
    user.is_superuser = is_superuser
    user.save()

    if is_active:
        reg.activate()
        reg.save()

    # ensure parental consent threshold is met
    year = datetime.date.today().year
    age_limit = settings.PARENTAL_CONSENT_AGE_LIMIT
    profile.year_of_birth = (year - age_limit) - 1
    profile.save()

    create_or_set_user_attribute_created_on_site(user, request.site)

    # Enroll the user in a course
    course_key = None
    if course_id:
        course_key = CourseLocator.from_string(course_id)
        CourseEnrollment.enroll(user, course_key, mode=enrollment_mode)

        # Apply the roles
        for role in roles:
            assign_role(course_key, user, role)

        for role in course_access_roles:
            CourseAccessRole.objects.update_or_create(user=user, course_id=course_key, org=course_key.org, role=role)

    # Log in as the user
    if login_when_done:
        user = authenticate_new_user(request, username, password)
        django_login(request, user)

    create_comments_service_user(user)

    if redirect_when_done:
        if redirect_to:
            # Redirect to page specified by the client
            redirect_url = redirect_to
        elif course_id:
            # Redirect to the course homepage (in LMS) or outline page (in Studio)
            try:
                redirect_url = reverse(course_home_url_name(course_key), kwargs={'course_id': course_id})
            except NoReverseMatch:
                redirect_url = reverse('course_handler', kwargs={'course_key_string': course_id})
        else:
            # Redirect to the learner dashboard (in LMS) or homepage (in Studio)
            try:
                redirect_url = reverse('dashboard')
            except NoReverseMatch:
                redirect_url = reverse('home')

        return redirect(redirect_url)
    else:
        response = JsonResponse({
            'created_status': 'Logged in' if login_when_done else 'Created',
            'username': username,
            'email': email,
            'password': password,
            'user_id': user.id,  # pylint: disable=no-member
            'anonymous_id': anonymous_id_for_user(user, None),
        })
    response.set_cookie('csrftoken', csrf(request)['csrf_token'])
    return response
示例#22
0
    def post(self, request, format=None):
        """
        """
        # Gather all the request data
        username = request.POST.get('username')
        email = request.POST.get('email')
        password = request.POST.get('password')
        contact_name = request.POST.get('contact_name')
        activate = request.POST.get('activate', False)
        org_manager = request.POST.get('org_manager', False)
        send_email = request.POST.get('send_email', False)
        language = request.POST.get('language', 'en')

        conflicts = check_account_exists(email=email, username=username)
        if conflicts:
            return JsonResponse({'conflict_on_fields': conflicts}, status=409)

        data = {
            'username': username,
            'email': email,
            'password': password,
            'name': contact_name,
        }

        # Go ahead and create the new user
        with transaction.commit_on_success():
            form = AccountCreationForm(
                data=data,
                tos_required=False,
            )
            (user, profile, registration) = _do_create_account(form)

        create_comments_service_user(user)

        if send_email:
            with override_language(language):
                context = {
                    'name': profile.name,
                    'key': registration.activation_key,
                }

                # composes activation email
                subject = render_to_string('emails/activation_email_subject.txt', context)
                subject = ''.join(subject.splitlines())
                message = render_to_string('emails/activation_email.txt', context)
                message_html = None
                if (settings.FEATURES.get('ENABLE_MULTIPART_EMAIL')):
                    message_html = render_to_string('emails/html/activation_email.html', context)
                from_address = microsite.get_value(
                    'email_from_address',
                    settings.DEFAULT_FROM_EMAIL
                )
                try:
                    mail.send_mail(subject, message, from_address, [user.email], html_message=message_html)
                except Exception:  # pylint: disable=broad-except
                    log.error(u'Unable to send activation email to remotely created user from "%s"', from_address, exc_info=True)

        # Assing the user to the org management roles
        if org_manager:
            # We have to make them active for the roles to stick
            user.is_active = True
            user.save()

            creator_role = OrgCourseCreatorRole(org_manager)
            creator_role.add_users(user)
            rerun_role = OrgRerunCreatorRole(org_manager)
            rerun_role.add_users(user)

            user.is_active = False
            user.save()

        if activate:
            registration.activate()

        return JsonResponse({"success": True}, status=201)