def handle(self, *args, **options): openid = args[0] new_password = args[1] self.stdout.write("Setting new password=%s for openid=%s" % (new_password, openid) ) try: # retrieve user from CoG database userOpenid = UserOpenID.objects.get(claimed_id=openid) # update password in ESGF database esgfDatabaseManager.updatePassword(userOpenid.user, new_password) except ObjectDoesNotExist: self.stdout.write("User with openid=%s not found in local database." % openid)
def password_reset(request): # redirect to another node if necessary if redirectToIdp(): return HttpResponseRedirect(settings.IDP_REDIRECT + request.path) if request.method == 'GET': # optional GET parameters to pre-populate the form initial = {'openid': request.GET.get('openid', ''), 'email': request.GET.get('email', '')} form = PasswordResetForm(initial=initial) return render_password_reset_form(request, form) else: form = PasswordResetForm(request.POST) # check form is valid first if not form.is_valid(): print "Form is invalid: %s" % form.errors return render_password_reset_form(request, form) openid = form.cleaned_data.get('openid') email = form.cleaned_data.get('email') # the openid entered by the user MUST be found in the local database # otherwise we can neither change the password, nor we can redirect to a known node try: userOpenid = UserOpenID.objects.get(claimed_id=openid) user = userOpenid.user # 1) local user (i.e. user home node == this node) if isUserLocal(user): # 1a) this node issued this openid if isOpenidLocal(openid): if user.email == email: # generate new random password # prepend "AB1-" to satisfy mandatory requirements new_password = "******"+User.objects.make_random_password(length=8) # change password in database user.set_password(new_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, new_password) # logout user (if logged in) logout(request) # user profile url url = reverse('user_detail', kwargs={'user_id': user.id}) url = request.build_absolute_uri(url) # send email to user subject = "Password Reset" message = "Your new password has been set to: %s\n" % new_password message += "Your openid is: %s\n" % user.profile.openid() message += "For security reasons, please change this password as soon as you log in.\n" message += "To change your password, first log in with your openid and new password,\n" message += "then click on the 'My Profile' link on the top-right of each page,\n" message += "or visit the following URL: %s" % url notify(user, subject, message) # redirect to login page with special message return HttpResponseRedirect(reverse('login')+"?message=password_reset") else: return render_password_reset_form(request, form, "Invalid OpenID/email combination") # 1b) user used an external ESGF openid (for example, http://dkrz...) to login onto this node # (for example, http://www.earthsystemcog.org/...) else: idpurl = urlparse(openid) idpurl = "%s://%s/" % (idpurl.scheme, idpurl.netloc) message = "This OpenID was issued by another node." message += "<br/>Please reset your password at <a href='%s'>that node</a>." % idpurl return render_password_reset_form(request, form, message) # 2) non-local user: redirect request to peer node, post automatically else: site = user.profile.site redirect_url = 'http://%s%s?openid=%s&email=%s' % (site.domain, reverse('password_reset'), openid, email) # 2a) automatically redirect to peer node #redirect_url += "&post=true" # submit form automatically at that node #return HttpResponseRedirect(redirect_url) # 2b) show message on this node with link to peer node message = "This OpenID was issued by another ESG-CoG node." message += "<br/>Please use the <a href='%s'>Reset Password</a> page at that node." % redirect_url return render_password_reset_form(request, form, message) # openid not found except UserOpenID.DoesNotExist: message = "OpenID not found." message += "<br/>If your OpenID was issued by '%s'," % settings.ESGF_HOSTNAME message += "<br/>then please use the 'Forgot OpenID?' link below to retrieve the correct OpenID." message += "<br/>Otherwise, please reset your password on the ESGF-CoG node that issued your OpenID." return render_password_reset_form(request, form, message)
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)