Commit a3a124c0 by Pavel Yushchenko

New registration form

parent a983fdb2
...@@ -25,6 +25,7 @@ from django.db import models ...@@ -25,6 +25,7 @@ from django.db import models
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.dispatch import receiver from django.dispatch import receiver
from django.forms import ModelForm, forms from django.forms import ModelForm, forms
from django.utils.translation import ugettext_lazy as _
import comment_client as cc import comment_client as cc
from pytz import UTC from pytz import UTC
...@@ -61,6 +62,13 @@ class UserProfile(models.Model): ...@@ -61,6 +62,13 @@ class UserProfile(models.Model):
# This is not visible to other users, but could introduce holes later # This is not visible to other users, but could introduce holes later
user = models.OneToOneField(User, unique=True, db_index=True, related_name='profile') user = models.OneToOneField(User, unique=True, db_index=True, related_name='profile')
name = models.CharField(blank=True, max_length=255, db_index=True) name = models.CharField(blank=True, max_length=255, db_index=True)
lastname = models.CharField(blank=False, null=True, max_length=30, db_index=True)
firstname = models.CharField(blank=False, null=True, max_length=30, db_index=True)
middlename = models.CharField(blank=False, null=True, max_length=30, db_index=True)
meta = models.TextField(blank=True) # JSON dictionary for future expansion meta = models.TextField(blank=True) # JSON dictionary for future expansion
courseware = models.CharField(blank=True, max_length=255, default='course.xml') courseware = models.CharField(blank=True, max_length=255, default='course.xml')
...@@ -74,6 +82,7 @@ class UserProfile(models.Model): ...@@ -74,6 +82,7 @@ class UserProfile(models.Model):
this_year = datetime.now(UTC).year this_year = datetime.now(UTC).year
VALID_YEARS = range(this_year, this_year - 120, -1) VALID_YEARS = range(this_year, this_year - 120, -1)
year_of_birth = models.IntegerField(blank=True, null=True, db_index=True) year_of_birth = models.IntegerField(blank=True, null=True, db_index=True)
GENDER_CHOICES = (('m', 'Male'), ('f', 'Female'), ('o', 'Other')) GENDER_CHOICES = (('m', 'Male'), ('f', 'Female'), ('o', 'Other'))
gender = models.CharField( gender = models.CharField(
blank=True, null=True, max_length=6, db_index=True, choices=GENDER_CHOICES blank=True, null=True, max_length=6, db_index=True, choices=GENDER_CHOICES
...@@ -84,20 +93,108 @@ class UserProfile(models.Model): ...@@ -84,20 +93,108 @@ class UserProfile(models.Model):
# ('p_se', 'Doctorate in science or engineering'), # ('p_se', 'Doctorate in science or engineering'),
# ('p_oth', 'Doctorate in another field'), # ('p_oth', 'Doctorate in another field'),
LEVEL_OF_EDUCATION_CHOICES = ( LEVEL_OF_EDUCATION_CHOICES = (
('p', 'Doctorate'), ('p', _("Doctorate")),
('m', "Master's or professional degree"), ('m', _("Master's or professional degree")),
('b', "Bachelor's degree"), ('b', _("Bachelor's degree")),
('a', "Associate's degree"), ('a', _("Associate's degree")),
('hs', "Secondary/high school"), ('hs', _("Secondary/high school")),
('jhs', "Junior secondary/junior high/middle school"), ('jhs', _("Junior secondary/junior high/middle school")),
('el', "Elementary/primary school"), ('el', _("Elementary/primary school")),
('none', "None"), ('none', _("None")),
('other', "Other") ('other', _("Other"))
) )
level_of_education = models.CharField( level_of_education = models.CharField(
blank=True, null=True, max_length=6, db_index=True, blank=True, null=True, max_length=6, db_index=True,
choices=LEVEL_OF_EDUCATION_CHOICES choices=LEVEL_OF_EDUCATION_CHOICES
) )
education_place = models.CharField(blank=False, null=True, max_length=255, db_index=False)
education_year = models.IntegerField(blank=False, null=True, db_index=True)
education_qualification = models.CharField(blank=True, null=True, max_length=30)
education_specialty = models.CharField(blank=True, null=True, max_length=30)
WORK_TYPE_CHOICES = (
('sch', _("School")),
('lyc', _("Lyceum")),
('edc', _('Education Center')),
('gymn', _('Gymnasium')),
('edu', _('Educational complex')),
('kind', _('Kindergarten')),
('npe', _('Non-profit educational institution')),
('coll', _('College')),
('none', _('None')),
('other', _('Other'))
)
work_type = models.CharField(blank=False, null=True, max_length=6, choices=WORK_TYPE_CHOICES)
work_number = models.IntegerField(blank=False, null=True, db_index=True)
work_name = models.CharField(blank=False, null=True, max_length=255, db_index=False)
work_login = models.CharField(blank=False, null=True, max_length=10, db_index=False)
WORK_LOCATION_CHOICES = (
('CAO', 'Central Administrative Okrug'),
('EAO', 'Eastern Administrative Okrug'),
('WAO', 'Western Administrative Okrug'),
('NAO', 'Northern Administrative Okrug'),
('NEAO', 'North-Eastern Administrative Okrug'),
('NWAO', 'North-Western Administrative Okrug'),
('SWAO', 'South-Western Administrative Okrug'),
('SEAO', 'South-Eastern Administrative Okrug'),
('SAO', 'Southern Administrative Okrug'),
('zel', 'Zelenogradsky Administrative Okrug'),
('troi', 'Troitsky Administrative Okrug'),
('novo', 'Novomoskovsky Administrative Okrug'),
('city', 'Territorial units with special status'),
('non', 'None'),
('other', 'Other')
)
work_location = models.CharField(blank=False, null=True, max_length=6, db_index=False, choices=WORK_LOCATION_CHOICES)
WORK_OCCUPATION_CHOICES = (
('tchr', _('Teacher')),
('tchrorg', _('Teacher and organizer')),
('scltchr', _('Social teacher')),
('edupsy', _('Educational Psychologist')),
('care', _('Caregiver (including older)')),
('mng', _('Manager (Director, Head of) the educational institution')),
('vcmng', _('Vice manager (director, head of) the educational institution')),
('smstr', _('Senior master')),
('intr', _('Instructor')),
('tchrsp', _('Teacher-pathologists, speech therapists (speech therapist)')),
('tutor', _('Tutor')),
('tchrlib', _('Teacher-librarian')),
('slead', _('Senior leader')),
('tchredu', _('Teacher of additional education (including older)')),
('mushead', _('Musical head')),
('conc', _('Concertmaster')),
('mstrphy', _('Master of Physical Education')),
('instphy', _('Instructor of Physical Education')),
('meth', _('The Methodist (including older)')),
('instlab', _('Instructor for Labour')),
('instorg', _('Instructor-organizer life safety')),
('coach', _('Coach and teacher (including older)')),
('mstrind', _('Master of of industrial training')),
('dtreg', _('The duty on the regime (including older)')),
('lead', _('Leader')),
('ascare', _('Assistant caregiver')),
('juncare', _('Junior caregiver')),
('secr', _('Secretary of teaching department')),
('disp', _('Dispatcher of the educational institution')),
('other', _('Other'))
)
work_occupation = models.CharField(blank=False, null=True, max_length=10, db_index=False, choices=WORK_OCCUPATION_CHOICES)
work_occupation_other = models.CharField(blank=True, max_length=10, db_index=False, choices=WORK_OCCUPATION_CHOICES)
work_teaching_experience = models.IntegerField(blank=True, null=True, db_index=True)
work_managing_experience = models.IntegerField(blank=False, null=True, db_index=True)
WORK_QUALIFICATION_CATEGORY_CHOICES = (
('none', _("None")),
('high', _("High")),
('first', _("First")),
('second', _("Second"))
)
work_qualification_category = models.CharField(blank=False, null=True, max_length=10, db_index=False, choices=WORK_QUALIFICATION_CATEGORY_CHOICES)
work_qualification_category_year = models.IntegerField(blank=False, null=True, db_index=True)
contact_phone = models.CharField(blank=False, null=True, max_length=10, db_index=False)
mailing_address = models.TextField(blank=True, null=True) mailing_address = models.TextField(blank=True, null=True)
goals = models.TextField(blank=True, null=True) goals = models.TextField(blank=True, null=True)
allow_certificate = models.BooleanField(default=1) allow_certificate = models.BooleanField(default=1)
......
...@@ -526,7 +526,7 @@ def _do_create_account(post_vars): ...@@ -526,7 +526,7 @@ def _do_create_account(post_vars):
Note: this function is also used for creating test users. Note: this function is also used for creating test users.
""" """
user = User(username=post_vars['username'], user = User(username=post_vars['email'],
email=post_vars['email'], email=post_vars['email'],
is_active=False) is_active=False)
user.set_password(post_vars['password']) user.set_password(post_vars['password'])
...@@ -538,11 +538,6 @@ def _do_create_account(post_vars): ...@@ -538,11 +538,6 @@ def _do_create_account(post_vars):
except IntegrityError: except IntegrityError:
js = {'success': False} js = {'success': False}
# Figure out the cause of the integrity error # Figure out the cause of the integrity error
if len(User.objects.filter(username=post_vars['username'])) > 0:
js['value'] = _("An account with the Public Username '{username}' already exists.").format(username=post_vars['username'])
js['field'] = 'username'
return HttpResponse(json.dumps(js))
if len(User.objects.filter(email=post_vars['email'])) > 0: if len(User.objects.filter(email=post_vars['email'])) > 0:
js['value'] = _("An account with the Email '{email}' already exists.").format(email=post_vars['email']) js['value'] = _("An account with the Email '{email}' already exists.").format(email=post_vars['email'])
js['field'] = 'email' js['field'] = 'email'
...@@ -553,18 +548,34 @@ def _do_create_account(post_vars): ...@@ -553,18 +548,34 @@ def _do_create_account(post_vars):
registration.register(user) registration.register(user)
profile = UserProfile(user=user) profile = UserProfile(user=user)
profile.name = post_vars['name'] profile.lastname = post_vars.get('lastname')
profile.firstname = post_vars.get('firstname')
profile.middlename = post_vars.get('middlename')
profile.year_of_birth = post_vars.get('year_of_birth')
profile.level_of_education = post_vars.get('level_of_education') profile.level_of_education = post_vars.get('level_of_education')
profile.gender = post_vars.get('gender') profile.education_place = post_vars.get('education_place')
profile.mailing_address = post_vars.get('mailing_address') profile.education_year = post_vars.get('education_year')
profile.goals = post_vars.get('goals') profile.education_qualification = post_vars.get('education_qualification')
profile.education_specialty = post_vars.get('education_specialty')
try: profile.work_type = post_vars.get('work_type')
profile.year_of_birth = int(post_vars['year_of_birth']) profile.work_number = post_vars.get('work_number')
except (ValueError, KeyError): profile.work_name = post_vars.get('work_name')
# If they give us garbage, just ignore it instead profile.work_login = post_vars.get('work_login')
# of asking them to put an integer. profile.work_location = post_vars.get('work_location')
profile.year_of_birth = None profile.work_occupation = post_vars.get('work_occupation')
profile.work_occupation_other = post_vars.get('work_occupation_other')
profile.work_teaching_experience = post_vars.get('work_teaching_experience')
profile.work_managing_experience = post_vars.get('work_managing_experience')
profile.work_qualification_category = post_vars.get('work_qualification_category')
profile.work_qualification_category_year = post_vars.get('work_qualification_category_year')
profile.contact_phone = post_vars.get('contact_phone')
# try:
# profile.year_of_birth = int(post_vars['year_of_birth'])
# except (ValueError, KeyError):
# # If they give us garbage, just ignore it instead
# # of asking them to put an integer.
# profile.year_of_birth = None
try: try:
profile.save() profile.save()
except Exception: except Exception:
...@@ -603,7 +614,7 @@ def create_account(request, post_override=None): ...@@ -603,7 +614,7 @@ def create_account(request, post_override=None):
log.debug(u'In create_account with external_auth: user = %s, email=%s', name, email) log.debug(u'In create_account with external_auth: user = %s, email=%s', name, email)
# Confirm we have a properly formed request # Confirm we have a properly formed request
for a in ['username', 'email', 'password', 'name']: for a in ['email', 'password']:
if a not in post_vars: if a not in post_vars:
js['value'] = _("Error (401 {field}). E-mail us.").format(field=a) js['value'] = _("Error (401 {field}). E-mail us.").format(field=a)
js['field'] = a js['field'] = a
...@@ -631,7 +642,11 @@ def create_account(request, post_override=None): ...@@ -631,7 +642,11 @@ def create_account(request, post_override=None):
# this is a good idea # this is a good idea
# TODO: Check password is sane # TODO: Check password is sane
required_post_vars = ['username', 'email', 'name', 'password', 'terms_of_service', 'honor_code'] required_post_vars = ['email', 'password', 'lastname', 'firstname', 'middlename', 'year_of_birth',
'level_of_education', 'education_place', 'education_year',
'work_type', 'work_number', 'work_name', 'work_login', 'work_location',
'work_occupation', 'work_teaching_experience', 'work_qualification_category', 'work_qualification_category_year',
'contact_phone', 'terms_of_service', 'honor_code']
if tos_not_required: if tos_not_required:
required_post_vars = ['username', 'email', 'name', 'password', 'honor_code'] required_post_vars = ['username', 'email', 'name', 'password', 'honor_code']
...@@ -654,12 +669,12 @@ def create_account(request, post_override=None): ...@@ -654,12 +669,12 @@ def create_account(request, post_override=None):
js['field'] = 'email' js['field'] = 'email'
return HttpResponse(json.dumps(js)) return HttpResponse(json.dumps(js))
try: # try:
validate_slug(post_vars['username']) # validate_slug(post_vars['username'])
except ValidationError: # except ValidationError:
js['value'] = _("Username should only consist of A-Z and 0-9, with no spaces.").format(field=a) # js['value'] = _("Username should only consist of A-Z and 0-9, with no spaces.").format(field=a)
js['field'] = 'username' # js['field'] = 'username'
return HttpResponse(json.dumps(js)) # return HttpResponse(json.dumps(js))
# Ok, looks like everything is legit. Create the account. # Ok, looks like everything is legit. Create the account.
ret = _do_create_account(post_vars) ret = _do_create_account(post_vars)
...@@ -667,7 +682,7 @@ def create_account(request, post_override=None): ...@@ -667,7 +682,7 @@ def create_account(request, post_override=None):
return ret return ret
(user, profile, registration) = ret (user, profile, registration) = ret
d = {'name': post_vars['name'], d = {'name': post_vars['lastname'],
'key': registration.activation_key, 'key': registration.activation_key,
} }
...@@ -695,7 +710,7 @@ def create_account(request, post_override=None): ...@@ -695,7 +710,7 @@ def create_account(request, post_override=None):
# Immediately after a user creates an account, we log them in. They are only # 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 # logged in until they close the browser. They can't log in again until they click
# the activation link from the email. # the activation link from the email.
login_user = authenticate(username=post_vars['username'], password=post_vars['password']) login_user = authenticate(username=post_vars['email'], password=post_vars['password'])
login(request, login_user) login(request, login_user)
request.session.set_expiry(0) request.session.set_expiry(0)
...@@ -708,8 +723,8 @@ def create_account(request, post_override=None): ...@@ -708,8 +723,8 @@ def create_account(request, post_override=None):
eamap.user = login_user eamap.user = login_user
eamap.dtsignup = datetime.datetime.now(UTC) eamap.dtsignup = datetime.datetime.now(UTC)
eamap.save() eamap.save()
AUDIT_LOG.info("User registered with external_auth %s", post_vars['username']) AUDIT_LOG.info("User registered with external_auth %s", post_vars['email'])
AUDIT_LOG.info('Updated ExternalAuthMap for %s to be %s', post_vars['username'], eamap) AUDIT_LOG.info('Updated ExternalAuthMap for %s to be %s', post_vars['email'], eamap)
if settings.MITX_FEATURES.get('BYPASS_ACTIVATION_EMAIL_FOR_EXTAUTH'): if settings.MITX_FEATURES.get('BYPASS_ACTIVATION_EMAIL_FOR_EXTAUTH'):
log.info('bypassing activation email') log.info('bypassing activation email')
......
# Extraction from Python source files # Extraction from Python source files
#[python: cms/**.py] [python: cms/**.py]
#[python: lms/**.py] [python: lms/**.py]
#[python: common/**.py] [python: common/**.py]
# Extraction from Javscript source files # Extraction from Javscript source files
#[javascript: cms/**.js] [javascript: cms/**.js]
#[javascript: lms/**.js] [javascript: lms/**.js]
#[javascript: common/static/js/capa/**.js] [javascript: common/static/js/capa/**.js]
#[javascript: common/static/js/course_groups/**.js] [javascript: common/static/js/course_groups/**.js]
# do not extract from common/static/js/vendor/** # do not extract from common/static/js/vendor/**
# Extraction from Mako templates # Extraction from Mako templates
......
{ {
"locales" : ["en"], "locales" : ["en","ru"],
"dummy-locale" : "fr" "dummy-locale" : "fr"
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment