Add access control to document model and view
The access checks are not yet written, but at least the model is
stable from now on.
Also converted the document view to dynaform while at it.
Patch by: Sverre Rabbelier
--- a/app/soc/logic/models/document.py Fri Jan 30 22:00:49 2009 +0000
+++ b/app/soc/logic/models/document.py Fri Jan 30 22:01:27 2009 +0000
@@ -42,6 +42,24 @@
super(Logic, self).__init__(model=model, base_model=base_model,
scope_logic=scope_logic)
+ def getKeyValues(self, entity):
+ """See base.Logic.getKeyNameValues.
+ """
+
+ return [entity.prefix, entity.scope_path, entity.link_id]
+
+ def getKeyValuesFromFields(self, fields):
+ """See base.Logic.getKeyValuesFromFields.
+ """
+
+ return [fields['prefix'], fields['scope_path'], fields['link_id']]
+
+ def getKeyFieldNames(self):
+ """See base.Logic.getKeyFieldNames.
+ """
+
+ return ['prefix', 'scope_path', 'link_id']
+
def _updateField(self, entity, name, value):
"""Special logic for role. If state changes to active we flush the sidebar.
"""
--- a/app/soc/models/document.py Fri Jan 30 22:00:49 2009 +0000
+++ b/app/soc/models/document.py Fri Jan 30 22:01:27 2009 +0000
@@ -46,6 +46,34 @@
URL_NAME = 'document'
+ #: field storing the prefix of this document
+ prefix = db.StringProperty(default='user',
+ choices=['site','sponsor','program', 'club', 'organization', 'user'],
+ verbose_name=ugettext('Prefix'))
+ prefix.help_text = ugettext(
+ 'Indicates the prefix of the document,'
+ ' determines which access scheme is used.')
+
+ #: field storing the access status of this document
+ # wiki = any user can read and write the document
+ # public = any user can read, only restricted can write
+ # member = member can read, only restricted can write
+ # restricted = restricted can read, only admin can write
+ # admin = admin can read, only admin can write
+ #
+ # example meanings for an organisations:
+ # admin = ['org_admin']
+ # restricted = ['org_admin', 'org_mentor']
+ # member = ['org_admin', 'org_mentor', 'org_student']
+ # public = anyone
+ # wiki = anyone
+ access_status = db.StringProperty(default='restricted', required=True,
+ choices=['admin','restricted', 'member', 'public', 'wiki'],
+ verbose_name=ugettext('Access type'))
+ access_status.help_text = ugettext(
+ 'Indicates the state of the document, '
+ 'determines the access scheme.')
+
#: field storing whether a link to the Document should be featured in
#: the sidebar menu (and possibly elsewhere); FAQs, Terms of Service,
#: and the like are examples of "featured" Document
--- a/app/soc/models/work.py Fri Jan 30 22:00:49 2009 +0000
+++ b/app/soc/models/work.py Fri Jan 30 22:01:27 2009 +0000
@@ -80,16 +80,6 @@
collection_name="modified_documents",
verbose_name=ugettext('Modified by'))
- # TODO: some sort of access control preferences are needed at this basic
- # level. Works need to be restrict-able to:
- # * the authors only
- # * the administrators of the Groups that the authors are in
- # * any member of the authors' Groups
- # * logged-in User with a profile
- # * logged-in Users, but no profile is necessary
- # * anyone, even those not logged in
- # (and possibly others)
-
def name(self):
"""Alias 'title' Property as 'name' for use in common templates.
"""
--- a/app/soc/views/models/document.py Fri Jan 30 22:00:49 2009 +0000
+++ b/app/soc/views/models/document.py Fri Jan 30 22:01:27 2009 +0000
@@ -28,12 +28,16 @@
from django import forms
+from soc.logic import cleaning
from soc.logic import dicts
from soc.logic import validate
-from soc.logic.models import user as user_logic
+from soc.logic.models.user import logic as user_logic
+from soc.logic.models.document import logic as document_logic
+from soc.models import linkable
from soc.views import helper
from soc.views.helper import access
from soc.views.helper import redirects
+from soc.views.helper import params as params_helper
from soc.views.models import base
import soc.models.document
@@ -43,47 +47,6 @@
import soc.views.helper.widgets
-class CreateForm(helper.forms.BaseForm):
- """Django form displayed when Developer creates a Document.
- """
-
- content = forms.fields.CharField(widget=helper.widgets.TinyMCE(
- attrs={'rows':10, 'cols':40}))
-
- class Meta:
- """Inner Meta class that defines some behavior for the form.
- """
- model = soc.models.document.Document
-
- #: list of model fields which will *not* be gathered by the form
- exclude = ['author', 'created', 'modified_by', 'modified', 'scope']
-
- def clean_scope_path(self):
- scope_path = self.cleaned_data.get('scope_path')
- # TODO(tlarsen): combine path and link_id and check for uniqueness
- if not validate.isScopePathFormatValid(scope_path):
- raise forms.ValidationError("This scope path is in wrong format.")
- return scope_path
-
- def clean_link_id(self):
- link_id = self.cleaned_data.get('link_id').lower()
- # TODO(tlarsen): combine path and link_id and check for uniqueness
- if not validate.isLinkIdFormatValid(link_id):
- raise forms.ValidationError("This link ID is in wrong format.")
- return link_id
-
-
-class EditForm(CreateForm):
- """Django form displayed a Document is edited.
- """
-
- doc_key_name = forms.fields.CharField(widget=forms.HiddenInput)
- created_by = forms.fields.CharField(widget=helper.widgets.ReadOnlyInput(),
- required=False)
- last_modified_by = forms.fields.CharField(
- widget=helper.widgets.ReadOnlyInput(), required=False)
-
-
class View(base.View):
"""View methods for the Document model.
"""
@@ -101,15 +64,44 @@
rights['show'] = ['checkIsDocumentPublic']
new_params = {}
- new_params['logic'] = soc.logic.models.document.logic
+ new_params['logic'] = document_logic
new_params['rights'] = rights
+ new_params['name'] = "Document"
+
new_params['export_content_type'] = 'text/text'
- new_params['name'] = "Document"
+ names = [i for i in document_logic.getKeyFieldNames() if i != 'link_id']
+ create_pattern = params_helper.getPattern(names, linkable.SCOPE_PATH_ARG_PATTERN)
+
+ new_params['extra_django_patterns'] = [
+ (r'^document/(?P<access_type>create)/%s$' % create_pattern,
+ 'soc.views.models.%(module_name)s.create', 'Create %(name_short)s')]
+
+ new_params['no_create_with_scope'] = True
+ new_params['no_create_with_key_fields'] = True
- new_params['edit_form'] = EditForm
- new_params['create_form'] = CreateForm
+ new_params['create_extra_dynafields'] = {
+ 'content': forms.fields.CharField(
+ widget=helper.widgets.TinyMCE(attrs={'rows':10, 'cols':40})),
+ 'scope_path': forms.fields.CharField(widget=forms.HiddenInput,
+ required=True),
+ 'prefix': forms.fields.CharField(widget=helper.widgets.ReadOnlyInput(),
+ required=True),
+
+ 'clean_link_id': cleaning.clean_link_id('link_id'),
+ 'clean_scope_path': cleaning.clean_scope_path('scope_path'),
+ }
+ new_params['extra_dynaexclude'] = ['author', 'created',
+ 'modified_by', 'modified']
+
+ new_params['edit_extra_dynafields'] = {
+ 'doc_key_name': forms.fields.CharField(widget=forms.HiddenInput),
+ 'created_by': forms.fields.CharField(widget=helper.widgets.ReadOnlyInput(),
+ required=False),
+ 'last_modified_by': forms.fields.CharField(
+ widget=helper.widgets.ReadOnlyInput(), required=False),
+ }
params = dicts.merge(params, new_params)
@@ -120,7 +112,7 @@
"""
account = users.get_current_user()
- user = user_logic.logic.getForFields({'account': account}, unique=True)
+ user = user_logic.getForFields({'account': account}, unique=True)
if not entity:
fields['author'] = user