diff options
author | David Kupka <dkupka@redhat.com> | 2016-06-21 14:07:07 +0200 |
---|---|---|
committer | Jan Cholasta <jcholast@redhat.com> | 2016-06-21 15:11:19 +0200 |
commit | 034a111972df7e1b2db71ea30440b36dc93e2c7b (patch) | |
tree | 3f0deee8112ffa3f47e7ab93ca22136c27afa1ae /ipaserver/plugins | |
parent | f85c347f4d2f50d49e77373a56c55f3e2b4bc473 (diff) | |
download | freeipa-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.py | 36 |
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) |