import click import ssl from ldap3 import Server, Connection, Tls @click.group() @click.option('--server', default='edir1.rz.hs-fulda.de', help='LDAP server URL') @click.option('--username', prompt=True, default='cn=fdhpc,ou=AI,o=FH-Fulda', help='LDAP bind username') @click.option('--password', prompt=True, hide_input=True, help='LDAP bind password') @click.pass_context def cli(ctx, server, username, password): tls = Tls(validate=ssl.CERT_REQUIRED, version=ssl.PROTOCOL_TLSv1_2, ciphers="AES256-GCM-SHA384") server = Server(server, tls=tls, get_info="ALL", use_ssl=True) ctx.obj = Connection(server, username, password, auto_bind=True) @cli.command() @click.pass_context def list(ctx): ctx.obj.search('o=FH-Fulda', '''(& (cn=fd*) (objectClass=inetOrgPerson) (groupMembership=cn=ORG-AI-HPC,ou=AI,o=FH-Fulda) (! (| (description=*funktion*) (loginDisabled=true) (sn=fd*) ) ) )''', attributes = ['cn', 'member', 'sn', 'givenName']) for e in ctx.obj.entries: click.echo(f'{click.style(e.cn, fg="blue", bold=True)}: {e.sn}, {e.givenName}') def find(ctx, name): from ldap3.utils.conv import escape_filter_chars ctx.obj.search('o=FH-Fulda', f'''(& (cn={escape_filter_chars(name)}) (objectClass=inetOrgPerson) (! (| (description=*funktion*) (loginDisabled=true) (sn=fd*) ) ) )''') if not ctx.obj.entries: ctx.fail(f'No user found: {name}') return ctx.obj.entries[0].entry_dn @cli.command() @click.argument('name', nargs=-1, required=True) @click.pass_context def add(ctx, name): members = [find(ctx, name) for name in name] ctx.obj.extend.novell.add_members_to_groups(members, 'cn=ORG-AI-HPC,ou=AI,o=FH-Fulda') @cli.command() @click.pass_context @click.argument('name', nargs=-1, required=True) def remove(ctx, name): members = [find(ctx, name) for name in name] ctx.obj.extend.novell.remove_members_from_groups(members, 'cn=ORG-AI-HPC,ou=AI,o=FH-Fulda') if __name__ == '__main__': cli()