Mercurial > personas_backend
changeset 64:5f21f8d3334b
Only users who have the personas.can_publish permission or who own a persona can edit them now; added more workflow logic. I'm not entirely happy with the way the workflow logic is structured right now, but this seems to work okay for the time being.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Tue, 11 Mar 2008 14:15:43 -0500 |
parents | ec4f7cbb1ae2 |
children | f54ea1612d1e |
files | PersonasBackend/personas/forms.py PersonasBackend/personas/models.py PersonasBackend/personas/templates/personas/list.html PersonasBackend/personas/views.py |
diffstat | 4 files changed, 85 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/PersonasBackend/personas/forms.py Tue Mar 11 11:40:00 2008 -0500 +++ b/PersonasBackend/personas/forms.py Tue Mar 11 14:15:43 2008 -0500 @@ -1,7 +1,22 @@ from django.newforms import ModelForm from PersonasBackend.personas import models -class PersonaForm( ModelForm ): +class StandardPersonaForm( ModelForm ): + """ + Form given to normal users who don't have the permission to + publish Personas. + """ + class Meta: model = models.Persona exclude = ["owner", "status", "updater"] + +class PublisherPersonaForm( ModelForm ): + """ + Form given to admin/staff users who have the permission to publish + Personas. + """ + + class Meta: + model = models.Persona + exclude = ["updater"]
--- a/PersonasBackend/personas/models.py Tue Mar 11 11:40:00 2008 -0500 +++ b/PersonasBackend/personas/models.py Tue Mar 11 14:15:43 2008 -0500 @@ -122,6 +122,11 @@ class Admin: pass + class Meta: + permissions = ( + ("can_publish", "Can publish"), + ) + MAX_NAME_LENGTH = 50 name = models.CharField( @@ -218,6 +223,8 @@ User, help_text="The user who made this revision.", related_name="changed_personas", + # TODO: Consider making this null=False. Keeping it true + # makes it easier to write tests, though. null=True, ) @@ -237,7 +244,6 @@ ("unpublished", "Unpublished"), ("deleted", "Deleted")), blank=False, - default="unpublished", help_text=("Status of the Persona; can be deleted, published, " "or unpublished (i.e., pending for review).") ) @@ -344,20 +350,53 @@ """ if self.id == None: + # We're a brand-new Persona. self.revision = 0 + if not self.owner: + self.owner = self.updater + assert self.owner == self.updater + if ( not self.status ) and self.updater: + if self.updater.has_perm( "personas.can_publish" ): + # If the person creating the Persona can publish + # Personas, mark this new Persona as published, by + # default. + self.status = "published" + else: + # Otherwise, mark this new Persona as unpublished by + # default. + self.status = "unpublished" else: - # TODO: See who made the update; depending on how much we - # trust them, this may mean: - # - # * rejecting the change, - # * accepting the changes but marking the persona's - # status as "unpublished", - # * accepting the changes. + # We're an existing Persona that's being modified. + + if self.updater: + if not self.can_user_edit( self.updater ): + # The user can't actually edit this Persona, reject + # the change. View logic should've prevented this + # from ever being the case, so we're going to be + # ungraceful here. + raise AssertionError( "User can't edit this persona." ) + + if ( self.status == "published" and + not self.updater.has_perm( "personas.can_publish" ) ): + # The Persona is currently published, but a user + # without publishing permissions has just changed it, + # so mark it as unpublished so an editor can review it + # before re-publishing it. + + self.status = "unpublished" self.__make_new_revision() super(Persona, self).save() + def can_user_edit( self, user ): + """ + Returns whether the given User can edit this Persona. + """ + + return ( user.has_perm( "personas.can_publish" ) or + self.owner == user ) + class Revision(models.Model): """ Represents an old revision of a Persona.
--- a/PersonasBackend/personas/templates/personas/list.html Tue Mar 11 11:40:00 2008 -0500 +++ b/PersonasBackend/personas/templates/personas/list.html Tue Mar 11 14:15:43 2008 -0500 @@ -7,6 +7,13 @@ <div class="addon-listitem clearfix-right corner-box"> <h2 class="addonname">{{ persona.name }}</h2> <div class="addon-desc">{{ persona.description }}</div> + {% ifequal persona.owner user %} + <a href="{% url edit-persona persona.id %}">Edit</a> + {% else %} + {% if perms.personas.can_publish %} + <a href="{% url edit-persona persona.id %}">Edit</a> + {% endif %} + {% endifequal %} </div> {% endfor %} {% else %}
--- a/PersonasBackend/personas/views.py Tue Mar 11 11:40:00 2008 -0500 +++ b/PersonasBackend/personas/views.py Tue Mar 11 14:15:43 2008 -0500 @@ -1,4 +1,4 @@ -from django.http import HttpResponseRedirect +from django.http import HttpResponseRedirect, HttpResponseForbidden from django.template import RequestContext from django.contrib.auth.decorators import login_required from django.core.urlresolvers import reverse @@ -68,34 +68,41 @@ @login_required def edit_view( request, persona_id=None ): - # TODO: Perform permissions check to see if user has - # the rights to edit the persona or create a new one. if persona_id is None: persona = None pageTitle = "Create a new Persona" else: persona = get_object_or_404( models.Persona, id=persona_id ) + if not persona.can_user_edit( request.user ): + return HttpResponseForbidden( + "<h1>You do not have permission to edit " + "this Persona.</h1>" + ) pageTitle = "Edit Persona" + if request.user.has_perm( "personas.can_publish" ): + PersonaForm = forms.PublisherPersonaForm + else: + PersonaForm = forms.StandardPersonaForm + if request.method == "POST": for img_name in request.FILES: _rename_file( request.FILES[img_name], persona ) - form = forms.PersonaForm( request.POST, request.FILES, - instance=persona ) + form = PersonaForm( request.POST, request.FILES, + instance=persona ) if form.is_valid(): newPersona = form.save( commit=False ) newPersona.updater = request.user + newPersona.save() if persona is None: msgText = "Persona created successfully." - newPersona.owner = request.user else: msgText = "Persona edited successfully." - newPersona.save() request.user.message_set.create( message = msgText ) url = reverse("edit-persona", args=[newPersona.id]) return HttpResponseRedirect( url ) else: - form = forms.PersonaForm( instance=persona ) + form = PersonaForm( instance=persona ) return render_to_response( "personas/edit.html",