# HG changeset patch # User Sverre Rabbelier # Date 1233352887 0 # Node ID 0122dc66e5d201b8b8c1da0daec218ada86bf97a # Parent e143974a6e27dcd2eda79ec249456ccd19e405eb 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 diff -r e143974a6e27 -r 0122dc66e5d2 app/soc/logic/models/document.py --- 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. """ diff -r e143974a6e27 -r 0122dc66e5d2 app/soc/models/document.py --- 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 diff -r e143974a6e27 -r 0122dc66e5d2 app/soc/models/work.py --- 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. """ diff -r e143974a6e27 -r 0122dc66e5d2 app/soc/views/models/document.py --- 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/(?Pcreate)/%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