Skip to content

Commit

Permalink
Add checks for lifetime, expire_at flags (#621)
Browse files Browse the repository at this point in the history
  • Loading branch information
roman-khimov authored Sep 1, 2023
2 parents 5a7f40f + ec7375f commit e95c173
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 12 deletions.
4 changes: 4 additions & 0 deletions pytest_tests/steps/session_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ def create_session_token(
wallet_path: str,
wallet_password: str,
rpc_endpoint: str,
lifetime: Optional[int] = None,
expire_at: Optional[int] = None
) -> str:
"""
Create session token for an object.
Expand All @@ -256,6 +258,8 @@ def create_session_token(
wallet=wallet_path,
wallet_password=wallet_password,
out=session_token,
lifetime=lifetime,
expire_at=expire_at
)
return session_token

Expand Down
10 changes: 7 additions & 3 deletions pytest_tests/testsuites/acl/storage_group/test_storagegroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
import allure
import pytest
from cluster_test_base import ClusterTestBase
from common import ASSETS_DIR, TEST_FILES_DIR, FREE_STORAGE, WALLET_PASS
from common import ASSETS_DIR, FREE_STORAGE, TEST_FILES_DIR, WALLET_PASS
from epoch import get_epoch
from file_helper import generate_file
from grpc_responses import OBJECT_ACCESS_DENIED, OBJECT_NOT_FOUND
from neofs_testlib.utils.wallet import init_wallet
Expand Down Expand Up @@ -233,7 +234,8 @@ def test_storagegroup_bearer_allow(self, object_size, max_object_size):
)

@allure.title("Test to check Storage Group lifetime")
def test_storagegroup_lifetime(self, object_size):
@pytest.mark.parametrize("expiration_flag", ["lifetime", "expire_at"])
def test_storagegroup_lifetime(self, object_size, expiration_flag, cluster):
cid = create_container(
self.main_wallet, shell=self.shell, endpoint=self.cluster.default_rpc_endpoint
)
Expand All @@ -242,13 +244,15 @@ def test_storagegroup_lifetime(self, object_size):
self.main_wallet, file_path, cid, shell=self.shell, cluster=self.cluster
)
objects = [oid]
current_epoch = get_epoch(self.shell, cluster)
storage_group = put_storagegroup(
self.shell,
self.cluster.default_rpc_endpoint,
self.main_wallet,
cid,
objects,
lifetime=1,
lifetime=1 if expiration_flag == "lifetime" else None,
expire_at=current_epoch + 1 if expiration_flag == "expire_at" else None,
)
with allure.step("Tick two epochs"):
for _ in range(2):
Expand Down
81 changes: 81 additions & 0 deletions pytest_tests/testsuites/acl/test_bearer.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import os
import uuid

import allure
import pytest
from cluster_test_base import ClusterTestBase
from common import ASSETS_DIR, TEST_FILES_DIR, WALLET_PASS
from epoch import get_epoch
from neofs_testlib.utils.wallet import get_last_address_from_wallet
from python_keywords.acl import (
EACLAccess,
EACLOperation,
EACLRole,
EACLRule,
create_bearer_token,
create_eacl,
form_bearertoken_file,
set_eacl,
sign_bearer,
wait_for_cache_expired,
)
from python_keywords.container_access import (
Expand Down Expand Up @@ -229,3 +237,76 @@ def test_bearer_token_compound_operations(self, wallets, eacl_container_with_obj
shell=self.shell,
cluster=self.cluster,
)

@pytest.mark.skip(reason="https://github.com/nspcc-dev/neofs-api/issues/273")
@pytest.mark.skip(reason="https://github.com/nspcc-dev/neofs-node/issues/2538")
@pytest.mark.nspcc_dev__neofs_api__issue_273
@pytest.mark.nspcc_dev__neofs_node__issue_2538
@pytest.mark.parametrize("expiration_flag", ["lifetime", "expire_at"])
def test_bearer_token_expiration(self, wallets, eacl_container_with_objects, expiration_flag):
current_epoch = get_epoch(self.shell, self.cluster)
self.tick_epochs(1)
cid, objects_oids, file_path = eacl_container_with_objects
user_wallet = wallets.get_wallet()

with allure.step("Create and sign bearer token via cli"):
eacl = [
EACLRule(access=EACLAccess.ALLOW, role=EACLRole.USER, operation=op)
for op in EACLOperation
]

path_to_bearer = os.path.join(
os.getcwd(), ASSETS_DIR, TEST_FILES_DIR, f"bearer_token_{str(uuid.uuid4())}"
)

create_bearer_token(
self.shell,
issued_at=1,
not_valid_before=1,
owner=get_last_address_from_wallet(user_wallet.wallet_path, WALLET_PASS),
out=path_to_bearer,
rpc_endpoint=self.cluster.default_rpc_endpoint,
eacl=create_eacl(cid, eacl, shell=self.shell),
lifetime=1 if expiration_flag == "lifetime" else None,
expire_at=current_epoch + 2 if expiration_flag == "expire_at" else None,
)

sign_bearer(
shell=self.shell,
wallet_path=user_wallet.wallet_path,
eacl_rules_file_from=path_to_bearer,
eacl_rules_file_to=path_to_bearer,
json=True,
)

self.tick_epochs(1)

with allure.step(
f"Check {EACLRole.USER.value} with token has access to all operations with container"
):
check_full_access_to_container(
user_wallet.wallet_path,
cid,
objects_oids.pop(),
file_path,
bearer=path_to_bearer,
wallet_config=user_wallet.config_path,
shell=self.shell,
cluster=self.cluster,
)

self.tick_epochs(1)

with allure.step(
f"Check {EACLRole.USER.value} has no access to all operations with container"
):
check_no_access_to_container(
user_wallet.wallet_path,
cid,
objects_oids.pop(),
file_path,
bearer=path_to_bearer,
wallet_config=user_wallet.config_path,
shell=self.shell,
cluster=self.cluster,
)
21 changes: 15 additions & 6 deletions pytest_tests/testsuites/object/test_object_lifetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import allure
import pytest
from epoch import get_epoch, tick_epoch
from epoch import get_epoch
from file_helper import generate_file, get_file_hash
from grpc_responses import OBJECT_NOT_FOUND
from pytest import FixtureRequest
Expand All @@ -19,12 +19,15 @@
class TestObjectApiLifetime(ClusterTestBase):
@allure.title("Test object life time")
@pytest.mark.parametrize(
"object_size",
[pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")],
ids=["simple object", "complex object"],
"object_size,expiration_flag",
[
(pytest.lazy_fixture("simple_object_size"), "lifetime"),
(pytest.lazy_fixture("complex_object_size"), "expire_at"),
],
ids=["simple object, lifetime", "complex object, expire_at"],
)
def test_object_api_lifetime(
self, default_wallet: str, request: FixtureRequest, object_size: int
self, default_wallet: str, request: FixtureRequest, object_size: int, expiration_flag: str
):
"""
Test object deleted after expiration epoch.
Expand All @@ -41,7 +44,13 @@ def test_object_api_lifetime(
epoch = get_epoch(self.shell, self.cluster)

oid = put_object_to_random_node(
wallet, file_path, cid, self.shell, self.cluster, expire_at=epoch + 1
wallet,
file_path,
cid,
self.shell,
self.cluster,
expire_at=epoch + 1 if expiration_flag == "expire_at" else None,
lifetime=1 if expiration_flag == "lifetime" else None,
)
got_file = get_object_from_random_node(wallet, cid, oid, self.shell, self.cluster)
assert get_file_hash(got_file) == file_hash
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
import pytest
from cluster_test_base import ClusterTestBase
from common import WALLET_PASS
from epoch import get_epoch
from file_helper import generate_file
from grpc_responses import SESSION_NOT_FOUND
from grpc_responses import EXPIRED_SESSION_TOKEN, SESSION_NOT_FOUND
from neofs_testlib.utils.wallet import get_last_address_from_wallet
from python_keywords.container import create_container
from python_keywords.neofs_verbs import delete_object, put_object, put_object_to_random_node
Expand Down Expand Up @@ -144,3 +145,73 @@ def test_object_session_token(self, default_wallet, object_size):
endpoint=non_container_node.get_rpc_endpoint(),
session=session_token,
)

@allure.title("Verify session token expiration flags")
@pytest.mark.skip(reason="https://github.com/nspcc-dev/neofs-node/issues/2539")
@pytest.mark.nspcc_dev__neofs_node__issue_2539
@pytest.mark.parametrize("expiration_flag", ["lifetime", "expire_at"])
def test_session_token_expiration_flags(
self, default_wallet, simple_object_size, expiration_flag, cluster
):
rpc_endpoint = self.cluster.storage_nodes[0].get_rpc_endpoint()

with allure.step("Create Session Token with Lifetime param"):
current_epoch = get_epoch(self.shell, cluster)

session_token = create_session_token(
shell=self.shell,
owner=get_last_address_from_wallet(default_wallet, ""),
wallet_path=default_wallet,
wallet_password=WALLET_PASS,
rpc_endpoint=rpc_endpoint,
lifetime=1 if expiration_flag == "lifetime" else None,
expire_at=current_epoch + 1 if expiration_flag == "expire_at" else None,
)

with allure.step("Create Private Container"):
un_locode = self.cluster.storage_nodes[0].get_un_locode()
locode = "SPB" if un_locode == "RU LED" else un_locode.split()[1]
placement_policy = (
f"REP 1 IN LOC_{locode}_PLACE CBF 1 SELECT 1 FROM LOC_{locode} "
f'AS LOC_{locode}_PLACE FILTER "UN-LOCODE" '
f'EQ "{un_locode}" AS LOC_{locode}'
)
cid = create_container(
default_wallet,
shell=self.shell,
endpoint=self.cluster.default_rpc_endpoint,
rule=placement_policy,
)

with allure.step("Verify object operations with created session token are allowed"):
file_path = generate_file(simple_object_size)
oid = put_object(
wallet=default_wallet,
path=file_path,
cid=cid,
shell=self.shell,
endpoint=rpc_endpoint,
session=session_token,
)
delete_object(
wallet=default_wallet,
cid=cid,
oid=oid,
shell=self.shell,
endpoint=rpc_endpoint,
session=session_token,
)

self.tick_epochs(2)

with allure.step("Verify object operations with created session token are not allowed"):
file_path = generate_file(simple_object_size)
with pytest.raises(RuntimeError, match=EXPIRED_SESSION_TOKEN):
oid = put_object(
wallet=default_wallet,
path=file_path,
cid=cid,
shell=self.shell,
endpoint=rpc_endpoint,
session=session_token,
)
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ mmh3==3.0.0
multidict==6.0.2
mypy==0.950
mypy-extensions==0.4.3
neofs-testlib==1.1.8
neofs-testlib==1.1.10
netaddr==0.8.0
packaging==21.3
paramiko==2.10.3
Expand Down
27 changes: 27 additions & 0 deletions robot/resources/lib/python_keywords/acl.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,3 +276,30 @@ def bearer_token_base64_from_file(
with open(bearer_path, "rb") as file:
signed = file.read()
return base64.b64encode(signed).decode("utf-8")


@allure.step("Create bearer token")
def create_bearer_token(
shell,
issued_at: int,
not_valid_before: int,
owner: str,
out: str,
rpc_endpoint: str,
json: Optional[bool] = False,
eacl: Optional[str] = None,
lifetime: Optional[int] = None,
expire_at: Optional[int] = None,
) -> str:
neofscli = NeofsCli(shell=shell, neofs_cli_exec_path=NEOFS_CLI_EXEC, config_file=WALLET_CONFIG)
neofscli.bearer.create(
issued_at=issued_at,
not_valid_before=not_valid_before,
owner=owner,
out=out,
rpc_endpoint=rpc_endpoint,
json=json,
eacl=eacl,
lifetime=lifetime,
expire_at=expire_at,
)
8 changes: 7 additions & 1 deletion robot/resources/lib/python_keywords/neofs_verbs.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ def put_object_to_random_node(
attributes: Optional[dict] = None,
xhdr: Optional[dict] = None,
wallet_config: Optional[str] = None,
lifetime: Optional[int] = None,
expire_at: Optional[int] = None,
no_progress: bool = True,
session: Optional[str] = None,
Expand All @@ -192,7 +193,8 @@ def put_object_to_random_node(
cluster: cluster under test
wallet_config: path to the wallet config
no_progress: do not show progress bar
expire_at: Last epoch in the life of the object
lifetime: Lock lifetime - relative to the current epoch.
expire_at: Last epoch in the life of the object - absolute value.
xhdr: Request X-Headers in form of Key=Value
session: path to a JSON-encoded container session token
Returns:
Expand All @@ -213,6 +215,7 @@ def put_object_to_random_node(
expire_at,
no_progress,
session,
lifetime
)


Expand All @@ -230,6 +233,7 @@ def put_object(
expire_at: Optional[int] = None,
no_progress: bool = True,
session: Optional[str] = None,
lifetime: Optional[int] = None,
):
"""
PUT of given file.
Expand All @@ -247,6 +251,7 @@ def put_object(
expire_at: Last epoch in the life of the object
xhdr: Request X-Headers in form of Key=Value
session: path to a JSON-encoded container session token
lifetime: Lock lifetime - relative to the current epoch.
Returns:
(str): ID of uploaded Object
"""
Expand All @@ -259,6 +264,7 @@ def put_object(
cid=cid,
attributes=attributes,
bearer=bearer,
lifetime=lifetime,
expire_at=expire_at,
no_progress=no_progress,
xhdr=xhdr,
Expand Down
3 changes: 3 additions & 0 deletions robot/resources/lib/python_keywords/storage_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def put_storagegroup(
bearer: Optional[str] = None,
wallet_config: str = WALLET_CONFIG,
lifetime: int = 10,
expire_at: Optional[int] = None,
) -> str:
"""
Wrapper for `neofs-cli storagegroup put`. Before the SG is created,
Expand All @@ -36,6 +37,7 @@ def put_storagegroup(
wallet: Path to wallet on whose behalf the SG is created.
cid: ID of Container to put SG to.
lifetime: Storage group lifetime in epochs.
expire_at: The last active epoch of the storage group.
objects: List of Object IDs to include into the SG.
bearer: Path to Bearer token file.
wallet_config: Path to neofs-cli config file.
Expand All @@ -47,6 +49,7 @@ def put_storagegroup(
wallet=wallet,
cid=cid,
lifetime=lifetime,
expire_at=expire_at,
members=objects,
bearer=bearer,
rpc_endpoint=endpoint,
Expand Down

0 comments on commit e95c173

Please sign in to comment.