import pytest
from ckan.plugins.toolkit import url_for
import ckan.tests.factories as factories
import ckan.logic as logic
from ckan.plugins.toolkit import NotAuthorized


@pytest.mark.usefixtures('clean_db', 'with_plugins', 'with_request_context')
@pytest.mark.slow
class TestAuthorization:
    def test_unauthenticated_user_gets_error_page(self, app):
        url = url_for("user.index")
        assert url == "/user/"
        response = app.get(url)
        assert response.status_code == 403
        assert "Zugriff nicht erlaubt" in response

        user = factories.User()
        username = user["name"]
        url = url_for("user.edit", id=username)
        assert url == f"/user/edit/{username}"
        response = app.get(url)
        assert response.status_code == 403
        assert "Zugriff nicht erlaubt" in response

        url = url_for("user.activity", id=username)
        response = app.get(url)
        assert response.status_code == 500

    
    def test_user_actions_not_accessible_by_regular_user(self):
        def assert_not_authorized(action, context, data_dict):
            with pytest.raises(NotAuthorized):
                logic.check_access(action, context, data_dict=data_dict)

        user = factories.User()
        username = user["name"]

        assert_not_authorized("user_list", {"user": username}, {})
        assert_not_authorized("user_update", {"user": username}, {"id": username})
        assert_not_authorized("user_delete", {"user": username}, {"id": username})
        assert_not_authorized("user_create", {"user": username}, {"name": "foo"})
        assert_not_authorized("user_invite", {"user": username}, {})
        assert_not_authorized("user_activity_list", {"user": username}, {"id": username})
    
    def test_user_list_accessible_for_sysadmin(self):
        adminuser = factories.Sysadmin()
        adminusername = adminuser["name"]
        user = factories.User()
        username = user["name"]
        logic.check_access("user_list", {"user": adminusername}, {})
        logic.check_access("user_update", {"user": adminusername}, {"id": username})
        logic.check_access("user_delete", {"user": adminusername}, {"id": username})
        logic.check_access("user_create", {"user": adminusername}, {"name": "foo"})
        logic.check_access("user_invite", {"user": adminusername}, {})