695 lines
26 KiB
Python
695 lines
26 KiB
Python
# Copyright (C) 2010-2024 RhodeCode GmbH
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Affero General Public License, version 3
|
|
# (only), as published by the Free Software Foundation.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
# This program is dual-licensed. If you wish to learn more about the
|
|
# RhodeCode Enterprise Edition, including its added features, Support services,
|
|
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
|
|
|
import os
|
|
|
|
import pytest
|
|
from mock import patch
|
|
|
|
from rhodecode.lib import auth
|
|
from rhodecode.lib.str_utils import safe_bytes
|
|
from rhodecode.lib.hash_utils import md5_safe, sha1
|
|
from rhodecode.model.auth_token import AuthTokenModel
|
|
from rhodecode.model.db import Session, User
|
|
from rhodecode.model.repo import RepoModel
|
|
from rhodecode.model.user import UserModel
|
|
from rhodecode.model.user_group import UserGroupModel
|
|
|
|
|
|
def repickle(obj):
|
|
import pickle
|
|
|
|
return pickle.loads(pickle.dumps(obj, protocol=pickle.HIGHEST_PROTOCOL))
|
|
|
|
|
|
def test_perm_origin_dict():
|
|
pod = auth.PermOriginDict()
|
|
pod["thing"] = "read", "default", 1
|
|
assert pod["thing"] == "read"
|
|
|
|
assert pod.perm_origin_stack == {"thing": [("read", "default", 1)]}
|
|
|
|
pod["thing"] = "write", "admin", 1
|
|
assert pod["thing"] == "write"
|
|
|
|
assert pod.perm_origin_stack == {"thing": [("read", "default", 1), ("write", "admin", 1)]}
|
|
|
|
pod["other"] = "write", "default", 8
|
|
|
|
assert pod.perm_origin_stack == {
|
|
"other": [("write", "default", 8)],
|
|
"thing": [("read", "default", 1), ("write", "admin", 1)],
|
|
}
|
|
|
|
pod["other"] = "none", "override", 8
|
|
|
|
assert pod.perm_origin_stack == {
|
|
"other": [("write", "default", 8), ("none", "override", 8)],
|
|
"thing": [("read", "default", 1), ("write", "admin", 1)],
|
|
}
|
|
|
|
# we can still save regular key
|
|
pod["thing"] = "read"
|
|
with pytest.raises(ValueError):
|
|
pod["thing"] = "read", "missing-3td-key"
|
|
|
|
|
|
def test_perm_origin_dict_serialization():
|
|
pod = auth.PermOriginDict()
|
|
pod["thing"] = "read", "default", 1
|
|
|
|
assert pod["thing"] == "read"
|
|
pod = repickle(pod)
|
|
assert pod["thing"] == "read"
|
|
|
|
assert pod.perm_origin_stack == {"thing": [("read", "default", 1)]}
|
|
|
|
pod["thing"] = "write", "admin", 1
|
|
assert pod["thing"] == "write"
|
|
assert pod["thing"] == "write"
|
|
assert pod.perm_origin_stack == {"thing": [("read", "default", 1), ("write", "admin", 1)]}
|
|
|
|
pod = repickle(pod)
|
|
assert pod["thing"] == "write"
|
|
assert pod["thing"] == "write"
|
|
assert pod.perm_origin_stack == {"thing": [("read", "default", 1), ("write", "admin", 1)]}
|
|
|
|
pod["other"] = "write", "default", 8
|
|
|
|
assert pod.perm_origin_stack == {
|
|
"other": [("write", "default", 8)],
|
|
"thing": [("read", "default", 1), ("write", "admin", 1)],
|
|
}
|
|
pod = repickle(pod)
|
|
assert pod.perm_origin_stack == {
|
|
"other": [("write", "default", 8)],
|
|
"thing": [("read", "default", 1), ("write", "admin", 1)],
|
|
}
|
|
|
|
pod["other"] = "none", "override", 8
|
|
|
|
assert pod.perm_origin_stack == {
|
|
"other": [("write", "default", 8), ("none", "override", 8)],
|
|
"thing": [("read", "default", 1), ("write", "admin", 1)],
|
|
}
|
|
pod = repickle(pod)
|
|
assert pod.perm_origin_stack == {
|
|
"other": [("write", "default", 8), ("none", "override", 8)],
|
|
"thing": [("read", "default", 1), ("write", "admin", 1)],
|
|
}
|
|
|
|
pod["thing"] = "read"
|
|
with pytest.raises(ValueError):
|
|
pod["thing"] = "read", "missing-3td-key"
|
|
|
|
|
|
def test_branch_perm_origin_dict():
|
|
pod = auth.BranchPermOriginDict()
|
|
pod["resource"] = {"*pattern": "read"}, "default"
|
|
assert pod["resource"] == {"*pattern": "read"}
|
|
assert pod.perm_origin_stack == {"resource": {"*pattern": [("read", "default")]}}
|
|
|
|
# 2nd call
|
|
pod["resource"] = {"*pattern": "write"}, "admin"
|
|
assert pod["resource"] == {"*pattern": "write"}
|
|
assert pod.perm_origin_stack == {"resource": {"*pattern": [("read", "default"), ("write", "admin")]}}
|
|
|
|
|
|
def test_branch_perm_origin_dict_serialization():
|
|
pod = auth.BranchPermOriginDict()
|
|
pod["resource"] = {"*pattern": "read"}, "default"
|
|
assert pod["resource"] == {"*pattern": "read"}
|
|
assert pod.perm_origin_stack == {"resource": {"*pattern": [("read", "default")]}}
|
|
|
|
pod = repickle(pod)
|
|
assert pod["resource"] == {"*pattern": "read"}
|
|
assert pod.perm_origin_stack == {"resource": {"*pattern": [("read", "default")]}}
|
|
|
|
# 2nd call
|
|
pod["resource"] = {"*pattern": "write"}, "admin"
|
|
assert pod["resource"] == {"*pattern": "write"}
|
|
assert pod.perm_origin_stack == {"resource": {"*pattern": [("read", "default"), ("write", "admin")]}}
|
|
|
|
pod = repickle(pod)
|
|
assert pod["resource"] == {"*pattern": "write"}
|
|
assert pod.perm_origin_stack == {"resource": {"*pattern": [("read", "default"), ("write", "admin")]}}
|
|
|
|
|
|
def test_cached_perms_data(user_regular, backend_random):
|
|
permissions = get_permissions(user_regular)
|
|
repo_name = backend_random.repo.repo_name
|
|
expected_global_permissions = {"repository.read", "group.read", "usergroup.read"}
|
|
assert expected_global_permissions.issubset(permissions["global"])
|
|
assert permissions["repositories"][repo_name] == "repository.read"
|
|
|
|
|
|
def test_cached_perms_data_with_admin_user(user_regular, backend_random):
|
|
permissions = get_permissions(user_regular, user_is_admin=True)
|
|
repo_name = backend_random.repo.repo_name
|
|
assert "hg.admin" in permissions["global"]
|
|
assert permissions["repositories"][repo_name] == "repository.admin"
|
|
|
|
|
|
def test_cached_perms_data_with_admin_user_extended_calculation(user_regular, backend_random):
|
|
permissions = get_permissions(user_regular, user_is_admin=True, calculate_super_admin=True)
|
|
repo_name = backend_random.repo.repo_name
|
|
assert "hg.admin" in permissions["global"]
|
|
assert permissions["repositories"][repo_name] == "repository.admin"
|
|
|
|
|
|
def test_cached_perms_data_user_group_global_permissions(user_util):
|
|
user, user_group = user_util.create_user_with_group()
|
|
user_group.inherit_default_permissions = False
|
|
|
|
granted_permission = "repository.write"
|
|
UserGroupModel().grant_perm(user_group, granted_permission)
|
|
Session().commit()
|
|
|
|
permissions = get_permissions(user)
|
|
assert granted_permission in permissions["global"]
|
|
|
|
|
|
@pytest.mark.xfail(reason="Not implemented, see TODO note")
|
|
def test_cached_perms_data_user_group_global_permissions_(user_util):
|
|
user, user_group = user_util.create_user_with_group()
|
|
|
|
granted_permission = "repository.write"
|
|
UserGroupModel().grant_perm(user_group, granted_permission)
|
|
Session().commit()
|
|
|
|
permissions = get_permissions(user)
|
|
assert granted_permission in permissions["global"]
|
|
|
|
|
|
def test_cached_perms_data_user_global_permissions(user_util):
|
|
user = user_util.create_user()
|
|
UserModel().grant_perm(user, "repository.none")
|
|
Session().commit()
|
|
|
|
permissions = get_permissions(user, user_inherit_default_permissions=True)
|
|
assert "repository.read" in permissions["global"]
|
|
|
|
|
|
def test_cached_perms_data_repository_permissions_on_private_repository(backend_random, user_util):
|
|
user, user_group = user_util.create_user_with_group()
|
|
|
|
repo = backend_random.create_repo()
|
|
repo.private = True
|
|
|
|
granted_permission = "repository.write"
|
|
RepoModel().grant_user_group_permission(repo, user_group.users_group_name, granted_permission)
|
|
Session().commit()
|
|
|
|
permissions = get_permissions(user)
|
|
assert permissions["repositories"][repo.repo_name] == granted_permission
|
|
|
|
|
|
def test_cached_perms_data_repository_permissions_for_owner(backend_random, user_util):
|
|
user = user_util.create_user()
|
|
|
|
repo = backend_random.create_repo()
|
|
repo.user_id = user.user_id
|
|
|
|
permissions = get_permissions(user)
|
|
assert permissions["repositories"][repo.repo_name] == "repository.admin"
|
|
|
|
# TODO: johbo: Make cleanup in UserUtility smarter, then remove this hack
|
|
repo.user_id = User.get_default_user_id()
|
|
|
|
|
|
def test_cached_perms_data_repository_permissions_not_inheriting_defaults(backend_random, user_util):
|
|
user = user_util.create_user()
|
|
repo = backend_random.create_repo()
|
|
|
|
# Don't inherit default object permissions
|
|
UserModel().grant_perm(user, "hg.inherit_default_perms.false")
|
|
Session().commit()
|
|
|
|
permissions = get_permissions(user)
|
|
assert permissions["repositories"][repo.repo_name] == "repository.none"
|
|
|
|
|
|
def test_cached_perms_data_default_permissions_on_repository_group(user_util):
|
|
# Have a repository group with default permissions set
|
|
repo_group = user_util.create_repo_group()
|
|
default_user = User.get_default_user()
|
|
user_util.grant_user_permission_to_repo_group(repo_group, default_user, "repository.write")
|
|
user = user_util.create_user()
|
|
|
|
permissions = get_permissions(user)
|
|
assert permissions["repositories_groups"][repo_group.group_name] == "repository.write"
|
|
|
|
|
|
def test_cached_perms_data_default_permissions_on_repository_group_owner(user_util):
|
|
# Have a repository group
|
|
repo_group = user_util.create_repo_group()
|
|
default_user = User.get_default_user()
|
|
|
|
# Add a permission for the default user to hit the code path
|
|
user_util.grant_user_permission_to_repo_group(repo_group, default_user, "repository.write")
|
|
|
|
# Have an owner of the group
|
|
user = user_util.create_user()
|
|
repo_group.user_id = user.user_id
|
|
|
|
permissions = get_permissions(user)
|
|
assert permissions["repositories_groups"][repo_group.group_name] == "group.admin"
|
|
|
|
|
|
def test_cached_perms_data_default_permissions_on_repository_group_no_inherit(user_util):
|
|
# Have a repository group
|
|
repo_group = user_util.create_repo_group()
|
|
default_user = User.get_default_user()
|
|
|
|
# Add a permission for the default user to hit the code path
|
|
user_util.grant_user_permission_to_repo_group(repo_group, default_user, "repository.write")
|
|
|
|
# Don't inherit default object permissions
|
|
user = user_util.create_user()
|
|
UserModel().grant_perm(user, "hg.inherit_default_perms.false")
|
|
Session().commit()
|
|
|
|
permissions = get_permissions(user)
|
|
assert permissions["repositories_groups"][repo_group.group_name] == "group.none"
|
|
|
|
|
|
def test_cached_perms_data_repository_permissions_from_user_group(user_util, backend_random):
|
|
user, user_group = user_util.create_user_with_group()
|
|
|
|
# Needs a second user group to make sure that we select the right
|
|
# permissions.
|
|
user_group2 = user_util.create_user_group()
|
|
UserGroupModel().add_user_to_group(user_group2, user)
|
|
|
|
repo = backend_random.create_repo()
|
|
|
|
RepoModel().grant_user_group_permission(repo, user_group.users_group_name, "repository.read")
|
|
RepoModel().grant_user_group_permission(repo, user_group2.users_group_name, "repository.write")
|
|
Session().commit()
|
|
|
|
permissions = get_permissions(user)
|
|
assert permissions["repositories"][repo.repo_name] == "repository.write"
|
|
|
|
|
|
def test_cached_perms_data_repository_permissions_from_user_group_owner(user_util, backend_random):
|
|
user, user_group = user_util.create_user_with_group()
|
|
|
|
repo = backend_random.create_repo()
|
|
repo.user_id = user.user_id
|
|
|
|
RepoModel().grant_user_group_permission(repo, user_group.users_group_name, "repository.write")
|
|
Session().commit()
|
|
|
|
permissions = get_permissions(user)
|
|
assert permissions["repositories"][repo.repo_name] == "repository.admin"
|
|
|
|
|
|
def test_cached_perms_data_user_repository_permissions(user_util, backend_random):
|
|
user = user_util.create_user()
|
|
repo = backend_random.create_repo()
|
|
granted_permission = "repository.write"
|
|
RepoModel().grant_user_permission(repo, user, granted_permission)
|
|
Session().commit()
|
|
|
|
permissions = get_permissions(user)
|
|
assert permissions["repositories"][repo.repo_name] == granted_permission
|
|
|
|
|
|
def test_cached_perms_data_user_repository_permissions_explicit(user_util, backend_random):
|
|
user = user_util.create_user()
|
|
repo = backend_random.create_repo()
|
|
granted_permission = "repository.none"
|
|
RepoModel().grant_user_permission(repo, user, granted_permission)
|
|
Session().commit()
|
|
|
|
permissions = get_permissions(user, explicit=True)
|
|
assert permissions["repositories"][repo.repo_name] == granted_permission
|
|
|
|
|
|
def test_cached_perms_data_user_repository_permissions_owner(user_util, backend_random):
|
|
user = user_util.create_user()
|
|
repo = backend_random.create_repo()
|
|
repo.user_id = user.user_id
|
|
RepoModel().grant_user_permission(repo, user, "repository.write")
|
|
Session().commit()
|
|
|
|
permissions = get_permissions(user)
|
|
assert permissions["repositories"][repo.repo_name] == "repository.admin"
|
|
|
|
|
|
def test_cached_perms_data_repository_groups_permissions_inherited(user_util, backend_random):
|
|
user, user_group = user_util.create_user_with_group()
|
|
|
|
# Needs a second group to hit the last condition
|
|
user_group2 = user_util.create_user_group()
|
|
UserGroupModel().add_user_to_group(user_group2, user)
|
|
|
|
repo_group = user_util.create_repo_group()
|
|
|
|
user_util.grant_user_group_permission_to_repo_group(repo_group, user_group, "group.read")
|
|
user_util.grant_user_group_permission_to_repo_group(repo_group, user_group2, "group.write")
|
|
|
|
permissions = get_permissions(user)
|
|
assert permissions["repositories_groups"][repo_group.group_name] == "group.write"
|
|
|
|
|
|
def test_cached_perms_data_repository_groups_permissions_inherited_owner(user_util, backend_random):
|
|
user, user_group = user_util.create_user_with_group()
|
|
repo_group = user_util.create_repo_group()
|
|
repo_group.user_id = user.user_id
|
|
|
|
granted_permission = "group.write"
|
|
user_util.grant_user_group_permission_to_repo_group(repo_group, user_group, granted_permission)
|
|
|
|
permissions = get_permissions(user)
|
|
assert permissions["repositories_groups"][repo_group.group_name] == "group.admin"
|
|
|
|
|
|
def test_cached_perms_data_repository_groups_permissions(user_util, backend_random):
|
|
user = user_util.create_user()
|
|
|
|
repo_group = user_util.create_repo_group()
|
|
|
|
granted_permission = "group.write"
|
|
user_util.grant_user_permission_to_repo_group(repo_group, user, granted_permission)
|
|
|
|
permissions = get_permissions(user)
|
|
assert permissions["repositories_groups"][repo_group.group_name] == "group.write"
|
|
|
|
|
|
def test_cached_perms_data_repository_groups_permissions_explicit(user_util, backend_random):
|
|
user = user_util.create_user()
|
|
|
|
repo_group = user_util.create_repo_group()
|
|
|
|
granted_permission = "group.none"
|
|
user_util.grant_user_permission_to_repo_group(repo_group, user, granted_permission)
|
|
|
|
permissions = get_permissions(user, explicit=True)
|
|
assert permissions["repositories_groups"][repo_group.group_name] == "group.none"
|
|
|
|
|
|
def test_cached_perms_data_repository_groups_permissions_owner(user_util, backend_random):
|
|
user = user_util.create_user()
|
|
|
|
repo_group = user_util.create_repo_group()
|
|
repo_group.user_id = user.user_id
|
|
|
|
granted_permission = "group.write"
|
|
user_util.grant_user_permission_to_repo_group(repo_group, user, granted_permission)
|
|
|
|
permissions = get_permissions(user)
|
|
assert permissions["repositories_groups"][repo_group.group_name] == "group.admin"
|
|
|
|
|
|
def test_cached_perms_data_user_group_permissions_inherited(user_util, backend_random):
|
|
user, user_group = user_util.create_user_with_group()
|
|
user_group2 = user_util.create_user_group()
|
|
UserGroupModel().add_user_to_group(user_group2, user)
|
|
|
|
target_user_group = user_util.create_user_group()
|
|
|
|
user_util.grant_user_group_permission_to_user_group(target_user_group, user_group, "usergroup.read")
|
|
user_util.grant_user_group_permission_to_user_group(target_user_group, user_group2, "usergroup.write")
|
|
|
|
permissions = get_permissions(user)
|
|
assert permissions["user_groups"][target_user_group.users_group_name] == "usergroup.write"
|
|
|
|
|
|
def test_cached_perms_data_user_group_permissions(user_util, backend_random):
|
|
user = user_util.create_user()
|
|
user_group = user_util.create_user_group()
|
|
UserGroupModel().grant_user_permission(user_group, user, "usergroup.write")
|
|
Session().commit()
|
|
|
|
permissions = get_permissions(user)
|
|
assert permissions["user_groups"][user_group.users_group_name] == "usergroup.write"
|
|
|
|
|
|
def test_cached_perms_data_user_group_permissions_explicit(user_util, backend_random):
|
|
user = user_util.create_user()
|
|
user_group = user_util.create_user_group()
|
|
UserGroupModel().grant_user_permission(user_group, user, "usergroup.none")
|
|
Session().commit()
|
|
|
|
permissions = get_permissions(user, explicit=True)
|
|
assert permissions["user_groups"][user_group.users_group_name] == "usergroup.none"
|
|
|
|
|
|
def test_cached_perms_data_user_group_permissions_not_inheriting_defaults(user_util, backend_random):
|
|
user = user_util.create_user()
|
|
user_group = user_util.create_user_group()
|
|
|
|
# Don't inherit default object permissions
|
|
UserModel().grant_perm(user, "hg.inherit_default_perms.false")
|
|
Session().commit()
|
|
|
|
permissions = get_permissions(user)
|
|
assert permissions["user_groups"][user_group.users_group_name] == "usergroup.none"
|
|
|
|
|
|
def test_permission_calculator_admin_permissions(user_util, backend_random):
|
|
user = user_util.create_user()
|
|
user_group = user_util.create_user_group()
|
|
repo = backend_random.repo
|
|
repo_group = user_util.create_repo_group()
|
|
|
|
calculator = auth.PermissionCalculator(user.user_id, {}, False, False, True, "higherwin")
|
|
permissions = calculator._calculate_super_admin_permissions()
|
|
|
|
assert permissions["repositories_groups"][repo_group.group_name] == "group.admin"
|
|
assert permissions["user_groups"][user_group.users_group_name] == "usergroup.admin"
|
|
assert permissions["repositories"][repo.repo_name] == "repository.admin"
|
|
assert "hg.admin" in permissions["global"]
|
|
|
|
|
|
def test_permission_calculator_repository_permissions_robustness_from_group(user_util, backend_random):
|
|
user, user_group = user_util.create_user_with_group()
|
|
|
|
RepoModel().grant_user_group_permission(backend_random.repo, user_group.users_group_name, "repository.write")
|
|
|
|
calculator = auth.PermissionCalculator(user.user_id, {}, False, False, False, "higherwin")
|
|
calculator._calculate_repository_permissions()
|
|
|
|
|
|
def test_permission_calculator_repository_permissions_robustness_from_user(user_util, backend_random):
|
|
user = user_util.create_user()
|
|
|
|
RepoModel().grant_user_permission(backend_random.repo, user, "repository.write")
|
|
Session().commit()
|
|
|
|
calculator = auth.PermissionCalculator(user.user_id, {}, False, False, False, "higherwin")
|
|
calculator._calculate_repository_permissions()
|
|
|
|
|
|
def test_permission_calculator_repo_group_permissions_robustness_from_group(user_util, backend_random):
|
|
user, user_group = user_util.create_user_with_group()
|
|
repo_group = user_util.create_repo_group()
|
|
|
|
user_util.grant_user_group_permission_to_repo_group(repo_group, user_group, "group.write")
|
|
|
|
calculator = auth.PermissionCalculator(user.user_id, {}, False, False, False, "higherwin")
|
|
calculator._calculate_repository_group_permissions()
|
|
|
|
|
|
def test_permission_calculator_repo_group_permissions_robustness_from_user(user_util, backend_random):
|
|
user = user_util.create_user()
|
|
repo_group = user_util.create_repo_group()
|
|
|
|
user_util.grant_user_permission_to_repo_group(repo_group, user, "group.write")
|
|
|
|
calculator = auth.PermissionCalculator(user.user_id, {}, False, False, False, "higherwin")
|
|
calculator._calculate_repository_group_permissions()
|
|
|
|
|
|
def test_permission_calculator_user_group_permissions_robustness_from_group(user_util, backend_random):
|
|
user, user_group = user_util.create_user_with_group()
|
|
target_user_group = user_util.create_user_group()
|
|
|
|
user_util.grant_user_group_permission_to_user_group(target_user_group, user_group, "usergroup.write")
|
|
|
|
calculator = auth.PermissionCalculator(user.user_id, {}, False, False, False, "higherwin")
|
|
calculator._calculate_user_group_permissions()
|
|
|
|
|
|
def test_permission_calculator_user_group_permissions_robustness_from_user(user_util, backend_random):
|
|
user = user_util.create_user()
|
|
target_user_group = user_util.create_user_group()
|
|
|
|
user_util.grant_user_permission_to_user_group(target_user_group, user, "usergroup.write")
|
|
|
|
calculator = auth.PermissionCalculator(user.user_id, {}, False, False, False, "higherwin")
|
|
calculator._calculate_user_group_permissions()
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"algo, new_permission, old_permission, expected",
|
|
[
|
|
("higherwin", "repository.none", "repository.none", "repository.none"),
|
|
("higherwin", "repository.read", "repository.none", "repository.read"),
|
|
("lowerwin", "repository.write", "repository.write", "repository.write"),
|
|
("lowerwin", "repository.read", "repository.write", "repository.read"),
|
|
],
|
|
)
|
|
def test_permission_calculator_choose_permission(user_regular, algo, new_permission, old_permission, expected):
|
|
calculator = auth.PermissionCalculator(user_regular.user_id, {}, False, False, False, algo)
|
|
result = calculator._choose_permission(new_permission, old_permission)
|
|
assert result == expected
|
|
|
|
|
|
def test_permission_calculator_choose_permission_raises_on_wrong_algo(user_regular):
|
|
calculator = auth.PermissionCalculator(user_regular.user_id, {}, False, False, False, "invalid")
|
|
result = calculator._choose_permission("repository.read", "repository.read")
|
|
# TODO: johbo: This documents the existing behavior. Think of an
|
|
# improvement.
|
|
assert result is None
|
|
|
|
|
|
def test_auth_user_get_cookie_store_for_normal_user(user_util):
|
|
user = user_util.create_user()
|
|
auth_user = auth.AuthUser(user_id=user.user_id)
|
|
expected_data = {
|
|
"username": user.username,
|
|
"user_id": user.user_id,
|
|
"password": md5_safe(user.password),
|
|
"is_authenticated": False,
|
|
}
|
|
assert auth_user.get_cookie_store() == expected_data
|
|
|
|
|
|
def test_auth_user_get_cookie_store_for_default_user(baseapp):
|
|
# NOTE: Importing baseapp is important—if this test runs in isolation,
|
|
# the User class may not be bound to the Session, resulting in an error.
|
|
# Importing baseapp ensures the session is explicitly bound for this test.
|
|
# When tests are run in batch, this binding often happens implicitly as a side effect of other tests or fixtures.
|
|
|
|
default_user = User.get_default_user()
|
|
auth_user = auth.AuthUser()
|
|
expected_data = {
|
|
"username": User.DEFAULT_USER,
|
|
"user_id": default_user.user_id,
|
|
"password": md5_safe(default_user.password),
|
|
"is_authenticated": True,
|
|
}
|
|
assert auth_user.get_cookie_store() == expected_data
|
|
|
|
|
|
def test_auth_not_allowed_for_ghost_user(baseapp):
|
|
# NOTE: Importing baseapp is important—if this test runs in isolation,
|
|
# the User class may not be bound to the Session, resulting in an error.
|
|
# Importing baseapp ensures the session is explicitly bound for this test.
|
|
# When tests are run in batch, this binding often happens implicitly as a side effect of other tests or fixtures.
|
|
ghost = User.get_ghost_user()
|
|
|
|
try:
|
|
# Under normal conditions, the ghost user should not have a password and should remain inactive.
|
|
ghost.password = "<PASSWORD>"
|
|
ghost.active = True
|
|
Session().commit()
|
|
|
|
auth_user = auth.AuthUser(user_id=ghost.user_id)
|
|
expected_data = {
|
|
"username": User.GHOST_USER,
|
|
"user_id": ghost.user_id,
|
|
"password": md5_safe(ghost.password),
|
|
"is_authenticated": False,
|
|
}
|
|
assert auth_user.get_cookie_store() == expected_data
|
|
finally:
|
|
# Important: Clean up after this test since the ghost user is unique in the system.
|
|
# Not cleaning up could affect other tests or parts of the application.
|
|
ghost.password = None
|
|
ghost.active = False
|
|
Session().commit()
|
|
|
|
|
|
def get_permissions(user, **kwargs):
|
|
"""
|
|
Utility filling in useful defaults into the call to `_cached_perms_data`.
|
|
|
|
Fill in `**kwargs` if specific values are needed for a test.
|
|
"""
|
|
call_args = {
|
|
"user_id": user.user_id,
|
|
"scope": {},
|
|
"user_is_admin": False,
|
|
"user_inherit_default_permissions": False,
|
|
"explicit": False,
|
|
"algo": "higherwin",
|
|
"calculate_super_admin": False,
|
|
}
|
|
call_args.update(kwargs)
|
|
permissions = auth._cached_perms_data(**call_args)
|
|
return permissions
|
|
|
|
|
|
class TestGenerateAuthToken(object):
|
|
def test_salt_is_used_when_specified(self):
|
|
salt = b"abcde"
|
|
user_name = "test_user"
|
|
result = auth.generate_auth_token(user_name, salt)
|
|
expected_result = sha1(safe_bytes(user_name) + salt)
|
|
assert result == expected_result
|
|
|
|
def test_salt_is_geneated_when_not_specified(self):
|
|
user_name = "test_user"
|
|
random_salt = os.urandom(16)
|
|
with patch.object(auth, "os") as os_mock:
|
|
os_mock.urandom.return_value = random_salt
|
|
result = auth.generate_auth_token(user_name)
|
|
|
|
expected_result = sha1(safe_bytes(user_name) + random_salt)
|
|
assert result == expected_result
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"test_token, test_roles, auth_result, expected_tokens",
|
|
[
|
|
("", None, False, []),
|
|
("wrongtoken", None, False, []),
|
|
(
|
|
"abracadabra_vcs",
|
|
[AuthTokenModel.cls.ROLE_API],
|
|
False,
|
|
[("abracadabra_api", AuthTokenModel.cls.ROLE_API, -1)],
|
|
),
|
|
(
|
|
"abracadabra_api",
|
|
[AuthTokenModel.cls.ROLE_API],
|
|
True,
|
|
[("abracadabra_api", AuthTokenModel.cls.ROLE_API, -1)],
|
|
),
|
|
(
|
|
"abracadabra_api",
|
|
[AuthTokenModel.cls.ROLE_API],
|
|
True,
|
|
[
|
|
("abracadabra_api", AuthTokenModel.cls.ROLE_API, -1),
|
|
("abracadabra_http", AuthTokenModel.cls.ROLE_HTTP, -1),
|
|
],
|
|
),
|
|
],
|
|
)
|
|
def test_auth_by_token(test_token, test_roles, auth_result, expected_tokens, user_util):
|
|
user = user_util.create_user()
|
|
user_id = user.user_id
|
|
for token, role, expires in expected_tokens:
|
|
new_token = AuthTokenModel().create(user_id, "test-token", expires, role)
|
|
new_token.api_key = token # inject known name for testing...
|
|
|
|
assert auth_result == user.authenticate_by_token(test_token, roles=test_roles)
|