From 57c108aea0975da51987afe741c559743b776d99 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Sat, 16 Jul 2022 22:16:24 +0200 Subject: [PATCH] add gitea tests --- seed/dns-local/tests/mookdns.py | 44 ++++ seed/dovecot/templates/imap.yml | 4 +- seed/dovecot/tests/test_imap.py | 108 ++++++--- seed/gitea/DEBUG.md | 5 +- seed/gitea/dictionaries/31_gitea.xml | 1 + seed/gitea/templates/gitea.service | 2 +- seed/gitea/templates/gitea.yml | 9 + seed/gitea/tests/test_gitea.py | 226 ++++++++++++++++++ seed/lemonldap/templates/lmConf-1.json | 1 + .../nginx-reverse-proxy/tests/test_revprox.py | 11 +- seed/openldap/DEBUG.md | 6 +- seed/openldap/templates/openldap.yml | 19 +- seed/openldap/templates/users.ldif | 86 ++++--- seed/openldap/templates/users_mod.ldif | 42 ++-- seed/reverse-proxy-client/tests/revprox.py | 84 +++++++ 15 files changed, 547 insertions(+), 101 deletions(-) create mode 100644 seed/dns-local/tests/mookdns.py create mode 100644 seed/gitea/templates/gitea.yml create mode 100644 seed/gitea/tests/test_gitea.py create mode 100644 seed/reverse-proxy-client/tests/revprox.py diff --git a/seed/dns-local/tests/mookdns.py b/seed/dns-local/tests/mookdns.py new file mode 100644 index 0000000..8ab236f --- /dev/null +++ b/seed/dns-local/tests/mookdns.py @@ -0,0 +1,44 @@ +import socket +from shutil import copyfile, move +from os import remove +from os.path import isfile + + +class MookDns: + # Monkey patch to force IPv4 resolution + def __init__(self, ip): + self.ip = ip + + def __enter__(self): + self.old_getaddrinfo = socket.getaddrinfo + def new_getaddrinfo(*args, **kwargs): + ret = self.old_getaddrinfo(*args, **kwargs) + dns = list(ret[0]) + dns[-1] = (self.ip, dns[-1][1]) + return [dns] + socket.getaddrinfo = new_getaddrinfo + return self + + def __exit__(self, exc_type, exc, tb): + socket.getaddrinfo = self.old_getaddrinfo + + +class MookDnsSystem: + # Monkey patch to force IPv4 resolution + def __init__(self, dns, ip): + self.dns = dns + self.ip = ip + + def __enter__(self): + if not isfile('/etc/hosts.risotto'): + copyfile('/etc/hosts', '/etc/hosts.risotto') + with open('/etc/hosts.risotto', 'r') as risotto: + with open('/etc/hosts', 'w') as hosts: + for line in risotto.readlines(): + if self.dns not in line: + hosts.write(line) + hosts.write(f'{self.ip} {self.dns}') + + def __exit__(self, exc_type, exc, tb): + remove('/etc/hosts') + move('/etc/hosts.risotto', '/etc/hosts') diff --git a/seed/dovecot/templates/imap.yml b/seed/dovecot/templates/imap.yml index 1836ec5..d5ef2bf 100644 --- a/seed/dovecot/templates/imap.yml +++ b/seed/dovecot/templates/imap.yml @@ -4,7 +4,7 @@ address: %%ip_eth0 dns: %%domain_name_eth0 username: %%username -password: %%get_password(server_name=%%ldap_server_address, username=%%username, description="ldap user", type="cleartext", hide=%%hide_secret, temporary=True) +password: %%get_password(server_name='test', username=%%username, description="test", type="cleartext", hide=%%hide_secret, temporary=True) username_family: %%username_family -password_family: %%get_password(server_name=%%ldap_server_address, username=%%username_family, description="ldap family user", type="cleartext", hide=%%hide_secret, temporary=True) +password_family: %%get_password(server_name='test', username=%%username_family, description='test', type="cleartext", hide=%%hide_secret, temporary=True) name_family: %%name_family diff --git a/seed/dovecot/tests/test_imap.py b/seed/dovecot/tests/test_imap.py index 6063348..9fb425b 100644 --- a/seed/dovecot/tests/test_imap.py +++ b/seed/dovecot/tests/test_imap.py @@ -10,8 +10,8 @@ from smtplib import SMTP, SMTPNotSupportedError, SMTPAuthenticationError conf_file = f'{environ["MACHINE_TEST_DIR"]}/imap.yml' with open(conf_file) as yaml: data = load(yaml, Loader=SafeLoader) -parameters = (('user', data['username'], data['password']), - ('family', data['username_family'], data['password_family'] + "2"), +parameters = (('user', data['username'], [data['password']]), + ('family', data['username_family'], [data['password_family'], data['password_family'] + "2"]), ) @@ -19,8 +19,8 @@ def get_msg(username, msg='MESSAGE'): return f'From: {username}\r\nTo: {username}\r\n\r\nSubject: TEST\r\n{msg}\r\n' -@pytest.mark.parametrize('typ, username, password', parameters) -def test_imap_wrong_password(typ, username, password): +@pytest.mark.parametrize('typ, username, passwords', parameters) +def test_imap_wrong_password(typ, username, passwords): imap = IMAP4_SSL(data['address']) try: imap.LOGIN(username, 'b') @@ -30,17 +30,33 @@ def test_imap_wrong_password(typ, username, password): raise Exception('wrong login !') -@pytest.mark.parametrize('typ, username, password', parameters) -def test_imap_migration(typ, username, password): +@pytest.mark.parametrize('typ, username, passwords', parameters) +def test_imap_migration(typ, username, passwords): msg = get_msg(username, 'MIGRATION') if 'FIRST_RUN' in environ: smtp = SMTP(data['address'], '587') smtp.starttls() - smtp.login(username, password) + error = None + for password in passwords: + try: + smtp.login(username, password) + break + except SMTPAuthenticationError as err: + error = err + else: + raise error from error smtp.sendmail(username, username, msg) smtp.quit() imap = IMAP4_SSL(data['address']) - imap.LOGIN(username, password) + error = None + for password in passwords: + try: + imap.LOGIN(username, password) + break + except Exception as err: + error = err + else: + raise error from error imap.SELECT(readonly=True) typ, req = imap.SEARCH(None, 'ALL') assert typ == 'OK' @@ -53,49 +69,67 @@ def test_imap_migration(typ, username, password): imap.LOGOUT() -@pytest.mark.parametrize('typ, username, password', parameters) -def test_smtp_no_tls(typ, username, password): +@pytest.mark.parametrize('typ, username, passwords', parameters) +def test_smtp_no_tls(typ, username, passwords): smtp = SMTP(data['address'], '587') - try: - smtp.login(username, password) - raise Exception('no tls!') - except SMTPNotSupportedError: - pass + with pytest.raises(SMTPNotSupportedError): + smtp.login(username, passwords[0]) -@pytest.mark.parametrize('typ, username, password', parameters) -def test_smtp_wrong_passwd(typ, username, password): +@pytest.mark.parametrize('typ, username, passwords', parameters) +def test_smtp_wrong_passwd(typ, username, passwords): smtp = SMTP(data['address'], '587') smtp.starttls() - try: + with pytest.raises(SMTPAuthenticationError): smtp.login(username, 'a') - raise Exception('wrong password!') - except SMTPAuthenticationError: - pass smtp.quit() -@pytest.mark.parametrize('typ, username, password', parameters) -def test_smtp_login(typ, username, password): +@pytest.mark.parametrize('typ, username, passwords', parameters) +def test_smtp_login(typ, username, passwords): smtp = SMTP(data['address'], '587') smtp.starttls() - smtp.login(username, password) + error = None + for password in passwords: + try: + smtp.login(username, password) + break + except SMTPAuthenticationError as err: + error = err + else: + raise error from error smtp.quit() -@pytest.mark.parametrize('typ, username, password', parameters) -def test_smtp_sendmail(typ, username, password): +@pytest.mark.parametrize('typ, username, passwords', parameters) +def test_smtp_sendmail(typ, username, passwords): smtp = SMTP(data['address'], '587') smtp.starttls() - smtp.login(username, password) + error = None + for password in passwords: + try: + smtp.login(username, password) + break + except SMTPAuthenticationError as err: + error = err + else: + raise error from error smtp.sendmail(username, username, get_msg(username)) smtp.quit() -@pytest.mark.parametrize('typ, username, password', parameters) -def test_imap_read_mail(typ, username, password): +@pytest.mark.parametrize('typ, username, passwords', parameters) +def test_imap_read_mail(typ, username, passwords): imap = IMAP4_SSL(data['address']) - imap.LOGIN(username, password) + error = None + for password in passwords: + try: + imap.LOGIN(username, password) + break + except Exception as err: + error = err + else: + raise error from error imap.SELECT(readonly=True) typ, req = imap.SEARCH(None, 'ALL') assert typ == 'OK' @@ -111,10 +145,18 @@ def test_imap_read_mail(typ, username, password): imap.LOGOUT() -@pytest.mark.parametrize('typ, username, password', parameters) -def test_imap_delete_mail(typ, username, password): +@pytest.mark.parametrize('typ, username, passwords', parameters) +def test_imap_delete_mail(typ, username, passwords): imap = IMAP4_SSL(data['address']) - imap.LOGIN(username, password) + error = None + for password in passwords: + try: + imap.LOGIN(username, password) + break + except Exception as err: + error = err + else: + raise error from error imap.SELECT() typ, req = imap.SEARCH(None, 'ALL') msg_no = req[0].split() diff --git a/seed/gitea/DEBUG.md b/seed/gitea/DEBUG.md index ca0ce10..26232ba 100644 --- a/seed/gitea/DEBUG.md +++ b/seed/gitea/DEBUG.md @@ -3,5 +3,8 @@ Créer un utilisateur su - gitea -s /bin/bash -c "gitea admin user create --username gnunux --password Njw_csh7DeeZtWDxC6WVXDdB-9A --email gnunux@gnunux.info --admin -c /etc/gitea/app.ini" +DEBUG +===== - +sed -i 's/info/debug/g' /etc/gitea/app.ini +systemctl restart gitea diff --git a/seed/gitea/dictionaries/31_gitea.xml b/seed/gitea/dictionaries/31_gitea.xml index 812ea94..f8ed610 100644 --- a/seed/gitea/dictionaries/31_gitea.xml +++ b/seed/gitea/dictionaries/31_gitea.xml @@ -6,6 +6,7 @@ /sysusers.d/0gitea.conf /tmpfiles.d/0gitea.conf /etc/gitea/app.ini + /tests/gitea.yml diff --git a/seed/gitea/templates/gitea.service b/seed/gitea/templates/gitea.service index 3100900..9f19bf7 100644 --- a/seed/gitea/templates/gitea.service +++ b/seed/gitea/templates/gitea.service @@ -16,7 +16,7 @@ User=gitea Group=gitea WorkingDirectory=/srv/gitea/lib/ ExecStart=/usr/bin/gitea web --config /etc/gitea/app.ini -ExecStartPost=-/usr/bin/timeout 90 bash -c 'while ! /usr/bin/gitea admin auth list --config /etc/gitea/app.ini | grep "OAuth2"; do echo "TRY TO CONFIGURE"; /usr/bin/gitea admin auth add-oauth --name "%%domain_name_eth0" --provider "openidConnect" --key "%%oauth2_client_id" --secret "%%oauth2_client_secret" --scopes "profile email" --auto-discover-url "https://%%oauth2_client_server_domainname/.well-known/openid-configuration" --config /etc/gitea/app.ini; sleep 2; done; echo "CONFIGURATION DONE"' +ExecStartPre=-/bin/bash -c 'if /usr/bin/gitea admin auth list --config /etc/gitea/app.ini | grep "OAuth2"; then echo "UPDATE";id=$(/usr/bin/gitea --config /etc/gitea/app.ini admin auth list |tail -n 1|awk "{ print \$1}");/usr/bin/gitea admin auth update-oauth --id $id --name "%%domain_name_eth0" --provider "openidConnect" --key "%%oauth2_client_id" --secret "%%oauth2_client_secret" --scopes "profile email" --auto-discover-url "https://%%oauth2_client_server_domainname/.well-known/openid-configuration" --config /etc/gitea/app.ini;else echo "CONFIGURE"; /usr/bin/gitea admin auth add-oauth --name "%%domain_name_eth0" --provider "openidConnect" --key "%%oauth2_client_id" --secret "%%oauth2_client_secret" --scopes "profile email" --auto-discover-url "https://%%oauth2_client_server_domainname/.well-known/openid-configuration" --config /etc/gitea/app.ini;fi;sleep 2; echo "CONFIGURATION DONE"' Restart=always Environment=USER=gitea HOME=/srv/gitea/home GITEA_WORK_DIR=/srv/gitea/lib diff --git a/seed/gitea/templates/gitea.yml b/seed/gitea/templates/gitea.yml new file mode 100644 index 0000000..fcd6671 --- /dev/null +++ b/seed/gitea/templates/gitea.yml @@ -0,0 +1,9 @@ +%set %%username="rougail_test@silique.fr" +ip: %%ip_eth0 +revprox_ip: %%revprox_client_server_ip +base_url: https://%%revprox_client_external_domainname%%revprox_client_location[0] +auth_url: %%oauth2_client_external[0] +auth_server: %%oauth2_server_domainname +username: %%username +password: %%get_password(server_name='test', username=%%username, description='test', type="cleartext", hide=%%hide_secret, temporary=True) +gitea_title: "%%gitea_title" diff --git a/seed/gitea/tests/test_gitea.py b/seed/gitea/tests/test_gitea.py new file mode 100644 index 0000000..003aca0 --- /dev/null +++ b/seed/gitea/tests/test_gitea.py @@ -0,0 +1,226 @@ +from yaml import load, SafeLoader +from os import environ, makedirs +from os.path import expandvars, isfile, isdir, dirname, join +from re import search +from dulwich.porcelain import init, clone, add, commit, push + +from tempfile import TemporaryDirectory +from subprocess import run + + +from revprox import Authentication +from mookdns import MookDnsSystem + + +PORT = '3000' +GITEA_USERNAME = 'gitea' +KEY_FILE = expandvars("$HOME/tests/risotto") + + +AUTHENTICATION = None +DATA = None + + +def get_data(): + global DATA + if not DATA: + conf_file = f'{environ["MACHINE_TEST_DIR"]}/gitea.yml' + with open(conf_file) as yaml: + DATA = load(yaml, Loader=SafeLoader) + return DATA + + +def get_authentication(data): + global AUTHENTICATION + if not AUTHENTICATION: + AUTHENTICATION = Authentication(data['auth_url'], + data['auth_server'], + data['revprox_ip'], + data['username'], + data['password'], + f'{data["username"]} - Dashboard - {data["gitea_title"]}', + ) + return AUTHENTICATION + + +def get_info(authentication, + url, + with_uid=False, + with_data_id=False, + found_string=None + ): + # + pattern_csrf = r'name="_csrf" value="([a-zA-Z0-9\-\_=]+)"' + ret = authentication.get(url) + csrf = search(pattern_csrf, ret)[1] + ret_data = [] + if with_uid: + pattern_uid = r'input type="hidden" id="uid" name="uid" value="(\d)+"' + uid = search(pattern_uid, ret) + if uid is None: + ret_data.append(uid) + else: + ret_data.append(uid[1]) + if with_data_id: + pattern_uid = r'/user/settings/keys/delete?type=ssh" data-id="(\d)+"' + uid = search(pattern_uid, ret) + if uid is None: + ret_data.append(uid) + else: + ret_data.append(uid[1]) + if found_string: + ret_data.append(found_string in ret) + ret_data.append(csrf) + if len(ret_data) == 1: + return ret_data[0] + return ret_data + + +def add_ssh_key(authentication, data): + # Send key to gitea + url = f'{data["base_url"]}user/settings/keys' + is_already_key, csrf = get_info(authentication, url, found_string='test_key_risotto') + if is_already_key: + return + # Gen SSH key if needed + if not isfile(KEY_FILE): + key_dir = dirname(KEY_FILE) + if not isdir(key_dir): + makedirs(key_dir) + cmd = ['/usr/bin/ssh-keygen', '-N', '', '-f', KEY_FILE] + run(cmd) + with open(f'{KEY_FILE}.pub') as fh: + key = fh.read() + authentication.post(url, {'_csrf': csrf, 'title': 'test_key_risotto', 'content': key, 'type': 'ssh'}) + + +def delete_ssh_key(authentication, data): + url = f'{data["base_url"]}user/settings/keys' + is_already_key, csrf = get_info(authentication, url, found_string='test_key_risotto') + if is_already_key: + uid, csrf = get_info(authentication, url, with_data_id=True) + url = f'{data["base_url"]}user/settings/keys/delete?type=ssh' + authentication.post(url, {'_csrf': csrf, 'id': uid}) + is_already_key, csrf = get_info(authentication, url, found_string='test_key_risotto') + + +def test_gitea(): + data = get_data() + get_authentication(data) + + +def test_gitea_repos(): + data = get_data() + authentication = get_authentication(data) + if 'FIRST_RUN' in environ: + url = f'{data["base_url"]}repo/create' + uid, csrf = get_info(authentication, url, with_uid=True) + authentication.post(url, {'_csrf': csrf, 'uid': uid, 'repo_name': 'test_persistent'}) + url = f'{data["base_url"]}api/v1/repos/search?sort=updated&order=desc&uid=1&team_id=0&q=&page=1&mode=' + json = authentication.get(url, json=True) + assert json['ok'] + assert len(json['data']) == 1 + username = data['username'].split('@', 1)[0] + assert json['data'][0]['full_name'] == f'{username}/test_persistent' + + +def test_gitea_create_repo(): + data = get_data() + authentication = get_authentication(data) + url = f'{data["base_url"]}repo/create' + uid, csrf = get_info(authentication, url, with_uid=True) + authentication.post(url, {'_csrf': csrf, 'uid': uid, 'repo_name': 'test', 'default_branch': 'main'}) + url = f'{data["base_url"]}api/v1/repos/search?sort=updated&order=desc&uid=1&team_id=0&q=&page=1&mode=' + json = authentication.get(url, json=True) + assert json['ok'] + assert len(json['data']) == 2 + username = data['username'].split('@', 1)[0] + assert {dat['full_name'] for dat in json['data']} == set([f'{username}/test_persistent', f'{username}/test']) + + +def test_repo(): + data = get_data() + authentication = get_authentication(data) + if 'FIRST_RUN' in environ: + # delete_ssh_key(authentication, data) + add_ssh_key(authentication, data) + with TemporaryDirectory() as tmpdirname: + username = data['username'].split('@', 1)[0] + dns = data['base_url'].split('/', 3)[2] + ssh_url = f'ssh://{GITEA_USERNAME}@{dns}:2222/{username}/test.git' + with MookDnsSystem(dns, data['ip']): + filename = join(tmpdirname, 'test.txt') + with open(filename, 'w') as fh: + fh.write('test') + repo = init(tmpdirname) + add(repo, filename) + commit(repo, message=b'test commit') + push(repo=repo, + remote_location=ssh_url, + refspecs='master', + ) + lst = list(repo.get_walker()) + assert len(lst) == 1 + assert lst[0].commit.message == b'test commit' + + +def test_clone_http(): + data = get_data() + authentication = get_authentication(data) + if 'FIRST_RUN' in environ: + # delete_ssh_key(authentication, data) + add_ssh_key(authentication, data) + with TemporaryDirectory() as tmpdirname: + username = data['username'].split('@', 1)[0] + dns = data['base_url'].split('/', 3)[2] + http_url = f'{data["base_url"]}{username}/test.git' + with MookDnsSystem(dns, data['revprox_ip']): + repo = clone(http_url, tmpdirname) + lst = list(repo.get_walker()) + assert len(lst) == 1 + assert lst[0].commit.message == b'test commit' + + +def test_gitea_delete_repo(): + repo_name = 'test' + data = get_data() + authentication = get_authentication(data) + username = data['username'].split('@', 1)[0] + url = f'{data["base_url"]}{username}/{repo_name}/settings' + csrf = get_info(authentication, url) + authentication.post(url, {'_csrf': csrf, 'action': 'delete', 'repo_name': repo_name}) + url = f'{data["base_url"]}api/v1/repos/search?sort=updated&order=desc&uid=1&team_id=0&q=&page=1&mode=' + json = authentication.get(url, json=True) + assert json['ok'] + assert len(json['data']) == 1 + username = data['username'].split('@', 1)[0] + assert json['data'][0]['full_name'] == f'{username}/test_persistent' + + +def test_repo_persistent(): + data = get_data() + authentication = get_authentication(data) + if 'FIRST_RUN' in environ: + # delete_ssh_key(authentication, data) + add_ssh_key(authentication, data) + with TemporaryDirectory() as tmpdirname: + username = data['username'].split('@', 1)[0] + dns = data['base_url'].split('/', 3)[2] + ssh_url = f'ssh://{GITEA_USERNAME}@{dns}:2222/{username}/test_persistent.git' + with MookDnsSystem(dns, data['ip']): + if 'FIRST_RUN' in environ: + filename = join(tmpdirname, 'test.txt') + with open(filename, 'w') as fh: + fh.write('test') + repo = init(tmpdirname) + add(repo, filename) + commit(repo, message=b'test commit') + push(repo=repo, + remote_location=ssh_url, + refspecs='master', + ) + else: + repo = clone(ssh_url, tmpdirname) + lst = list(repo.get_walker()) + assert len(lst) == 1 + assert lst[0].commit.message == b'test commit' diff --git a/seed/lemonldap/templates/lmConf-1.json b/seed/lemonldap/templates/lmConf-1.json index c7dd06f..38b3731 100644 --- a/seed/lemonldap/templates/lmConf-1.json +++ b/seed/lemonldap/templates/lmConf-1.json @@ -167,6 +167,7 @@ commentStartToken = § "portalDisplayResetPassword": 0, "portalMainLogo": "risotto/logo.png", "showLanguages": 0, + "requireToken": "$env->{REMOTE_ADDR} ne '%%gateway_eth0'", "whatToTrace" : "_whatToTrace", %set %%remotes = {} %for %%index, %%app in %%enumerate(%%oauth2.remotes) diff --git a/seed/nginx-reverse-proxy/tests/test_revprox.py b/seed/nginx-reverse-proxy/tests/test_revprox.py index ea50b26..d48cc78 100644 --- a/seed/nginx-reverse-proxy/tests/test_revprox.py +++ b/seed/nginx-reverse-proxy/tests/test_revprox.py @@ -16,7 +16,12 @@ def req(url, ip, verify=True): dns[-1] = (ip, dns[-1][1]) return [dns] socket.getaddrinfo = new_getaddrinfo - ret = get(url, verify=verify) + if not verify: + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + ret = get(url, verify=verify) + else: + ret = get(url, verify=verify) ret_code = ret.status_code content = ret.content socket.getaddrinfo = old_getaddrinfo @@ -29,9 +34,7 @@ def test_revprox(): data = load(yaml, Loader=SafeLoader) # test unknown domain url = 'google.fr' - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - ret_code, content = req(f'https://{url}', data['address'], verify=False) + ret_code, content = req(f'https://{url}', data['address'], verify=False) assert ret_code == 200, f'https://{url} do not returns code 200 but {ret_code}' assert "Test Page for the HTTP Server on Fedora" in content, f'https://{url} returns default fedora page' # test certificate diff --git a/seed/openldap/DEBUG.md b/seed/openldap/DEBUG.md index 8b91062..a760780 100644 --- a/seed/openldap/DEBUG.md +++ b/seed/openldap/DEBUG.md @@ -27,4 +27,8 @@ grep ldapAgentPassword /etc/nextcloud/nextcloud.init Search information with standard user: -ldapsearch -D cn=gnunux@gnunux.info,ou=users,ou=in,o=gnunux,o=info -w "1vCE09NRW2kxHIpf1PkehOS9bSLZual82saHSBj9RPM" -b cn=gnunux@gnunux.info,ou=users,ou=in,o=gnunux,o=info +ldapsearch -D cn=admin,ou=in,o=gnunux,o=info -w "1vCE09NRW2kxHIpf1PkehOS9bSLZual82saHSBj9RPM" -b cn=gnunux@gnunux.info,ou=users,ou=in,o=gnunux,o=info + +# Delete User + +ldapdelete -D cn=gnunux@gnunux.info,ou=users,ou=in,o=gnunux,o=info -y /usr/local/lib/secrets/admin_ldap.pwd cn=rougail_test@gnunux.info,ou=in,o=gnunux,o=info diff --git a/seed/openldap/templates/openldap.yml b/seed/openldap/templates/openldap.yml index 5466d09..50ef8b5 100644 --- a/seed/openldap/templates/openldap.yml +++ b/seed/openldap/templates/openldap.yml @@ -1,13 +1,16 @@ %set %%username = "rougail_test@silique.fr" %set %%username_family = "rougail_test@gnunux.info" -%set %%familydn = %%calc_ldapclient_base_dn(%%ldapclient_base_dn, family_name='gnunux') +%set %%name_family = 'gnunux' +%set %%familydn = %%calc_ldapclient_base_dn(%%ldapclient_base_dn, family_name=%%name_family) +%set %%userdn = 'cn=' + %%username + ',' + %%calc_ldapclient_base_dn(%%ldapclient_base_dn) +%set %%userfamilydn = 'cn=' + %%username_family + ',' + %%familydn address: %%ip_eth0 admin_dn: %%ldapclient_user admin_password: %%ldapclient_user_password -user_dn: cn=%%username,%%ldap_user_dn -user_password: %%get_password(server_name=%%ldap_server_address, username=%%username, description="ldap user", type="cleartext", hide=%%hide_secret, temporary=True) -user_family_dn: cn=%%username_family,%%familydn -user_family_password: %%get_password(server_name=%%ldap_server_address, username=%%username_family, description="ldap family user", type="cleartext", hide=%%hide_secret, temporary=True) +user_dn: %%userdn +user_password: %%get_password(server_name='test', username=%%username, description='test', type="cleartext", hide=%%hide_secret, temporary=True) +user_family_dn: %%userfamilydn +user_family_password: %%get_password(server_name='test', username=%%username_family, description="test", type="cleartext", hide=%%hide_secret, temporary=True) base_account_dn: %%ldap_account_dn base_user_dn: %%ldap_user_dn base_family_dn: %%familydn @@ -18,6 +21,8 @@ remote%%idx: cn=%%name,%%ldapclient_base_dn remote_password%%idx: %%get_password(server_name=%%domain_name_eth0, username=%%name, description="remote account", type="cleartext", hide=%%hide_secret, temporary=True) %end for users: + %%username: %%userdn + %%username_family: %%userfamilydn %for %%user in %%accounts.users.ldap_user_mail %%user: cn=%%user,%%ldap_user_dn %end for @@ -29,11 +34,15 @@ users: %end for groups: users: + - %%userdn %for %%user in %%accounts.users.ldap_user_mail - cn=%%user,%%ldap_user_dn %end for %for %%family in %%accounts.families %%family: + %if %%family == %%name_family + - %%userfamilydn + %end if %for %%user in %%accounts['family_' + %%family]['users_' + %%family]['ldap_user_mail_' + %%family] - cn=%%user,%%families %end for diff --git a/seed/openldap/templates/users.ldif b/seed/openldap/templates/users.ldif index 057c5bc..ad6d0b8 100644 --- a/seed/openldap/templates/users.ldif +++ b/seed/openldap/templates/users.ldif @@ -1,4 +1,6 @@ -%set name_family = 'gnunux' +%set %%username="rougail_test@silique.fr" +%set %%username_family="rougail_test@gnunux.info" +%set %%name_family="gnunux" # BaseDN %set groups = {} dn: %%ldapclient_base_dn @@ -44,30 +46,17 @@ ou: users objectClass: top objectClass: organizationalUnit +%set %%userdn = 'cn=' + %%username + ',' + %%calc_ldapclient_base_dn(%%ldapclient_base_dn) +%set %%userfamilydn = 'cn=' + %%username_family + ',' + %%calc_ldapclient_base_dn(%%ldapclient_base_dn, family_name=%%name_family) +%set %%acc = [(%%userdn, %%username, %%get_password(server_name='test', username=%%username, description="test", type="cleartext", hide=%%hide_secret, temporary=True), 'Rougail', 'Test', 'rougail_test', [], 'users'), + (%%userfamilydn, %%username_family, %%get_password(server_name='test', username=%%username_family, description='test', type="cleartext", hide=%%hide_secret, temporary=True), 'Rougail', 'Test', 'rougail_test_gnunux', [], %%name_family), + ] +%set %%groups['users'] = [%%userdn] +%set %%groups[%%name_family] = [%%userfamilydn] %for %%user in %%accounts.users.ldap_user_mail %set %%userdn = "cn=" + %%user + "," + %%users -%%groups.setdefault('users', []).append(%%userdn) -dn: %%userdn -cn: %%user -mail: %%user -sn: %%user.ldap_user_sn -givenName: %%user.ldap_user_gn -uid: %%user.ldap_user_uid -userPassword:: %%ssha_encode(%%user.ldap_user_password) -homeDirectory: /srv/home/users/%%user -mailLocalAddress: %%user - %if %%user.ldap_user_aliases - %for %%alias in %%user.ldap_user_aliases -mailLocalAddress: %%alias - %end for - %end if -uidNumber: 0 -gidNumber: 0 -objectClass: top -objectClass: inetOrgPerson -objectClass: posixAccount -objectClass: inetLocalMailRecipient - +%%acc.append((%%userdn, %%user, %%user.ldap_user_password, %%user.ldap_user_sn, %%user.ldap_user_gn, %%user.ldap_user_uid, %%user.ldap_user_aliases, 'users'))%slurp +%%groups.setdefault('users', []).append(%%userdn)%slurp %end for ## Families dn: %%calc_ldapclient_base_dn(%%ldapclient_base_dn, family_name='-') @@ -84,21 +73,53 @@ objectClass: organizationalUnit %for %%user in %%accounts['family_' + %%family]['users_' + %%family]['ldap_user_mail_' + %%family] %set %%userdn = "cn=" + %%user + "," + %%families -%%groups.setdefault(%%family, []).append(%%userdn) +%%groups.setdefault(%%family, []).append(%%userdn)%slurp +%%acc.append((%%userdn, %%user, %%user['ldap_user_password_' + %%family], %%user['ldap_user_sn_' + %%family], %%user['ldap_user_gn_' + %%family], %%user['ldap_user_uid_' + %%family], %%user['ldap_user_aliases_' + %%family], %%family))%slurp +#pouet +#dn: %%userdn +#cn: %%user +#mail: %%user +#sn: +#givenName: +#uid: +#userPassword:: %%ssha_encode() +#homeDirectory: /srv/home/families/%%family/%%user +#mailLocalAddress: %%user +# %if %%user['ldap_user_aliases_' + %%family] +# %for %%alias in +#mailLocalAddress: %%alias +# %end for +# %end if +#uidNumber: 0 +#gidNumber: 0 +#objectClass: top +#objectClass: inetOrgPerson +#objectClass: posixAccount +#objectClass: inetLocalMailRecipient +# +# %end for +#%end for + %end for +%end for +%for %%userdn, %%user, %%password, %%sn, %%gn, %%uid, %%aliases, %%family in %%acc dn: %%userdn cn: %%user mail: %%user -sn: %%user['ldap_user_sn_' + %%family] -givenName: %%user['ldap_user_gn_' + %%family] -uid: %%user['ldap_user_uid_' + %%family] -userPassword:: %%ssha_encode(%%user['ldap_user_password_' + %%family]) +sn: %%sn +givenName: %%gn +uid: %%uid +userPassword:: %%ssha_encode(%%password) +%if %%family == 'users' +homeDirectory: /srv/home/users/%%user +%else homeDirectory: /srv/home/families/%%family/%%user +%end if mailLocalAddress: %%user - %if %%user['ldap_user_aliases_' + %%family] - %for %%alias in %%user['ldap_user_aliases_' + %%family] + %if %%aliases + %for %%alias in %%aliases mailLocalAddress: %%alias - %end for - %end if + %end for + %end if uidNumber: 0 gidNumber: 0 objectClass: top @@ -106,7 +127,6 @@ objectClass: inetOrgPerson objectClass: posixAccount objectClass: inetLocalMailRecipient - %end for %end for ## Groups %set %%groupdn = %%ldap_group_dn diff --git a/seed/openldap/templates/users_mod.ldif b/seed/openldap/templates/users_mod.ldif index f4fce20..e85ada3 100644 --- a/seed/openldap/templates/users_mod.ldif +++ b/seed/openldap/templates/users_mod.ldif @@ -1,4 +1,6 @@ -%set groups = {} +%set %%username="rougail_test@silique.fr" +%set %%username_family="rougail_test@gnunux.info" +%set %%name_family="gnunux" # Remote %set %%acc = [] %for %%idx in %%range(3) @@ -17,30 +19,29 @@ userPassword:: %%ssha_encode(%%password) %end for # Users +%set %%userdn = 'cn=' + %%username + ',' + %%ldapclient_base_dn +%set %%userfamilydn = 'cn=' + %%username_family + ',' + %%calc_ldapclient_base_dn(%%ldapclient_base_dn, family_name=%%name_family) +%set %%acc = [(%%userdn, %%username, ['alias_' + %%username]), + (%%userfamilydn, %%username_family, ['alias_' + %%username_family]), + ] +%set groups = {'users': [%%userdn], + %%name_family: [%%userfamilydn], + } %set %%users = %%ldap_user_dn %for %%user in %%accounts.users.ldap_user_mail %set %%userdn = 'cn=' + %%user + ',' + %%users -%%groups.setdefault('users', []).append(%%userdn)%slurp -dn: %%userdn -changetype: modify -#add: objectClass -#objectClass: inetLocalMailRecipient -#- -replace: mailLocalAddress -mailLocalAddress: %%user - %if %%user.ldap_user_aliases - %for %%alias in %%user.ldap_user_aliases -mailLocalAddress: %%alias - %end for - %end if - +%%groups['users'].append(%%userdn)%slurp +%%acc.append((%%userdn, %%user, %%user.ldap_user_aliases))%slurp %end for -# Families %for %%family in %%accounts.families %set %%families = %%calc_ldapclient_base_dn(%%ldapclient_base_dn, %%family) %for %%user in %%accounts['family_' + %%family]['users_' + %%family]['ldap_user_mail_' + %%family] %set %%userdn = 'cn=' + %%user + ',' + %%families %%groups.setdefault(%%family, []).append(%%userdn)%slurp +%%acc.append((%%userdn, %%user, %%user['ldap_user_aliases_' + %%family]))%slurp + %end for +%end for +%for %%userdn, %%user, %%aliases in %%acc dn: %%userdn changetype: modify #add: objectClass @@ -48,13 +49,12 @@ changetype: modify #- replace: mailLocalAddress mailLocalAddress: %%user - %if %%user['ldap_user_aliases_' + %%family] - %for %%alias in %%user['ldap_user_aliases_' + %%family] + %if %%aliases + %for %%alias in %%aliases mailLocalAddress: %%alias - %end for - %end if + %end for + %end if - %end for %end for # Groups %set %%groupdn = %%ldap_group_dn diff --git a/seed/reverse-proxy-client/tests/revprox.py b/seed/reverse-proxy-client/tests/revprox.py new file mode 100644 index 0000000..9b85bf5 --- /dev/null +++ b/seed/reverse-proxy-client/tests/revprox.py @@ -0,0 +1,84 @@ +from requests import get, post, session +from mookdns import MookDns + + +class Authentication: + def __init__(self, + auth_url, + portal_server, + ip, + username, + password, + title, + ): + self.ip = ip + with session() as req: + with MookDns(self.ip): + self.is_lemonldap(req, + auth_url, + ) + self.auth_lemonldap(req, + portal_server, + username, + password, + title, + ) + self.cookies = dict(req.cookies) + +# @staticmethod + def is_lemonldap(self, + req, + url, + ): + ret = req.get(url) + code = ret.status_code + content = ret.content + assert code == 200 + assert b'Authentication portal' in content + + def auth_lemonldap(self, + req, + portal_server, + username, + password, + title, + ): + # authentification + json = {'user': username, + 'password': password, + } + headers = {"Content-Type": "application/x-www-form-urlencoded", + "Accept": "application/json", + } + portal_url = f'https://{portal_server}/oauth2/' + ret = req.post(portal_url, data=json, headers=headers) + json = ret.json() + assert json['error'] + assert json['result'] == 1 + assert json['id'] == ret.cookies.get('lemonldap') + # authorization code + # curl -X POST -d user=dwho -d password=dwho -H 'Accept: application/json' 'https://oidctest.wsweet.org/oauth2/' + # curl -s -D - -o /dev/null -b lemonldap=0640f95827111f00ba7ad5863ba819fe46cfbcecdb18ce525836369fb4c8350b 'https://oidctest.wsweet.org/oauth2/authorize?response_type=code&client_id=private&scope=openid+profile+email&redirect_uri=http://localhost' | grep '^location' + authorize_url = f'{portal_url}authorize' + ret = req.get(authorize_url) + assert ret.status_code == 200 + assert title in ret.content.decode() + + def get(self, + url, + json=False, + ): + with MookDns(self.ip): + ret = get(url, cookies=self.cookies) + assert ret.status_code == 200, f'return code is {ret.status_code}' + if json: + return ret.json() + return ret.content.decode() + + def post(self, + url, + data, + ): + with MookDns(self.ip): + ret = post(url, cookies=self.cookies, data=data) + assert ret.status_code == 200, f'return code is {ret.status_code}'