From: Sofia Papagiannaki Date: Fri, 16 Nov 2012 14:34:23 +0000 (+0200) Subject: Customize third party signup form fields X-Git-Url: https://code.grnet.gr/git/astakos/commitdiff_plain/678b2236de5d9cd11bf4cc65519d57b95ffa053b Customize third party signup form fields Refs: #3041 --- diff --git a/snf-astakos-app/README b/snf-astakos-app/README index 617ea32..11aa53e 100644 --- a/snf-astakos-app/README +++ b/snf-astakos-app/README @@ -91,6 +91,8 @@ ASTAKOS_EMAIL_CHANGE_EMAIL_SUBJECT 'Email change on %s alpha2 testing' ASTAKOS_PASSWORD_RESET_EMAIL_SUBJECT 'Password reset on %s alpha2 testing' % SITENAME Password change email subject ASTAKOS_NEWPASSWD_INVALIDATE_TOKEN True Enforce token renewal on password change/reset. If set to False, user can optionally decide whether to renew the token or not. +ASTAKOS_ENABLE_LOCAL_ACCOUNT_MIGRATION True Permit local account migration to third party account +ASTAKOS_THIRDPARTY_ACC_ADDITIONAL_FIELDS {'first_name':None, 'last_name':None} The additional user fields appearing during the second step of third party account creation =========================================== ============================================================================= =========================================================================================== Administrator functions diff --git a/snf-astakos-app/astakos/im/activation_backends.py b/snf-astakos-app/astakos/im/activation_backends.py index 71b0abe..7f6b5ae 100644 --- a/snf-astakos-app/astakos/im/activation_backends.py +++ b/snf-astakos-app/astakos/im/activation_backends.py @@ -101,11 +101,11 @@ class ActivationBackend(object): initial_data = request.POST return globals()[formclass](initial_data, instance=instance, request=request) - def handle_activation(self, user, \ - activation_template_name='im/activation_email.txt', \ - greeting_template_name='im/welcome_email.txt', \ - admin_email_template_name='im/admin_notification.txt', \ - switch_accounts_email_template_name='im/switch_accounts_email.txt'): + def handle_activation( + self, user, activation_template_name='im/activation_email.txt', + greeting_template_name='im/welcome_email.txt', + admin_email_template_name='im/admin_notification.txt' + ): """ If the user is already active returns immediately. If the user is not active and there is another account associated with @@ -120,9 +120,6 @@ class ActivationBackend(object): try: if user.is_active: return RegistationCompleted() - if user.conflicting_email(): - send_verification(user, switch_accounts_email_template_name) - return SwitchAccountsVerificationSent(user.email) if self._is_preaccepted(user): if user.email_verified: @@ -231,14 +228,6 @@ class VerificationSent(ActivationResult): message = _('Verification sent.') super(VerificationSent, self).__init__(message) -class SwitchAccountsVerificationSent(ActivationResult): - def __init__(self, email): - message = _('This email is already associated with another \ - local account. To change this account to a shibboleth \ - one follow the link in the verification email sent \ - to %s. Otherwise just ignore it.' % email) - super(SwitchAccountsVerificationSent, self).__init__(message) - class NotificationSent(ActivationResult): def __init__(self): message = _('Your request for an account was successfully received and is now pending \ diff --git a/snf-astakos-app/astakos/im/forms.py b/snf-astakos-app/astakos/im/forms.py index 28c76a5..3e498db 100644 --- a/snf-astakos-app/astakos/im/forms.py +++ b/snf-astakos-app/astakos/im/forms.py @@ -46,8 +46,12 @@ from django.utils.functional import lazy from django.utils.safestring import mark_safe from django.contrib import messages from django.utils.encoding import smart_str +from django.forms.models import fields_for_model -from astakos.im.models import AstakosUser, Invitation, get_latest_terms, EmailChange +from astakos.im.models import ( + AstakosUser, Invitation, get_latest_terms, + EmailChange, PendingThirdPartyUser +) from astakos.im.settings import (INVITATIONS_PER_LEVEL, DEFAULT_FROM_EMAIL, BASEURL, SITENAME, RECAPTCHA_PRIVATE_KEY, DEFAULT_CONTACT_EMAIL, RECAPTCHA_ENABLED, LOGGING_LEVEL, PASSWORD_RESET_EMAIL_SUBJECT, @@ -189,7 +193,7 @@ class ThirdPartyUserCreationForm(forms.ModelForm): ) class Meta: model = AstakosUser - fields = ("email", "first_name", "last_name", "third_party_identifier", "has_signed_terms") + fields = ['email', 'third_party_identifier'] def __init__(self, *args, **kwargs): """ @@ -202,7 +206,7 @@ class ThirdPartyUserCreationForm(forms.ModelForm): latest_terms = get_latest_terms() if latest_terms: self._meta.fields.append('has_signed_terms') - + super(ThirdPartyUserCreationForm, self).__init__(*args, **kwargs) if latest_terms: @@ -215,7 +219,17 @@ class ThirdPartyUserCreationForm(forms.ModelForm): % (reverse('latest_terms'), _("the terms")) self.fields['has_signed_terms'].label = \ mark_safe("I agree with %s" % terms_link_html) - + + default = fields_for_model( + self._meta.model, + THIRDPARTY_ACC_ADDITIONAL_FIELDS.keys() + ) + for fname, field in THIRDPARTY_ACC_ADDITIONAL_FIELDS.iteritems(): + if field: + self.fields[fname] = field + self.fields.setdefault(fname, default.get(fname)) + self.initial[fname] = getattr(self.instance, fname, None) + def clean_email(self): email = self.cleaned_data['email'] if not email: @@ -287,6 +301,19 @@ class ShibbolethUserCreationForm(ThirdPartyUserCreationForm): raise forms.ValidationError(_("This email is already used")) super(ShibbolethUserCreationForm, self).clean_email() return email + + def save(self, commit=True): + user = super(ShibbolethUserCreationForm, self).save(commit=False) + try: + p = PendingThirdPartyUser.objects.get( + provider=user.provider, + third_party_identifier=user.third_party_identifier + ) + except: + pass + else: + p.delete() + return user class InvitedShibbolethUserCreationForm(ShibbolethUserCreationForm, InvitedThirdPartyUserCreationForm): pass diff --git a/snf-astakos-app/astakos/im/migrations/0015_auto__add_pendingthirdpartyuser.py b/snf-astakos-app/astakos/im/migrations/0015_auto__add_pendingthirdpartyuser__add_unique_pendingthirdpartyuser_prov.py similarity index 92% rename from snf-astakos-app/astakos/im/migrations/0015_auto__add_pendingthirdpartyuser.py rename to snf-astakos-app/astakos/im/migrations/0015_auto__add_pendingthirdpartyuser__add_unique_pendingthirdpartyuser_prov.py index b98787c..ecef52a 100644 --- a/snf-astakos-app/astakos/im/migrations/0015_auto__add_pendingthirdpartyuser.py +++ b/snf-astakos-app/astakos/im/migrations/0015_auto__add_pendingthirdpartyuser__add_unique_pendingthirdpartyuser_prov.py @@ -13,7 +13,7 @@ class Migration(SchemaMigration): ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('third_party_identifier', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)), ('provider', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)), - ('email', self.gf('django.db.models.fields.EmailField')(max_length=75, blank=True)), + ('email', self.gf('django.db.models.fields.EmailField')(max_length=75, null=True, blank=True)), ('first_name', self.gf('django.db.models.fields.CharField')(max_length=30, blank=True)), ('last_name', self.gf('django.db.models.fields.CharField')(max_length=30, blank=True)), ('affiliation', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)), @@ -21,9 +21,15 @@ class Migration(SchemaMigration): )) db.send_create_signal('im', ['PendingThirdPartyUser']) + # Adding unique constraint on 'PendingThirdPartyUser', fields ['provider', 'third_party_identifier'] + db.create_unique('im_pendingthirdpartyuser', ['provider', 'third_party_identifier']) + def backwards(self, orm): + # Removing unique constraint on 'PendingThirdPartyUser', fields ['provider', 'third_party_identifier'] + db.delete_unique('im_pendingthirdpartyuser', ['provider', 'third_party_identifier']) + # Deleting model 'PendingThirdPartyUser' db.delete_table('im_pendingthirdpartyuser') @@ -73,7 +79,7 @@ class Migration(SchemaMigration): }, 'im.approvalterms': { 'Meta': {'object_name': 'ApprovalTerms'}, - 'date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 11, 15, 13, 7, 38, 626139)', 'db_index': 'True'}), + 'date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 11, 16, 11, 52, 33, 987227)', 'db_index': 'True'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'location': ('django.db.models.fields.CharField', [], {'max_length': '255'}) }, @@ -101,7 +107,7 @@ class Migration(SchemaMigration): 'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'new_email_address': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), - 'requested_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 11, 15, 13, 7, 38, 627944)'}), + 'requested_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 11, 16, 11, 52, 33, 988935)'}), 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'emailchange_user'", 'unique': 'True', 'to': "orm['im.AstakosUser']"}) }, 'im.invitation': { @@ -116,9 +122,9 @@ class Migration(SchemaMigration): 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}) }, 'im.pendingthirdpartyuser': { - 'Meta': {'object_name': 'PendingThirdPartyUser'}, + 'Meta': {'unique_together': "(('provider', 'third_party_identifier'),)", 'object_name': 'PendingThirdPartyUser'}, 'affiliation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), diff --git a/snf-astakos-app/astakos/im/models.py b/snf-astakos-app/astakos/im/models.py index 3600810..7099b0c 100644 --- a/snf-astakos-app/astakos/im/models.py +++ b/snf-astakos-app/astakos/im/models.py @@ -380,11 +380,14 @@ class PendingThirdPartyUser(models.Model): """ third_party_identifier = models.CharField('Third-party identifier', max_length=255, null=True, blank=True) provider = models.CharField('Provider', max_length=255, blank=True) - email = models.EmailField(_('e-mail address'), blank=True) + email = models.EmailField(_('e-mail address'), blank=True, null=True) first_name = models.CharField(_('first name'), max_length=30, blank=True) last_name = models.CharField(_('last name'), max_length=30, blank=True) affiliation = models.CharField('Affiliation', max_length=255, blank=True) username = models.CharField(_('username'), max_length=30, unique=True, help_text=_("Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters")) + + class Meta: + unique_together = ("provider", "third_party_identifier") @property def realname(self): diff --git a/snf-astakos-app/astakos/im/settings.py b/snf-astakos-app/astakos/im/settings.py index e674108..2e035c3 100644 --- a/snf-astakos-app/astakos/im/settings.py +++ b/snf-astakos-app/astakos/im/settings.py @@ -124,7 +124,7 @@ NEWPASSWD_INVALIDATE_TOKEN = getattr(settings, 'ASTAKOS_NEWPASSWD_INVALIDATE_TOK # Permit local account migration ENABLE_LOCAL_ACCOUNT_MIGRATION = getattr(settings, 'ASTAKOS_ENABLE_LOCAL_ACCOUNT_MIGRATION', True) -# A dictionary describing the user fields appearing during the second step of third party account creation +# A dictionary describing the additional user fields appearing during the second step of third party account creation from django import forms THIRDPARTY_ACC_ADDITIONAL_FIELDS = getattr(settings, 'ASTAKOS_THIRDPARTY_ACC_ADDITIONAL_FIELDS', { 'first_name':None, diff --git a/snf-astakos-app/astakos/im/target/shibboleth.py b/snf-astakos-app/astakos/im/target/shibboleth.py index 955c7e3..8c88669 100644 --- a/snf-astakos-app/astakos/im/target/shibboleth.py +++ b/snf-astakos-app/astakos/im/target/shibboleth.py @@ -72,7 +72,8 @@ def login( request, on_login_template='im/login.html', on_signup_template='im/third_party_check_local.html', - extra_context=None): + extra_context=None +): extra_context = extra_context or {} tokens = request.META @@ -149,10 +150,11 @@ def login( @require_http_methods(["GET"]) @requires_anonymous -def signup(request, - backend=None, - on_creation_template='im/third_party_registration.html', - extra_context=None +def signup( + request, + backend=None, + on_creation_template='im/third_party_registration.html', + extra_context=None ): extra_context = extra_context or {} username = request.GET.get('key') diff --git a/snf-astakos-app/astakos/im/views.py b/snf-astakos-app/astakos/im/views.py index 684be53..86e54a1 100644 --- a/snf-astakos-app/astakos/im/views.py +++ b/snf-astakos-app/astakos/im/views.py @@ -356,6 +356,7 @@ def signup(request, template_name='im/signup.html', on_success='im/signup_comple message = e.message messages.add_message(request, status, message) except BaseException, e: + logger.exception(e) status = messages.ERROR message = _('Something went wrong.') messages.add_message(request, status, message) diff --git a/snf-astakos-app/conf/20-snf-astakos-app-settings.conf b/snf-astakos-app/conf/20-snf-astakos-app-settings.conf index b0f2291..b26cd58 100644 --- a/snf-astakos-app/conf/20-snf-astakos-app-settings.conf +++ b/snf-astakos-app/conf/20-snf-astakos-app-settings.conf @@ -112,4 +112,13 @@ #ASTAKOS_PASSWORD_RESET_EMAIL_SUBJECT = 'Password reset on %s alpha2 testing' % SITENAME # Enforce token renewal on password change/reset -NEWPASSWD_INVALIDATE_TOKEN = getattr(settings, 'ASTAKOS_NEWPASSWD_INVALIDATE_TOKEN', True) \ No newline at end of file +# NEWPASSWD_INVALIDATE_TOKEN = getattr(settings, 'ASTAKOS_NEWPASSWD_INVALIDATE_TOKEN', True) + +# Permit local account migration +# ENABLE_LOCAL_ACCOUNT_MIGRATION = getattr(settings, 'ASTAKOS_ENABLE_LOCAL_ACCOUNT_MIGRATION', True) + +# A dictionary describing the additional user fields appearing during the second step of third party account creation +# THIRDPARTY_ACC_ADDITIONAL_FIELDS = getattr(settings, 'ASTAKOS_THIRDPARTY_ACC_ADDITIONAL_FIELDS', { +# 'first_name':None, +# 'last_name':None, +# }) \ No newline at end of file