예제 #1
0
def create_lti_user(lti_user_id, lti_consumer):
    """
    Generate a new user on the edX platform with a random username and password,
    and associates that account with the LTI identity.
    """
    edx_password = str(uuid.uuid4())

    created = False
    while not created:
        try:
            edx_user_id = generate_random_edx_username()
            edx_email = "{}@{}".format(edx_user_id,
                                       settings.LTI_USER_EMAIL_DOMAIN)
            with transaction.atomic():
                edx_user = User.objects.create_user(
                    username=edx_user_id,
                    password=edx_password,
                    email=edx_email,
                )
                # A profile is required if PREVENT_CONCURRENT_LOGINS flag is set.
                # TODO: We could populate user information from the LTI launch here,
                # but it's not necessary for our current uses.
                edx_user_profile = UserProfile(user=edx_user)
                edx_user_profile.save()
            created = True
        except IntegrityError:
            # The random edx_user_id wasn't unique. Since 'created' is still
            # False, we will retry with a different random ID.
            pass

    lti_user = LtiUser(lti_consumer=lti_consumer,
                       lti_user_id=lti_user_id,
                       edx_user=edx_user)
    lti_user.save()
    return lti_user
    def make_student(self, block, name, make_state=True, **state):
        """
        Create a student along with submission state.
        """
        answer = {}
        module = None
        for key in ('sha1', 'mimetype', 'filename', 'finalized'):
            if key in state:
                answer[key] = state.pop(key)
        score = state.pop('score', None)

        with transaction.atomic():
            user = User(username=name, email='{}@example.com'.format(name))
            user.save()
            profile = UserProfile(user=user, name=name)
            profile.save()
            if make_state:
                module = StudentModule(module_state_key=block.location,
                                       student=user,
                                       course_id=self.course_id,
                                       state=json.dumps(state))
                module.save()

            anonymous_id = anonymous_id_for_user(user, self.course_id)
            item = StudentItem(student_id=anonymous_id,
                               course_id=self.course_id,
                               item_id=block.block_id,
                               item_type='sga')
            item.save()

            if answer:
                student_id = block.get_student_item_dict(anonymous_id)
                submission = submissions_api.create_submission(
                    student_id, answer)
                if score is not None:
                    submissions_api.set_score(submission['uuid'], score,
                                              block.max_score())
            else:
                submission = None

            self.addCleanup(item.delete)
            self.addCleanup(profile.delete)
            self.addCleanup(user.delete)

            if make_state:
                self.addCleanup(module.delete)
                return {
                    'module': module,
                    'item': item,
                    'submission': submission
                }

            return {'item': item, 'submission': submission}
예제 #3
0
    def create_user(self, uname, name, password=None):
        """ Creates a user """

        if not uname:
            return _('Must provide username')
        if not name:
            return _('Must provide full name')

        msg = u''
        if not password:
            return _('Password must be supplied')

        email = uname

        if '@' not in email:
            msg += _('email address required (not username)')
            return msg
        new_password = password

        user = User(username=uname, email=email, is_active=True)
        user.set_password(new_password)
        try:
            user.save()
        except IntegrityError:
            msg += _(u'Oops, failed to create user {user}, {error}').format(
                user=user,
                error="IntegrityError"
            )
            return msg

        reg = Registration()
        reg.register(user)

        profile = UserProfile(user=user)
        profile.name = name
        profile.save()

        msg += _(u'User {user} created successfully!').format(user=user)
        return msg
예제 #4
0
def create_user_through_db_models(data):
    """
    It Registers User through database models

    Arguments:
    data (dict) - User account details

    Returns:
    context (dict) - context to be passed to templates having information about success and
        failure of account creation
    """
    context = {}
    try:
        if not User.objects.filter(email=data["email"]).exists():
            user = User(username=data["username"],
                        email=data["email"],
                        is_active=True)
            password = normalize_password(data["password"])
            user.set_password(password)
            user.save()

            profile = UserProfile(user=user)
            profile.name = data.get("name")
            profile.save()

            context[
                "success_message"] = f"{_('A new account has been registered for user')}: {data['username']}"
        else:
            context[
                "error_message"] = f"{_('An account already exists with email')}: {data['email']}"
            return context
    except Exception as err:  # pylint: disable=broad-except
        context[
            "error_message"] = f"{_('Account could not be created due to following error')}: {err}"

    return context
예제 #5
0
def do_create_account(form, custom_form=None):
    """
    Given cleaned post variables, create the User and UserProfile objects, as well as the
    registration for this user.

    Returns a tuple (User, UserProfile, Registration).

    Note: this function is also used for creating test users.
    """
    # Check if ALLOW_PUBLIC_ACCOUNT_CREATION flag turned off to restrict user account creation
    if not configuration_helpers.get_value(
            'ALLOW_PUBLIC_ACCOUNT_CREATION',
            settings.FEATURES.get('ALLOW_PUBLIC_ACCOUNT_CREATION', True)):
        raise PermissionDenied()

    errors = {}
    errors.update(form.errors)
    if custom_form:
        errors.update(custom_form.errors)

    if errors:
        raise ValidationError(errors)

    proposed_username = form.cleaned_data["username"]
    user = User(username=proposed_username,
                email=form.cleaned_data["email"],
                is_active=False)
    password = normalize_password(form.cleaned_data["password"])
    user.set_password(password)
    registration = Registration()

    # TODO: Rearrange so that if part of the process fails, the whole process fails.
    # Right now, we can have e.g. no registration e-mail sent out and a zombie account
    try:
        with transaction.atomic():
            user.save()
            if custom_form:
                custom_model = custom_form.save(commit=False)
                custom_model.user = user
                custom_model.save()
    except IntegrityError:
        # Figure out the cause of the integrity error
        # TODO duplicate email is already handled by form.errors above as a ValidationError.
        # The checks for duplicate email/username should occur in the same place with an
        # AccountValidationError and a consistent user message returned (i.e. both should
        # return "It looks like {username} belongs to an existing account. Try again with a
        # different username.")
        if username_exists_or_retired(user.username):
            raise AccountValidationError(
                USERNAME_EXISTS_MSG_FMT.format(username=proposed_username),
                field="username")
        elif email_exists_or_retired(user.email):
            raise AccountValidationError(_(
                "An account with the Email '{email}' already exists.").format(
                    email=user.email),
                                         field="email")
        else:
            raise

    registration.register(user)

    profile_fields = [
        "name", "level_of_education", "gender", "mailing_address", "city",
        "country", "goals", "year_of_birth"
    ]
    profile = UserProfile(
        user=user,
        **{key: form.cleaned_data.get(key)
           for key in profile_fields})
    extended_profile = form.cleaned_extended_profile
    if extended_profile:
        profile.meta = json.dumps(extended_profile)
    try:
        profile.save()
    except Exception:
        log.exception(
            "UserProfile creation failed for user {id}.".format(id=user.id))
        raise

    return user, profile, registration