from ldap3 import Server, Connection, ALL, ALL_ATTRIBUTES, MODIFY_REPLACE, SUBTREE
from getpass import getpass

def connectAD():
    # Получаем логин и пароль
    admin_username = input("Введите логин администратора домена в формате UserName@yourdomain.zone: \n")
    admin_password = getpass("Введите пароль: \n")

    # Данные для подключения к Active Directory
    server = Server('ldap://dct.yacsm.local')
    
    try:
        conn = Connection(server, user=admin_username, password=admin_password, auto_bind=True)
        print("Соединение с AD установлено.")
    except Exception as e:
        print(f"Ошибка соединения с AD: {e}")
        conn = None

    return conn    

def changePassADUser():
    
    #Соединяемся с AD
    conn = connectAD()

    # Логин пользователя, пароль которого нужно изменить
    user_to_reset = input("Введите логин пользователя домена в формате UserName@yourdomain.zone: \n")
    new_password = getpass("Введите новый пароль пользователя: \n")

    # Попытка смены пароля
    try:
        # Поиск пользователя
        conn.search(search_base='dc=domain,dc=com',
                    search_filter=f'(sAMAccountName={user_to_reset})',
                    search_scope=SUBTREE,
                    attributes=['distinguishedName'])

        if len(conn.entries) > 0:
            user_dn = str(conn.entries[0].distinguishedName)
            conn.extend.microsoft.modify_password(user_dn, new_password)
            print(f"Пароль пользователя {user_to_reset} успешно изменен!")
        else:
            print(f"Пользователь {user_to_reset} не найден в Active Directory")

    except Exception as e:
        print(f"Ошибка при смене пароля: {e}")

def listOUFromAD():

    #Соединяемся с AD
    conn = connectAD()

    try:
        result = conn.extend.standard.paged_search(search_base='dc=domain,dc=com',
                                                   search_filter='(objectCategory=organizationalUnit)',
                                                   search_scope=SUBTREE,
                                                   attributes=['name'])

        ou_list = [entry['attributes']['name'] for entry in conn.entries]

        #print("Выберите подразделение:")
        #for index, ou in enumerate(ou_list, start=1):
        #    print(f"{index}. {ou}")

        #selected_index = int(input("Введите число, соответствующее выбранному подразделению: "))
        #selected_ou = ou_list[selected_index - 1]
        #print(f"Вы выбрали подразделение: {selected_ou}")

    except Exception as e:
        print(f"Ошибка при получении списка подразделений: {e}")
        ou_list = None

    return ou_list    

def listUsersOUFromAD(selected_department):

    #Соединяемся с AD
    conn = connectAD()

    selected_ou = selected_department

    try:
        result = conn.search(search_base=f'ou={selected_ou},dc=domain,dc=com',
                             search_filter='(objectCategory=person)',
                             search_scope=SUBTREE,
                             attributes=ALL_ATTRIBUTES)

        entryes = conn.entries
        #for entry in conn.entries:
        #    print(entry.entry_attributes_as_dict)

    except Exception as e:
        print(f"Ошибка при получении списка пользователей: {e}")
        entryes = None

    return entryes

def main():
    #print("Что-то невообразивое")

    # Получаем список подразделений
    departments = listOUFromAD()
    
    # Выводим меню для выбора пользователю
    print("Список подразделений:")
    for index, ou in enumerate(departments, start=1):
        print(f"{index}. {ou}")
 
    selected_department = input("Введите подразделение, для которого нужно получить список пользователей: ")
    
    # Получаем список пользователей в выбранном подразделении
    users = listUsersOUFromAD(selected_department)

    # Выводим атрибуты пользователей в виде таблицы
    for user in users:
        print(user.entry_attributes_as_dict)

    #print("Список пользователей в выбранном подразделении:")
    #print("{:<20} {:<20} {:<30} {:<20}".format('Имя', 'Логин', 'Email', 'Дата создания'))
    #for user in users:
    #    print("{:<20} {:<20} {:<30} {:<20}".format(user['displayName'], user['sAMAccountName'], user['mail'], user['whenCreated']))



if __name__ == "__main__":
    main()