Skip to content

Give CloudDatabase a database ID and validate it in the reco counts path #3362

Description

@adamtheturtle

Follow-up to #3357 and #3359.

The mock accepts any database ID in the path of POST /imagetargets/databases/{database_id}/reports/recoCounts. It authenticates with the request's server keys and ignores the ID entirely. Real Vuforia returns a 401 for a request which is correctly signed but which names a database ID that the keys do not belong to, which is how #3357 discovered the ID mattered at all.

That difference is a false negative of exactly the kind the mock exists to prevent. Code which builds the path with the wrong value — the database name instead of its ID, a stale ID, an ID from a different environment — passes against the mock and fails against real Vuforia.

The change

mock_vws.database.CloudDatabase has no database ID. It would need one:

  • a database_id field, defaulting to a random hex string, exactly as database_name and the four keys already do. Users who want to build a request path read it off the database object, the same way they read the keys;
  • the field carried through CloudDatabaseDict, to_dict and from_dict, or the Flask and Docker backend will silently disagree with the in-process one. This is the same serialization trap the recognition count fields fell into, described in Make recognition counts seedable so reco reports can be non-empty #3356;
  • a validator which raises when the path's ID does not match the database the keys authenticate, using the existing AuthenticationFailureError. That already returns a 401 with an AuthenticationFailure result code, which matches the status code observed from real Vuforia.

The addition itself is backwards compatible: a new field with a default breaks no existing construction of CloudDatabase. Enforcing the ID would be breaking for anyone already calling the reco counts endpoint against the mock, but that endpoint only landed in #3357 and has not been released, so in practice nothing depends on the current permissiveness.

VuMarkDatabase is out of scope. No documented VuMark endpoint names a database by ID in its path.

Why this is blocked on #3359

Two things are guesses until the verified tests in #3359 actually run against real Vuforia:

  1. That the ID is what caused the 401. The evidence is one observation: a correctly signed request with a random UUID in the path came back 401. That is suggestive, not conclusive. If real Vuforia turns out to ignore the ID and to have rejected that request for another reason, then enforcing it in the mock would make the mock less faithful, not more.
  2. What the rejection looks like. Only the status code was captured, not the result code or body. AuthenticationFailure is the obvious candidate but has not been confirmed, and the endpoint may not use the standard VWS error shape at all.

#3359 settles both: it sends the real database ID, so a pass confirms the ID was the problem, and a deliberate mismatch would capture the real error body.

Doing this work before then means implementing a guess and documenting it as verified behaviour, which is the failure mode differences-to-vws.rst exists to avoid.

Acceptance criteria

  • Add a database ID credential so the reco counts tests can be verified #3359 has run against real Vuforia and confirmed both that a mismatched database ID is what causes the 401 and what the response body contains.
  • CloudDatabase has a database_id which round-trips through to_dict and from_dict, so the in-process and Flask backends behave identically.
  • The mock rejects a reco counts request whose path names a different database, with the result code observed from real Vuforia.
  • A verified fake test covers the mismatch, sending a well-formed ID which belongs to no database of the account.
  • differences-to-vws.rst drops the note that the mock cannot make this check.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions