The UUID -> Number -> UUID transformation was lossy and incorrect.
This commit preserves the UUID as-is, but parses the inbound element
into a number if the API being called (i.e. anything but Mobile)
requires a number for its PK.
**Summary:**
Calls to _retrieve_, _create_, and _update_ Authenticators have been isolated into a module
functions and code accessing those features have been revised to use those functions.
**This commit**
Isolates the Authenticators APIs for `authenticatorsAllList`, `authenticatorsAdminAllList`,
`authenticators<Type>Destroy` and `authenticators<Type>Update` into a connector module, and updates
client code to use them. This eliminates the duplication of `deleteAuthenticatorDevice`, the code
for which was in both *Admin* and *User*, and creates a single source of truth for the DeviceType
strings that identify Device subtypes.
**Details**
One thing that's bothered me a lot is the way our APIs, starting on the Django side, start with a
base model and then "spread out" to incorporate many different inheritance models: different kinds
of Providers, different kinds of Outposts, and different kinds of authentication devices.
In a proper object-oriented system, we'd be granted access to the base class and have the power to
use it effectively as a generic, switchboarding on some RTTI or value type to handle the differences
between the concrete child types. The code generator we use does not provide that base model to UI
clients; "funnelling down" to create a sort of artificial base class on the client and then fanning
back out is an impractical and error-prone exercise.
But we still do a lot of switchboarding, which has three problems:
- Adding subtypes touches a lot of different code
- Distant implementations can miss a specific instance of a subtype
- Repeated use of strings as type handles can introduce spelling errors
- The [last line effect](https://link.springer.com/article/10.1007/s10664-016-9489-6) can introduce
new and subtle bugs when cut-and-pasting prior examples
- Instances of the *same code* in multiple locations make for maintenance headaches
This patch introduces the concept of **connectors**, modules that provide CRUD functions for common
operations performed on objects of a specific subtype. It is *not* meant to replace concrete class
displays or manipulations, such as (using providers as an example) `ProxyProviderViewPage` or HTML
that is customized for a specific concrete type of provider.
For retrieving lists, deleting instances that can be addressed from the base class, or updating
objects — any place where which call among a collection of isomorphic APIs must be specifieda using
`switch/case` statements — the connector provides a single source of truth for how to recognize the
child types, which `switch/case` statements provide the utility, and what must be done to update
them.
this also treats accept/deny as "number" matching (we call it item matching to make it more general), since it's just a more static version of selecting the correct thing
Signed-off-by: Jens Langhammer <jens@goauthentik.io>