示例#1
0
文件: views.py 项目: stencila/hub
def accept(request, string):
    """
    @brief      View for accepting an invitation
    
    @param      request  The request
    @param      string   The string
    """
    api = API(request)

    # Get the invitation
    try:
        invitation = Invitation.objects.get(string=string)
    except Invitation.DoesNotExist:
        return api.raise_not_found()

    # If the invitatation has already expired, let the user know
    if invitation.sent + datetime.timedelta(days=invitation.expiry) < timezone.now():
        return render(request, 'invitations/expired.html', dict(
            invitation=invitation
        ))

    # Check whether the user need to be authenticated first
    if not request.user.is_authenticated():
        authed = False
    elif request.user.details.guest:
        # Logout the guest
        # TODO it would be better to "join up" the guest
        authed = False
    else:
        authed = True

    if authed:
        # Add the user to the key and redirect them to the path
        invitation.key.users.add(request.user)
        invitation.accepted = timezone.now()
        invitation.accepter = request.user
        invitation.save()
        return redirect(invitation.path)
    else:
        # Authenticate the user...
        if invitation.accepted:
            # Don't Offer the "express" login where we create
            # a new user if this invitation has already been accepted
            express_username = None
        else:
            # Create a username for "express" signin
            base = invitation.invitee.split('@')[0]
            express_username = base
            trials = 0
            while True:
                if User.objects.filter(username=express_username).count() == 0:
                    break
                trials += 1
                if trials > 1000000:
                    raise Exception("Maximum number of ")
                express_username = '******' %(base, trials)

        # URL for redirect when using third party account
        # to login (come back to this view and get redirected)
        next = '/invitations/%s/accept' % string

        if api.get:
            # Render athentication forms
            return render(request, 'invitations/accept.html', dict(
                invitation=invitation,
                next=next,
                userpass_form=AuthenticationForm(),
                express_username=express_username
            ))
        elif api.post:
            if request.POST.get('userpass_signin'):
                # Attempt to signin with username/password
                form = AuthenticationForm(data=request.POST)
                if not form.is_valid():
                    # Display errors
                    return render(request, 'invitations/accept.html', dict(
                        invitation=invitation,
                        next=next,
                        userpass_form=form,
                        express_username=express_username
                    ))
                else:
                    # Login the user and then proceed with accept view
                    login(request, form.get_user())
                    # Continue recursively
                    return accept(request, string)
            elif express_username and request.POST.get('express_signin'):
                # Create a new user and log them in 
                user = User.objects.create_user(
                    username=express_username,
                    email=invitation.invitee
                )
                user.backend = 'django.contrib.auth.backends.ModelBackend'
                login(request, user)
                # Continue recursively
                return accept(request, string)
            else:
                # Some thing else, just go back the page
                return redirect(next)
        else:
            return api.respond_bad()