Last active
March 31, 2020 14:07
-
-
Save baszoetekouw/0436704c28066919e88a9359c8b8e884 to your computer and use it in GitHub Desktop.
script to calculate checksum of an ldif (e.g., slapcat output)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import sys | |
import ldif | |
import hashlib | |
#import json | |
import numbers | |
from typing import Collection, Any | |
""" | |
# old approach; works well, but in json lists are ordered, so it is quite hard to get python to sort them aphabetically | |
# custom encoder | |
class MyEncoder(json.JSONEncoder): | |
def default(self, obj): | |
# handle byte objects | |
if isinstance(obj, bytes): | |
return obj.decode('utf8') | |
return obj.hex() | |
# Let the base class default method raise the TypeError | |
return json.JSONEncoder.default(self, obj) | |
ldifparser = ldif.LDIFRecordList(sys.stdin) | |
ldifparser.parse() | |
# note: this still doesn't sort lists of attributes | |
#print(json.dumps(ldifparser.all_records, cls=MyEncoder, sort_keys=True, indent=2)) | |
#sys.exit(0) | |
""" | |
# custom sorting of lists and tuples, with nonstrings at the end | |
def getsortkey(s: Any) -> str: | |
if isinstance(s, bytes): | |
return s.decode('utf8') | |
if isinstance(s, str): | |
return s | |
if isinstance(s, numbers.Number): | |
return str(s) | |
# sort other objects (dicts etc) at the end | |
return '\uffff' | |
# iterate over an LDIF structure | |
# LOOK MOM, IT'S RECURSION! | |
def iter_ldif(d: Collection[Any]) -> str: | |
if isinstance(d, dict): | |
result = "{" + ','.join([f"{iter_ldif(k)}: {iter_ldif(v)}" for k, v in sorted(d.items())]) + '}' | |
return result + "\n" | |
# be default, ldap object are returned as a (dn,{attributes}) tuple; uncomment this if you want a dict instead | |
#if isinstance(d, tuple) and len(d) == 2: | |
# return iter_ldif(dict((d,))) | |
if isinstance(d, list) or isinstance(d, tuple): | |
result = '[' + ','.join([iter_ldif(v) for v in sorted(d, key=getsortkey)]) + ']' | |
return result + "\n" | |
if isinstance(d, bytes): | |
return iter_ldif(d.decode('utf8')) | |
if isinstance(d, str): | |
return '"' + ''.join([c if ' ' <= c < '~' and c != '"' else f"\\u{ord(c):04x}" for c in d]) + '"' | |
raise Exception(f"weird object of type {type(d).__name__} found") | |
ldifparser = ldif.LDIFRecordList(sys.stdin) | |
ldifparser.parse() | |
json_data = iter_ldif(ldifparser.all_records) | |
#print(json_data) | |
h = hashlib.sha256(json_data.encode('ascii')) | |
print(h.hexdigest()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment