-
-
Notifications
You must be signed in to change notification settings - Fork 784
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LDAP Improvements and E2E testing #2199
Changes from all commits
0f78d33
63fd522
2fc415b
6b5815b
1a0a182
fa46d86
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -13,7 +13,7 @@ jobs: | |||||||
strategy: | ||||||||
fail-fast: true | ||||||||
matrix: | ||||||||
# Database ENV Variablse as Specified by Mealie | ||||||||
# Database ENV Variables as Specified by Mealie | ||||||||
Database: [sqlite, postgres] | ||||||||
|
||||||||
# Services | ||||||||
|
@@ -27,6 +27,12 @@ jobs: | |||||||
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 | ||||||||
ports: | ||||||||
- 5432:5432 | ||||||||
ldap: | ||||||||
image: rroemhild/test-openldap | ||||||||
ports: | ||||||||
- 10389:10389 | ||||||||
- 10636:10636 | ||||||||
Comment on lines
+32
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
You shouldn't have to expose any ports if you use the service name (similar to how you can do in docker-compose). |
||||||||
|
||||||||
# Steps | ||||||||
steps: | ||||||||
- name: Check out repository | ||||||||
|
@@ -82,5 +88,17 @@ jobs: | |||||||
env: | ||||||||
DB_ENGINE: ${{ matrix.Database }} | ||||||||
POSTGRES_SERVER: localhost | ||||||||
LDAP_AUTH_ENABLED: True | ||||||||
LDAP_SERVER_URL: ldap://localhost:10389 | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I think you can set it to the name of the service. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason I used localhost instead of the service name is mainly to keep it consistent with how the Postgres service is being used above |
||||||||
LDAP_TLS_INSECURE: true | ||||||||
LDAP_ENABLE_STARTTLS: false | ||||||||
LDAP_BASE_DN: "ou=people,dc=planetexpress,dc=com" | ||||||||
LDAP_QUERY_BIND: "cn=admin,dc=planetexpress,dc=com" | ||||||||
LDAP_QUERY_PASSWORD: "GoodNewsEveryone" | ||||||||
LDAP_USER_FILTER: "(&(|({id_attribute}={input})({mail_attribute}={input}))(|(memberOf=cn=ship_crew,ou=people,dc=planetexpress,dc=com)(memberOf=cn=admin_staff,ou=people,dc=planetexpress,dc=com)))" | ||||||||
LDAP_ADMIN_FILTER: "memberOf=cn=admin_staff,ou=people,dc=planetexpress,dc=com" | ||||||||
LDAP_ID_ATTRIBUTE: uid | ||||||||
LDAP_NAME_ATTRIBUTE: cn | ||||||||
LDAP_MAIL_ATTRIBUTE: mail | ||||||||
run: | | ||||||||
make backend-test |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
import json | ||
import os | ||
|
||
from fastapi.testclient import TestClient | ||
import pytest | ||
|
||
from mealie.core.config import get_app_settings | ||
from mealie.repos.repository_factory import AllRepositories | ||
|
@@ -57,3 +58,192 @@ def test_user_lockout_after_bad_attemps(api_client: TestClient, unique_user: Tes | |
user_service = UserService(database) | ||
user = database.users.get_one(unique_user.user_id) | ||
user_service.unlock_user(user) | ||
|
||
|
||
@pytest.mark.skipif(not os.environ.get("GITHUB_ACTIONS", False), reason="requires ldap service in github actions") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This makes it impossible to test locally. Is there a reason you can't set it to skip unless There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason it's like that and not just checking for the LDAP url variable is because the tests rely on the specific docker image that is spun up during the tests. So just setting your LDAP url, the tests would likely fail since it wouldn't be the correct LDAP url and wouldn't have the correct users the tests expect. You can still test it locally by setting |
||
def test_ldap_user_login(api_client: TestClient): | ||
form_data = {"username": "bender", "password": "bender"} | ||
response = api_client.post(api_routes.auth_token, data=form_data) | ||
|
||
assert response.status_code == 200 | ||
|
||
data = response.json() | ||
assert data is not None | ||
assert data.get("access_token") is not None | ||
|
||
response = api_client.get(api_routes.users_self, headers={"Authorization": f"Bearer {data.get('access_token')}"}) | ||
assert response.status_code == 200 | ||
|
||
data = response.json() | ||
assert data.get("username") == "bender" | ||
assert data.get("fullName") == "Bender Bending Rodríguez" | ||
assert data.get("email") == "[email protected]" | ||
assert data.get("admin") is False | ||
|
||
|
||
@pytest.mark.skipif(not os.environ.get("GITHUB_ACTIONS", False), reason="requires ldap service in github actions") | ||
def test_ldap_user_login_bad_password(api_client: TestClient): | ||
form_data = {"username": "bender", "password": "BAD_PASS"} | ||
response = api_client.post(api_routes.auth_token, data=form_data) | ||
|
||
assert response.status_code == 401 | ||
|
||
|
||
@pytest.mark.skipif(not os.environ.get("GITHUB_ACTIONS", False), reason="requires ldap service in github actions") | ||
def test_ldap_admin_login(api_client: TestClient): | ||
form_data = {"username": "professor", "password": "professor"} | ||
response = api_client.post(api_routes.auth_token, data=form_data) | ||
|
||
assert response.status_code == 200 | ||
|
||
data = response.json() | ||
assert data is not None | ||
assert data.get("access_token") is not None | ||
|
||
response = api_client.get(api_routes.users_self, headers={"Authorization": f"Bearer {data.get('access_token')}"}) | ||
assert response.status_code == 200 | ||
|
||
data = response.json() | ||
assert data.get("username") == "professor" | ||
assert data.get("fullName") == "Hubert J. Farnsworth" | ||
assert data.get("email") in ["[email protected]", "[email protected]"] | ||
assert data.get("admin") is True | ||
|
||
|
||
@pytest.mark.skipif(not os.environ.get("GITHUB_ACTIONS", False), reason="requires ldap service in github actions") | ||
def test_ldap_user_not_in_filter(api_client: TestClient): | ||
form_data = {"username": "amy", "password": "amy"} | ||
response = api_client.post(api_routes.auth_token, data=form_data) | ||
|
||
assert response.status_code == 401 | ||
|
||
|
||
@pytest.mark.skipif(not os.environ.get("GITHUB_ACTIONS", False), reason="requires ldap service in github actions") | ||
def test_ldap_user_login_starttls(api_client: TestClient): | ||
settings = get_app_settings() | ||
settings.LDAP_ENABLE_STARTTLS = True | ||
|
||
form_data = {"username": "bender", "password": "bender"} | ||
response = api_client.post(api_routes.auth_token, data=form_data) | ||
|
||
assert response.status_code == 200 | ||
|
||
data = response.json() | ||
assert data is not None | ||
assert data.get("access_token") is not None | ||
|
||
response = api_client.get(api_routes.users_self, headers={"Authorization": f"Bearer {data.get('access_token')}"}) | ||
assert response.status_code == 200 | ||
|
||
data = response.json() | ||
assert data.get("username") == "bender" | ||
assert data.get("fullName") == "Bender Bending Rodríguez" | ||
assert data.get("email") == "[email protected]" | ||
assert data.get("admin") is False | ||
|
||
get_app_settings.cache_clear() | ||
|
||
|
||
@pytest.mark.skipif(not os.environ.get("GITHUB_ACTIONS", False), reason="requires ldap service in github actions") | ||
def test_ldap_user_login_anonymous_bind(api_client: TestClient): | ||
settings = get_app_settings() | ||
settings.LDAP_QUERY_BIND = None | ||
settings.LDAP_QUERY_PASSWORD = None | ||
|
||
form_data = {"username": "bender", "password": "bender"} | ||
response = api_client.post(api_routes.auth_token, data=form_data) | ||
|
||
assert response.status_code == 200 | ||
|
||
data = response.json() | ||
assert data is not None | ||
assert data.get("access_token") is not None | ||
|
||
response = api_client.get(api_routes.users_self, headers={"Authorization": f"Bearer {data.get('access_token')}"}) | ||
assert response.status_code == 200 | ||
|
||
data = response.json() | ||
assert data.get("username") == "bender" | ||
assert data.get("fullName") == "Bender Bending Rodríguez" | ||
assert data.get("email") == "[email protected]" | ||
assert data.get("admin") is False | ||
|
||
get_app_settings.cache_clear() | ||
|
||
|
||
@pytest.mark.skipif(not os.environ.get("GITHUB_ACTIONS", False), reason="requires ldap service in github actions") | ||
def test_ldap_user_login_no_filter(api_client: TestClient): | ||
settings = get_app_settings() | ||
settings.LDAP_USER_FILTER = None | ||
|
||
form_data = {"username": "amy", "password": "amy"} | ||
response = api_client.post(api_routes.auth_token, data=form_data) | ||
|
||
assert response.status_code == 200 | ||
|
||
data = response.json() | ||
assert data is not None | ||
assert data.get("access_token") is not None | ||
|
||
response = api_client.get(api_routes.users_self, headers={"Authorization": f"Bearer {data.get('access_token')}"}) | ||
assert response.status_code == 200 | ||
|
||
data = response.json() | ||
assert data.get("username") == "amy" | ||
assert data.get("fullName") == "Amy Wong" | ||
assert data.get("email") == "[email protected]" | ||
assert data.get("admin") is False | ||
|
||
get_app_settings.cache_clear() | ||
|
||
|
||
@pytest.mark.skipif(not os.environ.get("GITHUB_ACTIONS", False), reason="requires ldap service in github actions") | ||
def test_ldap_user_login_simple_filter(api_client: TestClient): | ||
settings = get_app_settings() | ||
settings.LDAP_USER_FILTER = "(memberOf=cn=ship_crew,ou=people,dc=planetexpress,dc=com)" | ||
|
||
form_data = {"username": "bender", "password": "bender"} | ||
response = api_client.post(api_routes.auth_token, data=form_data) | ||
|
||
assert response.status_code == 200 | ||
|
||
data = response.json() | ||
assert data is not None | ||
assert data.get("access_token") is not None | ||
|
||
response = api_client.get(api_routes.users_self, headers={"Authorization": f"Bearer {data.get('access_token')}"}) | ||
assert response.status_code == 200 | ||
|
||
data = response.json() | ||
assert data.get("username") == "bender" | ||
assert data.get("fullName") == "Bender Bending Rodríguez" | ||
assert data.get("email") == "[email protected]" | ||
assert data.get("admin") is False | ||
|
||
get_app_settings.cache_clear() | ||
|
||
|
||
@pytest.mark.skipif(not os.environ.get("GITHUB_ACTIONS", False), reason="requires ldap service in github actions") | ||
def test_ldap_user_login_complex_filter(api_client: TestClient): | ||
settings = get_app_settings() | ||
settings.LDAP_USER_FILTER = "(&(objectClass=inetOrgPerson)(|(memberOf=cn=ship_crew,ou=people,dc=planetexpress,dc=com)(memberOf=cn=admin_staff,ou=people,dc=planetexpress,dc=com)))" | ||
|
||
form_data = {"username": "professor", "password": "professor"} | ||
response = api_client.post(api_routes.auth_token, data=form_data) | ||
|
||
assert response.status_code == 200 | ||
|
||
data = response.json() | ||
assert data is not None | ||
assert data.get("access_token") is not None | ||
|
||
response = api_client.get(api_routes.users_self, headers={"Authorization": f"Bearer {data.get('access_token')}"}) | ||
assert response.status_code == 200 | ||
|
||
data = response.json() | ||
assert data.get("username") == "professor" | ||
assert data.get("fullName") == "Hubert J. Farnsworth" | ||
assert data.get("email") in ["[email protected]", "[email protected]"] | ||
assert data.get("admin") is True | ||
|
||
get_app_settings.cache_clear() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just suggesting that the name match my suggestion on line 92.