← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~pappacena/lp-signing:fix-inject-datetime-format into lp-signing:master

 

Thiago F. Pappacena has proposed merging ~pappacena/lp-signing:fix-inject-datetime-format into lp-signing:master.

Commit message:
Accepting common isoformat dates on /inject's `created-at` attribute

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~pappacena/lp-signing/+git/lp-signing/+merge/383788
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~pappacena/lp-signing:fix-inject-datetime-format into lp-signing:master.
diff --git a/lp_signing/tests/test_webapi.py b/lp_signing/tests/test_webapi.py
index 8841d10..19e66bf 100644
--- a/lp_signing/tests/test_webapi.py
+++ b/lp_signing/tests/test_webapi.py
@@ -1185,6 +1185,21 @@ class TestInjectView(TestCase):
             resp, HasAPIError("'description' is a required property at /"))
         self.assertNonceConsumed()
 
+    def test_invalid_created_at_format(self):
+        private_key = factory.generate_random_bytes(size=64)
+        public_key = factory.generate_random_bytes(size=64)
+
+        resp = self.post_inject({
+            "key-type": "UEFI",
+            "private-key": base64.b64encode(private_key).decode("UTF-8"),
+            "public-key": base64.b64encode(public_key).decode("UTF-8"),
+            "description": "",
+            "created-at": "xxx"})
+        self.assertThat(
+            resp,
+            HasAPIError("created-at 'xxx' is not a valid datetime format"))
+        self.assertNonceConsumed()
+
     def test_invalid_key_type(self):
         resp = self.post_inject({"key-type": "nonsense", "description": ""})
         self.assertThat(
@@ -1205,6 +1220,7 @@ class TestInjectView(TestCase):
             private_key, public_key = Key._generateKeyCertPair(
                 Path(tmp), KeyType.UEFI, common_name)
 
+        now_with_tz = datetime.now().replace(tzinfo=pytz.utc)
         resp = self.post_inject(
             {
                 "key-type": "UEFI",
@@ -1212,7 +1228,7 @@ class TestInjectView(TestCase):
                     private_key).decode("UTF-8"),
                 "public-key": base64.b64encode(
                    public_key).decode("UTF-8"),
-                "created-at": (datetime.utcnow()).isoformat(),
+                "created-at": now_with_tz.isoformat(),
                 "description": "UEFI test description",
             })
 
diff --git a/lp_signing/webapi.py b/lp_signing/webapi.py
index 5726bf6..d0bc07e 100644
--- a/lp_signing/webapi.py
+++ b/lp_signing/webapi.py
@@ -10,10 +10,6 @@ JSON and thus take advantage of acceptable.
 
 import base64
 import binascii
-from datetime import (
-    datetime,
-    timezone,
-    )
 import functools
 
 from acceptable import (
@@ -21,6 +17,7 @@ from acceptable import (
     validate_body,
     validate_output,
     )
+import iso8601
 from flask import request
 from flask_storm import store
 from nacl.encoding import Base64Encoder
@@ -223,9 +220,12 @@ def inject_key():
             payload["public-key"].encode("UTF-8"), validate=True)
     except binascii.Error:
         raise DataValidationError.single("Cannot decode message")
-    datetime_object = datetime.strptime(created_at,
-                                        "%Y-%m-%dT%H:%M:%S.%f")
-    created_at = datetime_object.replace(tzinfo=timezone.utc)
+
+    try:
+        created_at = iso8601.parse_date(created_at)
+    except iso8601.ParseError:
+        raise DataValidationError.single(
+            "created-at '%s' is not a valid datetime format" % created_at)
 
     key = Key.inject(key_type, private_key, public_key,
                      description, created_at)
diff --git a/requirements.txt b/requirements.txt
index 3f4d8c3..96077cb 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -8,6 +8,7 @@ Flask-Storm==0.2.0
 future==0.16.0
 gunicorn==19.9.0
 idna==2.8
+iso8601==0.1.12
 itsdangerous==1.1.0
 Jinja2==2.10
 jsonschema==2.6.0
diff --git a/setup.py b/setup.py
index 3e2b603..ac4020f 100755
--- a/setup.py
+++ b/setup.py
@@ -13,6 +13,7 @@ requires = [
     "acceptable",
     "Flask",
     "Flask-Storm",
+    "iso8601",
     "lazr.enum",
     "lazr.postgresql",
     "PyNaCl",