Skip to content

Commit

Permalink
[uss_qualifier] attach participant id to net0210 check, fix Issue int…
Browse files Browse the repository at this point in the history
  • Loading branch information
Shastick committed Oct 13, 2023
1 parent 5d7821e commit c8bf7fd
Show file tree
Hide file tree
Showing 12 changed files with 123 additions and 81 deletions.
17 changes: 13 additions & 4 deletions monitoring/monitorlib/fetch/rid.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import datetime
from typing import Dict, List, Optional, Any, Union

import loguru
from implicitdict import ImplicitDict, StringBasedDateTime
import s2sphere
from uas_standards.astm.f3411 import v19, v22a
Expand Down Expand Up @@ -1163,8 +1164,15 @@ def all_flights(
session: UTMClientSession,
dss_base_url: str = "",
enhanced_details: bool = False,
server_id: Optional[str] = None,
dss_server_id: Optional[str] = None,
flights_urls_to_server_id: Optional[Dict[str, str]] = None,
) -> FetchedFlights:

loguru.logger.debug(f"Provided SP Flights URLs: {flights_urls_to_server_id}")

if flights_urls_to_server_id is None:
flights_urls_to_server_id = {}

t = datetime.datetime.utcnow()
isa_list = isas(
geo.get_latlngrect_vertices(area),
Expand All @@ -1173,7 +1181,7 @@ def all_flights(
rid_version,
session,
dss_base_url,
server_id=server_id,
server_id=dss_server_id,
)

uss_flight_queries: Dict[str, FetchedUSSFlights] = {}
Expand All @@ -1185,7 +1193,8 @@ def all_flights(
include_recent_positions,
rid_version,
session,
server_id=server_id,
# TODO we need an exact match of the flight url for this to work here
server_id=flights_urls_to_server_id.get(flights_url, None),
)
uss_flight_queries[flights_url] = flights_for_url

Expand All @@ -1197,7 +1206,7 @@ def all_flights(
enhanced_details,
rid_version,
session,
server_id=server_id,
server_id=flights_urls_to_server_id.get(flights_url, None),
)
uss_flight_details_queries[flight.id] = details

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ net_rid:
service_providers:
- participant_id: uss2
injection_base_url: http://v19.ridsp.uss2.localutm/ridsp/injection
flights_url: http://v19.ridsp.uss2.localutm/ridsp/flights # TODO confirm this is correct
local_debug: true
netrid_service_providers_v22a:
$content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json
Expand All @@ -44,6 +45,7 @@ net_rid:
service_providers:
- participant_id: uss1
injection_base_url: http://v22a.ridsp.uss1.localutm/ridsp/injection
flights_url: http://v19.ridsp.uss2.localutm/ridsp/flights # TODO confirm this is correct
local_debug: true
netrid_observers_v19:
$content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json
Expand Down
34 changes: 23 additions & 11 deletions monitoring/uss_qualifier/resources/netrid/service_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ class ServiceProviderConfiguration(ImplicitDict):
injection_base_url: str
"""Base URL for the Service Provider's implementation of the interfaces/automated-testing/rid/injection.yaml API"""

# TODO confirm that:
# 1, this is fine to have in the configuration?
# 2, we should instaed use a list of flight urls here? SPs could in theory use multiple ones
flights_url: str
"""URL the Service Provider will register with the DSS for providing flights information."""

local_debug: Optional[bool]
"""Whether this Service Provider instance is running locally for debugging or development purposes. Mostly used for relaxing
constraints around encryption.
Expand All @@ -41,25 +47,30 @@ class NetRIDServiceProvidersSpecification(ImplicitDict):

class NetRIDServiceProvider(object):
participant_id: str
base_url: str
client: infrastructure.UTMClientSession
injection_base_url: str
flights_url: str
flights_injection_client: infrastructure.UTMClientSession
local_debug: bool

def __init__(
self,
participant_id: str,
base_url: str,
injection_base_url: str,
flights_url: str,
auth_adapter: infrastructure.AuthAdapter,
local_debug: bool,
):
self.participant_id = participant_id
self.base_url = base_url
self.client = infrastructure.UTMClientSession(base_url, auth_adapter)
self.injection_base_url = injection_base_url
self.flights_url = flights_url
self.flights_injection_client = infrastructure.UTMClientSession(
injection_base_url, auth_adapter
)
self.local_debug = local_debug

def submit_test(self, request: CreateTestParameters, test_id: str) -> fetch.Query:
return fetch.query_and_describe(
self.client,
self.flights_injection_client,
"PUT",
url=f"/tests/{test_id}",
json=request,
Expand All @@ -69,7 +80,7 @@ def submit_test(self, request: CreateTestParameters, test_id: str) -> fetch.Quer

def delete_test(self, test_id: str, version: str) -> fetch.Query:
return fetch.query_and_describe(
self.client,
self.flights_injection_client,
"DELETE",
url=f"/tests/{test_id}/{version}",
scope=SCOPE_RID_QUALIFIER_INJECT,
Expand All @@ -87,10 +98,11 @@ def __init__(
):
self.service_providers = [
NetRIDServiceProvider(
s.participant_id,
s.injection_base_url,
auth_adapter.adapter,
s.get("local_debug", False),
participant_id=s.participant_id,
injection_base_url=s.injection_base_url,
flights_url=s.flights_url,
auth_adapter=auth_adapter.adapter,
local_debug=s.get("local_debug", False),
)
for s in specification.service_providers
]
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ def __init__(

# identify SPs and observers by their base URL
self._participants_by_base_url.update(
{sp.base_url: sp.participant_id for sp in self._service_providers}
{sp.injection_base_url: sp.participant_id for sp in self._service_providers}
)
self._participants_by_base_url.update(
{sp.flights_url: sp.participant_id for sp in self._service_providers}
)
self._participants_by_base_url.update(
{dp.base_url: dp.participant_id for dp in self._observers}
Expand Down Expand Up @@ -101,7 +104,7 @@ def run(self):
for sp in self._service_providers:
self.record_note(
"service_providers",
f"configured service providers: {sp.participant_id} - {sp.base_url}",
f"configured service providers: {sp.participant_id} - {sp.injection_base_url}",
)

for o in self._observers:
Expand Down
110 changes: 53 additions & 57 deletions monitoring/uss_qualifier/scenarios/astm/netrid/common/misbehavior.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,28 @@
import time
import traceback
import uuid
from typing import List
from typing import List, Dict

import arrow
import s2sphere
from implicitdict import ImplicitDict
from loguru import logger
from requests.exceptions import RequestException
from uas_standards.interuss.automated_testing.rid.v1.injection import ChangeTestResponse

from monitoring.monitorlib import fetch
from monitoring.monitorlib.fetch import rid
from monitoring.monitorlib.infrastructure import UTMClientSession
from monitoring.monitorlib.rid import RIDVersion
from monitoring.monitorlib.rid_automated_testing.injection_api import (
CreateTestParameters,
)
from monitoring.monitorlib.rid_automated_testing.injection_api import TestFlight
from monitoring.uss_qualifier.common_data_definitions import Severity
from monitoring.uss_qualifier.resources.astm.f3411.dss import DSSInstancesResource
from monitoring.uss_qualifier.resources.netrid import (
FlightDataResource,
NetRIDServiceProviders,
EvaluationConfigurationResource,
)
from monitoring.uss_qualifier.scenarios.astm.netrid import display_data_evaluator
from monitoring.uss_qualifier.scenarios.astm.netrid.common import nominal_behavior
from monitoring.uss_qualifier.scenarios.astm.netrid.injected_flight_collection import (
InjectedFlightCollection,
)
from monitoring.uss_qualifier.scenarios.astm.netrid.injection import (
InjectedFlight,
InjectedTest,
)
from monitoring.uss_qualifier.scenarios.astm.netrid.virtual_observer import (
VirtualObserver,
)
from monitoring.uss_qualifier.scenarios.scenario import GenericTestScenario


Expand All @@ -50,6 +36,7 @@ class Misbehavior(GenericTestScenario):
_evaluation_configuration: EvaluationConfigurationResource
_injected_flights: List[InjectedFlight]
_injected_tests: List[InjectedTest]
_flights_urls_to_participant_id: Dict[str, str]

def __init__(
self,
Expand All @@ -70,6 +57,11 @@ def __init__(
)
self._dss = dss_pool.dss_instances[0]

self._flights_urls_to_participant_id = {
sp.flights_url: sp.participant_id
for sp in self._service_providers.service_providers
}

@property
def _rid_version(self) -> RIDVersion:
raise NotImplementedError(
Expand Down Expand Up @@ -167,52 +159,56 @@ def _evaluate_and_test_authentication(
no flights were yet returned by the authenticated queries.
"""

with self.check("Missing credentials") as check:
# We grab all flights from the SP's. This is authenticated
# and is expected to succeed
sp_observation = rid.all_flights(
rect,
include_recent_positions=True,
get_details=True,
rid_version=self._rid_version,
session=self._dss.client,
server_id=self._dss.participant_id,
)
# We fish out the queries that were used to grab the flights from the SP,
# and attempt to re-query without credentials. This should fail.
# We grab all flights from the SP's (which we know how to reach by first querying the DSS).
# This is authenticated and is expected to succeed
sp_observation = rid.all_flights(
rect,
include_recent_positions=True,
get_details=True,
rid_version=self._rid_version,
session=self._dss.client,
dss_server_id=self._dss.participant_id,
flights_urls_to_server_id=self._flights_urls_to_participant_id,
)

unauthenticated_session = UTMClientSession(
prefix_url=self._dss.client.get_prefix_url(),
auth_adapter=None,
timeout_seconds=self._dss.client.timeout_seconds,
)
# We fish out the queries that were used to grab the flights from the SP,
# and attempt to re-query without credentials. This should fail.
unauthenticated_session = UTMClientSession(
prefix_url=self._dss.client.get_prefix_url(),
auth_adapter=None,
timeout_seconds=self._dss.client.timeout_seconds,
)

queries_to_repeat = list(sp_observation.uss_flight_queries.values()) + list(
sp_observation.uss_flight_details_queries.values()
)
queries_to_repeat = list(sp_observation.uss_flight_queries.values()) + list(
sp_observation.uss_flight_details_queries.values()
)

if len(queries_to_repeat) == 0:
logger.debug("no flights queries to repeat at this point.")
return False
if len(queries_to_repeat) == 0:
logger.debug("no flights queries to repeat at this point.")
return False

logger.debug(
f"about to repeat {len(queries_to_repeat)} flights queries without credentials"
)
logger.debug(
f"about to repeat {len(queries_to_repeat)} flights queries without credentials"
)

# Attempt to re-query the flights and flight details URLs:
for fq in queries_to_repeat:
failed_q = fetch.query_and_describe(
client=unauthenticated_session,
verb=fq.query.request.method,
url=fq.query.request.url,
json=fq.query.request.json,
data=fq.query.request.body,
server_id=self._dss.participant_id,
)
logger.info(
f"Repeating query to {fq.query.request.url} without credentials"
)
server_id = fq.query.get("server_id", "unknown")
# Attempt to re-query the flights and flight details URLs:
for fq in queries_to_repeat:
sp_server_id = fq.query.get("server_id", "unknown")
if sp_server_id == "unknown":
logger.warning(f"got unattributed SP query to: {fq.query.request.url}")

failed_q = fetch.query_and_describe(
client=unauthenticated_session,
verb=fq.query.request.method,
url=fq.query.request.url,
json=fq.query.request.json,
data=fq.query.request.body,
server_id=sp_server_id,
)
logger.info(
f"Repeating query to {fq.query.request.url} without credentials"
)
with self.check("Missing credentials", [sp_server_id]) as check:
if failed_q.response.code not in [401, 403]:
check.record_failed(
"unauthenticated request was fulfilled",
Expand All @@ -227,7 +223,7 @@ def _evaluate_and_test_authentication(
# Keep track of the failed queries, too
self.record_query(failed_q)

return True
return True

def cleanup(self):
self.begin_cleanup()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ def evaluate_system_instantaneously(
get_details=True,
rid_version=self._rid_version,
session=self._dss.client,
server_id=self._dss.participant_id,
dss_server_id=self._dss.participant_id,
)
for q in sp_observation.queries:
self._test_scenario.record_query(q)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ It then repeats the exact same request while omitting the credentials, and expec

#### Missing credentials check

This check ensures that all requests are properly authenticated, as required by **[astm.f3411.v19.NET0500](../../../../requirements/astm/f3411/v19.md)**,
This check ensures that all requests are properly authenticated, as required by **[astm.f3411.v19.NET0210](../../../../requirements/astm/f3411/v19.md)**,
and that requests for existing flights that are executed with missing or incorrect credentials fail.

## Cleanup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ It then repeats the exact same request while omitting the credentials, and expec

#### Missing credentials check

This check ensures that all requests are properly authenticated, as required by **[astm.f3411.v22a.NET0500](../../../../requirements/astm/f3411/v22a.md)**,
This check ensures that all requests are properly authenticated, as required by **[astm.f3411.v22a.NET0210](../../../../requirements/astm/f3411/v22a.md)**,
and that requests for existing flights that are executed with missing or incorrect credentials fail.

## Cleanup
Expand Down
7 changes: 6 additions & 1 deletion monitoring/uss_qualifier/suites/astm/netrid/f3411_19.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<th><a href="../../README.md#checked-in">Checked in</a></th>
</tr>
<tr>
<td rowspan="52" style="vertical-align:top;"><a href="../../../requirements/astm/f3411/v19.md">astm<br>.f3411<br>.v19</a></td>
<td rowspan="53" style="vertical-align:top;"><a href="../../../requirements/astm/f3411/v19.md">astm<br>.f3411<br>.v19</a></td>
<td><a href="../../../requirements/astm/f3411/v19.md">A2-6-1,1a</a></td>
<td>Implemented</td>
<td><a href="../../../scenarios/astm/netrid/v19/dss_interoperability.md">ASTM F3411-19 NetRID DSS interoperability</a></td>
Expand Down Expand Up @@ -186,6 +186,11 @@
<td>TODO</td>
<td><a href="../../../scenarios/astm/netrid/v19/operator_interactions.md">ASTM NetRID: Operator interactions</a></td>
</tr>
<tr>
<td><a href="../../../requirements/astm/f3411/v19.md">NET0210</a></td>
<td>Implemented</td>
<td><a href="../../../scenarios/astm/netrid/v19/misbehavior.md">ASTM NetRID SP clients misbehavior handling</a></td>
</tr>
<tr>
<td><a href="../../../requirements/astm/f3411/v19.md">NET0220</a></td>
<td>Implemented</td>
Expand Down
Loading

0 comments on commit c8bf7fd

Please sign in to comment.