From 370ac3ecd0ac1c3bc84975a8e7b6f1631e808eb5 Mon Sep 17 00:00:00 2001
From: Jimmy Zelinskie <jimmyzelinskie@gmail.com>
Date: Tue, 12 Apr 2016 17:58:52 -0400
Subject: [PATCH] service keys: add rotation_duration field

---
 data/database.py                              |  1 +
 .../a3ba52d02dec_initial_keyserver.py         | 51 +++++--------------
 data/model/service_keys.py                    |  6 +--
 endpoints/key_server.py                       |  8 ++-
 initdb.py                                     |  1 -
 5 files changed, 21 insertions(+), 46 deletions(-)

diff --git a/data/database.py b/data/database.py
index ed1d248ee..721dab45e 100644
--- a/data/database.py
+++ b/data/database.py
@@ -898,6 +898,7 @@ class ServiceKey(BaseModel):
   metadata = JSONField()
   created_date = DateTimeField(default=datetime.utcnow)
   expiration_date = DateTimeField(null=True)
+  rotation_duration = IntegerField(null=True)
   approval = ForeignKeyField(ServiceKeyApproval, index=True, null=True)
 
 
diff --git a/data/migrations/versions/a3ba52d02dec_initial_keyserver.py b/data/migrations/versions/a3ba52d02dec_initial_keyserver.py
index 360d427e3..4e49b03cf 100644
--- a/data/migrations/versions/a3ba52d02dec_initial_keyserver.py
+++ b/data/migrations/versions/a3ba52d02dec_initial_keyserver.py
@@ -31,14 +31,13 @@ def upgrade(tables):
     [{'name':'service_key_submitted'}],
   )
 
-  op.bulk_insert(tables.logentrykind,
-  [
-      {'name':'service_key_create'},
-      {'name':'service_key_approve'},
-      {'name':'service_key_delete'},
-      {'name':'service_key_modify'},
-      {'name':'service_key_extend'},
-      {'name':'service_key_rotate'},
+  op.bulk_insert(tables.logentrykind, [
+    {'name':'service_key_create'},
+    {'name':'service_key_approve'},
+    {'name':'service_key_delete'},
+    {'name':'service_key_modify'},
+    {'name':'service_key_extend'},
+    {'name':'service_key_rotate'},
   ])
 
   op.create_index('servicekeyapproval_approval_type', 'servicekeyapproval', ['approval_type'], unique=False)
@@ -53,6 +52,7 @@ def upgrade(tables):
     sa.Column('metadata', UTF8LongText(), nullable=False),
     sa.Column('created_date', sa.DateTime(), nullable=False),
     sa.Column('expiration_date', sa.DateTime(), nullable=True),
+    sa.Column('rotation_duration', sa.Integer(), nullable=True),
     sa.Column('approval_id', sa.Integer(), nullable=True),
     sa.ForeignKeyConstraint(['approval_id'], ['servicekeyapproval.id'],
                             name=op.f('fk_servicekey_approval_id_servicekeyapproval')),
@@ -70,35 +70,12 @@ def upgrade(tables):
 
 
 def downgrade(tables):
-  op.execute(
-      (tables.logentrykind.delete()
-       .where(tables.logentrykind.c.name == op.inline_literal('service_key_create')))
-      )
-
-  op.execute(
-      (tables.logentrykind.delete()
-       .where(tables.logentrykind.c.name == op.inline_literal('service_key_approve')))
-      )
-
-  op.execute(
-      (tables.logentrykind.delete()
-       .where(tables.logentrykind.c.name == op.inline_literal('service_key_delete')))
-      )
-
-  op.execute(
-      (tables.logentrykind.delete()
-       .where(tables.logentrykind.c.name == op.inline_literal('service_key_modify')))
-      )
-
-  op.execute(
-      (tables.logentrykind.delete()
-       .where(tables.logentrykind.c.name == op.inline_literal('service_key_extend')))
-      )
-
-  op.execute(
-      (tables.logentrykind.delete()
-       .where(tables.logentrykind.c.name == op.inline_literal('service_key_rotate')))
-      )
+  op.execute(tables.logentrykind.delete().where(tables.logentrykind.c.name == op.inline_literal('service_key_create')))
+  op.execute(tables.logentrykind.delete().where(tables.logentrykind.c.name == op.inline_literal('service_key_approve')))
+  op.execute(tables.logentrykind.delete().where(tables.logentrykind.c.name == op.inline_literal('service_key_delete')))
+  op.execute(tables.logentrykind.delete().where(tables.logentrykind.c.name == op.inline_literal('service_key_modify')))
+  op.execute(tables.logentrykind.delete().where(tables.logentrykind.c.name == op.inline_literal('service_key_extend')))
+  op.execute(tables.logentrykind.delete().where(tables.logentrykind.c.name == op.inline_literal('service_key_rotate')))
 
   op.drop_column(u'notification', 'lookup_path')
   op.drop_table('servicekey')
diff --git a/data/model/service_keys.py b/data/model/service_keys.py
index 784fb245e..2b6b879e6 100644
--- a/data/model/service_keys.py
+++ b/data/model/service_keys.py
@@ -47,9 +47,9 @@ def _notify_superusers(key):
                         lookup_path='/service_key_approval/{0}/{1}'.format(key.kid, superuser.id))
 
 
-def create_service_key(name, kid, service, jwk, metadata, expiration_date):
+def create_service_key(name, kid, service, jwk, metadata, expiration_date, rotation_duration=None):
   key = ServiceKey.create(name=name, kid=kid, service=service, jwk=jwk, metadata=metadata,
-                          expiration_date=expiration_date)
+                          expiration_date=expiration_date, rotation_duration=rotation_duration)
 
   _notify_superusers(key)
   _gc_expired(service)
