Skip to main content

kanidm_proto/internal/
error.rs

1use super::credupdate::PasswordFeedback;
2use crate::attribute::Attribute;
3use serde::{Deserialize, Serialize};
4use std::fmt::{Display, Formatter};
5use utoipa::ToSchema;
6use uuid::Uuid;
7
8/* ===== errors ===== */
9#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, ToSchema)]
10#[serde(rename_all = "lowercase")]
11pub enum SchemaError {
12    NotImplemented,
13    NoClassFound,
14    InvalidClass(Vec<String>),
15    MissingMustAttribute(Vec<Attribute>),
16    InvalidAttribute(String),
17    InvalidAttributeSyntax(String),
18    AttributeNotValidForClass(String),
19    SupplementsNotSatisfied(Vec<String>),
20    ExcludesNotSatisfied(Vec<String>),
21    EmptyFilter,
22    Corrupted,
23    PhantomAttribute(String),
24}
25
26#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, ToSchema)]
27#[serde(rename_all = "lowercase")]
28pub enum PluginError {
29    Base(String),
30    ReferentialIntegrity(String),
31    CredImport(String),
32    Oauth2Secrets,
33}
34
35#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, ToSchema)]
36#[serde(rename_all = "lowercase")]
37pub enum ConsistencyError {
38    Unknown,
39    // Class, Attribute
40    SchemaClassMissingAttribute(String, String),
41    SchemaClassPhantomAttribute(String, String),
42    SchemaUuidNotUnique(Uuid),
43    QueryServerSearchFailure,
44    EntryUuidCorrupt(u64),
45    UuidIndexCorrupt(String),
46    UuidNotUnique(String),
47    RefintNotUpheld(u64),
48    MemberOfInvalid(u64),
49    InvalidAttributeType(String),
50    DuplicateUniqueAttribute,
51    InvalidSpn(u64),
52    SqliteIntegrityFailure,
53    BackendAllIdsSync,
54    BackendIndexSync,
55    ChangelogDesynchronised(u64),
56    ChangeStateDesynchronised(u64),
57    RuvInconsistent(String),
58    DeniedName(Uuid),
59    KeyProviderUuidMissing { key_object: Uuid },
60    KeyProviderNoKeys { key_object: Uuid },
61    KeyProviderNotFound { key_object: Uuid, provider: Uuid },
62}
63
64#[derive(Serialize, Deserialize, Debug, ToSchema)]
65#[serde(rename_all = "lowercase")]
66pub enum OperationError {
67    // Logic errors, or "soft" errors. These are to guide the user or user-interface
68    // in some way.
69    SessionExpired,
70    DuplicateKey,
71    DuplicateLabel,
72    EmptyRequest,
73    Backend,
74    NoMatchingEntries,
75    NoMatchingAttributes,
76    UniqueConstraintViolation,
77    CorruptedEntry(u64),
78    CorruptedIndex(String),
79    ConsistencyError(Vec<ConsistencyError>),
80    SchemaViolation(SchemaError),
81    Plugin(PluginError),
82    FilterGeneration,
83    FilterParseError,
84    FilterUuidResolution,
85    InvalidAttributeName(String),
86    InvalidAttribute(String),
87    InvalidLabel,
88    InvalidDbState,
89    InvalidCacheState,
90    InvalidValueState,
91    InvalidEntryId,
92    InvalidRequestState,
93    InvalidSyncState,
94    InvalidState,
95    InvalidEntryState,
96    InvalidUuid,
97    InvalidReplChangeId,
98    InvalidAcpState(String),
99    InvalidSchemaState(String),
100    InvalidAccountState(String),
101    // This really oughta be EntryClass but its not in proto...
102    // It should at least be &'static str but we
103    // Serialize & Deserialize this enum...
104    MissingClass(String),
105    MissingAttribute(Attribute),
106    AttributeUniqueness(Vec<Attribute>),
107    MissingEntries,
108    ModifyAssertionFailed,
109    BackendEngine,
110    SqliteError, //(RusqliteError)
111    FsError,
112    SerdeJsonError,
113    SerdeCborError,
114    AccessDenied,
115    NotAuthenticated,
116    NotAuthorised,
117    InvalidAuthState(String),
118    InvalidSessionState,
119    SystemProtectedObject,
120    SystemProtectedAttribute,
121    PasswordQuality(Vec<PasswordFeedback>),
122    CryptographyError,
123    ResourceLimit,
124    QueueDisconnected,
125    Webauthn,
126    #[serde(with = "time::serde::timestamp")]
127    Wait(time::OffsetDateTime),
128    ReplReplayFailure,
129    ReplEntryNotChanged,
130    ReplInvalidRUVState,
131    ReplDomainLevelUnsatisfiable,
132    ReplDomainUuidMismatch,
133    ReplServerUuidSplitDataState,
134    TransactionAlreadyCommitted,
135    CannotStartMFADuringOngoingMFASession,
136    /// when you ask for a gid that overlaps a system reserved range
137    /// When a name is denied by the system config
138    ValueDenyName,
139    /// When the DB is potentially over-loaded a timeout can occur starting
140    /// your operation.
141    DatabaseLockAcquisitionTimeout,
142    /// Your change would introduce a reference loop
143    ReferenceLoop,
144    /// This session is not able to re-authenticate and has static privileges
145    SessionMayNotReauth,
146
147    // Specific internal errors.
148    AU0001InvalidState,
149    AU0002JwsSerialisation,
150    AU0003JwsSignature,
151    AU0004UserAuthTokenInvalid,
152    AU0005DelayedProcessFailure,
153    AU0006CredentialMayNotReauthenticate,
154    AU0007UserAuthTokenInvalid,
155    AU0008ClientAuthInfoPrevalidation,
156
157    // Kanidm Generic Errors
158    KG001TaskTimeout,
159    KG002TaskCommFailure,
160    KG003CacheClearFailed,
161    KG004UnknownFeatureUuid,
162    KG005HowDidYouEvenManageThis,
163    KG006DatastructureCorruption,
164
165    // Account Signup Errors
166    AS0001FeatureDisabled,
167
168    // Credential Update Errors
169    CU0001WebauthnAttestationNotTrusted,
170    CU0002WebauthnRegistrationError,
171    CU0003WebauthnUserNotVerified,
172
173    // The session is inconsistent and can't be committed, but the errors
174    // can be resolved.
175    CU0004SessionInconsistent,
176    // Another session used this intent token, and so it can't be committed.
177    CU0005IntentTokenConflict,
178    // The intent token was invalidated before we could commit.
179    CU0006IntentTokenInvalidated,
180    CU0007AccountEmailNotFound,
181    CU0008AccountMissingEmail,
182    CU0009AccountEmailNotFound,
183    CU0010AccountRecoveryDisabled,
184
185    // ValueSet errors
186    VS0001IncomingReplSshPublicKey,
187    VS0002CertificatePublicKeyDigest,
188    VS0003CertificateDerDecode,
189    VS0004CertificatePublicKeyDigest,
190    VS0005CertificatePublicKeyDigest,
191    // Value Errors
192    VL0001ValueSshPublicKeyString,
193
194    // LDAP Errors
195    LD0001AnonymousNotAllowed,
196
197    // DB low level errors.
198    DB0001MismatchedRestoreVersion,
199    DB0002MismatchedRestoreVersion,
200    DB0003FilterResolveCacheBuild,
201    DB0004DatabaseTooOld,
202
203    // SCIM
204    SC0001IncomingSshPublicKey,
205    SC0002ReferenceSyntaxInvalid,
206    SC0003MailSyntaxInvalid,
207    SC0004UuidSyntaxInvalid,
208    SC0005BoolSyntaxInvalid,
209    SC0006Uint32SyntaxInvalid,
210    SC0007UrlSyntaxInvalid,
211    SC0008SyntaxTypeSyntaxInvalid,
212    SC0009IndexTypeSyntaxInvalid,
213    SC0010DateTimeSyntaxInvalid,
214    SC0011AddressSyntaxInvalid,
215    SC0012CertificateSyntaxInvalid,
216    SC0013CertificateInvalidDer,
217    SC0014CertificateInvalidDigest,
218    SC0015CredentialTypeSyntaxInvalid,
219    SC0016InameSyntaxInvalid,
220    SC0017Iutf8SyntaxInvalid,
221    SC0018NsUniqueIdSyntaxInvalid,
222    SC0019Oauth2ScopeSyntaxInvalid,
223    SC0020Oauth2ScopeMapSyntaxInvalid,
224    SC0021Oauth2ScopeMapMissingGroupIdentifier,
225    SC0022Oauth2ClaimMapSyntaxInvalid,
226    SC0023Oauth2ClaimMapMissingGroupIdentifier,
227    SC0024SshPublicKeySyntaxInvalid,
228    SC0025UiHintSyntaxInvalid,
229    SC0026Utf8SyntaxInvalid,
230    SC0027ClassSetInvalid,
231    SC0028CreatedUuidsInvalid,
232    SC0029PaginationOutOfBounds,
233    SC0030Sha256SyntaxInvalid,
234    SC0031Int64SyntaxInvalid,
235    SC0032Uint64SyntaxInvalid,
236    SC0033AssertionContainsDuplicateUuids,
237    // Migration
238    MG0001InvalidReMigrationLevel,
239    MG0002RaiseDomainLevelExceedsMaximum,
240    MG0003ServerPhaseInvalidForMigration,
241    MG0004DomainLevelInDevelopment,
242    MG0005GidConstraintsNotMet,
243    MG0006SKConstraintsNotMet,
244    MG0007Oauth2StrictConstraintsNotMet,
245    MG0008SkipUpgradeAttempted,
246    MG0009InvalidTargetLevelForBootstrap,
247    MG0010DowngradeNotAllowed,
248    //
249    KP0001KeyProviderNotLoaded,
250    KP0002KeyProviderInvalidClass,
251    KP0003KeyProviderInvalidType,
252    KP0004KeyProviderMissingAttributeName,
253    KP0005KeyProviderDuplicate,
254    KP0006KeyObjectJwtEs256Generation,
255    KP0007KeyProviderDefaultNotAvailable,
256    KP0008KeyObjectMissingUuid,
257    KP0009KeyObjectPrivateToDer,
258    KP0010KeyObjectSignerToVerifier,
259    KP0011KeyObjectMissingClass,
260    KP0012KeyObjectMissingProvider,
261    KP0012KeyProviderNotLoaded,
262    KP0013KeyObjectJwsEs256DerInvalid,
263    KP0014KeyObjectSignerToVerifier,
264    KP0015KeyObjectJwsEs256DerInvalid,
265    KP0016KeyObjectJwsEs256DerInvalid,
266    KP0017KeyProviderNoSuchKey,
267    KP0018KeyProviderNoSuchKey,
268    KP0019KeyProviderUnsupportedAlgorithm,
269    KP0020KeyObjectNoActiveSigningKeys,
270    KP0021KeyObjectJwsEs256Signature,
271    KP0022KeyObjectJwsNotAssociated,
272    KP0023KeyObjectJwsKeyRevoked,
273    KP0024KeyObjectJwsInvalid,
274    KP0025KeyProviderNotAvailable,
275    KP0026KeyObjectNoSuchKey,
276    KP0027KeyObjectPublicToDer,
277    KP0028KeyObjectImportJwsEs256DerInvalid,
278    KP0029KeyObjectSignerToVerifier,
279    KP0030KeyObjectPublicToDer,
280    KP0031KeyObjectNotFound,
281    KP0032KeyProviderNoSuchKey,
282    KP0033KeyProviderNoSuchKey,
283    KP0034KeyProviderUnsupportedAlgorithm,
284    KP0035KeyObjectJweA128GCMGeneration,
285    KP0036KeyObjectPrivateToBytes,
286    KP0037KeyObjectImportJweA128GCMInvalid,
287    KP0038KeyObjectImportJweA128GCMInvalid,
288    KP0039KeyObjectJweNotAssociated,
289    KP0040KeyObjectJweInvalid,
290    KP0041KeyObjectJweRevoked,
291    KP0042KeyObjectNoActiveEncryptionKeys,
292    KP0043KeyObjectJweA128GCMEncryption,
293    KP0044KeyObjectJwsPublicJwk,
294
295    KP0045KeyObjectImportJwsRs256DerInvalid,
296    KP0046KeyObjectSignerToVerifier,
297    KP0047KeyObjectPublicToDer,
298    KP0048KeyObjectJwtRs256Generation,
299    KP0049KeyObjectSignerToVerifier,
300    KP0050KeyObjectPrivateToDer,
301    KP0051KeyObjectPublicToDer,
302    KP0052KeyObjectJwsRs256DerInvalid,
303    KP0053KeyObjectSignerToVerifier,
304    KP0054KeyObjectJwsRs256DerInvalid,
305    KP0055KeyObjectJwsRs256DerInvalid,
306    KP0056KeyObjectJwsRs256Signature,
307    KP0057KeyObjectJwsNotAssociated,
308    KP0058KeyObjectJwsInvalid,
309    KP0059KeyObjectJwsKeyRevoked,
310    KP0060KeyObjectJwsPublicJwk,
311    KP0061KeyObjectNoActiveSigningKeys,
312    KP0062KeyProviderNoSuchKey,
313
314    KP0063KeyObjectJwsHs256DerInvalid,
315    KP0064KeyObjectSignerToVerifier,
316    KP0065KeyObjectJwtHs256Generation,
317    KP0066KeyObjectJwsHs256DerInvalid,
318    KP0067KeyObjectSignerToVerifier,
319    KP0068KeyObjectJwsHs256DerInvalid,
320    KP0069KeyObjectNoActiveSigningKeys,
321    KP0070KeyObjectJwsHs256Signature,
322    KP0071KeyObjectPrivateToDer,
323
324    KP0072KeyObjectHs256Invalid,
325    KP0073KeyObjectHs256Invalid,
326    KP0074KeyObjectNoActiveSigningKeys,
327    KP0075KeyObjectHmacInvalidLength,
328    KP0076KeyObjectHkdfOutputLengthInvalid,
329    KP0077KeyProviderNoSuchKey,
330    KP0078KeyObjectNotFound,
331    KP0079KeyObjectNotFound,
332
333    KP0080KeyProviderNoSuchKey,
334
335    // Plugins
336    PL0001GidOverlapsSystemRange,
337
338    // Web UI
339    UI0001ChallengeSerialisation,
340    UI0002InvalidState,
341    UI0003InvalidOauth2Resume,
342    UI0004MemberAlreadyExists,
343
344    // Unixd Things
345    KU001InitWhileSessionActive,
346    KU002ContinueWhileSessionInActive,
347    KU003PamAuthFailed,
348    KU004PamInitFailed,
349    KU005ErrorCheckingAccount,
350    KU006OnlyRootAllowed,
351}
352
353impl PartialEq for OperationError {
354    fn eq(&self, other: &Self) -> bool {
355        // We do this to avoid InvalidPassword being checked as it's not
356        // derive PartialEq. Generally we only use the PartialEq for TESTING
357        // anyway.
358        std::mem::discriminant(self) == std::mem::discriminant(other)
359    }
360}
361
362impl Display for OperationError {
363    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
364        let mut output = format!("{self:?}")
365            .split("::")
366            .last()
367            .unwrap_or("")
368            .to_string();
369
370        if let Some(msg) = self.message() {
371            output += &format!(" - {msg}");
372        };
373        f.write_str(&output)
374    }
375}
376
377impl OperationError {
378    /// Return the message associated with the error if there is one.
379    pub fn message(&self) -> Option<String> {
380        match self {
381            Self::SessionExpired => None,
382            Self::EmptyRequest => None,
383            Self::Backend => None,
384            Self::NoMatchingEntries => None,
385            Self::NoMatchingAttributes => None,
386            Self::UniqueConstraintViolation => Some("A unique constraint was violated resulting in multiple conflicting results.".into()),
387            Self::CorruptedEntry(_) => None,
388            Self::CorruptedIndex(_) => None,
389            Self::ConsistencyError(_) => None,
390            Self::SchemaViolation(_) => None,
391            Self::Plugin(_) => None,
392            Self::FilterGeneration => None,
393            Self::FilterParseError => None,
394            Self::FilterUuidResolution => None,
395            Self::InvalidAttributeName(_) => None,
396            Self::InvalidAttribute(_) => None,
397            Self::InvalidLabel => Some("The submitted label for this item is invalid.".into()),
398            Self::DuplicateLabel => Some("The submitted label for this item is already in use.".into()),
399            Self::DuplicateKey => Some("The submitted key already exists.".into()),
400            Self::InvalidDbState => None,
401            Self::InvalidCacheState => None,
402            Self::InvalidValueState => None,
403            Self::InvalidEntryId => None,
404            Self::InvalidRequestState => None,
405            Self::InvalidSyncState => None,
406            Self::InvalidState => None,
407            Self::InvalidEntryState => None,
408            Self::InvalidUuid => None,
409            Self::InvalidReplChangeId => None,
410            Self::InvalidAcpState(_) => None,
411            Self::InvalidSchemaState(_) => None,
412            Self::InvalidAccountState(val) => Some(format!("Invalid account state: {val}")),
413            Self::MissingClass(val) => Some(format!("Missing class: {val}")),
414            Self::MissingAttribute(val) => Some(format!("Missing attribute: {val}")),
415            Self::AttributeUniqueness(attrs) => Some(format!("The value of some attributes is not unique. {attrs:?}")),
416            Self::MissingEntries => None,
417            Self::ModifyAssertionFailed => None,
418            Self::BackendEngine => None,
419            Self::SqliteError => None,
420            Self::FsError => None,
421            Self::SerdeJsonError => None,
422            Self::SerdeCborError => None,
423            Self::AccessDenied => None,
424            Self::NotAuthenticated => None,
425            Self::NotAuthorised => None,
426            Self::InvalidAuthState(_) => None,
427            Self::InvalidSessionState => None,
428            Self::SystemProtectedObject => None,
429            Self::SystemProtectedAttribute => None,
430            Self::PasswordQuality(_) => None,
431            Self::CryptographyError => None,
432            Self::ResourceLimit => None,
433            Self::QueueDisconnected => None,
434            Self::Webauthn => None,
435            Self::Wait(_) => None,
436            Self::CannotStartMFADuringOngoingMFASession => Some("Cannot start a new MFA authentication flow when there already is one active.".into()),
437            Self::ReplReplayFailure => None,
438            Self::ReplEntryNotChanged => None,
439            Self::ReplInvalidRUVState => None,
440            Self::ReplDomainLevelUnsatisfiable => None,
441            Self::ReplDomainUuidMismatch => None,
442            Self::ReplServerUuidSplitDataState => None,
443            Self::TransactionAlreadyCommitted => None,
444            Self::ValueDenyName => None,
445            Self::DatabaseLockAcquisitionTimeout => Some("Unable to acquire a database lock - the current server may be too busy. Try again later.".into()),
446            Self::ReferenceLoop => Some("The change you have made would introduce an invalid reference loop. Unable to proceed.".into()),
447            Self::SessionMayNotReauth => Some("The current session is not able to re-authenticate to elevate privileges to read-write.".into()),
448
449            Self::AU0001InvalidState => Some("Invalid authentication session state for request".into()),
450            Self::AU0002JwsSerialisation => Some("JWS serialisation failed".into()),
451            Self::AU0003JwsSignature => Some("JWS signature failed".into()),
452            Self::AU0004UserAuthTokenInvalid => Some("User auth token was unable to be generated".into()),
453            Self::AU0005DelayedProcessFailure => Some("Delaying processing failure, unable to proceed".into()),
454            Self::AU0006CredentialMayNotReauthenticate => Some("Credential may not reauthenticate".into()),
455            Self::AU0007UserAuthTokenInvalid => Some("User auth token was unable to be generated".into()),
456            Self::AU0008ClientAuthInfoPrevalidation => Some("Client Authentication Info prevalidation did not occur when expected".into()),
457
458            Self::CU0001WebauthnAttestationNotTrusted => None,
459            Self::CU0002WebauthnRegistrationError => None,
460            Self::CU0003WebauthnUserNotVerified => Some("User Verification bit not set while registering credential, you may need to configure a PIN on this device.".into()),
461
462            Self::CU0004SessionInconsistent => Some("The session is unable to be committed due to unresolved warnings.".into()),
463            Self::CU0005IntentTokenConflict => Some("The intent token used to create this session has been reused in another browser/tab and may not proceed.".into()),
464            Self::CU0006IntentTokenInvalidated => Some("The intent token has been invalidated/revoked before the commit could be accepted. Has it been used in another browser or tab?".into()),
465            Self::CU0007AccountEmailNotFound |
466            Self::CU0009AccountEmailNotFound
467            => Some("The target email for a credential update intent token send request is not registered to the account.".into()),
468            Self::CU0008AccountMissingEmail => Some("The account has no email addresses and may not have a credential update intent token sent to it.".into()),
469            Self::CU0010AccountRecoveryDisabled => Some("The account recovery feature is disabled. See `kanidm system domain set-allow-account-recovery`".into()),
470
471            Self::DB0001MismatchedRestoreVersion => None,
472            Self::DB0002MismatchedRestoreVersion => None,
473            Self::DB0003FilterResolveCacheBuild => None,
474            Self::DB0004DatabaseTooOld => Some("The database is too old to be migrated.".into()),
475            Self::KG001TaskTimeout => Some("Task timed out".into()),
476            Self::KG002TaskCommFailure => Some("Inter-Task communication failure".into()),
477            Self::KG003CacheClearFailed => Some("Failed to clear cache".into()),
478            Self::KG004UnknownFeatureUuid => None,
479            Self::KG005HowDidYouEvenManageThis => Some("You have damaged the fabric of space time and managed to perform an impossible action.".into()),
480            Self::KG006DatastructureCorruption => None,
481            Self::AS0001FeatureDisabled => None,
482            Self::KP0001KeyProviderNotLoaded => None,
483            Self::KP0002KeyProviderInvalidClass => None,
484            Self::KP0003KeyProviderInvalidType => None,
485            Self::KP0004KeyProviderMissingAttributeName => None,
486            Self::KP0005KeyProviderDuplicate => None,
487            Self::KP0006KeyObjectJwtEs256Generation => None,
488            Self::KP0007KeyProviderDefaultNotAvailable => None,
489            Self::KP0008KeyObjectMissingUuid => None,
490            Self::KP0009KeyObjectPrivateToDer => None,
491            Self::KP0010KeyObjectSignerToVerifier => None,
492            Self::KP0011KeyObjectMissingClass => None,
493            Self::KP0012KeyObjectMissingProvider => None,
494            Self::KP0012KeyProviderNotLoaded => None,
495            Self::KP0013KeyObjectJwsEs256DerInvalid => None,
496            Self::KP0014KeyObjectSignerToVerifier => None,
497            Self::KP0015KeyObjectJwsEs256DerInvalid => None,
498            Self::KP0016KeyObjectJwsEs256DerInvalid => None,
499            Self::KP0017KeyProviderNoSuchKey => None,
500            Self::KP0018KeyProviderNoSuchKey => None,
501            Self::KP0019KeyProviderUnsupportedAlgorithm => None,
502            Self::KP0020KeyObjectNoActiveSigningKeys => None,
503            Self::KP0021KeyObjectJwsEs256Signature => None,
504            Self::KP0022KeyObjectJwsNotAssociated => None,
505            Self::KP0023KeyObjectJwsKeyRevoked => None,
506            Self::KP0024KeyObjectJwsInvalid => None,
507            Self::KP0025KeyProviderNotAvailable => None,
508            Self::KP0026KeyObjectNoSuchKey => None,
509            Self::KP0027KeyObjectPublicToDer => None,
510            Self::KP0028KeyObjectImportJwsEs256DerInvalid => None,
511            Self::KP0029KeyObjectSignerToVerifier => None,
512            Self::KP0030KeyObjectPublicToDer => None,
513            Self::KP0031KeyObjectNotFound => None,
514            Self::KP0032KeyProviderNoSuchKey => None,
515            Self::KP0033KeyProviderNoSuchKey => None,
516            Self::KP0034KeyProviderUnsupportedAlgorithm => None,
517            Self::KP0035KeyObjectJweA128GCMGeneration => None,
518            Self::KP0036KeyObjectPrivateToBytes => None,
519            Self::KP0037KeyObjectImportJweA128GCMInvalid => None,
520            Self::KP0038KeyObjectImportJweA128GCMInvalid => None,
521            Self::KP0039KeyObjectJweNotAssociated => None,
522            Self::KP0040KeyObjectJweInvalid => None,
523            Self::KP0041KeyObjectJweRevoked => None,
524            Self::KP0042KeyObjectNoActiveEncryptionKeys => None,
525            Self::KP0043KeyObjectJweA128GCMEncryption => None,
526            Self::KP0044KeyObjectJwsPublicJwk => None,
527
528            Self::KP0045KeyObjectImportJwsRs256DerInvalid => None,
529            Self::KP0046KeyObjectSignerToVerifier => None,
530            Self::KP0047KeyObjectPublicToDer => None,
531            Self::KP0048KeyObjectJwtRs256Generation => None,
532            Self::KP0049KeyObjectSignerToVerifier => None,
533            Self::KP0050KeyObjectPrivateToDer => None,
534            Self::KP0051KeyObjectPublicToDer => None,
535            Self::KP0052KeyObjectJwsRs256DerInvalid => None,
536            Self::KP0053KeyObjectSignerToVerifier => None,
537            Self::KP0054KeyObjectJwsRs256DerInvalid => None,
538            Self::KP0055KeyObjectJwsRs256DerInvalid => None,
539            Self::KP0056KeyObjectJwsRs256Signature => None,
540            Self::KP0057KeyObjectJwsNotAssociated => None,
541            Self::KP0058KeyObjectJwsInvalid => None,
542            Self::KP0059KeyObjectJwsKeyRevoked => None,
543            Self::KP0060KeyObjectJwsPublicJwk => None,
544            Self::KP0061KeyObjectNoActiveSigningKeys => None,
545            Self::KP0062KeyProviderNoSuchKey => None,
546            Self::KP0063KeyObjectJwsHs256DerInvalid => None,
547            Self::KP0064KeyObjectSignerToVerifier => None,
548            Self::KP0065KeyObjectJwtHs256Generation => None,
549            Self::KP0066KeyObjectJwsHs256DerInvalid => None,
550            Self::KP0067KeyObjectSignerToVerifier => None,
551            Self::KP0068KeyObjectJwsHs256DerInvalid => None,
552            Self::KP0069KeyObjectNoActiveSigningKeys => None,
553            Self::KP0070KeyObjectJwsHs256Signature => None,
554            Self::KP0071KeyObjectPrivateToDer => None,
555            Self::KP0072KeyObjectHs256Invalid => None,
556            Self::KP0073KeyObjectHs256Invalid => None,
557            Self::KP0074KeyObjectNoActiveSigningKeys => None,
558            Self::KP0075KeyObjectHmacInvalidLength => None,
559            Self::KP0076KeyObjectHkdfOutputLengthInvalid => None,
560            Self::KP0077KeyProviderNoSuchKey => None,
561            Self::KP0078KeyObjectNotFound => None,
562            Self::KP0079KeyObjectNotFound => None,
563            Self::KP0080KeyProviderNoSuchKey => None,
564
565            Self::KU001InitWhileSessionActive => Some("The session was active when the init function was called.".into()),
566            Self::KU002ContinueWhileSessionInActive => Some("Attempted to continue auth session while current session is inactive".into()),
567            Self::KU003PamAuthFailed => Some("Failed PAM account authentication step".into()),
568            Self::KU004PamInitFailed => Some("Failed to initialise PAM authentication".into()),
569            Self::KU005ErrorCheckingAccount => Some("Error checking account".into()),
570            Self::KU006OnlyRootAllowed => Some("Only root is allowed to perform this operation".into()),
571            Self::LD0001AnonymousNotAllowed => Some("Anonymous is not allowed to access LDAP with this method.".into()),
572            Self::MG0001InvalidReMigrationLevel => None,
573            Self::MG0002RaiseDomainLevelExceedsMaximum => None,
574            Self::MG0003ServerPhaseInvalidForMigration => None,
575            Self::MG0004DomainLevelInDevelopment => None,
576            Self::MG0005GidConstraintsNotMet => None,
577            Self::MG0006SKConstraintsNotMet => Some("Migration Constraints Not Met - Security Keys should not be present.".into()),
578            Self::MG0007Oauth2StrictConstraintsNotMet => Some("Migration Constraints Not Met - All OAuth2 clients must have strict-redirect-uri mode enabled.".into()),
579            Self::MG0008SkipUpgradeAttempted => Some("Skip Upgrade Attempted.".into()),
580            Self::MG0009InvalidTargetLevelForBootstrap => Some("The request target domain level was not valid for bootstrapping a new server instance".into()),
581            Self::MG0010DowngradeNotAllowed => Some("Downgrade Attempted".into()),
582            Self::PL0001GidOverlapsSystemRange => None,
583            Self::SC0001IncomingSshPublicKey => None,
584            Self::SC0002ReferenceSyntaxInvalid => Some("A SCIM Reference Set contained invalid syntax and can not be processed.".into()),
585            Self::SC0003MailSyntaxInvalid => Some("A SCIM Mail Address contained invalid syntax".into()),
586            Self::SC0004UuidSyntaxInvalid => Some("A SCIM Uuid contained invalid syntax".into()),
587            Self::SC0005BoolSyntaxInvalid => Some("A SCIM boolean contained invalid syntax".into()),
588            Self::SC0006Uint32SyntaxInvalid => Some("A SCIM Uint32 contained invalid syntax".into()),
589            Self::SC0007UrlSyntaxInvalid => Some("A SCIM Url contained invalid syntax".into()),
590            Self::SC0008SyntaxTypeSyntaxInvalid => Some("A SCIM SyntaxType contained invalid syntax".into()),
591            Self::SC0009IndexTypeSyntaxInvalid => Some("A SCIM IndexType contained invalid syntax".into()),
592            Self::SC0010DateTimeSyntaxInvalid => Some("A SCIM DateTime contained invalid syntax".into()),
593
594            Self::SC0011AddressSyntaxInvalid => Some("A SCIM Address contained invalid syntax".into()),
595            Self::SC0012CertificateSyntaxInvalid => Some("A SCIM Certificate contained invalid binary data".into()),
596            Self::SC0013CertificateInvalidDer => Some("A SCIM Certificate did not contain valid DER".into()),
597            Self::SC0014CertificateInvalidDigest => Some("A SCIM Certificate was unable to be digested".into()),
598            Self::SC0015CredentialTypeSyntaxInvalid => Some("A SCIM CredentialType contained invalid syntax".into()),
599            Self::SC0016InameSyntaxInvalid => Some("A SCIM Iname string contained invalid syntax".into()),
600            Self::SC0017Iutf8SyntaxInvalid => Some("A SCIM Iutf8 string contained invalid syntax".into()),
601            Self::SC0018NsUniqueIdSyntaxInvalid => Some("A SCIM NsUniqueID contained invalid syntax".into()),
602            Self::SC0019Oauth2ScopeSyntaxInvalid => Some("A SCIM Oauth2 Scope contained invalid syntax".into()),
603            Self::SC0020Oauth2ScopeMapSyntaxInvalid => Some("A SCIM Oauth2 Scope Map contained invalid syntax".into()),
604            Self::SC0021Oauth2ScopeMapMissingGroupIdentifier => Some("A SCIM Oauth2 Scope Map was missing a group name or uuid".into()),
605            Self::SC0022Oauth2ClaimMapSyntaxInvalid => Some("A SCIM Oauth2 Claim Map contained invalid syntax".into()),
606            Self::SC0023Oauth2ClaimMapMissingGroupIdentifier => Some("A SCIM Claim Map was missing a group name or uuid".into()),
607            Self::SC0024SshPublicKeySyntaxInvalid => Some("A SCIM Ssh Public Key contained invalid syntax".into()),
608            Self::SC0025UiHintSyntaxInvalid => Some("A SCIM UiHint contained invalid syntax".into()),
609            Self::SC0026Utf8SyntaxInvalid => Some("A SCIM Utf8 String Scope Map contained invalid syntax".into()),
610            Self::SC0027ClassSetInvalid => Some("The internal set of class templates used in this create operation was invalid. THIS IS A BUG.".into()),
611            Self::SC0028CreatedUuidsInvalid => Some("The internal create query did not return the set of created UUIDs. THIS IS A BUG".into()),
612            Self::SC0029PaginationOutOfBounds => Some("The requested range for pagination was out of bounds of the result set".into()),
613            Self::SC0030Sha256SyntaxInvalid => Some("A SCIM SHA256 hex string was invalid.".into()),
614            Self::SC0031Int64SyntaxInvalid => Some("A SCIM Int64 contained invalid syntax".into()),
615            Self::SC0032Uint64SyntaxInvalid => Some("A SCIM Uint64 contained invalid syntax".into()),
616            Self::SC0033AssertionContainsDuplicateUuids => Some("SCIM assertion contains duplicate entry ids, unable to proceed.".into()),
617            Self::UI0001ChallengeSerialisation => Some("The WebAuthn challenge was unable to be serialised.".into()),
618            Self::UI0002InvalidState => Some("The credential update process returned an invalid state transition.".into()),
619            Self::UI0003InvalidOauth2Resume => Some("The server attempted to resume OAuth2, but no OAuth2 session is in progress.".into()),
620            Self::UI0004MemberAlreadyExists => Some("The target is already a member.".into()),
621            Self::VL0001ValueSshPublicKeyString => None,
622            Self::VS0001IncomingReplSshPublicKey => None,
623            Self::VS0002CertificatePublicKeyDigest |
624            Self::VS0003CertificateDerDecode => Some("Decoding the stored certificate from DER failed.".into()),
625            Self::VS0004CertificatePublicKeyDigest |
626            Self::VS0005CertificatePublicKeyDigest => Some("The certificates public key is unable to be digested.".into()),
627
628        }
629    }
630}
631
632#[test]
633fn test_operationerror_as_nice_string() {
634    assert_eq!(
635        OperationError::CU0001WebauthnAttestationNotTrusted.to_string(),
636        "CU0001WebauthnAttestationNotTrusted".to_string()
637    );
638    assert_eq!(
639        OperationError::CU0003WebauthnUserNotVerified.to_string(),
640        "CU0003WebauthnUserNotVerified - User Verification bit not set while registering credential, you may need to configure a PIN on this device.".to_string()
641    );
642    assert_eq!(
643        OperationError::SessionExpired.to_string(),
644        "SessionExpired".to_string()
645    );
646    assert_eq!(
647        OperationError::CorruptedEntry(12345).to_string(),
648        "CorruptedEntry(12345)".to_string()
649    );
650}