From 6d616855bccf90bcde8080e280741adfa34b766e Mon Sep 17 00:00:00 2001
From: Russ Housley <housley@vigilsec.com>
Date: Mon, 21 Aug 2017 14:30:20 +0000
Subject: [PATCH] Show which RFC was in force when the IPR disclosure was
 submitted. Fixes #2309.  - Legacy-Id: 14062

---
 ietf/ipr/models.py                   |  7 ++++-
 ietf/ipr/views.py                    | 39 ++++++++++++++++++++++++++++
 ietf/templates/ipr/details_view.html | 16 +++++++-----
 3 files changed, 55 insertions(+), 7 deletions(-)

diff --git a/ietf/ipr/models.py b/ietf/ipr/models.py
index 7bde39974..c46b48a0b 100644
--- a/ietf/ipr/models.py
+++ b/ietf/ipr/models.py
@@ -102,7 +102,12 @@ class IprDisclosureBase(models.Model):
         for disc in unseen:
             disc_set.update(disc.recursively_updates(disc_set))
         return disc_set
-        
+
+    def is_thirdparty(self):
+        """Returns True if this disclosure is a Third Party disclosure"""
+        ipr = self.get_child() if self.__class__ is IprDisclosureBase else self
+        return ipr.__class__ is ThirdPartyIprDisclosure
+
 
 class HolderIprDisclosure(IprDisclosureBase):
     ietfer_name              = models.CharField(max_length=255, blank=True) # "Whose Personal Belief Triggered..."
diff --git a/ietf/ipr/views.py b/ietf/ipr/views.py
index 2abf1ba72..53d1d8540 100644
--- a/ietf/ipr/views.py
+++ b/ietf/ipr/views.py
@@ -132,6 +132,44 @@ def set_disclosure_title(disclosure):
         title = title[:252] + "..."
     disclosure.title = title
 
+def ipr_rfc_number(disclosureDate, thirdPartyDisclosureFlag):
+    """Return the RFC as a string that was in force when the disclosure was made."""
+
+    # This works because the oldest IPR disclosure in the database was
+    # made on 1993-07-23, which is more than a year after RFC 1310.
+
+    # RFC publication date comes from the RFC Editor announcement
+    # TODO: These times are tzinfo=pytz.utc, but disclosure times are offset-naive
+    ipr_rfc_pub_datetime = {
+        1310 : datetime.datetime(1992,  3, 13,  0,  0),
+        1802 : datetime.datetime(1994,  3, 23,  0,  0),
+        2026 : datetime.datetime(1996, 10, 29,  0,  0),
+        3668 : datetime.datetime(2004,  2, 18,  0,  0),
+        3979 : datetime.datetime(2005,  3,  2,  2, 23),
+        4879 : datetime.datetime(2007,  4, 10, 18, 21),
+        8179 : datetime.datetime(2017,  5, 31, 23,  1),
+    }
+
+    if disclosureDate < ipr_rfc_pub_datetime[1310]:
+        rfcnum = "Error!"
+    elif disclosureDate < ipr_rfc_pub_datetime[1802]:
+        rfcnum = "RFC 1310"
+    elif disclosureDate < ipr_rfc_pub_datetime[2026]:
+        rfcnum = "RFC 1802"
+    elif disclosureDate < ipr_rfc_pub_datetime[3668]:
+        rfcnum = "RFC 2026"
+    elif disclosureDate < ipr_rfc_pub_datetime[3979]:
+        rfcnum = "RFC 3668"
+    elif disclosureDate < ipr_rfc_pub_datetime[8179]:
+        rfcnum = "RFC 3979"
+    else:
+        rfcnum = "RFC 8179"
+
+    if (thirdPartyDisclosureFlag) and (rfcnum == "RFC 3979") and \
+       (disclosureDate > ipr_rfc_pub_datetime[4879]):
+        rfcnum = rfcnum + " as updated by RFC 4879"
+
+    return rfcnum
 # ----------------------------------------------------------------
 # Ajax Views
 # ----------------------------------------------------------------
@@ -719,6 +757,7 @@ def show(request, id):
 
     return render(request, "ipr/details_view.html",  {
         'ipr': ipr,
+        'in_force_ipr_rfc': ipr_rfc_number(ipr.time, ipr.is_thirdparty),
         'tabs': get_details_tabs(ipr, 'Disclosure'),
         'choices_abc': [ i.desc for i in IprLicenseTypeName.objects.filter(slug__in=['no-license', 'royalty-free', 'reasonable', ]) ],
         'updates_iprs': ipr.relatedipr_source_set.all(),
diff --git a/ietf/templates/ipr/details_view.html b/ietf/templates/ipr/details_view.html
index 60ff0fc76..a41ec7526 100644
--- a/ietf/templates/ipr/details_view.html
+++ b/ietf/templates/ipr/details_view.html
@@ -1,5 +1,5 @@
 {% extends "base.html" %}
-{# Copyright The IETF Trust 2015, All Rights Reserved #}
+{# Copyright The IETF Trust 2015, 2017. All Rights Reserved. #}
 {% load origin %}
 
 {% load ietf_filters ipr_filters %}
@@ -40,9 +40,13 @@
     </div>
 
     {% if not ipr.compliant %}
-      <p class="alert alert-danger">This IPR disclosure does not comply with the formal requirements of Section 5,
-        "IPR Disclosures," of <a href="https://www.ietf.org/rfc/rfc8179.txt">RFC 8179</a>, "Intellectual Property Rights in IETF Technology."
-      </p>
+      {% if in_force_ipr_rfc == 'RFC 8179' %}
+        <p class="alert alert-danger">This IPR disclosure does not comply with the formal requirements of Section 5,
+          "IPR Disclosures," of <a href="https://www.rfc-editor.org/rfc/rfc8179.txt">RFC 8179</a>, "Intellectual Property Rights in IETF Technology."</p>
+      {% else %}
+        <p class="alert alert-danger">This IPR disclosure does not comply with the formal requirements of Section 6,
+          "IPR Disclosures," of <a href="https://www.rfc-editor.org/rfc/rfc3979.txt">RFC 3979</a>, "Intellectual Property Rights in IETF Technology."</p>
+      {% endif %}
     {% endif %}
 
     {% if ipr.has_legacy_event %}
@@ -51,7 +55,7 @@
 
     <div>
       <strong>Submitted:</strong>
-      {{ ipr.time|date:"F j, Y" }}
+      {{ ipr.time|date:"F j, Y" }} under the rules in {{ in_force_ipr_rfc }}
     </div>
 
     <div>
@@ -171,7 +175,7 @@
         {% endif %}
 
         {% if ipr.patent_info or ipr.has_patent_pending %}
-          <h2>{% cycle section %}. Disclosure of Patent Information <small>i.e., patents or patent applications required to be disclosed by Section 6 of RFC 8179</small></h2>
+          <h2>{% cycle section %}. Disclosure of Patent Information <small>i.e., patents or patent applications required to be disclosed by {{ in_force_ipr_rfc }}</small></h2>
 
           <p>A. For granted patents or published pending patent applications, please provide the following information:</p>