Пример #1
0
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)
Пример #2
0
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)
Пример #3
0
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')
Пример #4
0
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')