From 71b585bb614d80e79c8866b46145c6bdf6e95f20 Mon Sep 17 00:00:00 2001 From: Victor Shnayder <victor@mitx.mit.edu> Date: Sat, 17 Nov 2012 16:33:00 -0500 Subject: [PATCH] move unique_id_for_user into student/models.py --- common/djangoapps/student/models.py | 47 +++++++++++++++++++---------- common/djangoapps/student/tests.py | 6 ++-- common/djangoapps/student/views.py | 6 +--- 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/common/djangoapps/student/models.py b/common/djangoapps/student/models.py index 0eded21df10..4c91682ca66 100644 --- a/common/djangoapps/student/models.py +++ b/common/djangoapps/student/models.py @@ -36,10 +36,12 @@ file and check it in at the same time as your model changes. To do that, 3. Add the migration file created in mitx/common/djangoapps/student/migrations/ """ from datetime import datetime +from hashlib import sha1 import json import logging import uuid + from django.conf import settings from django.contrib.auth.models import User from django.db import models @@ -125,9 +127,9 @@ class UserProfile(models.Model): self.meta = json.dumps(js) class TestCenterUser(models.Model): - """This is our representation of the User for in-person testing, and + """This is our representation of the User for in-person testing, and specifically for Pearson at this point. A few things to note: - + * Pearson only supports Latin-1, so we have to make sure that the data we capture here will work with that encoding. * While we have a lot of this demographic data in UserProfile, it's much @@ -135,9 +137,9 @@ class TestCenterUser(models.Model): UserProfile, but we'll need to have a step where people who are signing up re-enter their demographic data into the fields we specify. * Users are only created here if they register to take an exam in person. - + The field names and lengths are modeled on the conventions and constraints - of Pearson's data import system, including oddities such as suffix having + of Pearson's data import system, including oddities such as suffix having a limit of 255 while last_name only gets 50. """ # Our own record keeping... @@ -148,21 +150,21 @@ class TestCenterUser(models.Model): # and is something Pearson needs to know to manage updates. Unlike # updated_at, this will not get incremented when we do a batch data import. user_updated_at = models.DateTimeField(db_index=True) - + # Unique ID given to us for this User by the Testing Center. It's null when # we first create the User entry, and is assigned by Pearson later. candidate_id = models.IntegerField(null=True, db_index=True) - + # Unique ID we assign our user for a the Test Center. client_candidate_id = models.CharField(max_length=50, db_index=True) - + # Name first_name = models.CharField(max_length=30, db_index=True) last_name = models.CharField(max_length=50, db_index=True) middle_name = models.CharField(max_length=30, blank=True) suffix = models.CharField(max_length=255, blank=True) salutation = models.CharField(max_length=50, blank=True) - + # Address address_1 = models.CharField(max_length=40) address_2 = models.CharField(max_length=40, blank=True) @@ -175,7 +177,7 @@ class TestCenterUser(models.Model): postal_code = models.CharField(max_length=16, blank=True, db_index=True) # country is a ISO 3166-1 alpha-3 country code (e.g. "USA", "CAN", "MNG") country = models.CharField(max_length=3, db_index=True) - + # Phone phone = models.CharField(max_length=35) extension = models.CharField(max_length=8, blank=True, db_index=True) @@ -183,14 +185,27 @@ class TestCenterUser(models.Model): fax = models.CharField(max_length=35, blank=True) # fax_country_code required *if* fax is present. fax_country_code = models.CharField(max_length=3, blank=True) - + # Company company_name = models.CharField(max_length=50, blank=True) - + @property def email(self): return self.user.email +def unique_id_for_user(user): + """ + Return a unique id for a user, suitable for inserting into + e.g. personalized survey links. + + Currently happens to be implemented as a sha1 hash of the username + (and thus assumes that usernames don't change). + """ + return sha1(user.username).hexdigest() + + + + ## TODO: Should be renamed to generic UserGroup, and possibly # Given an optional field for type of group class UserTestGroup(models.Model): @@ -363,10 +378,10 @@ def replicate_user_save(sender, **kwargs): # @receiver(post_save, sender=CourseEnrollment) def replicate_enrollment_save(sender, **kwargs): - """This is called when a Student enrolls in a course. It has to do the + """This is called when a Student enrolls in a course. It has to do the following: - 1. Make sure the User is copied into the Course DB. It may already exist + 1. Make sure the User is copied into the Course DB. It may already exist (someone deleting and re-adding a course). This has to happen first or the foreign key constraint breaks. 2. Replicate the CourseEnrollment. @@ -410,9 +425,9 @@ USER_FIELDS_TO_COPY = ["id", "username", "first_name", "last_name", "email", def replicate_user(portal_user, course_db_name): """Replicate a User to the correct Course DB. This is more complicated than - it should be because Askbot extends the auth_user table and adds its own + it should be because Askbot extends the auth_user table and adds its own fields. So we need to only push changes to the standard fields and leave - the rest alone so that Askbot changes at the Course DB level don't get + the rest alone so that Askbot changes at the Course DB level don't get overridden. """ try: @@ -457,7 +472,7 @@ def is_valid_course_id(course_id): """Right now, the only database that's not a course database is 'default'. I had nicer checking in here originally -- it would scan the courses that were in the system and only let you choose that. But it was annoying to run - tests with, since we don't have course data for some for our course test + tests with, since we don't have course data for some for our course test databases. Hence the lazy version. """ return course_id != 'default' diff --git a/common/djangoapps/student/tests.py b/common/djangoapps/student/tests.py index 16eec863799..4c7c9e25928 100644 --- a/common/djangoapps/student/tests.py +++ b/common/djangoapps/student/tests.py @@ -12,8 +12,10 @@ from django.test import TestCase from mock import patch, Mock from nose.plugins.skip import SkipTest -from .models import User, UserProfile, CourseEnrollment, replicate_user, USER_FIELDS_TO_COPY -from .views import process_survey_link, _cert_info, unique_id_for_user +from .models import (User, UserProfile, CourseEnrollment, + replicate_user, USER_FIELDS_TO_COPY, + unique_id_for_user) +from .views import process_survey_link, _cert_info COURSE_1 = 'edX/toy/2012_Fall' COURSE_2 = 'edx/full/6.002_Spring_2012' diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py index b354b8c20ab..ac3a97bd895 100644 --- a/common/djangoapps/student/views.py +++ b/common/djangoapps/student/views.py @@ -28,7 +28,7 @@ from django.core.cache import cache from django_future.csrf import ensure_csrf_cookie, csrf_exempt from student.models import (Registration, UserProfile, PendingNameChange, PendingEmailChange, - CourseEnrollment) + CourseEnrollment, unique_id_for_user) from certificates.models import CertificateStatuses, certificate_status_for_student @@ -39,7 +39,6 @@ from xmodule.modulestore.exceptions import ItemNotFoundError from datetime import date from collections import namedtuple -from hashlib import sha1 from courseware.courses import get_courses_by_university from courseware.access import has_access @@ -129,9 +128,6 @@ def press(request): return render_to_response('static_templates/press.html', {'articles': articles}) -def unique_id_for_user(user): - return sha1(user.username).hexdigest() - def process_survey_link(survey_link, user): """ If {UNIQUE_ID} appears in the link, replace it with a unique id for the user. -- GitLab