convert_ldap_to_db.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. import json
  2. from dataclasses import astuple, dataclass
  3. from pathlib import Path
  4. base_dir = Path(__file__).parent / "Reisacher"
  5. @dataclass
  6. class Benutzer:
  7. Benutzer_ID: str
  8. Name: str
  9. Email: str
  10. Rolle: str
  11. Mitarbeiter: str
  12. Benutzer_DN: str
  13. @dataclass
  14. class Benutzer_Gruppe:
  15. Benutzer_ID: str
  16. Gruppe_ID: str
  17. def read_ldap_json(json_file: str) -> dict:
  18. with open(base_dir / json_file, "r", encoding="latin-1") as frh:
  19. groups_temp = json.load(frh)
  20. res = {}
  21. for entry in groups_temp["entries"]:
  22. res[entry["dn"]] = entry["attributes"]
  23. return res
  24. def read_or_create_selected_groups(json_file: str, groups: dict) -> dict:
  25. sel_groups = []
  26. if Path(base_dir / json_file).exists():
  27. with open(base_dir / json_file, "r", encoding="latin-1") as frh:
  28. sel_groups = json.load(frh)
  29. else:
  30. sel_groups = [dn for dn, attrs in groups.items() if len(attrs.get("member", [])) > 0]
  31. sel_groups.sort()
  32. with open(base_dir / json_file, "w", encoding="latin-1") as fwh:
  33. json.dump(sel_groups, fwh, indent=2)
  34. return sel_groups
  35. def print_group_membership(groups: dict, sel_groups: list):
  36. for dn, attrs in groups.items():
  37. group_members = [member_dn for member_dn in attrs.get("member", []) if member_dn in groups]
  38. if group_members:
  39. print("\n" + dn, len(group_members))
  40. for member_dn in group_members:
  41. print(" * " + member_dn)
  42. def get_subgroups(groups: dict, sel_groups: list):
  43. res = []
  44. for group_dn in sel_groups:
  45. attrs = groups.get(group_dn, None)
  46. if not attrs:
  47. continue
  48. res.append(group_dn)
  49. res.extend(get_subgroups(groups, attrs.get("member", [])))
  50. return res
  51. def set_group_member_of(groups: dict, sel_groups: list, parents: list = None):
  52. if parents is None:
  53. parents = []
  54. for group_dn in sel_groups:
  55. attrs = groups.get(group_dn, None)
  56. if not attrs:
  57. continue
  58. attrs["memberOf"] = parents
  59. set_group_member_of(groups, attrs.get("member", []), parents + [group_dn])
  60. def get_cn_or_ou_from_dn(dn: str) -> str:
  61. return dn.split(",")[0][3:]
  62. def main():
  63. groups = read_ldap_json("groups.json")
  64. sel_roles = read_or_create_selected_groups("selected_roles.json", groups)
  65. sel_groups = read_or_create_selected_groups("selected_groups.json", groups)
  66. users = read_ldap_json("users.json")
  67. users_db = []
  68. users_roles = {}
  69. users_groups = {}
  70. for user_dn, attrs in users.items():
  71. member_of_role = [groups[dn]["cn"] for dn in sel_roles if is_transitive_member_of(groups, attrs, dn)]
  72. if len(member_of_role) <= 0:
  73. continue
  74. role = "Serviceberater" if "serv" in member_of_role[0].lower() else "Buchhaltung"
  75. users_db.append(
  76. Benutzer(
  77. Benutzer_ID=attrs.get("sAMAccountName", ""),
  78. Name=attrs.get("cn", ""),
  79. Email=attrs.get("mail", ""),
  80. Rolle=role,
  81. Mitarbeiter=attrs.get("cn", ""),
  82. Benutzer_DN=user_dn,
  83. )
  84. )
  85. user_id = attrs.get("sAMAccountName", user_dn)
  86. users_roles[user_id] = member_of_role
  87. users_groups[user_id] = [
  88. get_cn_or_ou_from_dn(dn) for dn in sel_groups if is_transitive_member_of(groups, attrs, dn)
  89. ]
  90. with open(base_dir / "insert_users_and_groups.sql", "w", encoding="latin-1") as fwh:
  91. for role in sel_roles:
  92. role_info = (groups[role].get("cn", ""), groups[role].get("cn", ""), role, "1")
  93. fwh.write("INSERT INTO [auth].[Rollen] VALUES ('" + "', '".join(role_info) + "');\n")
  94. fwh.write("\n")
  95. for group in sel_groups:
  96. group_info = (groups[group].get("cn", ""), groups[group].get("cn", ""), group)
  97. fwh.write(
  98. "INSERT INTO [auth].[Gruppen] (Gruppe_ID, Gruppe_Name, Gruppe_DN) VALUES ('"
  99. + "', '".join(group_info)
  100. + "');\n"
  101. )
  102. fwh.write("\n\n")
  103. for user in users_db:
  104. fwh.write("INSERT INTO [auth].[Benutzer] VALUES ('" + "', '".join(astuple(user)) + "');\n")
  105. fwh.write("\n")
  106. for user_id, roles in users_roles.items():
  107. for role in roles:
  108. fwh.write("INSERT INTO [auth].[Benutzer_Gruppe] VALUES ('" + user_id + "', '" + role + "');\n")
  109. fwh.write("\n")
  110. for user_id, groups in users_groups.items():
  111. for group in groups:
  112. fwh.write("INSERT INTO [auth].[Benutzer_Gruppe] VALUES ('" + user_id + "', '" + group + "');\n")
  113. # for dn in sel_groups:
  114. # group = groups.get(dn, {})
  115. # print("\n" + dn, len(group.get("member", [])))
  116. # for member_dn in group.get("member", []):
  117. # print(" - " + member_dn)
  118. def get_ou_subgroups(group_dn: str) -> list[str]:
  119. res = []
  120. group_dn_split = group_dn.split(",")
  121. for i, entry in enumerate(group_dn_split):
  122. if entry[:2] not in ("OU", "ou"):
  123. continue
  124. res.append(",".join(group_dn_split[i:]))
  125. return res
  126. def is_transitive_member_of(groups: dict, dn_attrs: dict, group_dn: str) -> bool:
  127. if group_dn in get_ou_subgroups(dn_attrs["distinguishedName"]):
  128. return True
  129. for dn in dn_attrs.get("memberOf", []):
  130. if dn == group_dn:
  131. return True
  132. if dn in groups and is_transitive_member_of(groups, groups[dn], group_dn):
  133. return True
  134. return False
  135. if __name__ == "__main__":
  136. main()