This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch 5.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 5f1a5a1f9848d72f083330282541e86df7ffaae7
Author: Beto Dealmeida <[email protected]>
AuthorDate: Tue Mar 4 13:33:53 2025 -0500

    fix: skip DB filter when doing OAuth2 (#32486)
    
    (cherry picked from commit 813e79fa9fcba502fc55d21a84c0628e1bb42493)
---
 superset/databases/api.py              |  2 +-
 tests/unit_tests/databases/api_test.py | 70 ++++++++++++++++++++++++++++++++++
 2 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/superset/databases/api.py b/superset/databases/api.py
index f9c1dfd122..f47293e891 100644
--- a/superset/databases/api.py
+++ b/superset/databases/api.py
@@ -1390,7 +1390,7 @@ class DatabaseRestApi(BaseSupersetModelRestApi):
         state = decode_oauth2_state(parameters["state"])
 
         # exchange code for access/refresh tokens
-        database = DatabaseDAO.find_by_id(state["database_id"])
+        database = DatabaseDAO.find_by_id(state["database_id"], 
skip_base_filter=True)
         if database is None:
             return self.response_404()
 
diff --git a/tests/unit_tests/databases/api_test.py 
b/tests/unit_tests/databases/api_test.py
index 63d61ce82a..4656ea9b86 100644
--- a/tests/unit_tests/databases/api_test.py
+++ b/tests/unit_tests/databases/api_test.py
@@ -728,6 +728,76 @@ def test_oauth2_happy_path(
     assert token.refresh_token == "ZZZ"  # noqa: S105
 
 
+def test_oauth2_permissions(
+    mocker: MockerFixture,
+    session: Session,
+    client: Any,
+) -> None:
+    """
+    Test the OAuth2 endpoint works for users without DB permissions.
+
+    Anyone should be able to authenticate with OAuth2, even if they don't have
+    permissions to read the database (which is needed to get the OAuth2 
config).
+    """
+    from superset.databases.api import DatabaseRestApi
+    from superset.models.core import Database, DatabaseUserOAuth2Tokens
+
+    DatabaseRestApi.datamodel.session = session
+
+    # create table for databases
+    Database.metadata.create_all(session.get_bind())  # pylint: 
disable=no-member
+    db.session.add(
+        Database(
+            database_name="my_db",
+            sqlalchemy_uri="sqlite://",
+            uuid=UUID("7c1b7880-a59d-47cd-8bf1-f1eb8d2863cb"),
+        )
+    )
+    db.session.commit()
+
+    mocker.patch.object(
+        SqliteEngineSpec,
+        "get_oauth2_config",
+        return_value={"id": "one", "secret": "two"},
+    )
+    get_oauth2_token = mocker.patch.object(SqliteEngineSpec, 
"get_oauth2_token")
+    get_oauth2_token.return_value = {
+        "access_token": "YYY",
+        "expires_in": 3600,
+        "refresh_token": "ZZZ",
+    }
+
+    state = {
+        "user_id": 1,
+        "database_id": 1,
+        "tab_id": 42,
+    }
+    decode_oauth2_state = 
mocker.patch("superset.databases.api.decode_oauth2_state")
+    decode_oauth2_state.return_value = state
+
+    mocker.patch("superset.databases.api.render_template", return_value="OK")
+
+    with freeze_time("2024-01-01T00:00:00Z"):
+        response = client.get(
+            "/api/v1/database/oauth2/",
+            query_string={
+                "state": "some%2Estate",
+                "code": "XXX",
+            },
+        )
+
+    assert response.status_code == 200
+    decode_oauth2_state.assert_called_with("some%2Estate")
+    get_oauth2_token.assert_called_with({"id": "one", "secret": "two"}, "XXX")
+
+    token = db.session.query(DatabaseUserOAuth2Tokens).one()
+    assert token.user_id == 1
+    assert token.database_id == 1
+    assert token.access_token == "YYY"  # noqa: S105
+    assert token.access_token_expiration == datetime(2024, 1, 1, 1, 0)
+    assert token.refresh_token == "ZZZ"  # noqa: S105
+
+
 def test_oauth2_multiple_tokens(
     mocker: MockerFixture,
     session: Session,

Reply via email to