def custom_login_complete(request, **kwargs): """ Method invoked after successful OpenID login. Overridden to create user profile after first successful OpenID login. """ # authenticate user response = login_complete(request, **kwargs) # create a stub profile with blank mandatory fields if not request.user.is_anonymous(): openid = request.GET.get('openid.claimed_id', None) try: request.user.profile except ObjectDoesNotExist: print 'Discovering site for user with openid=%s' % openid # retrieve user home node site = discoverSiteForUser(openid) if site is None: # set user home node to current node site = Site.objects.get_current() print 'User site=%s... creating user profile...' % site # create new ESGF/OpenID login, type=2: ESGF UserProfile.objects.create(user=request.user, institution='', city='', country='', type=2, site=site) # create user datacart DataCart.objects.create(user=request.user) # set openid cookie set_openid_cookie(response, openid) # check if user is valid return _custom_login(request, response)
def password_update(request, user_id): """ View used by the user (or by a node administrator) to change their password. """ # redirect to another node if necessary if redirectToIdp(): return HttpResponseRedirect(settings.IDP_REDIRECT + request.path) # check permission: user that owns the account, or a node administrator user = get_object_or_404(User, id=user_id) if user != request.user and not request.user.is_staff: return HttpResponseServerError("You don't have permission to change the password for this user.") # check use has OpenID issued by this node if user.profile.localOpenid() is None: return HttpResponseForbidden("Non local user: password must be changed at the node that issued the OpenID.") if request.method == 'GET': # create form (pre-fill username) initial = {'username': user.username, # the target user 'requestor': request.user.username} # the user requesting the change form = PasswordChangeForm(initial=initial) return render_password_change_form(request, form, user.username) else: form = PasswordChangeForm(request.POST) if form.is_valid(): #user = User.objects.get(username=form.cleaned_data.get('username')) # change password in database user.set_password(form.cleaned_data.get('password')) user.save() user.profile.last_password_update = datetime.datetime.now() user.profile.save() # update ESGF user object if settings.ESGF_CONFIG: esgfDatabaseManager.updatePassword(user, form.cleaned_data.get('password')) # standard user: logout if user == request.user: logout(request) # redirect to login page with special message response = HttpResponseRedirect(reverse('login')+"?message=password_update") openid = user.profile.openid() if openid is not None: set_openid_cookie(response, openid) return response # administrator: back to user profile else: return HttpResponseRedirect(reverse('user_detail', kwargs={'user_id': user.id})+"?message=password_updated_by_admin") else: print "Form is invalid: %s" % form.errors return render_password_change_form(request, form, user.username)
def user_update(request, user_id): # security check if str(request.user.id) != user_id and not request.user.is_staff: raise Exception("User not authorized to change profile data") # get user user = get_object_or_404(User, pk=user_id) profile = get_object_or_404(UserProfile, user=user) # create URLs formset UserUrlFormsetFactory = modelformset_factory(UserUrl, form=UserUrlForm, exclude=('profile',), can_delete=True, extra=2) if request.method == 'GET': # pre-populate form, including value of extra field 'confirm_password' form = UserForm(instance=user, initial={'confirm_password': user.password, 'institution': profile.institution, 'city': profile.city, 'state': profile.state, 'country': profile.country, 'department': profile.department, 'researchKeywords': profile.researchKeywords, 'researchInterests': profile.researchInterests, 'subscribed': profile.subscribed, 'private': profile.private, 'image': profile.image, 'type': profile.type}) # retrieve existing URLs and OpenIDs associated to this user formset = UserUrlFormsetFactory(queryset=UserUrl.objects.filter(profile=profile), prefix='url') return render_user_form(request, form, formset, title='Update User Profile') else: # form with bounded data form = UserForm(request.POST, request.FILES, instance=user) # formset with bounded data formset = UserUrlFormsetFactory(request.POST, queryset=UserUrl.objects.filter(profile=profile), prefix='url') if form.is_valid(): # delete UserUrls if found urls = UserUrl.objects.filter(profile=profile) for url in urls: print 'Deleting user URL: %s' % url.url url.delete() # update user user = form.save() # old user profile user_profile = get_object_or_404(UserProfile, user=user) # capture user profile status before it is updated oldValidFlag = isUserValid(user) oldSubscribed = user_profile.subscribed # new user profile user_profile.institution = form.cleaned_data['institution'] user_profile.city = form.cleaned_data['city'] user_profile.state = form.cleaned_data['state'] user_profile.country = form.cleaned_data['country'] user_profile.department = form.cleaned_data['department'] user_profile.researchKeywords = form.cleaned_data['researchKeywords'] user_profile.researchInterests = form.cleaned_data['researchInterests'] user_profile.subscribed = form.cleaned_data['subscribed'] user_profile.private = form.cleaned_data['private'] # check if the password is encoded already # if not, encode the password that the user provided in clear text if not is_password_usable(user.password): user.set_password(form.cleaned_data['password']) user.save() print 'Reset password for user=%s' % user # image management _generateThumbnail = False if form.cleaned_data.get('delete_image'): deleteImageAndThumbnail(user_profile) elif form.cleaned_data['image'] is not None: # delete previous image try: deleteImageAndThumbnail(user_profile) except ValueError: # image not existing, ignore pass user_profile.image = form.cleaned_data['image'] _generateThumbnail = True # persist changes user_profile.save() # must assign URL to this user #urls = formset.save(commit=False) #for url in urls: # url.profile = profile # url.save() #for obj in formset.deleted_objects: # obj.delete() # generate thumbnail - after picture has been saved if _generateThumbnail: generateThumbnail(user_profile.image.path, THUMBNAIL_SIZE_SMALL) # subscribe/unsubscribe user if mailing list selection changed if oldSubscribed and form.cleaned_data['subscribed'] == False: if oldValidFlag: # send email only for non-new users unSubscribeUserToMailingList(user, request) elif oldSubscribed == False and form.cleaned_data['subscribed']: subscribeUserToMailingList(user, request) # update ESGF user object in ESGF database if settings.ESGF_CONFIG: esgfDatabaseManager.updateUser(user_profile) # redirect user profile page response = HttpResponseRedirect(reverse('user_detail', kwargs={'user_id': user.id})) # set openid cookie to first available openid set_openid_cookie(response, user.profile.openid()) return response else: if not form.is_valid(): print "Form is invalid: %s" % form.errors elif not formset.is_valid(): print "URL formset is invalid: %s" % formset.errors return render_user_form(request, form, formset, title='Update User Profile')
def user_add(request): # redirection URL _next = request.GET.get('next', None) or request.POST.get('next', None) # redirect to another node if necessary if redirectToIdp(): redirect_url = settings.IDP_REDIRECT + request.path if _next is not None: redirect_url += ("?next=%s" % urllib.quote_plus(_next)) print 'Redirecting account creation to: %s' % redirect_url return HttpResponseRedirect(redirect_url) # create URLs formset UserUrlFormsetFactory = modelformset_factory(UserUrl, form=UserUrlForm, exclude=('profile',), can_delete=True, extra=2) if request.method == 'GET': form = UserForm(initial={'next': _next}) # initialize form with redirect URL formset = UserUrlFormsetFactory(queryset=UserUrl.objects.none(), prefix='url') # empty formset return render_user_form(request, form, formset, title='Create User Profile') else: # form with bounded data form = UserForm(request.POST, request.FILES,) # formset with bounded data formset = UserUrlFormsetFactory(request.POST, queryset=UserUrl.objects.none(), prefix='url') if form.is_valid() and formset.is_valid(): # create a user from the form but don't save it to the database yet because the password is not encoded yet user = form.save(commit=False) # must reset the password through the special method that encodes it correctly clearTextPwd = form.cleaned_data['password'] user.set_password(clearTextPwd) # save user to database user.save() print 'Created user=%s' % user.username # create openid if settings.ESGF_CONFIG: openid = form.cleaned_data['openid'] print 'Creating openid=%s' % openid userOpenID = UserOpenID.objects.create(user=user, claimed_id=openid, display_id=openid) print 'Added openid=%s for user=%s into COG database' % (openid, user.username) # use additional form fields to create user profile userp = UserProfile(user=user, institution=form.cleaned_data['institution'], city=form.cleaned_data['city'], state=form.cleaned_data['state'], country=form.cleaned_data['country'], department=form.cleaned_data['department'], researchKeywords=form.cleaned_data['researchKeywords'], researchInterests=form.cleaned_data['researchInterests'], subscribed=form.cleaned_data['subscribed'], private=form.cleaned_data['private'], image=form.cleaned_data['image'], last_password_update=datetime.datetime.now()) # save user profile --> will trigger userProfile post_save userp.save() # NOTE: this field is NOT persisted in the CoG database but it is used by insertEsgfUser() below userp.clearTextPwd = clearTextPwd # insert into ESGF database if settings.ESGF_CONFIG: esgfDatabaseManager.insertEsgfUser(userp) # create user data cart datacart = DataCart(user=user) datacart.save() # must assign URL to this user urls = formset.save(commit=False) for url in urls: url.profile = userp url.save() # generate thumbnail image if userp.image is not None: try: generateThumbnail(userp.image.path, THUMBNAIL_SIZE_SMALL) except ValueError: pass # image does not exist, ignore # notify user, node administrators of new registration notifyUserOfRegistration(user) notifyAdminsOfUserRegistration(user,request) # subscribe to mailing list ? if userp.subscribed: subscribeUserToMailingList(user, request) # redirect to login page with special message login_url = reverse('login')+"?message=user_add" if _next is not None and len(_next.strip()) > 0: login_url += ("&next=%s" % urllib.quote_plus(_next)) # redirect to absolute URL (possibly at an another node) if 'http' in _next: url = urlparse(_next) login_url = '%s://%s%s' % (url.scheme, url.netloc, login_url) # append openid to initial login_url if userp.openid() is not None: login_url += "&openid=%s" % urllib.quote_plus(userp.openid()) login_url += "&username=%s" % urllib.quote_plus(userp.user.username) response = HttpResponseRedirect(login_url) # set openid cookie on this host set_openid_cookie(response, userp.openid()) print 'New user account created: redirecting to login url: %s' % login_url return response else: if not form.is_valid(): print "Form is invalid: %s" % form.errors elif not formset.is_valid(): print "URL formset is invalid: %s" % formset.errors return render_user_form(request, form, formset, title='Create User Profile')