mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 12:37:00 +01:00
strip out some debug messages unless *really* debugging. (#2767)
* kanidm cli logs on debug level - Fixes #2745 * such clippy like wow * It's important for a wordsmith to know when to get its fixes in. * updootin' wasms
This commit is contained in:
parent
623fdfa635
commit
7964f55d59
|
@ -130,9 +130,9 @@ differ however, but generally Kanidm is much faster than FreeIPA).
|
|||
<details>
|
||||
<summary>Keycloak</summary>
|
||||
|
||||
Keycloak is an OIDC/OAuth2/SAML provider. It allows you to layer on WebAuthn to existing IDM systems.
|
||||
Keycloak can operate as a stand-alone IDM but generally is a component attached to an existing LDAP
|
||||
server or similar.
|
||||
Keycloak is an OIDC/OAuth2/SAML provider. It allows you to layer on WebAuthn to existing IDM
|
||||
systems. Keycloak can operate as a stand-alone IDM but generally is a component attached to an
|
||||
existing LDAP server or similar.
|
||||
|
||||
Keycloak requires a significant amount of configuration and experience to deploy. It allows high
|
||||
levels of customisation to every detail of its authentication work flows, which makes it harder to
|
||||
|
|
|
@ -26,8 +26,10 @@ as this may have important effects on your distribution or upgrades in future.
|
|||
|
||||
### 1.2.0 Important Changes
|
||||
|
||||
- On upgrade all OAuth2 sessions and user sessions will be reset due to changes in cryptographic key handling. This does not affect api tokens.
|
||||
- There is a maximum limit of 48 interactive sessions for persons where older sessions are automatically removed.
|
||||
- On upgrade all OAuth2 sessions and user sessions will be reset due to changes in cryptographic key
|
||||
handling. This does not affect api tokens.
|
||||
- There is a maximum limit of 48 interactive sessions for persons where older sessions are
|
||||
automatically removed.
|
||||
|
||||
### 1.2.0 Release Highlights
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ has access to cookies from `a.example.com` and `example.com`.
|
|||
|
||||
For this reason your Kanidm host (or hosts) should be on a unique subdomain, with no other services
|
||||
registered under that subdomain. For example, consider `idm.example.com` as a subdomain for
|
||||
exclusive use of Kanidm. This is _inverse_ to Active Directory which often has it's domain name
|
||||
exclusive use of Kanidm. This is _inverse_ to Active Directory which often has its domain name
|
||||
selected to be the parent (toplevel) domain (`example.com`).
|
||||
|
||||
Failure to use a unique subdomain may allow cookies to leak to other entities within your domain,
|
||||
|
|
|
@ -56,7 +56,7 @@ dc=example,dc=com. Within this search base, we show the same content from dc=exa
|
|||
when you have a group for allowing access to the application, but then still need other groups
|
||||
reflected into the subtree. In this case, if we limited the view to application access only, we
|
||||
wouldn't be displaying the non-access groups that the application may still rely on. Ultimately, in
|
||||
this case the application needs to make it's own authorisation decisions to an extend. Kanidm can
|
||||
this case the application needs to make its own authorisation decisions to an extend. Kanidm can
|
||||
limit which users are members of the access allowed group as only they can bind still as an extra
|
||||
layer of defence)
|
||||
|
||||
|
|
|
@ -185,7 +185,7 @@ Webauthn Challenges. For more details see: https://fy.blackhats.net.au/blog/html
|
|||
AuthSession
|
||||
-----------
|
||||
|
||||
Once these other changes are made, AuthSession will need to be simplified but it's core state machines
|
||||
Once these other changes are made, AuthSession will need to be simplified but its core state machines
|
||||
will remain mostly unchanged. This set of changes will likely result in the AuthSession being much
|
||||
clearer due to the enforcement of credential presentation order instead of the current design that
|
||||
may allow "all in one" submissions.
|
||||
|
|
|
@ -60,7 +60,7 @@ Only one credential update process may exist at a time for a user. Attempts to c
|
|||
credential update session while an existing session exists is rejected until the previous session
|
||||
is committed or timed out.
|
||||
|
||||
The credential update session can be rejected by the user, canceling it's progress.
|
||||
The credential update session can be rejected by the user, canceling its progress.
|
||||
|
||||
A credential update session IS tied to a single server, similar to authentication.
|
||||
|
||||
|
@ -69,7 +69,7 @@ on the users account so they can see and audit the change.
|
|||
|
||||
If an intent token is used, the uuid of the intent token becomes the uuid of the credential update session.
|
||||
|
||||
If an intent token is exchanged, and it's uuid already exists in the history-log of the account, the
|
||||
If an intent token is exchanged, and its uuid already exists in the history-log of the account, the
|
||||
intent token is rejected.
|
||||
|
||||
Credential Update Process
|
||||
|
|
|
@ -91,13 +91,13 @@ The type defines the possible operations of the Key Object but not how the opera
|
|||
A key object MAY have multiple Key Types.
|
||||
|
||||
Key Objects also must define their structure related to their Key Provider. For example a possible
|
||||
TPM Key Provider needs to store it's Public and Private components in the Key Object, where our
|
||||
TPM Key Provider needs to store its Public and Private components in the Key Object, where our
|
||||
internal provider needs to store the DER portions of the keys.
|
||||
|
||||
Between the type and the provider, this provides a concrete way to determine how a key needs to be
|
||||
used.
|
||||
|
||||
For each private/public key pair, or each symmetric key, a record of it's status (valid, retained,
|
||||
For each private/public key pair, or each symmetric key, a record of its status (valid, retained,
|
||||
expired, revoked)
|
||||
|
||||
In the valid state, a key has a validity "from" a point in time. The latest `valid_from` attribute
|
||||
|
@ -223,7 +223,7 @@ pkcs11 problem, not a problem for this change.
|
|||
In the future we need to consider how to perform a migration from internal keys to HSM's in a non
|
||||
disruptive manner.
|
||||
|
||||
The design presented above associates a Key Object with it's Key Provider. There isn't a way to mix
|
||||
The design presented above associates a Key Object with its Key Provider. There isn't a way to mix
|
||||
Key Objects with multiple possible providers.
|
||||
|
||||
However, we _can_ create a migration helper object. This would be a Key Object / Key Provider that
|
||||
|
|
|
@ -117,7 +117,7 @@ Summary
|
|||
^^^^^^^
|
||||
|
||||
For most people setting up MFA is an annoying process especially when you want to allow your accounts
|
||||
to be portable between multiple devices. At it's core, it's a failure of authentication providers
|
||||
to be portable between multiple devices. At its core, it's a failure of authentication providers
|
||||
to consider devices as part of their authentication workflow and how humans interact with these
|
||||
services.
|
||||
|
||||
|
@ -182,7 +182,7 @@ On a mobile device we should NOT require a password to be entered to the account
|
|||
the password rules we attempt to enforce in Kanidm should create passwords that are *not* memorisable
|
||||
meaning that the user is likely to store this in a password manager. Since the password manager
|
||||
is already on the mobile device, then compromise of the device yields access to the password, nullifying
|
||||
it's security benefit.
|
||||
its security benefit.
|
||||
|
||||
Since we require UV required, this means the credential is a self contained MFA of possession of the
|
||||
device, and authentication to the device (biometric, password/pin). Devices today contain hardware
|
||||
|
|
|
@ -68,7 +68,7 @@ establish and maintain this trust relationship.
|
|||
3. The join token is yielded to the Kanidm UNIX daemon which submits its signing key to the Kanidm
|
||||
server.
|
||||
4. The kanidm server verifies the submission and creates a machine account.
|
||||
5. The kanidm unix daemon now uses it's signing key to sign a challenge that is submitted with all
|
||||
5. The Kanidm UNIX daemon now uses its signing key to sign a challenge that is submitted with all
|
||||
requests to the kanidm server.
|
||||
|
||||
Extra
|
||||
|
|
|
@ -24,7 +24,7 @@ This will affect replication in two ways
|
|||
First, it means the RUV of a server node can move backwards. This requires
|
||||
us to limit changelog trimming of events to events that have expired by time
|
||||
rather than events that are fully resolved. This way within the changelog
|
||||
trim window, a server can be downgraded, and it's RUV move backwards, but the missing updates will be "replayed" backwards to it.
|
||||
trim window, a server can be downgraded, and its RUV move backwards, but the missing updates will be "replayed" backwards to it.
|
||||
|
||||
Second, it means we have to consider making replication either version (typed)
|
||||
data agnostic *or* have CSN's represent a dataset version from the server which gates or blocks replication events from newer to older instances until *they* are upgraded.
|
||||
|
|
|
@ -235,9 +235,9 @@ based on the pre-entry state, and then to create again. However the current desi
|
|||
modification doesn't work like this as we only get the Entry to add.
|
||||
|
||||
Most likely we will need to change modify to take the set of (pre, post) candidates as a pair _OR_
|
||||
we have the entry store it's own pre-post internally. Given we already need to store the pre /post
|
||||
we have the entry store its own pre-post internally. Given we already need to store the pre /post
|
||||
entries in the txn, it's likely better to have a pairing of these, and that allows us to then index
|
||||
replication metadata later as the entry will contain it's own changelog internally.
|
||||
replication metadata later as the entry will contain its own changelog internally.
|
||||
|
||||
Given the pair, we then assert that they are the same entry (id). We can then use the index metadata
|
||||
to generate an indexing diff between them, containing a set of index items to remove (due to removal
|
||||
|
|
|
@ -62,7 +62,7 @@ properties we want lets write some down.
|
|||
* Forwardable Credentials - once you issue a token in one domain can it forward to another and authenticate you
|
||||
* Credential Siloing - are credentials (pw, private keys) only stored in your home domain
|
||||
* PII Limits - limit the transmission of personal information
|
||||
* Group Management - can you add a trusted account to a local group to manage it's access?
|
||||
* Group Management - can you add a trusted account to a local group to manage its access?
|
||||
* Invite un-trusted domain - can you invite accounts to use resources from domains you don't know about?
|
||||
* Fully distributed - openid style, where any openid server could be a trusted provided
|
||||
* Client Switched - Is it up to the client to trust different domains? Or is it a server side issue?
|
||||
|
@ -86,7 +86,7 @@ So with a lot of though, I'm going to go with fractional replication.
|
|||
* PII limit - I want this as you can control who-has-what PII on the system side.
|
||||
* Group Mgmt - I want this as it enables rbac and familiar group management locally for remote and local entries.
|
||||
* Invite Ext - On the fence - cool idea, but not sure how it fits into kanidm with trusts.
|
||||
* Distributed - I don't want this because it's model is really different to what kani is trying to be
|
||||
* Distributed - I don't want this because its model is really different to what kani is trying to be
|
||||
* Client Switched - I don't want this because clients should only know they trust an IDM silo, and that does the rest.
|
||||
|
||||
But there are some things I want:
|
||||
|
@ -314,10 +314,10 @@ Webauthn requires correct presentation of a domain name that matches the TLS nam
|
|||
that is being connected to. Because of this it may not be possible to proxy Webauthn through
|
||||
in a trust scenario, requiring clients to need to directly authenticate to the trusted domain.
|
||||
|
||||
Oauth
|
||||
OAuth
|
||||
=====
|
||||
|
||||
Oauth may support some trust resources of it's own, that may support or help the Webauthn cases. This
|
||||
OAuth may support some trust resources of its own, that may support or help the Webauthn cases. This
|
||||
should be investigated.
|
||||
|
||||
An alternate solution to these two is that when domain A wants to issue oauth to a user in domain b
|
||||
|
|
|
@ -2,7 +2,7 @@ LDAP Gateway
|
|||
------------
|
||||
|
||||
LDAP is a legacy protocol for accessing directory (user, group, other) data over a network. Despite
|
||||
it's complex nature, it has been the staple of authentication and authorisation for many years, where
|
||||
its complex nature, it has been the staple of authentication and authorisation for many years, where
|
||||
many enterprise or unix focused applications are guaranteed to integrate with LDAP (even contrast to
|
||||
newer systems like SAML/OAuth).
|
||||
|
||||
|
@ -116,7 +116,7 @@ gecos: This needs synthesisation from displayname
|
|||
|
||||
homeDirectory: This needs to match the rules in kanidm_unix_int, especially once trusts are added (likely to be uuid based).
|
||||
|
||||
Kanidm is closest to rfc2307bis due to the structure of it's memberOf attributes and other
|
||||
Kanidm is closest to rfc2307bis due to the structure of its memberOf attributes and other
|
||||
elements, so this is what we will "look like" but may not strictly conform to.
|
||||
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ The major one is that the question is generally framed "what groups is this pers
|
|||
a member of". This is true in terms of application access checks (is user in group Y?), nss' calls
|
||||
ie 'id name'. As a result, we want to have our data for our user and groups in a close locality.
|
||||
Given the design of the KaniDM system, where we generally frame and present user id tokens, it
|
||||
is upon the user that we want to keep the reference to it's groups.
|
||||
is upon the user that we want to keep the reference to its groups.
|
||||
|
||||
Now at this point one could consider "Why not just store the groups on the user in the first place?".
|
||||
There is a security benefit to the relationship of "groups have members" rather than "users are
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
Oauth + Scopes + Claims
|
||||
OAuth + Scopes + Claims
|
||||
-----------------------
|
||||
|
||||
Oauth is a web authorisation protocol that allows "single sign on". It's key to note
|
||||
oauth is authorisation, not authentication, as the protocol in it's default forms
|
||||
OAuth is a web authorisation protocol that allows "single sign on". It's key to note
|
||||
OAuth is authorisation, not authentication, as the protocol in its default forms
|
||||
do not provide identity or authentication information, only information that
|
||||
an entity is authorised for the requested resources.
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ is important to limit where the tokens are used and monitor and revoke them effe
|
|||
|
||||
In addition, old refresh tokens should not be able to be used once exchanged, they should be "at
|
||||
most once". If this is not enforced then old refresh tokens can be used to gain access to sessions
|
||||
even if the associated access token was expired by many hours and it's refresh token was already
|
||||
even if the associated access token was expired by many hours and its refresh token was already
|
||||
used.
|
||||
|
||||
This is supported by
|
||||
|
|
|
@ -29,7 +29,7 @@ authentication type on radius, which is MSCHAPv2. This requires NTLM hash (md4)
|
|||
storage. It's hard to overstate this - MSCHAPv2 is the only auth type that works on all devices,
|
||||
out of box, with no messing around. It has to be offered.
|
||||
|
||||
This means whatever we do is limited now by it's requirements. For example, you can't have multiple
|
||||
This means whatever we do is limited now by its requirements. For example, you can't have multiple
|
||||
passwords per account (ie per-device radius pw) because of how the MSCHAPv2 chal-resp works. This
|
||||
means 1 to 1 of pw to account for RADIUS.
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ potentially. This is an argument for the filter-scan method, that checks if any
|
|||
the class, deleted, and if it does, we do not wrap with the AndNot term.
|
||||
|
||||
|
||||
The best solution is a whole separate interface (/search/recycle/) that has it's own access controls
|
||||
The best solution is a whole separate interface (/search/recycle/) that has its own access controls
|
||||
that is used. By default searches don't look at recycled items (but internal do). This interface would
|
||||
remove that limitation, but would require access controls to prevent read/changes.
|
||||
|
||||
|
|
|
@ -258,7 +258,7 @@ that the CID: (3, A) must be sent. The entry x is sent to R again.
|
|||
(002, B): [x, ...]
|
||||
]
|
||||
|
||||
Now, Server B now connects to A and supplies it's changes. Since the changes on B happen *before*
|
||||
Now, Server B now connects to A and supplies its changes. Since the changes on B happen *before*
|
||||
the changes on A, the CID slots between the existing changes (and an update resolution would take
|
||||
place, which is out of scope of this part of the design).
|
||||
|
||||
|
@ -331,7 +331,7 @@ move to tombstone, again which triggers the above.
|
|||
However, we must now discuss the tomstone purging process.
|
||||
|
||||
A tombstone would store the CID upon which it was ... well - tombstoned. As a result, the entry
|
||||
itself is aware of it's state.
|
||||
itself is aware of its state.
|
||||
|
||||
The tombstone purge process would work by detecting the MIN RUV of all replicas. If the MIN RUV
|
||||
is greater than the tombstone CID, then it must be true that all replicas HAVE the tombstone as
|
||||
|
|
|
@ -175,7 +175,7 @@ have applied to create that entity. As a result id2entry can be considered as an
|
|||
state cache.
|
||||
|
||||
The true stable storage and representation for an entry will exist in a separate Entry
|
||||
Change Log type. Each entry will have it's own internal changelog that represents the
|
||||
Change Log type. Each entry will have its own internal changelog that represents the
|
||||
changes that have occurred in the entries lifetime and it's relevant state at that time.
|
||||
|
||||
The reason for making a per-entry change log is to allow fine grained testing of the
|
||||
|
@ -408,7 +408,7 @@ So now we know that we must send A T7 to T8 and B T11 to T16 for this replica to
|
|||
to the state we hold.
|
||||
|
||||
You may notice the "min" and "max". The purpose of this is to show how far we may rewind our
|
||||
changelog - we have changes from min to max. If a server provides it's ruv, and it's max
|
||||
changelog - we have changes from min to max. If a server provides its ruv, and its max
|
||||
is lower than our min, we must consider that server has been disconnected for "too long" and
|
||||
we are unable to supply changes until an administrator intervenes.
|
||||
|
||||
|
|
|
@ -183,9 +183,9 @@ Origin Task? Single Node Operation Runner? Yes I'm trying to make silly acronyms
|
|||
|
||||
> Still not fully sure about the KRC config yet. More thinking needed!
|
||||
|
||||
The KRC is configured with it's URL and certificates.
|
||||
The KRC is configured with its URL and certificates.
|
||||
|
||||
```
|
||||
```toml
|
||||
[krc_config]
|
||||
origin = https://krc.example.com
|
||||
tls_chain = /path/to/tls/chain
|
||||
|
|
|
@ -276,7 +276,7 @@ latter entry will be moved to the conflict state instead.
|
|||
|
||||
The same process occurs with the same results when the reverse incremental operation occurs to
|
||||
server B where it receives the entry with the earlier creation from A. It will order the events and
|
||||
"conflict" it's local copy of the entry.
|
||||
"conflict" its local copy of the entry.
|
||||
|
||||
### Attribute
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@ We refer to a "synchronisation" as meaning a complete successful extract, transf
|
|||
|
||||
There are three expected methods of using the synchronisation tools for Kanidm
|
||||
|
||||
- Kanidm as a "read only" portal allowing access to it's specific features and integrations. This is
|
||||
less of a migration, and more of a way to "feed" data into Kanidm without relying on it's internal
|
||||
- Kanidm as a "read only" portal allowing access to its specific features and integrations. This is
|
||||
less of a migration, and more of a way to "feed" data into Kanidm without relying on its internal
|
||||
administration features.
|
||||
- "Big Bang" migration. This is where all the data from another IDM is synchronised in a single
|
||||
execution and applications are swapped to Kanidm. This is rare in larger deployments, but may be
|
||||
|
@ -89,7 +89,7 @@ successor" to LDAP, and aligns with Kani's design. SCIM allows structured data t
|
|||
(unlike LDAP which is simply strings). Because of this SCIM will allow us to expose more complex
|
||||
types that previously we have not been able to provide.
|
||||
|
||||
The largest benefit to SCIM's model is it's ability to perform "batched" operations, which work with
|
||||
The largest benefit to SCIM's model is its ability to perform "batched" operations, which work with
|
||||
Kanidm's transactional model to ensure that during load events, that content is always valid and
|
||||
correct.
|
||||
|
||||
|
@ -147,7 +147,7 @@ first operation of the batch request. Failure to do so will result in an error.
|
|||
|
||||
### Schema and Attributes
|
||||
|
||||
SCIM defines a number of "generic" schemas for User's and Group's. Kanidm will provide it's own
|
||||
SCIM defines a number of "generic" schemas for User's and Group's. Kanidm will provide its own
|
||||
schema definitions that extend or replace these. TBD.
|
||||
|
||||
## Post Migration Concerns
|
||||
|
@ -213,7 +213,7 @@ such that the subsequent operations are all "modifications" rather than mixed cr
|
|||
|
||||
For each entry in the sync request, if an entry with that uuid exists retrieve it.
|
||||
|
||||
- If an entry exists in the database, assert that it's sync\_parent\_uuid is the same as our
|
||||
- If an entry exists in the database, assert that its sync\_parent\_uuid is the same as our
|
||||
agreements.
|
||||
- If there is no sync\_parent\_uuid or the sync\_parent\_uuid does not match, reject the
|
||||
operation.
|
||||
|
|
|
@ -98,12 +98,12 @@ Negative Validation
|
|||
-------------------
|
||||
|
||||
This is a negative validation of if a session has been revoked. A session is considered valid
|
||||
unless it's unique id appears in the revocation list.
|
||||
unless its unique id appears in the revocation list.
|
||||
|
||||
The session "validity" stored on the account details are for metadata an inspection purposes only, and to
|
||||
help drive the UI elements so a user can understand which sessions can be revoked that belong to them.
|
||||
|
||||
When a session is invalidated, it's session id is added to a "site-wide" revocation list, along with
|
||||
When a session is invalidated, its session id is added to a "site-wide" revocation list, along with
|
||||
the maximum time of use of that session id.
|
||||
|
||||
When a session is check as part of a standard UAT check, or an OAuth 2.0 refresh, if the session
|
||||
|
@ -111,7 +111,7 @@ id is present in the revocation list, it is denied access. Absence from the revo
|
|||
the session remains valid.
|
||||
|
||||
This method requires no gracewindow, since the replication of the revocation list will be bound to the
|
||||
performance of replication and it's distribution.
|
||||
performance of replication and its distribution.
|
||||
|
||||
The risk is that all sessions *must* have a maximum life, so that their existence in the revocation
|
||||
list is not unbounded. This version may have a greater risk of disk/memory usage due to the size of
|
||||
|
@ -141,7 +141,7 @@ Next the user revokes the token at time C, and replication has not yet occurred.
|
|||
from time B was restored.
|
||||
|
||||
In this scenario, without access to the token itself, or without scouring logs to find the session
|
||||
id that was issued, this token is effectively "lost" and can be used until it's expiry, and would
|
||||
id that was issued, this token is effectively "lost" and can be used until its expiry, and would
|
||||
be difficult to revoke.
|
||||
|
||||
Session Management
|
||||
|
@ -206,7 +206,7 @@ To achieve this we need to determine an order of the events. Let's assume a bett
|
|||
We store a "refresh id" in the refresh token, and a issued-by id in the access token. Additionally
|
||||
we store an issued-at timestamp (from the replication CID) in both.
|
||||
|
||||
When we exchange the refresh token, we check that it's refresh id, is the next allowed refresh id that can proceed.
|
||||
When we exchange the refresh token, we check that its refresh id, is the next allowed refresh id that can proceed.
|
||||
We store in the session the "latest" issued-by id + timestamp in the session,
|
||||
as well as the next "refresh token" id in the session.
|
||||
|
||||
|
|
|
@ -113,16 +113,16 @@ This question is normally asked because people want to setup multiple Kanidm ser
|
|||
single database.
|
||||
|
||||
Kanidm does not use SQL as a _database_. Kanidm uses SQL as a durable key-value store and Kanidm
|
||||
implements it's own database, caching, querying, optimisation and indexing on top of that key-value
|
||||
implements its own database, caching, querying, optimisation and indexing on top of that key-value
|
||||
store.
|
||||
|
||||
As a result, because Kanidm specifically implements it's own cache layer above the key-value store
|
||||
As a result, because Kanidm specifically implements its own cache layer above the key-value store
|
||||
(sqlite in this example) then if you were to connect two Kanidm instances to the same key-value
|
||||
store, as each server has it's own cache layer and they are not in contact, it is possible for
|
||||
writes on one server to never be observed by the second, and if the second were to then write over
|
||||
those entries it will cause loss of the changes from the first server.
|
||||
store, as each server has its own cache layer and they are not in contact, it is possible for writes
|
||||
on one server to never be observed by the second, and if the second were to then write over those
|
||||
entries it will cause loss of the changes from the first server.
|
||||
|
||||
Kanidm now implements it's own eventually consistent distributed replication which also removes the
|
||||
Kanidm now implements its own eventually consistent distributed replication which also removes the
|
||||
need for external databases to be considered.
|
||||
|
||||
## Why aren't snaps launching with `home_alias` set?
|
||||
|
|
|
@ -25,7 +25,7 @@ and acronyms when they are used, this may be a useful reference if something fee
|
|||
their database content.
|
||||
- UAT - User Authentication Token. This is a token issue by Kanidm to an account after it has
|
||||
authenticated.
|
||||
- SPN - Security Principal Name. This is a name of an account comprising it's name and domain name.
|
||||
- SPN - Security Principal Name. This is a name of an account comprising its name and domain name.
|
||||
This allows distinction between accounts with identical names over a trust boundary
|
||||
|
||||
## Internals
|
||||
|
@ -43,4 +43,4 @@ and acronyms when they are used, this may be a useful reference if something fee
|
|||
- acp - an Access Control Profile which defines a set of privileges that are granted to receivers to
|
||||
affect target entries.
|
||||
- role - A term used to express a group that is the receiver of an access control profile allowing
|
||||
it's members to affect the target entries.
|
||||
its members to affect the target entries.
|
||||
|
|
|
@ -160,7 +160,7 @@ text=If you are creating an OpenID Connect (OIDC) client you <b>MUST</b> provide
|
|||
> associated claims will be added.
|
||||
>
|
||||
> - profile - (name, family\_name, given\_name, middle\_name, nickname, preferred\_username,
|
||||
> profile, picture, website, gender, birthdate, zoneinfo, locale, and updated\_at)
|
||||
> profile, picture, website, gender, birthdate, zoneinfo, locale, and updated\_at)
|
||||
> - email - (email, email\_verified)
|
||||
> - address - (address)
|
||||
> - phone - (phone\_number, phone\_number\_verified)
|
||||
|
|
|
@ -18,7 +18,7 @@ communicate to both sides.
|
|||
Like other components of Kanidm, the LDAP sync tool will read your /etc/kanidm/config if present to
|
||||
understand how to connect to Kanidm.
|
||||
|
||||
The sync tool specific components are configured in it's own configuration file.
|
||||
The sync tool specific components are configured in its own configuration file.
|
||||
|
||||
```toml
|
||||
{{#rustdoc_include ../../../examples/kanidm-ldap-sync}}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#![deny(warnings)]
|
||||
#![warn(unused_extern_crates)]
|
||||
#![allow(non_snake_case)]
|
||||
use std::fmt::Display;
|
||||
use std::str::FromStr;
|
||||
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
|
@ -125,13 +126,13 @@ impl FromStr for LogLevel {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToString for LogLevel {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
LogLevel::Info => "info".to_string(),
|
||||
LogLevel::Debug => "debug".to_string(),
|
||||
LogLevel::Trace => "trace".to_string(),
|
||||
}
|
||||
impl Display for LogLevel {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(match self {
|
||||
LogLevel::Info => "info",
|
||||
LogLevel::Debug => "debug",
|
||||
LogLevel::Trace => "trace",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ pub enum ScimSyncRetentionMode {
|
|||
/// All entries that have their uuid present in this set are retained.
|
||||
/// Anything not present will be deleted.
|
||||
Retain(Vec<Uuid>),
|
||||
/// Any entry with it's uuid in this set will be deleted. Anything not
|
||||
/// Any entry with its UUID in this set will be deleted. Anything not
|
||||
/// present will be retained.
|
||||
Delete(Vec<Uuid>),
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::BTreeMap;
|
||||
use std::fmt;
|
||||
use std::fmt::Display;
|
||||
use utoipa::ToSchema;
|
||||
use uuid::Uuid;
|
||||
|
||||
|
@ -24,12 +25,12 @@ pub enum AccountType {
|
|||
ServiceAccount,
|
||||
}
|
||||
|
||||
impl ToString for AccountType {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
AccountType::Person => "person".to_string(),
|
||||
AccountType::ServiceAccount => "service_account".to_string(),
|
||||
}
|
||||
impl Display for AccountType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str(match self {
|
||||
AccountType::Person => "person",
|
||||
AccountType::ServiceAccount => "service_account",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ eap {
|
|||
# http://www.securiteam.com/tools/5TP012ACKE.html
|
||||
#
|
||||
# Cisco LEAP uses the MS-CHAP algorithm (but not
|
||||
# the MS-CHAP attributes) to perform it's authentication.
|
||||
# the MS-CHAP attributes) to perform its authentication.
|
||||
#
|
||||
# As a result, LEAP *requires* access to the plain-text
|
||||
# User-Password, or the NT-Password attributes.
|
||||
|
@ -884,7 +884,7 @@ eap {
|
|||
#
|
||||
# If 'cipher_list' is set here, it will over-ride the
|
||||
# 'cipher_list' configuration from the 'tls-common'
|
||||
# configuration. The EAP-FAST module has it's own
|
||||
# configuration. The EAP-FAST module has its own
|
||||
# over-ride for 'cipher_list' because the
|
||||
# specifications mandata a different set of ciphers
|
||||
# than are used by the other EAP methods.
|
||||
|
|
|
@ -1040,7 +1040,7 @@ pub async fn create_server_core(
|
|||
}
|
||||
};
|
||||
|
||||
// If we have replication configured, setup the listener with it's initial replication
|
||||
// If we have replication configured, setup the listener with its initial replication
|
||||
// map (if any).
|
||||
let (maybe_repl_handle, maybe_repl_ctrl_tx) = match &config.repl_config {
|
||||
Some(rc) => {
|
||||
|
|
|
@ -772,7 +772,7 @@ async fn repl_acceptor(
|
|||
|
||||
// ⚠️ CRITICAL - Both verifications here are needed. PEER requests
|
||||
// the client cert to be sent. FAIL_IF_NO_PEER_CERT triggers an
|
||||
// error if the cert is NOT present. FAIL_IF_NO_PEER_CERT on it's own
|
||||
// error if the cert is NOT present. FAIL_IF_NO_PEER_CERT on its own
|
||||
// DOES NOTHING.
|
||||
let mut verify = SslVerifyMode::PEER;
|
||||
verify.insert(SslVerifyMode::FAIL_IF_NO_PEER_CERT);
|
||||
|
|
|
@ -1574,7 +1574,7 @@ impl IdlSqliteWriteTransaction {
|
|||
// | schema | 1 |
|
||||
// ----------------------
|
||||
//
|
||||
// This allows each component to initialise on it's own, be
|
||||
// This allows each component to initialise on its own, be
|
||||
// rolled back individually, by upgraded in isolation, and more
|
||||
//
|
||||
// NEVER CHANGE THIS DEFINITION.
|
||||
|
|
|
@ -95,7 +95,7 @@ impl BackupCodes {
|
|||
/// the auth as the password of B was incorrect. Additionally, while A only needs the "password",
|
||||
/// B requires both the password and otp to be valid.
|
||||
///
|
||||
/// In this way, each Credential provides it's own password requirements and policy, and requires
|
||||
/// In this way, each Credential provides its own password requirements and policy, and requires
|
||||
/// some metadata to support this such as it's source and strength etc.
|
||||
pub struct Credential {
|
||||
// policy: Policy,
|
||||
|
|
|
@ -1315,7 +1315,7 @@ type IdxDiff<'a> =
|
|||
Vec<Result<(&'a AttrString, IndexType, String), (&'a AttrString, IndexType, String)>>;
|
||||
|
||||
impl<VALID> Entry<VALID, EntryCommitted> {
|
||||
/// If this entry has ever been committed to disk, retrieve it's database id number.
|
||||
/// If this entry has ever been committed to disk, retrieve its database id number.
|
||||
pub fn get_id(&self) -> u64 {
|
||||
self.state.id
|
||||
}
|
||||
|
@ -1368,7 +1368,7 @@ impl Entry<EntrySealed, EntryCommitted> {
|
|||
compare_attrs(&self.attrs, &rhs.attrs)
|
||||
}
|
||||
|
||||
/// Serialise this entry to it's Database format ready for storage.
|
||||
/// Serialise this entry to its Database format ready for storage.
|
||||
pub fn to_dbentry(&self) -> DbEntry {
|
||||
// In the future this will do extra work to process uuid
|
||||
// into "attributes" suitable for dbentry storage.
|
||||
|
@ -1418,8 +1418,8 @@ impl Entry<EntrySealed, EntryCommitted> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
/// Given this entry, extract it's primary security prinicple name, or if not present
|
||||
/// extract it's name, and if that's not present, extract it's uuid.
|
||||
/// Given this entry, extract its primary security principal name, or if not present
|
||||
/// extract its name, and if that's not present, extract its uuid.
|
||||
pub(crate) fn get_uuid2spn(&self) -> Value {
|
||||
self.attrs
|
||||
.get("spn")
|
||||
|
@ -1433,7 +1433,7 @@ impl Entry<EntrySealed, EntryCommitted> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
/// Given this entry, determine it's relative distinguished named for LDAP compatibility.
|
||||
/// Given this entry, determine its relative distinguished named for LDAP compatibility.
|
||||
///
|
||||
/// See also - `get_display_id`
|
||||
pub(crate) fn get_uuid2rdn(&self) -> String {
|
||||
|
|
|
@ -99,7 +99,7 @@ macro_rules! try_from_entry {
|
|||
|
||||
let primary = $value
|
||||
.get_ava_single_credential(Attribute::PrimaryCredential)
|
||||
.map(|v| v.clone());
|
||||
.cloned();
|
||||
|
||||
let passkeys = $value
|
||||
.get_ava_passkeys(Attribute::PassKeys)
|
||||
|
@ -173,7 +173,7 @@ macro_rules! try_from_entry {
|
|||
|
||||
let ucred = $value
|
||||
.get_ava_single_credential(Attribute::UnixPassword)
|
||||
.map(|v| v.clone());
|
||||
.cloned();
|
||||
|
||||
let _shell = $value
|
||||
.get_ava_single_iutf8(Attribute::LoginShell)
|
||||
|
|
|
@ -1598,7 +1598,7 @@ impl<'a> IdmServerCredUpdateTransaction<'a> {
|
|||
.feedback()
|
||||
.as_ref()
|
||||
.ok_or(OperationError::InvalidState)
|
||||
.map(|v| v.clone())
|
||||
.cloned()
|
||||
.map_err(|e| {
|
||||
security_info!("zxcvbn returned no feedback when score < 3 -> {:?}", e);
|
||||
// Return some generic feedback when the password is this bad.
|
||||
|
|
|
@ -1336,7 +1336,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
let expiry = odt_ct + Duration::from_secs(OAUTH2_ACCESS_TOKEN_EXPIRY as u64);
|
||||
let expires_in = OAUTH2_ACCESS_TOKEN_EXPIRY;
|
||||
let refresh_expiry = iat + OAUTH_REFRESH_TOKEN_EXPIRY as i64;
|
||||
let odt_refresh_expiry = odt_ct + Duration::from_secs(OAUTH_REFRESH_TOKEN_EXPIRY as u64);
|
||||
let odt_refresh_expiry = odt_ct + Duration::from_secs(OAUTH_REFRESH_TOKEN_EXPIRY);
|
||||
|
||||
let scope = if scopes.is_empty() {
|
||||
None
|
||||
|
|
|
@ -1475,7 +1475,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
.feedback()
|
||||
.as_ref()
|
||||
.ok_or(OperationError::InvalidState)
|
||||
.map(|v| v.clone())
|
||||
.cloned()
|
||||
.map_err(|e| {
|
||||
security_info!("zxcvbn returned no feedback when score < 3");
|
||||
e
|
||||
|
|
|
@ -101,7 +101,7 @@ macro_rules! try_from_entry {
|
|||
|
||||
let cred = $value
|
||||
.get_ava_single_credential(Attribute::UnixPassword)
|
||||
.map(|v| v.clone());
|
||||
.cloned();
|
||||
|
||||
let radius_secret = $value
|
||||
.get_ava_single_secret(Attribute::RadiusSecret)
|
||||
|
|
|
@ -256,7 +256,7 @@ impl Plugin for AttrUnique {
|
|||
//
|
||||
// Because of this we have some key properties that we can observe.
|
||||
//
|
||||
// Every node when it makes a change with regard to it's own content is already compliant
|
||||
// Every node when it makes a change with regard to its own content is already compliant
|
||||
// to attribute uniqueness. This means the consumers db content before we begin is
|
||||
// fully consistent.
|
||||
//
|
||||
|
|
|
@ -105,19 +105,19 @@ fn apply_gidnumber<T: Clone>(
|
|||
}
|
||||
} else {
|
||||
// If they provided us with a gid number, ensure it's in a safe range.
|
||||
if (gid >= GID_REGULAR_USER_MIN && gid <= GID_REGULAR_USER_MAX)
|
||||
|| (gid >= GID_UNUSED_A_MIN && gid <= GID_UNUSED_A_MAX)
|
||||
|| (gid >= GID_UNUSED_B_MIN && gid <= GID_UNUSED_B_MAX)
|
||||
|| (gid >= GID_UNUSED_C_MIN && gid <= GID_UNUSED_C_MAX)
|
||||
if (GID_REGULAR_USER_MIN..=GID_REGULAR_USER_MAX).contains(&gid)
|
||||
|| (GID_UNUSED_A_MIN..=GID_UNUSED_A_MAX).contains(&gid)
|
||||
|| (GID_UNUSED_B_MIN..= GID_UNUSED_B_MAX).contains(&gid)
|
||||
|| (GID_UNUSED_C_MIN..=GID_UNUSED_C_MAX).contains(&gid)
|
||||
// We won't ever generate an id in the nspawn range, but we do secretly allow
|
||||
// it to be set for compatability with services like freeipa or openldap. TBH
|
||||
// most people don't even use systemd nspawn anyway ...
|
||||
//
|
||||
// I made this design choice to avoid a tunable that may confuse people to
|
||||
// it's purpose. This way things "just work" for imports and existing systems
|
||||
// its purpose. This way things "just work" for imports and existing systems
|
||||
// but we do the right thing in the future.
|
||||
|| (gid >= GID_NSPAWN_MIN && gid <= GID_NSPAWN_MAX)
|
||||
|| (gid >= GID_UNUSED_D_MIN && gid <= GID_UNUSED_D_MAX)
|
||||
|| (GID_NSPAWN_MIN..=GID_NSPAWN_MAX).contains(&gid)
|
||||
|| (GID_UNUSED_D_MIN..=GID_UNUSED_D_MAX).contains(&gid)
|
||||
{
|
||||
Ok(())
|
||||
} else {
|
||||
|
|
|
@ -86,7 +86,7 @@ impl Plugin for KeyObjectManagement {
|
|||
Err(e) => return vec![e],
|
||||
};
|
||||
|
||||
let errs = key_objects
|
||||
key_objects
|
||||
.into_iter()
|
||||
.filter_map(|key_object_entry| {
|
||||
let object_uuid = key_object_entry.get_uuid();
|
||||
|
@ -125,10 +125,8 @@ impl Plugin for KeyObjectManagement {
|
|||
|
||||
None
|
||||
})
|
||||
.map(|err| Err(err))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
errs
|
||||
.map(Err)
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -456,7 +456,6 @@ impl AccessControlProfile {
|
|||
// targetscope, and turn to real filter
|
||||
let targetscope_f: ProtoFilter = value
|
||||
.get_ava_single_protofilter(Attribute::AcpTargetScope)
|
||||
// .map(|pf| pf.clone())
|
||||
.cloned()
|
||||
.ok_or_else(|| {
|
||||
admin_error!("Missing {}", Attribute::AcpTargetScope);
|
||||
|
|
|
@ -94,7 +94,7 @@ impl KeyProviderInternal {
|
|||
match usage {
|
||||
KeyUsage::JwsEs256 => {
|
||||
let jws_es256_ref =
|
||||
jws_es256.get_or_insert_with(|| KeyObjectInternalJwtEs256::default());
|
||||
jws_es256.get_or_insert_with(KeyObjectInternalJwtEs256::default);
|
||||
|
||||
jws_es256_ref.load(
|
||||
key_id,
|
||||
|
@ -105,8 +105,8 @@ impl KeyProviderInternal {
|
|||
)?;
|
||||
}
|
||||
KeyUsage::JweA128GCM => {
|
||||
let jwe_a128gcm_ref = jwe_a128gcm
|
||||
.get_or_insert_with(|| KeyObjectInternalJweA128GCM::default());
|
||||
let jwe_a128gcm_ref =
|
||||
jwe_a128gcm.get_or_insert_with(KeyObjectInternalJweA128GCM::default);
|
||||
|
||||
jwe_a128gcm_ref.load(
|
||||
key_id,
|
||||
|
@ -855,7 +855,7 @@ impl KeyObjectT for KeyObjectInternal {
|
|||
) -> Result<(), OperationError> {
|
||||
let koi = self
|
||||
.jws_es256
|
||||
.get_or_insert_with(|| KeyObjectInternalJwtEs256::default());
|
||||
.get_or_insert_with(KeyObjectInternalJwtEs256::default);
|
||||
|
||||
koi.import(import_keys, valid_from, cid)
|
||||
}
|
||||
|
@ -863,7 +863,7 @@ impl KeyObjectT for KeyObjectInternal {
|
|||
fn jws_es256_assert(&mut self, valid_from: Duration, cid: &Cid) -> Result<(), OperationError> {
|
||||
let koi = self
|
||||
.jws_es256
|
||||
.get_or_insert_with(|| KeyObjectInternalJwtEs256::default());
|
||||
.get_or_insert_with(KeyObjectInternalJwtEs256::default);
|
||||
|
||||
koi.assert_active(valid_from, cid)
|
||||
}
|
||||
|
@ -895,7 +895,7 @@ impl KeyObjectT for KeyObjectInternal {
|
|||
) -> Result<(), OperationError> {
|
||||
let koi = self
|
||||
.jwe_a128gcm
|
||||
.get_or_insert_with(|| KeyObjectInternalJweA128GCM::default());
|
||||
.get_or_insert_with(KeyObjectInternalJweA128GCM::default);
|
||||
|
||||
koi.assert_active(valid_from, cid)
|
||||
}
|
||||
|
@ -936,20 +936,17 @@ impl KeyObjectT for KeyObjectInternal {
|
|||
);
|
||||
let key_vs = ValueSetKeyInternal::from_key_iter(key_iter)? as ValueSet;
|
||||
|
||||
let mut attrs = Vec::with_capacity(3);
|
||||
|
||||
attrs.push((
|
||||
Ok(vec![
|
||||
(
|
||||
Attribute::Class,
|
||||
ValueSetIutf8::new(EntryClass::KeyObjectInternal.into()) as ValueSet,
|
||||
));
|
||||
|
||||
attrs.push((
|
||||
),
|
||||
(
|
||||
Attribute::KeyProvider,
|
||||
ValueSetRefer::new(self.provider.uuid()) as ValueSet,
|
||||
));
|
||||
|
||||
attrs.push((Attribute::KeyInternalData, key_vs));
|
||||
Ok(attrs)
|
||||
),
|
||||
(Attribute::KeyInternalData, key_vs),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -155,11 +155,7 @@ impl KeyProvidersTransaction for KeyProvidersReadTransaction {
|
|||
}
|
||||
|
||||
fn get_key_object_handle(&self, key_object_uuid: Uuid) -> Option<Arc<KeyObject>> {
|
||||
self.inner
|
||||
.deref()
|
||||
.objects
|
||||
.get(&key_object_uuid)
|
||||
.map(|k| k.clone())
|
||||
self.inner.deref().objects.get(&key_object_uuid).cloned()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,11 +183,7 @@ impl<'a> KeyProvidersTransaction for KeyProvidersWriteTransaction<'a> {
|
|||
}
|
||||
|
||||
fn get_key_object_handle(&self, key_object_uuid: Uuid) -> Option<Arc<KeyObject>> {
|
||||
self.inner
|
||||
.deref()
|
||||
.objects
|
||||
.get(&key_object_uuid)
|
||||
.map(|k| k.clone())
|
||||
self.inner.deref().objects.get(&key_object_uuid).cloned()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -919,7 +919,7 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
|||
// Update anonymous with the correct entry manager,
|
||||
BUILTIN_ACCOUNT_ANONYMOUS_DL6.clone().into(),
|
||||
// Add the internal key provider.
|
||||
E_KEY_PROVIDER_INTERNAL_DL6.clone().into(),
|
||||
E_KEY_PROVIDER_INTERNAL_DL6.clone(),
|
||||
];
|
||||
|
||||
idm_data
|
||||
|
@ -942,10 +942,10 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
|||
// Reload such that the new default key provider is loaded.
|
||||
self.reload()?;
|
||||
|
||||
// Update the domain entry to contain it's key object, which can now be generated.
|
||||
// Update the domain entry to contain its key object, which can now be generated.
|
||||
let idm_data = [
|
||||
IDM_ACP_DOMAIN_ADMIN_DL6.clone().into(),
|
||||
E_DOMAIN_INFO_DL6.clone().into(),
|
||||
E_DOMAIN_INFO_DL6.clone(),
|
||||
];
|
||||
idm_data
|
||||
.into_iter()
|
||||
|
|
|
@ -1270,7 +1270,7 @@ impl QueryServer {
|
|||
resolve_filter_cache,
|
||||
dyngroup_cache,
|
||||
cid_max,
|
||||
key_providers: key_providers,
|
||||
key_providers,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -255,7 +255,7 @@ impl ValueSetEmailAddress {
|
|||
|
||||
pub fn push(&mut self, a: String, primary: bool) -> bool {
|
||||
if primary {
|
||||
self.primary = a.clone();
|
||||
self.primary.clone_from(&a);
|
||||
}
|
||||
self.set.insert(a)
|
||||
}
|
||||
|
@ -318,7 +318,7 @@ impl ValueSetT for ValueSetEmailAddress {
|
|||
Value::EmailAddress(a, p) => {
|
||||
// if the set was empty, we need to force update primary.
|
||||
if p || self.set.is_empty() {
|
||||
self.primary = a.clone();
|
||||
self.primary.clone_from(&a);
|
||||
}
|
||||
Ok(self.set.insert(a))
|
||||
}
|
||||
|
|
|
@ -160,8 +160,8 @@ impl ValueSetKeyInternal {
|
|||
}
|
||||
|
||||
impl ValueSetT for ValueSetKeyInternal {
|
||||
fn insert_checked(&mut self, value: crate::value::Value) -> Result<bool, OperationError> {
|
||||
match value {
|
||||
fn insert_checked(&mut self, _value: crate::value::Value) -> Result<bool, OperationError> {
|
||||
// match value {
|
||||
// I'm not sure we ever need to actually push this?
|
||||
/*
|
||||
Value::KeyInternal {
|
||||
|
@ -174,11 +174,11 @@ impl ValueSetT for ValueSetKeyInternal {
|
|||
todo!();
|
||||
}
|
||||
*/
|
||||
_ => {
|
||||
// _ => {
|
||||
debug_assert!(false);
|
||||
Err(OperationError::InvalidValueState)
|
||||
}
|
||||
}
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
fn clear(&mut self) {
|
||||
|
@ -258,7 +258,7 @@ impl ValueSetT for ValueSetKeyInternal {
|
|||
}
|
||||
|
||||
fn generate_idx_eq_keys(&self) -> Vec<String> {
|
||||
self.map.keys().map(|kid| hex::encode(kid)).collect()
|
||||
self.map.keys().map(hex::encode).collect()
|
||||
}
|
||||
|
||||
fn syntax(&self) -> SyntaxType {
|
||||
|
@ -313,8 +313,8 @@ impl ValueSetT for ValueSetKeyInternal {
|
|||
)| {
|
||||
Value::KeyInternal {
|
||||
id: id.clone(),
|
||||
usage: usage.clone(),
|
||||
status: status.clone(),
|
||||
usage: *usage,
|
||||
status: *status,
|
||||
status_cid: status_cid.clone(),
|
||||
der: der.clone(),
|
||||
valid_from: *valid_from,
|
||||
|
@ -358,9 +358,7 @@ impl ValueSetT for ValueSetKeyInternal {
|
|||
}
|
||||
|
||||
fn repl_merge_valueset(&self, older: &ValueSet, trim_cid: &Cid) -> Option<ValueSet> {
|
||||
let Some(b) = older.as_key_internal_map() else {
|
||||
return None;
|
||||
};
|
||||
let b = older.as_key_internal_map()?;
|
||||
|
||||
let mut map = self.map.clone();
|
||||
|
||||
|
|
|
@ -446,7 +446,7 @@ impl ValueSetT for ValueSetSession {
|
|||
let time_idx: BTreeMap<OffsetDateTime, Uuid> = self
|
||||
.map
|
||||
.iter()
|
||||
.map(|(session_id, session)| (session.issued_at.clone(), *session_id))
|
||||
.map(|(session_id, session)| (session.issued_at, *session_id))
|
||||
.collect();
|
||||
|
||||
let to_take = self.map.len() - SESSION_MAXIMUM;
|
||||
|
@ -697,9 +697,7 @@ impl ValueSetT for ValueSetSession {
|
|||
fn repl_merge_valueset(&self, older: &ValueSet, trim_cid: &Cid) -> Option<ValueSet> {
|
||||
// If the older value has a different type - return nothing, we
|
||||
// just take the newer value.
|
||||
let Some(b) = older.as_session_map() else {
|
||||
return None;
|
||||
};
|
||||
let b = older.as_session_map()?;
|
||||
// We can't just do merge maps here, we have to be aware of the
|
||||
// session.state value and what it currently is set to.
|
||||
let mut map = self.map.clone();
|
||||
|
|
Binary file not shown.
Binary file not shown.
BIN
server/web_ui/pkg/external/bootstrap.min.css.br
vendored
BIN
server/web_ui/pkg/external/bootstrap.min.css.br
vendored
Binary file not shown.
BIN
server/web_ui/pkg/external/bootstrap.min.css.map.br
vendored
BIN
server/web_ui/pkg/external/bootstrap.min.css.map.br
vendored
Binary file not shown.
BIN
server/web_ui/pkg/external/viz.js.br
vendored
BIN
server/web_ui/pkg/external/viz.js.br
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -232,19 +232,19 @@ function addBorrowedObject(obj) {
|
|||
}
|
||||
function __wbg_adapter_38(arg0, arg1, arg2) {
|
||||
try {
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hf1bc68da25052e00(arg0, arg1, addBorrowedObject(arg2));
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h669f989b94be751f(arg0, arg1, addBorrowedObject(arg2));
|
||||
} finally {
|
||||
heap[stack_pointer++] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function __wbg_adapter_41(arg0, arg1, arg2) {
|
||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h71952e63cc945b16(arg0, arg1, addHeapObject(arg2));
|
||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hec179d3e9a07fffa(arg0, arg1, addHeapObject(arg2));
|
||||
}
|
||||
|
||||
function __wbg_adapter_44(arg0, arg1, arg2) {
|
||||
try {
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h75b8ec943ddde760(arg0, arg1, addBorrowedObject(arg2));
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__heeb70e791d5cf4d1(arg0, arg1, addBorrowedObject(arg2));
|
||||
} finally {
|
||||
heap[stack_pointer++] = undefined;
|
||||
}
|
||||
|
@ -379,10 +379,10 @@ function __wbg_get_imports() {
|
|||
const ret = getObject(arg0) in getObject(arg1);
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_initgraphviz_c3ff41f4a4b3769c = function(arg0, arg1) {
|
||||
imports.wbg.__wbg_initgraphviz_f624e765cc5186ad = function(arg0, arg1) {
|
||||
init_graphviz(getStringFromWasm0(arg0, arg1));
|
||||
};
|
||||
imports.wbg.__wbg_openblank_46584d7c929c5e36 = function(arg0, arg1) {
|
||||
imports.wbg.__wbg_openblank_268c6be364354a77 = function(arg0, arg1) {
|
||||
open_blank(getStringFromWasm0(arg0, arg1));
|
||||
};
|
||||
imports.wbg.__wbindgen_boolean_get = function(arg0) {
|
||||
|
@ -404,6 +404,14 @@ function __wbg_get_imports() {
|
|||
const ret = arg0;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_listenerid_12315eee21527820 = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).__yew_listener_id;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = isLikeNone(ret) ? 0 : ret;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
|
||||
};
|
||||
imports.wbg.__wbg_setlistenerid_3183aae8fa5840fb = function(arg0, arg1) {
|
||||
getObject(arg0).__yew_listener_id = arg1 >>> 0;
|
||||
};
|
||||
imports.wbg.__wbg_cachekey_b61393159c57fd7b = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).__yew_subtree_cache_key;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = isLikeNone(ret) ? 0 : ret;
|
||||
|
@ -420,14 +428,6 @@ function __wbg_get_imports() {
|
|||
imports.wbg.__wbg_setcachekey_80183b7cfc421143 = function(arg0, arg1) {
|
||||
getObject(arg0).__yew_subtree_cache_key = arg1 >>> 0;
|
||||
};
|
||||
imports.wbg.__wbg_listenerid_12315eee21527820 = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).__yew_listener_id;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = isLikeNone(ret) ? 0 : ret;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
|
||||
};
|
||||
imports.wbg.__wbg_setlistenerid_3183aae8fa5840fb = function(arg0, arg1) {
|
||||
getObject(arg0).__yew_listener_id = arg1 >>> 0;
|
||||
};
|
||||
imports.wbg.__wbg_new_abda76e883ba8a5f = function() {
|
||||
const ret = new Error();
|
||||
return addHeapObject(ret);
|
||||
|
@ -450,9 +450,6 @@ function __wbg_get_imports() {
|
|||
wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
|
||||
}
|
||||
};
|
||||
imports.wbg.__wbg_queueMicrotask_481971b0d87f3dd4 = function(arg0) {
|
||||
queueMicrotask(getObject(arg0));
|
||||
};
|
||||
imports.wbg.__wbg_queueMicrotask_3cbae2ec6b6cd3d6 = function(arg0) {
|
||||
const ret = getObject(arg0).queueMicrotask;
|
||||
return addHeapObject(ret);
|
||||
|
@ -461,6 +458,9 @@ function __wbg_get_imports() {
|
|||
const ret = typeof(getObject(arg0)) === 'function';
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_queueMicrotask_481971b0d87f3dd4 = function(arg0) {
|
||||
queueMicrotask(getObject(arg0));
|
||||
};
|
||||
imports.wbg.__wbg_getwithrefkey_5e6d9547403deab8 = function(arg0, arg1) {
|
||||
const ret = getObject(arg0)[getObject(arg1)];
|
||||
return addHeapObject(ret);
|
||||
|
@ -578,14 +578,21 @@ function __wbg_get_imports() {
|
|||
imports.wbg.__wbg_setAttribute_3c9f6c303b696daa = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).setAttribute(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_value_d7f5bfbd9302c14b = function(arg0, arg1) {
|
||||
imports.wbg.__wbg_checked_749a34774f2df2e3 = function(arg0) {
|
||||
const ret = getObject(arg0).checked;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_setchecked_931ff2ed2cd3ebfd = function(arg0, arg1) {
|
||||
getObject(arg0).checked = arg1 !== 0;
|
||||
};
|
||||
imports.wbg.__wbg_value_47fe6384562f52ab = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).value;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_setvalue_090972231f0a4f6f = function(arg0, arg1, arg2) {
|
||||
imports.wbg.__wbg_setvalue_78cb4f1fef58ae98 = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
|
||||
};
|
||||
imports.wbg.__wbg_getItem_164e8e5265095b87 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
||||
|
@ -601,26 +608,16 @@ function __wbg_get_imports() {
|
|||
imports.wbg.__wbg_setItem_ba2bb41d73dac079 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).setItem(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_add_dcb05a8ba423bdac = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).add(getStringFromWasm0(arg1, arg2));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_get_0ebaad3318b38f2a = function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
||||
const ret = getObject(arg1).get(getStringFromWasm0(arg2, arg3));
|
||||
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_set_cb0e7a5c2dd66afd = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).set(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_href_2edbae9e92cdfeff = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).href;
|
||||
imports.wbg.__wbg_value_d7f5bfbd9302c14b = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).value;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_setvalue_090972231f0a4f6f = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
|
||||
};
|
||||
imports.wbg.__wbg_href_7bfb3b2fdc0a6c3f = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).href;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
|
@ -663,6 +660,53 @@ function __wbg_get_imports() {
|
|||
const ret = new URL(getStringFromWasm0(arg0, arg1), getStringFromWasm0(arg2, arg3));
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_add_dcb05a8ba423bdac = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).add(getStringFromWasm0(arg1, arg2));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_addEventListener_4283b15b4f039eb5 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), getObject(arg4));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_removeEventListener_5d31483804421bfa = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).removeEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), arg4 !== 0);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_href_706b235ecfe6848c = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg1).href;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_sethref_b94692d1a9f05b53 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).href = getStringFromWasm0(arg1, arg2);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_pathname_5449afe3829f96a1 = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg1).pathname;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_search_489f12953342ec1f = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg1).search;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_hash_553098e838e06c1d = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg1).hash;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_href_2edbae9e92cdfeff = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).href;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_parentNode_6be3abff20e1a5fb = function(arg0) {
|
||||
const ret = getObject(arg0).parentNode;
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
|
@ -701,52 +745,30 @@ function __wbg_get_imports() {
|
|||
const ret = getObject(arg0).removeChild(getObject(arg1));
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_href_706b235ecfe6848c = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg1).href;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_sethref_b94692d1a9f05b53 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).href = getStringFromWasm0(arg1, arg2);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_pathname_5449afe3829f96a1 = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg1).pathname;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_search_489f12953342ec1f = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg1).search;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_hash_553098e838e06c1d = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg1).hash;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_bubbles_abce839854481bc6 = function(arg0) {
|
||||
const ret = getObject(arg0).bubbles;
|
||||
imports.wbg.__wbg_instanceof_ShadowRoot_9db040264422e84a = function(arg0) {
|
||||
let result;
|
||||
try {
|
||||
result = getObject(arg0) instanceof ShadowRoot;
|
||||
} catch (_) {
|
||||
result = false;
|
||||
}
|
||||
const ret = result;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_cancelBubble_c0aa3172524eb03c = function(arg0) {
|
||||
const ret = getObject(arg0).cancelBubble;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_composedPath_58473fd5ae55f2cd = function(arg0) {
|
||||
const ret = getObject(arg0).composedPath();
|
||||
imports.wbg.__wbg_host_c667c7623404d6bf = function(arg0) {
|
||||
const ret = getObject(arg0).host;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_preventDefault_b1a4aafc79409429 = function(arg0) {
|
||||
getObject(arg0).preventDefault();
|
||||
};
|
||||
imports.wbg.__wbg_get_0ebaad3318b38f2a = function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
||||
const ret = getObject(arg1).get(getStringFromWasm0(arg2, arg3));
|
||||
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_set_cb0e7a5c2dd66afd = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).set(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_state_9cc3f933b7d50acb = function() { return handleError(function (arg0) {
|
||||
const ret = getObject(arg0).state;
|
||||
return addHeapObject(ret);
|
||||
|
@ -754,29 +776,6 @@ function __wbg_get_imports() {
|
|||
imports.wbg.__wbg_pushState_b8e8d346f8bb33fd = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
|
||||
getObject(arg0).pushState(getObject(arg1), getStringFromWasm0(arg2, arg3), arg4 === 0 ? undefined : getStringFromWasm0(arg4, arg5));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_checked_749a34774f2df2e3 = function(arg0) {
|
||||
const ret = getObject(arg0).checked;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_setchecked_931ff2ed2cd3ebfd = function(arg0, arg1) {
|
||||
getObject(arg0).checked = arg1 !== 0;
|
||||
};
|
||||
imports.wbg.__wbg_value_47fe6384562f52ab = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).value;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_setvalue_78cb4f1fef58ae98 = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
|
||||
};
|
||||
imports.wbg.__wbg_addEventListener_4283b15b4f039eb5 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), getObject(arg4));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_removeEventListener_5d31483804421bfa = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).removeEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), arg4 !== 0);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_headers_abb199c3be8d817c = function(arg0) {
|
||||
const ret = getObject(arg0).headers;
|
||||
return addHeapObject(ret);
|
||||
|
@ -807,20 +806,21 @@ function __wbg_get_imports() {
|
|||
const ret = getObject(arg0).json();
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_instanceof_ShadowRoot_9db040264422e84a = function(arg0) {
|
||||
let result;
|
||||
try {
|
||||
result = getObject(arg0) instanceof ShadowRoot;
|
||||
} catch (_) {
|
||||
result = false;
|
||||
}
|
||||
const ret = result;
|
||||
imports.wbg.__wbg_bubbles_abce839854481bc6 = function(arg0) {
|
||||
const ret = getObject(arg0).bubbles;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_host_c667c7623404d6bf = function(arg0) {
|
||||
const ret = getObject(arg0).host;
|
||||
imports.wbg.__wbg_cancelBubble_c0aa3172524eb03c = function(arg0) {
|
||||
const ret = getObject(arg0).cancelBubble;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_composedPath_58473fd5ae55f2cd = function(arg0) {
|
||||
const ret = getObject(arg0).composedPath();
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_preventDefault_b1a4aafc79409429 = function(arg0) {
|
||||
getObject(arg0).preventDefault();
|
||||
};
|
||||
imports.wbg.__wbg_get_bd8e338fbd5f5cc8 = function(arg0, arg1) {
|
||||
const ret = getObject(arg0)[arg1 >>> 0];
|
||||
return addHeapObject(ret);
|
||||
|
@ -977,14 +977,14 @@ function __wbg_get_imports() {
|
|||
const ret = result;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_stringify_8887fe74e1c50d81 = function() { return handleError(function (arg0) {
|
||||
const ret = JSON.stringify(getObject(arg0));
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_set_1f9b04f170055d33 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
|
||||
return ret;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_stringify_8887fe74e1c50d81 = function() { return handleError(function (arg0) {
|
||||
const ret = JSON.stringify(getObject(arg0));
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {
|
||||
const ret = debugString(getObject(arg1));
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
|
@ -999,16 +999,16 @@ function __wbg_get_imports() {
|
|||
const ret = wasm.memory;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper1202 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 563, __wbg_adapter_38);
|
||||
imports.wbg.__wbindgen_closure_wrapper1297 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 592, __wbg_adapter_38);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper1440 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 649, __wbg_adapter_41);
|
||||
imports.wbg.__wbindgen_closure_wrapper1408 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 639, __wbg_adapter_41);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper1473 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 665, __wbg_adapter_44);
|
||||
imports.wbg.__wbindgen_closure_wrapper1439 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 656, __wbg_adapter_44);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -239,19 +239,19 @@ function addBorrowedObject(obj) {
|
|||
}
|
||||
function __wbg_adapter_48(arg0, arg1, arg2) {
|
||||
try {
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h745fe1e798682f45(arg0, arg1, addBorrowedObject(arg2));
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hc006ce98f00d83e0(arg0, arg1, addBorrowedObject(arg2));
|
||||
} finally {
|
||||
heap[stack_pointer++] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function __wbg_adapter_51(arg0, arg1, arg2) {
|
||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h71952e63cc945b16(arg0, arg1, addHeapObject(arg2));
|
||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hec179d3e9a07fffa(arg0, arg1, addHeapObject(arg2));
|
||||
}
|
||||
|
||||
function __wbg_adapter_54(arg0, arg1, arg2) {
|
||||
try {
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h2b0420336379f71e(arg0, arg1, addBorrowedObject(arg2));
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h8e5f8844707a2983(arg0, arg1, addBorrowedObject(arg2));
|
||||
} finally {
|
||||
heap[stack_pointer++] = undefined;
|
||||
}
|
||||
|
@ -362,6 +362,21 @@ function __wbg_get_imports() {
|
|||
const ret = typeof(getObject(arg0)) === 'bigint';
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbindgen_number_get = function(arg0, arg1) {
|
||||
const obj = getObject(arg1);
|
||||
const ret = typeof(obj) === 'number' ? obj : undefined;
|
||||
getFloat64Memory0()[arg0 / 8 + 1] = isLikeNone(ret) ? 0 : ret;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_is_object = function(arg0) {
|
||||
const val = getObject(arg0);
|
||||
const ret = typeof(val) === 'object' && val !== null;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbindgen_in = function(arg0, arg1) {
|
||||
const ret = getObject(arg0) in getObject(arg1);
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbindgen_bigint_from_i64 = function(arg0) {
|
||||
const ret = arg0;
|
||||
return addHeapObject(ret);
|
||||
|
@ -378,21 +393,6 @@ function __wbg_get_imports() {
|
|||
const ret = new Error(getStringFromWasm0(arg0, arg1));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_number_get = function(arg0, arg1) {
|
||||
const obj = getObject(arg1);
|
||||
const ret = typeof(obj) === 'number' ? obj : undefined;
|
||||
getFloat64Memory0()[arg0 / 8 + 1] = isLikeNone(ret) ? 0 : ret;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_is_object = function(arg0) {
|
||||
const val = getObject(arg0);
|
||||
const ret = typeof(val) === 'object' && val !== null;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbindgen_in = function(arg0, arg1) {
|
||||
const ret = getObject(arg0) in getObject(arg1);
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbindgen_is_string = function(arg0) {
|
||||
const ret = typeof(getObject(arg0)) === 'string';
|
||||
return ret;
|
||||
|
@ -414,6 +414,14 @@ function __wbg_get_imports() {
|
|||
const ret = getObject(arg0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_listenerid_12315eee21527820 = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).__yew_listener_id;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = isLikeNone(ret) ? 0 : ret;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
|
||||
};
|
||||
imports.wbg.__wbg_setlistenerid_3183aae8fa5840fb = function(arg0, arg1) {
|
||||
getObject(arg0).__yew_listener_id = arg1 >>> 0;
|
||||
};
|
||||
imports.wbg.__wbg_cachekey_b61393159c57fd7b = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).__yew_subtree_cache_key;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = isLikeNone(ret) ? 0 : ret;
|
||||
|
@ -430,14 +438,6 @@ function __wbg_get_imports() {
|
|||
imports.wbg.__wbg_setcachekey_80183b7cfc421143 = function(arg0, arg1) {
|
||||
getObject(arg0).__yew_subtree_cache_key = arg1 >>> 0;
|
||||
};
|
||||
imports.wbg.__wbg_listenerid_12315eee21527820 = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).__yew_listener_id;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = isLikeNone(ret) ? 0 : ret;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
|
||||
};
|
||||
imports.wbg.__wbg_setlistenerid_3183aae8fa5840fb = function(arg0, arg1) {
|
||||
getObject(arg0).__yew_listener_id = arg1 >>> 0;
|
||||
};
|
||||
imports.wbg.__wbg_new_abda76e883ba8a5f = function() {
|
||||
const ret = new Error();
|
||||
return addHeapObject(ret);
|
||||
|
@ -471,9 +471,6 @@ function __wbg_get_imports() {
|
|||
imports.wbg.__wbg_set_20cbc34131e76824 = function(arg0, arg1, arg2) {
|
||||
getObject(arg0)[takeObject(arg1)] = takeObject(arg2);
|
||||
};
|
||||
imports.wbg.__wbg_queueMicrotask_481971b0d87f3dd4 = function(arg0) {
|
||||
queueMicrotask(getObject(arg0));
|
||||
};
|
||||
imports.wbg.__wbg_queueMicrotask_3cbae2ec6b6cd3d6 = function(arg0) {
|
||||
const ret = getObject(arg0).queueMicrotask;
|
||||
return addHeapObject(ret);
|
||||
|
@ -482,6 +479,9 @@ function __wbg_get_imports() {
|
|||
const ret = typeof(getObject(arg0)) === 'function';
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_queueMicrotask_481971b0d87f3dd4 = function(arg0) {
|
||||
queueMicrotask(getObject(arg0));
|
||||
};
|
||||
imports.wbg.__wbg_getwithrefkey_5e6d9547403deab8 = function(arg0, arg1) {
|
||||
const ret = getObject(arg0)[getObject(arg1)];
|
||||
return addHeapObject(ret);
|
||||
|
@ -630,36 +630,12 @@ function __wbg_get_imports() {
|
|||
imports.wbg.__wbg_focus_39d4b8ba8ff9df14 = function() { return handleError(function (arg0) {
|
||||
getObject(arg0).focus();
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_instanceof_HtmlInputElement_307512fe1252c849 = function(arg0) {
|
||||
let result;
|
||||
try {
|
||||
result = getObject(arg0) instanceof HTMLInputElement;
|
||||
} catch (_) {
|
||||
result = false;
|
||||
}
|
||||
const ret = result;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_checked_749a34774f2df2e3 = function(arg0) {
|
||||
const ret = getObject(arg0).checked;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_setchecked_931ff2ed2cd3ebfd = function(arg0, arg1) {
|
||||
getObject(arg0).checked = arg1 !== 0;
|
||||
};
|
||||
imports.wbg.__wbg_value_47fe6384562f52ab = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).value;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_setvalue_78cb4f1fef58ae98 = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
|
||||
};
|
||||
imports.wbg.__wbg_log_5bb5f88f245d7762 = function(arg0) {
|
||||
console.log(getObject(arg0));
|
||||
};
|
||||
imports.wbg.__wbg_add_dcb05a8ba423bdac = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).add(getStringFromWasm0(arg1, arg2));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_remove_698118fb25ab8150 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_href_2edbae9e92cdfeff = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).href;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
|
@ -667,28 +643,39 @@ function __wbg_get_imports() {
|
|||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_value_d7f5bfbd9302c14b = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).value;
|
||||
imports.wbg.__wbg_href_706b235ecfe6848c = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg1).href;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_setvalue_090972231f0a4f6f = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
|
||||
};
|
||||
imports.wbg.__wbg_getItem_164e8e5265095b87 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
||||
const ret = getObject(arg1).getItem(getStringFromWasm0(arg2, arg3));
|
||||
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len1 = WASM_VECTOR_LEN;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_sethref_b94692d1a9f05b53 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).href = getStringFromWasm0(arg1, arg2);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_pathname_5449afe3829f96a1 = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg1).pathname;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_removeItem_c0321116dc514363 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).removeItem(getStringFromWasm0(arg1, arg2));
|
||||
imports.wbg.__wbg_search_489f12953342ec1f = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg1).search;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_setItem_ba2bb41d73dac079 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).setItem(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
||||
imports.wbg.__wbg_hash_553098e838e06c1d = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg1).hash;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_replace_91b3d4a8be8b0f58 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).replace(getStringFromWasm0(arg1, arg2));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_addEventListener_4283b15b4f039eb5 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), getObject(arg4));
|
||||
|
@ -696,6 +683,16 @@ function __wbg_get_imports() {
|
|||
imports.wbg.__wbg_removeEventListener_5d31483804421bfa = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).removeEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), arg4 !== 0);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_log_5bb5f88f245d7762 = function(arg0) {
|
||||
console.log(getObject(arg0));
|
||||
};
|
||||
imports.wbg.__wbg_state_9cc3f933b7d50acb = function() { return handleError(function (arg0) {
|
||||
const ret = getObject(arg0).state;
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_pushState_b8e8d346f8bb33fd = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
|
||||
getObject(arg0).pushState(getObject(arg1), getStringFromWasm0(arg2, arg3), arg4 === 0 ? undefined : getStringFromWasm0(arg4, arg5));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_headers_abb199c3be8d817c = function(arg0) {
|
||||
const ret = getObject(arg0).headers;
|
||||
return addHeapObject(ret);
|
||||
|
@ -726,20 +723,6 @@ function __wbg_get_imports() {
|
|||
const ret = getObject(arg0).json();
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_instanceof_ShadowRoot_9db040264422e84a = function(arg0) {
|
||||
let result;
|
||||
try {
|
||||
result = getObject(arg0) instanceof ShadowRoot;
|
||||
} catch (_) {
|
||||
result = false;
|
||||
}
|
||||
const ret = result;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_host_c667c7623404d6bf = function(arg0) {
|
||||
const ret = getObject(arg0).host;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_href_7bfb3b2fdc0a6c3f = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).href;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
|
@ -779,75 +762,6 @@ function __wbg_get_imports() {
|
|||
const ret = new URL(getStringFromWasm0(arg0, arg1), getStringFromWasm0(arg2, arg3));
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_add_dcb05a8ba423bdac = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).add(getStringFromWasm0(arg1, arg2));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_remove_698118fb25ab8150 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_get_0ebaad3318b38f2a = function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
||||
const ret = getObject(arg1).get(getStringFromWasm0(arg2, arg3));
|
||||
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_set_cb0e7a5c2dd66afd = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).set(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_href_706b235ecfe6848c = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg1).href;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_sethref_b94692d1a9f05b53 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).href = getStringFromWasm0(arg1, arg2);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_pathname_5449afe3829f96a1 = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg1).pathname;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_search_489f12953342ec1f = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg1).search;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_hash_553098e838e06c1d = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg1).hash;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_replace_91b3d4a8be8b0f58 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).replace(getStringFromWasm0(arg1, arg2));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_get_af826bc073cbd7b3 = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg0).get(getObject(arg1));
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_state_9cc3f933b7d50acb = function() { return handleError(function (arg0) {
|
||||
const ret = getObject(arg0).state;
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_pushState_b8e8d346f8bb33fd = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
|
||||
getObject(arg0).pushState(getObject(arg1), getStringFromWasm0(arg2, arg3), arg4 === 0 ? undefined : getStringFromWasm0(arg4, arg5));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_credentials_301bbb1c5ba6b52c = function(arg0) {
|
||||
const ret = getObject(arg0).credentials;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_getClientExtensionResults_a849d498bd960116 = function(arg0) {
|
||||
const ret = getObject(arg0).getClientExtensionResults();
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_bubbles_abce839854481bc6 = function(arg0) {
|
||||
const ret = getObject(arg0).bubbles;
|
||||
return ret;
|
||||
|
@ -863,6 +777,56 @@ function __wbg_get_imports() {
|
|||
imports.wbg.__wbg_preventDefault_b1a4aafc79409429 = function(arg0) {
|
||||
getObject(arg0).preventDefault();
|
||||
};
|
||||
imports.wbg.__wbg_instanceof_HtmlInputElement_307512fe1252c849 = function(arg0) {
|
||||
let result;
|
||||
try {
|
||||
result = getObject(arg0) instanceof HTMLInputElement;
|
||||
} catch (_) {
|
||||
result = false;
|
||||
}
|
||||
const ret = result;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_checked_749a34774f2df2e3 = function(arg0) {
|
||||
const ret = getObject(arg0).checked;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_setchecked_931ff2ed2cd3ebfd = function(arg0, arg1) {
|
||||
getObject(arg0).checked = arg1 !== 0;
|
||||
};
|
||||
imports.wbg.__wbg_value_47fe6384562f52ab = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).value;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_setvalue_78cb4f1fef58ae98 = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
|
||||
};
|
||||
imports.wbg.__wbg_getItem_164e8e5265095b87 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
||||
const ret = getObject(arg1).getItem(getStringFromWasm0(arg2, arg3));
|
||||
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_removeItem_c0321116dc514363 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).removeItem(getStringFromWasm0(arg1, arg2));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_setItem_ba2bb41d73dac079 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).setItem(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_get_0ebaad3318b38f2a = function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
||||
const ret = getObject(arg1).get(getStringFromWasm0(arg2, arg3));
|
||||
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_set_cb0e7a5c2dd66afd = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).set(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_parentNode_6be3abff20e1a5fb = function(arg0) {
|
||||
const ret = getObject(arg0).parentNode;
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
|
@ -901,6 +865,42 @@ function __wbg_get_imports() {
|
|||
const ret = getObject(arg0).removeChild(getObject(arg1));
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_instanceof_ShadowRoot_9db040264422e84a = function(arg0) {
|
||||
let result;
|
||||
try {
|
||||
result = getObject(arg0) instanceof ShadowRoot;
|
||||
} catch (_) {
|
||||
result = false;
|
||||
}
|
||||
const ret = result;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_host_c667c7623404d6bf = function(arg0) {
|
||||
const ret = getObject(arg0).host;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_credentials_301bbb1c5ba6b52c = function(arg0) {
|
||||
const ret = getObject(arg0).credentials;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_get_af826bc073cbd7b3 = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg0).get(getObject(arg1));
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_value_d7f5bfbd9302c14b = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).value;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_setvalue_090972231f0a4f6f = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
|
||||
};
|
||||
imports.wbg.__wbg_getClientExtensionResults_a849d498bd960116 = function(arg0) {
|
||||
const ret = getObject(arg0).getClientExtensionResults();
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_get_bd8e338fbd5f5cc8 = function(arg0, arg1) {
|
||||
const ret = getObject(arg0)[arg1 >>> 0];
|
||||
return addHeapObject(ret);
|
||||
|
@ -1073,14 +1073,14 @@ function __wbg_get_imports() {
|
|||
const ret = result;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_stringify_8887fe74e1c50d81 = function() { return handleError(function (arg0) {
|
||||
const ret = JSON.stringify(getObject(arg0));
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_set_1f9b04f170055d33 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
|
||||
return ret;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_stringify_8887fe74e1c50d81 = function() { return handleError(function (arg0) {
|
||||
const ret = JSON.stringify(getObject(arg0));
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbindgen_bigint_get_as_i64 = function(arg0, arg1) {
|
||||
const v = getObject(arg1);
|
||||
const ret = typeof(v) === 'bigint' ? v : undefined;
|
||||
|
@ -1101,16 +1101,16 @@ function __wbg_get_imports() {
|
|||
const ret = wasm.memory;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper1311 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 512, __wbg_adapter_48);
|
||||
imports.wbg.__wbindgen_closure_wrapper1418 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 537, __wbg_adapter_48);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper1744 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 642, __wbg_adapter_51);
|
||||
imports.wbg.__wbindgen_closure_wrapper1729 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 626, __wbg_adapter_51);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper1777 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 658, __wbg_adapter_54);
|
||||
imports.wbg.__wbindgen_closure_wrapper1760 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 643, __wbg_adapter_54);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1148,20 +1148,20 @@ function __wbg_get_imports() {
|
|||
const ret = wasm.memory;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper1240 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 641, __wbg_adapter_48);
|
||||
imports.wbg.__wbindgen_closure_wrapper1348 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 693, __wbg_adapter_48);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper3882 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1951, __wbg_adapter_51);
|
||||
imports.wbg.__wbindgen_closure_wrapper3881 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1949, __wbg_adapter_51);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper3961 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1977, __wbg_adapter_54);
|
||||
imports.wbg.__wbindgen_closure_wrapper3960 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1975, __wbg_adapter_54);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper3992 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1994, __wbg_adapter_57);
|
||||
imports.wbg.__wbindgen_closure_wrapper3991 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1992, __wbg_adapter_57);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,3 +1,5 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
use constants::CONTENT_TYPE;
|
||||
use error::FetchError;
|
||||
use gloo::console;
|
||||
|
@ -50,7 +52,7 @@ pub async fn do_request<JV: AsRef<JsValue>>(
|
|||
body: Option<JV>,
|
||||
) -> Result<(Option<String>, u16, JsValue, Headers), FetchError> {
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method(&method.to_string());
|
||||
opts.method(method.as_ref());
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
opts.credentials(web_sys::RequestCredentials::SameOrigin);
|
||||
|
||||
|
@ -121,16 +123,22 @@ pub enum RequestMethod {
|
|||
PUT,
|
||||
}
|
||||
|
||||
impl ToString for RequestMethod {
|
||||
fn to_string(&self) -> String {
|
||||
impl AsRef<str> for RequestMethod {
|
||||
fn as_ref(&self) -> &str {
|
||||
match self {
|
||||
RequestMethod::PUT => "PUT".to_string(),
|
||||
RequestMethod::POST => "POST".to_string(),
|
||||
RequestMethod::GET => "GET".to_string(),
|
||||
RequestMethod::PUT => "PUT",
|
||||
RequestMethod::POST => "POST",
|
||||
RequestMethod::GET => "GET",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for RequestMethod {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(self.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
/// creates the "Kanidm is alpha" banner
|
||||
pub fn alpha_warning_banner() -> Html {
|
||||
html!(
|
||||
|
@ -153,15 +161,15 @@ pub enum SessionStatus {
|
|||
Error { emsg: String, kopid: Option<String> },
|
||||
}
|
||||
|
||||
impl ToString for SessionStatus {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
impl Display for SessionStatus {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(&match self {
|
||||
SessionStatus::TokenValid => "SessionStatus::TokenValid".to_string(),
|
||||
SessionStatus::LoginRequired => "SessionStatus::LoginRequired".to_string(),
|
||||
SessionStatus::Error { emsg, kopid } => {
|
||||
format!("SessionStatus::Error: {} {:?}", emsg, kopid)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -377,7 +377,7 @@ impl CredentialResetApp {
|
|||
attested_passkeys_allowed_devices,
|
||||
} = status;
|
||||
|
||||
let (username, domain) = spn.split_once('@').unwrap_or(("", &spn));
|
||||
let (username, domain) = spn.split_once('@').unwrap_or(("", spn));
|
||||
let names = format!("{} ({})", displayname, username);
|
||||
let cb = self.cb.clone();
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ fn main() {
|
|||
.build()
|
||||
.expect("Failed to initialise tokio runtime!");
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
tracing::debug!("Using {} worker threads", par_count);
|
||||
|
||||
rt.block_on(async { opt.commands.exec().await });
|
||||
|
|
|
@ -105,13 +105,13 @@ pub struct TokenStore {
|
|||
|
||||
impl TokenStore {
|
||||
pub fn instances(&self, name: &Option<String>) -> Option<&TokenInstance> {
|
||||
let n_lookup = name.clone().unwrap_or_else(|| "".to_string());
|
||||
let n_lookup = name.clone().unwrap_or_default();
|
||||
|
||||
self.instances.get(&n_lookup)
|
||||
}
|
||||
|
||||
pub fn instances_mut(&mut self, name: &Option<String>) -> Option<&mut TokenInstance> {
|
||||
let n_lookup = name.clone().unwrap_or_else(|| "".to_string());
|
||||
let n_lookup = name.clone().unwrap_or_default();
|
||||
|
||||
self.instances.get_mut(&n_lookup)
|
||||
}
|
||||
|
@ -413,7 +413,7 @@ async fn process_auth_state(
|
|||
let mut tokens = read_tokens(&client.get_token_cache_path()).unwrap_or_default();
|
||||
|
||||
// Select our token instance. Create it if empty.
|
||||
let n_lookup = instance_name.clone().unwrap_or_else(|| "".to_string());
|
||||
let n_lookup = instance_name.clone().unwrap_or_default();
|
||||
let token_instance = tokens.instances.entry(n_lookup).or_default();
|
||||
|
||||
// Add our new one
|
||||
|
@ -437,7 +437,7 @@ async fn process_auth_state(
|
|||
pub_jwk
|
||||
} else {
|
||||
// Get it from the server.
|
||||
let pub_jwk = match client.get_public_jwk(&key_id).await {
|
||||
let pub_jwk = match client.get_public_jwk(key_id).await {
|
||||
Ok(pj) => pj,
|
||||
Err(err) => {
|
||||
error!(?err, "Unable to retrieve jwk from server");
|
||||
|
@ -675,7 +675,7 @@ impl LogoutOpt {
|
|||
std::process::exit(1);
|
||||
});
|
||||
|
||||
let n_lookup = instance_name.clone().unwrap_or_else(|| "".to_string());
|
||||
let n_lookup = instance_name.clone().unwrap_or_default();
|
||||
let Some(token_instance) = tokens.instances.get_mut(&n_lookup) else {
|
||||
println!("No sessions for {}", spn);
|
||||
return;
|
||||
|
|
|
@ -1165,6 +1165,7 @@ fn main() {
|
|||
.build()
|
||||
.expect("Failed to initialise tokio runtime!");
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
tracing::debug!("Using {} worker threads", par_count);
|
||||
|
||||
rt.block_on(async move { driver_main(opt).await });
|
||||
|
|
|
@ -829,6 +829,7 @@ fn main() {
|
|||
.build()
|
||||
.expect("Failed to initialise tokio runtime!");
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
tracing::debug!("Using {} worker threads", par_count);
|
||||
|
||||
if rt.block_on(async move { driver_main(opt).await }).is_err() {
|
||||
|
|
|
@ -75,6 +75,7 @@ impl ActorAuthOnly {
|
|||
self.state = State::Unauthenticated;
|
||||
}
|
||||
// Shouldn't be reachable?
|
||||
#[allow(clippy::unreachable)]
|
||||
(_, _, TransitionResult::Ok) => {
|
||||
unreachable!();
|
||||
}
|
||||
|
|
|
@ -129,6 +129,7 @@ impl ActorBasic {
|
|||
(_, TransitionAction::Logout, TransitionResult::Ok) => {
|
||||
self.state = State::Unauthenticated;
|
||||
}
|
||||
#[allow(clippy::unreachable)]
|
||||
(_, _, TransitionResult::Ok) => {
|
||||
unreachable!();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// use async_trait::async_trait;
|
||||
use hashbrown::HashSet;
|
||||
use std::collections::BTreeSet;
|
||||
use std::fmt::Display;
|
||||
use std::num::NonZeroUsize;
|
||||
use std::ops::{Add, DerefMut, Sub};
|
||||
use std::path::Path;
|
||||
|
@ -82,12 +83,12 @@ where
|
|||
nxcache: Mutex<LruCache<Id, SystemTime>>,
|
||||
}
|
||||
|
||||
impl ToString for Id {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
Id::Name(s) => s.clone(),
|
||||
impl Display for Id {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(&match self {
|
||||
Id::Name(s) => s.to_string(),
|
||||
Id::Gid(g) => g.to_string(),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue