#!/usr/bin/python3
# -*- mode: python -*-
# Show some reports from the ldap database
# Call with nokey to generate a missing key report
# Call with noforward to generate a missing .forward report

from __future__ import print_function

import getopt
import sys
import time

import ldap

from userdir_ldap.ldap import connectLDAP, BaseDn, EmailAddress, GetAttr


def ShowDups(Attrs, Len):
   for x in Attrs:
      if "keyFingerPrint" not in x[1]:
         continue

      Count = 0
      for fpr in x[1]["keyFingerPrint"]:
         if len(fpr) == Len:
            Count = Count + 1
      if Count > 1:
         for fpr in x[1]["keyFingerPrint"]:
           if len(fpr) == Len:
              print("%s: %s" % (EmailAddress(x), fpr))


# Main program starts here
# Process options
(options, arguments) = getopt.getopt(sys.argv[1:], "")
for (switch, val) in options:
   if (switch == '-a'):
      DoAdd = 1

print("Connecting to LDAP directory")

# Connect to the ldap server
lc = connectLDAP()
lc.simple_bind_s("", "")

if arguments[0] == "nokey":
   Attrs = lc.search_s(
       BaseDn, ldap.SCOPE_ONELEVEL, "(!(keyFingerPrint=*))",
       ["uid", "cn", "sn", "emailForward", "comment"])
   Attrs.sort()
   for x in Attrs:
      print("Key Missing:", EmailAddress(x))
      if GetAttr(x, "emailForward") != "":
         print("  ->", GetAttr(x, "emailForward"))
      if GetAttr(x, "comment") != "":
         print("  :", GetAttr(x, "comment"))

if arguments[0] == "noforward":
   Attrs = lc.search_s(
       BaseDn, ldap.SCOPE_ONELEVEL, "(!(emailForward=*))",
       ["uid", "cn", "sn", "emailForward", "comment"])
   Attrs.sort()
   for x in Attrs:
      print("No Forward:", EmailAddress(x))

if arguments[0] == "badpriv":
   Attrs = lc.search_s(
       BaseDn, ldap.SCOPE_ONELEVEL, "(&(!(keyFingerPrint=*))(privateSub=*))",
       ["uid", "cn", "sn", "privateSub"])
   Attrs.sort()
   for x in Attrs:
      print(EmailAddress(x) + ": " + GetAttr(x, "privateSub"))

if arguments[0] == "nopriv":
   Attrs = lc.search_s(
       BaseDn, ldap.SCOPE_ONELEVEL, "(&(keyFingerPrint=*)(!(privateSub=*)))",
       ["uid", "cn", "sn", "privateSub"])
   Attrs.sort()
   for x in Attrs:
      print("  ", EmailAddress(x) + ": " + GetAttr(x, "privateSub"))

if arguments[0] == "keymap":
   Attrs = lc.search_s(BaseDn, ldap.SCOPE_ONELEVEL, "uid=*",
                       ["uid", "cn", "sn", "keyFingerPrint"])
   Attrs.sort()
   for x in Attrs:
      if "keyFingerPrint" in x[1]:
         for fpr in x[1]["keyFingerPrint"]:
           print("%s: %s" % (EmailAddress(x), fpr.decode('ascii')))

if arguments[0] == "devcount":
   Attrs = lc.search_s(BaseDn, ldap.SCOPE_ONELEVEL, "(&(keyFingerPrint=*)(supplementaryGid=Debian))",
                       ["uid"])
   Count = 0
   for x in Attrs:
      Count = Count + 1
   print("There are", Count, "developers as of", time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime(time.time())))

if arguments[0] == "echelon":
   Attrs = lc.search_s(
       BaseDn, ldap.SCOPE_ONELEVEL,
       "(&(|(activity-pgp=*)(activity-from=*))(&(keyFingerPrint=*)(supplementaryGid=Debian)))",
       ["activity-pgp", "activity-from"])
   Count = 0
   PGPCount = 0
   for x in Attrs:
      Count = Count + 1
      if "activity-pgp" in x[1]:
         PGPCount = PGPCount + 1
   print("Echelon has seen", Count, "developers, with", PGPCount, "PGP confirms as of", time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime(time.time())))

if arguments[0] == "missing":
   Attrs = lc.search_s(
       BaseDn, ldap.SCOPE_ONELEVEL,
       "(&(!(|(activity-pgp=*)(activity-from=*)))(&(keyFingerPrint=*)(supplementaryGid=Debian)))",
       ["uid", "cn", "sn", "mn"])
   Attrs.sort()
   for x in Attrs:
      print(EmailAddress(x))

if arguments[0] == "keystat":
   Attrs = lc.search_s(BaseDn, ldap.SCOPE_ONELEVEL, "keyFingerPrint=*",
                       ["keyFingerPrint"])
   KeyCount = 0
   GPGCount = 0
   for x in Attrs:
      if "keyFingerPrint" in x[1]:
         KeyCount = KeyCount + 1
         for fpr in x[1]["keyFingerPrint"]:
           if len(fpr) == 40:
              GPGCount = GPGCount + 1
              break
   print("There are", KeyCount, "accounts with PGP2/5 keys and", GPGCount, "of them have PGP5 keys")

if arguments[0] == "multikeys":
   Attrs = lc.search_s(BaseDn, ldap.SCOPE_ONELEVEL, "uid=*",
                       ["uid", "cn", "sn", "keyFingerPrint"])
   Attrs.sort()

   print("--- PGP Keys ---")
   ShowDups(Attrs, 32)
   print("--- GPG Keys ---")
   ShowDups(Attrs, 40)
