From c230f1c10406fcc84cba7408ee797d2660bb8b1b Mon Sep 17 00:00:00 2001 From: Julien Perrochet Date: Thu, 9 Nov 2023 16:55:03 +0100 Subject: [PATCH] [uss_qualifier] DSS0030 token validation scenario --- monitoring/monitorlib/auth.py | 68 +- monitoring/prober/infrastructure.py | 2 +- .../netrid/common/dss/token_validation.py | 594 ++++++++++++++++++ .../scenarios/astm/netrid/v19/dss/__init__.py | 1 + .../astm/netrid/v19/dss/token_validation.md | 120 ++++ .../astm/netrid/v19/dss/token_validation.py | 8 + .../astm/netrid/v22a/dss/__init__.py | 1 + .../astm/netrid/v22a/dss/token_validation.md | 120 ++++ .../astm/netrid/v22a/dss/token_validation.py | 8 + .../suites/astm/netrid/f3411_19.md | 8 +- .../astm/netrid/f3411_19/dss_probing.md | 11 +- .../astm/netrid/f3411_19/dss_probing.yaml | 6 + .../suites/astm/netrid/f3411_22a.md | 19 +- .../astm/netrid/f3411_22a/dss_probing.md | 22 +- .../astm/netrid/f3411_22a/dss_probing.yaml | 6 + .../suites/interuss/dss/all_tests.md | 8 +- .../suites/uspace/network_identification.md | 19 +- .../suites/uspace/required_services.md | 19 +- 18 files changed, 1015 insertions(+), 25 deletions(-) create mode 100644 monitoring/uss_qualifier/scenarios/astm/netrid/common/dss/token_validation.py create mode 100644 monitoring/uss_qualifier/scenarios/astm/netrid/v19/dss/token_validation.md create mode 100644 monitoring/uss_qualifier/scenarios/astm/netrid/v19/dss/token_validation.py create mode 100644 monitoring/uss_qualifier/scenarios/astm/netrid/v22a/dss/token_validation.md create mode 100644 monitoring/uss_qualifier/scenarios/astm/netrid/v22a/dss/token_validation.py diff --git a/monitoring/monitorlib/auth.py b/monitoring/monitorlib/auth.py index d1df97f29f..c494a484b4 100644 --- a/monitoring/monitorlib/auth.py +++ b/monitoring/monitorlib/auth.py @@ -2,9 +2,9 @@ import datetime import hashlib import re -from typing import Any, Dict, List, Optional, Tuple import urllib.parse import uuid +from typing import Any, Dict, List, Optional, Tuple import cryptography.exceptions import cryptography.hazmat.backends @@ -20,6 +20,7 @@ from google.auth import impersonated_credentials from google.auth.transport import requests as google_requests from google.oauth2 import service_account + from monitoring.monitorlib.infrastructure import AuthAdapter, AuthSpec _UNIX_EPOCH = datetime.datetime.utcfromtimestamp(0) @@ -82,6 +83,70 @@ def issue_token(self, intended_audience: str, scopes: List[str]) -> str: return jwt.serialize() +class InvalidTokenSignatureAuth(AuthAdapter): + """Auth adapter that generates well-formed tokens that are signed with an unknown private key. + + The generated tokens are not expected to be accepted, + and should be used in scenarios that test the authentication logic. + """ + + # A random RSA2048 private key + unknown_private_key = jwcrypto.jwk.JWK.from_pem( + "-----BEGIN PRIVATE KEY-----\n" + "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCsa9ZYfRoeA1A5\n" + "oUY38payXpOQzjFUVmm2CUh2WxY1HV3d2/0nkWcjHSD5wIKRCqhBQ3T3rj1AJm4f\n" + "mUasH0dAurutgggTDTxpX4XiskYdG8NuZfyQxtRMGBivFnbySi3A0FwOWZPW3ZXz\n" + "RC2r27URC1IvZc2cpSkbNngK9OUodbxX/pbFU6ltkPbyztcLgdnAcC/R7JfUUmgm\n" + "kmBg9ZTyCFB1gsX3Bgx2YSBGyjLejfTUBcySoJuYFPobSKxBpO1r3S0XWCnz4WOu\n" + "ho5asoqy23ucI5VXXcOSaNVIBVnJVhFyCum04m8E2BKUegJfsRU3DMmVA2kaZaTL\n" + "rcPqDbPzAgMBAAECggEAC5ATyM1i8f5Q4/x/xAK9vmp/ROe/ASPmZPHMbTuAisFU\n" + "aSt2l6+1lfI/IuCZIPbw/6dxcaa6rtGk8vOJfMOAOMQND/63YeeyVHK2fNRtxUf2\n" + "XDH0tRTQaeX3yc4c3fTBiruuYLv7IR6tDqpU0cCjLOhwc4NFPasJzaxicoGn2IWo\n" + "kItqGCBn9qz1Qpxe+GZq4Yzebja2czac0Y4khsvmDcWKuFvaX6rU58iiLEekaHeH\n" + "lu288MKYNUqdQ63HNhWhsAm+abVArAgcl2zWPwf5ex6jCyBxsPMRfoCUwjuJzI28\n" + "3AgOTrwnbmdrjEiF+2UVreTSHoBnVyMfGhAKZ1a0OQKBgQDZoANU/8jQZBSS4tdL\n" + "z5RIBa0pQEvV3mrB4n7rMvSytiYkCTHdD8HUT5PRSSF0fbqF6E3c7Fpq/4wP+Fhv\n" + "32+qJR/Y6uW6dMOwWMGAH5NV0+rvHaqCKRVugSvPx2DzZ7pJ0rEpfdCagc8mfIub\n" + "f0UBlnp13QVeNEfDPhJdk7HZ7QKBgQDK0z4ljFBNpRImdgn5gssR72697cSZim8E\n" + "F/wJinn9dHdCgUB/2hcpB4y2yzomHJAYZVI+I4jT0DryRi0NnlRDljkUXaC4dvlR\n" + "RboB8sPYBJ6GrtlAxBxFXYnzsIE3Xqozgt9LNQELhhKJNKSz4qG4AR4fGhwblaY5\n" + "ycTYXWaJXwKBgARXD5nzW/Lj/BEN2xNU+XUSP+jRsnF6dRCWzscsBftGbK5NTKRG\n" + "+yubxqvm1Hb5Ru4CuwLL5+W4YPe0kTbx8s0m3mK6FIjKaVir/HfsqUiN6GKKaesc\n" + "nKPOiawkIsfX6rwsKoJUUwOx0QrIcxRPznWApcKR/NhrHH9FTqJ1HpflAoGANp1B\n" + "G703lmC/jWm1b+E/Kxos2KmgibOUBycqL6uBA7WLs3W4V3TzTZIB2urIQqDoUBlg\n" + "Vukcm+RzKu+ojAU5LWXTAt/fOiyXH8JFvuaOw6kiwqNsTps//ZGdZuf9M1qjO/Ge\n" + "jNK98EtuzFFHlESPRUvPv5I5RVg7hU4GWjh0NsMCgYAqVoB5x4+ugae+eZgSLfwG\n" + "YWSOiHQhEqqLWAp3MHbuwDVNnpy1KNWh7A/f8Hd3xgPKQIGCl74dBQ+6pv08Dxyt\n" + "az+aNXi/CmaEb3v6abaKdF7uNJCpKUnYJ3lpLrrd9HsLbhszIhs1iPbJK38SDEm0\n" + "xgbwpLAv3YW+usS9x8LAPw==\n" + "-----END PRIVATE KEY-----".encode("UTF-8") + ) + + def __init__(self, sub: str = "uss_unsigned"): + super().__init__() + self.sub = sub + + def issue_token(self, intended_audience: str, scopes: List[str]) -> str: + timestamp = int((datetime.datetime.utcnow() - _UNIX_EPOCH).total_seconds()) + claims = { + "sub": self.sub, + "client_id": self.sub, + "scope": " ".join(scopes), + "aud": intended_audience, + "nbf": timestamp - 1, + "exp": timestamp + NoAuth.EXPIRATION, + "iss": "NoAuth", + "jti": str(uuid.uuid4()), + } + jwt = jwcrypto.jwt.JWT( + header={"typ": "JWT", "alg": "RS256"}, + claims=claims, + algs=["RS256"], + ) + jwt.make_signed_token(InvalidTokenSignatureAuth.unknown_private_key) + return jwt.serialize() + + class DummyOAuth(AuthAdapter): """Auth adapter that gets JWTs that uses the Dummy OAuth Server""" @@ -490,7 +555,6 @@ def __init__( client_secret: str, send_request_as_data: str = "true", ): - send_request_as_data = send_request_as_data.lower() == "true" super(FlightPassport, self).__init__( diff --git a/monitoring/prober/infrastructure.py b/monitoring/prober/infrastructure.py index f90115ff5b..5a5f145965 100644 --- a/monitoring/prober/infrastructure.py +++ b/monitoring/prober/infrastructure.py @@ -100,7 +100,7 @@ def wrapper_default_scope(*args, **kwargs): resource_type_code_descriptions: Dict[ResourceType, str] = {} -# Next code: 372 +# Next code: 373 def register_resource_type(code: int, description: str) -> ResourceType: """Register that the specified code refers to the described resource. diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/common/dss/token_validation.py b/monitoring/uss_qualifier/scenarios/astm/netrid/common/dss/token_validation.py new file mode 100644 index 0000000000..75cfd5dc88 --- /dev/null +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/common/dss/token_validation.py @@ -0,0 +1,594 @@ +from typing import Optional, Dict + +import arrow +from uas_standards.astm.f3411 import v19, v22a + +from monitoring.monitorlib import fetch, infrastructure +from monitoring.monitorlib import rid_v1, rid_v2 +from monitoring.monitorlib.auth import InvalidTokenSignatureAuth +from monitoring.monitorlib.fetch import rid as rid_fetch +from monitoring.monitorlib.fetch.rid import FetchedISA +from monitoring.monitorlib.mutate import rid as mutate +from monitoring.monitorlib.mutate.rid import ( + ISAChange, + ChangedISA, + ISAChangeNotification, +) +from monitoring.monitorlib.rid import RIDVersion +from monitoring.prober.infrastructure import register_resource_type +from monitoring.uss_qualifier.common_data_definitions import Severity +from monitoring.uss_qualifier.resources.astm.f3411.dss import DSSInstanceResource +from monitoring.uss_qualifier.resources.interuss.id_generator import IDGeneratorResource +from monitoring.uss_qualifier.resources.netrid.service_area import ServiceAreaResource +from monitoring.uss_qualifier.scenarios.astm.netrid.common.dss.isa_simple import ( + ISASimple, +) +from monitoring.uss_qualifier.scenarios.astm.netrid.dss_wrapper import DSSWrapper +from monitoring.uss_qualifier.scenarios.scenario import GenericTestScenario +from monitoring.uss_qualifier.suites.suite import ExecutionContext + + +class TokenValidation(GenericTestScenario): + """Based on prober/rid/v2/test_token_validation.py from the legacy prober tool.""" + + ISA_TYPE = register_resource_type(372, "ISA") + + def __init__( + self, + dss: DSSInstanceResource, + id_generator: IDGeneratorResource, + isa: ServiceAreaResource, + ): + super().__init__() + self._dss = dss.dss_instance + self._dss_wrapper = DSSWrapper(self, dss.dss_instance) + self._isa_id = id_generator.id_factory.make_id(ISASimple.ISA_TYPE) + self._isa_version: Optional[str] = None + self._isa = isa.specification + + now = arrow.utcnow().datetime + self._isa_start_time = self._isa.shifted_time_start(now) + self._isa_end_time = self._isa.shifted_time_end(now) + self._isa_area = [vertex.as_s2sphere() for vertex in self._isa.footprint] + + # correctly formed and signed using an unrecognized private key + # (should cause requests to be rejected) + self._unsigned_token_session = infrastructure.UTMClientSession( + self._dss.base_url, InvalidTokenSignatureAuth() + ) + # Session that won't provide a token at all + # (should cause requests to be rejected) + self._no_token_session = infrastructure.UTMClientSession( + self._dss.base_url, None + ) + + def run(self, context: ExecutionContext): + self.begin_test_scenario(context) + + self.begin_test_case("Setup") + self.begin_test_step("Ensure clean workspace") + self._delete_isa_if_exists() + self.end_test_step() + self.end_test_case() + + self.begin_test_case("Token validation") + self.begin_test_step("Token validation") + + self._wrong_auth_put() + self._create_isa() + self._wrong_auth_get() + self._wrong_auth_mutate() + self._wrong_auth_delete() + self._delete_isa() + + # TODO to potentially be added in a subsequent PR: testing the search endpoint too + + self.end_test_step() + self.end_test_case() + + self.end_test_scenario() + + def _wrong_auth_put(self): + # Try to create an ISA with a read scope + put_wrong_scope = self._put_isa_tweak_auth( + utm_client=self._dss.client, + scope_intent="read", + ) + with self.check( + "Read scope cannot create an ISA", participants=[self._dss.participant_id] + ) as check: + if put_wrong_scope.dss_query.success: + check.record_failed( + "Read scope can create ISA", + Severity.High, + f"Attempting to create ISA {self._isa_id} with read scope returned {put_wrong_scope.dss_query.status_code}", + query_timestamps=[ + put_wrong_scope.dss_query.query.request.timestamp + ], + ) + + # Try to create an ISA with a missing token + put_no_token = self._put_isa_tweak_auth( + utm_client=self._no_token_session, + scope_intent="write", + ) + + with self.check( + "Missing token prevents creating an ISA", + participants=[self._dss.participant_id], + ) as check: + if put_no_token.dss_query.success: + check.record_failed( + "Could create an ISA without a token", + Severity.High, + f"Attempting to create ISA {self._isa_id} with no token returned {put_no_token.dss_query.status_code}", + query_timestamps=[put_no_token.dss_query.query.request.timestamp], + ) + + # Try to create an ISA with a fake token + put_fake_token = self._put_isa_tweak_auth( + utm_client=self._unsigned_token_session, + scope_intent="write", + ) + + with self.check( + "Fake token prevents creating an ISA", + participants=[self._dss.participant_id], + ) as check: + if put_fake_token.dss_query.success: + check.record_failed( + "Could create an ISA with a fake token", + Severity.High, + f"Attempting to create ISA {self._isa_id} with a fake token returned {put_fake_token.dss_query.status_code}", + query_timestamps=[put_fake_token.dss_query.query.request.timestamp], + ) + + def _create_isa(self): + with self.check( + "Correct token and scope can create ISA", [self._dss_wrapper.participant_id] + ) as check: + new_isa = self._dss_wrapper.put_isa( + main_check=check, + area_vertices=self._isa_area, + start_time=self._isa_start_time, + end_time=self._isa_end_time, + uss_base_url=self._isa.base_url, + isa_id=self._isa_id, + isa_version=self._isa_version, + alt_lo=self._isa.altitude_min, + alt_hi=self._isa.altitude_max, + ) + self._isa_version = new_isa.dss_query.isa.version + + def _wrong_auth_get(self): + + get_no_token = self._get_isa_tweak_auth(self._no_token_session) + with self.check( + "Missing token prevents reading an ISA", + participants=[self._dss.participant_id], + ) as check: + if get_no_token.success: + check.record_failed( + "Could read an ISA without a token", + Severity.High, + f"Attempting to read ISA {self._isa_id} with no token returned {get_no_token.status_code}", + query_timestamps=[get_no_token.query.request.timestamp], + ) + + get_fake_token = self._get_isa_tweak_auth(self._unsigned_token_session) + with self.check( + "Fake token prevents reading an ISA", + participants=[self._dss.participant_id], + ) as check: + if get_fake_token.success: + check.record_failed( + "Could read an ISA with a fake token", + Severity.High, + f"Attempting to read ISA {self._isa_id} with a fake token returned {get_fake_token.status_code}", + query_timestamps=[get_fake_token.query.request.timestamp], + ) + + def _wrong_auth_mutate(self): + # Try to mutate an ISA with a read scope + mutate_wrong_scope = self._put_isa_tweak_auth( + utm_client=self._dss.client, + scope_intent="read", + isa_version=self._isa_version, + ) + with self.check( + "Read scope cannot mutate an ISA", participants=[self._dss.participant_id] + ) as check: + if mutate_wrong_scope.dss_query.success: + check.record_failed( + "Read scope can mutate an ISA", + Severity.High, + f"Attempting to create ISA {self._isa_id} with read scope returned {mutate_wrong_scope.dss_query.status_code}", + query_timestamps=[ + mutate_wrong_scope.dss_query.query.request.timestamp + ], + ) + + # Try to create an ISA with a missing token + mutate_no_token = self._put_isa_tweak_auth( + utm_client=self._no_token_session, + scope_intent="write", + ) + with self.check( + "Missing token prevents mutating an ISA", + participants=[self._dss.participant_id], + ) as check: + if mutate_no_token.dss_query.success: + check.record_failed( + "Could mutate an ISA without a token", + Severity.High, + f"Attempting to create ISA {self._isa_id} with no token returned {mutate_no_token.dss_query.status_code}", + query_timestamps=[ + mutate_no_token.dss_query.query.request.timestamp + ], + ) + + # Try to mutate an ISA with a fake token + mutate_fake_token = self._put_isa_tweak_auth( + utm_client=self._unsigned_token_session, + scope_intent="write", + ) + with self.check( + "Fake token cannot mutate an ISA", + participants=[self._dss.participant_id], + ) as check: + if mutate_fake_token.dss_query.success: + check.record_failed( + "Could mutate an ISA with a fake token", + Severity.High, + f"Attempting to create ISA {self._isa_id} with a fake token returned {mutate_fake_token.dss_query.status_code}", + query_timestamps=[ + mutate_fake_token.dss_query.query.request.timestamp + ], + ) + + def _wrong_auth_delete(self): + # Try to delete an ISA with a read scope + del_wrong_scope = self._del_isa_tweak_auth( + utm_client=self._dss.client, scope_intent="read" + ) + with self.check( + "Read scope cannot delete an ISA", participants=[self._dss.participant_id] + ) as check: + if del_wrong_scope.dss_query.success: + check.record_failed( + "Read scope can delete an ISA", + Severity.High, + f"Attempting to delete ISA {self._isa_id} with read scope returned {del_wrong_scope.dss_query.status_code}", + query_timestamps=[ + del_wrong_scope.dss_query.query.request.timestamp + ], + ) + + if del_wrong_scope.dss_query.success: + self._verify_notifications(del_wrong_scope.notifications) + + # Try to delete an ISA with a missing token + del_no_token = self._del_isa_tweak_auth( + utm_client=self._no_token_session, + scope_intent="write", + ) + with self.check( + "Missing token prevents ISA deletion", + participants=[self._dss.participant_id], + ) as check: + if del_no_token.dss_query.success: + check.record_failed( + "Could mutate an ISA without a token", + Severity.High, + f"Attempting to create ISA {self._isa_id} with no token returned {del_no_token.dss_query.status_code}", + query_timestamps=[del_no_token.dss_query.query.request.timestamp], + ) + + if del_no_token.dss_query.success: + self._verify_notifications(del_no_token.notifications) + + # Try to delete an ISA with a fake token + del_fake_token = self._del_isa_tweak_auth( + utm_client=self._unsigned_token_session, + scope_intent="write", + ) + with self.check( + "Fake token cannot delete an ISA", + participants=[self._dss.participant_id], + ) as check: + if del_fake_token.dss_query.success: + check.record_failed( + "Could delete an ISA with a fake token", + Severity.High, + f"Attempting to create ISA {self._isa_id} with a fake token returned {del_fake_token.dss_query.status_code}", + query_timestamps=[del_fake_token.dss_query.query.request.timestamp], + ) + + def _delete_isa(self): + del_isa_ok = self._del_isa_tweak_auth(self._dss.client, scope_intent="write") + with self.check( + "Correct token and scope can delete ISA", + participants=[self._dss.participant_id], + ) as check: + if not del_isa_ok.dss_query.success: + check.record_failed( + "Could not delete ISA with valid credentials", + Severity.High, + f"Attempting to delete ISA {self._isa_id} returned {del_isa_ok.dss_query.status_code}", + query_timestamps=[del_isa_ok.dss_query.query.request.timestamp], + ) + + self._verify_notifications(del_isa_ok.notifications) + + def _delete_isa_if_exists(self): + fetched = rid_fetch.isa( + self._isa_id, + rid_version=self._dss.rid_version, + session=self._dss.client, + participant_id=self._dss.participant_id, + ) + with self.check("Successful ISA query", [self._dss.participant_id]) as check: + self.record_query(fetched.query) + if not fetched.success and fetched.status_code != 404: + check.record_failed( + "ISA information could not be retrieved", + Severity.High, + f"{self._dss.participant_id} DSS instance returned {fetched.status_code} when queried for ISA {self._isa_id}", + query_timestamps=[fetched.query.request.timestamp], + ) + + if fetched.success: + deleted = mutate.delete_isa( + self._isa_id, + fetched.isa.version, + self._dss.rid_version, + self._dss.client, + participant_id=self._dss.participant_id, + ) + self.record_query(deleted.dss_query.query) + for subscriber_id, notification in deleted.notifications.items(): + self.record_query(notification.query) + with self.check( + "Removed pre-existing ISA", [self._dss.participant_id] + ) as check: + if not deleted.dss_query.success: + check.record_failed( + "Could not delete pre-existing ISA", + Severity.High, + f"Attempting to delete ISA {self._isa_id} from the {self._dss.participant_id} DSS returned error {deleted.dss_query.status_code}", + query_timestamps=[deleted.dss_query.query.request.timestamp], + ) + self._verify_notifications(deleted.notifications) + + def _verify_notifications(self, notifications: Dict[str, ISAChangeNotification]): + for subscriber_url, notification in notifications.items(): + pid = ( + notification.query.participant_id + if "participant_id" in notification.query + else None + ) + with self.check("Notified subscriber", [pid] if pid else []) as check: + if not notification.success: + check.record_failed( + "Could not notify ISA subscriber", + Severity.Medium, + f"Attempting to notify subscriber for ISA {self._isa_id} at {subscriber_url} resulted in {notification.status_code}", + query_timestamps=[notification.query.request.timestamp], + ) + + def _put_isa_tweak_auth( + self, + utm_client: infrastructure.UTMClientSession, + isa_version: Optional[str] = None, + scope_intent: str = "read", + ) -> ISAChange: + """A local version of mutate.rid.put_isa that lets us control authentication parameters""" + mutation = "create" if isa_version is None else "update" + + query_scope = self._query_scope_for_auth_params(utm_client, scope_intent) + + if self._dss.rid_version == RIDVersion.f3411_19: + body = { + "extents": rid_v1.make_volume_4d( + self._isa_area, + self._isa.altitude_min, + self._isa.altitude_max, + self._isa_start_time, + self._isa_end_time, + ), + "flights_url": self._isa.base_url + + v19.api.OPERATIONS[v19.api.OperationID.SearchFlights].path, + } + if isa_version is None: + op = v19.api.OPERATIONS[ + v19.api.OperationID.CreateIdentificationServiceArea + ] + url = op.path.format(id=self._isa_id) + else: + op = v19.api.OPERATIONS[ + v19.api.OperationID.UpdateIdentificationServiceArea + ] + url = op.path.format(id=self._isa_id, version=isa_version) + dss_response = ChangedISA( + mutation=mutation, + v19_query=fetch.query_and_describe( + utm_client, + op.verb, + url, + json=body, + participant_id=self._dss.participant_id, + **({} if query_scope is None else {"scope": query_scope}), + ), + ) + elif self._dss.rid_version == RIDVersion.f3411_22a: + body = { + "extents": rid_v2.make_volume_4d( + self._isa_area, + self._isa.altitude_min, + self._isa.altitude_max, + self._isa_start_time, + self._isa_end_time, + ), + "uss_base_url": self._isa.base_url, + } + if isa_version is None: + op = v22a.api.OPERATIONS[ + v22a.api.OperationID.CreateIdentificationServiceArea + ] + url = op.path.format(id=self._isa_id) + else: + op = v22a.api.OPERATIONS[ + v22a.api.OperationID.UpdateIdentificationServiceArea + ] + url = op.path.format(id=self._isa_id, version=isa_version) + dss_response = ChangedISA( + mutation=mutation, + v22a_query=fetch.query_and_describe( + utm_client, + op.verb, + url, + json=body, + participant_id=self._dss.participant_id, + **({} if query_scope is None else {"scope": query_scope}), + ), + ) + + if dss_response.success: + isa = dss_response.isa + notifications = { + sub.url: sub.notify(isa.id, utm_client, isa) + for sub in dss_response.subscribers + } + else: + notifications = {} + + self.record_query(dss_response.query) + + return ISAChange(dss_query=dss_response, notifications=notifications) + + def _get_isa_tweak_auth(self, utm_client: infrastructure.UTMClientSession): + """A local version of fetch.rid.isa that lets us control authentication parameters""" + if self._dss.rid_version == RIDVersion.f3411_19: + op = v19.api.OPERATIONS[v19.api.OperationID.GetIdentificationServiceArea] + url = f"{self._dss.base_url}{op.path}".replace("{id}", self._isa_id) + return FetchedISA( + v19_query=fetch.query_and_describe( + utm_client, + op.verb, + url, + participant_id=self._dss.participant_id, + **( + {} + if utm_client.auth_adapter is None + else {"scope": v19.constants.Scope.Read} + ), + ) + ) + elif self._dss.rid_version == RIDVersion.f3411_22a: + op = v22a.api.OPERATIONS[v22a.api.OperationID.GetIdentificationServiceArea] + url = f"{self._dss.base_url}{op.path}".replace("{id}", self._isa_id) + return FetchedISA( + v22a_query=fetch.query_and_describe( + utm_client, + op.verb, + url, + participant_id=self._dss.participant_id, + **( + {} + if utm_client.auth_adapter is None + else {"scope": v22a.constants.Scope.DisplayProvider} + ), + ) + ) + + else: + raise NotImplementedError( + f"Cannot query DSS for ISA using RID version {self._dss.rid_version}" + ) + + def _del_isa_tweak_auth( + self, + utm_client: infrastructure.UTMClientSession, + scope_intent: str = "read", + ) -> ISAChange: + """A local version of mutate.rid.delete_isa that lets us control authentication parameters""" + query_scope = self._query_scope_for_auth_params(utm_client, scope_intent) + + if self._dss.rid_version == RIDVersion.f3411_19: + op = v19.api.OPERATIONS[v19.api.OperationID.DeleteIdentificationServiceArea] + url = op.path.format(id=self._isa_id, version=self._isa_version) + dss_response = ChangedISA( + mutation="delete", + v19_query=fetch.query_and_describe( + utm_client, + op.verb, + url, + participant_id=self._dss.participant_id, + **({} if query_scope is None else {"scope": query_scope}), + ), + ) + elif self._dss.rid_version == RIDVersion.f3411_22a: + op = v22a.api.OPERATIONS[ + v22a.api.OperationID.DeleteIdentificationServiceArea + ] + url = op.path.format(id=self._isa_id, version=self._isa_version) + dss_response = ChangedISA( + mutation="delete", + v22a_query=fetch.query_and_describe( + utm_client, + op.verb, + url, + participant_id=self._dss.participant_id, + **({} if query_scope is None else {"scope": query_scope}), + ), + ) + else: + raise NotImplementedError( + f"Cannot delete ISA using RID version {self._dss.rid_version}" + ) + + if dss_response.success: + isa = dss_response.isa + notifications = { + sub.url: sub.notify(isa.id, utm_client) + for sub in dss_response.subscribers + } + else: + notifications = {} + + self.record_query(dss_response.query) + for notification_query in notifications.values(): + self.record_query(notification_query.query) + + return ISAChange(dss_query=dss_response, notifications=notifications) + + def _query_scope_for_auth_params( + self, utm_client: infrastructure.UTMClientSession, scope_intent: str + ) -> Optional[str]: + + if utm_client.auth_adapter is not None: + if self._dss.rid_version == RIDVersion.f3411_19: + if scope_intent == "read": + return v19.constants.Scope.Read + else: + return v19.constants.Scope.Write + elif self._dss.rid_version == RIDVersion.f3411_22a: + # There does not seem to be an explicit 'read' or 'write' scope in v22a, + # TODO confirm that we can consider the display provider scope as a 'read only scope' + if scope_intent == "read": + return v22a.constants.Scope.DisplayProvider + else: + return v22a.constants.Scope.ServiceProvider + else: + raise NotImplementedError( + f"Cannot upsert ISA using RID version {self._dss.rid_version}" + ) + + return None + + def cleanup(self): + self.begin_cleanup() + + self._delete_isa_if_exists() + + self.end_cleanup() diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/v19/dss/__init__.py b/monitoring/uss_qualifier/scenarios/astm/netrid/v19/dss/__init__.py index 60c13cf6d2..aed0f85b9d 100644 --- a/monitoring/uss_qualifier/scenarios/astm/netrid/v19/dss/__init__.py +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/v19/dss/__init__.py @@ -4,4 +4,5 @@ from .isa_subscription_interactions import ISASubscriptionInteractions from .subscription_validation import SubscriptionValidation from .subscription_simple import SubscriptionSimple +from .token_validation import TokenValidation from .crdb_access import CRDBAccess diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/v19/dss/token_validation.md b/monitoring/uss_qualifier/scenarios/astm/netrid/v19/dss/token_validation.md new file mode 100644 index 0000000000..f8af0ef184 --- /dev/null +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/v19/dss/token_validation.md @@ -0,0 +1,120 @@ +# ASTM NetRID DSS: Token Validation test scenario + +## Overview + +Checks that the DSS properly validates the provided client token on all its endpoints. + +## Resources + +### dss + +[`DSSInstanceResource`](../../../../../resources/astm/f3411/dss.py) to be tested in this scenario. + +### id_generator + +[`IDGeneratorResource`](../../../../../resources/interuss/id_generator.py) providing the ISA ID for this scenario. + +### isa + +[`ServiceAreaResource`](../../../../../resources/netrid/service_area.py) describing an ISA to be created. + +## Setup test case + +### Ensure clean workspace test step + +This scenario creates an ISA with a known ID. This step ensures that ISA does not exist before the start of the main +part of the test. + +#### Successful ISA query check + +While F3411-19 does not explicitly require the implementation of a specific ISA retrieval endpoint, Annex A4 specifies the explicit format for this endpoint. If this format is not followed and the error isn't a 404, this check will fail per **[interuss.f3411.dss_endpoints.GetISA](../../../../../requirements/interuss/f3411/dss_endpoints.md)**. + +#### Removed pre-existing ISA check + +If an ISA with the intended ID is already present in the DSS, it needs to be removed before proceeding with the test. If that ISA cannot be deleted, then the **[astm.f3411.v19.DSS0030,b](../../../../../requirements/astm/f3411/v19.md)** requirement to implement the ISA deletion endpoint might not be met. + +#### Notified subscriber check + +When a pre-existing ISA needs to be deleted to ensure a clean workspace, any subscribers to ISAs in that area must be notified (as specified by the DSS). If a notification cannot be delivered, then the **[astm.f3411.v19.NET0730](../../../../../requirements/astm/f3411/v19.md)** requirement to implement the POST ISAs endpoint isn't met. + +## Token validation test case + +### [Token validation test step](test_steps/put_isa.md) + +This step attempts to create and read ISAs by providing both the correct and incorrect scopes, omitting the token or providing an invalid one, +and expects the DSS to properly behave in each case. + +#### Read scope cannot create an ISA check + +If an ISA can be created with a scope that does not provide write permission, the DSS is in violation of **[astm.f3411.v19.DSS0030,a](../../../../../requirements/astm/f3411/v19.md)**. + +#### Missing token prevents creating an ISA check + +If an ISA can be created without a token being present in the request, the DSS is in violation of **[astm.f3411.v19.DSS0030,a](../../../../../requirements/astm/f3411/v19.md)**. + +#### Fake token prevents creating an ISA check + +If an ISA can be created with an incorrect token in the request, the DSS is in violation of **[astm.f3411.v19.DSS0030,a](../../../../../requirements/astm/f3411/v19.md)**. + +#### Correct token and scope can create ISA check + +If the ISA cannot be created when the proper credentials are presented, +the PUT DSS endpoint in **[astm.f3411.v19.DSS0030,a](../../../../../requirements/astm/f3411/v19.md)** is likely not implemented correctly. + +#### Missing token prevents reading an ISA check + +If the ISA that was created can be accessed without a token being present in the request, +the DSS is in violation of **[interuss.f3411.dss_endpoints.GetISA](../../../../../requirements/interuss/f3411/dss_endpoints.md)** + +#### Fake token prevents reading an ISA check + +If the ISA that was created can be accessed using a token with an invalid signature, +the DSS is in violation of **[interuss.f3411.dss_endpoints.GetISA](../../../../../requirements/interuss/f3411/dss_endpoints.md)** + +#### Read scope cannot mutate an ISA check + +If the existing ISA can be mutated by using a read-only scope, the DSS is in violation of **[astm.f3411.v19.DSS0030,a](../../../../../requirements/astm/f3411/v19.md)** + +#### Missing token prevents mutating an ISA check + +If the existing ISA can be mutated without a token being provided, the DSS is in violation of **[astm.f3411.v19.DSS0030,a](../../../../../requirements/astm/f3411/v19.md)** + +#### Fake token cannot mutate an ISA check + +If the existing ISA can be mutated by using an invalid token, the DSS is in violation of **[astm.f3411.v19.DSS0030,a](../../../../../requirements/astm/f3411/v19.md)** + +#### Read scope cannot delete an ISA check + +If the existing ISA can be deleted by using a read-only scope, the DSS is in violation of **[astm.f3411.v19.DSS0030,b](../../../../../requirements/astm/f3411/v19.md)** + +#### Missing token prevents ISA deletion check + +If the existing ISA can be deleted without a token being provided, the DSS is in violation of **[astm.f3411.v19.DSS0030,b](../../../../../requirements/astm/f3411/v19.md)** + +#### Fake token cannot delete an ISA check + +If the existing ISA can be deleted by using an invalid token, the DSS is in violation of **[astm.f3411.v19.DSS0030,b](../../../../../requirements/astm/f3411/v19.md)** + +#### Correct token and scope can delete ISA check + +If the existing ISA cannot be deleted when the proper credentials are presented, the DSS is in violation of **[astm.f3411.v19.DSS0030,b](../../../../../requirements/astm/f3411/v19.md)** + +#### Notified subscriber check + +When an ISA is deleted, subscribers must be notified. If a subscriber cannot be notified, that subscriber USS did not correctly implement "POST Identification Service Area" in **[astm.f3411.v19.NET0730](../../../../../requirements/astm/f3411/v19.md)**. + +## Cleanup + +The cleanup phase of this test scenario attempts to remove the ISA if the test ended prematurely. + +### Successful ISA query check + +**[interuss.f3411.dss_endpoints.GetISA](../../../../../requirements/interuss/f3411/dss_endpoints.md)** requires the implementation of the DSS endpoint enabling retrieval of information about a specific ISA; if the individual ISA cannot be retrieved and the error isn't a 404, then this requirement isn't met. + +### Removed pre-existing ISA check + +If an ISA with the intended ID is still present in the DSS, it needs to be removed before exiting the test. If that ISA cannot be deleted, then the **[astm.f3411.v19.DSS0030,b](../../../../../requirements/astm/f3411/v19.md)** requirement to implement the ISA deletion endpoint might not be met. + +### Notified subscriber check + +When an ISA is deleted, subscribers must be notified. If a subscriber cannot be notified, that subscriber USS did not correctly implement "POST Identification Service Area" in **[astm.f3411.v19.NET0730](../../../../../requirements/astm/f3411/v19.md)**. diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/v19/dss/token_validation.py b/monitoring/uss_qualifier/scenarios/astm/netrid/v19/dss/token_validation.py new file mode 100644 index 0000000000..84392ebbde --- /dev/null +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/v19/dss/token_validation.py @@ -0,0 +1,8 @@ +from monitoring.uss_qualifier.scenarios.astm.netrid.common.dss.token_validation import ( + TokenValidation as CommonTokenValidation, +) +from monitoring.uss_qualifier.scenarios.scenario import TestScenario + + +class TokenValidation(TestScenario, CommonTokenValidation): + pass diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/v22a/dss/__init__.py b/monitoring/uss_qualifier/scenarios/astm/netrid/v22a/dss/__init__.py index 60c13cf6d2..aed0f85b9d 100644 --- a/monitoring/uss_qualifier/scenarios/astm/netrid/v22a/dss/__init__.py +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/v22a/dss/__init__.py @@ -4,4 +4,5 @@ from .isa_subscription_interactions import ISASubscriptionInteractions from .subscription_validation import SubscriptionValidation from .subscription_simple import SubscriptionSimple +from .token_validation import TokenValidation from .crdb_access import CRDBAccess diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/v22a/dss/token_validation.md b/monitoring/uss_qualifier/scenarios/astm/netrid/v22a/dss/token_validation.md new file mode 100644 index 0000000000..7bf9e15a98 --- /dev/null +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/v22a/dss/token_validation.md @@ -0,0 +1,120 @@ +# ASTM NetRID DSS: Token Validation test scenario + +## Overview + +Checks that the DSS properly validates the provided client token on all its endpoints. + +## Resources + +### dss + +[`DSSInstanceResource`](../../../../../resources/astm/f3411/dss.py) to be tested in this scenario. + +### id_generator + +[`IDGeneratorResource`](../../../../../resources/interuss/id_generator.py) providing the ISA ID for this scenario. + +### isa + +[`ServiceAreaResource`](../../../../../resources/netrid/service_area.py) describing an ISA to be created. + +## Setup test case + +### Ensure clean workspace test step + +This scenario creates an ISA with a known ID. This step ensures that ISA does not exist before the start of the main +part of the test. + +#### Successful ISA query check + +While F3411-19 does not explicitly require the implementation of a specific ISA retrieval endpoint, Annex A4 specifies the explicit format for this endpoint. If this format is not followed and the error isn't a 404, this check will fail per **[interuss.f3411.dss_endpoints.GetISA](../../../../../requirements/interuss/f3411/dss_endpoints.md)**. + +#### Removed pre-existing ISA check + +If an ISA with the intended ID is already present in the DSS, it needs to be removed before proceeding with the test. If that ISA cannot be deleted, then the **[astm.f3411.v22a.DSS0030,b](../../../../../requirements/astm/f3411/v22a.md)** requirement to implement the ISA deletion endpoint might not be met. + +#### Notified subscriber check + +When a pre-existing ISA needs to be deleted to ensure a clean workspace, any subscribers to ISAs in that area must be notified (as specified by the DSS). If a notification cannot be delivered, then the **[astm.f3411.v22a.NET0730](../../../../../requirements/astm/f3411/v22a.md)** requirement to implement the POST ISAs endpoint isn't met. + +## Token validation test case + +### [Token validation test step](test_steps/put_isa.md) + +This step attempts to create and read ISAs by providing both the correct and incorrect scopes, omitting the token or providing an invalid one, +and expects the DSS to properly behave in each case. + +#### Read scope cannot create an ISA check + +If an ISA can be created with a scope that does not provide write permission, the DSS is in violation of **[astm.f3411.v22a.DSS0030,a](../../../../../requirements/astm/f3411/v22a.md)**. + +#### Missing token prevents creating an ISA check + +If an ISA can be created without a token being present in the request, the DSS is in violation of **[astm.f3411.v22a.DSS0030,a](../../../../../requirements/astm/f3411/v22a.md)**. + +#### Fake token prevents creating an ISA check + +If an ISA can be created with an incorrect token in the request, the DSS is in violation of **[astm.f3411.v22a.DSS0030,a](../../../../../requirements/astm/f3411/v22a.md)**. + +#### Correct token and scope can create ISA check + +If the ISA cannot be created when the proper credentials are presented, +the PUT DSS endpoint in **[astm.f3411.v22a.DSS0030,a](../../../../../requirements/astm/f3411/v22a.md)** is likely not implemented correctly. + +#### Missing token prevents reading an ISA check + +If the ISA that was created can be accessed without a token being present in the request, +the DSS is in violation of **[interuss.f3411.dss_endpoints.GetISA](../../../../../requirements/interuss/f3411/dss_endpoints.md)** + +#### Fake token prevents reading an ISA check + +If the ISA that was created can be accessed using a token with an invalid signature, +the DSS is in violation of **[interuss.f3411.dss_endpoints.GetISA](../../../../../requirements/interuss/f3411/dss_endpoints.md)** + +#### Read scope cannot mutate an ISA check + +If the existing ISA can be mutated by using a read-only scope, the DSS is in violation of **[astm.f3411.v22a.DSS0030,a](../../../../../requirements/astm/f3411/v22a.md)** + +#### Missing token prevents mutating an ISA check + +If the existing ISA can be mutated without a token being provided, the DSS is in violation of **[astm.f3411.v22a.DSS0030,a](../../../../../requirements/astm/f3411/v22a.md)** + +#### Fake token cannot mutate an ISA check + +If the existing ISA can be mutated by using an invalid token, the DSS is in violation of **[astm.f3411.v22a.DSS0030,a](../../../../../requirements/astm/f3411/v22a.md)** + +#### Read scope cannot delete an ISA check + +If the existing ISA can be deleted by using a read-only scope, the DSS is in violation of **[astm.f3411.v22a.DSS0030,b](../../../../../requirements/astm/f3411/v22a.md)** + +#### Missing token prevents ISA deletion check + +If the existing ISA can be deleted without a token being provided, the DSS is in violation of **[astm.f3411.v22a.DSS0030,b](../../../../../requirements/astm/f3411/v22a.md)** + +#### Fake token cannot delete an ISA check + +If the existing ISA can be deleted by using an invalid token, the DSS is in violation of **[astm.f3411.v22a.DSS0030,b](../../../../../requirements/astm/f3411/v22a.md)** + +#### Correct token and scope can delete ISA check + +If the existing ISA cannot be deleted when the proper credentials are presented, the DSS is in violation of **[astm.f3411.v22a.DSS0030,b](../../../../../requirements/astm/f3411/v22a.md)** + +#### Notified subscriber check + +When an ISA is deleted, subscribers must be notified. If a subscriber cannot be notified, that subscriber USS did not correctly implement "POST Identification Service Area" in **[astm.f3411.v22a.NET0730](../../../../../requirements/astm/f3411/v22a.md)**. + +## Cleanup + +The cleanup phase of this test scenario attempts to remove the ISA if the test ended prematurely. + +### Successful ISA query check + +**[interuss.f3411.dss_endpoints.GetISA](../../../../../requirements/interuss/f3411/dss_endpoints.md)** requires the implementation of the DSS endpoint enabling retrieval of information about a specific ISA; if the individual ISA cannot be retrieved and the error isn't a 404, then this requirement isn't met. + +### Removed pre-existing ISA check + +If an ISA with the intended ID is still present in the DSS, it needs to be removed before exiting the test. If that ISA cannot be deleted, then the **[astm.f3411.v22a.DSS0030,b](../../../../../requirements/astm/f3411/v22a.md)** requirement to implement the ISA deletion endpoint might not be met. + +### Notified subscriber check + +When an ISA is deleted, subscribers must be notified. If a subscriber cannot be notified, that subscriber USS did not correctly implement "POST Identification Service Area" in **[astm.f3411.v22a.NET0730](../../../../../requirements/astm/f3411/v22a.md)**. diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/v22a/dss/token_validation.py b/monitoring/uss_qualifier/scenarios/astm/netrid/v22a/dss/token_validation.py new file mode 100644 index 0000000000..84392ebbde --- /dev/null +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/v22a/dss/token_validation.py @@ -0,0 +1,8 @@ +from monitoring.uss_qualifier.scenarios.astm.netrid.common.dss.token_validation import ( + TokenValidation as CommonTokenValidation, +) +from monitoring.uss_qualifier.scenarios.scenario import TestScenario + + +class TokenValidation(TestScenario, CommonTokenValidation): + pass diff --git a/monitoring/uss_qualifier/suites/astm/netrid/f3411_19.md b/monitoring/uss_qualifier/suites/astm/netrid/f3411_19.md index c1e8dcb13d..7c6f4a358d 100644 --- a/monitoring/uss_qualifier/suites/astm/netrid/f3411_19.md +++ b/monitoring/uss_qualifier/suites/astm/netrid/f3411_19.md @@ -24,12 +24,12 @@ astm
.f3411
.v19
DSS0030,a Implemented - ASTM F3411-19 NetRID DSS interoperability
ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations + ASTM F3411-19 NetRID DSS interoperability
ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations
ASTM NetRID DSS: Token Validation DSS0030,b Implemented - ASTM F3411-19 NetRID DSS interoperability
ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations + ASTM F3411-19 NetRID DSS interoperability
ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations
ASTM NetRID DSS: Token Validation DSS0030,c @@ -329,7 +329,7 @@ NET0730 Implemented - ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations + ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations
ASTM NetRID DSS: Token Validation interuss
.automated_testing
.rid
.injection
@@ -367,7 +367,7 @@ interuss
.f3411
.dss_endpoints
GetISA Implemented - ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations + ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations
ASTM NetRID DSS: Token Validation SearchISAs diff --git a/monitoring/uss_qualifier/suites/astm/netrid/f3411_19/dss_probing.md b/monitoring/uss_qualifier/suites/astm/netrid/f3411_19/dss_probing.md index c1ef415741..601f9c6b09 100644 --- a/monitoring/uss_qualifier/suites/astm/netrid/f3411_19/dss_probing.md +++ b/monitoring/uss_qualifier/suites/astm/netrid/f3411_19/dss_probing.md @@ -11,7 +11,8 @@ 5. Scenario: [ASTM NetRID DSS: Subscription Validation](../../../../scenarios/astm/netrid/v19/dss/subscription_validation.md) ([`scenarios.astm.netrid.v19.dss.SubscriptionValidation`](../../../../scenarios/astm/netrid/v19/dss/subscription_validation.py)) 6. Scenario: [ASTM NetRID DSS: Subscription Simple](../../../../scenarios/astm/netrid/v19/dss/subscription_simple.md) ([`scenarios.astm.netrid.v19.dss.SubscriptionSimple`](../../../../scenarios/astm/netrid/v19/dss/subscription_simple.py)) 7. Scenario: [ASTM F3411-19 NetRID DSS interoperability](../../../../scenarios/astm/netrid/v19/dss_interoperability.md) ([`scenarios.astm.netrid.v19.DSSInteroperability`](../../../../scenarios/astm/netrid/v19/dss_interoperability.py)) -8. Scenario: [ASTM NetRID DSS: Direct CRDB access](../../../../scenarios/astm/netrid/v19/dss/crdb_access.md) ([`scenarios.astm.netrid.v19.dss.CRDBAccess`](../../../../scenarios/astm/netrid/v19/dss/crdb_access.py)) +8. Scenario: [ASTM NetRID DSS: Token Validation](../../../../scenarios/astm/netrid/v19/dss/token_validation.md) ([`scenarios.astm.netrid.v19.dss.TokenValidation`](../../../../scenarios/astm/netrid/v19/dss/token_validation.py)) +9. Scenario: [ASTM NetRID DSS: Direct CRDB access](../../../../scenarios/astm/netrid/v19/dss/crdb_access.md) ([`scenarios.astm.netrid.v19.dss.CRDBAccess`](../../../../scenarios/astm/netrid/v19/dss/crdb_access.py)) ## [Checked requirements](../../../README.md#checked-requirements) @@ -26,12 +27,12 @@ astm
.f3411
.v19
DSS0030,a Implemented - ASTM F3411-19 NetRID DSS interoperability
ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations + ASTM F3411-19 NetRID DSS interoperability
ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations
ASTM NetRID DSS: Token Validation DSS0030,b Implemented - ASTM F3411-19 NetRID DSS interoperability
ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations + ASTM F3411-19 NetRID DSS interoperability
ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations
ASTM NetRID DSS: Token Validation DSS0030,c @@ -206,13 +207,13 @@ NET0730 Implemented - ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations + ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations
ASTM NetRID DSS: Token Validation interuss
.f3411
.dss_endpoints
GetISA Implemented - ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations + ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations
ASTM NetRID DSS: Token Validation SearchISAs diff --git a/monitoring/uss_qualifier/suites/astm/netrid/f3411_19/dss_probing.yaml b/monitoring/uss_qualifier/suites/astm/netrid/f3411_19/dss_probing.yaml index 3ee3003be1..3edcffd08d 100644 --- a/monitoring/uss_qualifier/suites/astm/netrid/f3411_19/dss_probing.yaml +++ b/monitoring/uss_qualifier/suites/astm/netrid/f3411_19/dss_probing.yaml @@ -50,6 +50,12 @@ actions: resources: primary_dss_instance: dss all_dss_instances: all_dss_instances + - test_scenario: + scenario_type: scenarios.astm.netrid.v19.dss.TokenValidation + resources: + dss: dss + id_generator: id_generator + isa: isa - test_scenario: scenario_type: scenarios.astm.netrid.v19.dss.CRDBAccess resources: {} diff --git a/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a.md b/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a.md index 14befdeabb..c0b817a23b 100644 --- a/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a.md +++ b/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a.md @@ -21,11 +21,26 @@ Checked in - astm
.f3411
.v19
+ astm
.f3411
.v19
+ DSS0030,a + Implemented + ASTM NetRID DSS: Token Validation + + + DSS0030,b + Implemented + ASTM NetRID DSS: Token Validation + + DSS0030,e Implemented ASTM NetRID DSS: Subscription Simple + + NET0730 + Implemented + ASTM NetRID DSS: Token Validation + astm
.f3411
.v22a
DSS0030 @@ -498,7 +513,7 @@ interuss
.f3411
.dss_endpoints
GetISA Implemented - ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations + ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations
ASTM NetRID DSS: Token Validation SearchISAs diff --git a/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a/dss_probing.md b/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a/dss_probing.md index 57a745d7a4..c0aec9c588 100644 --- a/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a/dss_probing.md +++ b/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a/dss_probing.md @@ -11,7 +11,8 @@ 5. Scenario: [ASTM NetRID DSS: Subscription Validation](../../../../scenarios/astm/netrid/v22a/dss/subscription_validation.md) ([`scenarios.astm.netrid.v22a.dss.SubscriptionValidation`](../../../../scenarios/astm/netrid/v22a/dss/subscription_validation.py)) 6. Scenario: [ASTM NetRID DSS: Subscription Simple](../../../../scenarios/astm/netrid/v22a/dss/subscription_simple.md) ([`scenarios.astm.netrid.v22a.dss.SubscriptionSimple`](../../../../scenarios/astm/netrid/v22a/dss/subscription_simple.py)) 7. Scenario: [ASTM F3411-22a NetRID DSS interoperability](../../../../scenarios/astm/netrid/v22a/dss_interoperability.md) ([`scenarios.astm.netrid.v22a.DSSInteroperability`](../../../../scenarios/astm/netrid/v22a/dss_interoperability.py)) -8. Scenario: [ASTM NetRID DSS: Direct CRDB access](../../../../scenarios/astm/netrid/v22a/dss/crdb_access.md) ([`scenarios.astm.netrid.v22a.dss.CRDBAccess`](../../../../scenarios/astm/netrid/v22a/dss/crdb_access.py)) +8. Scenario: [ASTM NetRID DSS: Token Validation](../../../../scenarios/astm/netrid/v19/dss/token_validation.md) ([`scenarios.astm.netrid.v19.dss.TokenValidation`](../../../../scenarios/astm/netrid/v19/dss/token_validation.py)) +9. Scenario: [ASTM NetRID DSS: Direct CRDB access](../../../../scenarios/astm/netrid/v22a/dss/crdb_access.md) ([`scenarios.astm.netrid.v22a.dss.CRDBAccess`](../../../../scenarios/astm/netrid/v22a/dss/crdb_access.py)) ## [Checked requirements](../../../README.md#checked-requirements) @@ -23,11 +24,26 @@ Checked in - astm
.f3411
.v19
+ astm
.f3411
.v19
+ DSS0030,a + Implemented + ASTM NetRID DSS: Token Validation + + + DSS0030,b + Implemented + ASTM NetRID DSS: Token Validation + + DSS0030,e Implemented ASTM NetRID DSS: Subscription Simple + + NET0730 + Implemented + ASTM NetRID DSS: Token Validation + astm
.f3411
.v22a
DSS0030 @@ -228,7 +244,7 @@ interuss
.f3411
.dss_endpoints
GetISA Implemented - ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations + ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations
ASTM NetRID DSS: Token Validation SearchISAs diff --git a/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a/dss_probing.yaml b/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a/dss_probing.yaml index 61723b8915..fe94dc34c6 100644 --- a/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a/dss_probing.yaml +++ b/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a/dss_probing.yaml @@ -50,6 +50,12 @@ actions: resources: primary_dss_instance: dss all_dss_instances: all_dss_instances + - test_scenario: + scenario_type: scenarios.astm.netrid.v19.dss.TokenValidation + resources: + dss: dss + id_generator: id_generator + isa: isa - test_scenario: scenario_type: scenarios.astm.netrid.v22a.dss.CRDBAccess resources: {} diff --git a/monitoring/uss_qualifier/suites/interuss/dss/all_tests.md b/monitoring/uss_qualifier/suites/interuss/dss/all_tests.md index 676c644b7d..33913722d5 100644 --- a/monitoring/uss_qualifier/suites/interuss/dss/all_tests.md +++ b/monitoring/uss_qualifier/suites/interuss/dss/all_tests.md @@ -22,12 +22,12 @@ astm
.f3411
.v19
DSS0030,a Implemented - ASTM F3411-19 NetRID DSS interoperability
ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations + ASTM F3411-19 NetRID DSS interoperability
ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations
ASTM NetRID DSS: Token Validation DSS0030,b Implemented - ASTM F3411-19 NetRID DSS interoperability
ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations + ASTM F3411-19 NetRID DSS interoperability
ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations
ASTM NetRID DSS: Token Validation DSS0030,c @@ -202,7 +202,7 @@ NET0730 Implemented - ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations + ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations
ASTM NetRID DSS: Token Validation astm
.f3411
.v22a
@@ -404,7 +404,7 @@ interuss
.f3411
.dss_endpoints
GetISA Implemented - ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations + ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations
ASTM NetRID DSS: Token Validation SearchISAs diff --git a/monitoring/uss_qualifier/suites/uspace/network_identification.md b/monitoring/uss_qualifier/suites/uspace/network_identification.md index 0dfe0275ae..97233ee0ec 100644 --- a/monitoring/uss_qualifier/suites/uspace/network_identification.md +++ b/monitoring/uss_qualifier/suites/uspace/network_identification.md @@ -16,11 +16,26 @@ Checked in - astm
.f3411
.v19
+ astm
.f3411
.v19
+ DSS0030,a + Implemented + ASTM NetRID DSS: Token Validation + + + DSS0030,b + Implemented + ASTM NetRID DSS: Token Validation + + DSS0030,e Implemented ASTM NetRID DSS: Subscription Simple + + NET0730 + Implemented + ASTM NetRID DSS: Token Validation + astm
.f3411
.v22a
DSS0030 @@ -493,7 +508,7 @@ interuss
.f3411
.dss_endpoints
GetISA Implemented - ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations + ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations
ASTM NetRID DSS: Token Validation SearchISAs diff --git a/monitoring/uss_qualifier/suites/uspace/required_services.md b/monitoring/uss_qualifier/suites/uspace/required_services.md index 2a3f6d28c5..4baa59598c 100644 --- a/monitoring/uss_qualifier/suites/uspace/required_services.md +++ b/monitoring/uss_qualifier/suites/uspace/required_services.md @@ -18,11 +18,26 @@ Checked in - astm
.f3411
.v19
+ astm
.f3411
.v19
+ DSS0030,a + Implemented + ASTM NetRID DSS: Token Validation + + + DSS0030,b + Implemented + ASTM NetRID DSS: Token Validation + + DSS0030,e Implemented ASTM NetRID DSS: Subscription Simple + + NET0730 + Implemented + ASTM NetRID DSS: Token Validation + astm
.f3411
.v22a
DSS0030 @@ -632,7 +647,7 @@ interuss
.f3411
.dss_endpoints
GetISA Implemented - ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations + ASTM NetRID DSS: ISA Expiry
ASTM NetRID DSS: ISA Subscription Interactions
ASTM NetRID DSS: Simple ISA
ASTM NetRID DSS: Submitted ISA Validations
ASTM NetRID DSS: Token Validation SearchISAs