diff --git a/ietf/doc/migrations/0034_documenturl.py b/ietf/doc/migrations/0034_documenturl.py new file mode 100644 index 000000000..d198be8e1 --- /dev/null +++ b/ietf/doc/migrations/0034_documenturl.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.8 on 2017-09-26 05:36 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('name', '0027_docurltagname'), + ('doc', '0033_fix_conflict_review_dochistory'), + ] + + operations = [ + migrations.CreateModel( + name='DocumentURL', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('desc', models.CharField(blank=True, default=b'', max_length=255)), + ('url', models.URLField()), + ('doc', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document')), + ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='name.DocUrlTagName')), + ], + ), + ] diff --git a/ietf/doc/models.py b/ietf/doc/models.py index 43d7b53d3..26d64659d 100644 --- a/ietf/doc/models.py +++ b/ietf/doc/models.py @@ -335,6 +335,9 @@ class DocumentInfo(models.Model): def author_list(self): return u", ".join(author.email_id for author in self.documentauthor_set.all() if author.email_id) + def authors(self): + return [ a.person for a in self.documentauthor_set.all() ] + # This, and several other ballot related functions here, assume that there is only one active ballot for a document at any point in time. # If that assumption is violated, they will only expose the most recently created ballot def ballot_open(self, ballot_type_slug): diff --git a/ietf/doc/views_doc.py b/ietf/doc/views_doc.py index 5f663456d..a7063ef2e 100644 --- a/ietf/doc/views_doc.py +++ b/ietf/doc/views_doc.py @@ -54,7 +54,8 @@ from ietf.doc.utils import ( add_links_in_new_revision_events, augment_events_wi from ietf.community.utils import augment_docs_with_tracking_info from ietf.group.models import Role from ietf.group.utils import can_manage_group_type, can_manage_materials -from ietf.ietfauth.utils import has_role, is_authorized_in_doc_stream, user_is_person, role_required +from ietf.ietfauth.utils import ( has_role, is_authorized_in_doc_stream, user_is_person, + role_required, is_individual_draft_author) from ietf.name.models import StreamName, BallotPositionName from ietf.utils.history import find_history_active_at from ietf.doc.forms import TelechatForm, NotifyForm @@ -284,6 +285,7 @@ def document_main(request, name, rev=None): can_edit_stream_info = is_authorized_in_doc_stream(request.user, doc) can_edit_shepherd_writeup = can_edit_stream_info or user_is_person(request.user, doc.shepherd and doc.shepherd.person) or has_role(request.user, ["Area Director"]) can_edit_notify = can_edit_shepherd_writeup + can_edit_individual = is_individual_draft_author(request.user, doc) can_edit_consensus = False consensus = nice_consensus(default_consensus(doc)) @@ -383,6 +385,7 @@ def document_main(request, name, rev=None): can_edit=can_edit, can_change_stream=can_change_stream, can_edit_stream_info=can_edit_stream_info, + can_edit_individual=can_edit_individual, is_shepherd = user_is_person(request.user, doc.shepherd and doc.shepherd.person), can_edit_shepherd_writeup=can_edit_shepherd_writeup, can_edit_notify=can_edit_notify, diff --git a/ietf/doc/views_draft.py b/ietf/doc/views_draft.py index bdd169775..b7b78617b 100644 --- a/ietf/doc/views_draft.py +++ b/ietf/doc/views_draft.py @@ -32,7 +32,7 @@ from ietf.doc.lastcall import request_last_call from ietf.doc.fields import SearchableDocAliasesField from ietf.group.models import Group, Role from ietf.iesg.models import TelechatDate -from ietf.ietfauth.utils import has_role, is_authorized_in_doc_stream, user_is_person +from ietf.ietfauth.utils import has_role, is_authorized_in_doc_stream, user_is_person, is_individual_draft_author from ietf.ietfauth.utils import role_required from ietf.message.models import Message from ietf.name.models import IntendedStdLevelName, DocTagName, StreamName, DocUrlTagName @@ -1153,7 +1153,8 @@ def edit_document_urls(request, name): doc = get_object_or_404(Document, name=name) if not (has_role(request.user, ("Secretariat", "Area Director")) - or is_authorized_in_doc_stream(request.user, doc)): + or is_authorized_in_doc_stream(request.user, doc) + or is_individual_draft_author(request.user, doc)): return HttpResponseForbidden("You do not have the necessary permissions to view this page") old_urls = format_urls(doc.documenturl_set.all()) diff --git a/ietf/ietfauth/utils.py b/ietf/ietfauth/utils.py index 3be74cd08..90c8eefe7 100644 --- a/ietf/ietfauth/utils.py +++ b/ietf/ietfauth/utils.py @@ -9,6 +9,8 @@ from django.http import HttpResponseRedirect, HttpResponseForbidden from django.contrib.auth import REDIRECT_FIELD_NAME from django.utils.decorators import available_attrs +import debug # pyflakes:ignore + from ietf.group.models import Role from ietf.person.models import Person @@ -128,7 +130,7 @@ def is_authorized_in_doc_stream(user, doc): if not doc.stream: return False - if doc.stream.slug == "ietf" and doc.group.type == "individ": + if doc.stream.slug == "ietf" and doc.group.type_id == "individ": return False if doc.stream.slug == "ietf": @@ -141,3 +143,17 @@ def is_authorized_in_doc_stream(user, doc): group_req = Q() return Role.objects.filter(Q(name__in=("chair", "secr", "delegate", "auth"), person__user=user) & group_req).exists() + +def is_individual_draft_author(user, doc): + + if not user.is_authenticated: + return False + + if not doc.group.type_id == "individ" : + return False + + if user.person in doc.authors(): + return True + + return False + diff --git a/ietf/name/fixtures/names.json b/ietf/name/fixtures/names.json index 65aebbf83..fac0c11a3 100644 --- a/ietf/name/fixtures/names.json +++ b/ietf/name/fixtures/names.json @@ -7769,17 +7769,17 @@ { "fields": { "desc": "", - "name": "Document Issue Tracker", + "name": "Document issue tracker", "order": 0, "used": true }, "model": "name.docurltagname", - "pk": "tracker" + "pk": "issues" }, { "fields": { "desc": "", - "name": "Document Wiki", + "name": "Document wiki", "order": 0, "used": true }, @@ -7789,7 +7789,7 @@ { "fields": { "desc": "", - "name": "Yang Impact Analysis", + "name": "Yang impact analysis", "order": 0, "used": true }, @@ -7799,7 +7799,7 @@ { "fields": { "desc": "", - "name": "Extracted Yang Module", + "name": "Extracted yang module", "order": 0, "used": true }, diff --git a/ietf/name/migrations/0027_docurltagname.py b/ietf/name/migrations/0027_docurltagname.py new file mode 100644 index 000000000..31b8d36b5 --- /dev/null +++ b/ietf/name/migrations/0027_docurltagname.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.8 on 2017-09-26 05:36 +from __future__ import unicode_literals + +from django.db import migrations, models + +def forwards(apps,schema_editor): + DocUrlTagName = apps.get_model('name','DocUrlTagName') + + DocUrlTagName.objects.create( + slug='wiki', + name='Document wiki', + ) + DocUrlTagName.objects.create( + slug='issues', + name='Document Issue Tracker', + ) + DocUrlTagName.objects.create( + slug='repository', + name='Document Source Repository', + ) + DocUrlTagName.objects.create( + slug='yang-module', + name='Extracted Yang Module', + ) + DocUrlTagName.objects.create( + slug='yang-impact-analysis', + name='Yang Impact Analysis', + ) + DocUrlTagName.objects.create( + slug='yang-module-metadata', + name='Yang module metadata', + ) + +def backwards(apps,schema_editor): + pass + +class Migration(migrations.Migration): + + dependencies = [ + ('name', '0026_popuulate-important-date-names'), + ] + + operations = [ + migrations.CreateModel( + name='DocUrlTagName', + fields=[ + ('slug', models.CharField(max_length=32, primary_key=True, serialize=False)), + ('name', models.CharField(max_length=255)), + ('desc', models.TextField(blank=True)), + ('used', models.BooleanField(default=True)), + ('order', models.IntegerField(default=0)), + ], + options={ + 'ordering': ['order', 'name'], + 'abstract': False, + }, + ), + migrations.RunPython(forwards, backwards), + ] + + diff --git a/ietf/templates/doc/document_draft.html b/ietf/templates/doc/document_draft.html index b70061cc9..b68209427 100644 --- a/ietf/templates/doc/document_draft.html +++ b/ietf/templates/doc/document_draft.html @@ -241,12 +241,12 @@ {% endif %} {% with doc.documenturl_set.all as urls %} - {% if urls or can_edit_stream_info %} + {% if urls or can_edit_stream_info or can_edit_individual %}