mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
1151 lines
38 KiB
Python
1151 lines
38 KiB
Python
import socket
|
|
import requests
|
|
import pytest
|
|
import string
|
|
import os
|
|
import json
|
|
import shutil
|
|
|
|
from .conftest import message, raiseYunohostError, get_test_apps_dir
|
|
|
|
from yunohost.app import (
|
|
app_install,
|
|
app_upgrade,
|
|
app_remove,
|
|
app_change_url,
|
|
app_map,
|
|
_installed_apps,
|
|
APPS_SETTING_PATH,
|
|
_set_app_settings,
|
|
_get_app_settings,
|
|
)
|
|
from yunohost.user import (
|
|
user_list,
|
|
user_create,
|
|
user_delete,
|
|
user_group_list,
|
|
user_group_delete,
|
|
)
|
|
from yunohost.permission import (
|
|
user_permission_update,
|
|
user_permission_list,
|
|
user_permission_reset,
|
|
permission_create,
|
|
permission_delete,
|
|
permission_url,
|
|
)
|
|
from yunohost.domain import _get_maindomain, domain_add, domain_remove, domain_list
|
|
|
|
# Get main domain
|
|
maindomain = ""
|
|
other_domains = []
|
|
dummy_password = "test123Ynh"
|
|
|
|
# Dirty patch of DNS resolution. Force the DNS to 127.0.0.1 address even if dnsmasq have the public address.
|
|
# Mainly used for 'can_access_webpage' function
|
|
|
|
prv_getaddrinfo = socket.getaddrinfo
|
|
|
|
|
|
def _permission_create_with_dummy_app(
|
|
permission,
|
|
allowed=None,
|
|
url=None,
|
|
additional_urls=None,
|
|
auth_header=True,
|
|
label=None,
|
|
show_tile=False,
|
|
protected=True,
|
|
sync_perm=True,
|
|
domain=None,
|
|
path=None,
|
|
):
|
|
app = permission.split(".")[0]
|
|
if app not in _installed_apps():
|
|
app_setting_path = os.path.join(APPS_SETTING_PATH, app)
|
|
if not os.path.exists(app_setting_path):
|
|
os.makedirs(app_setting_path)
|
|
settings = {"id": app, "dummy_permission_app": True}
|
|
if domain:
|
|
settings["domain"] = domain
|
|
if path:
|
|
settings["path"] = path
|
|
_set_app_settings(app, settings)
|
|
|
|
with open(os.path.join(APPS_SETTING_PATH, app, "manifest.json"), "w") as f:
|
|
json.dump(
|
|
{
|
|
"name": app,
|
|
"id": app,
|
|
"description": {"en": "Dummy app to test permissions"},
|
|
"arguments": {"install": []},
|
|
},
|
|
f,
|
|
)
|
|
permission_create(
|
|
permission=permission,
|
|
allowed=allowed,
|
|
url=url,
|
|
additional_urls=additional_urls,
|
|
auth_header=auth_header,
|
|
label=label,
|
|
show_tile=show_tile,
|
|
protected=protected,
|
|
sync_perm=sync_perm,
|
|
)
|
|
|
|
|
|
def _clear_dummy_app_settings():
|
|
# Clean dummy app settings
|
|
for app in _installed_apps():
|
|
if _get_app_settings(app).get("dummy_permission_app", False):
|
|
app_setting_path = os.path.join(APPS_SETTING_PATH, app)
|
|
if os.path.exists(app_setting_path):
|
|
shutil.rmtree(app_setting_path)
|
|
|
|
|
|
def clean_user_groups_permission():
|
|
for u in user_list()["users"]:
|
|
user_delete(u)
|
|
|
|
for g in user_group_list()["groups"]:
|
|
if g not in ["all_users", "visitors", "admins"]:
|
|
user_group_delete(g)
|
|
|
|
for p in user_permission_list()["permissions"]:
|
|
if any(
|
|
p.startswith(name)
|
|
for name in ["wiki", "blog", "site", "web", "permissions_app"]
|
|
):
|
|
permission_delete(p, force=True, sync_perm=False)
|
|
socket.getaddrinfo = prv_getaddrinfo
|
|
|
|
|
|
def setup_function(function):
|
|
clean_user_groups_permission()
|
|
|
|
global maindomain
|
|
global other_domains
|
|
maindomain = _get_maindomain()
|
|
|
|
markers = {
|
|
m.name: {"args": m.args, "kwargs": m.kwargs}
|
|
for m in function.__dict__.get("pytestmark", [])
|
|
}
|
|
|
|
if "other_domains" in markers:
|
|
other_domains = [
|
|
"domain_%s.dev" % string.ascii_lowercase[number]
|
|
for number in range(markers["other_domains"]["kwargs"]["number"])
|
|
]
|
|
for domain in other_domains:
|
|
if domain not in domain_list()["domains"]:
|
|
domain_add(domain)
|
|
|
|
# Dirty patch of DNS resolution. Force the DNS to 127.0.0.1 address even if dnsmasq have the public address.
|
|
# Mainly used for 'can_access_webpage' function
|
|
dns_cache = {(maindomain, 443, 0, 1): [(2, 1, 6, "", ("127.0.0.1", 443))]}
|
|
for domain in other_domains:
|
|
dns_cache[(domain, 443, 0, 1)] = [(2, 1, 6, "", ("127.0.0.1", 443))]
|
|
|
|
def new_getaddrinfo(*args):
|
|
try:
|
|
return dns_cache[args]
|
|
except KeyError:
|
|
res = prv_getaddrinfo(*args)
|
|
dns_cache[args] = res
|
|
return res
|
|
|
|
socket.getaddrinfo = new_getaddrinfo
|
|
|
|
user_create("alice", maindomain, dummy_password, fullname="Alice White", admin=True)
|
|
user_create("bob", maindomain, dummy_password, fullname="Bob Snow")
|
|
_permission_create_with_dummy_app(
|
|
permission="wiki.main",
|
|
url="/",
|
|
additional_urls=["/whatever", "/idontnow"],
|
|
auth_header=False,
|
|
label="Wiki",
|
|
show_tile=True,
|
|
allowed=["all_users"],
|
|
protected=False,
|
|
sync_perm=False,
|
|
domain=maindomain,
|
|
path="/wiki",
|
|
)
|
|
_permission_create_with_dummy_app(
|
|
permission="blog.main",
|
|
url="/",
|
|
auth_header=True,
|
|
show_tile=False,
|
|
protected=False,
|
|
sync_perm=False,
|
|
allowed=["alice"],
|
|
domain=maindomain,
|
|
path="/blog",
|
|
)
|
|
_permission_create_with_dummy_app(
|
|
permission="blog.api", allowed=["visitors"], protected=True, sync_perm=True
|
|
)
|
|
|
|
|
|
def teardown_function(function):
|
|
clean_user_groups_permission()
|
|
global other_domains
|
|
for domain in other_domains:
|
|
domain_remove(domain)
|
|
other_domains = []
|
|
|
|
_clear_dummy_app_settings()
|
|
|
|
try:
|
|
app_remove("permissions_app")
|
|
except Exception:
|
|
pass
|
|
try:
|
|
app_remove("legacy_app")
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
def teardown_module(module):
|
|
global other_domains
|
|
for domain in other_domains:
|
|
domain_remove(domain)
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def check_LDAP_db_integrity_call():
|
|
check_LDAP_db_integrity()
|
|
yield
|
|
check_LDAP_db_integrity()
|
|
|
|
|
|
def check_LDAP_db_integrity():
|
|
# Here we check that all attributes in all object are sychronized.
|
|
# Here is the list of attributes per object:
|
|
# user : memberOf, permission
|
|
# group : member, permission
|
|
# permission : groupPermission, inheritPermission
|
|
#
|
|
# The idea is to check that all attributes on all sides of object are sychronized.
|
|
# One part should be done automatically by the "memberOf" overlay of LDAP.
|
|
# The other part is done by the the "permission_sync_to_user" function of the permission module
|
|
|
|
from yunohost.utils.ldap import _get_ldap_interface, _ldap_path_extract
|
|
|
|
ldap = _get_ldap_interface()
|
|
|
|
user_search = ldap.search(
|
|
"ou=users",
|
|
"(&(objectclass=person)(!(uid=root))(!(uid=nobody)))",
|
|
["uid", "memberOf", "permission"],
|
|
)
|
|
group_search = ldap.search(
|
|
"ou=groups",
|
|
"(objectclass=groupOfNamesYnh)",
|
|
["cn", "member", "memberUid", "permission"],
|
|
)
|
|
permission_search = ldap.search(
|
|
"ou=permission",
|
|
"(objectclass=permissionYnh)",
|
|
["cn", "groupPermission", "inheritPermission", "memberUid"],
|
|
)
|
|
|
|
user_map = {u["uid"][0]: u for u in user_search}
|
|
group_map = {g["cn"][0]: g for g in group_search}
|
|
permission_map = {p["cn"][0]: p for p in permission_search}
|
|
|
|
for user in user_search:
|
|
user_dn = "uid=" + user["uid"][0] + ",ou=users,dc=yunohost,dc=org"
|
|
group_list = [_ldap_path_extract(m, "cn") for m in user.get("memberOf", [])]
|
|
permission_list = [
|
|
_ldap_path_extract(m, "cn") for m in user.get("permission", [])
|
|
]
|
|
|
|
# This user's DN sould be found in all groups it is a member of
|
|
for group in group_list:
|
|
assert user_dn in group_map[group]["member"]
|
|
|
|
# This user's DN should be found in all perms it has access to
|
|
for permission in permission_list:
|
|
assert user_dn in permission_map[permission]["inheritPermission"]
|
|
|
|
for permission in permission_search:
|
|
permission_dn = (
|
|
"cn=" + permission["cn"][0] + ",ou=permission,dc=yunohost,dc=org"
|
|
)
|
|
|
|
# inheritPermission uid's should match memberUids
|
|
user_list = [
|
|
_ldap_path_extract(m, "uid")
|
|
for m in permission.get("inheritPermission", [])
|
|
]
|
|
assert set(user_list) == set(permission.get("memberUid", []))
|
|
|
|
# This perm's DN should be found on all related users it is related to
|
|
for user in user_list:
|
|
assert permission_dn in user_map[user]["permission"]
|
|
|
|
# Same for groups : we should find the permission's DN for all related groups
|
|
group_list = [
|
|
_ldap_path_extract(m, "cn") for m in permission.get("groupPermission", [])
|
|
]
|
|
for group in group_list:
|
|
assert permission_dn in group_map[group]["permission"]
|
|
|
|
# The list of user in the group should be a subset of all users related to the current permission
|
|
users_in_group = [
|
|
_ldap_path_extract(m, "uid") for m in group_map[group].get("member", [])
|
|
]
|
|
assert set(users_in_group) <= set(user_list)
|
|
|
|
for group in group_search:
|
|
group_dn = "cn=" + group["cn"][0] + ",ou=groups,dc=yunohost,dc=org"
|
|
|
|
user_list = [_ldap_path_extract(m, "uid") for m in group.get("member", [])]
|
|
# For primary groups, we should find that :
|
|
# - len(user_list) is 1 (a primary group has only 1 member)
|
|
# - the group name should be an existing yunohost user
|
|
# - memberUid is empty (meaning no other member than the corresponding user)
|
|
if group["cn"][0] in user_list:
|
|
assert len(user_list) == 1
|
|
assert group["cn"][0] in user_map
|
|
assert group.get("memberUid", []) == []
|
|
# Otherwise, user_list and memberUid should have the same content
|
|
else:
|
|
assert set(user_list) == set(group.get("memberUid", []))
|
|
|
|
# For all users members, this group should be in the "memberOf" on the other side
|
|
for user in user_list:
|
|
assert group_dn in user_map[user]["memberOf"]
|
|
|
|
# For all the permissions of this group, the group should be among the "groupPermission" on the other side
|
|
permission_list = [
|
|
_ldap_path_extract(m, "cn") for m in group.get("permission", [])
|
|
]
|
|
for permission in permission_list:
|
|
assert group_dn in permission_map[permission]["groupPermission"]
|
|
|
|
# And the list of user of this group (user_list) should be a subset of all allowed users for this perm...
|
|
allowed_user_list = [
|
|
_ldap_path_extract(m, "uid")
|
|
for m in permission_map[permission].get("inheritPermission", [])
|
|
]
|
|
assert set(user_list) <= set(allowed_user_list)
|
|
|
|
|
|
def check_permission_for_apps():
|
|
# We check that the for each installed apps we have at last the "main" permission
|
|
# and we don't have any permission linked to no apps. The only exception who is not liked to an app
|
|
# is mail, xmpp, and sftp
|
|
|
|
app_perms = user_permission_list(ignore_system_perms=True)["permissions"].keys()
|
|
|
|
# Keep only the prefix so that
|
|
# ["foo.main", "foo.pwet", "bar.main"]
|
|
# becomes
|
|
# {"bar", "foo"}
|
|
# and compare this to the list of installed apps ...
|
|
|
|
app_perms_prefix = {p.split(".")[0] for p in app_perms}
|
|
|
|
assert set(_installed_apps()) == app_perms_prefix
|
|
|
|
|
|
def can_access_webpage(webpath, logged_as=None):
|
|
webpath = webpath.rstrip("/")
|
|
sso_url = "https://" + maindomain + "/yunohost/portalapi/login"
|
|
|
|
# Anonymous access
|
|
if not logged_as:
|
|
r = requests.get(webpath, verify=False)
|
|
# Login as a user using dummy password
|
|
else:
|
|
with requests.Session() as session:
|
|
session.post(
|
|
sso_url,
|
|
data={"credentials": f"{logged_as}:{dummy_password}"},
|
|
headers={
|
|
"Referer": sso_url,
|
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
},
|
|
verify=False,
|
|
)
|
|
# We should have some cookies related to authentication now
|
|
assert session.cookies
|
|
r = session.get(webpath, verify=False)
|
|
|
|
# If we can't access it, we got redirected to the SSO
|
|
return not r.url.startswith(sso_url)
|
|
|
|
|
|
#
|
|
# List functions
|
|
#
|
|
|
|
|
|
def test_permission_list():
|
|
res = user_permission_list(full=True)["permissions"]
|
|
|
|
assert "mail.main" in res
|
|
assert "xmpp.main" in res
|
|
|
|
assert "wiki.main" in res
|
|
assert "blog.main" in res
|
|
assert "blog.api" in res
|
|
|
|
assert res["wiki.main"]["allowed"] == ["all_users"]
|
|
assert res["blog.main"]["allowed"] == ["alice"]
|
|
assert res["blog.api"]["allowed"] == ["visitors"]
|
|
assert set(res["wiki.main"]["corresponding_users"]) == {"alice", "bob"}
|
|
assert res["blog.main"]["corresponding_users"] == ["alice"]
|
|
assert res["blog.api"]["corresponding_users"] == []
|
|
assert res["wiki.main"]["url"] == "/"
|
|
assert res["blog.main"]["url"] == "/"
|
|
assert res["blog.api"]["url"] is None
|
|
assert set(res["wiki.main"]["additional_urls"]) == {"/whatever", "/idontnow"}
|
|
assert res["wiki.main"]["protected"] is False
|
|
assert res["blog.main"]["protected"] is False
|
|
assert res["blog.api"]["protected"] is True
|
|
assert res["wiki.main"]["label"] == "Wiki"
|
|
assert res["blog.main"]["label"] == "Blog"
|
|
assert res["blog.api"]["label"] == "Blog (api)"
|
|
assert res["wiki.main"]["show_tile"] is True
|
|
assert res["blog.main"]["show_tile"] is False
|
|
assert res["blog.api"]["show_tile"] is False
|
|
assert res["wiki.main"]["auth_header"] is False
|
|
assert res["blog.main"]["auth_header"] is True
|
|
assert res["blog.api"]["auth_header"] is True
|
|
|
|
res = user_permission_list(full=True, absolute_urls=True)["permissions"]
|
|
assert res["wiki.main"]["url"] == maindomain + "/wiki"
|
|
assert res["blog.main"]["url"] == maindomain + "/blog"
|
|
assert res["blog.api"]["url"] is None
|
|
assert set(res["wiki.main"]["additional_urls"]) == {
|
|
maindomain + "/wiki/whatever",
|
|
maindomain + "/wiki/idontnow",
|
|
}
|
|
assert res["blog.main"]["additional_urls"] == []
|
|
assert res["blog.api"]["additional_urls"] == []
|
|
|
|
|
|
#
|
|
# Create - Remove functions
|
|
#
|
|
|
|
|
|
def test_permission_create_main():
|
|
with message("permission_created", permission="site.main"):
|
|
permission_create("site.main", allowed=["all_users"], protected=False)
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert "site.main" in res
|
|
assert res["site.main"]["allowed"] == ["all_users"]
|
|
assert set(res["site.main"]["corresponding_users"]) == {"alice", "bob"}
|
|
assert res["site.main"]["protected"] is False
|
|
|
|
|
|
def test_permission_create_extra():
|
|
with message("permission_created", permission="site.test"):
|
|
permission_create("site.test")
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert "site.test" in res
|
|
# all_users is only enabled by default on .main perms
|
|
assert "all_users" not in res["site.test"]["allowed"]
|
|
assert res["site.test"]["corresponding_users"] == []
|
|
assert res["site.test"]["protected"] is False
|
|
|
|
|
|
def test_permission_create_with_specific_user():
|
|
permission_create("site.test", allowed=["alice"])
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert "site.test" in res
|
|
assert res["site.test"]["allowed"] == ["alice"]
|
|
|
|
|
|
def test_permission_create_with_tile_management():
|
|
with message("permission_created", permission="site.main"):
|
|
_permission_create_with_dummy_app(
|
|
"site.main",
|
|
allowed=["all_users"],
|
|
label="The Site",
|
|
show_tile=False,
|
|
domain=maindomain,
|
|
path="/site",
|
|
)
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert "site.main" in res
|
|
assert res["site.main"]["label"] == "The Site"
|
|
assert res["site.main"]["show_tile"] is False
|
|
|
|
|
|
def test_permission_create_with_tile_management_with_main_default_value():
|
|
with message("permission_created", permission="site.main"):
|
|
_permission_create_with_dummy_app(
|
|
"site.main",
|
|
allowed=["all_users"],
|
|
show_tile=True,
|
|
url="/",
|
|
domain=maindomain,
|
|
path="/site",
|
|
)
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert "site.main" in res
|
|
assert res["site.main"]["label"] == "Site"
|
|
assert res["site.main"]["show_tile"] is True
|
|
|
|
|
|
def test_permission_create_with_tile_management_with_not_main_default_value():
|
|
with message("permission_created", permission="wiki.api"):
|
|
_permission_create_with_dummy_app(
|
|
"wiki.api",
|
|
allowed=["all_users"],
|
|
show_tile=True,
|
|
url="/",
|
|
domain=maindomain,
|
|
path="/site",
|
|
)
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert "wiki.api" in res
|
|
assert res["wiki.api"]["label"] == "Wiki (api)"
|
|
assert res["wiki.api"]["show_tile"] is True
|
|
|
|
|
|
def test_permission_create_with_urls_management_without_url():
|
|
with message("permission_created", permission="wiki.api"):
|
|
_permission_create_with_dummy_app(
|
|
"wiki.api", allowed=["all_users"], domain=maindomain, path="/site"
|
|
)
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert "wiki.api" in res
|
|
assert res["wiki.api"]["url"] is None
|
|
assert res["wiki.api"]["additional_urls"] == []
|
|
assert res["wiki.api"]["auth_header"] is True
|
|
|
|
|
|
def test_permission_create_with_urls_management_simple_domain():
|
|
with message("permission_created", permission="site.main"):
|
|
_permission_create_with_dummy_app(
|
|
"site.main",
|
|
allowed=["all_users"],
|
|
url="/",
|
|
additional_urls=["/whatever", "/idontnow"],
|
|
auth_header=False,
|
|
domain=maindomain,
|
|
path="/site",
|
|
)
|
|
|
|
res = user_permission_list(full=True, absolute_urls=True)["permissions"]
|
|
assert "site.main" in res
|
|
assert res["site.main"]["url"] == maindomain + "/site"
|
|
assert set(res["site.main"]["additional_urls"]) == {
|
|
maindomain + "/site/whatever",
|
|
maindomain + "/site/idontnow",
|
|
}
|
|
assert res["site.main"]["auth_header"] is False
|
|
|
|
|
|
@pytest.mark.other_domains(number=2)
|
|
def test_permission_create_with_urls_management_multiple_domain():
|
|
with message("permission_created", permission="site.main"):
|
|
_permission_create_with_dummy_app(
|
|
"site.main",
|
|
allowed=["all_users"],
|
|
url=maindomain + "/site/something",
|
|
additional_urls=[other_domains[0] + "/blabla", other_domains[1] + "/ahh"],
|
|
auth_header=True,
|
|
domain=maindomain,
|
|
path="/site",
|
|
)
|
|
|
|
res = user_permission_list(full=True, absolute_urls=True)["permissions"]
|
|
assert "site.main" in res
|
|
assert res["site.main"]["url"] == maindomain + "/site/something"
|
|
assert set(res["site.main"]["additional_urls"]) == {
|
|
other_domains[0] + "/blabla",
|
|
other_domains[1] + "/ahh",
|
|
}
|
|
assert res["site.main"]["auth_header"] is True
|
|
|
|
|
|
def test_permission_delete():
|
|
with message("permission_deleted", permission="wiki.main"):
|
|
permission_delete("wiki.main", force=True)
|
|
|
|
res = user_permission_list()["permissions"]
|
|
assert "wiki.main" not in res
|
|
|
|
with message("permission_deleted", permission="blog.api"):
|
|
permission_delete("blog.api", force=False)
|
|
|
|
res = user_permission_list()["permissions"]
|
|
assert "blog.api" not in res
|
|
|
|
|
|
#
|
|
# Error on create - remove function
|
|
#
|
|
|
|
|
|
def test_permission_create_already_existing(mocker):
|
|
with raiseYunohostError(mocker, "permission_already_exist"):
|
|
permission_create("wiki.main")
|
|
|
|
|
|
def test_permission_delete_doesnt_existing(mocker):
|
|
with raiseYunohostError(mocker, "permission_not_found"):
|
|
permission_delete("doesnt.exist", force=True)
|
|
|
|
res = user_permission_list()["permissions"]
|
|
assert "wiki.main" in res
|
|
assert "blog.main" in res
|
|
assert "mail.main" in res
|
|
assert "xmpp.main" in res
|
|
|
|
|
|
def test_permission_delete_main_without_force(mocker):
|
|
with raiseYunohostError(mocker, "permission_cannot_remove_main"):
|
|
permission_delete("blog.main")
|
|
|
|
res = user_permission_list()["permissions"]
|
|
assert "blog.main" in res
|
|
|
|
|
|
#
|
|
# Update functions
|
|
#
|
|
|
|
# user side functions
|
|
|
|
|
|
def test_permission_add_group():
|
|
with message("permission_updated", permission="wiki.main"):
|
|
user_permission_update("wiki.main", add="alice")
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert set(res["wiki.main"]["allowed"]) == {"all_users", "alice"}
|
|
assert set(res["wiki.main"]["corresponding_users"]) == {"alice", "bob"}
|
|
|
|
|
|
def test_permission_remove_group():
|
|
with message("permission_updated", permission="blog.main"):
|
|
user_permission_update("blog.main", remove="alice")
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["blog.main"]["allowed"] == []
|
|
assert res["blog.main"]["corresponding_users"] == []
|
|
|
|
|
|
def test_permission_add_and_remove_group():
|
|
with message("permission_updated", permission="wiki.main"):
|
|
user_permission_update("wiki.main", add="alice", remove="all_users")
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["wiki.main"]["allowed"] == ["alice"]
|
|
assert res["wiki.main"]["corresponding_users"] == ["alice"]
|
|
|
|
|
|
def test_permission_add_group_already_allowed():
|
|
with message(
|
|
"permission_already_allowed", permission="blog.main", group="alice"
|
|
):
|
|
user_permission_update("blog.main", add="alice")
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["blog.main"]["allowed"] == ["alice"]
|
|
assert res["blog.main"]["corresponding_users"] == ["alice"]
|
|
|
|
|
|
def test_permission_remove_group_already_not_allowed():
|
|
with message(
|
|
"permission_already_disallowed", permission="blog.main", group="bob"
|
|
):
|
|
user_permission_update("blog.main", remove="bob")
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["blog.main"]["allowed"] == ["alice"]
|
|
assert res["blog.main"]["corresponding_users"] == ["alice"]
|
|
|
|
|
|
def test_permission_reset():
|
|
with message("permission_updated", permission="blog.main"):
|
|
user_permission_reset("blog.main")
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["blog.main"]["allowed"] == ["all_users"]
|
|
assert set(res["blog.main"]["corresponding_users"]) == {"alice", "bob"}
|
|
|
|
|
|
def test_permission_reset_idempotency():
|
|
# Reset permission
|
|
user_permission_reset("blog.main")
|
|
user_permission_reset("blog.main")
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["blog.main"]["allowed"] == ["all_users"]
|
|
assert set(res["blog.main"]["corresponding_users"]) == {"alice", "bob"}
|
|
|
|
|
|
def test_permission_change_label():
|
|
with message("permission_updated", permission="wiki.main"):
|
|
user_permission_update("wiki.main", label="New Wiki")
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["wiki.main"]["label"] == "New Wiki"
|
|
|
|
|
|
def test_permission_change_label_with_same_value():
|
|
with message("permission_updated", permission="wiki.main"):
|
|
user_permission_update("wiki.main", label="Wiki")
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["wiki.main"]["label"] == "Wiki"
|
|
|
|
|
|
def test_permission_switch_show_tile():
|
|
# Note that from the actionmap the value is passed as string, not as bool
|
|
# Try with lowercase
|
|
with message("permission_updated", permission="wiki.main"):
|
|
user_permission_update("wiki.main", show_tile="false")
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["wiki.main"]["show_tile"] is False
|
|
|
|
# Try with uppercase
|
|
with message("permission_updated", permission="wiki.main"):
|
|
user_permission_update("wiki.main", show_tile="TRUE")
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["wiki.main"]["show_tile"] is True
|
|
|
|
|
|
def test_permission_switch_show_tile_with_same_value():
|
|
# Note that from the actionmap the value is passed as string, not as bool
|
|
with message("permission_updated", permission="wiki.main"):
|
|
user_permission_update("wiki.main", show_tile="True")
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["wiki.main"]["show_tile"] is True
|
|
|
|
|
|
#
|
|
# Error on update function
|
|
#
|
|
|
|
|
|
def test_permission_add_group_that_doesnt_exist(mocker):
|
|
with raiseYunohostError(mocker, "group_unknown"):
|
|
user_permission_update("blog.main", add="doesnt_exist")
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["blog.main"]["allowed"] == ["alice"]
|
|
assert res["blog.main"]["corresponding_users"] == ["alice"]
|
|
|
|
|
|
def test_permission_update_permission_that_doesnt_exist(mocker):
|
|
with raiseYunohostError(mocker, "permission_not_found"):
|
|
user_permission_update("doesnt.exist", add="alice")
|
|
|
|
|
|
def test_permission_protected_update(mocker):
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["blog.api"]["allowed"] == ["visitors"]
|
|
|
|
with raiseYunohostError(mocker, "permission_protected"):
|
|
user_permission_update("blog.api", remove="visitors")
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["blog.api"]["allowed"] == ["visitors"]
|
|
|
|
user_permission_update("blog.api", remove="visitors", force=True)
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["blog.api"]["allowed"] == []
|
|
|
|
with raiseYunohostError(mocker, "permission_protected"):
|
|
user_permission_update("blog.api", add="visitors")
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["blog.api"]["allowed"] == []
|
|
|
|
|
|
# Permission url management
|
|
|
|
|
|
def test_permission_redefine_url():
|
|
permission_url("blog.main", url="/pwet")
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["blog.main"]["url"] == "/pwet"
|
|
|
|
|
|
def test_permission_remove_url():
|
|
permission_url("blog.main", clear_urls=True)
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["blog.main"]["url"] is None
|
|
|
|
|
|
def test_permission_main_url_regex():
|
|
permission_url("blog.main", url="re:/[a-z]+reboy/.*")
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["blog.main"]["url"] == "re:/[a-z]+reboy/.*"
|
|
|
|
res = user_permission_list(full=True, absolute_urls=True)["permissions"]
|
|
assert res["blog.main"]["url"] == "re:%s/blog/[a-z]+reboy/.*" % maindomain.replace(
|
|
".", r"\."
|
|
)
|
|
|
|
|
|
def test_permission_main_url_bad_regex(mocker):
|
|
with raiseYunohostError(mocker, "invalid_regex"):
|
|
permission_url("blog.main", url="re:/[a-z]+++reboy/.*")
|
|
|
|
|
|
@pytest.mark.other_domains(number=1)
|
|
def test_permission_add_additional_url():
|
|
permission_url("wiki.main", add_url=[other_domains[0] + "/heyby", "/myhouse"])
|
|
|
|
res = user_permission_list(full=True, absolute_urls=True)["permissions"]
|
|
assert res["wiki.main"]["url"] == maindomain + "/wiki"
|
|
assert set(res["wiki.main"]["additional_urls"]) == {
|
|
maindomain + "/wiki/whatever",
|
|
maindomain + "/wiki/idontnow",
|
|
other_domains[0] + "/heyby",
|
|
maindomain + "/wiki/myhouse",
|
|
}
|
|
|
|
|
|
def test_permission_add_additional_regex():
|
|
permission_url("blog.main", add_url=["re:/[a-z]+reboy/.*"])
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["blog.main"]["additional_urls"] == ["re:/[a-z]+reboy/.*"]
|
|
|
|
res = user_permission_list(full=True, absolute_urls=True)["permissions"]
|
|
assert res["blog.main"]["additional_urls"] == [
|
|
"re:%s/blog/[a-z]+reboy/.*" % maindomain.replace(".", r"\.")
|
|
]
|
|
|
|
|
|
def test_permission_add_additional_bad_regex(mocker):
|
|
with raiseYunohostError(mocker, "invalid_regex"):
|
|
permission_url("blog.main", add_url=["re:/[a-z]+++reboy/.*"])
|
|
|
|
|
|
def test_permission_remove_additional_url():
|
|
permission_url("wiki.main", remove_url=["/whatever"])
|
|
|
|
res = user_permission_list(full=True, absolute_urls=True)["permissions"]
|
|
assert res["wiki.main"]["url"] == maindomain + "/wiki"
|
|
assert res["wiki.main"]["additional_urls"] == [maindomain + "/wiki/idontnow"]
|
|
|
|
|
|
def test_permssion_add_additional_url_already_exist():
|
|
permission_url("wiki.main", add_url=["/whatever", "/myhouse"])
|
|
permission_url("wiki.main", add_url=["/whatever"])
|
|
|
|
res = user_permission_list(full=True, absolute_urls=True)["permissions"]
|
|
assert res["wiki.main"]["url"] == maindomain + "/wiki"
|
|
assert set(res["wiki.main"]["additional_urls"]) == {
|
|
maindomain + "/wiki/whatever",
|
|
maindomain + "/wiki/idontnow",
|
|
maindomain + "/wiki/myhouse",
|
|
}
|
|
|
|
|
|
def test_permission_remove_additional_url_dont_exist():
|
|
permission_url("wiki.main", remove_url=["/shouldntexist", "/whatever"])
|
|
permission_url("wiki.main", remove_url=["/shouldntexist"])
|
|
|
|
res = user_permission_list(full=True, absolute_urls=True)["permissions"]
|
|
assert res["wiki.main"]["url"] == maindomain + "/wiki"
|
|
assert res["wiki.main"]["additional_urls"] == [maindomain + "/wiki/idontnow"]
|
|
|
|
|
|
def test_permission_clear_additional_url():
|
|
permission_url("wiki.main", clear_urls=True)
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["wiki.main"]["url"] is None
|
|
assert res["wiki.main"]["additional_urls"] == []
|
|
|
|
|
|
def test_permission_switch_auth_header():
|
|
permission_url("wiki.main", auth_header=True)
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["wiki.main"]["auth_header"] is True
|
|
|
|
permission_url("wiki.main", auth_header=False)
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["wiki.main"]["auth_header"] is False
|
|
|
|
|
|
def test_permission_switch_auth_header_with_same_value():
|
|
permission_url("wiki.main", auth_header=False)
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["wiki.main"]["auth_header"] is False
|
|
|
|
|
|
# Permission protected
|
|
|
|
|
|
def test_permission_switch_protected():
|
|
user_permission_update("wiki.main", protected=True)
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["wiki.main"]["protected"] is True
|
|
|
|
user_permission_update("wiki.main", protected=False)
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["wiki.main"]["protected"] is False
|
|
|
|
|
|
def test_permission_switch_protected_with_same_value():
|
|
user_permission_update("wiki.main", protected=False)
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["wiki.main"]["protected"] is False
|
|
|
|
|
|
# Test SSOWAT conf generation
|
|
|
|
|
|
def test_ssowat_conf():
|
|
with open("/etc/ssowat/conf.json") as f:
|
|
res = json.load(f)
|
|
|
|
permissions = res["permissions"]
|
|
assert "wiki.main" in permissions
|
|
assert "blog.main" in permissions
|
|
assert (
|
|
"blog.api" not in permissions
|
|
) # blog.api has no url/additional url defined and therefore is not added to ssowat conf
|
|
|
|
assert set(permissions["wiki.main"]["users"]) == {"alice", "bob"}
|
|
assert permissions["blog.main"]["users"] == ["alice"]
|
|
|
|
assert permissions["wiki.main"]["uris"][0] == maindomain + "/wiki"
|
|
|
|
assert set(permissions["wiki.main"]["uris"]) == {
|
|
maindomain + "/wiki",
|
|
maindomain + "/wiki/whatever",
|
|
maindomain + "/wiki/idontnow",
|
|
}
|
|
assert permissions["blog.main"]["uris"] == [maindomain + "/blog"]
|
|
|
|
assert permissions["wiki.main"]["public"] is False
|
|
assert permissions["blog.main"]["public"] is False
|
|
|
|
assert permissions["wiki.main"]["auth_header"] is False
|
|
assert permissions["blog.main"]["auth_header"] is True
|
|
|
|
|
|
def test_show_tile_cant_be_enabled():
|
|
_permission_create_with_dummy_app(
|
|
permission="site.main",
|
|
auth_header=False,
|
|
label="Site",
|
|
show_tile=True,
|
|
allowed=["all_users"],
|
|
protected=False,
|
|
sync_perm=False,
|
|
domain=maindomain,
|
|
path="/site",
|
|
)
|
|
|
|
_permission_create_with_dummy_app(
|
|
permission="web.main",
|
|
url="re:/[a-z]{3}/bla",
|
|
auth_header=False,
|
|
label="Web",
|
|
show_tile=True,
|
|
allowed=["all_users"],
|
|
protected=False,
|
|
sync_perm=True,
|
|
domain=maindomain,
|
|
path="/web",
|
|
)
|
|
|
|
permissions = user_permission_list(full=True)["permissions"]
|
|
|
|
assert permissions["site.main"]["show_tile"] is False
|
|
assert permissions["web.main"]["show_tile"] is False
|
|
|
|
|
|
#
|
|
# Application interaction
|
|
#
|
|
|
|
|
|
@pytest.mark.other_domains(number=1)
|
|
def test_permission_app_install():
|
|
app_install(
|
|
os.path.join(get_test_apps_dir(), "permissions_app_ynh"),
|
|
args="domain=%s&domain_2=%s&path=%s&is_public=0&admin=%s"
|
|
% (maindomain, other_domains[0], "/urlpermissionapp", "alice"),
|
|
force=True,
|
|
)
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert "permissions_app.main" in res
|
|
assert "permissions_app.admin" in res
|
|
assert "permissions_app.dev" in res
|
|
assert res["permissions_app.main"]["url"] == "/"
|
|
assert res["permissions_app.admin"]["url"] == "/admin"
|
|
assert res["permissions_app.dev"]["url"] == "/dev"
|
|
|
|
assert res["permissions_app.main"]["allowed"] == ["all_users"]
|
|
assert set(res["permissions_app.main"]["corresponding_users"]) == {"alice", "bob"}
|
|
|
|
assert res["permissions_app.admin"]["allowed"] == ["alice"]
|
|
assert res["permissions_app.admin"]["corresponding_users"] == ["alice"]
|
|
|
|
assert res["permissions_app.dev"]["allowed"] == []
|
|
assert set(res["permissions_app.dev"]["corresponding_users"]) == set()
|
|
|
|
# Check that we get the right stuff in app_map, which is used to generate the ssowatconf
|
|
assert maindomain + "/urlpermissionapp" in app_map(user="alice").keys()
|
|
user_permission_update("permissions_app.main", remove="all_users", add="bob")
|
|
assert maindomain + "/urlpermissionapp" not in app_map(user="alice").keys()
|
|
assert maindomain + "/urlpermissionapp" in app_map(user="bob").keys()
|
|
|
|
|
|
@pytest.mark.other_domains(number=1)
|
|
def test_permission_app_remove():
|
|
app_install(
|
|
os.path.join(get_test_apps_dir(), "permissions_app_ynh"),
|
|
args="domain=%s&domain_2=%s&path=%s&is_public=0&admin=%s"
|
|
% (maindomain, other_domains[0], "/urlpermissionapp", "alice"),
|
|
force=True,
|
|
)
|
|
app_remove("permissions_app")
|
|
|
|
# Check all permissions for this app got deleted
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert not any(p.startswith("permissions_app.") for p in res.keys())
|
|
|
|
|
|
@pytest.mark.other_domains(number=1)
|
|
def test_permission_app_change_url():
|
|
app_install(
|
|
os.path.join(get_test_apps_dir(), "permissions_app_ynh"),
|
|
args="domain=%s&domain_2=%s&path=%s&is_public=1&admin=%s"
|
|
% (maindomain, other_domains[0], "/urlpermissionapp", "alice"),
|
|
force=True,
|
|
)
|
|
|
|
# FIXME : should rework this test to look for differences in the generated app map / app tiles ...
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["permissions_app.main"]["url"] == "/"
|
|
assert res["permissions_app.admin"]["url"] == "/admin"
|
|
assert res["permissions_app.dev"]["url"] == "/dev"
|
|
|
|
app_change_url("permissions_app", maindomain, "/newchangeurl")
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["permissions_app.main"]["url"] == "/"
|
|
assert res["permissions_app.admin"]["url"] == "/admin"
|
|
assert res["permissions_app.dev"]["url"] == "/dev"
|
|
|
|
|
|
@pytest.mark.other_domains(number=1)
|
|
def test_permission_protection_management_by_helper():
|
|
app_install(
|
|
os.path.join(get_test_apps_dir(), "permissions_app_ynh"),
|
|
args="domain=%s&domain_2=%s&path=%s&is_public=1&admin=%s"
|
|
% (maindomain, other_domains[0], "/urlpermissionapp", "alice"),
|
|
force=True,
|
|
)
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["permissions_app.main"]["protected"] is False
|
|
assert res["permissions_app.admin"]["protected"] is True
|
|
assert res["permissions_app.dev"]["protected"] is False
|
|
|
|
app_upgrade(
|
|
["permissions_app"],
|
|
file=os.path.join(get_test_apps_dir(), "permissions_app_ynh"),
|
|
)
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert res["permissions_app.main"]["protected"] is False
|
|
assert res["permissions_app.admin"]["protected"] is False
|
|
assert res["permissions_app.dev"]["protected"] is True
|
|
|
|
|
|
@pytest.mark.other_domains(number=1)
|
|
def test_permission_app_propagation_on_ssowat():
|
|
app_install(
|
|
os.path.join(get_test_apps_dir(), "permissions_app_ynh"),
|
|
args="domain=%s&domain_2=%s&path=%s&is_public=1&admin=%s"
|
|
% (maindomain, other_domains[0], "/urlpermissionapp", "alice"),
|
|
force=True,
|
|
)
|
|
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert "visitors" in res["permissions_app.main"]["allowed"]
|
|
assert "all_users" in res["permissions_app.main"]["allowed"]
|
|
|
|
app_webroot = "https://%s/urlpermissionapp" % maindomain
|
|
assert can_access_webpage(app_webroot, logged_as=None)
|
|
assert can_access_webpage(app_webroot, logged_as="alice")
|
|
|
|
user_permission_update(
|
|
"permissions_app.main", remove=["visitors", "all_users"], add="bob"
|
|
)
|
|
res = user_permission_list(full=True)["permissions"]
|
|
|
|
assert not can_access_webpage(app_webroot, logged_as=None)
|
|
assert not can_access_webpage(app_webroot, logged_as="alice")
|
|
assert can_access_webpage(app_webroot, logged_as="bob")
|
|
|
|
# Test admin access, as configured during install, only alice should be able to access it
|
|
|
|
# alice gotta be allowed on the main permission to access the admin tho
|
|
user_permission_update("permissions_app.main", remove="bob", add="all_users")
|
|
|
|
assert not can_access_webpage(app_webroot + "/admin", logged_as=None)
|
|
assert can_access_webpage(app_webroot + "/admin", logged_as="alice")
|
|
assert not can_access_webpage(app_webroot + "/admin", logged_as="bob")
|
|
|
|
|
|
@pytest.mark.other_domains(number=1)
|
|
def test_permission_legacy_app_propagation_on_ssowat():
|
|
app_install(
|
|
os.path.join(get_test_apps_dir(), "legacy_app_ynh"),
|
|
args="domain=%s&domain_2=%s&path=%s&is_public=0"
|
|
% (maindomain, other_domains[0], "/legacy"),
|
|
force=True,
|
|
)
|
|
|
|
# App is configured as public by default using the legacy unprotected_uri mechanics
|
|
# It should automatically be migrated during the install
|
|
res = user_permission_list(full=True)["permissions"]
|
|
assert "visitors" not in res["legacy_app.main"]["allowed"]
|
|
assert "all_users" in res["legacy_app.main"]["allowed"]
|
|
|
|
app_webroot = "https://%s/legacy" % maindomain
|
|
|
|
assert not can_access_webpage(app_webroot, logged_as=None)
|
|
assert can_access_webpage(app_webroot, logged_as="alice")
|
|
|
|
# Try to update the permission and check that permissions are still consistent
|
|
user_permission_update(
|
|
"legacy_app.main", remove=["visitors", "all_users"], add="bob"
|
|
)
|
|
|
|
assert not can_access_webpage(app_webroot, logged_as=None)
|
|
assert not can_access_webpage(app_webroot, logged_as="alice")
|
|
assert can_access_webpage(app_webroot, logged_as="bob")
|