Files
superset2/tests/integration_tests/security/password_complexity_tests.py

71 lines
3.1 KiB
Python

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""Integration tests asserting the password-complexity policy is wired into
Flask-AppBuilder's User REST API (not just the validator function itself)."""
from superset import db, security_manager
from tests.integration_tests.base_tests import SupersetTestCase
from tests.integration_tests.constants import ADMIN_USERNAME
USERS_API_URI = "/api/v1/security/users/"
class TestPasswordComplexityUserApi(SupersetTestCase):
"""Exercise the real FAB ``/api/v1/security/users/`` path so that a future
Flask-AppBuilder bump that drops enforcement fails these tests."""
def _user_payload(self, password: str) -> dict[str, object]:
"""Build a valid user-creation payload with the given password."""
gamma_role = security_manager.find_role("Gamma")
return {
"active": True,
"email": "pw_complexity_test@example.com",
"first_name": "Password",
"last_name": "Complexity",
"username": "pw_complexity_test_user",
"roles": [gamma_role.id],
"password": password,
}
def test_create_user_rejects_short_password(self):
"""A too-short password is rejected by the User REST API with a 400."""
self.login(ADMIN_USERNAME)
rv = self.client.post(USERS_API_URI, json=self._user_payload("Ab1!"))
assert rv.status_code == 400
assert b"at least" in rv.data
assert security_manager.find_user(username="pw_complexity_test_user") is None
def test_create_user_rejects_common_password(self):
"""A blocklisted common password is rejected by the User REST API."""
self.login(ADMIN_USERNAME)
rv = self.client.post(USERS_API_URI, json=self._user_payload("password123"))
assert rv.status_code == 400
assert b"too common" in rv.data
assert security_manager.find_user(username="pw_complexity_test_user") is None
def test_create_user_accepts_compliant_password(self):
"""A password satisfying the policy is accepted by the User REST API."""
self.login(ADMIN_USERNAME)
rv = self.client.post(
USERS_API_URI, json=self._user_payload("correct-horse-battery")
)
assert rv.status_code == 201
user = security_manager.find_user(username="pw_complexity_test_user")
assert user is not None
db.session.delete(user)
db.session.commit()