Holger Frey
3 years ago
7 changed files with 459 additions and 850 deletions
@ -1,6 +1,2 @@
@@ -1,6 +1,2 @@
|
||||
foo:$apr1$SzJRyvJU$U3luHwCA6xHfKowizE.Gl. |
||||
FOO:$apr1$LSPDdLqg$tiGbDGgNEXcRA/oyadYSw1 |
||||
AndreasEvers:$apr1$n0Oaok6e$wyHcUg6Upm9sE2AoYlVMO/ |
||||
FOOBar:$apr1$pZCbClF5$smEDwhMJIVmPsNmMEkRPd1 |
||||
FooBar:$apr1$24r9zF2e$9q30fNOqSlvn6itdhZMpc1 |
||||
AlexanderDietz:$apr1$n0Oaok6e$wyHcUg6Upm9sE2AoYlVMO/ |
||||
UrmilShh:$apr1$WxMGE8Wb$H0xWao6KZGqBJoXj7fJ420 |
||||
|
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
import shutil |
||||
import tempfile |
||||
from typing import Dict, List |
||||
from pathlib import Path |
||||
from dataclasses import dataclass |
||||
|
||||
import pytest |
||||
|
||||
|
||||
@dataclass |
||||
class StubCall: |
||||
func: str |
||||
args: List |
||||
kargs: Dict |
||||
|
||||
|
||||
class StubShell: |
||||
|
||||
STDOUT = "STDOUT" |
||||
|
||||
def __init__(self): |
||||
self.stack = [] |
||||
|
||||
def _add(self, func, args, kargs): |
||||
sc = StubCall(func, args, kargs) |
||||
self.stack.append(sc) |
||||
|
||||
def check_call(self, args, **kargs): |
||||
self._add("check_call", args, kargs) |
||||
|
||||
|
||||
@pytest.fixture |
||||
def stub_handler(): |
||||
return StubShell() |
||||
|
||||
|
||||
def temporary_data_file(src_data_dir, file_name): |
||||
source = src_data_dir / file_name |
||||
with tempfile.TemporaryDirectory() as tmpdirname: |
||||
destination = Path(tmpdirname) / file_name |
||||
shutil.copy(source, destination) |
||||
yield destination |
||||
|
||||
|
||||
@pytest.fixture |
||||
def example_data_dir(): |
||||
this_file = Path(__file__).absolute() |
||||
src_dir = this_file.parent.parent |
||||
return src_dir / "test-data" |
||||
|
||||
|
||||
@pytest.fixture |
||||
def example_authz(example_data_dir): |
||||
yield from temporary_data_file(example_data_dir, "authz") |
||||
|
||||
|
||||
@pytest.fixture |
||||
def example_htpasswd(example_data_dir): |
||||
yield from temporary_data_file(example_data_dir, "htpasswd") |
||||
|
||||
|
||||
@pytest.fixture |
||||
def example_empty_file(): |
||||
with tempfile.TemporaryDirectory() as tmpdirname: |
||||
destination = Path(tmpdirname) / "empty" |
||||
yield destination |
@ -0,0 +1,258 @@
@@ -0,0 +1,258 @@
|
||||
import pytest |
||||
|
||||
|
||||
def read_lines(path): |
||||
with path.open("r") as fh: |
||||
content = fh.read().strip() |
||||
lines = content.splitlines() |
||||
return [line.strip() for line in lines] |
||||
|
||||
|
||||
@pytest.mark.parametrize( |
||||
"value, expected", |
||||
[ |
||||
("no line break", "KEY = no line break"), |
||||
("with\nline\nbreak", "KEY = with\n\tline\n\tbreak"), |
||||
], |
||||
) |
||||
def test_authz_format_ini_option(value, expected): |
||||
from elab_users.authz import format_ini_option |
||||
|
||||
result = format_ini_option("KEY", value) |
||||
|
||||
assert result == expected |
||||
|
||||
|
||||
def test_authz_parser_init(): |
||||
import configparser |
||||
|
||||
from elab_users.authz import AuthzConfigParser |
||||
|
||||
parser = AuthzConfigParser() |
||||
|
||||
assert isinstance(parser, configparser.ConfigParser) |
||||
assert parser.elab_users == {} |
||||
assert parser.original_path is None |
||||
|
||||
|
||||
def test_authz_parser_optionxfrom(): |
||||
from elab_users.authz import AuthzConfigParser |
||||
|
||||
parser = AuthzConfigParser() |
||||
|
||||
assert parser.optionxform(123) == "123" |
||||
|
||||
|
||||
def test_authz_parser_read(example_authz): |
||||
from elab_users.authz import AuthzConfigParser |
||||
|
||||
parser = AuthzConfigParser() |
||||
parser.read(example_authz) |
||||
|
||||
assert parser.original_path == example_authz |
||||
assert parser.elab_users != {} |
||||
|
||||
|
||||
def test_authz_parser_from_file(example_authz): |
||||
from elab_users.authz import AuthzConfigParser |
||||
|
||||
parser = AuthzConfigParser.from_file(example_authz) |
||||
|
||||
assert isinstance(parser, AuthzConfigParser) |
||||
assert parser.original_path == example_authz |
||||
assert parser.elab_users != {} |
||||
|
||||
|
||||
def test_authz_parser_write_to_file_raises_error(): |
||||
from elab_users.authz import AuthzConfigParser |
||||
|
||||
parser = AuthzConfigParser() |
||||
|
||||
with pytest.raises(IOError): |
||||
parser.write_to_file(path=None) |
||||
|
||||
|
||||
def test_authz_parser_write_to_file_uses_original_path( |
||||
example_authz, example_empty_file |
||||
): |
||||
from elab_users.authz import AuthzConfigParser |
||||
|
||||
parser = AuthzConfigParser.from_file(example_authz) |
||||
parser.original_path = example_empty_file |
||||
parser.write_to_file(path=None) |
||||
|
||||
assert example_empty_file.is_file() |
||||
|
||||
|
||||
def test_authz_parser_write_to_file_custom_path( |
||||
example_authz, example_empty_file |
||||
): |
||||
from elab_users.authz import AuthzConfigParser |
||||
|
||||
parser = AuthzConfigParser.from_file(example_authz) |
||||
parser.write_to_file(path=example_empty_file) |
||||
|
||||
assert example_empty_file.is_file() |
||||
|
||||
|
||||
def test_authz_parser_write(example_authz, example_empty_file): |
||||
from elab_users.authz import AuthzConfigParser |
||||
|
||||
parser = AuthzConfigParser.from_file(example_authz) |
||||
with open(example_empty_file, "w") as fh: |
||||
parser.write(fh) |
||||
|
||||
original = read_lines(example_authz) |
||||
created = read_lines(example_empty_file) |
||||
assert original == created |
||||
|
||||
|
||||
def test_authz_parser_extract_user_info_from_config(example_authz): |
||||
from elab_users.authz import AuthzConfigParser |
||||
|
||||
parser = AuthzConfigParser() |
||||
|
||||
super(type(parser), parser).read(example_authz) |
||||
assert parser.elab_users == {} |
||||
|
||||
parser._extract_user_info_from_config() |
||||
assert parser.elab_users != {} |
||||
|
||||
|
||||
@pytest.mark.parametrize( |
||||
"name, group", |
||||
[ |
||||
("OswaldPrucker", "administrators"), |
||||
("AlexanderDietz", "users"), |
||||
("UrmilShah", "restricted"), |
||||
("CamillaOestevold", "alumni"), |
||||
], |
||||
) |
||||
def test_authz_parser_extract_group_definitions(name, group, example_authz): |
||||
from elab_users.authz import AuthzConfigParser |
||||
|
||||
parser = AuthzConfigParser() |
||||
|
||||
super(type(parser), parser).read(example_authz) |
||||
parser._extract_group_definitions() |
||||
|
||||
user = parser.elab_users[name] |
||||
assert user.group == group |
||||
|
||||
|
||||
@pytest.mark.parametrize( |
||||
"name, read, write", |
||||
[ |
||||
("OswaldPrucker", [], []), |
||||
("AlexanderDietz", [], ["AlexanderDietz"]), |
||||
("UrmilShah", ["AndreasEvers"], ["UrmilShah"]), |
||||
], |
||||
) |
||||
def test_authz_parser_extract_individual_acls( |
||||
name, read, write, example_authz |
||||
): |
||||
from elab_users.authz import AuthzConfigParser |
||||
|
||||
parser = AuthzConfigParser() |
||||
|
||||
super(type(parser), parser).read(example_authz) |
||||
parser._extract_group_definitions() |
||||
parser._extract_individual_acls() |
||||
|
||||
user = parser.elab_users[name] |
||||
assert user.read_acl == set(read) |
||||
assert user.write_acl == set(write) |
||||
|
||||
|
||||
def test_authz_parser_group_users(example_authz): |
||||
from elab_users.authz import AuthzConfigParser |
||||
|
||||
parser = AuthzConfigParser.from_file(example_authz) |
||||
|
||||
groups = parser.group_users() |
||||
|
||||
assert len(groups) == 4 |
||||
assert len(groups["administrators"]) == 2 |
||||
assert len(groups["users"]) == 54 |
||||
assert len(groups["restricted"]) == 5 |
||||
assert len(groups["alumni"]) == 62 |
||||
|
||||
|
||||
def test_authz_parser_add_journal_acl_for(example_authz): |
||||
from elab_users.authz import AuthzConfigParser |
||||
|
||||
parser = AuthzConfigParser.from_file(example_authz) |
||||
|
||||
user = parser.add_journal_acl_for("JaneDoe", "users") |
||||
|
||||
assert user.name == "JaneDoe" |
||||
assert user.group == "users" |
||||
assert parser.elab_users["JaneDoe"] == user |
||||
assert "JaneDoe:/" in parser.sections() |
||||
items = parser.items("JaneDoe:/") |
||||
assert sorted(items) == [ |
||||
("@administrators", "rw"), |
||||
("@alumni", ""), |
||||
("@restricted", ""), |
||||
("@users", "r"), |
||||
("JaneDoe", "rw"), |
||||
] |
||||
|
||||
|
||||
def test_authz_parser_move_user_to_alumni(example_authz): |
||||
from elab_users.authz import AuthzConfigParser |
||||
|
||||
parser = AuthzConfigParser.from_file(example_authz) |
||||
|
||||
user = parser.move_user_to_alumni("UrmilShah") |
||||
|
||||
assert user.name == "UrmilShah" |
||||
assert user.group == "alumni" |
||||
assert user.write_acl == set() |
||||
assert user.read_acl == set() |
||||
|
||||
for group, userlist in parser.items("groups"): |
||||
if group == "alumni": |
||||
assert "UrmilShah" in userlist |
||||
else: |
||||
assert "UrmilShah" not in userlist |
||||
|
||||
|
||||
def test_authz_parser_update_user_group_config(example_authz): |
||||
from elab_users.authz import AuthzConfigParser |
||||
|
||||
parser = AuthzConfigParser.from_file(example_authz) |
||||
parser.elab_users["UrmilShah"].group = "alumni" |
||||
|
||||
parser._update_user_group_config() |
||||
|
||||
for group, userlist in parser.items("groups"): |
||||
if group == "alumni": |
||||
assert "UrmilShah" in userlist |
||||
else: |
||||
assert "UrmilShah" not in userlist |
||||
|
||||
|
||||
@pytest.mark.parametrize( |
||||
"elab, read, write", |
||||
[ |
||||
("AlexeyKopyshev:/", ["@users"], ["@administrators"]), |
||||
( |
||||
"AndreasEvers:/", |
||||
["@users", "UrmilShah"], |
||||
["@administrators"], |
||||
), |
||||
( |
||||
"UrmilShah:/", |
||||
["@users"], |
||||
["@administrators", "UrmilShah"], |
||||
), |
||||
], |
||||
) |
||||
def test_authz_parser_get_journal_info(elab, read, write, example_authz): |
||||
from elab_users.authz import AuthzConfigParser |
||||
|
||||
parser = AuthzConfigParser.from_file(example_authz) |
||||
|
||||
info = parser.get_journal_info(elab) |
||||
assert info == {"r": read, "rw": write} |
@ -0,0 +1,104 @@
@@ -0,0 +1,104 @@
|
||||
# import pytest |
||||
from datetime import datetime |
||||
|
||||
|
||||
def test_elabuser_string_representation(): |
||||
from elab_users.users import ElabUser |
||||
|
||||
eu = ElabUser("John Doe", "Some Group") |
||||
|
||||
assert str(eu) == "John Doe" |
||||
|
||||
|
||||
def test_elabuser_set_new_password(stub_handler): |
||||
from elab_users.users import ElabUser |
||||
|
||||
eu = ElabUser("John Doe", "Some Group") |
||||
|
||||
password = eu.set_new_password("some path", 12, handler=stub_handler) |
||||
|
||||
assert len(password) == 12 |
||||
assert len(stub_handler.stack) == 1 |
||||
called = stub_handler.stack[0] |
||||
assert called.func == "check_call" |
||||
assert called.args == [ |
||||
"htpasswd", |
||||
"-b", |
||||
"some path", |
||||
"John Doe", |
||||
password, |
||||
] |
||||
assert called.kargs == {} |
||||
|
||||
|
||||
def test_elabuser_delete_password(stub_handler): |
||||
from elab_users.users import ElabUser |
||||
|
||||
eu = ElabUser("John Doe", "Some Group") |
||||
|
||||
eu.delete_password("some path", handler=stub_handler) |
||||
|
||||
assert len(stub_handler.stack) == 1 |
||||
called = stub_handler.stack[0] |
||||
assert called.func == "check_call" |
||||
assert called.args == [ |
||||
"htpasswd", |
||||
"-D", |
||||
"some path", |
||||
"John Doe", |
||||
] |
||||
assert list(called.kargs.keys()) == ["stderr"] |
||||
|
||||
|
||||
def test_elabuser_create_new_repo(stub_handler): |
||||
from elab_users.users import ElabUser |
||||
|
||||
eu = ElabUser("John Doe", "Some Group") |
||||
|
||||
eu.create_new_repository("some path", handler=stub_handler) |
||||
|
||||
today = datetime.now() |
||||
current_month = today.month |
||||
current_year = today.year |
||||
|
||||
assert len(stub_handler.stack) == 8 + (12 - current_month) |
||||
|
||||
called = stub_handler.stack[0] |
||||
assert called.func == "check_call" |
||||
assert called.args == ["svnadmin", "create", "some path/John Doe"] |
||||
assert called.kargs == {"stderr": stub_handler.STDOUT} |
||||
|
||||
called = stub_handler.stack[1] |
||||
assert called.func == "check_call" |
||||
assert called.args[:3] == ["svn", "checkout", "file://some path/John Doe"] |
||||
assert called.args[3].startswith("/tmp/") # noqa: S108 |
||||
assert called.kargs == {} |
||||
|
||||
called = stub_handler.stack[2] |
||||
assert called.func == "check_call" |
||||
assert called.args[0] == "touch" |
||||
assert called.args[1].startswith("/tmp/") # noqa: S108 |
||||
assert called.args[1].endswith( |
||||
f"/{current_year:0>4}/{current_month:0>2}/.empty" |
||||
) |
||||
assert called.kargs == {} |
||||
|
||||
called = stub_handler.stack[-3] |
||||
assert called.func == "check_call" |
||||
assert called.args[0] == "cp" |
||||
assert called.args[1] == "some path/template-toc.doc" |
||||
assert called.args[2].startswith("/tmp/") # noqa: S108 |
||||
assert called.args[2].endswith("/template-toc.doc") |
||||
assert called.kargs == {} |
||||
|
||||
called = stub_handler.stack[-2] |
||||
assert called.func == "check_call" |
||||
assert called.args[:2] == ["svn", "add"] |
||||
assert called.args[2].startswith("/tmp/") # noqa: S108 |
||||
assert called.args[2].endswith("/*") |
||||
assert called.kargs == {"shell": True} |
||||
|
||||
called = stub_handler.stack[-1] |
||||
assert called.func == "check_call" |
||||
assert called.args[:4] == ["svn", "commit", "-m", "New User: John Doe"] |
||||
assert called.args[4].startswith("/tmp/") # noqa: S108 |
Loading…
Reference in new issue