@@ -75,7 +75,7 @@ def replace_service_key(old_kid, kid, jwk, metadata, expiration_date):
 
       ServiceKey.create(name=key.name, kid=kid, service=key.service, jwk=jwk,
                         metadata=key.metadata, expiration_date=expiration_date,
-                        approval=key.approval)
+                        rotation_duration=key.rotation_duration, approval=key.approval)
       key.delete_instance()
   except ServiceKey.DoesNotExist:
     raise ServiceKeyDoesNotExist
diff --git a/endpoints/key_server.py b/endpoints/key_server.py
index 5c095d353..4cfb6fc25 100644
--- a/endpoints/key_server.py
+++ b/endpoints/key_server.py
@@ -95,6 +95,7 @@ def get_service_key(service, kid):
 def put_service_key(service, kid):
   metadata = {'ip': request.remote_addr}
 
+  rotation_duration = request.args.get('rotation', None)
   expiration_date = request.args.get('expiration', None)
   if expiration_date is not None:
     try:
@@ -103,10 +104,6 @@ def put_service_key(service, kid):
       logger.exception('Error parsing expiration date on key')
       abort(400)
 
-  rotation_ttl = request.args.get('rotation', None)
-  if rotation_ttl is not None:
-    metadata['rotation_ttl'] = rotation_ttl
-
   try:
     jwk = request.get_json()
   except ValueError:
@@ -128,7 +125,8 @@ def put_service_key(service, kid):
   if kid == signer_kid or signer_kid is None:
     # The key is self-signed. Create a new instance and await approval.
     _validate_jwt(encoded_jwt, jwk, service)
-    data.model.service_keys.create_service_key('', kid, service, jwk, metadata, expiration_date)
+    data.model.service_keys.create_service_key('', kid, service, jwk, metadata, expiration_date,
+                                               rotation_duration=rotation_duration)
 
     key_log_metadata = {
       'kid': kid,
diff --git a/initdb.py b/initdb.py
index f72cb7bd2..c629b2d30 100644
--- a/initdb.py
+++ b/initdb.py
@@ -28,7 +28,6 @@ from data.queue import WorkQueue
 from app import app, storage as store, tf
 from storage.basestorage import StoragePaths
 from endpoints.v2.manifest import _generate_and_store_manifest
-from util import canonicalize
 
 
 from workers import repositoryactioncounter