What happens
ModelTargetDataset records whether it is standard or advanced:
dataset_type: ModelTargetDatasetType
but nothing checks that field again. Datasets are stored in one flat dict keyed by UUID (TargetManager._model_target_datasets), and the status, download and delete handlers look the UUID up without regard to which route family the request came in on.
So a dataset created as standard is fully reachable through the advanced routes:
created standard dataset: 201
status via standard route -> 200
status via ADVANCED route -> 200
download via standard route -> 200
download via ADVANCED route -> 200
DELETE via ADVANCED route -> 200
status after cross-type delete -> 404
The last two lines are the sharpest version: a dataset created at POST /modeltargets/datasets is deleted by DELETE /modeltargets/advancedDatasets/{uuid}.
The eight routes are therefore four routes with two spellings each. dataset_type is used at creation time, for _model_count_details and for the advanced-only model count limit, and then never again.
Why it matters
Real Vuforia treats these as separate resources. They have separate documented OAuth scopes — modeltargets.standardmodeltarget.all and modeltargets.advancedmodeltarget.all, listed in #3345 — and #3202 records that real Vuforia rejects an unscoped client at /modeltargets/advancedDatasets with a 403 before validating anything. A standard-only client asking the advanced endpoint about its own dataset is not going to get a 200.
The consequence for users is the specific failure a verified fake exists to prevent: code which polls or deletes via the wrong endpoint family passes against the mock and fails against real Vuforia, and the mock gave no signal.
Relationship to existing issues
Not covered by the open Model Target issues, which I checked before filing:
- #3194 is about the shape of the status response body and the status lifecycle.
- #3195 is about the realism of the downloaded zip.
- #3196 is about adding verified fake coverage for advanced create/status/download/delete — it would exercise advanced datasets through advanced routes, so it would not catch cross-type access.
- #3345 and #3192 are about tokens and scopes rather than resource identity.
Scoping by token would partly mask this once #3345 lands, but only for clients which lack the advanced scope. A client holding both scopes would still be able to delete a standard dataset through the advanced route.
Suggested resolution
Check dataset_type in the status, download and delete handlers and return a not-found error when it does not match the route.
What the not-found error looks like should be checked against real Vuforia rather than guessed — the mock already has a Vuforia-shaped unknown-dataset error using userId:mock as the target, so reusing that is the obvious first guess, but whether real Vuforia gives 404 or 403 here depends on scope checking happening first.
A test for this fits naturally into #3196: while adding advanced-route coverage, assert that a standard dataset is not visible through the advanced routes and vice versa.
What happens
ModelTargetDatasetrecords whether it is standard or advanced:but nothing checks that field again. Datasets are stored in one flat dict keyed by UUID (
TargetManager._model_target_datasets), and the status, download and delete handlers look the UUID up without regard to which route family the request came in on.So a dataset created as standard is fully reachable through the advanced routes:
The last two lines are the sharpest version: a dataset created at
POST /modeltargets/datasetsis deleted byDELETE /modeltargets/advancedDatasets/{uuid}.The eight routes are therefore four routes with two spellings each.
dataset_typeis used at creation time, for_model_count_detailsand for the advanced-only model count limit, and then never again.Why it matters
Real Vuforia treats these as separate resources. They have separate documented OAuth scopes —
modeltargets.standardmodeltarget.allandmodeltargets.advancedmodeltarget.all, listed in #3345 — and #3202 records that real Vuforia rejects an unscoped client at/modeltargets/advancedDatasetswith a 403 before validating anything. A standard-only client asking the advanced endpoint about its own dataset is not going to get a 200.The consequence for users is the specific failure a verified fake exists to prevent: code which polls or deletes via the wrong endpoint family passes against the mock and fails against real Vuforia, and the mock gave no signal.
Relationship to existing issues
Not covered by the open Model Target issues, which I checked before filing:
Scoping by token would partly mask this once #3345 lands, but only for clients which lack the advanced scope. A client holding both scopes would still be able to delete a standard dataset through the advanced route.
Suggested resolution
Check
dataset_typein the status, download and delete handlers and return a not-found error when it does not match the route.What the not-found error looks like should be checked against real Vuforia rather than guessed — the mock already has a Vuforia-shaped unknown-dataset error using
userId:mockas the target, so reusing that is the obvious first guess, but whether real Vuforia gives 404 or 403 here depends on scope checking happening first.A test for this fits naturally into #3196: while adding advanced-route coverage, assert that a standard dataset is not visible through the advanced routes and vice versa.