summaryrefslogtreecommitdiffstats
path: root/ipaserver/plugins
diff options
context:
space:
mode:
authorDavid Kupka <dkupka@redhat.com>2016-06-21 14:07:07 +0200
committerJan Cholasta <jcholast@redhat.com>2016-06-21 15:11:19 +0200
commit034a111972df7e1b2db71ea30440b36dc93e2c7b (patch)
tree3f0deee8112ffa3f47e7ab93ca22136c27afa1ae /ipaserver/plugins
parentf85c347f4d2f50d49e77373a56c55f3e2b4bc473 (diff)
downloadfreeipa-034a111972df7e1b2db71ea30440b36dc93e2c7b.tar.gz
freeipa-034a111972df7e1b2db71ea30440b36dc93e2c7b.tar.xz
freeipa-034a111972df7e1b2db71ea30440b36dc93e2c7b.zip
schema: Add fingerprint and TTL
Calculate fingerprint for schema in deterministic way. Send fingerprint value together with schema. Send TTL with schema to inform client about caching interval. https://fedorahosted.org/freeipa/ticket/4739 Reviewed-By: Jan Cholasta <jcholast@redhat.com>
Diffstat (limited to 'ipaserver/plugins')
-rw-r--r--ipaserver/plugins/schema.py36
1 files changed, 36 insertions, 0 deletions
diff --git a/ipaserver/plugins/schema.py b/ipaserver/plugins/schema.py
index 98b47cbbb..847d8c442 100644
--- a/ipaserver/plugins/schema.py
+++ b/ipaserver/plugins/schema.py
@@ -7,6 +7,7 @@ import itertools
import sys
import six
+import hashlib
from .baseldap import LDAPObject
from ipalib import errors
@@ -18,6 +19,10 @@ from ipalib.plugable import Registry
from ipalib.text import _
from ipapython.version import API_VERSION
+# Schema TTL sent to clients in response to schema call.
+# Number of seconds before client should check for schema update.
+SCHEMA_TTL = 7*24*3600 # default: 7 days
+
__doc__ = _("""
API Schema
""") + _("""
@@ -690,6 +695,33 @@ class output_find(BaseParamSearch):
class schema(Command):
NO_CLI = True
+ @staticmethod
+ def _calculate_fingerprint(data):
+ """
+ Returns fingerprint for schema
+
+ Behavior of this function can be changed at any time
+ given that it always generates identical fingerprint for
+ identical data (change in order of items in dict is
+ irelevant) and the risk of generating identical fingerprint
+ for different inputs is low.
+ """
+ to_process = [data]
+ fingerprint = hashlib.sha1()
+
+ for entry in to_process:
+ if isinstance(entry, (list, tuple)):
+ for item in entry:
+ to_process.append(item)
+ elif isinstance(entry, dict):
+ for key in sorted(entry.keys()):
+ to_process.append(key)
+ to_process.append(entry[key])
+ else:
+ fingerprint.update(unicode(entry).encode('utf-8'))
+
+ return fingerprint.hexdigest()[:8]
+
def execute(self, *args, **kwargs):
commands = list(self.api.Object.command.search(**kwargs))
for command in commands:
@@ -712,4 +744,8 @@ class schema(Command):
schema['classes'] = classes
schema['topics'] = topics
+ schema_fp = self._calculate_fingerprint(schema)
+ schema['fingerprint'] = schema_fp
+ schema['ttl'] = SCHEMA_TTL
+
return dict(result=schema)